Authored by yyq

merge

Showing 79 changed files with 4115 additions and 218 deletions

Too many changes to show.

To preserve performance only 79 of 79+ files are displayed.

... ... @@ -142,4 +142,6 @@ nbproject/*
.DS_Store
.devhost
.happypack/
bundle/
\ No newline at end of file
bundle/
package-lock.json
... ...
phantomjs_cdnurl=http://npm.taobao.org/mirrors/phantomjs
sass_binary_site=https://npm.taobao.org/mirrors/node-sass/
\ No newline at end of file
sass_binary_site=https://npm.taobao.org/mirrors/node-sass/
package-lock=false
... ...
import axios from 'axios';
import config from 'config';
import {sign} from './utils';
import {
sign
} from './utils';
axios.defaults.baseURL = config.axiosBaseUrl;
axios.defaults.responseType = config.axiosResponseType;
... ... @@ -20,7 +22,9 @@ const request = (options, store) => {
return axios(options).then((res) => {
if (res.data.code === 401) {
store && store.commit('needLogin', {needLogin: true});
store && store.commit('needLogin', {
needLogin: true
});
return Promise.reject(res.data);
}
return res.data;
... ...
/* eslint-disable indent */
/* eslint-disable operator-linebreak */
import checkParams from '../../utils/check-params';
import apiMaps from '../../config/api-map';
import createReport from 'report-error';
... ... @@ -5,81 +8,122 @@ import createReport from 'report-error';
const yohoApi = global.yoho.API;
const ufoAPI = global.yoho.UfoAPI;
const serviceApi = global.yoho.ServiceAPI;
const checkApiMap = url => {
return apiMaps[url] ? apiMaps[url] : void 0;
};
const request = async({url, method, reqParams = {}, context}) => {
// eslint-disable-next-line space-before-function-paren
const request = async ({ url, method, reqParams = {}, context }) => {
const apiInfo = checkApiMap(url);
const {env, user} = context;
const { env, user = {} } = context;
if (!apiInfo) {
return Promise.reject(new Error(`未找到对应的接口:${url}`));
}
// 登陆:取session中用户信息
// 非登录: 可以传参
if (!apiInfo.service) {
Object.assign(reqParams, {
uid: (user && user.uid) ? {
toString: () => {
return user.uid;
const { uid, sessionKey, appSessionType } = user;
Object.assign(reqParams, { method: apiInfo.api });
if (uid) {
Object.assign(reqParams, {
uid: {
toString: () => {
return user.uid;
},
sessionKey,
appSessionType,
},
sessionKey: user.sessionKey,
appSessionType: user.appSessionType
} : 1,
method: apiInfo.api,
});
});
}
}
// 开发环境接口调用非延签参数
if (context.env.unProd) {
Object.assign(reqParams, { debug: 'XYZ' });
}
const params = checkParams.getParams(reqParams, apiInfo);
const cache = method.toLowerCase() !== 'get' ? false : apiInfo.cache;
const headers = {
'X-YOHO-IP': env.clientIp,
'X-Forwarded-For': env.clientIp,
'User-Agent': 'yoho/nodejs'
'User-Agent': 'yoho/nodejs',
};
try {
if (apiInfo.service) {
return await serviceApi.get(`${apiInfo.api}${apiInfo.path}`, params, {
cache: cache,
headers
headers,
});
} else if (apiInfo.ufo) {
return await ufoAPI[method](`${apiInfo.path || ''}`, params, {
cache: cache,
headers
headers,
});
} else {
return await yohoApi[method](`${apiInfo.path || ''}`, params, {
cache: cache,
headers
headers,
});
}
} catch (error) {
return Promise.reject({
code: error.code || 500,
message: error.message || '服务器错误'
message: error.message || '服务器错误',
});
}
};
const catchError = (context, reqParams) => {
return result => {
if (result && result.code === 500) {
createReport(context, 'api')(Object.assign({
api: reqParams.method,
}, result));
const resolve = ({ context, store, reqParams }) => {
return res => {
if (res) {
const { code } = res;
if (code === 500) {
createReport(context, 'api')(
Object.assign(
{
api: reqParams.method,
},
res,
),
);
} else if (code === 401) {
store.commit('SET_NEED_LOGIN', { needLogin: true });
}
}
return result;
return res;
};
};
export const createApi = context => {
export const createApi = (context, store) => {
return {
get(url, reqParams = {}) {
return request({url, method: 'get', reqParams, context}).then(catchError(context, reqParams));
return request({
url,
method: 'get',
reqParams,
context,
})
.then(resolve({ context, store, reqParams }))
.catch(err => {
console.log('----create----api--server--get---', err);
});
},
post(url, reqParams = {}) {
return request({url, method: 'post', reqParams, context}).then(catchError(context, reqParams));
}
return request({
url,
method: 'post',
reqParams,
context,
})
.then(resolve({ context, store, reqParams }))
.catch(err => {
console.log('----create----api--server--post---', err);
});
},
};
};
... ...
export default {
name: 'AutoAuth',
functional: true,
props: {
tag: {
type: String,
default: 'dev'
}
},
render(h, { scopedSlots, props, data, parent }) {
return h(props.props, {
'!click': this.onClick
}, [h(scopedSlots.defaults(), data)]);
},
methods: {
onClick() {
console.log('on-click');
}
}
};
... ...
<template>
<img v-lazy="currentSrc" :alt="alt" v-if="!refresh">
<img v-lazy="currentSrc" :alt="alt" v-if="!refresh" />
</template>
<script>
export default {
name: 'ImgSize',
name: "ImgSize",
props: {
src: String,
width: Number,
height: Number,
alt: String,
alt: String
},
data() {
return {
... ... @@ -26,15 +26,12 @@ export default {
},
computed: {
currentSrc() {
return (this.src || '')
.replace('http://', '//')
.replace('{width}', this.width)
.replace('{height}', this.height);
return (this.src || "")
.replace("http://", "//")
.replace("{width}", this.width)
.replace("{height}", this.height);
}
}
};
</script>
<style>
</style>
... ...
<template>
<LayoutApp title="选择地址" :show-back="true">
<AddressItem :list="addressList"></AddressItem>
</LayoutApp>
</template>
<script>
import Layout from "../../../components/layout/layout-app";
import AddressItem from "./components/address-item";
import { createNamespacedHelpers } from "vuex";
const { mapState, mapMutations, mapActions } = createNamespacedHelpers(
"address/address"
);
export default {
name: "addressManager",
components: {
LayoutApp: Layout,
AddressItem
},
data() {
return {};
},
computed: {
...mapState(["addressList"])
},
methods: {
...mapMutations({}),
...mapActions(["fetchUserAddressList"])
},
mounted() {
this.fetchUserAddressList();
}
};
</script>
<style lang="scss" scoped>
.body {
height: 100%;
background-color: #e0e0e0;
overflow-y: auto;
}
.address-container {
margin-bottom: 120px;
}
.addNew {
display: block;
height: 80px;
margin-top: 20px;
background-color: white;
}
.newText {
line-height: 80px;
font-size: 28px;
letter-spacing: 0.6px;
white-space: nowrap;
text-align: center;
}
</style>
... ...
<template>
<LayoutApp title="添加地址" :show-back="true">
<div class="pane-body">
<FormItem>
<CInput label="收货人" place-holder="请写姓名" v-model="model.receiverName"></CInput>
</FormItem>
<FormItem>
<CInput label="手机号" place-holder="请填写手机号" v-model="model.receiverMobile"></CInput>
</FormItem>
<template>
<FormItem>
<div class="wrapper-area">
<label class="input-label">所在区域</label>
<div class="wrapper-arrow">
<template v-if="model.receiverArea">
<label class="text-label">江苏省南京市三山区</label>
</template>
<template v-else>
<label class="choose-area" @click="chooseArea">请选择</label>
</template>
<div class="arrow"></div>
</div>
</div>
</FormItem>
</template>
<FormItem>
<CInput label="详细地址" place-holder="请输入详细地址" v-model="model.receiverAddress"></CInput>
</FormItem>
<label
ref="labelTags"
class="wrapper-tag"
action="radio_submit"
method="get"
accept-charset="utf-8"
>
<p class="tag-text">设置标签:</p>
<label class="label-text">
<input type="radio" name="tag" value="1" class="label-tag" v-model="model.tagType" /> 家
</label>
<label class="label-text">
<input type="radio" name="tag" value="2" class="label-tag" v-model="model.tagType" /> 公司
</label>
<label class="label-text">
<input type="radio" name="tag" value="3" class="label-tag" v-model="model.tagType" /> 学校
</label>
<label class="label-text">
<input type="radio" name="tag" value="4" class="label-tag" v-model="model.tagType" /> 其他
</label>
</label>
<Radio
class="radio"
:label="{text: '设为默认地址', value: 1}"
style="flex: 0 1 100%;"
v-model="model.defaultType"
></Radio>
<div :class="submitClass" @touchend="onSubmit">确定</div>
</div>
<!-- <AddressAct></AddressAct> -->
</LayoutApp>
</template>
<script>
import Layout from "../../../components/layout/layout-app";
import Input from "./components/input";
import FormItem from "./components/form-item";
import Radio from "./components/radio";
import AddressAct from "./components/address-act";
import { createNamespacedHelpers } from "vuex";
const { mapState, mapMutations, mapActions } = createNamespacedHelpers(
"address/address"
);
export default {
name: "addressEdit",
components: {
LayoutApp: Layout,
CInput: Input,
FormItem,
Radio,
AddressAct
},
data() {
return {
model: {
receiverName: "",
receiverMobile: "",
receiverArea: "",
receiverAddress: "",
tagType: 0,
defaultType: false
}
};
},
computed: {
...mapState(["addressList"]),
submitClass() {
return [
"sure-btn",
{
active: this.inNotEmpty
}
];
},
inNotEmpty() {
return true;
}
},
methods: {
...mapMutations({}),
...mapActions([""]),
async onSubmit() {
console.log("被选中的值为:" + this.model.tagType);
console.log("被选中的值为:" + this.model.defaultType);
if (!this.inNotEmpty) {
return;
}
},
chooseArea() {}
},
mounted() {}
};
</script>
<style lang="scss" scoped>
.pane-body {
height: 100%;
overflow-y: auto;
padding-top: 12px;
padding-left: 40px;
padding-right: 40px;
}
.wrapper-area {
display: flex;
flex-direction: column;
.input-label {
font-size: 36px;
display: inline-block;
font-weight: bold;
margin-bottom: 30px;
}
.text-label {
font-size: 28px;
color: #444444;
display: inline-block;
}
.choose-area {
font-size: 28px;
color: #cccccc;
}
.wrapper-arrow {
display: flex;
justify-content: space-between;
}
.arrow {
height: 44px;
width: 44px;
background: url("~statics/image/order/arrow-right.png");
background-size: cover;
}
}
.wrapper-tag {
display: flex;
flex-direction: row;
margin: 30px 0;
align-items: center;
.tag-text {
font-size: 36px;
display: inline-block;
font-weight: bold;
}
.label-text {
margin-left: 20px;
font-size: 30px;
color: #444444;
line-height: 44px;
}
.label-tag {
display: inline-block;
vertical-align: middle;
}
}
.radio {
margin: 30px 0;
}
.sure-btn {
height: 120px;
line-height: 120px;
font-size: 28px;
text-align: center;
background-color: #cccccc;
color: white;
position: absolute;
left: 40px;
right: 40px;
bottom: 40px;
&.active {
background-color: #002b47;
}
}
</style>
... ...
<template>
<div class="address-select-component" v-show="true">
<div class="address-select-box">
<div class="component-title">
<span class="title">所在地区</span>
<span class="iconfont close" @click="closeAddBox">&#xe623;</span>
</div>
<ul class="head-address-ul">
<li
v-if="province.title"
:class="{ 'head-address-li': common.titleActive, 'disable': !supportChangeProvince}"
@click="clickTitle('province')"
>{{province.title}}</li>
<li
v-if="city.title"
:class="{ 'head-address-li': province.titleActive }"
@click="clickTitle('city')"
>{{city.title}}</li>
<li
v-if="area.title"
:class="{ 'head-address-li': city.titleActive }"
@click="clickTitle('area')"
>{{area.title}}</li>
<li v-if="street.title" :class="{ 'head-address-li': area.titleActive }">{{street.title}}</li>
</ul>
<div class="address-container">
<div class="address-content">
<ul v-if="province.showList" class="address-ul">
<li
v-for="(pprovince, index) in provinces"
:key="index"
@click="switchAddress(pprovince.id, pprovince.caption)"
>
{{pprovince.caption}}
<span
v-if="pprovince.id === province.id"
class="iconfont icon-v"
></span>
</li>
</ul>
<ul v-if="city.showList" class="address-ul">
<li
v-for="(pcity, index) in citys"
:key="index"
@click="switchAddress(pcity.id, pcity.caption)"
>
{{pcity.caption}}
<span v-if="pcity.id === city.id" class="iconfont icon-v"></span>
</li>
</ul>
<ul v-if="area.showList" class="address-ul">
<li
v-for="(parea, index) in areas"
:key="index"
@click="switchAddress(parea.id, parea.caption)"
>
{{parea.caption}}
<span v-if="parea.id === area.id" class="iconfont icon-v"></span>
</li>
</ul>
<ul v-if="street.showList" class="address-ul">
<li
v-for="(pstreet, index) in streets"
:key="index"
@click="switchAddress(pstreet.id, pstreet.caption)"
>
{{pstreet.caption}}
<span v-if="pstreet.id === street.id" class="iconfont icon-v"></span>
</li>
</ul>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
supportChangeProvince: true, // 是否支持修改省
provinces: [],
citys: [],
areas: [],
streets: [],
show: false,
common: {
titleActive: true
},
province: {
id: "",
title: "",
allTitle: "",
showList: true,
titleActive: false
},
city: {
id: "",
title: "",
allTitle: "",
showList: false,
titleActive: false
},
area: {
id: "",
title: "",
allTitle: "",
showList: false,
titleActive: false
},
street: {
id: "",
title: "",
allTitle: "",
showList: false,
titleActive: false
}
};
}
// methods: {
// /* 返回标题处理 */
// returnTitle() {
// let getTitle = "";
// let returnTitle = "";
// if (this.supportChangeProvince) {
// getTitle =
// this.province.allTitle +
// this.city.allTitle +
// this.area.allTitle +
// this.street.allTitle;
// } else {
// getTitle =
// this.city.allTitle + this.area.allTitle + this.street.allTitle;
// }
// if (getTitle.length > 11) {
// returnTitle = getTitle.substr(0, 5) + "..." + getTitle.substr(-5);
// } else {
// returnTitle = getTitle;
// }
// return returnTitle;
// },
// /* 标题长度处理 */
// titleHandle(caption) {
// if (caption.length > 3) {
// return caption.substring(0, 3) + "...";
// } else {
// return caption;
// }
// },
// /* 选择地址后的显示控制 */
// changeShow(id, caption) {
// switch ((id + "").length) {
// case 2:
// this.province.id = id;
// this.province.allTitle = caption;
// this.province.title = this.titleHandle(caption);
// this.city.title = "请选择";
// this.city.showList = this.province.titleActive = true;
// this.province.showList = this.area.showList = this.street.showList = false;
// this.common.titleActive = this.city.titleActive = this.area.titleActive = this.street.titleActive = false;
// break;
// case 4:
// this.city.id = id;
// this.city.allTitle = caption;
// this.city.title = this.titleHandle(caption);
// this.area.title = "请选择";
// this.area.showList = this.city.titleActive = true;
// this.province.showList = this.city.showList = this.street.showList = false;
// this.province.titleActive = this.area.titleActive = this.street.titleActive = false;
// break;
// case 6:
// this.area.id = id;
// this.area.allTitle = caption;
// this.area.title = this.titleHandle(caption);
// this.street.title = "请选择";
// this.street.showList = this.area.titleActive = true;
// this.province.showList = this.city.showList = this.area.showList = false;
// this.province.titleActive = this.city.titleActive = this.street.titleActive = false;
// break;
// case 9:
// this.street.id = id;
// this.street.allTitle = caption;
// this.street.title = this.titleHandle(caption);
// this.street.showList = this.street.titleActive = true;
// this.province.showList = this.city.showList = this.area.showList = false;
// this.province.titleActive = this.city.titleActive = this.area.titleActive = false;
// break;
// default:
// this.province.title = "请选择";
// this.province.showList = this.province.titleActive = true;
// this.city.showList = this.area.showList = this.street.showList = false;
// this.city.titleActive = this.area.titleActive = this.street.titleActive = false;
// break;
// }
// },
// /* 获取地址数据绑定 */
// switchAddress(id, caption) {
// if (!id) {
// id = 0;
// }
// this.changeShow(id, caption);
// $.get(
// "/home/getaddress.json",
// {
// id: id
// },
// resultData => {
// /* 结果返回 */
// if (resultData.length < 1) {
// areaCode.val(id);
// let returnTitle = this.returnTitle();
// area.val(returnTitle);
// this.show = false;
// // this.$emit("modify.addressAct", {
// // code: id,
// // area: returnTitle
// // });
// }
// /* 数据绑定 */
// switch ((id + "").length) {
// case 2:
// this.citys = resultData;
// break;
// case 4:
// this.areas = resultData;
// break;
// case 6:
// this.streets = resultData;
// break;
// default:
// this.provinces = resultData;
// break;
// }
// }
// );
// },
// /* 关闭地址选择组件 */
// closeAddBox() {
// this.show = false;
// },
// /* 点击地址标题时的处理 */
// clickTitle(type) {
// switch (type) {
// case "province":
// if (!this.supportChangeProvince) {
// return false;
// }
// if (this.provinces.length < 1) {
// this.switchAddress();
// }
// this.province.titleActive = this.province.showList = true;
// this.city.titleActive = this.area.titleActive = this.street.titleActive = false;
// this.city.title = this.area.title = this.street.title = "";
// break;
// case "city":
// this.city.titleActive = this.city.showList = true;
// this.province.titleActive = this.area.titleActive = this.street.titleActive = false;
// this.province.showList = this.area.showList = this.street.showList = false;
// this.area.title = this.street.title = "";
// break;
// case "area":
// this.area.titleActive = this.area.showList = true;
// this.province.titleActive = this.city.titleActive = this.street.titleActive = false;
// this.province.showList = this.city.showList = this.street.showList = false;
// this.street.title = "";
// break;
// default:
// break;
// }
// }
// },
// created: function() {
// this.switchAddress();
// }
};
</script>
<style lang="scss">
.disable {
color: #a6a6a6;
}
.icon-v:before {
content: "\e6ea";
}
.address-select-component {
position: fixed;
bottom: 0;
left: 0;
top: 0;
width: 100%;
background: rgba(0, 0, 0, 0.5);
.address-select-box {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: #fff;
.component-title {
text-align: center;
line-height: 80px;
font-size: 32px;
color: #ccc;
padding: 0 30px;
.close {
float: right;
}
}
.head-address-ul {
margin: 0 0 0 30px;
padding: 0;
list-style: none;
overflow: hidden;
background-color: white;
font-size: 24px;
color: #444;
li {
display: block;
float: left;
height: 40px;
line-height: 40px;
position: relative;
margin-right: 70px;
}
li:last-child {
margin-right: 30px;
}
.head-address-li {
color: #f23030;
}
.head-address-li:after {
width: 100%;
height: 1px;
border-bottom: 2px solid #f23030;
position: absolute;
bottom: 0;
left: 0;
content: "";
}
}
.head-address-ul:after {
content: "";
width: 100%;
height: 1px;
position: absolute;
border-bottom: 1px solid #e3e5e9;
left: 0;
bottom: 0;
transform: scaleY(0.5);
-webkit-transform: scaleY(0.5);
}
.address-container {
margin: 0;
overflow: hidden;
height: 100%;
width: 100%;
border-top: solid 1px #ccc;
.address-content {
transform: translate(0, 0) translateZ(0);
height: 620px;
}
}
.address-ul {
padding: 0;
margin: 0;
list-style: none;
height: 100%;
overflow: auto;
font-size: 24px;
color: #232326;
li {
height: 80px;
line-height: 80px;
padding-left: 30px;
position: relative;
overflow: hidden;
span {
color: #f23030;
font-size: 14px;
}
}
li:after {
content: "";
width: 100%;
height: 1px;
position: absolute;
left: 0;
bottom: 0;
transform: scaleY(0.5);
-webkit-transform: scaleY(0.5);
}
}
}
}
</style>
... ...
<template>
<CubeScroll class="main-container" ref="scroll" :options="scrollOpts">
<div class="user-list">
<div v-for="(item, index) in list" :key="index" class="item" @click="toOrderPage(item)">
<slot name="item" :data="item">
<div class="user-item">
<div class="user-info">
<div class="extra">
<p class="name">{{item.consignee}}</p>
<p class="mobile">{{item.mobile}}</p>
<div v-if="item.is_default === 'Y'" class="tag-btn">默认</div>
<div v-if="item.tag_code" class="tag-btn">{{item.tag}}</div>
<div class="option-btn" :data-item="item" :data-add="false" @click="toEditorPage">编辑</div>
</div>
<p class="address">{{item.area}}{{item.address}}</p>
<div class="border-line"></div>
</div>
</div>
</slot>
</div>
</div>
<div class="add-btn" :data-add="true" @click="toEditorPage">添加地址</div>
</CubeScroll>
</template>
<script>
import { get } from "lodash";
import { Scroll, Loading } from "cube-ui";
export default {
props: {
list: {
type: Array,
default: function() {
return [];
}
}
},
data() {
return {
scrollOpts: {
bounce: false
}
};
},
methods: {
toOrderPage(item) {
this.$router.push({
name: "detail",
params: {
consignee: item.consignee,
mobile: item.mobile,
area: item.area,
address: item.address
}
});
},
toEditorPage(event) {
event.stopPropagation();
let isAdd = event.currentTarget.dataset.add;
let item = event.currentTarget.dataset.item || {};
if (isAdd) {
this.$router.push({
name: "addressEdit"
});
} else {
this.$router.push({
name: "addressEdit",
item: item
});
}
}
},
components: {
CubeScroll: Scroll
}
};
</script>
<style lang="scss" scoped>
/deep/ {
.cube-scroll-content {
min-height: 100%;
}
.cube-scroll-list-wrapper {
overflow: auto;
}
.cube-loading-spinners {
margin: auto;
}
}
.user-list {
background-color: white;
.border-line {
height: 1px;
margin-top: 40px;
background-color: #e0e0e0;
}
}
.user-item {
display: flex;
padding-top: 40px;
padding-left: 40px;
padding-right: 40px;
align-items: center;
.user-info {
flex-grow: 1;
overflow: hidden;
}
.extra {
display: flex;
flex-direction: row;
.name {
font-size: 32px;
font-weight: 400;
color: #000000;
line-height: 44px;
}
.mobile {
display: block;
margin-left: 20px;
font-size: 32px;
font-weight: 400;
color: #000000;
line-height: 44px;
}
.tag-btn {
width: 80px;
line-height: 44px;
font-size: 22px;
text-align: center;
background-color: #002b47;
margin-left: 18px;
color: white;
}
.option-btn {
display: block;
width: 48px;
line-height: 44px;
letter-spacing: -0.29;
color: black;
font-size: 24px;
position: absolute;
right: 40px;
}
}
.address {
width: 100%;
font-size: 22px;
line-height: 1.4;
margin-top: 16px;
color: #b0b0b0;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
}
.add-btn {
height: 100px;
line-height: 100px;
font-size: 32px;
text-align: center;
background-color: #002b47;
color: white;
position: absolute;
left: 40px;
right: 40px;
bottom: 40px;
}
</style>
... ...
<template>
<div class="form-item">
<slot></slot>
</div>
</template>
<script>
export default {
name: 'FormItem',
props: {
model: {
type: String
}
},
data() {
return {
items: []
};
},
methods: {
validate() {
let result = true;
this.items.forEach(i => {
if (!i.validate()) {
result = false;
}
});
return result;
},
getItem() {
this.items = this.$children.filter(i => i.$options.name === 'CUpload' || i.$options.name === 'CInput' || i.$options.name === 'CDatePick');
}
},
mounted() {
this.getItem();
}
};
</script>
<style lang="scss" scoped>
.form-item {
border-bottom: 2px solid #eee;
padding: 30px 0;
}
</style>
... ...
<template>
<div class="input-class">
<div class="wrapper-label" v-if="label">
<label class="input-label">{{label}}</label>
<span class="tip" v-if="showRequired">{{ required ? tip.required : tip.optional}}</span>
<span class="error" v-if="showError">{{error}}</span>
</div>
<slot>
<input
ref="input"
:type="type"
class="wrapper-input"
:placeholder="placeHolder"
:value="inputValue"
@input="onInputChange"
@blur="validate"
:maxlength="maxLength"
/>
</slot>
</div>
</template>
<script>
const NUMREG = /^[0-9]+([.]{1}[0-9]+){0,1}$/;
export default {
name: "CInput",
props: {
value: {
type: [String, Number],
default() {
return "";
}
},
label: {
type: String,
default() {
return "";
}
},
type: {
type: String,
default() {
return "";
}
},
placeHolder: {
type: String,
default() {
return "";
}
},
showRequired: {
type: Boolean,
default() {
return false;
}
},
required: {
type: Boolean,
default() {
return false;
}
},
maxLength: {
type: Number,
default() {
return 100;
}
}
},
data() {
return {
inputValue: this.value,
tipError: "不能为空",
numTipError: "只能为数字",
error: "不能为空",
showError: false,
tip: {
required: "(必填)",
optional: "(选填)"
}
};
},
methods: {
onInputChange() {
if (this.$refs.input.value.length > this.maxLength) {
this.$refs.input.value = this.$refs.input.value.slice(
0,
this.maxLength
);
}
this.inputValue = this.$refs.input.value;
this.$emit("input", this.$refs.input.value);
},
setShowError(status = true) {
this.showError = status;
},
validate() {
if (!this.required) {
return true;
}
if (!this.inputValue) {
this.error = this.tipError;
this.showError = true;
return false;
} else {
if (this.type === "number") {
if (NUMREG.test(this.inputValue)) {
this.showError = false;
return true;
} else {
this.error = this.numTipError;
this.showError = true;
return false;
}
} else {
this.showError = false;
return true;
}
}
}
}
};
</script>
<style lang="scss" scoped>
.input-label {
font-size: 36px;
display: inline-block;
font-weight: bold;
}
.wrapper-label {
margin-bottom: 30px;
}
.wrapper-input {
font-size: 28px;
width: 100%;
/*line-height: 1;*/
line-height: normal;
}
.error {
margin-left: 12px;
color: #d0021b;
}
.tip {
font-size: 20px;
}
::-webkit-input-placeholder {
color: #aaa;
}
</style>
... ...
<template>
<label class="container" @click.stop.prevent="onClickLabel">
<span :class="classes"></span>
<span :class="labelClasses">{{label.text}}</span>
</label>
</template>
<script>
export default {
name: "CRadio",
props: {
value: {
type: [String, Number, Boolean],
default() {
return "";
}
},
label: {
type: Object,
default() {
return { text: "", value: false };
}
},
active: {
type: false,
default() {
return false;
}
}
},
data() {
return {
checked: false
};
},
methods: {
updateLabel() {
this.updateStatus();
},
onClickLabel() {
if (this.$parent.$options.name !== "Radio-Group") {
this.checked = !this.checked;
this.$emit("input", this.checked);
return;
}
this.$emit("input", this.label.value);
},
updateStatus() {
if (this.value === this.label.value) {
this.checked = true;
} else {
this.checked = false;
}
}
},
computed: {
classes() {
return [
"checkmark",
{
"cubeic-round-border": !this.checked,
"cubeic-right": this.checked
}
];
},
labelClasses() {
return [
"radio-label",
{
active: this.checked || this.active,
ml5: this.active
}
];
}
},
watch: {
value() {
this.updateStatus();
}
},
created() {
// this.updateLabel();
this.updateStatus();
}
};
</script>
<style lang="scss" scoped>
.container {
font-size: 28px;
display: flex;
align-content: center;
}
.checkmark {
font-size: 40px;
display: flex;
align-items: center;
}
.radio-label {
display: inline-block;
height: 55px;
font-size: 28px;
line-height: 55px;
margin-left: 20px;
color: #999;
&.active {
color: black;
}
&.ml5 {
margin-left: 10px;
}
}
</style>
... ...
export default [{
name: 'address',
path: '/xianyu/address',
component: () => import(/* webpackChunkName: "address" */ './address')
}, {
name: 'addressEdit',
path: '/xianyu/address/edit',
component: () => import(/* webpackChunkName: "address" */ './addressEdit')
}];
... ...
import Address from './address';
export default [...Address];
... ...
<template>
<!-- <LayoutApp :show-back="true">
<div class="body" ref="body">
<List></List>
<div v-for="(item, index) in channelData" :key="index">
<template v-if="item.template_name == 'focus'">
<Slider :list="list"></Slider>
</template>
<template v-if="item.template_name == 'hotSeries'">
<Hot :list="item.data"></Hot>
</template>
<template v-if="item.template_name == 'single_image'">
<Banner :linkUrl="linkUrl" :imgUrl="imgUrl"></Banner>
</template>
<template v-if="item.template_name == 'twoPicture'">
<TwoBanner :list="item.data"></TwoBanner>
</template>
</div>
<!-- <ScrollNav></ScrollNav> -->
</div>
<Footer class="footer"></Footer>
</LayoutApp> -->
<div>wdwqdwqdwq </div>
</template>
<script>
import Footer from './components/footer';
import List from './components/list';
import Slider from './components/slider'; // 轮播图
import Banner from './components/banner'; // 一张图广告位
import TwoBanner from './components/twoBanner'; // 两张图广告位
import Hot from './components/hot'; // 热门系列
import ScrollNav from './components/scrollNav'; // 滑动导航
import { createNamespacedHelpers } from 'vuex';
const {mapState, mapActions} = createNamespacedHelpers('home/channel');
export default {
data() {
return {
list: [
{
url: 'http://www.didichuxing.com/',
image: '//webapp.didistatic.com/static/webapp/shield/cube-ui-examples-slide01.png'
},
{
url: 'http://www.didichuxing.com/',
image: '//webapp.didistatic.com/static/webapp/shield/cube-ui-examples-slide01.png'
}
],
linkUrl: 'https://www.baidu.com',
imgUrl: 'https://ss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/baike/pic/item/cb8065380cd79123d7648113a7345982b3b780d4.jpg',
list2: [
{
"data": [
{
"bgColor": "",
"src": "http://img10.static.yhbimg.com/yhb-img01/2017/07/26/16/01d47fc95f71a19469f38a19c7c843fe43.jpg?imageView2/{mode}/w/{width}/h/{height}",
"title": "",
"url": "https://m.yohobuy.com/?title=标题&openby:yohobuy={\"action\":\"go.collagehome\",\"params\":{\"title\":\"标题\"}}"
},
{
"bgColor": "",
"src": "http://img10.static.yhbimg.com/yhb-img01/2017/07/26/16/01e90704cc16d5a32a1680ae1d415426c6.jpg?imageView2/{mode}/w/{width}/h/{height}",
"title": "",
"url": "https://m.yohobuy.com/groupPurchase?activityId=56&type=2&title=模式2测试&openby:yohobuy={\"action\":\"go.activitytemplate\",\"params\":{\"activityId\":\"56\",\"type\":\"2\",\"title\":\"模式2测试\"}}"
},
{
"bgColor": "",
"src": "http://img10.static.yhbimg.com/yhb-img01/2017/07/27/09/01cc06fea3c1d22375abcd90836759f85f.png?imageView2/{mode}/w/{width}/h/{height}",
"title": "",
"url": "http://m.yohobuy.com/groupPurchase?activityId=58&type=2&title=团购状态验证&openby:yohobuy={\"action\":\"go.activitytemplate\",\"params\":{\"activityId\":\"58\",\"type\":\"2\",\"title\":\"团购状态验证\"}}"
},
{
"bgColor": "",
"src": "http://img11.static.yhbimg.com/yhb-img01/2017/09/20/09/01cf74dac1b0a354b82dc894dc66634352.jpg?imageView2/{mode}/w/{width}/h/{height}",
"title": "",
"url": "https://list.m.yohobuy.com/?specialsale_id=2&gender=1,3&actiontype=2&cover_url=http://img10.static.yhbimg.com/couponImg/2018/08/27/10/01021a4ec4029934bcffca8ee912f61654.jpg&openby:yohobuy={\"action\":\"go.list\",\"params\":{\"actiontype\":\"2\",\"cover_url\":\"http://img10.static.yhbimg.com/couponImg/2018/08/27/10/01021a4ec4029934bcffca8ee912f61654.jpg\",\"gender\":\"1,3\",\"specialsale_id\":\"2\"}}"
},
{
"bgColor": "",
"src": "http://img11.static.yhbimg.com/yhb-img01/2017/10/13/18/018044cceeb5a2afe6223a1412ccda89b9.jpg?imageView2/{mode}/w/{width}/h/{height}",
"title": "",
"url": "https://search.m.yohobuy.com/?productPool=680&title=618抢先购-6.1折封顶&openby:yohobuy={\"action\":\"go.poollist\",\"params\":{\"title\":\"618抢先购-6.1折封顶\",\"productPool\":\"680\"}}"
},
{
"bgColor": "",
"src": "http://img11.static.yhbimg.com/yhb-img01/2018/03/06/11/019dea67754e6c4c08711b118c3d050891.JPG?imageView2/{mode}/w/{width}/h/{height}",
"title": "秒杀",
"url": "http://m.yohobuy.com/product/seckill?type=2&openby:yohobuy={\"action\":\"go.h5\",\"params\":{\"param\":{\"type\":\"2\"},\"type\":\"2\",\"url\":\"http://m.yohobuy.com/product/seckill\"}}"
},
{
"bgColor": "",
"src": "http://img11.static.yhbimg.com/yhb-img01/2018/03/06/11/016a0402a7ff364326046b215f4d088cb8.JPG?imageView2/{mode}/w/{width}/h/{height}",
"title": "",
"url": "https://m.yohobuy.com/home/family?openby:yohobuy={\"action\":\"go.family\"}"
}
],
"focus_type": "2",
"original_template_id": 1,
"template_id": "1",
"template_intro": "焦点图",
"template_name": "focus"
},
{
"template_name": "hotSeries",
"data": [
{
"image_url": "http://img11.static.yhbimg.com/yhb-img01/2017/07/26/16/0186f834d5a21f26717254407c28fc3c53.jpg",
"series_name": "哈哈",
"series_id": "1"
},
{
"image_url": "http://img11.static.yhbimg.com/yhb-img01/2017/07/26/16/0186f834d5a21f26717254407c28fc3c53.jpg",
"series_name": "耐克",
"series_id": "2"
},
{
"image_url": "http://img11.static.yhbimg.com/yhb-img01/2017/07/26/16/0186f834d5a21f26717254407c28fc3c53.jpg",
"series_name": "哈哈",
"series_id": "1"
},
{
"image_url": "http://img11.static.yhbimg.com/yhb-img01/2017/07/26/16/0186f834d5a21f26717254407c28fc3c53.jpg",
"series_name": "耐克",
"series_id": "2"
},
{
"image_url": "http://img11.static.yhbimg.com/yhb-img01/2017/07/26/16/0186f834d5a21f26717254407c28fc3c53.jpg",
"series_name": "哈哈",
"series_id": "1"
},
{
"image_url": "http://img11.static.yhbimg.com/yhb-img01/2017/07/26/16/0186f834d5a21f26717254407c28fc3c53.jpg",
"series_name": "耐克",
"series_id": "2"
},
{
"image_url": "http://img11.static.yhbimg.com/yhb-img01/2017/07/26/16/0186f834d5a21f26717254407c28fc3c53.jpg",
"series_name": "耐克",
"series_id": "2"
},
],
"template_intro": "热门系列",
"template_id": "1"
},
{
"template_name": "single_image",
"data": [
{
"image_url": "http://img11.static.yhbimg.com/yhb-img01/2017/07/26/16/0186f834d5a21f26717254407c28fc3c53.jpg",
"series_name": "",
"series_id": "1"
},
{
"image_url": "http://img11.static.yhbimg.com/yhb-img01/2017/07/26/16/0186f834d5a21f26717254407c28fc3c53.jpg",
"series_name": "",
"series_id": "2"
}
],
"template_intro": "热门系列",
"template_id": "1"
},
{
"template_name": "twoPicture",
"data": [
{
"src": "http://img11.static.yhbimg.com/yhb-img01/2019/09/24/14/01bdf0e379025b33c9690861b843dbd966.jpg",
"id": "",
"url": "https://m.yohobuy.com/?openby:yohobuy={'action':'go.bargainlist'}"
},
{
"src": "http://img11.static.yhbimg.com/yhb-img01/2019/09/24/14/01bdf0e379025b33c9690861b843dbd966.jpg",
"id": "",
"url": "https://m.yohobuy.com/?openby:yohobuy={'action':'go.bargainlist'}"
},
],
"template_intro": "热门系列",
"template_id": "1"
},
{
"template_name": "single_image",
"data": [
{
"image_url": "http://img11.static.yhbimg.com/yhb-img01/2017/07/26/16/0186f834d5a21f26717254407c28fc3c53.jpg",
"series_name": "",
"series_id": "1"
},
{
"image_url": "http://img11.static.yhbimg.com/yhb-img01/2017/07/26/16/0186f834d5a21f26717254407c28fc3c53.jpg",
"series_name": "",
"series_id": "2"
}
],
"template_intro": "热门系列",
"template_id": "1"
},
],
}
},
computed: {
...mapState(['channelData']),
},
created() {
},
mounted() {
this.fetchChannelList();
},
methods: {
...mapActions(['fetchChannelList']),
},
components: {
Footer,
List
Slider,
Banner,
TwoBanner,
Hot,
ScrollNav
}
};
</script>
<style lang="scss" scoped>
.footer {
position: absolute;
bottom: 0;
width: 100%;
z-index: 100;
}
.body {
height: 100%;
overflow-y: auto;
// padding: 0 40px;
}
</style>
... ...
<template>
<div class="banner">
<img :src="resource" alt="">
<div class="link" @click="onClick"></div>
<a :href="linkUrl">
<img class="banner-image" :src="imgUrl" alt="" />
</a>
</div>
</template>
<script>
import {createNamespacedHelpers} from 'vuex';
const {mapState} = createNamespacedHelpers('gain');
export default {
computed: {
...mapState(['resource'])
name: 'banner',
props: {
linkUrl: {
type: String,
default: true,
},
imgUrl: {
type: String,
default: true,
},
},
methods: {
onClick() {
this.$yoho.goNewPage({
url: 'https://activity.yoho.cn/feature/5729.html?title=活动规则&openby:yohobuy={"action":"go.h5","params":{"title":"活动规则","url":"https://activity.yoho.cn/feature/5729.html"}}'
});
}
// onClick() {
// this.$yoho.goNewPage({
// url: 'https://activity.yoho.cn/feature/5729.html?title=活动规则&openby:yohobuy={"action":"go.h5","params":{"title":"活动规则","url":"https://activity.yoho.cn/feature/5729.html"}}'
// });
// }
}
};
</script>
<style lang="scss" scoped>
.banner {
font-size: 0;
padding-bottom: 20px;
background-color: #f0f0f0;
img {
position: relative;
width: 100%;
margin: 20px 0;
overflow: hidden;
.banner-image {
width: 100%;
}
.link {
position: absolute;
width: 200px;
height: 200px;
top: 0;
right: 0;
display: block;
}
}
</style>
... ...
<template>
<div class="hot" v-if="list.length > 0">
<ul>
<li v-for="(item, index) in list" :key="index" @click="goProduct(item)">
<div class="hot-image">
<img :src="item.image_url" alt="" />
</div>
<div class="hot-name">{{item.series_name}}</div>
</li>
<li @click="goMore">
<div class="hot-image hot-more">更多</div>
<div class="hot-name">More</div>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'hot',
props: {
list: {
type: Array,
default: true,
},
},
methods: {
goProduct() {
alert('跳转列表!');
},
goMore() {
alert('跳转更多!');
}
// onClick() {
// this.$yoho.goNewPage({
// url: 'https://activity.yoho.cn/feature/5729.html?title=活动规则&openby:yohobuy={"action":"go.h5","params":{"title":"活动规则","url":"https://activity.yoho.cn/feature/5729.html"}}'
// });
// }
}
};
</script>
<style lang="scss" scoped>
.hot {
ul {
overflow: hidden;
li {
width: 25%;
float: left;
text-align: center;
margin-top: 20px;
.hot-image {
width: 150px;
height: 100px;
overflow: hidden;
margin: 0 auto;
img {
width: 100%;
height: 100%;
display: block;
}
}
.hot-name {
margin-top: 20px;
}
.hot-more {
line-height: 100px;
border: 1px solid #999;
}
}
}
}
</style>
... ...
<template>
<div class="ScrollNav">
<ScrollNav>
<ScrollNav-panel
v-for="item in [1,2,3,4,5]"
:key="item"
:label="item">
<div v-for="item in [1,2,3,4,5]" :key="item" :label="item">22222</div>
</ScrollNav-panel>
</ScrollNav>
</div>
</template>
<script>
import Vue from 'vue'
import { Style, ScrollNav } from 'cube-ui';
export default {
name: 'slide',
props: {
// list: {
// type: Array,
// default: true
// },
},
components: {
Style,
ScrollNav
},
computed: {
// ...mapState(['resource'])
},
methods: {
}
};
</script>
<style lang="scss" scoped>
.ScrollNav {
}
</style>
... ...
<template>
<div class="slider" v-if="list.length > 0">
<Slide :data="list"></Slide>
</div>
</template>
<script>
import Vue from 'vue'
import { Style, Slide } from 'cube-ui';
// import { createNamespacedHelpers } from 'vuex';
// const {mapState} = createNamespacedHelpers('channel');
export default {
name: 'slide',
props: {
list: {
type: Array,
default: true
},
},
components: {
Style,
Slide
},
computed: {
// ...mapState(['resource'])
},
methods: {
}
};
</script>
<style lang="scss" scoped>
.slider {
}
</style>
... ...
<template>
<div class="twoBanner" v-if="list.length > 0">
<div class="list" v-for="(item, index) in list" :key="index">
<a :href="item.url">
<img class="banner-image" :src="item.src" :alt="item.alt" />
</a>
</div>
</div>
</template>
<script>
export default {
name: 'twoBanner',
props: {
list: {
type: Array,
default: [1,2],
},
},
methods: {
// onClick() {
// this.$yoho.goNewPage({
// url: 'https://activity.yoho.cn/feature/5729.html?title=活动规则&openby:yohobuy={"action":"go.h5","params":{"title":"活动规则","url":"https://activity.yoho.cn/feature/5729.html"}}'
// });
// }
}
};
</script>
<style lang="scss" scoped>
.twoBanner {
width: 100%;
margin: 20px 0;
overflow: hidden;
display: flex;
// align-items: center;
justify-content: space-between;
.list {
width: 48%;
img {
width: 100%;
height: 200px;
display: block;
}
}
}
</style>
... ...
... ... @@ -4,7 +4,7 @@ export default [
{
name: 'channel',
path: '/xianyu/channel',
component: () => import('./channel/channel')
component: () => import(/* webpackChunkName: "channel" */ './channel/channel')
},
...Mine
...Mine,
];
... ...
... ... @@ -20,37 +20,26 @@ export default {
},
data() {
return {
animate:false,
// lists:[
// {name:'公告1'},
// {name:'公告2'}
// ],
};
},
computed: {
...mapState({
animate: state => state.animate,
lists: state => state.rollNoticeList
})
},
mounted() {
this.fetchRollBoardList()
},
created(){
if(this.lists.length > 1) {
this.fetchRollBoardList().then((data) => {
if(data.length > 1) {
setInterval(this.showMarquee, 3000)
}
},
}
})
},
methods: {
...mapActions(['fetchRollBoardList']),
 showMarquee() {
let that = this
that.animate = true;
setTimeout(()=>{
that.lists.push(that.lists[0]);
that.lists.shift();
that.animate = false;
},800)
},
...mapActions(['fetchRollBoardList','showMarquee']),
}
}
</script>
... ... @@ -68,6 +57,7 @@ export default {
position: absolute;
top: 0;
left: 0;
right: 0;
}
.marquee_top {
... ... @@ -77,9 +67,13 @@ export default {
.marquee_list li {
height: 90px;
width: 100%;
line-height: 90px;
font-size: 24px;
color: #D0021B;
padding-left: 20px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
</style>
... ...
... ... @@ -20,7 +20,7 @@ import scroll from './components/scroll';
import { createNamespacedHelpers } from 'vuex';
const {mapState} = createNamespacedHelpers('home/mine');
const {mapState, mapActions} = createNamespacedHelpers('home/mine');
export default {
data() {
return {
... ... @@ -36,9 +36,24 @@ export default {
}
},
computed:{
...mapState({
username: state => state.username
})
...mapState([
'favoriteNum',
'buyNum'
])
},
created() {
this.fetchResource()
this.fetchFavoriteNum()
this.fetchOrderSummary().then(data => {
console.log(data)
})
this.fetchSellerOrder()
this.fetchAssets().then(data => {
console.log(data)
})
},
methods: {
...mapActions(['fetchFavoriteNum','fetchResource','fetchSellerOrder','fetchOrderSummary', 'fetchAssets'])
},
components: {
tabItem,
... ...
<template>
<div>
<Scroll ref="recyclelist" class="list" :on-fetch="onFetch">
<div >
<NoticeItem v-for="(item, index) in noticeList" :key="index" :data="item"></NoticeItem>
</div>
</Scroll>
</div>
</template>
<script>
import { createNamespacedHelpers } from 'vuex';
const { mapState, mapActions } = createNamespacedHelpers('gain');
import NoticeItem from './noticeItem';
import {
Style,
Scroll,
RecycleList
} from 'cube-ui';
// import { resolve } from 'dns';
export default {
components: {
NoticeItem,
Scroll,
RecycleList,
Style
},
data(){
return {
scrollOptions: {
bounce: {
top: false
},
pullUpLoad: true
},
fixed: false
};
},
mounted(){
// this.fetchList
},
methods:{
// async onPullingUp() {
// const result = await this.fetchList();
// if (!result) {
// this.$refs.scroll.$forceUpdate();
// }
// },
onFetch(){
let items = []
return new Promise((resolve) => {
setTimeout(() => {
for(let i = 0; i < 50; i++){
items.push({
id:i,
contents:'【税率调整】您的商品AIR JORDAN 4 RESET PUSH NONEKJG 2017已经被用户下单,请及时发货'+i,
time:'2018.08.08 17:20'
})
}
resolve(items)
}, 1000)
})
}
},
// async fetchList({ commit, state }) {
// let page = state.page;
// const result = await this.$api.get('/api/union/inviteList', {
// page: page,
// size: state.size
// });
// if (result.code === 200) {
// commit('addList', { list: result.data.list });
// commit('changePage', { page: ++page });
// }
// return result.data ? result.data.length : 0;
// }
}
</script>
\ No newline at end of file
... ...
<template>
<div class="notice-root">
<p class="notice-content">【税率调整】您的商品AIR JORDAN 4 RESET PUSH NONEKJG 2017已经被用户下单,请及时发货</p>
<div class="time">
<time> 2018.08.08 17:20</time>
</div>
</div>
</template>
<script>
// export default {
// data(){
// },
// props:[
// ]
// };
// methods: {
// onGo()
// };
</script>
<style>
.notice-root{
margin-left: 40px;
margin-right: 40px;
}
.notice-content{
font-family: 'PingFang-SC-Regular';
font-size: 28px;
color: #000000;
}
.time {
font-size: 28px;
color: #999999;
}
</style>
\ No newline at end of file
... ...
<template>
<LayoutApp :show-back="true">
<div class="body" ref="body">
<List>
</List>
</div>
</LayoutApp>
</template>
<script>
import List from './components/list';
export default {
components: {
List
}
};
</script>
<style>
.body {
height: 100%;
overflow-y: auto;
}
</style>
\ No newline at end of file
... ...
... ... @@ -4,5 +4,7 @@ import List from './list';
import Product from './product';
import Home from './home';
import Passport from './passport';
import Address from './address';
import Notice from './notice';
export default [...Order, ...Common, ...List, ...Product, ...Home, ...Passport];
export default [...Order, ...Common, ...List, ...Product, ...Home, ...Passport, ...Address, ...Notice];
... ...
<template>
<div>
<div class="item" v-if="list.length" v-for="(product,index) in list"
:class="((index === 0 || index === 1) ? 'top-line':'') +' '+((index) % 2 === 0 ? 'right-line' :'')"
:key="index">
<div class="item-price">{{product.price ? '¥' + product.price : ' '}}</div>
<ImgSize class="item-imge" :src="product.default_images" :width="300" :height="300"/>
<div class="item-name">{{product.product_name}}</div>
</div>
</div>
</template>
<script>
import {Scroll} from 'cube-ui';
import ImgSize from '../../../components/img-size';
export default {
props: {
list: Array,
},
methods: {},
components: {
ImgSize,
Scroll,
}
};
</script>
<style lang="scss" scoped>
.top-line {
border-top: 1px #ddd solid;
}
.right-line {
border-right: 1px #ddd solid;
}
.item {
width: 9.37rem;
border-bottom: 1px #ddd solid;
padding: 28px 38px 0 38px;
float: left;
overflow: hidden;
height: 560px;
}
.item-price {
margin-bottom: 38px;
font-size: 28px;
color: #000;
letter-spacing: 0;
}
.item-imge {
width: 300px;
height: 300px;
}
.item-name {
font-size: 28px;
color: #000;
letter-spacing: 0;
text-align: center;
line-height: 40px;
margin-top: 38px;
margin-bottom: 44px;
}
</style>
... ...
export default [{
name: 'list',
path: '/xianyu/list',
component: () => null
component: () => import(/* webpackChunkName: "list" */ './list')
},
{
name: 'filter',
path: '/xianyu/list/filter',
component: () => import(/* webpackChunkName: "filter" */ './filter')
},
{
name: 'search',
path: '/xianyu/list/search',
component: () => import(/* webpackChunkName: "search" */ './search')
}];
... ...
<template>
<LayoutApp :show-back="true">
<Scroll :scrollEvents="['scroll']" :options="scrollOptions" @scroll="scroll"
@pulling-up="onPullingUp">
<ProductList :list="productList.list"></ProductList>
</Scroll>
</LayoutApp>
</template>
<script>
import ProductList from './components/productList';
import {Scroll} from 'cube-ui';
import {createNamespacedHelpers} from 'vuex';
const {mapState, mapActions} = createNamespacedHelpers('list');
export default {
name: 'list',
components: {
ProductList,
Scroll
},
data() {
return {
scrollOptions: {
bounce: {
top: false
},
pullUpLoad: true
},
fixed: false
};
},
mounted() {
this.fetchProductList();
},
methods: {
...mapActions(['fetchProductList']),
async onPullingUp() {
await this.fetchProductList();
},
scroll({ y }) {
const height = this.$refs.banner.$el.offsetHeight + this.$refs.header.offsetHeight;
if (-y >= height) {
this.fixed = true;
} else {
this.fixed = false;
}
}
},
computed: {
...mapState(['productList']),
},
};
</script>
<style scoped>
</style>
... ...
export default [
{
name: 'noticeList',
path: '/xianyu/notice',
component: () => import(/* webpackChunkName: "notice" */ './list/notice')
}
];
... ...
<template>
<div>
<Scroll
ref="scroll"
class="list"
:data="noticeList"
:options="scrollOption"
@pulling-up="onPullingUp">
<div class="content-root">
<NoticeItem v-for="(item, index) in noticeList" :key="index" :data="item"></NoticeItem>
</div>
</Scroll>
</div>
</template>
<script>
import { createNamespacedHelpers } from 'vuex';
const { mapState, mapActions} = createNamespacedHelpers('notice');
import NoticeItem from './noticeItem';
import {
Style,
Scroll,
RecycleList
} from 'cube-ui';
// import { resolve } from 'dns';
export default {
components: {
NoticeItem,
Scroll,
RecycleList,
Style
},
name: 'NoticeListPage',
data(){
return {
data: {},
noMore: false,
scrolling: false,
scrollOption: {
// bounce: false,
pullUpLoad:true,
},
};
},
created(){
// console.log(this.noticeList)
this.fetchNoticeList();
},
// activated(){
// this.fetchList();
// },
// async serverPrefetch(){
// this.fetchNoticeList();
// },
mounted(){
// this.fetchNoticeList();
},
computed: {
...mapState(['noticeList','fetchNoticePage']),
},
methods:{
...mapActions(['fetchNoticeList']),
onScroll(){
console.log('onScroll')
this.scrolling = true;
this._scTimer && clearTimeout(this._scTimer);
this._scTimer = setTimeout(() => {
this.scrolling = false;
}, 400);
},
onPullingUp(){
console.log('onPullingUp:'+this.noMore)
},
onPullingDown() {
console.log('onPullingDown:'+this.noMore)
},
onFetch() {
// console.log('fetchList:'+this.noticeList)
// let items = []
// return new Promise((resolve) => {
// // 模拟请求 50 条数据,因为 size 设置为 50
// setTimeout(() => {
// for (let i = 0; i < 50; i++) {
// items.push({
// id: i,
// avatar: 'https://s3.amazonaws.com/uifaces/faces/twitter/danpliego/128.jpg',
// msg: '123',
// time: 'Thu Oct 25 2018 15:02:12 GMT+0800 (中国标准时间)'
// })
// }
// resolve(items)
// }, 1000)
// })
if (this.noMore) {
return;
}
this.fetchNoticeList();
// this.fetchNoticeList({}).then(res => {
// if (+this.fetchNoticePage > +get(res, 'data.totalPage')) {
// this.noMore = true;
// }
// this.$nextTick(() => {
// this.$refs.scroll.forceUpdate(true);
// });
// });
}
},
}
</script>
<style>
.list{
/* height: 400px; */
width: 100%;
}
.content-root{
/* height: 400px; */
width: 100%;
}
</style>
\ No newline at end of file
... ...
<template>
<div class="notice-root">
<p class="notice-content">{{data.name}}</p>
<div class="time">
<time> {{data.createTime}}</time>
</div>
<div class="item-split-line"/>
</div>
</template>
<script>
import {
Style,
Scroll,
RecycleList
} from 'cube-ui';
export default {
data(){
return {};
},
props:{
data: {
type: Object,
default() {
return {};
}
}
},
created() {
console.log(this.data)
},
methods: {
onFetch: Function,
goDetail(){
this.$router.push({
name: 'notice',
params: {
url: this.data.url,
}
});
}
},
components: {
Scroll,
RecycleList,
Style
},
};
</script>
<style>
.notice-root{
margin-left: 40px;
margin-right: 40px;
padding-top: 32px;
}
.notice-content{
font-family: 'PingFang-SC-Regular';
font-size: 28px;
color: #000000;
line-height: 1.5;
text-overflow: ellipsis;
-webkit-line-clamp: 2;
display: -webkit-box;
-webkit-box-orient: vertical;
overflow: hidden;
}
.time {
font-size: 28px;
color: #999999;
margin-top: 12px;
}
.item-split-line {
height: 1px;
width: 100%;
background-color: #EEEEEE;
margin-top: 32px;
}
</style>
\ No newline at end of file
... ...
<template>
<LayoutApp :show-back="true">
<div class="body" ref="body">
<List>
</List>
</div>
</LayoutApp>
</template>
<script>
import List from './components/list';
export default {
components: {
List
}
};
</script>
<style>
.body {
height: 100%;
overflow-y: auto;
}
</style>
\ No newline at end of file
... ...
<!--买家求购确认页-->
<template>
<LayoutApp :show-back="true">
<div class="body" ref="body">
<div class="topContainer">
<div class="topView">
<div class="title">出价求购</div>
</div>
<!--商品信息-->
<div class="productDetail">
<div class="productImageWrapper">
<!--<ImageFormat class="image" :lazy="lazy" :src="" :width="136" :height="180"></ImageFormat>-->
</div>
<div class="productPrice">
<span class="size">{{sizeInfo}}</span>
<div class="pricedetail">
<span class="priceTitle">最低售价</span>
<span class="price">{{''}}</span>
</div>
</div>
</div>
<div class="inputView">
<span class="inputViewIcon">
¥
</span>
<Input class="wordText" v-model="inputPrice" clearable="true" type="number" placeholder="定价需以9为结尾,例如1999"></Input>
</div>
<div>
<div class="sales">
<span class="tipHeaderText">需要支付保证金:</span>
<span class="tipPriceText">¥{{''}}</span>
</div>
</div>
<div class="saleDetailTips">
{{terms}}
</div>
<div class="space"></div>
<div class="line"></div>
<div class="space"></div>
<div>
<span>商品金额:</span>
<span>{{''}}</span>
</div>
<div>
<span>运费:</span>
<span>{{''}}</span>
</div>
<div>
<span>预计实付金额:</span>
<span>{{''}}</span>
</div>
<order-address></order-address>
<div class="line"></div>
<div class="space"></div>
<day-choose></day-choose>
<div class="space"></div>
<div class="line"></div>
<div class="bottomContainer">
<Button type="submit" disabled="true">提交</Button>
</div>
</div>
</div>
</LayoutApp>
</template>
<script>
import {Input, Button} from 'cube-ui';
import OrderAddress from './components/confirm/address';
import DayChoose from './components/askorder/day-choose';
export default {
name: 'BuyerAskOrder',
components: {Button, DayChoose, OrderAddress},
props: {
lazy: Boolean,
product: Object,
},
component: {
Input,
OrderAddress,
Button,
},
data() {
return {
inputPrice: '',
terms: '求购须支付定金。\n卖家接单后,你需要在24小时内支付商品款。卖家将在你付款后36小时内发货。'
};
},
computed: {
sizeInfo: {
get() {
return '44'
// return goodsInfo ? goodsInfo.colorName + ',' + goodsInfo.sizeName : ''
}
}
}
};
</script>
<style lang="scss" scoped>
.body {
height: 100%;
position: relative;
}
.topContainer {
height: calc(100% - 100px);
padding-left: 20px;
padding-right: 20px;
}
.topView {
width: 100%;
height: 167px;
display: flex;
align-items: flex-start;
background-color: white;
}
.title {
font-weight: bold;
font-size: 34px;
color: #000;
letter-spacing: 0.41px;
line-height: 41px;
margin-left: 20px;
margin-top: 5px;
}
.productDetail {
display: flex;
flex-direction: row;
width: calc(100% - 40);
height: 120px;
margin-left: 20px;
align-items: center;
margin-top: 5px;
background-color: white;
}
.productImageWrapper {
width: 120px;
height: 120px;
background-color: white;
display: flex;
justify-content: center;
align-items: center;
}
.productImage {
width: 110px;
height: 110px;
}
.productPrice {
width: calc(100% - 120px - 40px - 10px);
height: 120px;
margin-left: 10px;
}
.size {
margin-top: 37px;
font-family: "PingFang SC";
font-size: 12px;
color: #999;
letter-spacing: 0;
}
.pricedetail {
display: flex;
flex-direction: row;
height: 30px;
margin-top: 5px;
align-items: flex-end;
}
.priceTitle {
font-family: "PingFang SC";
font-size: 14px;
color: #000;
letter-spacing: 0;
}
.price {
font-family: "DIN Alternate";
font-size: 14px;
color: #000;
line-height: 20.5px;
letter-spacing: 0px;
}
.priceTip {
font-family: "PingFang SC";
font-size: 12px;
color: #D0021B;
letter-spacing: 0px;
width: 80px;
text-align: right;
}
.inputView {
width: calc(100% - 40px);
height: 50px;
border-radius: 5px;
display: flex;
flex-direction: row;
align-items: center;
background-color: #f5f5f5;
}
.inputViewIcon{
line-height: 50px;
font-size: 20px;
color: #000;
margin-left: 10px;
}
.wordText {
margin-left: 10px;
font-family: "DIN Alternate";
font-size: 16px;
color: #000;
width: 100%;
background-color: transparent;
}
.sales {
display: flex;
flex-direction: row;
align-items: center;
}
.tipHeaderText {
font-family: "PingFang SC";
font-size: 14px;
color:#000;
letter-spacing: 0;
margin-left: 20px;
margin-top: 15px;
}
.tipPriceText {
font-family: "PingFang SC";
font-size: 14px;
color: #D0021B;
letter-spacing: 0;
margin-top: 15px;
}
.saleDetailTips {
font-family: "PingFang SC";
font-size: 12px;
color: #999;
letter-spacing: 0px;
margin-top: 5px;
margin-left: 20px;
width: calc(100% - 40px);
}
.space {
width: 100%;
background-color: white;
height: 20px;
}
.line {
width: 100%;
height: 1px;
background-color: #eee;
}
.priceCell {
display: flex;
width: 100%;
height: 25px;
align-items: center;
justify-content: space-between;
}
.bottomContainer {
position: absolute;
bottom: 0px;
height: 100px;
display: flex;
align-items: stretch;
width: 100%;
left: 0px;
}
</style>
... ...
<template>
<LayoutApp :show-back="true">
<div class="body">
<TitleComp txt="出售"></TitleComp>
<ProductInfo :data="orderDetail.goodsInfo" class="product-info"></ProductInfo>
<InputPrice class="input-price"></InputPrice>
<OrderMargin class="order-item order-margin"></OrderMargin>
<OrderFee class="order-item"></OrderFee>
<AddressInfo :data="orderDetail.userAddress" class="order-item"></AddressInfo>
<OrderAgree v-model="agree" class="order-item"></OrderAgree>
</div>
<ConfirmButton :txt="txt" class="footer"></ConfirmButton>
</LayoutApp>
</template>
<script>
import ProductInfo from './components/confirm/product';
import InputPrice from './components/confirm/input-price';
import AddressInfo from './components/confirm/address';
import ConfirmButton from './components/confirm/button';
import TitleComp from './components/confirm/title';
import OrderMargin from './components/confirm/order-margin';
import OrderFee from './components/confirm/order-fee';
import OrderAgree from './components/confirm/agree';
import { createNamespacedHelpers } from 'vuex';
const { mapState, mapActions, mapMutations } = createNamespacedHelpers('order/orderConfirm');
export default {
name: 'OrderConfirm',
props: {
orderCode: {
type: String,
default: ''
}
},
components: {
ProductInfo,
AddressInfo,
ConfirmButton,
InputPrice,
TitleComp,
OrderMargin,
OrderFee,
OrderAgree
},
data() {
return {
txt: '提交',
agree: false
};
},
mounted() {
this.fetchOrderDetail({orderCode: this.orderCode})
},
computed: {
...mapState(['orderDetail'])
},
methods: {
...mapActions(['fetchOrderDetail'])
}
};
</script>
<style lang="scss" scoped>
.footer {
position: absolute;
bottom: 0;
width: 100%;
z-index: 100;
}
.body {
height: 100%;
margin: 0 40px;
padding-bottom: 140px;
overflow-y: auto;
}
.order-item {
padding-top: 40px;
padding-bottom: 40px;
}
.order-item + .order-item {
border-top: 1px solid #eee;
}
</style>
... ...
<!--求购时限选择-->
<template>
<div class="customSelectWrapper">
<div class="customSelectTextWrapper">
<span class="leftText">求购期限:</span>
<div class="rightWrapper">
<span class="rightText">{{value}}</span>
<i class="cubeic-arrow" ></i>
</div>
</div>
<Select
v-model="value"
:title="title"
:options="options"
@change="change"
class="customSelect"
/>
</div>
</template>
<script>
import {Select} from 'cube-ui';
export default {
name: 'DayChoose',
components: {Select},
data() {
return {
options: ['1天', '3天', '7天', '15天', '30天'],
value: '7天',
title: '选择求购时限',
};
},
methods: {
change(value, index, text) {
console.log('change', value, index, text);
}
}
};
</script>
<style lang="scss" scoped>
.customSelectWrapper {
position: relative;
height: 60px;
padding-top: 10px;
}
.customSelectTextWrapper {
position: absolute;
width: 100%;
height: 100%;
display: flex;
flex-direction: row;
justify-content: space-between;
}
.leftText {
font-family: PingFang-SC-Regular;
font-size: 14px;
color: #000000;
letter-spacing: 0;
}
.rightWrapper {
}
.rightText {
font-family: PingFang-SC-Regular;
font-size: 14px;
color: #000000;
letter-spacing: 0;
}
.customSelect {
position: relative;
opacity: 0 !important;
}
</style>
... ...
<template>
<div>address</div>
<div class="address-wrapper" @click="onClick">
<div v-if="data" class="address-info">
<div class="index">
<i class="iconfont iconaddress icon-size2"></i>
</div>
<div class="user-info">
<div class="name">{{data.consignee}}</div>
<div class="area">{{data.area}}</div>
<div class="area">{{data.address}}</div>
<div class="mobile">{{data.mobile}}</div>
</div>
</div>
<template v-else>
<div class="title"><i class="iconfont iconaddress icon-size"></i>添加地址</div>
<div class="tip">商品不符合平检查验标准时,将到付寄还给您</div>
</template>
</div>
</template>
<script>
export default {
name: 'OrderAddress'
}
name: 'OrderAddress',
props: {
data: {
type: Object,
default() {
return null;
}
}
},
methods: {
onClick() {
this.$router.push({
name: 'address'
});
}
}
};
</script>
<style lang="scss" scoped>
.address-wrapper {
}
.title {
font-size: 40px;
font-weight: bold;
text-align: center;
margin-bottom: 12px;
}
.index {
display: flex;
align-items: center;
}
.icon-size {
font-size: 34px;
margin-right: 10px;
}
.icon-size2 {
font-size: 38px;
}
.index {
margin-right: 40px;
}
.tip {
font-size: 24px;
color: #999;
text-align: center;
}
.address-info {
display: flex;
}
.name {
font-size: 32px;
margin-bottom: 12px;
}
.area {
font-size: 24px;
color: #999;
}
.mobile {
font-size: 28px;
margin-top: 12px;
}
</style>
... ...
<template>
<div class="agree">
<span @click="onClick"><i :class="getClass"></i> 我已阅读并同意</span> <span class="link" @click="onLinkClick">有货卖家协议</span>
</div>
</template>
<script>
export default {
name: 'OrderCheck',
props: {
value: {
type: Boolean,
default: true
}
},
data() {
return {
val: this.value
};
},
computed: {
getClass() {
return {
iconfont: true,
iconcheck_default: !this.val,
iconcheck_full: this.val,
icon_color: this.val
};
}
},
watch: {
value(newVal) {
this.val = newVal;
}
},
methods: {
onClick() {
this.val = !this.val;
this.$emit('input', this.val);
},
onLinkClick() {
}
}
};
</script>
<style lang="scss" scoped>
.agree {
font-size: 24px;
color: #999;
}
.link {
color: #65ab85;
text-decoration: underline;
text-decoration-color: #65ab85;
}
.icon_color {
color: #002b47;
}
</style>
... ...
<template>
<div class='btn' @click="onClick">
<div :class='getClass' @click="onClick">
{{txt}}
</div>
</template>
<script>
export default {
name: "OrderButton",
name: 'OrderButton',
props: {
txt: {
type: String,
default: false
},
active: {
type: Boolean,
default: true
}
},
methods: {
onClick() {
this.$emit('on-click');
}
},
computed: {
getClass() {
return { btn: true, active: this.active };
}
}
};
</script>
... ... @@ -25,8 +36,11 @@ export default {
height: 120px;
font-size: 28px;
background: #ccc;
text-align: center;
line-height: 120px;
color: #fff;
.active {
&.active {
background: #002b47;
}
}
... ...
<template>
<div class="input-wrapper" @click="onClick">
<div class="price-symbol">¥</div>
<input class="tip" type="text" placeholder="定价需以9结尾,例如¥1299"></input>
</div>
</template>
<script>
export default {
name: 'InputPrice',
data() {
return {
show: false,
};
},
methods: {
onClick() {
},
},
watch: {
}
};
</script>
<style lang="scss" scoped>
.input-wrapper {
display: flex;
position: relative;
height: 100px;
background: #f5f5f5;
}
.price-symbol {
width: 40px;
margin-left: 20px;
margin-right: 10px;
font-size: 40px;
font-weight: bolder;
line-height: 100px;
}
.tip {
flex: 1;
font-size: 28px;
line-height: 100px;
background: #f5f5f5;
}
::placeholder {
color: #ccc;
opacity: 1; /* Firefox */
}
</style>
... ...
<template>
<div class="fee-detail">
<div class="item">
<div>平台用费:<i class="iconfont iconquestion icon-class"></i></div>
<div>-¥10.00</div>
</div>
<div class="item">
<div>银行转账费(0.6%):</div>
<div>-¥10.00</div>
</div>
<div class="item">
<div class="total-fee">实际收入:</div>
<div class="fee">¥0.00</div>
</div>
</div>
</template>
<script>
export default {
name: 'OrderFee'
};
</script>
<style lang="scss" scoped>
.item {
display: flex;
justify-content: space-between;
color: #999;
font-size: 28px;
margin: 12px 0;
}
.total-fee {
font-size: 28px;
color: black;
}
.fee {
font-size: 28px;
color: red;
}
.icon-class {
color: #d8d8d8;
font-size: 26px;
margin-left: 10px;
}
</style>
... ...
<template>
<div>
<div class="tip">需支付保证金:<span class="red">¥0</span><i class="iconfont iconquestion icon-class"></i></div>
<div class="tip2">所有商品必须为国内现货,且承诺36小时内发货,交易成功后将自动退还保证金</div>
</div>
</template>
<script>
export default {
name: 'OrderFee'
};
</script>
<style lang="scss" scoped>
.tip {
font-size: 28px;
color: black;
margin-bottom: 10px;
}
.red {
color: red;
}
.tip2 {
font-size: 24px;
color: #999;
}
.icon-class {
color: #d8d8d8;
font-size: 26px;
margin-left: 20px;
}
</style>
... ...
<template>
<div>product info</div>
<div class="product-wrapper">
<ImageFormat :src="data.goodImg" width="120" height="120"></ImageFormat>
<div class="product-price">
<div class="product-price-wrapper">
<div class="price">{{data.colorName}},{{data.sizeName}}</div>
<div class="tip">最低售价:<span class="price2">¥{{data.goodPrice}}</span></div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'OrderProductInfo'
}
name: 'OrderProductInfo',
props: {
data: {
type: Object,
default() {
return {};
}
}
}
};
</script>
<style lang="scss" scoped>
.product-wrapper {
height: 240px;
}
.product-price {
display: inline-block;
vertical-align: top;
height: 100%;
margin-left: 20px;
padding-top: 10%;
}
.price {
font-weight: bold;
font-size: 24px;
color: #999;
}
.tip {
font-size: 28px;
margin-top: 24px;
}
.price2 {
font-size: 40px;
font-weight: bold;
line-height: 40px;
}
</style>
... ...
<template>
<div class="title">{{txt}}</div>
</template>
<script>
export default {
name: 'OrderTitle',
props: {
txt: ''
}
};
</script>
<style lang="scss" scoped>
.title {
font-size: 68px;
font-weight: bolder;
}
</style>
... ...
<template>
<LayoutApp :show-back="true">
<div class="title">出售</div>
<ProductInfo></ProductInfo>
<div>
<div>需支付保证金:¥0</div>
<div>所有商品必须为国内现货,且承诺36小时内发货,交易成功后将自动退还保证金</div>
</div>
<div class="fee-detail">
<div></div>
<div></div>
<div></div>
</div>
<AddressInfo></AddressInfo>
</LayoutApp>
</template>
<script>
import ProductInfo from './components/confirm/product';
import AddressInfo from './components/confirm/address';
export default {
name: 'OrderConfirm',
components: {
ProductInfo,
AddressInfo
},
data() {
return {};
}
};
</script>
<style lang="scss" scoped>
.footer {
position: absolute;
bottom: 0;
width: 100%;
z-index: 100;
}
.body {
height: 100%;
overflow-y: auto;
}
</style>
import PriceChange from './price-change';
import OrderList from './order-list';
export default [{
name: 'OrderDetail',
path: '/xianyu/order/detail.html',
component: () => import(/* webpackChunkName: "order" */ './detail')
}, {
name: 'OrderConfirm',
path: '/xianyu/order/confirm.html',
component: () => import(/* webpackChunkName: "order" */ './confirm')
}, ...PriceChange];
export default [
{
name: 'OrderDetail',
path: '/xianyu/order/detail.html',
component: () => import(/* webpackChunkName: "order" */ './detail'),
},
{
name: 'OrderSellConfirm',
path: '/xianyu/order/sellerconfirm/:orderCode.html',
component: () => import(/* webpackChunkName: "order" */ './seller-confirm'),
props: true
},
{
name: 'OrderBuyConfirm',
path: '/xianyu/order/buyerconfirm/:orderCode.html',
component: () => import(/* webpackChunkName: "order" */ './buyer-confirm'),
props: true
},
{
name: 'PayOk',
path: '/xianyu/order/ok.html',
component: () => import(/* webpackChunkName: "order" */ './pay-ok'),
},
{
name: 'buyerAskOrder', //买家求购确认
path: '/xianyu/order/buyeraskorder.html',
component: () => import('./buyer-ask-order')
},
...PriceChange,
...OrderList,
];
... ...
<template>
<div class="order-item-wrapper">
<div class="item-img">
<img
<image-format
alt=""
src="//img10.static.yhbimg.com/goodsimg/2019/06/17/16/01c74e27eab148e4731af0e53518878972.jpg?imageMogr2/thumbnail/235x314/position/center/quality/60/format/webp"
:src="goodsInfo.goodImg"
:width="180"
:height="180"
/>
</div>
<div class="item-info">
<div class="price-status">
<span class="price">¥299.00</span>
<slot name="orderStatus" :orderStatus="orderStatus"></slot>
<div>
<div class="price-status">
<span class="price">¥{{ goodsInfo.goodPrice }}</span>
<span class="status">
<slot name="orderStatus" :status="order.statuStr"></slot>
</span>
</div>
<p class="item-name">
{{ goodsInfo.productName }}
</p>
</div>
<p class="item-name">
Nike Air Max 97 秋季限定款Kobe签名独家发售 限购
</p>
<p class="item-spec">
蓝色,39码
<span>{{ goodsInfo.colorName }},</span>
<span>{{ goodsInfo.sizeName }}码</span>
</p>
</div>
</div>
... ... @@ -23,10 +30,20 @@
<script>
export default {
data() {
return {
orderStatus: "交易成功"
};
props: {
order: {
type: Object,
default: {}
}
},
computed: {
goodsInfo: function() {
return this.$props.order.goodsInfo;
},
spec: function() {
const { colorName, sizeName } = this.goodsInfo;
return `${colorName},${sizeName}码`;
}
}
};
</script>
... ... @@ -34,13 +51,16 @@ export default {
<style lang="scss" scoped>
.order-item-wrapper {
display: flex;
margin: 40px 0;
.item-img {
min-width: 180px;
max-width: 180px;
max-height: 180px;
display: inline-block;
text-align: center;
& > img {
width: 100%;
height: 100%;
}
}
... ... @@ -55,8 +75,44 @@ export default {
.item-info {
display: flex;
flex: 1;
flex-direction: column;
margin-left: 20px;
font-size: 24px;
justify-content: space-between;
align-items: center;
.price-status {
display: flex;
justify-content: space-between;
margin-bottom: 12px;
.price {
font-size: 28px;
color: #d0021b;
letter-spacing: 0;
font-weight: bold;
}
.status {
color: #000;
letter-spacing: 0;
font-weight: bold;
}
}
.item-name {
color: #999;
letter-spacing: 0;
line-height: 36px;
}
.item-spec {
font-weight: bold;
& > :last-child {
padding-left: 10px;
}
}
}
}
</style>
\ No newline at end of file
... ...
<template>
<scroll class="" direction="horizontal"></scroll>
</template>
<script>
import { Scroll } from "cube-ui";
export default {
components: {
Scroll
}
};
</script>
<style lang="scss" scoped>
</style>
\ No newline at end of file
... ...
const routers = [
// 买家订单
// owner: {sell, buy} 订单来源
// status: 订单状态
{
name: 'BuyerOrderList',
path: '/xianyu/order/list/:owner',
path: '/xianyu/:owner/order/list/:status',
component: () => import('./order-list'),
},
];
... ...
<template> </template>
<template>
<scroll :data="orderList" class="order-list-wrapper">
<ul>
<li v-for="order in orderList" :key="order.orderCode">
<order-list-item :order="order">
<template #orderStatus="{status}">{{ status }}</template>
</order-list-item>
<div class="actions">
<Button v-for="action in order.buttons" :key="action.code">
{{ action.text }}
</Button>
</div>
</li>
</ul>
</scroll>
</template>
<script>
import { Button } from "cube-ui";
import { Button, Scroll } from "cube-ui";
import { createNamespacedHelpers } from "vuex";
import OrderListItem from "./components/order-list-item";
const { mapActions, mapState } = createNamespacedHelpers("order/orderList");
export default {
components: {
Button
Button,
Scroll,
OrderListItem
},
computed: {
...mapState(["orderList"])
},
// 获取订单数据
asyncData({ store, router }) {
const { owner, status } = router.params;
store.dispatch("order/orderList/fetchOrderList", { owner, status });
},
mounted() {
const { owner, status } = this.$route.params;
this.fetchOrderList({ owner, status });
},
methods: {
...mapActions(["fetchOrderList"]),
fetchMore() {
const { owner, status } = this.$route.params;
this.fetchOrderList({ owner, status });
}
}
};
</script>
<style lang="scss" scoped>
.order-list-wrapper {
margin: 40px 40px;
.actions {
display: flex;
justify-content: flex-end;
button {
font-size: 24px;
padding: 24px 64px 22px 64px;
color: #999;
letter-spacing: 0;
border-radius: 0;
background: #fff;
border: 1px solid #ccc;
line-height: 1.3;
width: 224px;
margin-right: 20px;
}
& :last-child {
background: #002b47;
color: #fff;
border: 1px solid #002b47;
margin-right: 0;
}
}
}
</style>
\ No newline at end of file
... ...
<template>
<LayoutApp :show-back="true">
<div class="body">
<div class="header">
<i class="iconfont iconOk icon-class"></i>
</div>
<div class="title">支付成功</div>
<OrderButton :txt="txt" class="btn-class" @on-click="onClick"></OrderButton>
<div class="info">
<div class="item" @click="goPublish">继续发布</div>
<div class="item" @click="goHome">随便逛逛</div>
</div>
</div>
</LayoutApp>
</template>
<script>
import OrderButton from './components/confirm/button';
export default {
name: 'PayOk',
data() {
return {
txt: '查看商品'
};
},
components: {
OrderButton
},
methods: {
onClick() {
},
goPublish() {
},
goHome() {
}
}
};
</script>
<style lang="scss" scoped>
.body {
height: 100%;
margin: 0 74px;
padding-bottom: 140px;
overflow-y: auto;
}
.header {
margin-top: 170px;
text-align: center;
}
.icon-class {
font-size: 120px;
}
.btn-class {
height: 100px;
font-size: 32px;
line-height: 100px;
}
.title {
font-size: 40px;
font-weight: bold;
text-align: center;
margin-bottom: 60px;
}
.info {
font-size: 28px;
display: flex;
margin-top: 30px;
.item {
width: 50%;
text-align: center;
}
.item + .item {
border-left: 1px solid black;
}
}
</style>
... ...
<template>
<LayoutApp :show-back="true">
<div class="body">
<TitleComp txt="出售"></TitleComp>
<ProductInfo :data="orderDetail.goodsInfo" class="product-info"></ProductInfo>
<InputPrice class="input-price"></InputPrice>
<OrderMargin class="order-item order-margin"></OrderMargin>
<OrderFee class="order-item"></OrderFee>
<AddressInfo :data="orderDetail.userAddress" class="order-item"></AddressInfo>
<OrderAgree v-model="agree" class="order-item"></OrderAgree>
</div>
<ConfirmButton :txt="txt" class="footer"></ConfirmButton>
</LayoutApp>
</template>
<script>
import ProductInfo from './components/confirm/product';
import InputPrice from './components/confirm/input-price';
import AddressInfo from './components/confirm/address';
import ConfirmButton from './components/confirm/button';
import TitleComp from './components/confirm/title';
import OrderMargin from './components/confirm/order-margin';
import OrderFee from './components/confirm/order-fee';
import OrderAgree from './components/confirm/agree';
import { createNamespacedHelpers } from 'vuex';
const { mapState, mapActions, mapMutations } = createNamespacedHelpers('order/orderConfirm');
export default {
name: 'OrderConfirm',
props: {
orderCode: {
type: String,
default: ''
}
},
components: {
ProductInfo,
AddressInfo,
ConfirmButton,
InputPrice,
TitleComp,
OrderMargin,
OrderFee,
OrderAgree
},
data() {
return {
txt: '提交',
agree: false
};
},
mounted() {
this.fetchOrderDetail({orderCode: this.orderCode})
},
computed: {
...mapState(['orderDetail'])
},
methods: {
...mapActions(['fetchOrderDetail'])
}
};
</script>
<style lang="scss" scoped>
.footer {
position: absolute;
bottom: 0;
width: 100%;
z-index: 100;
}
.body {
height: 100%;
margin: 0 40px;
padding-bottom: 140px;
overflow-y: auto;
}
.order-item {
padding-top: 40px;
padding-bottom: 40px;
}
.order-item + .order-item {
border-top: 1px solid #eee;
}
</style>
... ...
... ... @@ -4,7 +4,7 @@
import store from 'yoho-store';
import cookie from 'yoho-cookie';
import components from '../components';
import {each} from 'lodash';
import { each } from 'lodash';
export default {
loadGlobalComponents(Vue) {
... ... @@ -28,5 +28,5 @@ export default {
// 附加Vue原型属性
Vue.prop('store', store);
Vue.prop('cookie', cookie);
}
},
};
... ...
@font-face {font-family: "iconfont";
src: url('iconfont.eot?t=1569294019297'); /* IE9 */
src: url('iconfont.eot?t=1569294019297#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAS4AAsAAAAACfQAAARsAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCEAgqGCIUfATYCJAMkCxQABCAFhG0HaxuuCCMRJmyRR/aPBMdY62DdNnKu8kfgxUASfQRHyjPB8/850/v0vuSvAAGtgOSEPQkbwtx2F6JVgUAusmeOAmBxzhMYE2GG8hY9+kK6cfo0Pfz9oXLGpARsvsxvQYng3AMDGA5QgLI7p5esBckVuCDWRTyDXSg86MbrEKAQ1WiC9Ok3ZAwWw/qUALJk4fyZ2IID00EXrNlruNV8L/txsc4u52Vgn/t5+YFWYsHBVdZvGjGv7xx6hDb7TIMoYIrGCQ7nA4Z3gQJNAANysDGwW0OhCUqhea1hBlBC/FaF0A8rhC3Cb7INsrOzz6IotJVZlBRKUGoQHBSDe3v/eDEsiMfaUAQJK1IWQoXgQOgjKIQVEAyELRBcCL9BEMg2QPAgOxshBtlnDizi/OOlgJLAJyDdgdDF5+IIlmCQ6iJFxC9arJi1VvH58jolPJ357rvj3ntv/DvvjH377bVSN8bL8pvffXdMoWPXCuRdCS4nrk4kn2h8bsUhwXWSTJQbl64qOzYVLJHgKz8+s0muzJhkYp0yXS3qlnWYLm/0R1lXRNPpRLKMUySZDFJlizqpVF6mvBbNZOLp2Ueu5F2LX01cHnsJ105JXxU59bTxtefKn3wz8XqVizFKr9rjjxpcvleB1adLpNMi8Uz5kqkUEiSXzps/ds7cdavXRl3vmVxucU9IjUxrUtf+rfZn9L33FLVnWIZTXLjSQq82EFXN3N0tVrJYDWWoYjbTqUaWj+v9mPvtkzovDjD/e/sXRWs/CTU/1rtT55UcxelU84N84sU6n+QarKalC75S505fqX0RHX5Lr1sTu1bqWmzNmhV3St1ZsWZdgbpuXYzXlptT6huetvrpfZOfb+4LqZFpTeoq/FXns/r++4rasyzDKb666usli7bzPr3d+5vidtyoMbboJVcVld4TJ/Qmmkyc1KOXr4ypqO2K3sSRmfOGnP5pT+GfTrsn8cqaglxBQa9et+/cvsUMDVoY5HnYBED0WB9qdwB9wamPAtEnek5rWx+pyPYAwCNyFKJtWkrjf8PzUCK/YzG9eJe/bGEDwAfPXXqKsSjw2KwZLA5srPzTBWNV+fDVC/Xa6ZuZnk65UhfVaPIOMYRPX1z4+mwUEhGIKFKKTw9rKrtxDgRbUA7BIUZVUCx1MIbQBFwK0wY8LN2hEI3pf3dhSrMKRYwPNGIbgFCC58ChGA9BKcErGEP4BFzK8RN4lBCFQoyT0o8sTL11snB3ZFSCFvQfGkOjk27Z+fYbVrFXnFc7xgs5NGko0rxcvuKIfIgrwqcqRRw4pgEu8DbsewLP1KKRtBbxhyxzTV+UGhomO46MStAC+g80hkZnlsuu8v03rGKvuGPuXPyFHJr1gYKUfAPM1TBuNPdStodPVSLi+JhjGoAL+rAXBQJ8874WjaTUO+T8gYwWuU0N6elNw3u9AhRi/URfHFEx4oonMbHiSyEWCx//02bRLy19x3HZJMra7TtikBe0odit6GNIhmY0uxdamW6pmOk7mQA=') format('woff2'),
url('iconfont.woff?t=1569294019297') format('woff'),
url('iconfont.ttf?t=1569294019297') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url('iconfont.svg?t=1569294019297#iconfont') format('svg'); /* iOS 4.1- */
src: url('iconfont.eot?t=1569468612498'); /* IE9 */
src: url('iconfont.eot?t=1569468612498#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAdwAAsAAAAADywAAAchAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCFGgqOKItIATYCJANECyQABCAFhG0HgTkb3QwjEVacMrK/SLCNHR86OkSlyPGNjgoBL+u+kgn9I+majMKZ7ukkEz0wB9D/IbI/wOB0Krfsb9kQQHQAyBCyy1KRH8RD/u3d7xYlUORx4HmQYB5RohEkra2/5iFsAxmdry3qtO2QjkfHEzz7jk6gdw7Iic2T5UIBBAzd7+X/Vw2WtyzhAU7w7kXd3Y9eZeq3NfAGEtmAA920eUIT5JlIVzvp4d8F1zkIZwMBqCQrRMaGvhYosKRC0GKZPnU8FBUjdogfodDImD1zJfkIHEV5l7kL4MPw9uRGeSgABtdAnmvglPpJ6CIoxPuUl3iMonbw80sH0FsOoIBCANujJ5t5FTTJhQGruI6sVYB4hsavu5RCrFAqVAq1wgRhr/CNmCtOFK+K9yUJQSHE8Oq7Q5GLI+IlSlb/xAMYlAxLQU1Oj0MoqRhoaOmAtADWCKeHVQYQFCYKGBCUUUBBiIkCGQixUcCCUKpgGlIJPdQgtdBDDjIBeuhB9kIPDuQbRAEBMTcKlCBOjAIViFejwADi3SjQgHhPDy3IfXSCDgAYXft0QCYwAVOF9JyFdA6jMDlPswnWZTKoaUM6DVFqdTq/RaKGTYmIUGo0mQaZxpDlGwxGg9xaozHR8QEDgcZgcKjfb/X5VmjZElF56UDAolq7t2k3v8uxZzilE2r/0YGh8DbidEQ3uutEWV38LJLSY4Z6ximPtDgdNkP3VOU5Q+iusV6cTUPdboczktE4nbwrSsu4XE2eGKr1eOzu8QGhMSgO9X9j9X09QU1UI++rHD6LeuuD+p3Ho3aD3+crXLUJ6jUbY9YGg8Q+25E9JXr+rlN3Lrs+ctJkF3/K1pQ1OWrh+ZO2Obyt72TKGvuZiat3N+2173Hssm7YjqPcewjZeKVg78GYDY8dDxM3kZCR6q+7mLvrbCz+L2xwuwmxe2KMLhcI75w9Zap10uTxe4S5qb6GMq7V/03WTnFoMIAty8CW5R3B2nTP73voC1xO3hpcrrseSOfC2Xvor/nT2E2+FdvOxrKrz2Xpd15I4Nacz564j+rtjLJO9WzfIjvOySOnAsv/pE131ZfKbvbX628EM7gtgWGTnJP326H9NznDqSIjOa7d4vj6SNuyFVLHs2xzM3tWQYesWLRRP6nZTINBCmmzQOgjKneX0j25qk7xGZ0xbEo1ONEtjXa9iJfZPzbXUObtrup/Ww8trBRK9X7M9mbea6YCtBuelQtvZ4aaGR1bFrLuZXpHhf5UqK1u23L5XtNe+fLl87wm77zltoq7zdYG0qvP2NRU1krPughi8VfgwjSw//G/xw4bMnOcbNCgd5oMH21q+6U0btbYwRH2N3IGaLhRpyY3Zjbk9cbVDjH6dxwmFP5vv64vljRSN3ryVKkwEbF3Y931RW5Tfk1/MJfdUiVva+tcOce2tLBWOtdFEIs26q/ab6FPn1JIWwRCH7F90kOjtloWPt39G72icbBFod1TdbSk+/Bh3cmXDB/Rju7abYmj1dp9t848pe+mn9RQP5vC8ri3vLW5tbVbt9Pe06c2fImPZnwae5Ye/O67g0KiXQhYgY2jkK07zFhZMXZ8xSswR67NH9S3r4FBB3NVN3Y8t4T5o8HM7NlkEBnsYGL7foPJoCs1ZJ9MrNc2WBq05kQbx5jNqH6nh9PMZlPYZLVptF5ZhHtThSqsqtgUDg/BnYBm6ckTy2Iw7p2tmym9/c/qjYtd+mnnUNn4kNTdle5TpjhUkRBOqDgUslv9LaJs65z42KVKc2qWvhz1Dn6wXbmn09B+6j0K1/t83rs6aLcdO5bLjbzngw8Zxd3a185iHOVLWejvga0NAOkSvUA7AwA9mJwQTgrRrTQj7WWmjXbXXaSqrAsAYBmyBpDepCZqzwJ4upHyQR76HZ3uJDBV7m1mLdTPvD19rL7DXwr1S8+8Z0cGXRUFEi/DfJpAgYGxuTeVLHkSHlPCryBNxvxWMJQxQnVEQGXL6AKjenDwlNRDpXIBiXJNwsulUWNz72U0qgAMuSRAKWSqWKdCwFGrBDIKnYFKgR77q0VYAIqkEkC+NzNAGBwEDJ0LgDK4p2KdQoAT7ScgYwgKVPY0fjiiGtnV+SNhxzhCvwc1BC+1hc9jy0+csu2oLAT/X6SkSqAp63rNK3qkeWyTNlPLLEFScPCSnQ+tDRApaBy4nJnjuqokt205BLc4R3cEddiFH4HePrEyCDw5OTtvvP4nNMmsDg0Z8CfxL0QStXDQKNVjqF6xH2vAdWmfbExaTOkSmO4kcMALpSOrKgMQ+dU0NGCleYryaK2iieS4uFw+dac9xsk3qHwm45WiarphWrbjekL67947nH48jrfK8WgMW++PVNGN4+l/xsRHbMNDi5KPSE0znzWXaM6jzalwyrt6h303mJOxT0OY0tUw42D+RpRdtnxUIediJ5mtXb2Zo44obBcLAAA=') format('woff2'),
url('iconfont.woff?t=1569468612498') format('woff'),
url('iconfont.ttf?t=1569468612498') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url('iconfont.svg?t=1569468612498#iconfont') format('svg'); /* iOS 4.1- */
}
.iconfont {
... ... @@ -31,6 +31,18 @@
content: "\e618";
}
.iconquestion:before {
content: "\e6ab";
}
.iconleft:before {
content: "\e617";
}
.iconright:before {
content: "\e638";
}
.iconquestion1:before {
content: "\e630";
}
... ... @@ -43,6 +55,26 @@
content: "\e763";
}
.iconaddress:before {
content: "\e634";
}
.iconcheck_default:before {
content: "\e7cc";
}
.iconcheck:before {
content: "\e7cd";
}
.iconcheck_full:before {
content: "\e7ce";
}
.iconOk:before {
content: "\e662";
}
.iconarrow:before {
content: "\e7c4";
}
... ...
... ... @@ -32,6 +32,15 @@ Created by iconfont
<glyph glyph-name="i-add" unicode="&#58904;" d="M910.509 405.585h-378.843v376.925c0 11.2-9.427 20.281-20.626 20.281s-20.626-9.080-20.626-20.281v-376.925h-376.925c-11.2 0-20.281-9.426-20.281-20.626s9.080-20.626 20.281-20.626h376.925v-378.844c0-11.199 9.427-20.281 20.626-20.281s20.626 9.081 20.626 20.281v378.844h378.843c11.199 0 20.281 9.426 20.281 20.626s-9.081 20.626-20.281 20.626z" horiz-adv-x="1024" />
<glyph glyph-name="question" unicode="&#59051;" d="M512-128C229.216-128 0 101.248 0 384 0 666.784 229.216 896 512 896 794.752 896 1024 666.784 1024 384 1024 101.248 794.752-128 512-128ZM473.28 69.248 551.328 69.248 551.328 148.512 473.28 148.512 473.28 69.248ZM655.008 652.384C618.88 684.16 571.584 700 512.96 700 457.696 700 412.064 683.84 376.096 651.552 340.16 619.264 319.808 575.616 315.072 520.608L396.288 520.608C407.968 598.464 445.568 620.608 512.224 620.608 546.368 620.608 575.584 626.88 596.672 605.856 617.792 584.864 628.352 558.144 628.352 525.696 628.352 509.088 624.448 493.312 616.704 478.528 608.896 463.712 588.96 442.464 556.896 414.848 524.8 387.232 502.816 361.184 490.88 336.768 478.944 312.384 472.832 279.232 472.832 226.784L551.616 226.784C551.616 266.56 550.176 289.696 557.952 306.784 565.728 323.808 586.688 346.752 620.832 375.52 655.008 404.288 678.272 430.496 690.624 454.208 702.944 477.888 709.152 503.552 709.152 531.2 709.152 580.288 691.104 620.704 655.008 652.384Z" horiz-adv-x="1024" />
<glyph glyph-name="left" unicode="&#58903;" d="M709.254038-61.195501c-15.286148 0-29.522384 5.878894-40.166815 16.564257L279.38971 345.759047c-1.425466 1.39272-2.537799 2.577708-3.449565 3.846608l-2.304486 2.905166c-11.362792 11.416004-16.945951 24.848944-16.945951 39.068807 0 14.475689 5.708002 28.010961 16.056698 38.110993l392.376529 388.216789c10.612709 10.467399 24.785499 16.236799 39.892569 16.236799 14.772448 0 28.726252-5.599532 39.287795-15.753799 10.497075-10.18599 16.538675-24.390503 16.538675-38.95215 0-14.382569-5.722328-28.009937-16.142655-38.366819L390.732587 390.901177 749.217215 31.473061c10.249435-10.30981 15.909341-23.781636 15.909341-37.994336 0-14.889105-6.05081-28.859281-16.999163-39.333844C737.70809-55.744349 723.878107-61.195501 709.254038-61.195501z" horiz-adv-x="1024" />
<glyph glyph-name="right" unicode="&#58936;" d="M312.56325 834.14421c15.286148 0 29.522384-5.878894 40.166815-16.564257l389.69649-390.391315c1.425466-1.39272 2.537799-2.577708 3.449565-3.846608l2.304486-2.905166c11.362792-11.416004 16.945951-24.848944 16.945951-39.068807 0-14.475689-5.708002-28.010961-16.056698-38.110993L356.692307-44.958702c-10.612709-10.467399-24.785499-16.236799-39.892569-16.236799-14.772448 0-28.726252 5.599532-39.287795 15.753799-10.497075 10.18599-16.538675 24.390503-16.538675 38.95215 0 14.382569 5.722328 28.009937 16.142655 38.366819l353.968777 350.170265L272.59905 741.475648c-10.249435 10.30981-15.909341 23.781636-15.909341 37.994336 0 14.889105 6.051833 28.859281 17.000186 39.333844C284.109198 828.693058 297.939181 834.14421 312.56325 834.14421z" horiz-adv-x="1024" />
<glyph glyph-name="question1" unicode="&#58928;" d="M463.99957 111.647789c0-26.509985 21.490445-48.00043 48.00043-48.00043s48.00043 21.490445 48.00043 48.00043c0 26.509985-21.490445 48.00043-48.00043 48.00043S463.99957 138.157774 463.99957 111.647789zM512-64c-247.039484 0-448 200.960516-448 448S264.960516 832 512 832 960 631.039484 960 384 759.039484-64 512-64zM512 767.712727c-211.584464 0-383.712727-172.128262-383.712727-383.712727 0-211.551781 172.128262-383.712727 383.712727-383.712727 211.551781 0 383.712727 172.159226 383.712727 383.712727C895.712727 595.584464 723.551781 767.712727 512 767.712727zM512 222.304744c-17.664722 0-32.00086 14.336138-32.00086 31.99914l0 54.112297c0 52.352533 39.999785 92.352318 75.32751 127.647359 25.887273 25.919957 52.67249 52.67249 52.67249 74.016718 0 53.343368-43.07206 96.735385-95.99914 96.735385-53.823303 0-95.99914-41.535923-95.99914-94.559333 0-17.664722-14.336138-31.99914-32.00086-31.99914s-32.00086 14.336138-32.00086 31.99914c0 87.423948 71.775299 158.559333 160.00086 158.559333s160.00086-72.095256 160.00086-160.735385c0-47.904099-36.32028-84.191695-71.424378-119.295794-27.839699-27.776052-56.575622-56.511974-56.575622-82.3356l0-54.112297C544.00086 236.671845 529.664722 222.304744 512 222.304744z" horiz-adv-x="1024" />
... ... @@ -41,6 +50,21 @@ Created by iconfont
<glyph glyph-name="back" unicode="&#59235;" d="M718.08-122.464L208 386.016 718.016 896.032l67.36-67.36-442.56-442.56 442.496-441.12-67.264-67.456z" horiz-adv-x="1024" />
<glyph glyph-name="address" unicode="&#58932;" d="M512-128S97.52381 252.586667 97.52381 481.52381a414.47619 414.47619 0 0 0 828.95238 0c0-228.937143-414.47619-609.52381-414.47619-609.52381z m0 950.857143A343.356952 343.356952 0 0 1 170.666667 477.379048C170.666667 286.72 512-30.47619 512-30.47619s341.333333 317.19619 341.333333 507.855238A343.356952 343.356952 0 0 1 512 822.857143z m0-146.285714a195.047619 195.047619 0 1 0-195.047619-195.047619 195.047619 195.047619 0 0 0 195.047619 195.047619z m0-73.142858a121.904762 121.904762 0 1 0-121.904762-121.904761 121.904762 121.904762 0 0 0 121.904762 121.904761z" horiz-adv-x="1024" />
<glyph glyph-name="check_default" unicode="&#59340;" d="M878.545455-104.727273h-733.09091A122.298182 122.298182 0 0 0 23.272727 17.454545v733.09091A122.298182 122.298182 0 0 0 145.454545 872.727273h733.09091A122.298182 122.298182 0 0 0 1000.727273 750.545455v-733.09091A122.298182 122.298182 0 0 0 878.545455-104.727273z m-733.09091 919.272728A64.116364 64.116364 0 0 1 81.454545 750.545455v-733.09091a64.116364 64.116364 0 0 1 64-64h733.09091a64.116364 64.116364 0 0 1 64 64v733.09091A64.116364 64.116364 0 0 1 878.545455 814.545455z" horiz-adv-x="1024" />
<glyph glyph-name="check" unicode="&#59341;" d="M459.985455 214.690909a28.974545 28.974545 0 0 0-20.48 8.494546L256 406.109091a29.090909 29.090909 0 0 0 40.96 41.309091l163.607273-162.909091L721.454545 544.814545a29.090909 29.090909 0 1 0 40.96-41.30909L480.465455 223.185455a28.974545 28.974545 0 0 0-20.48-8.494546zM875.636364-104.727273h-733.090909a122.298182 122.298182 0 0 0-122.181819 122.181818v733.09091A122.298182 122.298182 0 0 0 142.545455 872.727273h733.090909a122.298182 122.298182 0 0 0 122.181818-122.181818v-733.09091A122.298182 122.298182 0 0 0 875.636364-104.727273z m-733.090909 919.272728a64.116364 64.116364 0 0 1-64-64v-733.09091a64.116364 64.116364 0 0 1 64-64h733.090909a64.116364 64.116364 0 0 1 64 64v733.09091a64.116364 64.116364 0 0 1-64 64z" horiz-adv-x="1024" />
<glyph glyph-name="check_full" unicode="&#59342;" d="M878.545455 872.727273h-733.09091A122.298182 122.298182 0 0 1 23.272727 750.545455v-733.09091A122.298182 122.298182 0 0 1 145.454545-104.727273h733.09091A122.298182 122.298182 0 0 1 1000.727273 17.454545v733.09091A122.298182 122.298182 0 0 1 878.545455 872.727273z m-112.872728-369.105455l-282.181818-280.436363a29.090909 29.090909 0 0 0-40.96 0L258.327273 406.109091a29.090909 29.090909 0 0 0 40.96 41.309091l163.607272-162.909091 261.701819 260.305454a29.090909 29.090909 0 1 0 40.96-41.30909z" horiz-adv-x="1024" />
<glyph glyph-name="Ok" unicode="&#58978;" d="M512-128a512 512 0 1 0 512 512 512.576 512.576 0 0 0-512-512z m0 960a448 448 0 1 1 448-448A448.512 448.512 0 0 1 512 832z m-34.848-630.4a32 32 0 0 0-22.688-9.6H454.4a32 32 0 0 0-22.624 9.376l-166.4 166.4A32 32 0 0 0 310.624 412.8l143.424-143.36 259.2 264.864a32 32 0 1 0 45.76-44.8z" horiz-adv-x="1024" />
<glyph glyph-name="arrow" unicode="&#59332;" d="M1536 896L768-128 0 896z" horiz-adv-x="1536" />
... ...
import * as Types from './types';
import {
get
} from 'lodash';
export default {
// 获取用户地址列表
async fetchUserAddressList({
commit
}) {
const result = await this.$api.get('/api/address/gethidden', {
uid: '500031912',
});
if (result.code === 200) {
commit(Types.FETCH_USER_ADDRESS_LIST, {
list: get(result, 'data', [])
});
}
},
// 获取地址标签
async fetchAddressTags({
commit
}) {
const result = await this.$api.get('/api/address/getTags');
if (result.code === 200) {
commit(Types.FETCH_ADDRESS_TAGS, {
list: get(result, 'data', [])
});
}
},
async fetchAddressProvinces({
commit
}) {
const result = await this.$api.get('/api/address/getProvinces');
if (result.code === 200) {
commit(Types.FETCH_ADDRESS_PROVINCES, {
list: get(result, 'data', [])
});
}
},
// 设置默认地址, post请求
async setDefaultAddress({
commit
}) {
const result = await this.$api.post('/api/address/setDefaultAddress');
if (result.code === 200) {
commit(Types.SET_DEFAULT_ADDRESS);
}
return result || {};
},
// 添加、更新、删除地址,post请求
async addUserAddress({
commit
}, {
uid
}) {
const result = await this.$api.post('/api/address/addAddress', {
uid
});
if (result.code === 200) {
commit(Types.ADD_USER_ADDRESS_INFO);
}
return result || {};
},
async updateUserAddress({
commit
}) {
const result = await this.$api.post('/api/address/updateAddress');
if (result.code === 200) {
commit(Types.UPDATE_USER_ADDRESS_INFO);
}
return result || {};
},
async deleteUserAddress({
commit
}) {
const result = await this.$api.post('/api/address/delAddress');
if (result.code === 200) {
commit(Types.DELETE_USER_ADDRESS_INFO);
}
return result || {};
},
};
... ...
import actions from './actions';
import mutations from './mutations';
export default function () {
return {
namespaced: true,
state: {
addressList: [],
addressTags: [],
provincesList: [],
},
actions,
mutations,
};
}
... ...
import * as Types from './types';
export default {
[Types.FETCH_USER_ADDRESS_LIST](state, {
list
}) {
state.addressList = list;
},
[Types.FETCH_ADDRESS_TAGS](state, {
list
}) {
state.addressTags = list;
},
[Types.FETCH_ADDRESS_PROVINCES](state, {
list
}) {
state.provincesList = list;
},
};
... ...
export const FETCH_USER_ADDRESS_LIST = 'FETCH_USER_ADDRESS_LIST';
export const FETCH_ADDRESS_TAGS = 'FETCH_ADDRESS_TAGS';
export const ADD_USER_ADDRESS_INFO = 'ADD_USER_ADDRESS_INFO';
export const UPDATE_USER_ADDRESS_INFO = 'UPDATE_USER_ADDRESS_INFO';
export const DELETE_USER_ADDRESS_INFO = 'DELETE_USER_ADDRESS_INFO';
export const FETCH_ADDRESS_PROVINCES = 'FETCH_ADDRESS_PROVINCES';
export const SET_DEFAULT_ADDRESS = 'SET_DEFAULT_ADDRESS';
... ...
import address from './address';
export default function () {
return {
namespaced: true,
modules: {
address: address()
}
};
}
... ...
import * as Types from './types';
import { get } from 'lodash';
export default {
async fetchTopicList({ commit, state }, { page, limit }) {
if (state.fetchTopicList) {
return {};
}
page = page || state.fetchTopicPage || 1;
commit(Types.FETCH_NOTICE_LIST_REQUEST, { page });
const result = await this.$api.post('/api/grass/getGrassTopicList', {
page,
limit: limit || 10,
filter: 'Y',
lastedTime: state.fetchTopicLastedTime || void 0
});
if (result && result.code === 200) {
commit(Types.FETCH_NOTICE_LIST_SUCCESS, {
data: result.data,
page
});
} else {
commit(Types.FETCH_NOTICE_LIST_FAILD);
}
return result;
},
};
... ...
import * as Types from './types';
import { get, set } from 'lodash';
import { getImgUrl } from '../../common/utils';
export default function() {
return {
namespaced: true,
state: {
channelData: [],
},
mutations: {
[Types.FETCH_CHANNEL](state, { list }) {
state.channelData = list;
},
},
actions: {
async fetchChannelList({ commit }) {
const result = await this.$api.get('/api/ufo/channel/channelList', {
content_code: '9cb6138be8e60c96f48107da481816c3',
uid: '64668089',
});
if (result.code === 200) {
result.data.map(res => {
// 焦点图
if(res.template_name === 'focus') {
for (let i = 0; i < res.data.length; i++) {
let url = "https:" + getImgUrl(get(res.data[i], "src") || '', 750, 200);
set(res.data[i], "src", url);
}
}
// 热门系列
if(res.template_name === 'hotSeries') {
for (let i = 0; i < res.data.length; i++) {
let url = "https:" + getImgUrl(get(res.data[i], "image_url") || '', 100, 80);
set(res.data[i], "image_url", url);
}
}
})
console.log(result.data);
commit(Types.FETCH_CHANNEL, { list: result.data });
}
}
},
};
}
... ...
import mine from './mine';
import channel from './channel'
export default function() {
return {
namespaced: true,
state: {
fetchNoticeList:false,
noticeList:[],
fetchNoticePage: 1,
fetchNoticeLastedTime: 0,
},
mutations: {
},
actions: {
},
modules: {
mine: mine()
mine: mine(),
channel: channel()
}
};
}
}
\ No newline at end of file
... ...
import { parseAssetList, maskAccount } from '../../utils/mine-handler';
import { get, set } from 'lodash';
import { getImgUrl } from '../../common/utils';
const uid = '600046428';
const MINE_RESOURCE_CODE1 = '11a73219a63b50067d88e75c0fe04d10';
const MINE_RESOURCE_CODE2 = 'dc2731fbbebcba6329c74a379e9c41ec';
export default function() {
return {
namespaced: true,
state: {
animate: false,
rollNoticeList: [],
orderSum: {
sellerNum: 0,
readyNum: 0,
sentNum: 0,
finishNum: 0,
failNum: 0
},
favoriteNum: 0,
buyNum: 0,
assetData: {
list: [],
currentPage: 1,
endReached: false,
compensateIncome: 0,
goodsIncome: 0,
totalIncome: 0
},
resource1: {},
resource2: {}
},
mutations: {
addList(state, { list }) {
state.rollNoticeList = state.rollNoticeList.concat(list);
},
startAnimate(state) {
state.animate = true;
},
animateHandler(state) {
state.rollNoticeList.push(state.rollNoticeList[0]);
state.rollNoticeList.shift();
state.animate = false;
},
addSellerOrder(state, { orderSumList }) {
let orderSum = {};
orderSumList.forEach((item) => {
switch (item.listType) {
case 1:
orderSum.sellerNum = item.sum;
break;
case 2:
orderSum.readyNum = item.sum;
break;
case 3:
orderSum.sentNum = item.sum;
break;
case 5:
orderSum.finishNum = item.sum;
break;
case 6:
orderSum.failNum = item.sum;
break;
default:
break;
}
});
state.orderSum = Object.assign({}, state.orderSum, orderSum);
},
addFavoriteNum(state, {count}) {
state.favoriteNum = count;
},
addOrderSummary(state, {count}) {
state.buyNum = count;
},
addAssets(state, assetData) {
state.assetData = Object.assign({}, state.assetData, assetData);
},
addResource(state, {resource1 = {}, resource2 = {}}) {
state.resource1 = Object.assign({}, state.resource1, resource1);
state.resource2 = Object.assign({}, state.resource1, resource2);
}
},
actions: {
async fetchRollBoardList({ commit }) {
const result = await this.$api.get('/api/ufo/mine/rollBoardList', {});
if (result.code === 200) {
commit('addList', { list: result.data.list });
commit('addList', { list: result.data });
}
}
return result.data || [];
},
async showMarquee({ commit }) {
commit('startAnimate');
setTimeout(() => {
commit('animateHandler');
}, 500);
},
async fetchResource({commit}) {
const result = await this.$api.get('/api/ufo/mine/resource', {
content_code: MINE_RESOURCE_CODE1,
uid
});
const result1 = await this.$api.get('/api/ufo/mine/resource', {
content_code: MINE_RESOURCE_CODE2,
uid
});
if (result.code === 200) {
let src = getImgUrl(get(result, 'data[0].data[0].src') || '', 1000, 1000);
set(result, 'data[0].data[0].src', src);
commit('addResource', {resource1: result.data[0]});
}
if (result1.code === 200) {
let src = getImgUrl(get(result1, 'data[0].data[0].src') || '', 1000, 1000);
set(result1, 'data[0].data[0].src', src);
commit('addResource', {resource2: result1.data[0]});
}
},
async fetchSellerOrder({ commit }) {
const result = await this.$api.get('/api/ufo/mine/seller/orderSummary', {uid, debug: 'XYZ'});
if (result.code === 200) {
commit('addSellerOrder', { orderSumList: result.data });
}
return result.data || [];
},
async fetchFavoriteNum({ commit }) {
const result = await this.$api.get('/api/ufo/mine/favoriteNum', {uid});
if (result.code === 200) {
commit('addFavoriteNum', { count: result.data.product_favorite_total });
}
return result.data || [];
},
async fetchOrderSummary({ commit }) {
const result = await this.$api.get('/api/ufo/mine/order/summary', {uid, debug: 'XYZ'});
if (result.code === 200) {
commit('addOrderSummary', { count: result.data.buyCount });
}
return result.data || [];
},
async fetchAssets({ commit }) {
const result = await this.$api.get('/api/ufo/mine/assets', {page: 1, limit: 20, uid, debug: 'XYZ'});
if (result.code === 200) {
let assetData = parseAssetList(result.data);
commit('addAssets', assetData);
}
return result.data || [];
},
},
};
}
... ...
export const FETCH_NOTICE_LIST_REQUEST = 'FETCH_NOTICE_LIST_REQUEST';
export const FETCH_NOTICE_LIST_FAILD = 'FETCH_NOTICE_LIST_FAILD';
export const FETCH_NOTICE_LIST_SUCCESS = 'FETCH_NOTICE_LIST_SUCCESS';
export const FETCH_CHANNEL = 'FETCH_CHANNEL';
... ...
... ... @@ -2,11 +2,15 @@ import Vue from 'vue';
import Vuex from 'vuex';
import { createApi } from 'create-api';
import storeYoho from './yoho';
import storeOrder, { buyerOderList } from './order';
import storeOrder from './order';
import storeList from './list';
import storeProduct from './product';
import storeHome from './home';
import storeAddress from './address';
import storeNotice from './notice';
Vue.use(Vuex);
export function createStore(context) {
... ... @@ -17,11 +21,16 @@ export function createStore(context) {
order: storeOrder(),
list: storeList(),
produt: storeProduct(),
home: storeHome(),
address: storeAddress(),
// 买家订单列表
buyerOderList: buyerOderList(),
notice: storeNotice(),
// buyerOderList: buyerOderList(),
},
strict: process.env.NODE_ENV !== 'production',
});
... ...
import { get } from 'lodash';
import { getImgUrl } from '../../common/utils';
import {get} from 'lodash';
import Vue from 'vue';
export default function() {
return {
namespaced: true,
state: {
productList: {
showErrorPage: false,
isFetching: false,
error: null,
page: 0, // 当前页
page_size: 10, // 每页数量
page_total: 0, // 总共多少页
total: 0, // 总共多少条
endReached: false, // 到达底部
list: [], // 商品列表
isEmpty: false,
},
searchParams: {
type: 0, // type:0,推荐;1,热销;2,即将发售; 3,品类; 4,品牌;5,系列;6,搜索 7, 收藏
order: null, // 指定排序
productPool: null, // 商品池id
sort: null, // 品类id
brand: null, // 品牌id
series: null, // 系列id
gender: null, // 性别
size: null, // 尺码id
isSoonSale: null, // 是否是即将售卖
query: null, // 搜索词
limit: null, // 每页记录数
page: null, // 当前页号
coupon_token: null, // 优惠券token
},
filterParams: {
sort: [], // 品类id
brand: [], // 品牌id
gender: [], // 性别
size: [], // 尺码id
},
filterData: [],
filterVisible: false,
},
mutations: {
addProductList(state, {data}) {
Vue.set(state.productList, 'list', state.productList.list.concat(data.product_list));
Vue.set(state.productList, 'page', data.page);
},
},
actions: {
async fetchProductList({commit, state}) {
let page = state.productList.page;
let size = state.productList.page_size;
const result = await this.$api.get('/api/ufo/list/productList', {
page: page + 1,
size: size
});
if (result.code === 200) {
commit('addProductList', {data: result.data});
}
return result.data ? result.data.length : 0;
},
},
};
}
... ...