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,3 @@
> 1%
last 2 versions
not dead

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 @@
# zaibaohe
## 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'
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,34 @@
{
"name": "zaibaohe",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
},
"dependencies": {
"amfe-flexible": "^2.2.1",
"axios": "^0.21.1",
"core-js": "^3.6.5",
"node-rsa": "^1.1.1",
"vant": "^2.12.3",
"vue": "^2.6.11",
"vue-router": "^3.2.0",
"vuex": "^3.6.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0",
"@vue/cli-plugin-vuex": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"less": "^3.0.4",
"less-loader": "^5.0.0",
"postcss-pxtorem": "^5.1.1",
"pug": "^3.0.0",
"pug-html-loader": "^1.1.5",
"pug-plain-loader": "^1.1.0",
"style-resources-loader": "^1.4.1",
"vue-cli-plugin-style-resources-loader": "~0.1.4",
"vue-template-compiler": "^2.6.11"
}
}

View File

@@ -0,0 +1,12 @@
module.exports = {
plugins: {
'autoprefixer': {
browsers: ['Android >= 4.0', 'iOS >= 7']
},
'postcss-pxtorem': {
rootValue: 37.5,
//这是基准值在375px的屏幕变大rem的值会变大小于这个大小元素的rem值会变小
propList: ['*']
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 724 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 703 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 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: 65 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: 1.7 KiB

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,18 @@
<!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>
<script src="//at.alicdn.com/t/font_2269051_1j1ibqf3iej.js"></script>
</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 -->
</body>
</html>

View File

@@ -0,0 +1,28 @@
<template lang="pug">
#app
keep-alive
router-view(v-if="$route.meta.keepAlive")
router-view(v-if="!$route.meta.keepAlive")
van-tabbar(v-if="$route.meta.isShowTabbar" v-model='active' route)
van-tabbar-item(icon='home-o' to="/") 首页
van-tabbar-item(icon='apps-o' to="/type") 分类
van-tabbar-item(icon='shopping-cart-o' to="/car") 购物车
van-tabbar-item(icon='friends-o' to="/me") 我的
</template>
<script>
export default {
data () {
return {
active: 0
}
}
}
</script>
<style lang="less">
@import "~@common/_.less";
</style>

View File

@@ -0,0 +1,4 @@
@import "normalize.less";
@import "base.less";
@import "colors.less";
@import "mixins.less";

View File

@@ -0,0 +1,46 @@
@import "./normalize.less";
body,ul,li,p,h1,h2,h3,h4,h5,h6 {
margin: 0;
padding: 0;
list-style: none;
}
a {
text-decoration: none;
color: #000;
}
input {
outline: none;
}
.content {
margin-top: 45px;
}
img {
width: 100%;
}
.me {
.van-divider {
margin: 0 !important;
}
}
.icon {
width: 16px;
height: 16px;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
.car {
.list_item {
display: flex;
padding-left: 15px;
}
.van-card {
flex: 1;
}
}

View File

@@ -0,0 +1,2 @@
@themeColor: #ff6700;
@whileColor: #fff;

View File

@@ -0,0 +1,16 @@
.ellipsis() {
white-space:nowrap;
text-overflow:ellipsis;
overflow:hidden;
word-wrap: break-word;
}
.no-scrollbar() {
&::-webkit-scrollbar {
display: none !important;
width: 0 !important;
height: 0 !important;
-webkit-appearance: none;
opacity: 0 !important;
}
}

View File

@@ -0,0 +1,419 @@
/*! 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 {
margin: 0;
}
/* 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 */
}
/**
* 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 */
}
/**
* 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,38 @@
@import "../common/_.less";
.home {
h2 {
color: @themeColor;
font-size: 37.5px;
}
.recommen_item {
.van-image {
width: 40px;
height: 40px;
margin-bottom: 15px;
}
span {
font-size: 14px;
}
}
.navbar {
display: flex;
height: 45px;
align-items: center;
justify-content: space-between;
padding: 0 15px;
box-sizing: border-box;
position: fixed;
left: 0;
top: 0;
width: 100%;
border-bottom: 1px solid #f7f8fa;
background: @whileColor;
.logo_text {
font-size: 14px;
}
.van-search {
padding: 0 0.32rem !important;
flex: 1;
}
}
}

View File

@@ -0,0 +1,147 @@
.info {
margin-bottom: 50px;
.header {
display: flex;
height: 40px;
align-items: center;
justify-content: space-between;
position: fixed;
left: 0;
top: 10px;
width: 100%;
z-index: 999;
padding: 0 15px;
box-sizing: border-box;
i {
width: 35px;
height: 35px;
border-radius: 100%;
text-align: center;
line-height: 35px;
background: #00000080;
color: #fff;
font-size: 14px;
}
}
.info_text {
padding: 0 15px;
.pabcd{
display: flex;
align-items: flex-end;
.abcd {
color: @themeColor;
font-size: 25px;
}
.aabcd{
font-size: 12px;
align-items: flex-end;
margin-bottom: 7px;
margin-left: 9px;
}
}
.title{
font-size: 17px;
margin-top: 8px;
margin-bottom: 8px;
}
.mess{
font-size: 12px;
margin-top: 6px;
margin-bottom: 6px;
border-bottom: 2px solid rgb(241, 241, 241);
height: 37px;
padding: 4px;
}
.config{
display: flex;
justify-content: space-between;
font-size: 12px;
height: 46px;
text-align: center;
line-height: 46px;
box-sizing: border-box;
.spanTxt1{
margin-right: 20px;
}
.span_linee{
border-bottom: 2px solid rgb(241, 241, 241);
flex: 1;
display: flex;
justify-content: space-between;
.van-icon{
line-height: 46px;
}
}
}
.remarks{
display: flex;
justify-content: space-between;
background-color: #fcfcfc;
line-height: 32px;
margin-top: 4px;
.van-icon{
font-size: 12px;
color: #cecece;
line-height: 32px;
}
.van-cell{
padding: 10px 0;
display: flex;
img{
width: 12px;
height: 12px;
margin-right: 4.7px;
}
.remarks_right{
display: flex;
li{
margin-right: 16px;
span{
font-size: 12px;
}
}
}
}
.van-popup{
box-sizing: border-box;
padding-left: 20px;
padding-right: 20px;
.p1{
font-size: 16px;
text-align: center;
margin-top: 10px;
}
.pp1{
display: flex;
font-size: 12px;
line-height: 15px;
margin-top: 20px;
img{
width: 12px;
height: 12px;
margin-right: 9px;
}
}
}
}
}
.figures{
p{
text-align: center;
}
}
.van-goods-action{
.txtt{
font-size: 16px;
}
}
}

View File

@@ -0,0 +1,68 @@
@import "../common/_.less";
.login {
padding: 0 0.48rem;
.user_header {
margin-bottom: 25px;
text-align: center;
margin-top: 20px;
.logo_header {
width: 80px;
height: 80px;
margin-bottom: 12px;
}
p {
font-size: 18px;
color: #000;
font-weight: 400;
}
}
.user_login {
margin: 20px auto;
position: relative;
}
.user_reg {
position: relative;
.showpwd {
right: 0 !important;
bottom: 3.7rem !important;
}
}
input {
border: none;
border-bottom: 0.02667rem solid #d3d3d3;
width: 100%;
margin-bottom: 13px;
font-size: 16px;
padding-bottom: 15px;
padding-right: 20px;
box-sizing: border-box;
}
.showpwd {
position: absolute;
right: 15px;
bottom: 27px;
}
.submit {
width: 100%;
height: 47px;
border-radius: 20px;
background: @themeColor;
text-align: center;
line-height: 47px;
color: #fff;
font-size: 18px;
}
.action {
margin-top: 10px;
display: flex;
align-items: center;
justify-content: space-between;
position: fixed;
bottom: 15px;
width: calc(100% - 36px);
span {
font-size: 13px;
color: #d3d3d3;
}
}
}

View File

@@ -0,0 +1,31 @@
.me {
.me_header {
display: flex;
height: 85px;
align-items: center;
padding: 0 15px;
box-sizing: border-box;
background: url("https://m.mi.com/static/img/bg.63c8e19851.png") center 0 #f37d0f;
background-size: auto 100%;
img {
width: 44px;
height: 44px;
margin-right: 10px;
}
span {
color: #fff;
font-size: 12px;
}
}
.van-grid-item {
text-align: center;
p {
font-size: 14px;
margin-top: 10px;
}
}
.van-image {
width: 35px;
height: 35px;
}
}

View File

@@ -0,0 +1,59 @@
<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>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex" target="_blank" rel="noopener">vuex</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,80 @@
<template lang="pug">
.list_item
van-row(gutter="5" type="flex" justify="space-between")
router-link(tag="div" class="van-col van-col van-col--12" span="12",
v-for="(v,index) in data" :to="{ path: '/info', query: { id: v.wares_id } }"
:key="index")
img(
:src="v.wares_masterimg[0]"
)
.item_text
p.name {{ v.wares_title }}
p.info {{ v.wares_info }}
.price
.now_price {{ v.wares_oldprice }}
span
del.old_price {{ v.wares_nowprice }}
.buy 立即购买
</template>
<script>
export default {
props: {
data: {
type: Array,
default: () => []
}
}
};
</script>
<style lang="less" scoped>
@import "~@common/mixins.less";
.list_item {
.van-col {
text-align: center;
margin-bottom: 20px;
.item_text {
.name {
font-size: 16px;
color: rgba(0, 0, 0, 0.87);
}
.info {
font-size: 12px;
color: rgba(0, 0, 0, 0.54);
margin-top: 3px;
padding: 0 26px;
.ellipsis();
}
.price {
display: flex;
align-items: flex-end;
justify-content: center;
.now_price {
color: #ea625b;
font-size: 13px;
span {
font-size: 12px;
}
}
.old_price {
color: rgba(0, 0, 0, 0.54);
font-size: 12px;
}
}
}
.buy {
width: 104px;
background: #ea625b;
text-align: center;
height: 30px;
line-height: 30px;
color: #fff;
font-size: 12px;
margin: 0 auto;
margin-top: 8px;
}
}
}
</style>

View File

@@ -0,0 +1,26 @@
<template lang="pug">
.swiper
van-swipe.my-swipe(:autoplay='3000', indicator-color='white')
van-swipe-item(v-for="(item,index) in data" :key="index" @click="SwiperClick(item)")
img(:src="item.banner || item.img || item")
</template>
<script>
export default {
props: {
data: {
type: Array,
default: () => []
}
},
methods: {
SwiperClick(item) {
this.$emit("swiperClick", item)
}
}
}
</script>
<style lang="less" scoped>
</style>

View File

@@ -0,0 +1,43 @@
import Vant from 'vant'
import 'vant/lib/index.css'
import service from '../service/_'
export default {
DevUrl: 'http://127.0.0.1:9090',
ProdUrl: 'http://127.0.0.1:9090',
check: function () {
if (process.env.NODE_ENV == "development") {
return this.DevUrl
} else {
return this.ProdUrl
}
},
ApiUrl: {
index: '/home/index',
add: '/user/add',
login: '/user/login',
activity: '/home/activity',
info: '/home/info',
banner: '/home/banner',
recommend: '/home/recommend',
addCar: '/car/addCar',
checkCar: '/car/checkCar',
getCar: '/car/getCarList',
deleteCar: '/car/deleteCar',
updateCarNum: '/car/updateCarNum',
submitCar: '/car/submitCar',
buyOrder: '/order/buyOrder',
allOrder: '/order/allOrder'
},
VuePlug: [ Vant ],
CustomPlug: [
{ n: '$api', v: service }
],
RsaPublicKey: `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9eo8WIbWS5Yql06imlhrW0ZXh
faivPavdULvYLIxIKyUaOwMPFrPuHqqBNGnYOpiPHAKL+zxk2j4u+6jhB6VK1SOD
ccSLxIRxd0HmSDS+hBzYRf4vKc8BLlhMrYhnLmcxCc+PJIIa4DfCZnu8FfQlu/5L
ljjpYN9kHOpHAT+xpQIDAQAB
-----END PUBLIC KEY-----`
}

View File

@@ -0,0 +1,99 @@
import axios from 'axios'
import config from '@config'
import rsa from '@utils/rsa';
import { Dialog } from 'vant';
class Http {
static instance;
static getInstance() {
if (this.instance instanceof this) {
return this.instance;
} else {
this.instance = new this;
return this.instance;
}
}
constructor() {
this.SetBaseUrl();
this.interceptors();
this.rsa = new rsa();
}
async get(url, params = {}, header = {}) {
return await axios.get(url, {
params: params,
headers: header
})
}
async post(url, params, header = {}) {
return await axios.post(url, params, {
headers: Object.assign(
header,
{
data: this.rsa.PublicKeyEncryption(params),
token: localStorage.getItem("token")
}
),
})
}
interceptors() {
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
axios.interceptors.response.use(async (response) => {
// 对响应数据做点什么
switch (response.data.status) {
case 200:
response.data.result = this.rsa.PublicKeyDecryption(response.data.result);
return response.data.result;
break;
case 500:
await Dialog.alert({
title: '提示',
message: response.data.message,
});
throw new Error(response.data.message);
break;
case 404:
await Dialog.alert({
title: '提示',
message: response.data.message,
});
throw new Error(response.data.message);
break;
// token 失效
case 501:
let a = await Dialog.alert({
title: '提示',
message: response.data.message,
});
if (a == "confirm") {
location.href = "#/login"
}
break;
};
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
}
SetBaseUrl() {
if (axios.defaults.baseURL == null) {
axios.defaults.baseURL = config.check();
}
}
}
export default Http

View File

@@ -0,0 +1,18 @@
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.VuePlug.forEach((v)=> Vue.use(v));
config.CustomPlug.forEach((v) => Vue.prototype[v.n] = v.v);
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')

View File

@@ -0,0 +1,19 @@
import {mapActions, mapGetters} from "vuex";
export default {
methods: {
...mapActions({
getCar: 'GET_CARDATA'
})
},
computed: {
...mapGetters({
carList: 'GET_CARLIST'
}),
},
filters: {
subdesc(desc) {
return desc.substr(0,20) + '...'
}
},
}

View File

@@ -0,0 +1,132 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location, onResolve, onReject) {
if (onResolve || onReject) return originalPush.call(this, location, onResolve, onReject)
return originalPush.call(this, location).catch(err => err)
}
const routes = [
{
path: '/',
name: 'Home',
component: () => import(/* webpackChunkName: "Home" */ '../views/Home.vue'),
meta: {
keepAlive: true,
isLogin: false,
isShowTabbar: true
}
},
{
path: '/type',
name: 'type',
component: () => import(/* webpackChunkName: "Type" */ '../views/Type.vue'),
meta: {
keepAlive: true,
isLogin: false,
isShowTabbar: true
}
},
{
path: '/car',
name: 'car',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "Car" */ '../views/Car.vue'),
meta: {
keepAlive: true,
isLogin: true,
isShowTabbar: true
}
},
{
path: '/me',
name: 'me',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "Me" */ '../views/Me.vue'),
meta: {
keepAlive: false,
isLogin: true,
isShowTabbar: true
}
},
{
path: '/info',
name: 'info',
component: () => import(/* webpackChunkName: "Info" */ '../views/Info.vue'),
meta: {
keepAlive: false,
isLogin: false,
isShowTabbar: false
}
},
{
path: '/login',
name: 'login',
component: () => import(/* webpackChunkName: "Login" */ '../views/Login.vue'),
meta: {
keepAlive: false,
isLogin: false,
isShowTabbar: false
}
},
{
path: '/order',
name: 'order',
component: () => import(/* webpackChunkName: "Order" */ '../views/order/Order.vue'),
meta: {
keepAlive: false,
isLogin: true,
isShowTabbar: false
}
},
{
path: '/orderSuccess',
name: 'orderSuccess',
component: () => import(/* webpackChunkName: "OrderSuccess" */ '../views/order/OrderSuccess.vue'),
meta: {
keepAlive: false,
isLogin: true,
isShowTabbar: false
}
},
{
path: '/orderStatus',
name: 'OrderStatus',
component: () => import(/* webpackChunkName: "OrderStatus" */ '../views/order/OrderStatus.vue'),
meta: {
keepAlive: false,
isLogin: true,
isShowTabbar: false
}
}
]
const router = new VueRouter({
routes
});
router.beforeEach((to, from, next) => {
if (to.meta.isLogin) {
if (localStorage.getItem("token") !== null) {
next()
} else {
next({
path: '/login',
query: {
from: to.fullPath
}
})
}
} else {
next();
}
})
export default router

