diff --git a/.gitignore b/.gitignore index acb9cf955..bea114387 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ dist/ .rn_temp/ node_modules/ .DS_Store +.idea diff --git a/package-lock.json b/package-lock.json index 4aa30eb5c..1bf7d15e1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "mshop-taro", + "name": "espier-taro-fenxiao", "version": "1.0.0", "lockfileVersion": 1, "requires": true, @@ -2777,6 +2777,14 @@ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true }, + "copy-to-clipboard": { + "version": "3.0.8", + "resolved": "http://registry.npm.taobao.org/copy-to-clipboard/download/copy-to-clipboard-3.0.8.tgz", + "integrity": "sha1-9OgvSogw3ORma3643tDJvMMTq6k=", + "requires": { + "toggle-selection": "^1.0.3" + } + }, "core-js": { "version": "2.6.5", "resolved": "https://r.cnpmjs.org/core-js/download/core-js-2.6.5.tgz", @@ -9574,6 +9582,11 @@ "repeat-string": "^1.6.1" } }, + "toggle-selection": { + "version": "1.0.6", + "resolved": "http://registry.npm.taobao.org/toggle-selection/download/toggle-selection-1.0.6.tgz", + "integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI=" + }, "toposort": { "version": "1.0.7", "resolved": "https://r.cnpmjs.org/toposort/download/toposort-1.0.7.tgz", diff --git a/package.json b/package.json index 3ef70096e..b9871b927 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "mshop-taro", - "app_name": "我的商铺", + "name": "espier-taro-fenxiao", + "app_name": "源源客h5", "version": "1.0.0", "private": true, "description": "taro app for bbc", @@ -34,6 +34,7 @@ "@tarojs/taro-weapp": "1.2.13", "axios": "^0.18.0", "classnames": "^2.2.6", + "copy-to-clipboard": "^3.0.8", "lodash-es": "^4.17.11", "memoize-one": "^5.0.0", "moment": "^2.24.0", diff --git a/src/app.js b/src/app.js index 717b56b3e..2535f11f6 100644 --- a/src/app.js +++ b/src/app.js @@ -25,7 +25,8 @@ class App extends Component { 'pages/member/index', 'pages/member/favorite', - 'pages/trade/list' + 'pages/trade/list', + 'pages/trade/detail' ], window: { backgroundTextStyle: 'light', diff --git a/src/app.scss b/src/app.scss index fa91f82b9..ade9d1d01 100644 --- a/src/app.scss +++ b/src/app.scss @@ -77,6 +77,7 @@ page, body { .toolbar { background: #fff; + font-size: $font-size; display: flex; height: $toolbar-height; box-shadow: $toolbar-shadow; @@ -90,6 +91,9 @@ page, body { align-content: center; justify-content: space-between; z-index: $z-index-toolbar; + .at-button { + font-size: $font-size; + } &-hd {} &-ft { max-width: 120px; diff --git a/src/hocs/withPager.js b/src/hocs/withPager.js index 0f2956656..fb4d4f7d8 100644 --- a/src/hocs/withPager.js +++ b/src/hocs/withPager.js @@ -2,7 +2,7 @@ export default function withPager (Component) { return class WithPagerComponent extends Component { constructor (props) { super(props) - const { pageSize = 10, pageNo = 1, pageTotal = 0 } = props + const { pageSize = 10, pageNo = 0, pageTotal = 0 } = props || {} const page = { hasNext: true, diff --git a/src/pages/index/index.js b/src/pages/index/index.js index 0beb68968..80c285f9d 100644 --- a/src/pages/index/index.js +++ b/src/pages/index/index.js @@ -10,7 +10,7 @@ export default class Index extends Component { componentWillMount () { Taro.redirectTo({ - url: `/pages/trade/list` + url: `/pages/trade/detail?id=123` }) } diff --git a/src/pages/trade/comps/item.js b/src/pages/trade/comps/item.js index e7a1f1451..5a1c3439a 100644 --- a/src/pages/trade/comps/item.js +++ b/src/pages/trade/comps/item.js @@ -1,5 +1,8 @@ import Taro, { Component } from '@tarojs/taro' import { View, Text, Image } from '@tarojs/components' +import { AtButton } from 'taro-ui' +import { Price } from '@/components' +import { OrderItem } from './order-item' import './item.scss' @@ -9,48 +12,85 @@ export default class TradeItem extends Component { } static defaultProps = { - customHeader: false + customHeader: false, + customFooter: false, + customRender: false, + onClickBtn: () => {}, + onClick: () => {} + } + + handleClickBtn (type) { + const { info } = this.props + this.props.onClickBtn && this.props.onClickBtn(type, info) } render () { - const { customHeader, info } = this.props + const { customHeader, customFooter, onClick, info } = this.props return ( { customHeader - ? - 丰收蟹旗舰店待付款{info.status_desc} + ? {this.props.renderHeader} + : + {info.shopname}{info.status_desc} - : this.props.renderHeader } - + { - info.order.map((item, idx) => { - return ( - - - - - - {item.title} - {item.goods_props} - - - - + info.order.map((item, idx) => + + ) + } + { + this.props.customRender + ? this.props.customRender + : + 共{info.totalItem}件商品 合计: - ) - }) } + {customFooter && {this.props.renderFooter}} + {!customFooter && info.status === 'WAIT_BUYER_PAY' && + 取消订单 + 立即支付 + } + {!customFooter && info.status === 'WAIT_BUYER_CONFIRM_GOODS' && + 查看物流 + 确认收货 + } + {!customFooter && info.status === 'WAIT_RATE' && + 评价 + } ) } diff --git a/src/pages/trade/comps/item.scss b/src/pages/trade/comps/item.scss index 2b1d3290c..6d9fbad04 100644 --- a/src/pages/trade/comps/item.scss +++ b/src/pages/trade/comps/item.scss @@ -3,6 +3,7 @@ .trade-item { background: #fff; border-radius: $item-border-radius; + margin: 0 0 $edge-margin; &__hd { padding: 28px $edge-size; line-height: 1; @@ -15,4 +16,15 @@ text-align: right; } } + + &__total { + padding: 0 $edge-size floor($edge-size/2); + text-align: right; + } + + &__ft { + display: flex; + justify-content: flex-end; + padding: floor($edge-size/2) $edge-size; + } } \ No newline at end of file diff --git a/src/pages/trade/comps/order-item.js b/src/pages/trade/comps/order-item.js new file mode 100644 index 000000000..784ff0fe8 --- /dev/null +++ b/src/pages/trade/comps/order-item.js @@ -0,0 +1,38 @@ +import Taro, { Component } from '@tarojs/taro' +import { View, Text, Image } from '@tarojs/components' +import { Price } from '@/components' + +import './order-item.scss' + +export default class OrderItem extends Component { + static defaultProps = { + onClick: () => {} + } + + render () { + const { info, onClick } = this.props + + return ( + + + + + + {info.title} + {info.goods_props} + + + + x {info.num} + + + ) + } +} diff --git a/src/pages/trade/comps/order-item.scss b/src/pages/trade/comps/order-item.scss new file mode 100644 index 000000000..27005d59b --- /dev/null +++ b/src/pages/trade/comps/order-item.scss @@ -0,0 +1,39 @@ +@import "../../../style/imports"; + +.order-item { + display: flex; + align-items: flex-start; + padding: $edge-size; + &__img { + width: 160px; + height: 160px; + margin-right: 18px + } + &__hd { + } + &__bd { + width: 50%; + } + &__ft { + flex: 1; + text-align: right; + font-size: $font-size-small; + } + &__title { + font-size: floor(0.95 * $font-size); + @include mult-ellipsis(2); + line-height: 1.4; + margin: 0 0 4px; + } + &__desc { + color: $color-gray; + font-size: $font-size-small; + } + &__price { + color: $color-primary-text; + } + &__num { + display: block; + color: $color-gray; + } +} \ No newline at end of file diff --git a/src/pages/trade/detail.js b/src/pages/trade/detail.js new file mode 100644 index 000000000..a8a6ece41 --- /dev/null +++ b/src/pages/trade/detail.js @@ -0,0 +1,178 @@ +import Taro, { Component } from '@tarojs/taro' +import { View, Text } from '@tarojs/components' +import { AtButton } from 'taro-ui' +import { Loading, SpCell, SpToast, GoodsItem, Price } from '@/components' +import { classNames, formatTime, copyText } from '@/utils' +import api from '@/api' +import S from '@/spx' +import OrderItem from './comps/order-item' + +import './detail.scss' + +function resolveTradeOrders (info) { + return info.orders.map(order => { + const { item_id, title, pic_path: img, total_fee: price, num } = order + return { + item_id, + title, + img, + price, + num + } + }) +} + +export default class TradeDetail extends Component { + constructor (props) { + super(props) + + this.state = { + info: null + } + } + + componentDidMount () { + this.fetch() + } + + async fetch () { + const { id } = this.$router.params + const info = await api.trade.detail(id) + info.created_time_str = formatTime(info.created_time, 'YYYY-MM-DD hh:mm:ss') + this.setState({ + info + }) + } + + handleCopy = async () => { + const { info } = this.state + const msg = `收货人:${info.receiver_name} ${info.receiver_mobile} +收货地址:${info.receiver_state}${info.receiver_city}${info.receiver_district}${info.receiver_address} +订单号:${info.tid} +创建时间:${info.created_time_str} +` + await copyText(msg) + S.toast('已复制信息') + } + + async handleClickBtn (type) { + console.log(type) + } + + render () { + const { info } = this.state + if (!info) { + return + } + + // TODO: orders 多商铺 + const tradeOrders = resolveTradeOrders(info) + + return ( + + + 等待付款 + + + + { + + + 收货人:{info.receiver_name} {info.receiver_mobile} + + + 收货地址:{info.receiver_state}{info.receiver_city}{info.receiver_district}{info.receiver_address} + + + } + + 配送方式:{info.shipping_type_name} + + + + + 丰收蟹旗舰店 + + + { + info.orders.map((item, idx) => { + return ( + + ) + }) + } + + + + + + + + + + + + + + + + + 订单编号:{info.tid} + 创建时间:{info.created_time_str} + + + 复制 + + + + {info.status === 'WAIT_BUYER_PAY' && ( + 取消订单 + 立即支付 + )} + + {info.status === 'WAIT_BUYER_CONFIRM_GOODS' && ( + 确认收货 + )} + + {info.status === 'WAIT_RATE' && ( + 评价 + )} + + + + ) + } +} diff --git a/src/pages/trade/detail.scss b/src/pages/trade/detail.scss new file mode 100644 index 000000000..f1293e467 --- /dev/null +++ b/src/pages/trade/detail.scss @@ -0,0 +1,85 @@ +@import "../../style/imports"; + +.trade-detail { + padding-bottom: $toolbar-height + $edge-margin; + &__status { + background: linear-gradient(227deg,rgba(250,167,97,1) 0%,rgba(250,53,21,1) 100%); + position: relative; + height: 160px; + display: flex; + align-items: center; + padding: 0 80px; + &-text { + color: #fff; + } + } + + &__addr { + background: #fff; + margin: 0 0 $edge-margin; + } + + &__express { + padding: $edge-margin $edge-size $edge-margin ($edge-size + 40px); + } + + &__total { + padding: 0 0 $edge-size; + .sp-cell { + padding: 8px $edge-size; + display: flex; + align-items: space-between; + &__bd { + text-align: right; + } + } + } + + .address-info { + margin: 0 0 $edge-margin; + &__receiver { + color: #111; + display: block; + font-size: $font-size-large; + margin: 0 0 16px; + line-height: 1; + } + &__addr { + color: #111; + line-height: 1; + display: block; + } + } + + .sec-orders { + &__hd { + padding: $edge-margin $edge-size; + } + } + + .trade-extra { + display: flex; + align-items: space-between; + padding: $edge-margin $edge-size; + &__bd { + flex: 1; + display: flex; + flex-direction: column; + font-size: $font-size-small; + } + &__ft { + .at-button { + transform: scale(0.8); + transform-origin: center right; + } + } + } + + .toolbar-actions { + display: flex; + justify-content: flex-end; + .at-button { + margin: 0 0 0 20px; + } + } +} \ No newline at end of file diff --git a/src/pages/trade/list.js b/src/pages/trade/list.js index 2137f10c8..5d6fe30da 100644 --- a/src/pages/trade/list.js +++ b/src/pages/trade/list.js @@ -1,14 +1,18 @@ import Taro, { Component } from '@tarojs/taro' import { View, Text, ScrollView } from '@tarojs/components' import { AtTabs, AtTabsPane } from 'taro-ui' +import { Loading } from '@/components' import api from '@/api' +import { withPager } from '@/hocs' import { TradeItem } from './comps/item' import './list.scss' +@withPager export default class TradeList extends Component { constructor (props) { super(props) + this.state = { ...this.state, curTabIdx: 0, @@ -19,41 +23,67 @@ export default class TradeList extends Component { {title: '待收货'}, {title: '待评价'} ], - initedTabs: {}, - lists: [] + list: [], + isLoading: false } } componentDidMount () { - this.fetch({ tab: 0 }) + this.nextPage() } async fetch (params) { - const { tab } = params - const { list } = await api.trade.list({ status: tab }) - this.setState({ list }) + this.setState({ isLoading: true }) + const { curTabIdx } = this.state + const { list, total_count: total } = await api.trade.list({ status: curTabIdx, ...params }) + + const nList = this.state.list.concat(list) + this.setState({ + list: nList, + isLoading: false + }) + + return { total } } - onClickTab = (idx) => { + handleClickTab = (idx) => { + if (this.state.isLoading || this.state.page.isLoading) return + + if (idx !== this.state.curTabIdx) { + this.resetPage() + this.setState({ + list: [] + }) + } + this.setState({ curTabIdx: idx + }, () => { + this.nextPage() }) - console.log(idx) - if (this.state.lists[idx] === undefined) { - this.fetch({ tab: idx }) - } + } + + handleClickItem (trade) { + const { tid } = trade + Taro.navigateTo({ + url: `/pages/trade/detail?id=${tid}` + }) + } + + handleClickItemBtn = (type, trade) => { + console.log(type, trade) } render () { - const { curTabIdx, tabList, lists } = this.state - const list = lists[curTabIdx] + const { curTabIdx, tabList, list, page } = this.state return ( { tabList.map((panes, pIdx) => @@ -62,22 +92,32 @@ export default class TradeList extends Component { key={pIdx} index={pIdx} > - - {list.map((item, idx) => { - return ( - - ) - })} - ) ) } + + + { + list.map((item, idx) => { + return ( + + ) + }) + } + { + page.isLoading && 正在加载... + } + ) } diff --git a/src/pages/trade/list.scss b/src/pages/trade/list.scss index 233ed9e50..feb942f68 100644 --- a/src/pages/trade/list.scss +++ b/src/pages/trade/list.scss @@ -1,7 +1,30 @@ @import "../../style/imports"; .trade-list { + .at-tabs__header { + position: absolute; + top: 0; + width: 100%; + z-index: $z-index-toolbar; + } &__scroll { - padding-top: $tabbar-height $edge-size $edge-margin; + height: 100vh; + padding: $tabbar-height 0 $edge-margin; + box-sizing: border-box; + } + &__tabs { + position: fixed; + left: 0; + top: 0; + width: 100%; + } + .trade-item { + margin: 0 $edge-size $edge-margin; + .at-button { + font-size: $font-size-small; + padding-left: 26px; + padding-right: 26px; + margin-left: 20px; + } } } \ No newline at end of file diff --git a/src/style/variables.scss b/src/style/variables.scss index 64162709d..12a717e48 100644 --- a/src/style/variables.scss +++ b/src/style/variables.scss @@ -10,7 +10,7 @@ $edge-margin : 5px * 4 !default; $toolbar-height : 120px !default; $toolbar-shadow : 0 -2px 3px rgba(#000, 0.05); -$tabbar-height : 120px !default; +$tabbar-height : 100px !default; $color-weixin : #07C15F !default; $item-border-radius : 20px; diff --git a/src/trade/trade/item.scss b/src/trade/trade/item.scss deleted file mode 100644 index aa45895a3..000000000 --- a/src/trade/trade/item.scss +++ /dev/null @@ -1,18 +0,0 @@ -@import "../../style/imports"; - -.trade-item { - background: #fff; - border-radius: $item-border-radius; - &__hd { - padding: 28px $edge-size; - line-height: 1; - display: flex; - align-items: center; - justify-content: space-between; - .more { - color: $color-link; - font-size: small; - text-align: right; - } - } -} \ No newline at end of file diff --git a/src/utils/index.js b/src/utils/index.js index 756729c31..425cb06c7 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -3,6 +3,7 @@ import styleNames from 'stylenames' import Taro from '@tarojs/taro' import qs from 'qs' import moment from 'moment' +import copy from 'copy-to-clipboard' export { default as log } from './log' @@ -67,6 +68,19 @@ export function formatTime (time, formatter = 'YYYY-MM-DD') { return moment(time).format(formatter) } +export function copyText (text) { + return new Promise((resolve, reject) => { + if (Taro.getEnv() === Taro.ENV_TYPE.WEAPP) { + Taro.setClipboardData({ + data: text, + success: resolve + }) + } else if (copy(Text)) { + resolve(text) + } + }) +} + export { classNames, styleNames