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,14 @@
<template>
<div id="app">
<keep-alive>
<router-view v-if="$route.meta.isAlive"/>
</keep-alive>
<router-view v-if="!$route.meta.isAlive"/>
</div>
</template>
<style lang="less">
</style>

View File

@@ -0,0 +1,6 @@
@import "./config/color.less";
@import "./config/size.less";
@import "./mixins/mixins.less";
@import "./mixins/normalize.less";
@import "./mixins/resetUI.less";

View File

@@ -0,0 +1,3 @@
@defaultSize: 14px;
@smallSize: 12px;
@bigSize_19: 19px;

View File

@@ -0,0 +1,273 @@
.padding-lr(@px) {
padding: 0 @px;
}
.transform(@t) {
-webkit-transform: @t;
transform: @t;
}
.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 left and top
.hairline-color(@position, @color) when not (@position = right) and not (@position = bottom) {
&:before {
background-color: @color;
}
}
// 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,426 @@
/*! 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).
*/
.content {
margin-top: 45px;
margin-bottom: 50px;
}
input {
outline: none;
border: none;
}
body,h1,h2,h3,h4,h5,h6,ul,li,p{
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,49 @@
.Car {
.nodata {
margin-top: 40%;
text-align: center;
font-size: 14px;
color: #8d8d8d;
}
/deep/ .van-submit-bar {
bottom: 1.33333rem;
}
.van-checkbox-group {
margin-top: 1.22667rem;
margin-bottom: 100px;
.van-checkbox{
width: 30px;
justify-content: center;
}
.checkbox_item {
display: flex;
}
/deep/ .van-card {
padding-left: 0;
background: #fff !important;
width: calc(100vw - 40px);
}
}
.van-checkbox {
padding-left: 15px;
}
.van-submit-bar {
/deep/ .van-submit-bar__bar {
padding-left: 0 !important;
}
}
.delete {
/deep/ .van-submit-bar__bar {
justify-content: space-between !important;
padding-left: 0 !important;
}
/deep/ .van-submit-bar__text {
display: none !important;
}
}
}

View File

@@ -0,0 +1,46 @@
.home {
.search {
display: flex;
align-items: center;
justify-content: space-between;
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 45px;
padding: 0 15px;
box-sizing: border-box;
background: #fff;
z-index: 999;
.van-search {
flex: 1;
padding: 0 0.32rem !important;
}
img {
width: 0.66667rem;
height: 0.42667rem;
}
.searchbottom{
background-color: #f2f0f0;
font-size: 12px;
padding: 6px 10px;
border-radius: 12px;
color: #313133;
}
}
.content {
.van-image {
width: 0.85333rem;
}
.ad {
margin-top: 20px;
img {
width: 100%;
}
}
.hf {
width: 100%;
}
}
}

View File

@@ -0,0 +1,93 @@
.Info {
.nobuy {
background: linear-gradient(to right, #d3d3d3, #999999) !important;
}
/deep/ .van-tabs__wrap {
position: fixed;
top: 0;
z-index: 9;
width: 45%;
left: 50%;
transform: translateX(-50%);
}
.header_back {
width: 100%;
position: fixed;
height: 45px;
top: 0;
left: 0;
z-index: 2;
}
.back,
.car {
color: #fff;
border-radius: 100%;
display: inline-block;
text-align: center;
line-height: 28px;
background: rgba(0, 0, 0, 0.46);
width: 28px;
height: 28px;
position: fixed;
top: 10px;
z-index: 3;
}
.back {
left: 15px;
}
.car {
right: 15px;
}
.noback {
background: rgba(0, 0, 0, 0) !important;
color: #000 !important;
}
.wrap {
.padding-lr(15px);
.price {
color: #ff6700;
font-size: 25px;
font-weight: 700;
margin-bottom: 15px;
del {
color: rgba(0, 0, 0, .54);
font-size: 12.5px;
margin-left: 8.33px;
}
}
.title {
color: #000;
font-weight: 700;
font-size: 16px;
margin-bottom: 8.33px;
}
.desc {
margin-bottom: 6.25px;
color: #000;
font-size: 12.5px;
}
}
.info_img {
margin-bottom: 50px;
img {
width: 100%;
}
}
/deep/ .van-button__text {
font-size: 15px;
}
}

View File

@@ -0,0 +1,55 @@
.Login {
padding-left: 1.027rem;
padding-right: 1rem;
padding-top: 1.867rem;
h2 {
font-size: 0.926rem;
color: #000000;
margin-bottom: 2.707rem;
}
.user_input {
input {
width: 100%;
height: 40px;
background-repeat: no-repeat !important;
border-bottom: 0.027rem solid #ccc;
font-size: 0.333rem;
color: #c2bebe;
padding-left: 0.76rem;
background-position: left center !important;
box-sizing: border-box;
}
.user_name {
background: url("/img/name.png");
background-size: 0.347rem 0.4rem;
margin-bottom: 0.567rem;
}
.user_pwd {
background: url("/img/pwd.png");
background-size: 0.347rem 0.4rem;
margin-bottom: 0.827rem;
}
}
.submit {
width: 7.973rem;
height: 1.333rem;
background-image: linear-gradient(268deg, #42e57b 0%,#42e97d 25%,#3fee9b 50%,#37f9d6 100%),
linear-gradient(#42e97d,#42e97d);
background-blend-mode: normal,normal;
border-radius: 0.662rem;
text-align: center;
line-height: 1.333rem;
color: #fff;
font-size: 0.426rem;
margin-bottom: 0.827rem;
}
.tips {
font-size: 0.333rem;
color: #7b7a7a;
text-align: right;
span {
font-size: 0.333rem;
color: #42e97d !important;
}
}
}

View File

@@ -0,0 +1,65 @@
.header {
background-image: url(/img/me_back.png);
background-size:100%100%;
height: 200px;
position: relative;
.user {
position: absolute;
bottom: 50px;
left: 30px;
display: flex;
align-items: center;
img {
height: 45px;
margin-right: 10px;
}
span {
font-size: 18px;
}
}
}
.con{
display: flex;
flex-direction: column;
.order {
padding: 0 15px;
display: flex;
justify-content: space-between;
//height: 60px;
li {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
img {
width: 30px;
}
span {
font-size: 15px;
}
}
}
.meItem {
display: flex;
padding: 0 20px;
flex-direction: column;
li {
height: 60px;
display: flex;
align-items: center;
img {
width: 30px;
margin-right: 10px;
}
span {
font-size: 15px;
}
}
}
}

View File

@@ -0,0 +1,31 @@
.Type{
.list{
.van-tree-select{
.div{
display: flex;
flex-wrap:wrap;
.text{
width: 110px;
margin: 0 5px 20px 9px;
img{
width: 100%;
}
p{
padding-top: 10px;
font-size: 14px;
text-align: center;
}
}
}
.van-sidebar-item--select{
background-color:#fff;
}
}
}
}

View File

@@ -0,0 +1,8 @@
@import "../_.less";
.about {
h2 {
color: @themeColor;
font-size: @bigSize_19;
}
}

View File

@@ -0,0 +1,34 @@
<template>
<div class="hello">
<h1>{{ msg }}</h1>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
<style lang="less" scoped>
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,30 @@
<template lang="pug">
van-tabbar(v-model='active' route active-color="#42e97d")
van-tabbar-item(icon='home-o' to="/home" ) 首页
van-tabbar-item(icon='shopping-cart-o' to="/car" ) 购物车
van-tabbar-item(icon='apps-o' to="/type" ) 分类
van-tabbar-item(icon='contact' to="/me" ) 我的
</template>
<script>
export default {
name: 'Nav',
data() {
return {
active: 0
}
},
created() {
},
methods: {
async getIndex() {
}
},
components: {}
}
</script>
<style lang="less" scoped>
</style>

View File

@@ -0,0 +1,64 @@
<template lang="pug">
.ShopItem
van-row()
van-col(span='12' v-for="(item,index) in list" :key="index")
router-link(:to="{ path: '/info', query: { id: item.wares_id } }")
img(:src="item.wares_masterimg[0]")
h3.title {{ item.wares_title }}
p.desc {{ item.wares_info }}
p.pice {{ item.wares_oldprice }}
</template>
<script>
export default {
name: 'ShopItem',
props: {
list: {
type: Array,
default: () => []
}
},
data() {
return {}
},
created() {
},
methods: {
async getIndex() {
}
},
components: {}
}
</script>
<style lang="less" scoped>
.ShopItem {
.van-col {
text-align: center;
margin-bottom: 15px;
height: 267px;
img {
width: 100%;
}
.title {
font-size: 0.37333rem;
color: #000;
}
.desc {
color: rgba(0,0,0,0.54);
font-size: 0.32rem;
margin-top: 0.08333rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.pice {
color: #ea625b;
font-size: 0.37333rem;
margin-top: 0.13333rem;
}
}
}
</style>

View File

@@ -0,0 +1,74 @@
<template lang="pug">
.Swiper
van-swipe(:autoplay='3000', indicator-color='white', @change="onChange", :initial-swipe="current")
van-swipe-item(v-for="(item,index) in list" :key="index" @click="emitClick")
slot(:item='item')
template(#indicator='' v-if="isIndicator")
.custom-indicator {{ current + 1 }} / {{ list.length }}
</template>
<script>
export default {
name: 'Swiper',
props: {
list: {
type: Array,
default: () => []
},
isIndicator: {
type: Boolean,
default: false
},
initSwiper: {
type: Number,
default: 0
}
},
data() {
return {
current: this.initSwiper
}
},
watch: {
initSwiper(index) {
this.current = index
}
},
created() {
},
methods: {
emitClick() {
this.$emit("tap", this.current)
},
async getIndex() {
},
onChange(index) {
this.current = index;
}
},
components: {}
}
</script>
<style lang="less" scoped>
.van-swipe {
/deep/ img {
width: 100%;
}
/deep/ .custom-indicator {
position: absolute;
right: 15px;
bottom: 15px;
padding: 4px 10px;
font-size: 0.32rem;
background-color: rgba(0,0,0,.5);
color: #fff;
border-radius: 12px;
}
}
</style>

View File

@@ -0,0 +1,62 @@
import Vant from 'vant';
import 'vant/lib/index.css';
import Swiper from "@/components/Swiper";
import ShopItem from "@/components/ShopItem";
// import http from "@/service";
// import utils from "@/utils";
export default {
devBaseUrl: 'http://127.0.0.1:9090', // 开发阶段
testBaseUrl: '', // 测试阶段
prodBaseUrl: '', // 正式阶段
apiList: {
home: '/home/index',
info: '/home/info',
login: '/user/login',
add: '/user/add',
activity: '/home/activity',
CarList: '/car/getCarList',
addCar: '/car/addCar',
checkCar: '/car/checkCar',
updateCarNum: '/car/updateCarNum',
deleteCar: '/car/deleteCar',
submitCar: '/car/submitCar',
buyOrder: '/order/buyOrder',
allOrder: '/order/allOrder',
search: '/home/search',
list:'/type/list',
like: '/user/like',
likeList: '/user/likeList',
},
VuePlugins: [Vant],
VueComponents: [ Swiper, ShopItem ],
// NotVuePlugins: [
// {n: '$http', v: http},
// {n: '$utils', v: 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;
default:
break;
}
},
rsa_public_key: `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9eo8WIbWS5Yql06imlhrW0ZXh
faivPavdULvYLIxIKyUaOwMPFrPuHqqBNGnYOpiPHAKL+zxk2j4u+6jhB6VK1SOD
ccSLxIRxd0HmSDS+hBzYRf4vKc8BLlhMrYhnLmcxCc+PJIIa4DfCZnu8FfQlu/5L
ljjpYN9kHOpHAT+xpQIDAQAB
-----END PUBLIC KEY-----`
}

View File

@@ -0,0 +1,100 @@
import axios from "axios";
import rsa from "@/utils/rsa"
import config from "@/config"
import {Toast, Dialog} from 'vant';
export default class Http {
constructor() {
this.instance = axios.create({
baseURL: config.CheckBaseUrl(),
timeout: 10000,
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({
data: new rsa(config).PublicKeyEncryption(params.data),
token: localStorage.getItem("token")
}, params.headers)
})
}
async post(params) {
return await this.instance.post(params.url, null,{
headers: Object.assign({
data: new rsa(config).PublicKeyEncryption(params.data),
token: localStorage.getItem("token")
}, params.headers)
})
}
interceptors() {
// 添加请求拦截器
this.instance.interceptors.request.use(function (config) {
Toast.loading({
duration: 0,
message: '加载中...'
})
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
this.instance.interceptors.response.use(function (response) {
if (response.data.hasOwnProperty("result") && response.data.result != null) {
response.data.result = new rsa(config).PublicKeyDecryption(response.data.result)
}
Toast.clear()
switch (response.data.status) {
case 200:
return response.data.result
break;
case 501:
Dialog.alert({
title: '温馨提示',
message: response.data.message,
}).then(() => {
location.href = "/#/login"
});
break;
case 500:
Toast.fail({
duration: 3000,
message: response.data.message
})
throw new Error(response.data.message);
break;
case 404:
Toast.fail({
duration: 3000,
message: response.data.message
})
throw new Error(response.data.message);
break;
default:
break;
}
return response.data;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
}
}

View File

@@ -0,0 +1,27 @@
import "amfe-flexible"
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import config from "@/config";
import http from "@/service";
import utils from "@/utils";
Vue.config.productionTip = false
// 初始化vue插件
config.VuePlugins.forEach(v => Vue.use(v));
config.VueComponents.forEach(v => Vue.component(v.name, v));
Vue.prototype.$http = http;
Vue.prototype.$utils = utils;
// 挂载自定义方法到vue实例上,实现全局访问
// config.NotVuePlugins.forEach(v => Vue.prototype[v["n"]] = v["v"]);
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')

View File

@@ -0,0 +1,169 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
}
const routes = [
{
path: '/login',
name: 'login',
component: () => import(/* webpackChunkName: "login" */ '../views/User/Login'),
meta: {
isLogin: false,
title: '登录',
isAlive: false
}
},
{
path: '/reg',
name: 'reg',
component: () => import(/* webpackChunkName: "reg" */ '../views/User/Reg'),
meta: {
isLogin: false,
title: '注册',
isAlive: false
}
},
{
path: '/',
redirect: '/home',
component: () => import(/* webpackChunkName: "layout" */ '../views/layout'),
children: [
{
path: '/home',
name: 'home',
component: () => import(/* webpackChunkName: "home" */ '../views/Home'),
meta: {
isLogin: true,
title: '首页',
isAlive: true
}
},
{
path: '/car',
name: 'car',
component: () => import(/* webpackChunkName: "car" */ '../views/Car'),
meta: {
isLogin: true,
title: '购物车',
isAlive: false
}
},
{
path: '/type',
name: 'type',
component: () => import(/* webpackChunkName: "type" */ '../views/Type'),
meta: {
isLogin: true,
title: '分类',
isAlive: false
}
},
{
path: '/me',
name: 'me',
component: () => import(/* webpackChunkName: "me" */ '../views/Me'),
meta: {
isLogin: true,
title: '我的',
isAlive: false
}
},
]
},
{
path: '/activity_info',
name: 'activity_info',
component: () => import(/* webpackChunkName: "ActivityInfo" */ '../views/ActivityInfo'),
meta: {
isLogin: true,
title: '活动详情',
isAlive: false
}
},
{
path: '/info',
name: 'info',
component: () => import(/* webpackChunkName: "Info" */ '../views/Info'),
meta: {
isLogin: true,
title: '详情',
isAlive: false
}
},
{
path: '/search',
name: 'search',
component: () => import(/* webpackChunkName: "Info" */ '../views/Search'),
meta: {
isLogin: true,
title: '搜索',
isAlive: false
}
},
{
path: '/order',
name: 'ConfirmOrder',
component: () => import(/* webpackChunkName: "ConfirmOrder" */ '../views/order/ConfirmOrder'),
meta: {
isLogin: true,
title: '确认订单',
isAlive: false
}
},
{
path: '/orderStatus',
name: 'OrderStatus',
component: () => import(/* webpackChunkName: "OrderStatus" */ '../views/order/OrderStatus'),
meta: {
isLogin: true,
title: '确认订单',
isAlive: false
}
},
{
path: '/like',
name: 'like',
component: () => import(/* webpackChunkName: "like" */ '../views/like'),
meta: {
isLogin: true,
title: '收藏',
isAlive: false
}
}
]
const router = new VueRouter({
routes
})
// 实现页面的权限控制(有些页面需要登录才可以访问)
router.beforeEach((to, from, next) => {
document.title = to.meta.title
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 @@
import Http from "@/http";
import config from "@/config"
export default class UserService {
async login(data = {}, headers = {}) {
return await (new Http()).post({
url: config.apiList.login,
data: data,
headers: headers
})
}
async add(data = {}, headers = {}) {
return await (new Http()).post({
url: config.apiList.add,
data: data,
headers: headers
})
}
}

View File

@@ -0,0 +1,62 @@
import Http from "@/http";
import config from "@/config"
export default class carService {
async CarList(data = {}, headers = {}) {
let res = await (new Http()).post({
url: config.apiList.CarList,
data: data,
headers: headers
});
if (!Array.isArray(res)) {
res = []
} else {
res.forEach(v => {
v.wares_masterimg = JSON.parse(v.wares_masterimg)
v.isEdit = true
})
}
return res;
}
async addCar(data = {}, headers = {}) {
return await (new Http()).post({
url: config.apiList.addCar,
data: data,
headers: headers
})
}
async submitCar(data = {}, headers = {}) {
return await (new Http()).post({
url: config.apiList.submitCar,
data: data,
headers: headers
})
}
async updateCarNum(data = {}, headers = {}) {
return await (new Http()).post({
url: config.apiList.updateCarNum,
data: data,
headers: headers
})
}
async deleteCar(data = {}, headers = {}) {
return await (new Http()).post({
url: config.apiList.deleteCar,
data: data,
headers: headers
})
}
async checkCar(data = {}, headers = {}) {
return await (new Http()).post({
url: config.apiList.checkCar,
data: data,
headers: headers
})
}
}

View File

@@ -0,0 +1,15 @@
// 统一导出
import indexService from "@/service/indexService";
import carService from "@/service/carService";
import userService from "@/service/UserService";
import orderService from "@/service/orderService";
import likeService from "@/service/likeService";
export default {
index: new indexService(),
car: new carService(),
user: new userService(),
order: new orderService(),
like: new likeService(),
}

View File

@@ -0,0 +1,59 @@
import Http from "@/http";
import config from "@/config"
export default class indexService {
async home(data = {}, headers = {}) {
let res = await (new Http()).post({
url: config.apiList.home,
data: data,
headers: headers
})
res.forEach(v => {
v.wares_masterimg = JSON.parse(v.wares_masterimg)
});
return res;
}
async info(data = {}, headers = {}) {
let res = await (new Http()).post({
url: config.apiList.info,
data: data,
headers: headers
})
res.wares_infoimg = JSON.parse(res.wares_infoimg)
res.wares_masterimg = JSON.parse(res.wares_masterimg)
return res;
}
async activity(data = {}, headers = {}) {
let res = await (new Http()).post({
url: config.apiList.activity,
data: data,
headers: headers
})
res.forEach(v => {
v.wares_masterimg = JSON.parse(v.wares_masterimg)
});
return res;
}
async search(data = {}, headers = {}) {
let res = await (new Http()).post({
url: config.apiList.search,
data: data,
headers: headers
})
res.forEach(v => {
v.wares_masterimg = JSON.parse(v.wares_masterimg)
});
return res;
}
async list(data = {}, headers = {}) {
return await (new Http()).post({
url: config.apiList.list,
data: data,
headers: headers
})
}
}

View File

@@ -0,0 +1,31 @@
import Http from "@/http";
import config from "@/config"
export default class likeService {
async like(data = {}, headers = {}) {
return await (new Http()).post({
url: config.apiList.like,
data: data,
headers: headers
})
}
async likeList(data = {}, headers = {}) {
let res = await (new Http()).post({
url: config.apiList.likeList,
data: data,
headers: headers
})
if (!Array.isArray(res)) {
res = []
} else {
res.forEach(v => {
v.wares_masterimg = JSON.parse(v.wares_masterimg)
v.isEdit = true
})
}
return res
}
}

View File

@@ -0,0 +1,32 @@
import Http from "@/http";
import config from "@/config"
export default class orderService {
async buyOrder(data = {}, headers = {}) {
return await (new Http()).post({
url: config.apiList.buyOrder,
data: data,
headers: headers
})
}
async allOrder(data = {}, headers = {}) {
let res = await (new Http()).post({
url: config.apiList.allOrder,
data: data,
headers: headers
})
if (!Array.isArray(res)) {
res = []
} else {
res.forEach(v => {
v.wares_masterimg = JSON.parse(v.wares_masterimg)
v.isEdit = true
})
}
return res
}
}

View File

@@ -0,0 +1,4 @@
export default {
getCarList: (state) => state.car.carList,
getTheme: (state) => state.setting.theme
}

View File

@@ -0,0 +1,20 @@
import Vue from 'vue'
import Vuex from 'vuex'
import common from "./modules/public";
import car from "./modules/car";
import setting from "./modules/setting";
import getters from "./getters";
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
common,
car,
setting
},
getters
})
export default store

View File

@@ -0,0 +1,26 @@
import http from "@/service";
export default {
state: {
carList: []
},
getters: {},
mutations: {
SET_LIST(state, data) {
state.carList = data;
}
},
actions: {
// 获取购物车商品的数量
async HttpCarList({ commit }) {
let res = await http.car.CarList();
commit("SET_LIST", res)
},
// 商品添加购物车
async addCarList({ commit }, params) {
let res = await http.car.addCar(params)
}
}
}

View File

@@ -0,0 +1,6 @@
export default {
state: {},
getters: {},
mutations: {},
actions: {}
}

View File

@@ -0,0 +1,8 @@
export default {
state: {
theme: "red"
},
getters: {},
mutations: {},
actions: {}
}

View File

@@ -0,0 +1,14 @@
class utils {
test() {
console.log("工具函数");
}
checkPhone(phoneNumber) {
return /^[1][3,4,5,7,8,9][0-9]{9}$/.test(phoneNumber);
}
}
export default new utils();

View File

@@ -0,0 +1,18 @@
import NodeRSA from "node-rsa";
class Rsa {
constructor (config) {
this.public_key = config.rsa_public_key
}
// 公钥加密
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,37 @@
<template lang="pug">
.ActivityInfo
van-nav-bar(fixed :title='title', left-arrow='', @click-left='$router.back()')
.content
ShopItem(:list="list")
</template>
<script>
export default {
name: 'ActivityInfo',
data() {
return {
title: '',
list: []
}
},
created() {
this.title = this.$route.query.title;
this.getActivity();
},
methods: {
async getActivity() {
this.list = await this.$http.index.activity({
id: this.$route.query.id
});
}
},
components: {}
}
</script>
<style lang="less" scoped>
.content {
margin-bottom: 0 !important;
}
</style>

View File

@@ -0,0 +1,132 @@
<template lang="pug">
.Car
van-nav-bar(title='购物车', fixed ,:right-text="isDelete ? '管理': '删除' ", left-arrow='', @click-left='$router.back()', @click-right='onClickRight')
van-checkbox-group(v-if="carList.length != 0" v-model='YouSelectResult', ref='checkboxGroup' @change="SelectChange")
div(v-for="(v,i) in carList" :key="i" class="checkbox_item")
van-checkbox(:name='v.car_id')
van-card(:price='v.wares_oldprice', :desc='v.wares_info', :title='v.wares_title', :thumb='v.wares_masterimg[0]')
template(#num v-if="v.isEdit")
span.nums(@click="ShowEdit(v)") x{{v.car_num}}
template(#num v-else)
van-stepper(v-model="v.car_num" @change="updateCarNum" :name="v.car_id")
.nodata(v-else) 暂无数据
van-submit-bar(:price='totalMoney', @submit='', :class="isDelete ? '' : 'delete' ")
van-checkbox(v-model='checked' @click="checkAll") 全选
template(#button v-if="isDelete" )
van-button(round='', type='danger' @click="submitCarShop") 提交订单
template(#button v-else)
van-button(round='', type='danger' @click="deleteCarItem") 删 除
</template>
<script>
import {mapGetters, mapMutations, mapActions} from 'vuex'
export default {
name: 'Car',
data() {
return {
checked: false,
isDelete: true, // false显示删除 true不显示删除
YouSelectResult: []
}
},
async created() {
await this.carData();
console.log("carList: ", this.carList)
},
mounted() {
document.querySelector("html").addEventListener("touchstart", (e) => {
if (!e.target.className.includes("van-stepper") && e.target.className != "nums") {
this.carList.forEach(v => {
v.isEdit = true
})
}
})
},
methods: {
async updateCarNum(value, del) {
await this.$http.car.updateCarNum({
carid: del.name,
quantity: value
});
},
async deleteCarItem() {
await this.$http.car.deleteCar({
carid: this.YouSelectResult
});
await this.carData();
this.checked = false
},
async submitCarShop() {
let params = []
this.YouSelectResult.forEach(v => {
this.carList.forEach(k => {
if (v == k.car_id) {
params.push({
waresid: k.wares_id,
goodsnum: k.car_num,
goodsprice: k.wares_oldprice,
})
}
})
})
await this.$http.car.submitCar({
carList: params
});
this.$router.push("/order")
},
SelectChange() {
if (this.YouSelectResult.length == this.carList.length) {
this.checked = true
} else {
this.checked = false
}
console.log("YouSelectResult: ", this.YouSelectResult)
},
checkAll() {
if (this.checked) {
this.$refs.checkboxGroup.toggleAll(true);
} else {
this.$refs.checkboxGroup.toggleAll(false);
}
},
ShowEdit(v) {
v.isEdit = false
},
async getIndex() {
},
onClickRight() {
this.isDelete = !this.isDelete
},
...mapActions({
carData: "HttpCarList"
}),
},
components: {},
computed: {
totalMoney() {
let total = 0;
this.YouSelectResult.forEach(v => {
this.carList.forEach(k => {
if (v == k.car_id) {
total += k.car_num * k.wares_oldprice
}
})
})
return total * 100
},
...mapGetters({
carList: "getCarList"
})
}
}
</script>
<style lang="less" scoped>
@import "~@page/Car.less";
</style>

View File

@@ -0,0 +1,82 @@
<template lang="pug">
.home
.search
img(src="/img/logo.png")
van-search(shape='round', v-model="getValue" placeholder='请输入搜索关键词', type='text')
.searchbottom(@click='searchinfo()') 搜索
.content
Swiper(:list="SwiperList")
template(v-slot:default='{ item }')
img(:src="item" )
van-grid(:border="false")
van-grid-item(v-for="(item,index) in typeList"
:text='item.title' :key="index"
:to="{ path: 'activity_info', query: { id: item.id, title: item.title }}")
template(v-slot:icon)
van-image(:src='item.icon')
van-row.ad
van-col(span='12')
img(src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/32b5d24417b673008f386592c4d17046.jpg?thumb=1&w=358&h=508")
van-col(span='12')
van-row
van-col(span='24')
img(src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/1480d862e1f5a41e5adae8c030eef511.jpg?thumb=1&w=358&h=252")
van-col(span='24')
img(src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/1480d862e1f5a41e5adae8c030eef511.jpg?thumb=1&w=358&h=252")
img.hf(src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/3ca39ff880dfbcbc0e45314782c39fff.jpg?thumb=1&w=720&h=280")
ShopItem(:list="list")
</template>
<script>
export default {
name: 'Home',
data() {
return {
getValue:'',
list: [],
SwiperList: [
'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/bb4a8b7d9e77567c7330776a866e717f.jpg?thumb=1&w=720&h=360',
'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/0b2bb13c396cc6205dd91da3a91a275a.jpg?thumb=1&w=720&h=360',
'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/69d599cf6d4f0188312f4386b8bfd093.jpeg?thumb=1&w=720&h=360'
],
typeList: [
{ title: '限时白嫖', icon: '/img/type_1.png', id: 1 },
{ title: '新品推荐', icon: '/img/type_2.png', id: 2 },
{ title: '低价高配', icon: '/img/type_3.png', id: 3 },
{ title: '超值特卖', icon: '/img/type_4.png', id: 4 },
],
}
},
created() {
this.getIndex();
},
methods: {
async getIndex() {
let res = await this.$http.index.home();
this.list = res;
console.log(this.list);
},
async searchinfo() {
await this.$router.push({
path:'/Search',
query :{
keyword:this.getValue
}
});
console.log(this.getValue);
}
},
components: {
}
}
</script>
<style lang="less" scoped>
@import "~@page/Home.less";
</style>

View File

@@ -0,0 +1,142 @@
<template lang="pug">
.Info
.header_back(:style="{ backgroundColor: `rgba(255, 255, 255, ${opacity})` }")
van-icon(name='arrow-left' class="back" :class="{ noback: isShow }" size="16" @click='$router.back()')
van-icon(name='shopping-cart-o' class="car" :class="{ noback: isShow }" size="16")
van-tabs(v-model='active', scrollspy='', sticky='',
:line-width=" width + 'px' ",
ref="infoTabs",
background="rgba(255, 255, 255, 0)")
van-tab
template(#title v-if="isShow") 商品
Swiper(:list="infoData.wares_masterimg"
:init-swiper="currentIndex",
:isIndicator="true"
@tap="ShowImagePreview")
template(v-slot:default='{ item }')
img(:src="item")
.wrap
.price
| ¥{{infoData.wares_oldprice}}
del ¥{{infoData.wares_nowprice}}
.title {{infoData.wares_title}}
.desc {{infoData.wares_info}}
van-tab
template(#title v-if="isShow") 详情
.info_img
img(v-for="i,index in infoData.wares_infoimg" :src="i" :key="index" @click="showInfo(index)")
van-goods-action
van-goods-action-icon(icon='shop-o', text='收藏' @click="like()")
van-goods-action-icon(icon='cart-o', text='购物车', :badge='carList.length', to="/car")
van-goods-action-button(:class=" isAddCar ? 'nobuy' : '' " type='warning', text='加入购物车' @click="isAddCar ? '' : add() ")
van-goods-action-button(type='danger', text='立即购买')
</template>
<script>
import { ImagePreview } from 'vant';
import { mapGetters, mapMutations, mapActions } from 'vuex'
export default {
name: 'Info',
data() {
return {
isShow: false,
width: 0, // 15
opacity: 0,
infoData: {},
active: 0,
currentIndex: 0,
isAddCar: false, // true 已添加购物车,false 没有添加购物车
}
},
created() {
this.getCheckCar();
this.carData();
this.getInfo();
},
mounted() {
window.addEventListener('scroll', this.handleScroll)
},
beforeDestroy() {
window.removeEventListener("scroll", this.handleScroll)
},
methods: {
...mapActions({
carData: "HttpCarList",
addCar: 'addCarList'
}),
// ...mapMutations({
// setCount: "SET_COUNT"
// }),
async add() {
await this.addCar({
waresid: this.$route.query.id
});
await this.carData();
this.isAddCar = true;
},
async like() {
await this.$http.like.like({
shopid: this.$route.query.id
});
},
async getCheckCar() {
let res = await this.$http.car.checkCar({
waresid: this.$route.query.id
});
this.isAddCar = res.isAddCar
console.log("getCheckCar: ",res)
},
ShowImagePreview(index) {
ImagePreview({
images: this.infoData.wares_masterimg,
startPosition: index,
onChange: (index) => {
this.currentIndex = index;
}
});
},
showInfo(index) {
ImagePreview({
images: this.infoData.wares_infoimg,
startPosition: index
});
},
async getInfo() {
this.infoData = await this.$http.index.info({
id: this.$route.query.id
});
},
handleScroll() {
let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
var top = scrollTop / 412
this.opacity = top
if (top >= 0.5) {
this.isShow = true;
this.width = 15;
} else {
this.isShow = false;
this.width = 0;
}
this.$refs.infoTabs.resize();
}
},
components: {},
computed: {
...mapGetters({
carList: "getCarList",
theme: "getTheme"
})
}
}
</script>
<style lang="less" scoped>
@import "~@page/Info.less";
</style>

View File

@@ -0,0 +1,54 @@
<template lang="pug">
.Me
.header
.user
img(src='/img/user_head.png')
span 编码猿
.con
ul.order
router-link(v-for="(v,i) in status" tag="li" :to="{ path: 'orderStatus', query: { id: i}}")
img(:src='v.img')
span {{v.text}}
ul.meItem
router-link(v-for="(v,i) in meItem" tag="li" :to="{path:v.path}")
img(:src='v.img')
span {{v.text}}
</template>
<script>
export default {
name: 'Me',
data() {
return {
status: [
{ text: '全部', id: -1, img: '/img/me_1.png' },
{ text: '待付款', id: 0, img: '/img/me_2.png' },
{ text: '待发货', id: 1, img: '/img/me_3.png' },
{ text: '待收货', id: 2, img: '/img/me_4.png' },
{ text: '退款/售后', id: 3, img: '/img/me_5.png' },
],
meItem:[
{ text: '优惠券',img:'/img/me_address.png', path: '' },
{ text: '红包',img:'/img/me_address.png', path: '' },
{ text: '收货地址',img:'/img/me_address.png', path: '' },
{ text: '附近门店',img:'/img/type_1.png', path: '' },
{ text: '我的收藏',img:'/img/me_like.png', path: 'like' },
]
}
},
created() {
},
methods: {
async getIndex() {
}
},
components: {}
}
</script>
<style lang="less" scoped>
@import "~@page/Me.less";
</style>

View File

@@ -0,0 +1,42 @@
<template lang="pug">
.Search
van-nav-bar(fixed , :title='this.$route.query.keyword', left-arrow='', @click-left="$router.go(-1)")
.content
ShopItem(:list="list")
</template>
<script>
export default {
name: 'Search',
data() {
return {
list: []
}
},
created() {
this.getSearch();
},
methods: {
async getSearch() {
this.list = await this.$http.index.search({
keyword: this.$route.query.keyword
// keyword:"华为"
});
// console.log(res);
}
},
components: {}
}
</script>
<style lang="less" scoped>
.Search{
.content{
margin-bottom: 0 !important;
.nodata{
font-size: 20px;
}
}
}
</style>

View File

@@ -0,0 +1,71 @@
<template lang="pug">
.Type
van-search(placeholder="请输入搜索关键词")
.list
van-tree-select(
@click-nav="onNavClick",
height="calc(100vh - 100px)",
:items="items",
:main-active-index.sync="active"
)
template(#content)
.div(v-if="active === active")
.text(v-for="(v, i) in items[active].content", :key="i")
img(:src="v.wares_masterimg")
p {{ v.wares_title }}
</template>
<script>
export default {
name: "Type",
created() {
if (this.$route.query.hasOwnProperty("id")) {
this.active = Number(this.$route.query.id);
}
this.getlist();
},
data() {
return {
active: 0,
items: [
{ text: "小米", content: [] },
{ text: "魅族", content: [] },
{ text: "华为", content: [] },
{ text: "iphone", content: [] },
{ text: "三星", content: [] },
{ text: "锤子", content: [] },
{ text: "诺基亚", content: [] },
],
};
},
methods: {
onNavClick() {
this.getlist();
},
async getlist() {
this.$router.push({
query: {
id: this.active,
},
});
if (this.items[this.active].content.length == 0){
let res = await this.$http.index.list({
typename: this.items[this.active].text,
});
this.items[this.active].content = [
...res,
...this.items[this.active].content
]
}
},
},
components: {},
};
</script>
<style lang="less" scoped>
@import "~@page/Type.less";
</style>

View File

@@ -0,0 +1,100 @@
<template lang="pug">
.Login
h2 {{ status ? '登 录' : '注 册' }}
.user_input
.login(v-if="status" )
input.user_name(placeholder="用户名" type="text" v-model="loginParams.name")
input.user_pwd(placeholder="密码" type="password" v-model="loginParams.pwd")
.reg(v-else)
input.user_pwd(placeholder="手机号" type="number" v-model="regParams.phone")
input.user_name(placeholder="用户名" type="text" v-model="regParams.name")
input.user_pwd(placeholder="密码" type="password" v-model="regParams.pwd")
.submit(@click="status ? UserLogin() : UserReg()") {{ status ? '登 录' : '注 册' }}
.tips
| {{ status ? '没有账号?' : '已有账号?' }}
span(@click="status = !status") 立刻{{ status ? '注册' : '登录' }}
</template>
<script>
export default {
name: 'Login',
data() {
return {
status: true, // true 登录 false 注册
loginParams: {
name: 'lb',
pwd: '1234567890'
},
regParams: {
name: '',
pwd: '',
phone: ''
}
}
},
created() {
},
methods: {
async UserLogin() {
if (this.loginParams.name.length === 0) {
this.$toast("用户名不能为空")
return false;
}
if (this.loginParams.pwd.length === 0) {
this.$toast("密码不能为空")
return false;
}
let res = await this.$http.user.login(this.loginParams);
console.log(res)
localStorage.setItem("token", res.token)
this.$toast.success({
message: '恭喜,登录成功!',
forbidClick: true,
onClose: () => {
this.$router.replace("/home")
}
})
},
async UserReg() {
if (!this.$utils.checkPhone(this.regParams.phone)) {
this.$toast("手机号不正确")
return false;
}
if (this.regParams.name.length === 0) {
this.$toast("用户名不能为空")
return false;
}
if (this.regParams.pwd.length === 0) {
this.$toast("密码不能为空")
return false;
}
let res = await this.$http.user.add(this.regParams);
this.$toast.success({
message: '恭喜,注册成功!',
forbidClick: true,
onClose: () => {
this.loginParams.name = this.regParams.name
this.loginParams.pwd = this.regParams.pwd
this.status = true
}
})
}
},
components: {}
}
</script>
<style lang="less" scoped>
@import "~@page/Login.less";
</style>

View File

@@ -0,0 +1,23 @@
<template lang="pug">
.Reg
h2 Reg
</template>
<script>
export default {
name: 'Reg',
created() {
},
methods: {
async getIndex() {
}
},
components: {}
}
</script>
<style lang="less" scoped>
@import "~@page/Reg.less";
</style>

View File

@@ -0,0 +1,27 @@
<template lang="pug">
.layout
router-view
Nav
</template>
<script>
import Nav from "@/components/Nav";
export default {
name: 'layout',
created() {
},
methods: {
async getIndex() {
}
},
components: {
Nav
}
}
</script>
<style lang="less" scoped>
</style>

View File

@@ -0,0 +1,34 @@
<template lang="pug">
.like
van-nav-bar(title='收藏', fixed ,left-arrow='', @click-left='$router.back()')
.content
ShopItem(:list="List" v-if="List.length != 0" )
</template>
<script>
export default {
name: "like",
data() {
return {
List:[]
}
},
methods: {
async likeList() {
this.List = await this.$http.like.likeList();
console.log(this.List);
}
},
created() {
this.likeList()
}
}
</script>
<style lang="less" scoped>
.content {
margin-top: 45px;
}
</style>

View File

@@ -0,0 +1,77 @@
<template lang="pug">
.ConfirmOrder
van-nav-bar(title='确认订单', fixed, left-arrow='', @click-left='$router.back()')
.content
van-contact-card(type='edit', name='张三', tel='15155145354')
van-card(:num='v.goods_num',
v-for="(v,i) in order" :key="i"
:price='v.wares_oldprice',
:desc='v.wares_info',
:title='v.wares_title',
:thumb='v.wares_masterimg[0]'
)
van-checkbox-group(v-model='result')
van-cell-group
van-cell(v-for='(item, index) in list', clickable='', :key='index', :title='item.title')
template(#right-icon='')
van-checkbox(:name='item.id', ref='checkboxes' disabled)
van-submit-bar(:price='totalMoney', button-text='付款', @submit='onSubmit')
</template>
<script>
export default {
name: 'ConfirmOrder',
data() {
return {
result: [1],
list: [
{id: 1, title: '支付宝支付', isCheck: true},
{id: 2, title: '微信支付', isCheck: false},
],
order: []
}
},
created() {
this.getOrder();
},
methods: {
async onSubmit() {
var goodsId = [];
this.order.forEach(k => {
goodsId.push(k.goods_id);
})
await this.$http.order.buyOrder({
goodsid: goodsId
});
this.$router.push("/orderStatus")
},
async getOrder() {
let res = await this.$http.order.allOrder({
status: 0
});
this.order = res;
console.log(res)
}
},
components: {},
computed: {
totalMoney() {
let total = 0;
this.order.forEach(k => {
total += k.goods_num * k.wares_oldprice
})
return total * 100
},
}
}
</script>
<style lang="less" scoped>
@import "~@page/ConfirmOrder.less";
</style>

View File

@@ -0,0 +1,67 @@
<template lang="pug">
.OrderStatus
van-nav-bar(title='订单状态', fixed ,left-arrow='', @click-left='$router.back()')
.content
van-tabs(v-model='active' @click="getOrder")
van-tab(:title='item.text' v-for="(item,index) in status" :key="index")
div(v-if="item.content.length != 0")
van-card(:num='v.goods_num',
v-for="(v,i) in item.content" :key="i"
:price='v.wares_oldprice',
:desc='v.wares_info',
:title='v.wares_title',
:thumb='v.wares_masterimg[0]'
)
.nodata(v-else) 暂无数据
</template>
<script>
export default {
name: 'OrderStatus',
data() {
return {
active: 0,
status: [
{ text: '全部', id: -1, content: [] },
{ text: '待付款', id: 0, content: [] },
{ text: '待发货', id: 1, content: [] },
{ text: '待收货', id: 2, content: [] },
{ text: '退款/售后', id: 3, content: [] },
]
}
},
created() {
if (this.$route.query.hasOwnProperty("id")) {
this.active = Number(this.$route.query.id)
}
this.getOrder();
},
methods: {
async getOrder() {
this.$router.push({
query: {
id: this.active
}
})
if (this.status[this.active].content.length == 0) {
let res = await this.$http.order.allOrder({
status: this.status[this.active].id
});
this.status[this.active].content = [
...res,
...this.status[this.active].content
]
console.log(this.status[this.active])
}
}
},
components: {}
}
</script>
<style lang="less" scoped>
@import "~@page/OrderStatus.less";
</style>