View File

@@ -0,0 +1,20 @@
export class BaseService {
handle (data) {
if (Array.isArray(data)) {
data.forEach(v => {
v.wares_masterimg = JSON.parse(v.wares_masterimg);
v.wares_infoimg = JSON.parse(v.wares_infoimg)
});
} else if (Object.keys(data).length != 0) {
data.wares_masterimg = JSON.parse(data.wares_masterimg);
data.wares_infoimg = JSON.parse(data.wares_infoimg);
} else {
return []
}
return data;
}
}

View File

@@ -0,0 +1,69 @@
import http from '@http'
import config from '@config'
import { BaseService } from './BaseService';
class CarServce extends BaseService {
async addCar (params = {} ) {
return await http.getInstance().post(
config.ApiUrl.addCar,
params
)
}
async checkCar (params = {} ) {
console.log("111")
return await http.getInstance().post(
config.ApiUrl.checkCar,
params
)
}
async getCar (params = {} ) {
return this.handle(
await http.getInstance().post(
config.ApiUrl.getCar,
params
)
)
}
async deleteCar (params = {} ) {
return await http.getInstance().post(
config.ApiUrl.deleteCar,
params
)
}
async updateCarNum (params = {} ) {
return await http.getInstance().post(
config.ApiUrl.updateCarNum,
params
)
}
async submitCar (params = {} ) {
return await http.getInstance().post(
config.ApiUrl.submitCar,
params
)
}
async buyOrder (params = {} ) {
return await http.getInstance().post(
config.ApiUrl.buyOrder,
params
)
}
async allOrder (params = {} ) {
return this.handle(
await http.getInstance().post(
config.ApiUrl.allOrder,
params
)
)
}
}
export default new CarServce()

