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,21 @@
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

View File

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

View File

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

View File

@@ -0,0 +1,46 @@
<template lang="pug">
#app
van-nav-bar(:title='navTitle',
fixed
left-text='返回',
right-text='按钮',
left-arrow='')
router-view
van-tabbar(v-model='active' @change="onChange")
van-tabbar-item(v-for="(item,index) in TabBar"
:icon='item.icon'
:to="item.href"
:key="index") {{item.title}}
</template>
<script>
export default {
data() {
return {
active: 0,
navTitle: '首页',
TabBar: [
{ title: '首页', icon: 'home-o', href: '/' },
{ title: '分类', icon: 'search', href: '/class' },
{ title: '购物车', icon: 'friends-o', href: '/car' },
{ title: '我的', icon: 'setting-o', href: '/me' },
]
}
},
methods: {
onChange(index) {
this.navTitle = this.TabBar[index].title
this.active = index
}
}
}
</script>
<style lang="less">
.content {
margin-top: 46px;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,31 @@
{
"name": "shopfont",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "vue-cli-service serve",
"build": "vue-cli-service build"
},
"dependencies": {
"axios": "^0.19.2",
"core-js": "^3.6.4",
"node-rsa": "^1.0.8",
"vant": "^2.2.15",
"vue": "^2.6.11",
"vue-router": "^3.1.6",
"vuex": "^3.1.3"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.3.0",
"@vue/cli-plugin-router": "~4.3.0",
"@vue/cli-plugin-vuex": "~4.3.0",
"@vue/cli-service": "~4.3.0",
"less": "^3.11.1",
"less-loader": "^5.0.0",
"pug-html-loader": "^1.1.5",
"pug-plain-loader": "^1.0.0",
"style-resources-loader": "^1.3.3",
"stylus-loader": "^3.0.2",
"vue-template-compiler": "^2.6.11"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 703 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 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: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<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>

View File

@@ -0,0 +1,73 @@
<template lang="pug">
#app
router-view(@hiddenNav="hiddenNabBar"
@showNab="showNabBar"
@hiddenTb="hiddenShowTabbar"
@showTb="ShowTabbar")
van-tabbar(v-if="isShowTabbar" v-model='active' @change="onChange" active-color="#F22E00")
van-tabbar-item(v-for="(item,index) in TabBar"
:icon='item.icon'
:to="item.href"
:key="index") {{item.title}}
</template>
<script>
export default {
data() {
return {
isShowNavBar: true,
isShowTabbar: true,
active: 0,
navTitle: '首页',
TabBar: [
{ title: '首页', icon: 'home-o', href: '/' },
{ title: '分类', icon: 'search', href: '/class' },
{ title: '购物车', icon: 'shopping-cart-o', href: '/car' },
{ title: '我的', icon: 'friends-o', href: '/me' },
]
}
},
methods: {
onChange(index) {
this.navTitle = this.TabBar[index].title
this.active = index
},
hiddenNabBar() {
this.isShowNavBar = false
},
showNabBar() {
this.isShowNavBar = true
},
hiddenShowTabbar() {
this.isShowTabbar = false
},
ShowTabbar() {
this.isShowTabbar = true
}
}
}
</script>
<style lang="less">
html,
body,
#app,
.class{
height: 100%;
}
.login{
height: 100%;
}
.Reg{
height: 100%;
}
.content {
padding-top: 46px;
padding-bottom: 50px;
}
</style>

View File

@@ -0,0 +1,3 @@
@import "./tpl/color";
@import "./tpl/mixins";
@import "./tpl/normalize";

View File

@@ -0,0 +1,47 @@
.car {
.van-submit-bar {
bottom: 50px !important;
}
.van-checkbox-group {
display: flex;
align-items: center;
padding-left: 18px;
flex-direction: column;
.item {
width: 100%;
display: flex;
align-items: center;
}
}
.cart_action {
position: fixed;
width: 100%;
height: 50px;
background: #fff;
display: flex;
bottom: 50px;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
padding-left: 18px;
padding-right: 10px;
.van-button--danger {
width: 108px;
font-size: 16px;
margin-left: 19px;
}
.right {
em {
font-style: normal;
color: #ee0924;
}
}
}
.van-card {
background: #fff !important;
width: 93%;
}
.content {
padding-bottom: 100px!important;
}
}

View File

@@ -0,0 +1,15 @@
.class {
.content {
box-sizing: border-box;
height: 100%;
.van-tree-select {
height: 100%;
.van-tree-select__content {
flex: 3 !important;
}
}
.c_t {
width: 80px;
}
}
}

View File

@@ -0,0 +1,42 @@
.home {
.type_img {
width: 40px;
height: 40px;
margin-bottom: 12px;
}
.type_text {
font-size: 14px;
color: #8d8d8d;
}
.search {
display: flex;
justify-content: space-between;
align-items: center;
position: fixed;
width: 100%;
left: 0;
right: 0;
top: 0;
z-index: 9;
background: #fff;
span {
width: 8%;
text-align: center;
margin-left: 10px;
font-size: 19px;
}
form {
flex: 1;
}
.van-icon {
width: 8%;
text-align: center;
margin-right: 10px;
}
}
.advertisement {
img {
width: 100%;
}
}
}

View File

@@ -0,0 +1,16 @@
.Search {
.hostory {
padding: 10px;
.item {
margin-bottom: 15px;
h2 {
margin-bottom: 7px;
font-size: 17px;
}
.van-tag {
margin-right: 5px;
margin-bottom: 5px;
}
}
}
}

View File

@@ -0,0 +1,97 @@
.info {
.swiper {
position: relative;
.nav {
position: fixed;
top:0;
left:0;
right: 0;
width: 100%;
height: 50px;
display: flex;
align-items: center;
box-sizing: border-box;
justify-content: space-between;
padding: 0 15px;
z-index: 99;
.van-icon {
width: 35px;
height: 35px;
text-align: center;
line-height: 35px;
color: #fff;
border-radius: 100%;
background: #00000078;
}
}
}
.info_content {
padding: 0 18px;
h2 {
font-size: 23px;
margin-top: 10px;
color: #3c3c3c;
margin-bottom: 9.2px;
}
.goods_brief {
font-size: 14px;
.active {
color: rgb(255, 74, 0);;
}
span {
color: rgba(0,0,0,.54);;
}
}
.price {
margin-top: 10px;
font-size: 26px;
color: #ff6700;
}
.configure {
margin-top: 12px;
.item {
.van-cell {
background-color: #f6f6f6 !important;
border-bottom: 1px solid #f2f2f2;
}
background: #e5e5e5;
.ddd {
display: flex;
justify-content: space-between;
.t {
display: flex;
.tex {
margin-right: 12px;
img{
margin-right: 5px;
width: 11.5px;
height: 11.5px;
}
span {
color: rgba(0,0,0,.54);
font-size: 12px;
}
}
}
}
}
}
}
.xqt {
img {
width: 100%;
}
}
.van-goods-action {
padding-right: 8px;
width: 90%;
box-shadow: 0 2px 4px -1px rgba(238, 238, 238, 0.2), 0 4px 5px rgba(229, 229, 229, 0.14), 0 1px 10px rgba(146, 145, 145, 0.12);
height: 57px;
border-radius: 11px;
left: 50%;
margin-left: -190px;
bottom: 11px;
border: 1px solid #e5e5e5;
}
}

View File

@@ -0,0 +1,33 @@
.login {
background: linear-gradient(to top right,#4c97d1,#43a8de,#3fb7eb);
.header {
width: 100%;
height: 200px;
display: flex;
justify-content: center;
align-items: center;
font-size: 18px;
color: #000;
}
.van-form {
padding: 0 65px;
}
.van-field {
margin-bottom: 20px;
border-radius: 5px;
background-color: #ffffff;
}
.action {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 75px;
margin-top: 10px;
box-sizing: border-box;
a {
color: #ffffff;
}
}
}

View File

@@ -0,0 +1,29 @@
.me {
.header {
height: 92px;
background: url("https://m.mi.com/static/img/bg.63c8e19851.png") center 0 #f37d0f;
display: flex;
align-items: center;
box-sizing: border-box;
padding-left: 20px;
img {
width: 50px;
height: 50px;
margin-right: 10px;
}
span {
color: #fff;
font-size: 15px;
}
}
.van-cell {
padding: 20px 16px;
}
.van-button{
width: 91%;
margin: 0 auto;
margin-top: 30px;
background: #f47d0e;
border: 1px solid #ffb501;
}
}

View File

@@ -0,0 +1,22 @@
.Reg {
background: linear-gradient(to top right,#4c97d1,#43a8de,#3fb7eb);
.header {
width: 100%;
height: 200px;
display: flex;
justify-content: center;
align-items: center;
font-size: 18px;
color: #000;
}
.van-form {
padding: 0 65px;
}
.van-field {
margin-bottom: 20px;
border-radius: 5px;
background-color: #ffffff;
}
}

View File

@@ -0,0 +1,431 @@
/*! 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.
*/
h1,h1,h2,h3,h4,h5,h6,p,ul,li {
margin: 0;
padding: 0;
list-style: none;
}
html,
body,
#app,
.Search{
height: 100%;
}
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 */
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@@ -0,0 +1,50 @@
<template lang="pug">
.header
van-nav-bar(:title='navTitle', left-arrow, @click-left="onClickLeft")
template(#right v-if="isShowText")
van-icon(:name='rightIcon', size='18')
template(#right v-else)
span(@click="TextEdit") {{ShowText}}
</template>
<script>
export default {
props: {
navTitle: {
type: String,
default: ''
},
ShowText: {
type: String,
default: '编辑'
},
isShowText: {
type: Boolean,
default: true
},
rightIcon: {
type: String,
default: 'search'
}
},
methods: {
onClickLeft() {
this.$router.back()
},
TextEdit() {
this.$emit("textClick")
}
}
}
</script>
<style scoped lang="less">
.header {
position: fixed;
width: 100%;
left: 0;
right: 0;
top: 0;
z-index: 999;
}
</style>

View File

@@ -0,0 +1,78 @@
<template lang="pug">
.ListItem
van-row
van-col(span='12' class="item" v-for="(item,index) in list" @click="enterInfo(item.wares_id)")
img(:src="item.wares_masterimg | firstImg")
h2 {{item.wares_title}}
span {{item.wares_conf | subStr}}
.price {{item.wares_nowprice}}
.buy 立即购买
</template>
<script>
export default {
props: {
list: {
type: Array,
default: []
}
},
data() {
return {}
},
created() {
},
filters: {
subStr(val) {
return val[0].substring(0,20)+'..'
},
firstImg(val) {
return val[0]
},
},
methods: {
enterInfo(id) {
this.$router.push({
path: '/info',
query: {
id: id
}
})
},
}
}
</script>
<style scoped lang="less">
.item {
text-align: center;
margin-bottom: 25px;
img {
width: 173px;
}
h2 {
color: rgba(0,0,0,.87);
font-size: 16.1px;
}
span {
color: rgba(0,0,0,.54);
font-size: 12.65px;
margin-top: 3.450px;
}
.price {
color: #ea625b;
font-size: 16.1px;
}
.buy {
width: 115px;
height: 33px;
color: #fff;
text-align: center;
line-height: 33px;
border-radius: 3px;
font-size: 13px;
background: #ea625b;
margin: 0 auto;
}
}
</style>

View File

@@ -0,0 +1,37 @@
<template lang="pug">
.swiper
van-swipe.my-swipe(:autoplay='3000', indicator-color='white')
van-swipe-item(v-for="(item,index) in list")
img(:src="item.hasOwnProperty('imgUrl') ? item.imgUrl : item ")
</template>
<script>
export default {
props: {
list: {
type: Array,
default: []
}
},
data() {
return {}
},
created() {
},
methods: {
async getTvList() {
}
}
}
</script>
<style scoped lang="less">
.van-swipe {
img {
width: 100%;
}
}
</style>

View File

@@ -0,0 +1,30 @@
export default {
apiUrl: {
devUrl: 'http://192.168.0.100:9090/',
prodUrl: 'https://zbhapi.ahtv.cn/h5/',
list: {
index: '/home/index',
login: '/user/login',
add: '/user/add',
search: '/home/search',
activity: '/home/activity',
info: '/home/info',
like: '/user/like',
addCar: '/car/addCar',
checkCar: '/car/checkCar',
getCarList: '/car/getCarList',
updateCarNum: '/car/updateCarNum',
submitCar: '/car/submitCar',
allOrder: '/order/allOrder',
deleteCar: '/car/deleteCar',
getUserInfo: '/user/getUserInfo',
buyOrder: '/order/buyOrder'
}
},
rsa_public_key: `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9eo8WIbWS5Yql06imlhrW0ZXh
faivPavdULvYLIxIKyUaOwMPFrPuHqqBNGnYOpiPHAKL+zxk2j4u+6jhB6VK1SOD
ccSLxIRxd0HmSDS+hBzYRf4vKc8BLlhMrYhnLmcxCc+PJIIa4DfCZnu8FfQlu/5L
ljjpYN9kHOpHAT+xpQIDAQAB
-----END PUBLIC KEY-----`
}

View File

@@ -0,0 +1,91 @@
import axios from "axios";
import utils from "../utils"
import { Toast } from 'vant';
import rsa from "../utils/rsa"
class Axios {
constructor() {
// 测试请求基地址 http://115.159.153.142:9010/h5
// 正式请求基地址 http://115.159.153.142:9020/h5
this.instance = axios.create({
baseURL: utils.getApiurl(),
timeout: 3000
});
this.interceptorsRequest();
this.interceptorsResponse();
}
/**
*
* @param params
* {
* url: '',
* data: {}
* }
* @returns {Promise<void>}
*/
async get(params) {
return await this.instance.get(params.url, {
params: params.data
})
}
async post(params) {
return this.instance({
method: 'post',
url: params.url,
headers: {
data: rsa.PublicKeyEncryption(params.data),
token: localStorage.getItem("shop_token") == null ? '' : localStorage.getItem("shop_token")
}
});
}
// 添加请求拦截器
interceptorsRequest() {
this.instance.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
Toast.loading({
message: '正在加载...',
forbidClick: true,
});
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
}
// 添加响应拦截器
interceptorsResponse() {
this.instance.interceptors.response.use(function (response) {
// 对响应数据做点什么
Toast.clear();
switch (response.data.status) {
case 200:
return rsa.PublicKeyDecryption(response.data.result);
break;
case 500:
Toast(response.data.message);
setTimeout(()=> {
location.href = "/#/login"
},2100)
break;
case 404:
Toast(response.data.message);
break;
}
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
}
}
export default new Axios();

View File

@@ -0,0 +1,10 @@
import http from "../";
import config from "../../config";
export default class BaseService {
constructor() {
this.config = config;
this.http = http
}
}

View File

@@ -0,0 +1,63 @@
import BaseService from "./BaseService"
export default class IndexService extends BaseService {
async index(params) {
let data = await this.http.post({
url: this.config.apiUrl.list.index,
data: params
});
data.forEach(val => {
val.wares_infoimg = JSON.parse(val.wares_infoimg)
val.wares_masterimg = JSON.parse(val.wares_masterimg)
val.wares_conf = JSON.parse(val.wares_conf)
})
return data
}
async search(params) {
let data = await this.http.post({
url: this.config.apiUrl.list.search,
data: params
})
data.forEach(val => {
val.wares_infoimg = JSON.parse(val.wares_infoimg)
val.wares_masterimg = JSON.parse(val.wares_masterimg)
val.wares_conf = JSON.parse(val.wares_conf)
})
return data
}
async activity(params) {
let data = await this.http.post({
url: this.config.apiUrl.list.activity,
data: params
});
data.forEach(val => {
val.wares_infoimg = JSON.parse(val.wares_infoimg)
val.wares_masterimg = JSON.parse(val.wares_masterimg)
val.wares_conf = JSON.parse(val.wares_conf)
});
return data
}
async info(params) {
let data = await this.http.post({
url: this.config.apiUrl.list.info,
data: params
});
data.wares_infoimg = JSON.parse(data.wares_infoimg)
data.wares_masterimg = JSON.parse(data.wares_masterimg)
data.wares_conf = JSON.parse(data.wares_conf)
return data
}
}

View File

@@ -0,0 +1,12 @@
import BaseService from "./BaseService"
export default class InfoService extends BaseService {
async getInfoList(params) {
return await http.get({
url: this.config.apiUrl.list.channelList,
data: params
})
}
}

View File

@@ -0,0 +1,113 @@
import BaseService from "./BaseService"
export default class UserService extends BaseService {
async login(params) {
return await this.http.post({
url: this.config.apiUrl.list.login,
data: params
})
}
async add(params) {
return await this.http.post({
url: this.config.apiUrl.list.add,
data: params
})
}
async like(params) {
return await this.http.post({
url: this.config.apiUrl.list.like,
data: params
})
}
async addCar(params) {
return await this.http.post({
url: this.config.apiUrl.list.addCar,
data: params
})
}
async checkCar(params) {
return await this.http.post({
url: this.config.apiUrl.list.checkCar,
data: params
})
}
async updateCarNum(params) {
return await this.http.post({
url: this.config.apiUrl.list.updateCarNum,
data: params
})
}
async deleteCar(params) {
return await this.http.post({
url: this.config.apiUrl.list.deleteCar,
data: params
})
}
async buyOrder(params) {
return await this.http.post({
url: this.config.apiUrl.list.buyOrder,
data: params
})
}
async getUserInfo(params) {
return await this.http.post({
url: this.config.apiUrl.list.getUserInfo,
data: params
})
}
async submitCar(params) {
return await this.http.post({
url: this.config.apiUrl.list.submitCar,
data: params
})
}
async allOrder(params) {
let data = await this.http.post({
url: this.config.apiUrl.list.allOrder,
data: params
})
if (Object.keys(data).length == 0) {
return []
} else {
data.forEach(val => {
val.wares_infoimg = JSON.parse(val.wares_infoimg)
val.wares_masterimg = JSON.parse(val.wares_masterimg)
})
return data
}
}
async getCarList(params) {
let data = await this.http.post({
url: this.config.apiUrl.list.getCarList,
data: params
});
data.forEach(val => {
val.wares_infoimg = JSON.parse(val.wares_infoimg)
val.wares_masterimg = JSON.parse(val.wares_masterimg)
val.wares_conf = JSON.parse(val.wares_conf)
})
return data
}
async deleteCar(params) {
return await this.http.post({
url: this.config.apiUrl.list.deleteCar,
data: params
})
}
}

View File

@@ -0,0 +1,9 @@
import InfoService from "./InfoService";
import IndexService from "./IndexService";
import UserService from "./UserService";
export default {
InfoService: new InfoService(),
IndexService: new IndexService(),
UserService: new UserService(),
}

View File

@@ -0,0 +1,29 @@
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import Vant from 'vant';
import 'vant/lib/index.css';
Vue.use(Vant);
import utils from "./utils";
import index from "./http/service"
import { PasswordInput, NumberKeyboard } from 'vant';
Vue.use(PasswordInput);
Vue.use(NumberKeyboard);
Vue.prototype.$http = index;
Vue.prototype.$utils = utils;
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')

View File

@@ -0,0 +1,130 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Home',
component: () => import(/* webpackChunkName: "Home" */ '../views/Home.vue'),
meta: {
title: '首页',
isLogin: false
}
},
{
path: '/me',
name: 'Me',
component: () => import(/* webpackChunkName: "Me" */ '../views/Me.vue'),
meta: {
title: '我的',
isLogin: false
}
},
{
path: '/car',
name: 'car',
component: () => import(/* webpackChunkName: "Car" */ '../views/Car.vue'),
meta: {
title: '购物车',
isLogin: false
}
},
{
path: '/info',
name: 'info',
component: () => import(/* webpackChunkName: "Info" */ '../views/Info.vue'),
meta: {
title: '详情页',
isLogin: false
}
},
{
path: '/class',
name: 'class',
component: () => import(/* webpackChunkName: "Class" */ '../views/Class.vue'),
meta: {
title: '分类',
isLogin: false
}
},
{
path: '/order',
name: 'order',
component: () => import(/* webpackChunkName: "index" */ '../views/Order/index.vue'),
meta: {
title: '我的订单',
isLogin: true
}
},
{
path: '/orderStatus',
name: 'orderStatus',
component: () => import(/* webpackChunkName: "orderStatus" */ '../views/Order/OrderStatus.vue'),
meta: {
title: '订单状态',
isLogin: true
}
},
{
path: '/login',
name: 'login',
component: () => import(/* webpackChunkName: "Login" */ '../views/Login.vue'),
meta: {
title: '登录',
isLogin: false
}
},
{
path: '/reg',
name: 'reg',
component: () => import(/* webpackChunkName: "Reg" */ '../views/Reg.vue'),
meta: {
title: '注册',
isLogin: false
}
},
{
path: '/search',
name: 'search',
component: () => import(/* webpackChunkName: "Search" */ '../views/Search.vue'),
meta: {
title: '搜索',
isLogin: false
}
},
{
path: '/Collection',
name: 'Collection',
component: () => import(/* webpackChunkName: "Search" */ '../views/Collection.vue'),
meta: {
title: '我的收藏',
isLogin: false
}
}
];
const router = new VueRouter({
routes
})
router.beforeEach((to, from, next) => {
document.title = to.meta.title;
if (to.meta.isLogin) {
if (localStorage.getItem("shop_token") != null) {
next()
} else {
next({
path: '/login',
query: {
from: from.path
}
})
}
} else {
next()
}
})
export default router

View File

@@ -0,0 +1,15 @@
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
modules: {
}
})

View File

@@ -0,0 +1,61 @@
import config from "../config"
import { Toast } from 'vant';
class Utils {
getApiurl () {
if (process.env.NODE_ENV === 'production') {
return config.apiUrl.prodUrl
} else {
return config.apiUrl.devUrl
}
}
/**
* 校验用户名是否合法
*/
checkUserName(username) {
if (!(username.length >= 6 && username.length < 20)) {
Toast({
message: '用户名长度应该6~20位'
});
return false
}
return true
}
/**
* 校验用户密码是否合法
* @param pwd
* @returns {boolean}
*/
checkUserPassword(pwd) {
if (!(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[^]{8,16}$/.test(pwd))) {
Toast({
message: '密码8~16位至少含1个大写字母1个小写字母1个数字'
});
return false
}
return true
}
/**
* 本地保存数据的方法
* @param key 名字
* @param value 值
* @constructor
*/
SetlocalStorage(key,value) {
typeof value == "string" || value == "number"
? localStorage.setItem('shop_' + key, value)
: localStorage.setItem('shop_' + key, JSON.stringify(value))
}
}
export default new Utils();

View File

@@ -0,0 +1,20 @@
import NodeRsa from "node-rsa";
import config from "../config";
class RSA {
constructor () {
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 new RSA();

View File

@@ -0,0 +1,166 @@
<template lang="pug">
.car
HeaderComponents(navTitle="购物车" :isShowText="false", :ShowText="editText", @textClick="editClick")
.content
.car_list(v-if="CarList.length != 0")
van-checkbox-group( v-model="result" ref="checkboxGroup" @change="CarChange")
.item(v-for="(item,index) in CarList")
van-checkbox(:name="item.car_id")
van-card(:price='item.wares_nowprice' :desc='item.wares_info' :title='item.wares_title' :thumb='item.wares_infoimg[0]')
template(#num)
van-button(size='mini')
van-stepper(v-model="item.car_num", @change="CarChange",
@minus="updateCarNum(item.car_id,item.car_num,'minus')"
@plus="updateCarNum(item.car_id,item.car_num,'plus')")
.nodata(v-else style="text-align: center;")
van-icon(name="shopping-cart-o", size="40")
span 购物车为空
a(@click="$router.push('/')") 首页
.cart_action
.left
van-checkbox(v-model="isCheck", @click="checkAll") 全选
.right(v-if="isEdit")
span 合计
em {{TotalMoney}}
van-button(type='danger',round, @click="SubmitCarList") 结算
van-button.delete(v-else, plain='', type='danger' round, @click="DeleteCar") 删除
</template>
<script>
import HeaderComponents from "@/components/Header.vue"
export default {
components: {
HeaderComponents
},
data() {
return {
defaultValue: 1,
isCheck: false,
result: [],
isEdit: true,
editText: '编辑',
CarList: [],
TotalMoney: 0
}
},
created() {
this.getCarList()
},
computed: {
},
methods: {
async updateCarNum(carid, quantity, type) {
type == 'plus' ? quantity = quantity + 1 : quantity = quantity - 1;
let res = await this.$http.UserService.updateCarNum({
quantity: quantity,
carid: carid
})
console.log(res)
},
async SubmitCarList() {
let data = this.CarList.filter((value, index) => {
for (let i = 0;i<this.result.length;i ++) {
if (value.car_id == this.result[i]) {
return value
}
}
});
this.$utils.SetlocalStorage('car', data)
this.$router.push({ path: '/order' })
},
async DeleteCar() {
let res = await this.$http.UserService.deleteCar({
carid: JSON.stringify(this.result)
});
for(let i = this.CarList.length - 1; i >=0; i--) {
if(this.result.indexOf(this.CarList[i].car_id) != -1) {
let index = this.result.indexOf(this.CarList[i].car_id)
this.result.splice(index,1)
this.CarList.splice(i,1)
}
}
},
async CarChange(value) {
let price = 0;
if (this.result.length != this.CarList.length) {
this.isCheck = false
} else {
this.isCheck = true
}
let data = this.CarList.filter((value, index) => {
for (let i = 0;i<this.result.length;i ++) {
if (value.car_id == this.result[i]) {
return value
}
}
})
data.forEach(val => {
price += parseInt(val.wares_nowprice) * val.car_num
});
this.TotalMoney = price;
// console.log(this.result)
},
async getCarList() {
let res = await this.$http.UserService.getCarList({});
this.CarList = res
this.CarList.forEach(val => {
})
console.log(res)
},
editClick() {
if (this.isEdit) {
this.editText = "完成"
this.isEdit = false
} else {
this.editText = "编辑"
this.isEdit = true
}
console.log("编辑")
},
checkAll() {
if (this.isCheck) {
this.$refs.checkboxGroup.toggleAll(true);
} else {
this.$refs.checkboxGroup.toggleAll();
}
console.log('result', JSON.stringify(this.result))
}
}
}
</script>
<style scoped lang="less">
.nodata{
text-align: center;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
margin-top: 27%;
span {
margin-top: 20px;
display: inline-block;
font-size: 14px;
color: #333;
}
}
@import "~@less/Car.less";
</style>

View File

@@ -0,0 +1,84 @@
<template lang="pug">
.class
HeaderComponents(navTitle="分类")
.content
van-tree-select(height='',
@click-nav="LeftNavClick",
:items='items',
:main-active-index.sync='active')
template(#content)
van-row(v-for="(item,index) in items" :key="index" v-if="active == index")
van-col(span='8', v-for="(its,ins) in item.children" :key="ins" @click="$router.push({ path: '/info', query: { id: its.wares_id } })")
van-grid(:column-num="1")
van-grid-item()
img.c_t(:src="its.wares_masterimg")
span {{its.wares_title.substring(0,5)}}
</template>
<script>
import HeaderComponents from "@/components/Header.vue"
export default {
components: {
HeaderComponents
},
data() {
return {
active: 0,
items: [
{
id: 1,
text: '限时白嫖',
children: []
},
{
id: 2,
text: '新品推荐',
children: [
]
},
{
id: 3,
text: '低价高配',
children: []
},
{
id: 4,
text: '超值特卖',
children: []
}
],
}
},
created() {
if (this.$route.query.hasOwnProperty("id")) {
this.active = this.$route.query.id - 1;
this.getClassList();
return false
}
this.getClassList();
},
methods: {
LeftNavClick(index) {
if (this.items[this.active].children.length == 0) {
this.getClassList()
}
},
async getClassList() {
let res = await this.$http.IndexService.activity({
id: this.items[this.active].id
});
res.forEach(val => {
val.wares_masterimg = val.wares_masterimg[0]
})
console.log(res)
this.items[this.active].children = res
}
}
}
</script>
<style scoped lang="less">
@import "~@less/Class.less";
</style>

View File

@@ -0,0 +1,45 @@
<template>
</template>
<script>
export default {
data () {
return{
}
},
beforeRouteEnter (to, from, next) {
next(vm => {
vm.$emit("hiddenNav")
vm.$emit("hiddenTb")
})
},
beforeRouteLeave (to, from, next) {
this.$emit("showNab")
this.$emit("showTb")
next()
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,89 @@
<template lang="pug">
.home
.search
span
form(action="/")
van-search(@click="$router.push({path: 'search'})", v-model='SearchKey',disabled, :show-action='false', placeholder='请输入搜索关键词', @search='onSearch', @cancel='onCancel')
van-icon(name='manager-o' size="22px")
.content
SwiperComponents(:list="BannerList")
van-grid(:column-num='4' :border="false")
van-grid-item(v-for='(value,index) in typeList', :key='index' @click="$router.push({ path: '/class', query: { id: value.id } })")
img(class="type_img" :src="value.img")
p(class="type_text") {{value.text}}
.advertisement
img(src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/489121f41279038693dbff01cbc03a1d.jpg?thumb=1&w=720&h=280")
.list
ListItemComponents(:list="IndexShopList")
</template>
<script>
import SwiperComponents from "@/components/Swiper"
import ListItemComponents from "@/components/ListItem"
export default {
name: 'Home',
components: {
SwiperComponents,
ListItemComponents
},
beforeRouteEnter (to, from, next) {
next(vm => {
vm.$emit("hiddenNav")
})
},
beforeRouteLeave (to, from, next) {
this.$emit("showNab")
next()
},
data() {
return {
SearchKey: '',
IndexShopList: [],
BannerList: [],
typeList: [
{ text: '限时白嫖', id: 1, img: '/img/type_1.png' },
{ text: '新品推荐', id: 2, img: '/img/type_2.png' },
{ text: '低价高配', id: 3, img: '/img/type_3.png' },
{ text: '超值特卖', id: 4, img: '/img/type_4.png' },
]
}
},
async created() {
this.getIndexList()
},
methods: {
async getIndexList() {
let res = await this.$http.IndexService.index({});
this.IndexShopList = res
let Banner = []
this.IndexShopList.filter((val,index) => {
if (val.wares_activity == '5') {
Banner.push({
imgUrl: val.wares_masterimg[0],
id: val.wares_id
})
return val
}
})
this.BannerList = Banner
},
onSearch() {
},
onCancel() {
}
}
}
</script>
<style scoped lang="less">
@import "~@less/Home.less";
</style>

View File

@@ -0,0 +1,129 @@
<template lang="pug">
.info(v-if="InfoList.hasOwnProperty('wares_conf')")
.swiper
.nav
van-icon(name='arrow-left', size="18", @click="$router.back()")
van-icon(name='share', size="18")
SwiperComponents(:list="InfoList.wares_masterimg")
.info_content
h2 {{InfoList.wares_title}}
.goods_brief
span.active {{InfoList.wares_title}}
span {{InfoList.wares_info}}
.price {{ choiceConfig == 1 ? InfoList.wares_oldprice : InfoList.wares_nowprice}}
.configure
.item
van-cell(:title='InfoList.wares_conf[choiceConfig].name', icon='' @click="isShowConfig = true")
template(#right-icon)
van-icon(name='arrow', style='line-height: inherit;')
van-cell(title='送至', icon='')
template(#right-icon)
van-icon(name='arrow', style='line-height: inherit;')
van-cell(icon='', class="ddd")
template(#right-icon)
.t
.tex
img(src="/img/do_icon.png")
span xx自营
.tex
img(src="/img/do_icon.png")
span xx发货
.tex
img(src="/img/do_icon.png")
span 7天无理由退货
van-icon(name='arrow', style='line-height: inherit;')
.xqt
img(v-for="i in InfoList.wares_infoimg" :src="i")
van-goods-action
van-goods-action-icon(icon='chat-o', text='客服', color='#07c160')
van-goods-action-icon(icon="cart-o", text='购物车', color='#ff5000', @click="$router.push({path: '/car'})")
van-goods-action-icon(:icon="isUserLike ? 'star' : 'star-o'", text='收藏', color='#ff5000', @click="UserAddLike")
van-goods-action-button(:type="isUserAddCar ? 'default' : 'warning'", :text="isUserAddCar ? '已加入购物车': '加入购物车'", @click=" isUserAddCar ? '' : UserAddCar()")
van-goods-action-button(type='danger', text='立即购买')
van-action-sheet(v-model="isShowConfig"
cancel-text="取消"
:actions="InfoList.wares_conf" @select="ConfigSelect")
</template>
<script>
import SwiperComponents from "@/components/Swiper"
export default {
components: {
SwiperComponents
},
data() {
return {
isUserAddCar: false,
isUserLike: false,
isShowConfig: false,
id: this.$route.query.id,
InfoList: {},
choiceConfig: 1
}
},
created() {
this.getInfoList()
this.checkCar()
},
beforeRouteEnter (to, from, next) {
next(vm => {
vm.$emit("hiddenTb")
})
},
beforeRouteLeave (to, from, next) {
this.$emit("showTb")
next()
},
methods: {
async checkCar() {
let res = await this.$http.UserService.checkCar({
waresid: this.id
});
this.isUserAddCar = res.isAddCar
},
async UserAddCar() {
let res = await this.$http.UserService.addCar({
waresid: this.id
});
this.isUserAddCar = true
},
async UserAddLike() {
let res = await this.$http.UserService.like({
shopid: this.id
});
this.isUserLike = true
},
ConfigSelect(action,index) {
this.choiceConfig = index;
this.isShowConfig = false
},
async getInfoList() {
let res = await this.$http.IndexService.info({
id: this.$route.query.id
});
this.InfoList = res;
let waresCconf = []
this.InfoList.wares_conf.forEach(val => {
waresCconf.push({
name: val
})
})
this.InfoList.wares_conf = waresCconf
console.log(res)
}
}
}
</script>
<style scoped lang="less">
@import "~@less/info.less";
</style>

View File

@@ -0,0 +1,57 @@
<template lang="pug">
.login
.header 用户登录
van-form
van-field(v-model='username', name='用户名', label='用户名', left-icon="",placeholder='用户名', :rules="[{ required: true, message: '请填写用户名' }]")
van-field(v-model='userpassword', type='password', name='密码', label='密码', placeholder='密码', :rules="[{ required: true, message: '请填写密码' }]")
div
van-button(round='', block='', type='info', native-type='submit', @click="UserLogin")
.action
router-link(to="/") 首页
router-link(to="/reg") 注册
</template>
<script>
export default {
data() {
return {
username: '',
userpassword: ''
}
},
created() {
},
methods: {
async UserLogin() {
if (this.$utils.checkUserName(this.username) && this.$utils.checkUserPassword(this.userpassword)) {
let res = await this.$http.UserService.login({
name: this.username,
pwd: this.userpassword
});
this.$utils.SetlocalStorage("token", res.token)
this.$router.push({ path: '/' })
console.log("登录成功的信息:", res)
}
}
},
beforeRouteEnter (to, from, next) {
next(vm => {
vm.$emit("hiddenNav")
vm.$emit("hiddenTb")
})
},
beforeRouteLeave (to, from, next) {
this.$emit("showNab")
this.$emit("showTb")
next()
}
}
</script>
<style scoped lang="less">
@import "~@less/login.less";
</style>

View File

@@ -0,0 +1,71 @@
<template lang="pug">
.me
.header
img(src="https://m.mi.com/static/img/avatar.76a75b8f17.png")
span {{ Object.keys(UserInfo).length == 0 ? '登录注册' : UserInfo.user_name }}
p(v-if="Object.keys(UserInfo).length != 0") 余额:{{ UserInfo.user_money }}
.order
van-cell(title='我的订单', is-link='', value='全部订单' @click="$router.push({ path: '/orderStatus'})")
van-grid(:column-num="3", :border="false")
van-grid-item(icon='pending-payment',text='待付款' @click="$router.push({path:'/orderStatus',query:{ id: 0 }})")
van-grid-item(icon='logistics', text='待收货')
van-grid-item(icon='after-sale', text='退货/退款')
van-cell(title='会员中心', icon='contact',is-link, to = "")
van-cell(title='我的收藏', icon='like-o',is-link, to = "/Collection")
van-cell(title='我的优惠', icon='pending-payment',is-link, to = "")
van-cell(title='服务中心', icon='shop-o',is-link, to = "")
template(#right-icon='')
van-icon(name='arrow', color="#969799", size="17", style='line-height: inherit;')
van-button( type="danger" block @click="LoginOut") 退出登录
</template>
<script>
export default {
created() {
this.getUserInfo()
},
data() {
return {
UserInfo: {}
}
},
methods: {
async getUserInfo() {
let data = await this.$http.UserService.getUserInfo({});
this.UserInfo = data[0]
console.log(data[0])
},
LoginOut () {
this.$dialog.confirm({
title: '温馨提示',
message: '是否退出登录',
}).then(() => {
localStorage.removeItem("shop_token")
this.$router.push({
path: '/'
})
})
.catch(() => {
});
}
},
beforeRouteEnter (to, from, next) {
next(vm => {
vm.$emit("hiddenNav")
})
},
beforeRouteLeave (to, from, next) {
this.$emit("showNab")
next()
}
}
</script>
<style scoped lang="less">
@import "~@less/me.less";
</style>

View File

@@ -0,0 +1,108 @@
<template lang="pug">
.order_status
van-nav-bar(title='订单状态', left-arrow='')
van-tabs(v-model='active', @change="ItemChange")
van-tab(:title='item.text' v-for="(item,index) in TabsList")
div(v-if="index == active")
div(v-if="item.content.length != 0")
van-card(v-for="(it,ix) in item.content", :key="index" :num='it.goods_num',
:price='it.wares_nowprice', :desc='it.wares_info',
:title='it.wares_title', :thumb='it.wares_masterimg[0]')
.nodata(v-else) 暂无数据
</template>
<script>
export default {
data() {
return {
active: 0,
TabsList: [
{ text: '全部', id: -1, content: [] },
{ text: '待付款', id: 0, content: [] },
{ text: '待发货', id: 1, content: [] },
{ text: '待收货', id: 2, content: [] },
{ text: '退款/售后', id: 3, content: [] },
],
allOrderList: [],
CarList: []
}
},
created() {
if(this.$route.query.hasOwnProperty("id")) {
this.active = this.$route.query.id
this.CarList = JSON.parse(localStorage.getItem("shop_car"))
this.getOrderList()
return false
}
this.CarList = JSON.parse(localStorage.getItem("shop_car"))
this.getOrderList()
},
methods: {
ItemChange() {
if (this.TabsList[this.active].content.length == 0) {
this.getOrderList()
}
},
async getOrderList() {
let res = await this.$http.UserService.allOrder({
status: this.TabsList[this.active].id
});
console.log(res)
let Arr = [];
let dd = res.filter((value, index) => {
for (let i = 0; i<this.CarList.length;i++) {
if (value.wares_id == this.CarList[i].wares_id) {
Arr.push(value.wares_id)
return value
}
}
});
if (this.TabsList[this.active].id == -1) {
for(let i = res.length - 1; i >=0; i--) {
if(Arr.indexOf(res[i].wares_id) != -1) {
let index = Arr.indexOf(res[i].wares_id)
Arr.splice(index,1)
res.splice(i,1)
}
}
}
let params = []
dd.forEach(val=> {
params.push(val.goods_id)
})
let BuyOrder = await this.$http.UserService.buyOrder({
goodsid: JSON.stringify(params)
});
this.TabsList[this.active].content = [ ...this.TabsList[this.active].content, ...res ]
}
},
beforeRouteEnter (to, from, next) {
next(vm => {
vm.$emit("hiddenTb")
})
},
beforeRouteLeave (to, from, next) {
this.$emit("showTb")
next()
},
}
</script>
<style scoped lang="less">
</style>

View File

@@ -0,0 +1,157 @@
<template lang="pug">
.order
van-contact-card(:type='cardType', :name='currentContact.name', :tel='currentContact.tel', @click='showList = true')
van-radio-group(v-model="payType" class="pay_type")
van-cell(:title='item.text', icon='shop-o', v-for="(item,index) in PayList")
// 使用 right-icon 插槽来自定义右侧图标
template(#icon)
img(:src="item.icon")
template(#right-icon)
van-radio(:name="index")
van-cell-group
van-cell(title='运费', value='包邮')
van-cell(title='发票', value='无')
van-cell(title='折扣', value='无')
.car_list
van-card(v-for="(item,index) in CarListArr" :num='item.car_num', :desc="item.wares_info" , :price='item.wares_nowprice', :title='item.wares_title', :thumb='item.wares_masterimg[0]')
van-submit-bar(:price='TotalPrice * 100', button-text='提交订单', @submit='onSubmit')
van-popup(v-model='show', position='bottom', :style="{ height: '100%' }")
div(@click="close()" class="guanbi") X
// 密码输入框
van-password-input(:value='value', info='密码为 6 位数字', :focused='showKeyboard', @focus='showKeyboard = true')
// 数字键盘
van-button(type="info" @click="pay" block, style="width: 95%;margin: 30px auto") 确认付款
van-number-keyboard(:show='showKeyboard', @input='onInput', @delete='onDelete', @blur='showKeyboard = false')
</template>
<script>
import HeaderComponents from "@/components/Header.vue"
export default {
data() {
return {
chosenContactId: null,
payType: 0,
PayList: [
{ id: 1, text: '支付宝', icon: 'https://s1.mi.com/m/images/m/pay_zfb2.png' },
{ id: 2, text: '微信', icon: 'https://s1.mi.com/m/images/m/pay_wx.png' },
{ id: 3, text: '余额', icon: 'https://s1.mi.com/m/images/m/micash_wap.png' }
],
TotalPrice: 0,
CarListArr:[],
show: false,
value: '',
showKeyboard: true,
}
},
created() {
this.CarListArr = JSON.parse(localStorage.getItem("shop_car"));
this.CarListArr.forEach(val => {
this.TotalPrice += parseInt(val.wares_nowprice) * val.car_num
});
},
methods: {
async onSubmit() {
let params = { carList: [] }
this.CarListArr.forEach(val => {
params.carList.push({
waresid: val.wares_id,
goodsnum: val.car_num,
goodsprice: val.wares_nowprice
})
});
this.show = true
//{"carList":[{"waresid":113,"goodsnum":2,"goodsprice":1000},{"waresid":114,"goodsnum":1,"goodsprice":1100}]}
let res = await this.$http.UserService.submitCar(JSON.stringify(params))
},
close(){
this.show=false
},
onInput(key) {
this.value = (this.value + key).slice(0, 6);
if (this.value.length === 6) {
this.$router.push({ path: '/orderStatus' })
}
},
onDelete() {
this.value = this.value.slice(0, this.value.length - 1);
},
pay(){
}
},
computed: {
cardType() {
return this.chosenContactId !== null ? 'edit' : 'add';
},
currentContact() {
const id = this.chosenContactId;
return id !== null ? this.list.filter((item) => item.id === id)[0] : {};
},
},
beforeRouteEnter (to, from, next) {
next(vm => {
vm.$emit("hiddenTb")
})
},
beforeRouteLeave (to, from, next) {
this.$emit("showTb")
next()
},
}
</script>
<style scoped lang="less">
.car_list{
margin-top: 20px;
}
.pay_type {
margin-top: 20px;
margin-bottom: 20px;
}
.van-cell {
align-items: center;
img {
width: 30px;
height: 30px;
margin-right: 10px;
}
}
.pay_type {
}
.guanbi{
width: 30px;
height: 30px;
background: #e1e1ea;
border-right: 15px;
text-align: center;
line-height: 30px;
color: black;
position: fixed;
right: 5px;
top: 5px;
}
.van-password-input{
margin-top: 100px;
}
.pay{
width: 200px;
height: 55px;
color: skyblue;
text-align: center;
line-height: 55;
}
</style>

View File

@@ -0,0 +1,77 @@
<template lang="pug">
.Reg
.header 用户注册
van-form
van-field(v-model='username', name='用户名', label='用户名', placeholder='用户名')
van-field(v-model='userpassword', type='password', name='密码', label='密码', placeholder='密码')
van-field(v-model='userphone', maxlength="11", type='tel', name='手机号', label='手机号', placeholder='手机号')
div(style='margin: 16px;')
van-button(round='', block='', type='info', native-type='submit', @click="Reg")
</template>
<script>
export default {
data() {
return {
username: '',
userpassword: '',
userphone: ''
}
},
created() {
},
methods: {
async Reg() {
if (this.username.length != 0 && this.userpassword.length != 0 && this.userphone.length != 0) {
if(!(/^1[3456789]\d{9}$/.test(this.userphone))){
this.$toast({
message: '手机号不合法'
});
return false;
}
if (this.$utils.checkUserName(this.username) && this.$utils.checkUserPassword(this.userpassword) ) {
let res = await this.$http.UserService.add({
name: this.username,
pwd: this.userpassword,
phone: this.userphone
});
this.$toast({
message: '注册成功,请登录',
onOpened: () => {
setTimeout( () => {
this.$router.push({ path: '/login' })
},2100)
}
});
}
} else {
this.$toast({
message: '账户,密码,手机号都必须填写'
});
}
}
},
beforeRouteEnter (to, from, next) {
next(vm => {
vm.$emit("hiddenNav")
vm.$emit("hiddenTb")
})
},
beforeRouteLeave (to, from, next) {
this.$emit("showNab")
this.$emit("showTb")
next()
}
}
</script>
<style scoped lang="less">
@import "~@less/reg.less";
</style>

View File

@@ -0,0 +1,83 @@
<template lang="pug">
.Search(@click="isShowList")
form(@click.stop="")
van-search(v-model='SearchKey', @focus="showHis()" @clear="isShowList" show-action='', placeholder='请输入搜索关键词')
template(#action)
div(@click='onSearch(null)') 搜索
.hostory(v-if="isShowHistory")
.item(v-if="HistoryList.length != 0")
h2 历史搜索
van-tag(round v-for="i in 10") 测试
.item
h2 搜索建议
van-tag(round v-for="i in SearchProposal", @click="onSearch(i.text)") {{i.text}}
.list(v-else)
ListItemComponents(:list="SearchList")
</template>
<script>
import ListItemComponents from "@/components/ListItem"
export default {
components: {
ListItemComponents
},
data() {
return {
isShowHistory: true,
SearchKey: '',
SearchList: [],
HistoryList: [],
SearchProposal: [
{ text: '小米', id: ''},
{ text: '魅族', id: ''},
{ text: '苹果', id: ''},
{ text: '三星', id: ''},
{ text: '诺基亚', id: ''}
]
}
},
created() {
},
methods: {
showHis() {
console.log("子")
this.isShowHistory = true
},
isShowList() {
if (this.SearchList.length != 0) {
console.log("ddd")
this.isShowHistory = false
}
},
async onSearch(text) {
let res = await this.$http.IndexService.search({
keyword: text == null ? this.SearchKey : text
});
this.SearchList = res
this.isShowHistory = false
console.log(this.SearchList)
}
},
beforeRouteEnter (to, from, next) {
next(vm => {
vm.$emit("hiddenNav")
vm.$emit("hiddenTb")
})
},
beforeRouteLeave (to, from, next) {
this.$emit("showNab")
this.$emit("showTb")
next()
}
}
</script>
<style scoped lang="less">
@import "~@less/Search.less";
</style>

View File

@@ -0,0 +1,40 @@
const path = require("path");
module.exports = {
lintOnSave: false,
publicPath: './',
chainWebpack: config => {
config.module.rule('pug')
.test(/\.pug$/)
.use('pug-html-loader')
.loader('pug-html-loader')
.end();
config.resolve.alias
.set('@c',resolve('src/components'))
.set('@img',resolve('src/assets/img'))
.set('@less',resolve('src/assets/less/page'));
const types = ['vue-modules', 'vue', 'normal-modules', 'normal']
types.forEach(type => addStyleResource(config.module.rule('less').oneOf(type)))
}
}
function addStyleResource (rule) {
rule.use('style-resource')
.loader('style-resources-loader')
.options({
patterns: [
path.resolve(__dirname, './src/assets/less/index.less'),
],
})
}
function resolve(dir) {
return path.join(__dirname, dir);
}

View File

@@ -0,0 +1,25 @@
1: 登录注册页面
2: 搜索页面
3: 我的订单
4: 我的收藏页面
5: 关于软件页面
6: 留言页面
任务登录注册页面自己找ui图实现
删除购物车商品 调用 /car/deleteCar
页面原型https://org.modao.cc/app/b8dd67c8e0e2c7631c4f1862d4d47e25b0317da5?simulator_type=outside_artboard&sticky=#screen=ska1swo4bxy0aqi
线上地址http://www.zhiyuanhelp.com/test/#/
接口地址https://www.showdoc.cc/zhiyuanhelp?page_id=4279650807030330
访问密码zyhelp
提交时间:周日下午
任务:
1我的页面点击 代付款,待收货,待退款 能够跳转到订单页面的对应tabs上
2我的收藏页面
未完成1页面回退激活样式没有改变
未完成2页面回退激活样式没有改变