View File

@@ -0,0 +1,37 @@
import http from '@http'
import config from '@config'
import { BaseService } from './BaseService';
class HomeService extends BaseService {
async index(params = {}) {
return this.handle(await http.getInstance().post(
config.ApiUrl.index,
params
))
}
async info(params = {}) {
return this.handle(
await http.getInstance().post(
config.ApiUrl.info,
params
)
)
}
async banner(params = {}) {
return await http.getInstance().post(
config.ApiUrl.banner,
params
)
}
async recommend(params = {}) {
return await http.getInstance().post(
config.ApiUrl.recommend,
params
)
}
}
export default new HomeService()

View File

@@ -0,0 +1,20 @@
import http from '@http'
import config from '@config'
class UserService {
async add (params = {} ) {
return await http.getInstance().post(
config.ApiUrl.add,
params
)
}
async login (params = {} ) {
return await http.getInstance().post(
config.ApiUrl.login,
params
)
}
}
export default new UserService()

View File

@@ -0,0 +1,9 @@
import HomeService from './HomeService';
import UserService from './UserService';
import CarServce from './CarServce';
export default {
home: HomeService,
user: UserService,
car: CarServce,
}

View File

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

View File

@@ -0,0 +1,25 @@
import vue from "vue";
export default {
state: {
carList: []
},
getters: {
GET_CARLIST: state => {
return state.carList
}
},
mutations: {
SET_CARLIST (state, params) {
state.carList = params;
}
},
actions: {
async GET_CARDATA(context, type = false) {
if (this.state.car.carList.length == 0 || type) {
let res = await vue.prototype.$api.car.getCar();
context.commit("SET_CARLIST", res)
}
}
}
}

View File

@@ -0,0 +1,13 @@
export default {
state: {
test: "设置"
},
getters: {
GET_TEST: state => {
return state.test
}
},
mutations: {
}
}

View File

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

View File

@@ -0,0 +1,124 @@
<template lang="pug">
.car
van-nav-bar(title='购物车', left-arrow, @click-right="status = !status")
template(#right) {{ status ? '管理' : '完成' }}
.car_list
div(v-if="carList.length == 0" class="nocar") 暂无数据
van-checkbox-group(v-else v-model="selecCarItem" @change="ItemChange" ref="checkboxGroup")
div(v-for="(v,i) in carList" class="list_item" :key="i")
van-checkbox(:name="v.car_id")
van-card(:price='v.wares_oldprice',
:desc='v.wares_info | subdesc',
:title='v.wares_title',
:thumb='v.wares_masterimg[0]')
template(#num)
van-stepper(:name="i" v-model="v.car_num" @change="NumChange")
van-submit-bar(:price="GoodsTotal",
:button-text="status ? '提交订单' : '删除' "
@submit="status ? onSubmit() : deleteCarItem()")
van-checkbox(v-model="isSelectAll" @click="checkAll") 全选
</template>
<script>
import CarMixins from "../mixins/car"
export default {
mixins: [CarMixins],
data () {
return {
selecCarItem: [],
isSelectAll: false,
status: true
}
},
async created() {
await this.getCar();
console.log("carList: ",this.carList)
},
methods: {
async NumChange(value,detail) {
await this.$api.car.updateCarNum({
carid: this.carList[detail.name].car_id,
quantity: this.carList[detail.name].car_num,
});
},
// 全选按钮被点击
checkAll() {
if (this.isSelectAll) {
this.$refs.checkboxGroup.toggleAll(true);
} else {
this.$refs.checkboxGroup.toggleAll();
}
},
// 列表每一项被点击触发事件
ItemChange() {
if (this.carList.length == this.selecCarItem.length) {
this.isSelectAll = true;
} else {
this.isSelectAll = false;
}
},
// 提交订单
async onSubmit() {
let submitCar = []
this.carList.forEach(v => {
if (this.selecCarItem.includes(v.car_id)) {
submitCar.push({
waresid: v.wares_id,
goodsnum: v.car_num,
goodsprice: v.wares_oldprice
})
}
});
let res = await this.$api.car.submitCar(JSON.stringify({
carList: submitCar
}))
console.log("提交订单 ===== : ", res)
this.$router.push("/order")
},
// 删除购物车商品
async deleteCarItem() {
let res = await this.$api.car.deleteCar({
carid: this.selecCarItem
});
await this.getCar(true);
if (this.carList.length == 0) {
this.isSelectAll = false
}
},
},
computed: {
GoodsTotal() {
let Total = 0;
this.carList.forEach(v => {
if (this.selecCarItem.includes(v.car_id)) {
Total += v.wares_oldprice * v.car_num
}
});
return Total * 100
},
},
}
</script>
<style lang="less" scoped>
.car {
.nocar {
text-align: center;
margin: 10% 0;
font-size: 14px;
color: #8d8d8d;
}
.van-submit-bar {
bottom: 50px !important;
}
.van-card {
background: #fff !important;
}
}
</style>

View File

@@ -0,0 +1,71 @@
<template lang="pug">
.content
.home
.navbar
span.logo_text 基友汇
van-search(v-model='SearchKey', placeholder='请输入搜索关键词', shape="round")
van-icon(name='friends-o' size="18")
Swiper(:data="bannerData" @swiperClick="EnterInfo")
van-grid(:border="false")
van-grid-item(class="recommen_item" v-for="(v,i) in recommendData")
van-image(:src="v.url")
span {{ v.title }}
.adv
img(src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/189acdf7e9b807cfc22d394df87c1958.jpg")
ListItem(:data="shopList")
h2 首页
</template>
<script>
import Swiper from '@com/Swiper'
import ListItem from '@com/ListItem'
export default {
data () {
return {
SearchKey: '',
shopList: [],
bannerData: [],
recommendData: []
}
},
created() {
this.GetIndexData();
this.banner();
this.recommend()
},
methods: {
EnterInfo(value) {
this.$router.push({
path: 'info',
query: {
id: value.wares_id
}
})
},
async GetIndexData () {
this.shopList = await this.$api.home.index()
console.log(this.shopList)
},
async banner() {
this.bannerData = await this.$api.home.banner();
console.log("banner: ", this.bannerData)
},
async recommend() {
this.recommendData = await this.$api.home.recommend();
console.log("recommend == : ", this.recommendData)
}
},
components: {
Swiper,
ListItem
}
}
</script>
<style scoped lang="less">
@import "~@views/Home.less";
</style>

View File

@@ -0,0 +1,143 @@
<template lang="pug">
.info
.header
van-icon(name="arrow-left")
van-icon(name="shopping-cart-o")
Swiper(:data="res.wares_masterimg")
.info_text
p.aaabcd
.pabcd
p.abcd {{res.wares_oldprice}}
span.aabcd {{res.wares_nowprice}}
.title {{res.wares_title}}
.mess {{res.wares_info}}
.config
//- .span_text
//- span.spanTxt1 已选
//- .span_line
//- span.spanTxt2 Redmi Note 8 4GB+64GB 曜石黑
//- span x 1
//- van-icon(name="arrow")
span.spanTxt1 已选
.span_linee
span.spanTxt2 Redmi Note 8 4GB+64GB 曜石黑 x1
van-icon(name="arrow")
.remarks
van-cell(is-link='', @click='showPopup')
ul.remarks_right
li
img(src="/img/bz.png")
span 小米自营
li
img(src="/img/bz.png")
span 小米发货
li
img(src="/img/bz.png")
span 7天无理由退货
van-popup(v-model='show' , round , position='bottom', :style="{ height: '70%' }")
p.p1 服务说明
.pp1
img(src="/img/right.png")
|小米自营
.pp1
img(src="/img/right.png")
|小米自营
.pp1
img(src="/img/right.png")
|小米自营
.pp1
img(src="/img/right.png")
|小米自营
.figures
p 商品介绍
img(v-for="(item,index) in res.wares_infoimg" :src="item" @click="OpenPreview(index)")
van-goods-action
van-goods-action-icon(icon='cart-o', text='购物车', :badge='carList.length' @click="$router.push('/car')")
van-goods-action-icon(icon='shop-o', text='店铺')
van-goods-action-button(type='warning', :disabled="isAddCar",text='加入购物车',class="txtt", @click="AddCar()")
van-goods-action-button(type='danger', text='立即购买',class="txtt")
van-image-preview(v-model='isShowPreview', :images='res.wares_infoimg', :startPosition="Position", @change="onChange")
template(v-slot:index='') {{ Position + 1 }} / {{ res.wares_infoimg.length }}
</template>
<script>
import Swiper from '@com/Swiper'
import { mapActions, mapGetters } from 'vuex'
export default {
data () {
return {
id: this.$route.query.id,
list: [],
res: {},
lista: [],
show: false,
isAddCar: false,
Position: 0,
isShowPreview: false // 控制预览图是否显示
}
},
created() {
this.getCar();
this.checkCar();
this.GetInfoData();
},
methods: {
onChange(index) {
this.Position = index;
},
OpenPreview(index) {
this.Position = index;
this.isShowPreview = true;
},
// 检查该商品是否已经被添加购物车
async checkCar() {
this.isAddCar = (await this.$api.car.checkCar({
waresid: this.id
})).isAddCar
},
// 添加购物车
async AddCar() {
let res = await this.$api.car.addCar({
waresid: this.id
});
this.$toast("成功加入购物车");
this.isAddCar = true;
await this.getCar(true);
},
// 获取详情数据
async GetInfoData() {
this.res = await this.$api.home.info({
id: this.id
})
console.log(this.res)
},
showPopup() {
this.show = true;
},
...mapActions({
getCar: 'GET_CARDATA'
})
},
components: {
Swiper
},
computed: {
// 使用对象展开运算符将 getter 混入 computed 对象中
...mapGetters({
carList: 'GET_CARLIST'
})
},
}
</script>
<style scoped lang="less">
@import "~@views/Info.less";
</style>

View File

@@ -0,0 +1,93 @@
<template lang="pug">
.login
.user_header
svg.icon.logo_header(aria-hidden='true')
use(xlink:href='#icon-shouji')
p 基友汇{{ status ? '登 录' : '注 册' }}
.user_login(v-if="status")
input(v-model="loginParams.name", type="text", placeholder="请输入用户名")
input(v-model="loginParams.pwd", :type="isShowPassword ? 'password': 'text' ", placeholder="请输入密码")
svg.icon.showpwd(aria-hidden='true' @click="isShowPassword = !isShowPassword")
use(v-bind:xlink:href="isShowPassword ? '#icon-eye1':'#icon-eye'")
.user_reg(v-else)
input(type="text", v-model="add.name", placeholder="请输入用户名")
input(v-model="add.pwd", :type="isShowPassword ? 'password': 'text' ", placeholder="请输入密码")
input(v-model="add.againPwd", :type="isShowPassword ? 'password': 'text' ", placeholder="请输入确认密码")
input(v-model="add.phone", type="number", placeholder="请输入手机号")
svg.icon.showpwd(aria-hidden='true' @click="isShowPassword = !isShowPassword")
use(v-bind:xlink:href="isShowPassword ? '#icon-eye1':'#icon-eye'")
.submit(@click="status ? login() : reg() ") {{ status ? '登 录' : '注 册' }}
.action
span 首页
span(@click="status = !status") {{ status ? '注 册' : '登 录' }}
</template>
<script>
export default {
data() {
return {
status: true,
// true 闭眼false 睁眼
isShowPassword: true,
loginParams: {
name: '',
pwd: ''
},
add: {
name: '',
pwd: '',
againPwd: '',
phone: ''
}
}
},
methods: {
async login() {
let res = await this.$api.user.login(this.loginParams);
localStorage.setItem("token", res.token);
localStorage.setItem("USER_NAME", this.loginParams.name);
if (this.$route.query.hasOwnProperty("from")) {
this.$router.push(this.$route.query.from)
} else {
this.$router.push("/")
}
},
async reg() {
var phoneRole = /^[1][3,4,5,6,7,8,9][0-9]{9}$/;
var nameRole = /^[a-zA-Z0-9]{4,16}$/;
if (!nameRole.test(this.add.name)) {
this.$toast("用户名4~16字母和数字组合");
return;
}
if (!nameRole.test(this.add.pwd)) {
this.$toast("密码4~16字母和数字组合");
return;
}
if (! (this.add.pwd == this.add.againPwd) ) {
this.$toast("两次密码不一致");
return;
}
if (!phoneRole.test(this.add.phone)) {
this.$toast("手机号格式不对,请检查");
return;
}
delete this.add.againPwd;
let res = await this.$api.user.add(this.add);
this.$toast.success({
message: '注册成功',
onClose: () => this.status = true
})
}
}
}
</script>
<style lang="less" scoped>
@import "~@views/Login.less";
</style>

View File

@@ -0,0 +1,54 @@
<template lang="pug">
.me
.me_header
img(src="https://m.mi.com/static/img/avatar.76a75b8f17.png")
span {{ USERNAME }}
.me_order
.top_order
van-cell(title='我的订单', value='全部订单' is-link url="#/orderStatus?id=-1")
van-divider
.bottom_order
van-grid(:column-num="4" :border="false")
van-grid-item
router-link(to="/orderStatus?id=0")
van-image(src='/img/me_2.png')
p 待付款
van-grid-item
router-link(to="/orderStatus?id=1")
van-image(src='/img/me_5.png')
p 待发货
van-grid-item
router-link(to="/orderStatus?id=2")
van-image(src='/img/me_3.png')
p 待收货
van-grid-item
router-link(to="/orderStatus?id=3")
van-image(src='/img/me_4.png')
p 退款/售后
.setting
van-cell-group(:border="false")
van-cell(v-for="i in 5" icon="location-o" title='单元格', value='内容' is-link)
</template>
<script>
export default {
data() {
return {
USERNAME: ""
}
},
created() {
if (localStorage.getItem("USER_NAME") != null) {
this.USERNAME = localStorage.getItem("USER_NAME")
}
}
}
</script>
<style scoped lang="less">
@import "~@views/Me.less";
</style>

View File

@@ -0,0 +1,40 @@
<template lang="pug">
.type
van-nav-bar(title='分类', left-arrow)
template(#right)
van-icon(name='search', size='18')
van-tree-select(height='calc(100vh - 50px - 46px)', :items='items', :main-active-index.sync='active')
template(#content)
div(v-for="(v,i) in items")
div(v-if='active === i')
p(v-for="(j,z) in items[active].content") {{ j }}
</template>
<script>
export default {
data() {
return {
active: 0,
items: [
{ text: '小米', content: ['小米内容1','小米内容2'] },
{ text: '锤子', content: ['小米内容1','小米内容2'] },
{ text: 'iphone', content: ['小米内容1','小米内容2'] },
{ text: '三星', content: ['小米内容1','小米内容2'] },
{ text: '魅族', content: ['魅族内容'] },
{ text: '诺基亚', content: ['魅族内容'] },
{ text: '华为', content: ['华为内容'] },
],
};
},
}
</script>
<style lang="less" scoped>
.type {
.van-tree-select__content {
flex: 3 !important;
}
}
</style>

View File

@@ -0,0 +1,249 @@
<template>
<div class="order">
<van-nav-bar
title="确认订单"
left-arrow
fixed
@click-left="$router.back()"
/>
<div class="order_content">
<div class="payList">
<van-cell title="微信支付" icon="shop-o">
<template #icon>
<img src="/img/pay_wx.png" alt="">
</template>
<template #right-icon>
<van-checkbox v-model="wxpay" disabled></van-checkbox>
</template>
</van-cell>
<van-cell title="支付宝支付" icon="shop-o">
<template #icon>
<img src="/img/pay_zfb2.png" alt="">
</template>
<template #right-icon>
<van-checkbox disabled></van-checkbox>
</template>
</van-cell>
<van-cell title="银联支付" icon="shop-o">
<template #icon>
<img src="/img/pay_yl1.png" alt="">
</template>
<template #right-icon>
<van-checkbox disabled></van-checkbox>
</template>
</van-cell>
<van-cell title="花呗分期" icon="shop-o">
<template #icon>
<img src="/img/pay_antinstalment.png" alt="">
</template>
<template #right-icon>
<van-checkbox disabled></van-checkbox>
</template>
</van-cell>
</div>
<van-cell-group style="margin-top: 20px">
<van-cell title="运费" value="包邮" />
<van-cell title="电子普通发票" value="个人"/>
<van-cell title="优惠券" value="无"/>
</van-cell-group>
<div class="orderList">
<van-card
v-for="(v,i) in carLists"
:num="v.goods_num"
:price='v.wares_oldprice'
:desc='v.wares_info | subdesc'
:title='v.wares_title'
:thumb='v.wares_masterimg[0]'
/>
</div>
</div>
<van-submit-bar :price="total" button-text="去付款" @submit="showPay = true" />
<div class="popup" v-if="showPay">
<div class="payContent">
<div class="pay_title">
<img src="/img/wxPay/xx_03.jpg" alt=""/>
<img src="/img/wxPay/jftc_03.jpg" alt=""/>
<span>请输入支付密码</span>
</div>
<div class="pay_money">
<p>合肥源学思信息科技有限公司</p>
<span>{{total/100}}</span>
</div>
<div class="pay_select">
<van-cell is-link>
<template #title>
<span class="custom-title">余额</span>
</template>
<template #icon>
<img src="/img/wxPay/ye.png" alt="">
</template>
</van-cell>
</div>
<div class="input_pwd">
<van-password-input :value="value"/>
</div>
</div>
<van-number-keyboard
:show="showPay"
v-model="value"
:maxlength="6"
@blur="showPay = false"
@input="onInput"
@delete="onDelete"/>
</div>
</div>
</template>
<script>
import CarMixins from "../../mixins/car"
export default {
mixins: [CarMixins],
data() {
return {
value: '',
wxpay: true,
showPay: false,
carLists: []
}
},
async created() {
// await this.getCar();
// console.log("carList: ",this.carList)
this.GetAllOrder();
},
methods: {
async GetAllOrder() {
this.carLists = await this.$api.car.allOrder({
status: 0
});
console.log(this.carLists)
},
async onInput() {
if (this.value.length == 5) {
let goodsidArr = []
this.carLists.forEach(v => {
goodsidArr.push(v.goods_id)
});
let res = await this.$api.car.buyOrder({
goodsid: JSON.stringify(goodsidArr)
});
this.$toast.success({
message: '购买成功',
onClose: () => {
this.$router.push("/orderSuccess")
}
})
console.log(res)
}
},
onDelete() {
this.$toast('删除');
},
},
computed: {
total() {
let Total = 0;
this.carLists.forEach(v => {
Total += v.goods_price * v.goods_num
});
return Total * 100;
}
}
}
</script>
<style scoped lang="less">
.order_content {
margin-top: 45px;
margin-bottom: 50px;
}
.van-cell {
img {
width: 25px;
height: 25px;
margin-right: 10px;
}
}
.popup {
position: fixed;
width: 100%;
height: 100%;
background: #00000069;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: 99999;
.payContent {
width: 85%;
background: #f8f8f8;
padding-bottom: 15px;
margin: 0 auto;
margin-top: 17%;
.pay_title {
display: flex;
align-items: center;
height: 45px;
padding: 10px 0;
border-bottom: 1px solid #e4e2e2;
img {
&:first-child {
width: 35px;
height: 35px;
}
&:nth-child(2) {
width: 40px;
height: 40px;
margin-right: 10px;
}
}
span {
font-size: 15px;
}
}
.pay_money {
text-align: center;
padding: 10px 0;
border-bottom: 0.02667rem solid #e4e2e2;
margin: 0 15px;
p {
font-size: 16px;
margin-bottom: 8px;
}
span {
font-size: 25px;
}
}
.pay_select {
border-bottom: 0.02667rem solid #e4e2e2;
margin: 0 15px;
.van-cell {
background: #f8f8f8 !important;
}
}
}
}
</style>

View File

@@ -0,0 +1,73 @@
<template>
<div class="orderStatus">
<van-nav-bar
title="订单状态"
left-arrow
fixed
@click-left="$router.back()"
/>
<van-tabs v-model="active" style="margin-top: 45px;" :ellipsis="false" @click="TabsClick">
<van-tab :title="v.title" v-for="(v,i) in TabsArr" :key="i">
<div v-if="TabsArr[active].content.length == 0" class="nodata">暂无订单</div>
<div v-else>
<van-card
v-for="(v,i) in TabsArr[active].content"
:num="v.goods_num"
:price='v.wares_oldprice'
:desc='v.wares_info'
:title='v.wares_title'
:thumb='v.wares_masterimg[0]'
/>
</div>
</van-tab>
</van-tabs>
</div>
</template>
<script>
export default {
name: "OrderStatus",
data() {
return {
carLists: [],
TabsArr: [
{ title: '查看所有订单', id: -1, content: []},
{ title: '待付款', id: 0, content: []},
{ title: '待发货', id: 1, content: []},
{ title: '待收货', id: 2, content: []},
{ title: '退款/售后', id: 3, content: []},
],
active: parseInt(this.$route.query.id)+1 || 0
}
},
created() {
this.GetAllOrder()
},
methods: {
async GetAllOrder() {
let res = await this.$api.car.allOrder({
status: this.active
});
this.TabsArr[this.active].content = res;
},
TabsClick(index) {
this.$router.push({ query: { id: index - 1 }});
if (this.TabsArr[index].content.length == 0) {
this.GetAllOrder()
}
}
}
}
</script>
<style scoped lang="less">
.nodata {
text-align: center;
margin: 10% auto;
font-size: 14px;
color: #8d8d8d;
}
</style>

View File

@@ -0,0 +1,58 @@
<template>
<div class="OrderSuccess">
<van-nav-bar
title="支付成功"
left-arrow
fixed
@click-left="$router.back()"
/>
<div class="order_content">
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-success"></use>
</svg>
<p>恭喜支付成功</p>
<div class="line">
<van-button type="default" @click="$router.push('/')">回到首页</van-button>
<van-button type="primary" @click="$router.push('/orderStatus?id=-1')">查看订单</van-button>
</div>
</div>
</div>
</template>
<script>
export default {
name: "OrderSuccess"
}
</script>
<style scoped lang="less">
.OrderSuccess {
.order_content {
margin-top: 105px;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
.icon {
width: 60px;
height: 60px;
margin-bottom: 15px;
}
p {
font-size: 18px;
margin-bottom: 20px;
}
.line {
.van-button {
margin-right: 15px;
font-size: 15px;
&:nth-child(2) {
margin-right: 0 !important;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,42 @@
const path = require('path');
function resolve(dir) {
return path.join(__dirname, dir)
}
module.exports = {
publicPath: './',
pluginOptions: {
'style-resources-loader': {
preProcessor: 'less',
patterns: [
path.resolve(__dirname, './src/assets/less/common/_.less')
],
},
},
chainWebpack: (config) => {
// 配置别名
config.resolve.alias
.set('@', resolve('./src'))
.set('@config', resolve('./src/config'))
.set('@service', resolve('./src/service'))
.set('@utils', resolve('./src/utils'))
.set('@view', resolve('./src/view'))
.set('@http', resolve('./src/http'))
.set('@com', resolve('./src/components'))
.set('@views', resolve('./src/assets/less/views'))
.set('@common', resolve('./src/assets/less/common'))
config.module.rule('pug')
.test(/\.pug$/)
.use('pug-html-loader')
.loader('pug-html-loader')
.end()
// 移除 prefetch 插件
config.plugins.delete('prefetch')
config.plugins.delete('preload')
}
}

View File

@@ -0,0 +1,84 @@
ajax 请求是无状态
json web token
jwt
用户登录后
id + WEFREFSDGTRH4354
token: 213456YTFQER4546Y56URYESRDT6U453456576434564U7TR65ERSYH5ETT53E
{
token: '213456YTFQER4546Y56URYESRDT6U453456576434564U7TR65ERSYH5ETT53E'
}
用户访问购物车页面的时候:
id = 1
{
status: 200,
result: "ASDERBGFREWQ32456435678UYTEWERFGRTHYJ6HY5T4WEHRJTYR6"
}
{
id: 253
}
data: WEFGFWERT56467I54TRGTHYTTRY6JH65
MD5 不能反向解密,不可逆的加密算法
bmycode
lb1223444
MD5("lb1223444") = ASDFGBGREW4TE54356764765Y4ETWGSBFDGGFAESRDHTRJ64
在线MD5解密
RSA 非对称加密
公钥 哈哈哈哈
私钥
前端请求参数
{
id: 1
}
RSA 加密
rsa({
id: 1
}) = DSFBGR4356Y45657UY54T/5465UY4T3454/5Y/65U6Y576U7U
data: DSFBGR4356Y45657UY54T/5465UY4T3454/5Y/65U6Y576U7U
{
status: 200,
result: "234567UJY5TR4FGT45YU685Y4TE54676Y"
}
[
{
id: 1
}
]
vuex
vue 全局存放响应式数据和方法的地方
1state 用来存数据的data
2getters 用来读 state 数据的
3mutations 用来修改 state 数据的
4actions 提交 mutations 修改数据methods

View File

@@ -0,0 +1,62 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body {
margin: 0;
padding: 0;
}
body,html{
width: 100%;
height: 100%;
position: relative;
}
span {
transition: all 1s ease;
user-select: none;
}
</style>
</head>
<body>
</body>
<script>
var body = document.querySelector("body"), index = 0;
body.onclick = function (event) {
var x = event.x, y = event.y;
var Text = ["富强", "民主", "文明", "和谐", "自由", "平等", "公正", "法治", "爱国", "敬业", "诚信", "友善"];
var span = document.createElement("span");
span.innerText = Text[index];
span.style = `
color: hsl(${parseInt(Math.random() * 360)},100%,50%,1);
position: absolute;
opacity: 1;
left: ${x - 32}px;
top: ${y - 21}px
`;
body.appendChild(span);
setTimeout(function(){
span.style.top = `${y - 150}px`;
span.style.opacity = 0
},100)
setTimeout(function(){
body.removeChild(span)
},1100)
index++;
index >= 12 ? index = 0 : ''
}
</script>
</html>

View File

@@ -0,0 +1,70 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>tabs</title>
<style>
body, ul,li{
margin: 0;
padding: 0;
list-style: none;
}
.tabs_title {
overflow: hidden;
}
.tabs_title li {
float: left;
margin-right: 10px;
}
.title_active {
color: red;
}
.tabs_content li{
display: none;
}
.content_active {
display: block !important;
}
</style>
</head>
<body>
<ul class="tabs_title">
<li class="title_active">全部</li>
<li>规则</li>
<li>安全</li>
<li>论坛</li>
</ul>
<ul class="tabs_content">
<li class="content_active">全部的内容</li>
<li>规则的内容</li>
<li>安全的内容</li>
<li>论坛的内容</li>
</ul>
</body>
<script>
var TitleLi = document.querySelectorAll(".tabs_title li")
var ContentLi = document.querySelectorAll(".tabs_content li")
console.log(TitleLi);
TitleLi.forEach(function(v,index){
v.onmouseover = function () {
TitleLi.forEach(function(v,i){
v.className = ""
ContentLi[i].className = ""
})
v.className = "title_active"
ContentLi[index].className = "content_active"
}
})
</script>
</html>

View File

@@ -0,0 +1,3 @@
> 1%
last 2 versions
not dead

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 @@
# zaibaohe
## 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'
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,31 @@
{
"name": "zaibaohe",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
},
"dependencies": {
"amfe-flexible": "^2.2.1",
"axios": "^0.21.1",
"core-js": "^3.6.5",
"vant": "^2.12.3",
"vue": "^2.6.11",
"vue-router": "^3.2.0",
"vuex": "^3.4.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0",
"@vue/cli-plugin-vuex": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"less": "^3.0.4",
"less-loader": "^5.0.0",
"postcss-pxtorem": "^5.1.1",
"pug": "^3.0.0",
"pug-html-loader": "^1.1.5",
"pug-plain-loader": "^1.1.0",
"vue-template-compiler": "^2.6.11"
}
}

View File

@@ -0,0 +1,12 @@
module.exports = {
plugins: {
'autoprefixer': {
browsers: ['Android >= 4.0', 'iOS >= 7']
},
'postcss-pxtorem': {
rootValue: 37.5,
//这是基准值在375px的屏幕变大rem的值会变大小于这个大小元素的rem值会变小
propList: ['*']
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@@ -0,0 +1,17 @@
<!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>
</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 -->
</body>
</html>

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