Compare commits

...

2 Commits

Author SHA1 Message Date
王文龙 82a04ee96f update 2024-02-01 10:52:06 +08:00
王文龙 3621def2f5 update 2024-01-24 09:39:31 +08:00
82 changed files with 3049 additions and 756 deletions

View File

@ -14,7 +14,7 @@ import { SG_DIANWU_TOKEN } from '@/consts'
import log from '@/utils/log' import log from '@/utils/log'
import { HTTP_STATUS } from './consts' import { HTTP_STATUS } from './consts'
function addQuery(url, query) { function addQuery (url, query) {
return url + (url.indexOf('?') >= 0 ? '&' : '?') + query return url + (url.indexOf('?') >= 0 ? '&' : '?') + query
} }
@ -49,16 +49,16 @@ class RequestQueue {
this.isRunning = false this.isRunning = false
} }
push(req) { push (req) {
this.requestList.push(req) this.requestList.push(req)
} }
destroy() { destroy () {
this.isRunning = false this.isRunning = false
this.requestList = [] this.requestList = []
} }
run() { run () {
this.isRunning = true this.isRunning = true
const next = async () => { const next = async () => {
const req = this.requestList.shift() const req = this.requestList.shift()
@ -82,7 +82,7 @@ class API {
this.requestQueue = new RequestQueue() this.requestQueue = new RequestQueue()
} }
setOptions(opts) { setOptions (opts) {
let { baseURL = '/' } = opts let { baseURL = '/' } = opts
if (!/\/$/.test(baseURL)) { if (!/\/$/.test(baseURL)) {
baseURL = baseURL + '/' baseURL = baseURL + '/'
@ -102,7 +102,7 @@ class API {
this.options = options this.options = options
} }
errorToast(data) { errorToast (data) {
let errMsg = data.message || (data.data && data.data.message) || '操作失败,请稍后重试' let errMsg = data.message || (data.data && data.data.message) || '操作失败,请稍后重试'
if (errMsg.length > 11) { if (errMsg.length > 11) {
@ -117,11 +117,11 @@ class API {
}, 200) }, 200)
} }
getReqUrl(url) { getReqUrl (url) {
return /^http/.test(url) ? url : `${this.baseURL}${url.replace(/^\//, '')}` return /^http/.test(url) ? url : `${this.baseURL}${url.replace(/^\//, '')}`
} }
handleLogout() { handleLogout () {
this.requestQueue.destroy() this.requestQueue.destroy()
this.isRefreshingToken = false this.isRefreshingToken = false
// S.logout() // S.logout()
@ -148,7 +148,7 @@ class API {
}, 300) }, 300)
} }
intereptorReq(params) { intereptorReq (params) {
const { url, data, header = {}, method = 'GET' } = params const { url, data, header = {}, method = 'GET' } = params
const { company_id, appid } = this.options const { company_id, appid } = this.options
const methodIsGet = method.toLowerCase() === 'get' const methodIsGet = method.toLowerCase() === 'get'
@ -202,7 +202,7 @@ class API {
return config return config
} }
intereptorRes(res) { intereptorRes (res) {
const { data, statusCode, config } = res const { data, statusCode, config } = res
const { showError = true } = config const { showError = true } = config
if (statusCode == HTTP_STATUS.SUCCESS) { if (statusCode == HTTP_STATUS.SUCCESS) {
@ -241,7 +241,7 @@ class API {
return Promise.reject(this.reqError(res, `API error: ${statusCode}`)) return Promise.reject(this.reqError(res, `API error: ${statusCode}`))
} }
async refreshToken() { async refreshToken () {
this.isRefreshingToken = true this.isRefreshingToken = true
// const token = S.getAuthToken() // const token = S.getAuthToken()
const token = Taro.getStorageSync(SG_DIANWU_TOKEN) const token = Taro.getStorageSync(SG_DIANWU_TOKEN)
@ -284,7 +284,7 @@ class API {
* @return {Object} 请求返回的数据 * @return {Object} 请求返回的数据
* @memberof API * @memberof API
*/ */
async makeReq(config = {}, intereptorRes, intereptorReq) { async makeReq (config = {}, intereptorRes, intereptorReq) {
const { showLoading } = config const { showLoading } = config
const options = intereptorReq ? intereptorReq(config) : this.intereptorReq(config) const options = intereptorReq ? intereptorReq(config) : this.intereptorReq(config)
@ -301,7 +301,7 @@ class API {
const token = Taro.getStorageSync(SG_DIANWU_TOKEN) const token = Taro.getStorageSync(SG_DIANWU_TOKEN)
if ( if (
res.statusCode === HTTP_STATUS.UNAUTHORIZED && res.statusCode === HTTP_STATUS.UNAUTHORIZED &&
(res.data.data && res.data.data.status_code) === HTTP_STATUS.TOKEN_NEEDS_REFRESH && token (res.data?.data && res.data.data?.status_code) === HTTP_STATUS.TOKEN_NEEDS_REFRESH && token
// S.getAuthToken() // S.getAuthToken()
) { ) {
// token失效时重造请求并刷新token // token失效时重造请求并刷新token
@ -328,7 +328,7 @@ class API {
return ret return ret
} }
pendingReq(config, intereptorRes, intereptorReq, isSend) { pendingReq (config, intereptorRes, intereptorReq, isSend) {
return new Promise((resolve) => { return new Promise((resolve) => {
const pendingReq = async () => { const pendingReq = async () => {
// 仅加入队列一次 // 仅加入队列一次
@ -344,7 +344,7 @@ class API {
}) })
} }
get(url, data, config) { get (url, data, config) {
return this.makeReq({ return this.makeReq({
...config, ...config,
url, url,
@ -353,14 +353,14 @@ class API {
}) })
} }
reqError(res, msg = '') { reqError (res, msg = '') {
const errMsg = (res.data && res.data?.data?.message) || msg const errMsg = (res.data && res.data?.data?.message) || msg
const err = new Error(errMsg) const err = new Error(errMsg)
err.res = res err.res = res
return err return err
} }
post(url, data, config) { post (url, data, config) {
return this.makeReq({ return this.makeReq({
...config, ...config,
url, url,
@ -369,7 +369,7 @@ class API {
}) })
} }
put(url, data, config) { put (url, data, config) {
return this.makeReq({ return this.makeReq({
...config, ...config,
url, url,
@ -378,7 +378,7 @@ class API {
}) })
} }
delete(url, data, config) { delete (url, data, config) {
return this.makeReq({ return this.makeReq({
...config, ...config,
url, url,

View File

@ -13,7 +13,7 @@ import {
import log from '@/utils/log' import log from '@/utils/log'
import { HTTP_STATUS } from './consts' import { HTTP_STATUS } from './consts'
function addQuery(url, query) { function addQuery (url, query) {
return url + (url.indexOf('?') >= 0 ? '&' : '?') + query return url + (url.indexOf('?') >= 0 ? '&' : '?') + query
} }
@ -41,7 +41,7 @@ const request = (() => {
} }
// 支付宝小程序,请求失败时,需要额外处理 // 支付宝小程序,请求失败时,需要额外处理
if(isAlipay){ if (isAlipay) {
return async (...args) => { return async (...args) => {
let res let res
try { try {
@ -65,16 +65,16 @@ class RequestQueue {
this.isRunning = false this.isRunning = false
} }
push(req) { push (req) {
this.requestList.push(req) this.requestList.push(req)
} }
destroy() { destroy () {
this.isRunning = false this.isRunning = false
this.requestList = [] this.requestList = []
} }
run() { run () {
this.isRunning = true this.isRunning = true
const next = async () => { const next = async () => {
const req = this.requestList.shift() const req = this.requestList.shift()
@ -98,7 +98,7 @@ class API {
this.requestQueue = new RequestQueue() this.requestQueue = new RequestQueue()
} }
setOptions(opts) { setOptions (opts) {
let { baseURL = '/' } = opts let { baseURL = '/' } = opts
if (!/\/$/.test(baseURL)) { if (!/\/$/.test(baseURL)) {
baseURL = baseURL + '/' baseURL = baseURL + '/'
@ -118,7 +118,7 @@ class API {
this.options = options this.options = options
} }
errorToast(data) { errorToast (data) {
let errMsg = data.message || (data.data && data.data.message) || '操作失败,请稍后重试' let errMsg = data.message || (data.data && data.data.message) || '操作失败,请稍后重试'
if (errMsg.length > 11) { if (errMsg.length > 11) {
@ -133,11 +133,11 @@ class API {
}, 200) }, 200)
} }
getReqUrl(url) { getReqUrl (url) {
return /^http/.test(url) ? url : `${this.baseURL}${url.replace(/^\//, '')}` return /^http/.test(url) ? url : `${this.baseURL}${url.replace(/^\//, '')}`
} }
handleLogout() { handleLogout () {
this.requestQueue.destroy() this.requestQueue.destroy()
this.isRefreshingToken = false this.isRefreshingToken = false
S.logout() S.logout()
@ -151,19 +151,19 @@ class API {
url = '/subpages/merchant/login' url = '/subpages/merchant/login'
} else if (isGoodsShelves()) { } else if (isGoodsShelves()) {
url = '/subpages/guide/index' url = '/subpages/guide/index'
} else if (VERSION_IN_PURCHASE){ } else if (VERSION_IN_PURCHASE) {
url = `/subpages/purchase/member` url = `/subpages/purchase/member`
} else { } else {
url = `/subpages/member/index` url = `/subpages/member/index`
} }
if(path != url) { if (path != url) {
url = url + `?redirect_url=${encodeURIComponent(fullPath)}` url = url + `?redirect_url=${encodeURIComponent(fullPath)}`
Taro.redirectTo({ url }) Taro.redirectTo({ url })
} }
}, 300) }, 300)
} }
intereptorReq(params) { intereptorReq (params) {
const { url, data, header = {}, method = 'GET' } = params const { url, data, header = {}, method = 'GET' } = params
const { company_id, appid } = this.options const { company_id, appid } = this.options
const methodIsGet = method.toLowerCase() === 'get' const methodIsGet = method.toLowerCase() === 'get'
@ -216,11 +216,11 @@ class API {
return config return config
} }
intereptorRes(res) { intereptorRes (res) {
const { data, statusCode, config } = res const { data, statusCode, config } = res
const { showError = true } = config const { showError = true } = config
if (statusCode == HTTP_STATUS.SUCCESS) { if (statusCode == HTTP_STATUS.SUCCESS) {
const { status_code } = data.data const { status_code } = data.data || {}
if (!status_code) { if (!status_code) {
return data.data return data.data
} else { } else {
@ -255,10 +255,10 @@ class API {
return Promise.reject(this.reqError(res, `API error: ${statusCode}`)) return Promise.reject(this.reqError(res, `API error: ${statusCode}`))
} }
async refreshToken() { async refreshToken () {
this.isRefreshingToken = true this.isRefreshingToken = true
const token = S.getAuthToken() const token = S.getAuthToken()
console.log('refreshToken',66); console.log('refreshToken', 66)
try { try {
await this.makeReq( await this.makeReq(
{ {
@ -298,7 +298,7 @@ class API {
* @return {Object} 请求返回的数据 * @return {Object} 请求返回的数据
* @memberof API * @memberof API
*/ */
async makeReq(config = {}, intereptorRes, intereptorReq) { async makeReq (config = {}, intereptorRes, intereptorReq) {
const { showLoading } = config const { showLoading } = config
const options = intereptorReq ? intereptorReq(config) : this.intereptorReq(config) const options = intereptorReq ? intereptorReq(config) : this.intereptorReq(config)
@ -342,7 +342,7 @@ class API {
return ret return ret
} }
pendingReq(config, intereptorRes, intereptorReq, isSend) { pendingReq (config, intereptorRes, intereptorReq, isSend) {
return new Promise((resolve) => { return new Promise((resolve) => {
const pendingReq = async () => { const pendingReq = async () => {
// 仅加入队列一次 // 仅加入队列一次
@ -358,7 +358,7 @@ class API {
}) })
} }
get(url, data, config) { get (url, data, config) {
return this.makeReq({ return this.makeReq({
...config, ...config,
url, url,
@ -367,14 +367,14 @@ class API {
}) })
} }
reqError(res, msg = '') { reqError (res, msg = '') {
const errMsg = (res.data && res.data?.data?.message) || msg const errMsg = (res.data && res.data?.data?.message) || msg
const err = new Error(errMsg) const err = new Error(errMsg)
err.res = res err.res = res
return err return err
} }
post(url, data, config) { post (url, data, config) {
return this.makeReq({ return this.makeReq({
...config, ...config,
url, url,
@ -383,7 +383,7 @@ class API {
}) })
} }
put(url, data, config) { put (url, data, config) {
return this.makeReq({ return this.makeReq({
...config, ...config,
url, url,
@ -392,7 +392,7 @@ class API {
}) })
} }
delete(url, data, config) { delete (url, data, config) {
return this.makeReq({ return this.makeReq({
...config, ...config,
url, url,

View File

@ -87,7 +87,7 @@ export function getShopTemplate (params) {
/** /**
* @function 店铺首页模版配置 * @function 店铺首页模版配置
*/ */
export function getStoreShopTemplate (params) { export function getStoreShopTemplate (params) {
return req.get(`/pagestemplate/shopDetail`, { return req.get(`/pagestemplate/shopDetail`, {
template_name: 'yykweishop', template_name: 'yykweishop',
weapp_pages: 'index', weapp_pages: 'index',
@ -102,6 +102,11 @@ export function getMapKeyDetail (params) {
} }
// 获取小程序价格配置 // 获取小程序价格配置
export function getAppGoodsPriceSetting() { export function getAppGoodsPriceSetting () {
return req.get('/setting/itemPrice') return req.get('/setting/itemPrice')
} }
// 获取首页轮播图
export function homeSwiperList (params) {
return req.get('/xiudibanner', params)
}

View File

@ -275,6 +275,8 @@ const config = {
'pages/trade/refund-detail', //售后申请提交结果页面 'pages/trade/refund-detail', //售后申请提交结果页面
'pages/trade/refund-sendback', //售后填写物流公司页面 'pages/trade/refund-sendback', //售后填写物流公司页面
'pages/trade/invoice-list', //发票管理 'pages/trade/invoice-list', //发票管理
'pages/trade/invoice-info', //发票信息
'pages/trade/invoice-record', //发票列表
// 'pages/cashier/index', //收银台页面 // 'pages/cashier/index', //收银台页面
// 'pages/cashier/cashier-result', //支付结果页面 // 'pages/cashier/cashier-result', //支付结果页面
'pages/qrcode-buy', //二维码购买页 'pages/qrcode-buy', //二维码购买页

BIN
src/assets/close.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 509 B

View File

@ -9,7 +9,21 @@
.address { .address {
display: flex; display: flex;
align-items: center; align-items: center;
padding: 24px 16px; padding: 24px 28px;
.dz-addr {
font-size: 40px;
color: #000;
line-height: 1;
margin-bottom: 20px;
display: flex;
justify-content: space-between;
align-items: center;
.bj {
font-size: 26px;
line-height: 1;
padding: 18px 20px;
}
}
} }
// choose-address // choose-address
&__bd { &__bd {
@ -28,16 +42,17 @@
} }
.user-info-trade { .user-info-trade {
color: #666; color: #666;
font-size: 28px; font-size: 26px;
.name { .name {
margin-right: $edge-margin; margin-right: 8px;
} }
} }
.address-detail { .address-detail {
color: #222; color: #666;
font-weight: bold; // font-weight: bold;
font-size: 32px; font-size: 26px;
padding: 24px 0; // padding: 24px 0;
padding-top: 6px;
} }
.address-area { .address-area {
color: #666; color: #666;

View File

@ -17,10 +17,10 @@ import './address.scss'
) )
export default class AddressChoose extends Component { export default class AddressChoose extends Component {
static defaultProps = { static defaultProps = {
onClickBack: () => {} onClickBack: () => { }
} }
constructor (props) { constructor(props) {
super(props) super(props)
this.state = {} this.state = {}
@ -45,25 +45,31 @@ export default class AddressChoose extends Component {
return ( return (
<View className='address-picker'> <View className='address-picker'>
<View className='address' onClick={this.clickTo.bind(this, 'choose')}> <View className='address'>
{isObjectsValue(isAddress) ? ( {isObjectsValue(isAddress) ? (
<View className='address-picker__bd'> <View className='address-picker__bd'>
<View className='address-receive'> <View className='address-receive'>
<View className='info-trade'> <View className='info-trade'>
<View className='address-area'> {/* <View className='address-area'>
{isAddress.is_def && <View className='def'>默认</View>} {isAddress.is_def && <View className='def'>默认</View>}
{isAddress.province} {isAddress.province}
{isAddress.city} {isAddress.city}
{isAddress.county} {isAddress.county}
</View> */}
<View className="dz-addr">
<Text>收货地址</Text>
<Text className='bj' onClick={this.clickTo.bind(this, 'choose')}>编辑</Text>
</View> </View>
<View className='address-detail'>{isAddress.adrdetail}</View>
<View className='user-info-trade'> <View className='user-info-trade'>
<Text className='name'>{isAddress.username}</Text> <Text className='name'>{isAddress.username}</Text>
<Text>{isAddress.telephone}</Text> <Text>{isAddress.telephone}</Text>
</View> </View>
<View className='address-detail'> {isAddress.province}
{isAddress.city}
{isAddress.county}{isAddress.adrdetail}</View>
</View> </View>
</View> </View>
<View className='sp-cell__ft-icon iconfont icon-arrowRight'></View> {/* <View className='sp-cell__ft-icon iconfont icon-arrowRight'></View> */}
</View> </View>
) : ( ) : (
<View className='address-info__bd'>+请选择收货地址</View> <View className='address-info__bd'>+请选择收货地址</View>

View File

@ -5,7 +5,7 @@
box-sizing: border-box; box-sizing: border-box;
&__focus { &__focus {
height: 100vh; height: 100vh;
z-index: 10; z-index: 99;
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
@ -14,6 +14,7 @@
padding: 16px 28px; padding: 16px 28px;
background: #fff; background: #fff;
box-sizing: border-box; box-sizing: border-box;
overflow: hidden;
&.without-dialog { &.without-dialog {
height: auto; height: auto;
} }

View File

@ -6,8 +6,25 @@
margin-left: 10px; margin-left: 10px;
} }
.icon-my { .icon-my {
transition: all 0.2s ease-in-out; transition: all 0.3s ease-in-out;
} }
@keyframes scale {
0% {
transform: scale(0.1);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
// .icon-checkbox-weixuan {
// animation: scale 0.5s reverse forwards;
// }
// .icon-checkbox-xuanzhong {
// animation: scale 0.5s forwards;
// }
.icon-checkbox-xuanzhong, .icon-checkbox-xuanzhong,
.icon-roundcheckfill { .icon-roundcheckfill {
font-size: 40px; font-size: 40px;

View File

@ -6,7 +6,8 @@ import SpImage from './../sp-image'
import './index.scss' import './index.scss'
const TYPES = { const TYPES = {
cart: 'empty_cart.png' // cart: 'empty_cart.png'
cart: 'cart/logo-hui.png'
} }
function SpDefault (props) { function SpDefault (props) {
@ -21,7 +22,7 @@ function SpDefault (props) {
)} )}
> >
<View className='sp-default-hd'> <View className='sp-default-hd'>
{type && <SpImage className='default-img' src={TYPES[type]} width={350} />} {type && <SpImage className='default-img' src={TYPES[type]} width={350} isNew />}
</View> </View>
<View className='sp-default-bd'>{message}</View> <View className='sp-default-bd'>{message}</View>
<View className='sp-default-ft'>{children}</View> <View className='sp-default-ft'>{children}</View>

View File

@ -16,9 +16,9 @@ export default class SpFilterBar extends Component {
sort: {}, sort: {},
current: 0, current: 0,
list: [ list: [
{ text: '推荐', val: '0' }, // { text: '推荐', val: '0' },
{ text: '上架时间', val: '3' }, { text: '上架时间', val: '6' }, //更新时间降序
{ text: '价格低-高', val: '1' }, { text: '价格低-高', val: '3' },
{ text: '价格高-低', val: '2' }, { text: '价格高-低', val: '2' },
] ]
} }
@ -31,6 +31,7 @@ export default class SpFilterBar extends Component {
curIdx: current, curIdx: current,
sortOrder: 1, sortOrder: 1,
value: '0', value: '0',
sortVal: '0',
showFilter: false showFilter: false
} }
} }
@ -54,19 +55,18 @@ export default class SpFilterBar extends Component {
}) })
} }
handleConfirm = (val, index) => { handleConfirm = ({ val }, index) => {
console.log("🚀 ~ SpFilterBar ~ val:", val, index)
// this.setState({ // this.setState({
// value: val // value: val
// }) // })
// this.props.onChange({ this.props.onChange({
// current: val current: val
// }) })
} }
render () { render () {
const { list = [], className, custom, color, num } = this.props const { list = [], className, custom, color, num } = this.props
const { sortOrder, curIdx, value, showFilter } = this.state const { sortOrder, curIdx, value, showFilter, sortVal } = this.state
return ( return (
<View className={classNames('sp-filter-bar', className)}> <View className={classNames('sp-filter-bar', className)}>
@ -95,7 +95,7 @@ export default class SpFilterBar extends Component {
<AtIcon value='menu' size='16' color='#000'></AtIcon> <AtIcon value='menu' size='16' color='#000'></AtIcon>
</View> </View>
</SpPicker> </SpPicker>
<SpPicker mode="select" source={list} value={value} pickerConfirm={this.handleConfirm.bind(this)} leftBtnTxt="排序" rightBtnTxt={<AtIcon value="close" size={14} color="#000"></AtIcon>}> <SpPicker mode="select" source={list} value={sortVal} pickerConfirm={this.handleConfirm.bind(this)} leftBtnTxt="排序" rightBtnTxt={<AtIcon value="close" size={14} color="#000"></AtIcon>}>
<View className="item item-right"> <View className="item item-right">
<Text className='text'>排序</Text> <Text className='text'>排序</Text>
<Image className="img" src={require('@/assets/icon/sort.png')}></Image> <Image className="img" src={require('@/assets/icon/sort.png')}></Image>

View File

@ -7,13 +7,29 @@ import { GOODS_TYPE } from '@/consts'
import { VERSION_IN_PURCHASE } from '@/utils' import { VERSION_IN_PURCHASE } from '@/utils'
import './index.scss' import './index.scss'
function SpGoodsCell(props) { function SpGoodsCell (props) {
const { info, onSelectSku } = props const { info, onSelectSku } = props
const { userInfo = {}, vipInfo = {} } = useSelector((state) => state.user) const { userInfo = {}, vipInfo = {} } = useSelector((state) => state.user)
if (!info) { if (!info) {
return null return null
} }
const desc = info.itemSpecDesc
let desc_info = ''
if (desc) {
try {
const descArr = desc.split(',')
descArr.forEach((item, index) => {
let [_, value] = item.split(':')
if (index === 1) {
value = value.substring(0, 2)
}
desc_info += value + ' '
})
} catch (error) {
}
}
const handleClick = () => { const handleClick = () => {
onSelectSku && onSelectSku(info) onSelectSku && onSelectSku(info)
} }
@ -45,89 +61,91 @@ function SpGoodsCell(props) {
// console.log('isNaN(memberPrice):', info.orderItemType) // console.log('isNaN(memberPrice):', info.orderItemType)
return ( return (
<View className='sp-goods-cell'> <>
<View className='goods-item-hd'> <View className='sp-goods-cell'>
<SpImage mode='aspectFit' src={info.img} width={180} height={180} /> <View className='goods-item-hd'>
</View> <SpImage mode='aspectFit' src={info.img} width={150} height={150} />
<View className='goods-item-bd'>
<View className='item-hd'>
<View className='goods-title'>{info.itemName}</View>
</View> </View>
<View className='item-bd'> <View className='goods-item-bd'>
<View> <View className='item-hd'>
{/* 多规格商品 */} <View className='goods-title'>{info.itemName}</View>
{!info.nospec && ( </View>
<View className='goods-sku' onClick={handleClick}> <View className='item-bd'>
{onSelectSku && ( <View>
<View className='spec-text'> {/* 多规格商品 */}
{info.specText || '选择规格'} {!info.nospec && (
<Text className='iconfont icon-qianwang-01'></Text> <View className='goods-sku' onClick={handleClick}>
</View> {onSelectSku && (
)} <View className='spec-text'>
{!onSelectSku && info.itemSpecDesc} {desc_info || info.specText || '选择规格'}
<Text className='iconfont icon-qianwang-01'></Text>
</View>
)}
{!onSelectSku && (desc_info || info.itemSpecDesc)}
</View>
)}
</View>
</View>
<View className='labels-block'>
{!isNaN(memberPrice) && !VERSION_IN_PURCHASE && (
<View className='goods-type'>
{vipInfo?.isVip ? vipInfo?.grade_name : userInfo?.gradeInfo?.grade_name}
</View> </View>
)} )}
</View> {info?.orderItemType && info?.orderItemType != 'normal' && (
</View> <View className='goods-type'>{GOODS_TYPE[info.orderItemType]}</View>
<View className='labels-block'>
{!isNaN(memberPrice) && !VERSION_IN_PURCHASE && (
<View className='goods-type'>
{vipInfo?.isVip ? vipInfo?.grade_name : userInfo?.gradeInfo?.grade_name}
</View>
)}
{info?.orderItemType && info?.orderItemType != 'normal' && (
<View className='goods-type'>{GOODS_TYPE[info.orderItemType]}</View>
)}
{info.discount_info?.map((sp, idx) => {
if (sp.type != 'coupon_discount' && sp.type != 'member_price') {
return (
<View className='goods-type' key={`goods-type__${idx}`}>
{sp.info}
</View>
)
}
})}
{cusActivity?.map((el) => {
let limitTxt = ''
let limitNum = ''
if (el?.activity_type == 'limited_buy') {
limitNum = el?.limit
if (el?.day == 0) {
limitTxt = `限购${limitNum}`
} else {
limitTxt = `${el?.day}天,限购${limitNum}`
}
}
{
/* else if (el?.activity_type == 'seckill' || el?.activity_type == 'limited_time_sale') {
limitNum = el?.limit
limitTxt = `(限购${limitNum}件)`
} else if (el?.activity_type == 'member_tag_targeted_promotion') {
limitTxt = '专属优惠'
} */
}
return <View className='goods-type'>{limitTxt}</View>
})}
{/* {limitTxt && <View className='goods-type'>{limitTxt}</View>} */}
</View>
<View className='item-ft'>
<View className='price-gp'>
{isPoint && <SpPoint value={point} />}
{!isPoint && <SpPrice value={_price}></SpPrice>}
{info.marketPrice > 0 && (
<SpPrice
className='market-price'
size={28}
lineThrough
value={info.marketPrice}
></SpPrice>
)} )}
{info.discount_info?.map((sp, idx) => {
if (sp.type != 'coupon_discount' && sp.type != 'member_price') {
return (
<View className='goods-type' key={`goods-type__${idx}`}>
{sp.info}
</View>
)
}
})}
{cusActivity?.map((el) => {
let limitTxt = ''
let limitNum = ''
if (el?.activity_type == 'limited_buy') {
limitNum = el?.limit
if (el?.day == 0) {
limitTxt = `限购${limitNum}`
} else {
limitTxt = `${el?.day}天,限购${limitNum}`
}
}
{
/* else if (el?.activity_type == 'seckill' || el?.activity_type == 'limited_time_sale') {
limitNum = el?.limit
limitTxt = `(限购${limitNum}件)`
} else if (el?.activity_type == 'member_tag_targeted_promotion') {
limitTxt = '专属优惠'
} */
}
return <View className='goods-type'>{limitTxt}</View>
})}
{/* {limitTxt && <View className='goods-type'>{limitTxt}</View>} */}
</View> </View>
<View className='item-ft'>
{info.num && <Text className='item-num'>x {info.num}</Text>} {info.num && <Text className='item-num'>数量{info.num}</Text>}
</View>
</View> </View>
</View> </View>
</View> <View className='price-gp'>
{isPoint && <SpPoint value={point} />}
{!isPoint && <SpPrice value={_price} noDecimal={false} showSeparator ></SpPrice>}
{info.marketPrice > 0 && (
<SpPrice
className='market-price'
size={32}
lineThrough
value={info.marketPrice}
></SpPrice>
)}
</View>
</>
) )
} }

View File

@ -1,12 +1,17 @@
.sp-goods-cell { .sp-goods-cell {
display: flex; display: flex;
.goods-item-hd { .goods-item-hd {
margin-right: 24px; margin-right: 60px;
} }
.goods-item-bd { .goods-item-bd {
flex: 1; flex: 1;
// flex-direction: column;
// display: flex;
// justify-content: space-between;
.goods-title { .goods-title {
max-width: 400px; max-width: 400px;
font-size: 20px;
color: #000;
@include multi-ellipsis(2); @include multi-ellipsis(2);
} }
.item-bd { .item-bd {
@ -16,13 +21,15 @@
justify-content: space-between; justify-content: space-between;
.goods-sku { .goods-sku {
background: #f5f5f5; // background: #f5f5f5;
height: 46px; // height: 46px;
line-height: 46px; // line-height: 46px;
padding: 0 2px; // padding: 0 2px;
color: #666; color: #333;
display: inline-block; display: inline-block;
max-width: 400px; max-width: 400px;
font-size: 20px;
padding: 26px 0;
@include text-overflow(); @include text-overflow();
} }
} }
@ -30,6 +37,8 @@
.item-ft { .item-ft {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
font-size: 20px;
line-height: 1;
.price-gp { .price-gp {
display: flex; display: flex;
align-items: flex-end; align-items: flex-end;
@ -43,7 +52,7 @@
.spec-text { .spec-text {
display: flex; display: flex;
align-items: center; align-items: center;
font-size: 26px; font-size: 20px;
color: #222; color: #222;
.icon-qianwang-01 { .icon-qianwang-01 {
font-size: 16px; font-size: 16px;

View File

@ -4,6 +4,7 @@ import Taro, { getCurrentInstance } from '@tarojs/taro'
import { View, Text, Image, ScrollView } from '@tarojs/components' import { View, Text, Image, ScrollView } from '@tarojs/components'
import { SpImage, SpPoint, SpPrice, SpVipLabel } from '@/components' import { SpImage, SpPoint, SpPrice, SpVipLabel } from '@/components'
import { fetchUserFavs, addUserFav, deleteUserFav } from '@/store/slices/user' import { fetchUserFavs, addUserFav, deleteUserFav } from '@/store/slices/user'
import throttle from 'lodash/throttle'
import qs from 'qs' import qs from 'qs'
import api from '@/api' import api from '@/api'
import S from '@/spx' import S from '@/spx'
@ -37,11 +38,20 @@ function SpGoodsItem (props) {
showPrice = true, showPrice = true,
hideStore = false, hideStore = false,
renderBrand, renderBrand,
mode = 'scaleToFill' mode = 'scaleToFill',
showSalePrice = true,
height = 310,
width = 310
} = props } = props
const [info, setInfo] = useState(props.info || null) const [info, setInfo] = useState(props.info || null)
const [current, setCurrent] = useState(0) const [current, setCurrent] = useState(0)
const [move, setMove] = useState(0) const [move, setMove] = useState(0)
const [selColorItem, setSelColorItem] = useState({})
const setSelColor = (index, item) => {
setCurrent(index)
setSelColorItem(item)
}
const handleFavClick = async (e) => { const handleFavClick = async (e) => {
e.stopPropagation() e.stopPropagation()
@ -62,16 +72,16 @@ function SpGoodsItem (props) {
} }
const handleClick = () => { const handleClick = () => {
const { itemId, distributorId, card_id, code, user_card_id, point } = info const { itemId, item_id, distributorId, distributor_id, card_id, code, user_card_id, point } = info
if (onClick) { if (onClick) {
onClick() onClick()
return return
} }
let query = { id: itemId } let query = { id: itemId || item_id }
if (typeof distributorId != 'undefined') { if (typeof distributorId != 'undefined' || typeof distributor_id != 'undefined') {
query = { query = {
...query, ...query,
dtid: distributorId dtid: distributorId || distributor_id
} }
} }
if (card_id) { if (card_id) {
@ -82,8 +92,9 @@ function SpGoodsItem (props) {
user_card_id user_card_id
} }
} }
query.idx = current
const url = `${!!point ? '/subpages/pointshop/espier-detail' : '/pages/item/espier-detail'}?${qs.stringify(query)}` // const url = `${!!point ? '/subpages/pointshop/espier-detail' : '/pages/item/espier-detail'}?${qs.stringify(query)}`
const url = `${'/pages/item/espier-detail'}?${qs.stringify(query)}`
Taro.navigateTo({ Taro.navigateTo({
url url
}) })
@ -93,17 +104,38 @@ function SpGoodsItem (props) {
return null return null
} }
const colors = [{ color: '#000' }, { color: '#fff' }, { color: 'skyblue' }, { color: 'purple' }] const colors = [{ color_value: '#000' }, { color_value: '#fff' }, { color_value: 'skyblue' }, { color_value: 'purple' }]
// console.log( "favs:", favs );
const isFaved = favs.findIndex((item) => item.item_id == info.itemId) > -1 const isFaved = favs.findIndex((item) => item.item_id == info.itemId) > -1
const isShowStore = const isShowStore =
!hideStore && VERSION_PLATFORM && info.distributor_info && !Array.isArray(info.distributor_info) !hideStore && VERSION_PLATFORM && info.distributor_info && !Array.isArray(info.distributor_info)
let left = false
const handleLeft = () => {
if (left) return
left = true
setMove(move > 1 ? move - 1 : 0)
setTimeout(() => {
left = false
}, 800)
}
let right = false
const i = (info.spec_images || colors).length
const handleRight = () => {
if (right) return
right = true
setMove(move < i - 2 ? move + 1 : move)
setTimeout(() => {
right = false
}, 1000)
}
return ( return (
<View className={classNames('sp-goods-item')} onClick={handleClick.bind(this)}> <View className={classNames('sp-goods-item')} onClick={handleClick.bind(this)}>
<View className='goods-item__hd'> <View className='goods-item__hd'>
<SpImage lazyLoad src={info.pic} height={310} width={310} mode={"aspectFill"} /> <SpImage lazyLoad src={selColorItem.item_image_url?.[0] || info.spec_images?.[0]?.item_image_url?.[0] || info.pic} height={height} width={width} mode={"scaleToFill"} />
<View className="new">NEW</View> {info.tagList.map((item, index) => <View className="new" style={{ borderColor: item.tag_color, color: item.font_color, left: index === 0 ? '20rpx' : index * 30 + 8 + 'rpx' }} key={index + item.item_id}>{item.tag_name}</View>)}
{/* <View className="new" style={{ left: '120rpx' }}>NEW</View> */}
</View> </View>
{/* {renderBrand && <View className='goods-brand-wrap'>{renderBrand}</View>} */} {/* {renderBrand && <View className='goods-brand-wrap'>{renderBrand}</View>} */}
<View className='goods-item__bd'> <View className='goods-item__bd'>
@ -121,26 +153,28 @@ function SpGoodsItem (props) {
)} )}
<View className='goods-info'> <View className='goods-info'>
<View className='goods-desc'>{info.brief}</View> <View className='goods-desc-text'>{info.item_name || info.itemName}</View>
<View className='goods-title'>{info.itemName}</View> <View className='goods-title'>{info.brief}</View>
<View className="goods-price"> {showSalePrice && <>
<Text className="symobol">¥</Text> <View className="goods-price">
<Text className="price">{info.activityPrice || info.price}</Text> <Text className="symobol">¥</Text>
</View> <Text className="price">{info.activityPrice || info.price}</Text>
<View className="switch-color" onClick={(e) => e.stopPropagation()}> </View>
<Text className="icon-my icon-arrow" onClick={() => setMove(move > 1 ? move - 1 : 0)}></Text> <View className="switch-color" onClick={(e) => e.stopPropagation()}>
<ScrollView onScroll={(e) => { <Text className="icon-my icon-arrow" onClick={handleLeft}></Text>
console.log(e.detail.scrollLeft / 32) <ScrollView onScroll={(e) => {
// setMove(Math.floor(e.detail.scrollLeft / 32)) // console.log(e.detail.scrollLeft / 32)
}} scrollLeft={move * 32} scrollX scrollWithAnimation className='color-box' showScrollbar={false}> // setMove(Math.floor(e.detail.scrollLeft / 32))
{(info.colors || colors).map((item, index) => ( }} scrollLeft={move * 32} scrollX scrollWithAnimation className='color-box' showScrollbar={false}>
<View className='color-item' style={{ transfor: `translateX(-${move * 32}px)` }} onClick={() => setCurrent(index)}> {(info.spec_images || colors).map((item, index) => (
<View className={`color${index == current ? ' active' : ''}`} style={{ backgroundColor: item.color || '#000' }} key={`color__${index}`}></View> <View className='color-item' style={{ transform: `translateX(-${move * 32}px)` }} onClick={() => setSelColor(index, item)} key={`color__${index}`}>
</View> <View className={`color${index == current ? ' active' : ''}`} style={{ backgroundColor: item.color_value || '#000' }}></View>
))} </View>
</ScrollView> ))}
<Text className="icon-my icon-arrow-right" onClick={() => setMove(move < (info.colors || colors).length - 2 ? move + 1 : move)}></Text> </ScrollView>
</View> <Text className="icon-my icon-arrow-right" onClick={handleRight}></Text>
</View>
</>}
</View> </View>
{/* 促销活动标签 */} {/* 促销活动标签 */}
@ -154,13 +188,13 @@ function SpGoodsItem (props) {
</View> </View>
)} )}
<View className='bd-block'> {false && <View className='bd-block'>
{/* 商品价格、积分 */} {/* 商品价格、积分 */}
{info.point && ( {/* {info.point && (
<View className='goods-point'> <View className='goods-point'>
<SpPoint value={info.point} /> <SpPoint value={info.point} />
</View> </View>
)} )} */}
{!info.point && showPrice && ( {!info.point && showPrice && (
<View className='goods-price'> <View className='goods-price'>
@ -220,10 +254,10 @@ function SpGoodsItem (props) {
/> />
</View> </View>
)} */} )} */}
</View> </View>}
{isShowStore && ( {isShowStore && (
<View className='goods__store' onClick={() => onStoreClick(info)}> <View className='goods__store' onClick={() => onStoreClick(info, current)}>
<SpImage <SpImage
src={info.distributor_info.distributor_info || 'shop_default_logo.png'} src={info.distributor_info.distributor_info || 'shop_default_logo.png'}
width={60} width={60}
@ -238,7 +272,7 @@ function SpGoodsItem (props) {
)} )}
</View> </View>
<View className='goods-item__ft'>{renderFooter}</View> {renderFooter && <View className='goods-item__ft'>{renderFooter}</View>}
{/* {info.brand && ( {/* {info.brand && (
<View className='goods-item__ft'> <View className='goods-item__ft'>

View File

@ -2,7 +2,8 @@
background-color: #fff; background-color: #fff;
// border-radius: 4px; // border-radius: 4px;
overflow: hidden; overflow: hidden;
padding-bottom: 24px; padding-bottom: 20px;
animation: fadeInAnimation 0.35s ease-in;
// background-color: #222; // background-color: #222;
.goods-item { .goods-item {
&__hd { &__hd {
@ -11,6 +12,9 @@
align-items: center; align-items: center;
box-sizing: border-box; box-sizing: border-box;
position: relative; position: relative;
image {
animation: fadeInAnimation 0.35s ease-in;
}
// padding-top: 100%; // padding-top: 100%;
// position: relative; // position: relative;
// .sp-image { // .sp-image {
@ -39,7 +43,7 @@
} }
&__bd { &__bd {
border-radius: 0; border-radius: 0;
padding: 10px 16px 0; padding: 20px 16px 0;
box-sizing: border-box; box-sizing: border-box;
.goods-info { .goods-info {
display: flex; display: flex;
@ -49,7 +53,7 @@
margin: 0 auto; margin: 0 auto;
line-height: 1; line-height: 1;
.switch-color { .switch-color {
margin-top: 12px; margin-top: 10px;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
@ -101,16 +105,22 @@
font-size: 16px; font-size: 16px;
color: #000; color: #000;
// font-weight: bold; // font-weight: bold;
margin: 12px auto; padding: 10px 20px;
text-align: center;
width: 100%;
box-sizing: border-box;
line-height: 1;
@include multi-ellipsis(2); @include multi-ellipsis(2);
// padding-top: 15px; // padding-top: 15px;
// padding: 15px; // padding: 15px;
} }
.goods-desc { .goods-desc-text {
font-size: 16px; font-size: 16px;
height: auto;
// color: $color-hint-text; // color: $color-hint-text;
color: #000; color: #000;
@include multi-ellipsis(2); @include multi-ellipsis(2);
padding: 2px 0;
} }
.goods-price { .goods-price {
font-weight: bold; font-weight: bold;
@ -203,3 +213,11 @@
} }
} }
} }
@keyframes fadeInAnimation {
from {
opacity: 0;
}
to {
opacity: 1;
}
}

View File

@ -8,7 +8,7 @@ import AtComponent from './component'
import './index.scss' import './index.scss'
// 实现两数相加并保留小数点后最短尾数 // 实现两数相加并保留小数点后最短尾数
function addNum(num1, num2) { function addNum (num1, num2) {
let sq1, sq2 let sq1, sq2
try { try {
sq1 = _toString(num1).split('.')[1].length sq1 = _toString(num1).split('.')[1].length
@ -25,7 +25,7 @@ function addNum(num1, num2) {
} }
// 格式化数字处理01变成1,并且不处理1. 这种情况 // 格式化数字处理01变成1,并且不处理1. 这种情况
function parseValue(num) { function parseValue (num) {
if (num === '') return '0' if (num === '') return '0'
const numStr = _toString(num) const numStr = _toString(num)
@ -37,7 +37,7 @@ function parseValue(num) {
} }
class AtInputNumber extends AtComponent { class AtInputNumber extends AtComponent {
handleClick(clickType) { handleClick (clickType) {
const { disabled, value, min, max, step } = this.props const { disabled, value, min, max, step } = this.props
const lowThanMin = clickType === 'minus' && value <= min const lowThanMin = clickType === 'minus' && value <= min
const overThanMax = clickType === 'plus' && value >= max const overThanMax = clickType === 'plus' && value >= max
@ -104,14 +104,14 @@ class AtInputNumber extends AtComponent {
this.props.onErrorInput(errorValue) this.props.onErrorInput(errorValue)
} }
render() { render () {
const { customStyle, className, width, disabled, value, type, min, max, size } = this.props const { customStyle, className, width, disabled, value, type, min, max, size } = this.props
const inputStyle = { const inputStyle = {
width: width ? `${Taro.pxTransform(width)}` : '' width: width ? `${Taro.pxTransform(width)}` : ''
} }
const inputValue = this.handleValue(value) const inputValue = this.handleValue(value)
console.log('inputValue', inputValue, max, inputValue >= parseInt(max)) // console.log('inputValue', inputValue, max, inputValue >= parseInt(max))
const rootCls = classNames( const rootCls = classNames(
'sp-input-number', 'sp-input-number',
'at-input-number', 'at-input-number',
@ -161,8 +161,8 @@ AtInputNumber.defaultProps = {
max: 100, max: 100,
step: 1, step: 1,
size: '', size: '',
onChange: () => {}, onChange: () => { },
onBlur: () => {} onBlur: () => { }
} }
export default AtInputNumber export default AtInputNumber

View File

@ -99,4 +99,118 @@
padding: 0 50px 50px; padding: 0 50px 50px;
} }
} }
.curtain {
.at-curtain__container {
width: 100%;
padding: 0 30px;
}
.at-curtain__btn-close--bottom {
display: none;
}
&.show {
opacity: 1;
visibility: visible;
}
&.hide {
opacity: 0;
visibility: hidden;
}
&_mask {
display: flex;
position: relative;
width: 100%;
height: 100%;
// padding: 100px 30px;
justify-content: center;
align-items: center;
box-sizing: border-box;
opacity: 1;
}
&_content {
width: 100%;
background-color: #fff;
border-radius: 10px;
padding: 60px 46px 30px;
box-sizing: border-box;
&_title {
display: flex;
justify-content: center;
align-items: center;
font-size: 34px;
line-height: 1;
margin-bottom: 80px;
color: #000;
.sp-image {
margin-right: 4px;
}
}
&_text {
font-size: 26px;
line-height: 2;
max-height: 620px;
color: #000;
}
.agreement-list {
display: inline-block;
}
.agreement-name {
color: #14287e;
padding: 0px 2px;
// font-size: 26px;
}
}
.btn-wrap {
position: relative;
}
.btn {
margin-top: 40px;
margin-bottom: 30px;
}
.no-btn {
display: flex;
justify-content: center;
margin: 0 auto;
padding: 0 32rpx;
height: 80rpx;
color: #222;
font-size: 32rpx;
line-height: 78rpx;
text-align: center;
border-radius: 8rpx;
border: 1px solid #000;
box-sizing: border-box;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.no-text {
color: #7e7e7e;
font-size: 20rpx;
margin-top: 28rpx;
line-height: 1.4;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
}
.btn-cantact {
background: transparent;
// background: skyblue;
padding: 0;
position: absolute;
top: 0;
left: 0;
border: none;
width: 600px;
height: 80px;
z-index: 10;
&:after {
border-width: 0;
}
}
} }

View File

@ -1,6 +1,6 @@
import Taro from '@tarojs/taro' import Taro from '@tarojs/taro'
import React, { useEffect, useState, useCallback, useRef, useImperativeHandle } from 'react' import React, { useEffect, useState, useCallback, useRef, useImperativeHandle } from 'react'
import { View, Text, Button } from '@tarojs/components' import { View, Text, Button, ScrollView } from '@tarojs/components'
import { AtButton, AtCurtain } from 'taro-ui' import { AtButton, AtCurtain } from 'taro-ui'
import { useImmer } from 'use-immer' import { useImmer } from 'use-immer'
import S from '@/spx' import S from '@/spx'
@ -19,7 +19,7 @@ const initialState = {
privacyName: '', privacyName: '',
agreeMentChecked: false agreeMentChecked: false
} }
function SpLogin(props, ref) { function SpLogin (props, ref) {
const { children, className, onChange, newUser = false } = props const { children, className, onChange, newUser = false } = props
const { isLogin, login, setToken, checkPolicyChange } = useLogin({ const { isLogin, login, setToken, checkPolicyChange } = useLogin({
policyUpdateHook: (isUpdate) => { policyUpdateHook: (isUpdate) => {
@ -203,12 +203,13 @@ function SpLogin(props, ref) {
{/* 授权登录 */} {/* 授权登录 */}
<AtCurtain <AtCurtain
className='curtain'
isOpened={loginModal} isOpened={loginModal}
onClose={() => { onClose={() => {
setLoginModal(false) setLoginModal(false)
}} }}
> >
<View className='login-modal'> {/* <View className='login-modal'>
<View className='login-modal__hd'> <View className='login-modal__hd'>
<SpImage circle src={icon} width={120} height={120} /> <SpImage circle src={icon} width={120} height={120} />
<View className='nick-name'>{nickname}</View> <View className='nick-name'>{nickname}</View>
@ -232,6 +233,45 @@ function SpLogin(props, ref) {
登录 登录
</AtButton>} </AtButton>}
</View> </View>
</View> */}
<View className="curtain_content">
<View className="curtain_content_title">
<SpImage src={`member/logo-black.png`} height={32} mode='heightFix' isNew />
<View className="">隐私政策</View>
</View>
<ScrollView scrollY
scrollWithAnimation className="curtain_content_text" showScrollbar={false} enhanced>
亲爱的用户,感谢您使用Birkenstock微信小程序!为了加强对您个人信息的保护,我们根据最新法律的要求制定/更新了
<View className="agreement-list">
<Text className='agreement-name' onClick={handleClickPrivacy.bind(this, 'member_register')}>{registerName}</Text>
<Text className='agreement-name' onClick={handleClickPrivacy.bind(this, 'privacy')}>{privacyName}</Text>
</View>,,
<View>
本政策旨在向您说明休迪贸易 (上海)有限公司及其在中国大陆境内的线上线下门店如何收集使用传输和保护您的个人信息
通过隐私政策,我们向您主要说明:
</View>
<View className="">
1.您在使用Birkenstock微信小程序时,可以选择浏览模式,也可以选择注册/登录成为Birkenstock微信小程序用户
</View>
<View className="">
2为了向你提供Birkenstock微信小程序的其本服条,我们将基于合法以及正当必要的原则,按照本政策的规定向您提供各项服务
</View>
</ScrollView>
<View className='btn-wrap'>
{isNewUser && <AtButton className='btn' type='primary' openType="getPhoneNumber" onGetPhoneNumber={(e) => {
setLoginModal(false)
handleBindPhone(e)
}}>
同意并继续
</AtButton>}
{!isNewUser && <AtButton className='btn' type='primary' onClick={handleUserLogin}>
同意并继续
</AtButton>}
</View>
<View className="no-btn" onClick={() => setLoginModal(false)}>不同意</View>
<View className="no-text">
*如果您不同意Birkenstock隐私政策您可继续浏览小程序但您无法使用购物结算功能
</View>
</View> </View>
</AtCurtain> </AtCurtain>
</View> </View>

View File

@ -15,7 +15,9 @@ export default class SpNote extends Component {
btnText: '', btnText: '',
to: '', to: '',
isUrl: true, isUrl: true,
img: '' img: '',
width: 292,
height: 224
} }
static options = { static options = {
@ -26,18 +28,18 @@ export default class SpNote extends Component {
handleClick = () => { } handleClick = () => { }
resolveUrl(img) { resolveUrl (img) {
return `/assets/imgs/${img}` return `/assets/imgs/${img}`
} }
render() { render () {
const { icon, className, title, button, value, btnText, to, isUrl, img } = this.props const { icon, className, title, button, value, btnText, to, isUrl, img, width, height } = this.props
return ( return (
<View className={classNames('sp-note', className)}> <View className={classNames('sp-note', className)}>
{/* {icon && <AtIcon prefixClass='sw-icon' value={value} size='60' color='#cdcdcd' />} */} {/* {icon && <AtIcon prefixClass='sw-icon' value={value} size='60' color='#cdcdcd' />} */}
{img && ( {img && (
<SpImage className='default-img' src={img} width={292} height={224} /> <SpImage className='default-img' src={img} width={width} height={height} />
)} )}
<Text className='sp-note__text'>{title || this.props.children}</Text> <Text className='sp-note__text'>{title || this.props.children}</Text>
{button && to && ( {button && to && (

View File

@ -5,14 +5,14 @@ import { View, Text, Image } from '@tarojs/components'
import { SpPage, SpPrice, SpImage, SpPoint } from '@/components' import { SpPage, SpPrice, SpImage, SpPoint } from '@/components'
import './index.scss' import './index.scss'
function SpOrderItem(props) { function SpOrderItem (props) {
const { const {
payType = '', payType = '',
showExtra = true, showExtra = true,
info = null, info = null,
isPointitemGood = false, isPointitemGood = false,
isShowPointTag = false, isShowPointTag = false,
onClick = () => {}, onClick = () => { },
customFooter, customFooter,
showDesc, showDesc,
renderDesc, renderDesc,
@ -24,24 +24,38 @@ function SpOrderItem(props) {
const { market_price: enMarketPrice } = order_page const { market_price: enMarketPrice } = order_page
if (!info) return null if (!info) return null
const desc = info.item_spec_desc
let desc_info = ''
if (desc) {
try {
const descArr = desc.split(',')
descArr.forEach((item, index) => {
let [_, value] = item.split(':')
if (index === 1) {
value = value.substring(0, 2)
}
desc_info += value + ' '
})
} catch (error) {
}
}
const showExtraComp = () => { const showExtraComp = () => {
if (showExtra) { if (showExtra) {
return ( return (
<View className='sp-order-item__extra'> <View className='sp-order-item__extra'>
<Text className='sp-order-item__desc'>{info.goods_props}</Text> <Text className='sp-order-item__desc'>{info.goods_props}</Text>
{info.num && <Text className='sp-order-item__num'>数量{info.num}</Text>}
{info.item_spec_desc && ( {info.item_spec_desc && (
<Text className='sp-order-item__desc'>{info.item_spec_desc}</Text> <Text className='sp-order-item__desc'>{desc_info || info.item_spec_desc}</Text>
)} )}
{info.num && <Text className='sp-order-item__num'>数量{info.num}</Text>}
</View> </View>
) )
} }
} }
const img = info.pic_path ? info.pic_path : Array.isArray(info.pics) ? info.pics[0] : info.pics const img = info.pic || info.pic_path ? info.pic_path : Array.isArray(info.pics) ? info.pics[0] : info.pics
const title = info.title || info.item_name
console.log('order item info:', info)
return ( return (
<View className='sp-order-item' onClick={onClick}> <View className='sp-order-item' onClick={onClick}>
@ -57,7 +71,7 @@ function SpOrderItem(props) {
{info.order_item_type === 'gift' && ( {info.order_item_type === 'gift' && (
<Text className='sp-order-item__title-tag'>赠品</Text> <Text className='sp-order-item__title-tag'>赠品</Text>
)} )}
{info.title} {title}
</View> </View>
{showDesc && info.item_spec_desc && ( {showDesc && info.item_spec_desc && (
<Text className='sp-order-item__spec'>{info.item_spec_desc}</Text> <Text className='sp-order-item__spec'>{info.item_spec_desc}</Text>
@ -79,7 +93,7 @@ function SpOrderItem(props) {
/> />
) : ( ) : (
<View> <View>
<SpPrice className='sp-order-item__price' value={info.price}></SpPrice> <SpPrice className='sp-order-item__price' value={info.price} showSeparator noDecimal={false}></SpPrice>
{/* {info.market_price > 0 && enMarketPrice && ( {/* {info.market_price > 0 && enMarketPrice && (
<SpPrice lineThrough value={info.market_price}></SpPrice> <SpPrice lineThrough value={info.market_price}></SpPrice>
)} */} )} */}

View File

@ -4,23 +4,36 @@
display: flex; display: flex;
align-items: flex-start; align-items: flex-start;
padding: $edge-size; padding: $edge-size;
&__extra {
width: 450px;
font-size: 20px;
line-height: 1;
color: #000;
opacity: 0.85;
}
&__hd { &__hd {
margin-right: 20px; margin-right: 60px;
} }
&__bd { &__bd {
width: 50%; width: 38%;
margin-bottom: 40px; // margin-bottom: 40px;
padding: 20px 0;
position: relative; position: relative;
font-size: 20px;
line-height: 1;
box-sizing: border-box;
} }
&__ft { &__ft {
flex: 1; flex: 1;
text-align: right; text-align: right;
font-size: $font-size-small; padding-top: 10px;
// font-size: $font-size-small;
} }
&__title { &__title {
// font-size: floor(0.95 * $font-size); // font-size: floor(0.95 * $font-size);
@include multi-ellipsis(1); @include multi-ellipsis(1);
line-height: 1.4; margin-bottom: 26px;
color: #000;
// margin: 0 0 15px; // margin: 0 0 15px;
&-tag { &-tag {
display: inline-block; display: inline-block;
@ -32,16 +45,17 @@
} }
} }
&__desc { &__desc {
color: $color-gray; // color: $color-gray;
font-size: $font-size-small; // font-size: $font-size-small;
// margin-bottom: 10px; // margin-bottom: 10px;
} }
&__spec { &__spec {
color: $color-gray; // color: $color-gray;
font-size: $font-size-small; // font-size: $font-size-small;
max-width: 90%; max-width: 90%;
min-width: 100px; min-width: 100px;
display: inline-block; display: inline-block;
opacity: 0.85;
@include text-overflow(); @include text-overflow();
} }
&__price { &__price {
@ -52,7 +66,8 @@
} }
&__num { &__num {
display: block; display: block;
color: $color-gray; margin-top: 26px;
// color: $color-gray;
} }
&__pay-type { &__pay-type {
display: block; display: block;
@ -60,4 +75,8 @@
font-size: 20px; font-size: 20px;
color: #c1c1c1; color: #c1c1c1;
} }
.sp-price__symbol,
.sp-price__int {
font-weight: bold !important;
}
} }

View File

@ -3,7 +3,7 @@ import { useSelector, useDispatch } from 'react-redux'
import Taro, { useDidShow, usePageScroll, getCurrentInstance, useReady } from '@tarojs/taro' import Taro, { useDidShow, usePageScroll, getCurrentInstance, useReady } from '@tarojs/taro'
import { View, Text, Image } from '@tarojs/components' import { View, Text, Image } from '@tarojs/components'
import { useImmer } from 'use-immer' import { useImmer } from 'use-immer'
import { SpNavBar, SpFloatMenuItem, SpNote, SpLoading, SpImage } from '@/components' import { SpNavBar, SpFloatMenuItem, SpNote, SpLoading, SpImage, SpChat } from '@/components'
import { TABBAR_PATH } from '@/consts' import { TABBAR_PATH } from '@/consts'
import { classNames, styleNames, hasNavbar, isWeixin, isAlipay, isGoodsShelves, entryLaunch, isObject } from '@/utils' import { classNames, styleNames, hasNavbar, isWeixin, isAlipay, isGoodsShelves, entryLaunch, isObject } from '@/utils'
import { AtBadge } from 'taro-ui' import { AtBadge } from 'taro-ui'
@ -26,6 +26,7 @@ const initialState = {
function SpPage (props, ref) { function SpPage (props, ref) {
const $instance = getCurrentInstance() const $instance = getCurrentInstance()
const [state, setState] = useImmer(initialState) const [state, setState] = useImmer(initialState)
const { cartCount = 0 } = useSelector((state) => state.cart)
const { lock, lockStyle, pageTitle, isTabBarPage, customNavigation, cusCurrentPage, showLeftContainer, currentPath, showCustomNavigation, showNavCartIcon } = state const { lock, lockStyle, pageTitle, isTabBarPage, customNavigation, cusCurrentPage, showLeftContainer, currentPath, showCustomNavigation, showNavCartIcon } = state
const { const {
className, className,
@ -50,6 +51,7 @@ function SpPage (props, ref) {
showNavLogo = true, showNavLogo = true,
showNavkfIcon = false, showNavkfIcon = false,
showNavHomeIcon = false, showNavHomeIcon = false,
showNavSearchIcon = false,
} = props } = props
let { renderTitle } = props let { renderTitle } = props
const wrapRef = useRef(null) const wrapRef = useRef(null)
@ -253,7 +255,7 @@ function SpPage (props, ref) {
} }
renderTitle = showCustomNavigation && showNavLogo ? <SpImage src={`member/logo-${isBlack ? "black" : "light"}.png`} height={34} mode='heightFix' isNew /> : undefined renderTitle = showCustomNavigation && showNavLogo ? <SpImage src={`member/logo-${isBlack ? "black" : "light"}.png`} height={34} mode='heightFix' isNew /> : undefined
const navigationBarTitleText = getCurrentInstance().page?.config?.navigationBarTitleText const navigationBarTitleText = props.navigationBarTitleText || getCurrentInstance().page?.config?.navigationBarTitleText
return ( return (
<View <View
className={classNames('custom-navigation', { className={classNames('custom-navigation', {
@ -290,7 +292,7 @@ function SpPage (props, ref) {
/> />
</View>} </View>}
{/* <Image className="chazhao" src={require("@/assets/chazhao-light.png")}></Image> */} {/* <Image className="chazhao" src={require("@/assets/chazhao-light.png")}></Image> */}
{showCustomNavigation ? <SpImage src={`member/chazhao-${isBlack ? "black" : "light"}.png`} height={34} mode='heightFix' isNew /> {showCustomNavigation ? <SpImage onClick={() => Taro.navigateTo({ url: '/pages/item/list' })} src={`member/chazhao-${isBlack ? "black" : "light"}.png`} height={34} mode='heightFix' isNew />
: <View className='icon-wrap'> : <View className='icon-wrap'>
<Text <Text
className={classNames('iconfont', { className={classNames('iconfont', {
@ -307,11 +309,12 @@ function SpPage (props, ref) {
} }
}} }}
/> />
{showNavCartIcon && <AtBadge value={10} maxValue={99}><SpImage src={`member/cart.png`} onClick={() => Taro.redirectTo({ url: '/pages/cart/espier-index' })} height={36} mode='heightFix' isNew /></AtBadge>} {showNavCartIcon && <AtBadge value={cartCount} maxValue={99}><SpImage src={`member/cart.png`} onClick={() => Taro.redirectTo({ url: '/pages/cart/espier-index' })} height={36} mode='heightFix' isNew /></AtBadge>}
{showNavHomeIcon && <SpImage src={`cart/home.png`} onClick={() => Taro.redirectTo({ url: '/pages/index' })} height={36} mode='heightFix' isNew />} {showNavHomeIcon && <SpImage src={`cart/home.png`} onClick={() => Taro.redirectTo({ url: '/pages/index' })} height={36} mode='heightFix' isNew />}
{showNavSearchIcon && <SpImage onClick={() => Taro.navigateTo({ url: '/pages/item/list' })} src={`member/chazhao-${isBlack ? "black" : "light"}.png`} height={34} mode='heightFix' isNew />}
</View> </View>
} }
{showNavkfIcon && <SpImage className='icon-kf' src={`index/kf.png`} onClick={() => Taro.redirectTo({ url: '/pages/cart/espier-index' })} height={46} mode='heightFix' isNew />} {showNavkfIcon && <SpChat><SpImage className='icon-kf' src={`index/kf.png`} onClick={() => Taro.redirectTo({ url: '/pages/cart/espier-index' })} height={46} mode='heightFix' isNew /></SpChat>}
</View>} </View>}
{isWeixin && <View className='title-container' style={styleNames(pageTitleStyle)}> {isWeixin && <View className='title-container' style={styleNames(pageTitleStyle)}>

View File

@ -108,6 +108,20 @@
.icon-kf { .icon-kf {
margin-left: 40px; margin-left: 40px;
} }
.at-badge {
&__num {
font-size: 14px;
width: 24px;
height: 24px;
line-height: 24px;
top: -6px;
right: 4px;
padding: 0;
border-radius: 50%;
overflow: hidden;
text-align: center;
}
}
} }
.icon-wrap { .icon-wrap {
// width: 56px; // width: 56px;
@ -191,7 +205,7 @@
// background: #a0a0a0; // background: #a0a0a0;
} }
.title-container { .title-container {
color: #333; color: #000;
} }
.custom-status-bar { .custom-status-bar {
background: #fff; background: #fff;

View File

@ -26,10 +26,14 @@ const initialState = {
} }
function SpPicker (props) { function SpPicker (props) {
const { mode, children, leftBtnTxt = '取消', rightBtnTxt = '确定', source = [], value, pickerConfirm, isTop = false } = props const { mode, children, leftBtnTxt = '取消', rightBtnTxt = '确定', source = [], value, pickerConfirm, isTop = false } = props
const [state, setState] = useImmer(initialState) const [state, setState] = useImmer({ ...initialState, value })
const { visible, isOpen, list } = state const { visible, isOpen, list } = state
const handlerChange = () => { } const handlerChange = (value) => {
// setState((draft) => {
// draft.value = value
// })
}
const onPickerCancel = () => { const onPickerCancel = () => {
setState((draft) => { setState((draft) => {
@ -43,7 +47,7 @@ function SpPicker (props) {
// const pickerConfirm = () => { } // const pickerConfirm = () => { }
return ( return (
<View className='sp-picker'> <View className='sp-picker' style={{ 'z-index': isTop ? 999 : 10 }}>
<View <View
className='picker-value' className='picker-value'
onClick={() => { onClick={() => {
@ -91,7 +95,7 @@ function SpPicker (props) {
value={value} value={value}
fields='minute' fields='minute'
onPickerCancel={onPickerCancel} onPickerCancel={onPickerCancel}
// change={handlerChange} onChange={handlerChange}
handleConfirm={pickerConfirm} handleConfirm={pickerConfirm}
/> />
) : null} ) : null}
@ -127,4 +131,4 @@ SpPicker.options = {
addGlobalClass: true addGlobalClass: true
} }
export default SpPicker export default React.memo(SpPicker)

View File

@ -12,13 +12,14 @@ const initialState = {
markMultiDateTime: false markMultiDateTime: false
} }
function PickerDateTime (props) { function PickerDateTime (props) {
const { handleConfirm, onPickerCancel } = props const { handleConfirm, onPickerCancel, list = [] } = props
const dateTime = [ const dateTime = [
{ mode: 'year', unit: '年' }, { mode: 'year', unit: '年' },
{ mode: 'month', unit: '月' }, { mode: 'month', unit: '月' },
{ mode: 'day', unit: '日' }, { mode: 'day', unit: '日' },
] ]
const [state, setState] = useAsyncCallback({ source: props.list || [], value: props.value || '' }) // const [state, setState] = useAsyncCallback({ source: props.list || [], value: props.value || '' })
const [state, setState] = useImmer({ source: list, value: props.value })
const { source, value } = state const { source, value } = state
// useEffect(() => { // useEffect(() => {
// // const { dateTime, start } = this.props // // const { dateTime, start } = this.props
@ -45,30 +46,30 @@ function PickerDateTime (props) {
(draft) => { (draft) => {
draft.value = e.detail.value draft.value = e.detail.value
}, },
({ source, value }) => { // ({ source, value }) => {
// const res = [] // const res = []
// for (let i = 0; i < source.length; i++) { // for (let i = 0; i < source.length; i++) {
// let time = '', // let time = '',
// token = '' // token = ''
// // source[i].item.length为可选项的列数 // // source[i].item.length为可选项的列数
// for (let j = 0; j < source[i].item.length; j++) { // for (let j = 0; j < source[i].item.length; j++) {
// const select = source[i].item[j][value[i][j]] // const select = source[i].item[j][value[i][j]]
// time += (select === '今天' ? dayjs().format('M月D日') : select) + '-' // time += (select === '今天' ? dayjs().format('M月D日') : select) + '-'
// // 对于二维数组取i、j对于一维数组取j // // 对于二维数组取i、j对于一维数组取j
// const item = markMultiDateTime ? dateTime[i][j] : dateTime[j] // const item = markMultiDateTime ? dateTime[i][j] : dateTime[j]
// token += (item.format || getToken(item.mode)) + '-' // token += (item.format || getToken(item.mode)) + '-'
// } // }
// res.push(dayjs(time, token)[mode]()) // res.push(dayjs(time, token)[mode]())
// } // }
// return markMultiDateTime ? res : res[0] // return markMultiDateTime ? res : res[0]
// const res = source.map((item, index) => item[value[index]]) // const res = source.map((item, index) => item[value[index]])
// const cur = getDayjs() // const cur = getDayjs()
// const source2 = dateTime && format(dateTime, dayjs(start)) // const source2 = dateTime && format(dateTime, dayjs(start))
// console.log('source2:', source2) // console.log('source2:', source2)
} // }
) )
} }
console.log(value)
return ( return (
<View className='picker-custom'> <View className='picker-custom'>
<PickerView <PickerView
@ -85,7 +86,9 @@ function PickerDateTime (props) {
</PickerView> </PickerView>
<View className="picker-btn" onClick={() => { <View className="picker-btn" onClick={() => {
onPickerCancel() onPickerCancel()
handleConfirm(source[value[0]], value[0]) setTimeout(() => {
handleConfirm(source[value[0]], value[0])
}, 100)
}}>确定</View> }}>确定</View>
</View> </View>
) )
@ -95,4 +98,4 @@ PickerDateTime.options = {
addGlobalClass: true addGlobalClass: true
} }
export default PickerDateTime export default React.memo(PickerDateTime)

View File

@ -34,7 +34,8 @@ export default class SpPrice extends Component {
appendText, appendText,
lineThrough, lineThrough,
plus, plus,
size size,
showSeparator = false
} = this.props } = this.props
let _value = value let _value = value
if (isString(value)) { if (isString(value)) {
@ -78,13 +79,13 @@ export default class SpPrice extends Component {
fontSize: `${size}rpx` fontSize: `${size}rpx`
})} })}
> >
{int.indexOf('-') === 0 ? int.slice(1) : int} {showSeparator ? parseInt(int).toLocaleString() : int.indexOf('-') === 0 ? int.slice(1) : int}
</Text> </Text>
{decimal !== undefined && !noDecimal && ( {decimal !== undefined && !noDecimal && (
<Text <Text
className='sp-price__decimal' className='sp-price__decimal'
style={styleNames({ style={styleNames({
fontSize: `${size - 4}rpx` fontSize: `${size}rpx`
})} })}
> >
.{decimal} .{decimal}

View File

@ -1,8 +1,8 @@
import React, { useEffect, useRef } from 'react' import React, { useEffect, useImperativeHandle, useRef } from 'react'
import { useSelector, useDispatch } from 'react-redux' import { useSelector, useDispatch } from 'react-redux'
import Taro from '@tarojs/taro' import Taro from '@tarojs/taro'
import { AtButton } from 'taro-ui' import { AtButton } from 'taro-ui'
import { View, Text } from '@tarojs/components' import { View, Text, ScrollView } from '@tarojs/components'
import { useImmer } from 'use-immer' import { useImmer } from 'use-immer'
import { import {
SpFloatLayout, SpFloatLayout,
@ -38,16 +38,17 @@ const initialState = {
loading: false loading: false
} }
function SpSkuSelect (props) { function SpSkuSelect (props, ref) {
const { const {
info, info,
open = true, open = true,
onClose = () => { }, onClose = () => { },
onChange = () => { }, onChange = () => { },
type, type,
hideInputNumber = false hideInputNumber = false,
onChangeImg
} = props } = props
console.log('SpSkuSelect:info', info) // console.log('SpSkuSelect:info', info)
// const [state, setState] = useImmer(initialState) // const [state, setState] = useImmer(initialState)
const [state, setState] = useAsyncCallback(initialState) const [state, setState] = useAsyncCallback(initialState)
const { selection, curImage, disabledSet, curItem, skuText, num, loading } = state const { selection, curImage, disabledSet, curItem, skuText, num, loading } = state
@ -62,8 +63,6 @@ function SpSkuSelect (props) {
const init = () => { const init = () => {
const { skuList, specItems } = info const { skuList, specItems } = info
console.log('skuList:', skuList)
console.log('specItems:', specItems)
specItems.forEach((item) => { specItems.forEach((item) => {
const key = item.specItem.map((spec) => spec.specId).join('_') const key = item.specItem.map((spec) => spec.specId).join('_')
skuDictRef.current[key] = item skuDictRef.current[key] = item
@ -78,7 +77,7 @@ function SpSkuSelect (props) {
calcDisabled(selection) calcDisabled(selection)
} }
const calcDisabled = (selection) => { const calcDisabled = (selection, i = 0) => {
const disabledSet = new Set() const disabledSet = new Set()
const makeReg = (sel, row, val) => { const makeReg = (sel, row, val) => {
const tSel = sel.slice() const tSel = sel.slice()
@ -104,18 +103,21 @@ function SpSkuSelect (props) {
} }
} }
} }
console.log( // console.log(
'skuDict:', // 'skuDict:',
skuDictRef.current, // skuDictRef.current,
'selection:', // 'selection:',
selection, // selection,
'disabledSet:', // 'disabledSet:',
disabledSet // disabledSet
) // )
const curItem = skuDictRef.current[selection.join('_')] const curItem = skuDictRef.current[selection.join('_')]
// const skuText = curItem
// ? `已选:${curItem.specItem.map((item) => `${item.skuName}:${item.specName}`).join(',')}`
// : '请选择规格'
const skuText = curItem const skuText = curItem
? `已选:${curItem.specItem.map((item) => `${item.skuName}:${item.specName}`).join(',')}` ? `已选${curItem.specItem.map((item, index) => `${index === 1 ? item.specName.substr(0, 2) : item.specName}`).join(' ')}`
: '请选择规格' : '请选择规格'
setState((draft) => { setState((draft) => {
@ -125,7 +127,7 @@ function SpSkuSelect (props) {
draft.skuText = skuText draft.skuText = skuText
}) })
onChange(skuText, curItem) onChange(skuText, curItem, i)
} }
// calcDisabled(initSelection) // calcDisabled(initSelection)
@ -133,14 +135,15 @@ function SpSkuSelect (props) {
// console.log('disabledSet:', disabledSet) // console.log('disabledSet:', disabledSet)
const handleSelectSku = ({ specId }, idx) => { const handleSelectSku = ({ specId }, idx) => {
console.log("🚀 ~ { specId }, idx:", specId, idx)
if (disabledSet.has(specId)) return if (disabledSet.has(specId)) return
setState( setState(
(draft) => { (draft) => {
draft.selection[idx] = selection[idx] == specId ? null : specId draft.selection[idx] = selection[idx] == specId ? specId : specId //null
draft.curImage = 1 draft.curImage = 1
}, },
({ selection }) => { (row) => {
calcDisabled(selection) calcDisabled(row.selection, idx)
} }
) )
} }
@ -153,6 +156,7 @@ function SpSkuSelect (props) {
img = specImgs[0] img = specImgs[0]
} }
} }
onChangeImg && onChangeImg(img)
// console.log('img:', img) // console.log('img:', img)
return img return img
} }
@ -175,7 +179,6 @@ function SpSkuSelect (props) {
} }
const { skuList } = info const { skuList } = info
console.log("🚀 ~ skuList:", skuList)
const addToCart = async () => { const addToCart = async () => {
const { nospec } = info const { nospec } = info
@ -234,6 +237,15 @@ function SpSkuSelect (props) {
}) })
} }
useImperativeHandle(ref, () => {
return {
fastBuy,
addToCart,
getImgs,
handleSelectSku
}
})
const renderFooter = () => { const renderFooter = () => {
let btnTxt = '' let btnTxt = ''
Object.keys(BUY_TOOL_BTNS).forEach((key) => { Object.keys(BUY_TOOL_BTNS).forEach((key) => {
@ -362,26 +374,43 @@ function SpSkuSelect (props) {
<View className='sku-group' key={`sku-group__${index}`}> <View className='sku-group' key={`sku-group__${index}`}>
{/* <View className='sku-name'>{item.skuName}</View> */} {/* <View className='sku-name'>{item.skuName}</View> */}
<View className='sku-values'> <View className='sku-values'>
{item.skuValue.map((spec, idx) => ( {index === 0 && <ScrollView scrollX scrollWithAnimation showScrollbar={false} scrollLeft={0} className="sku-img-box">
{item.skuValue?.length > 0 && item.skuValue.map((spec, idx) => spec.specImgs.length > 0 && (
<View
className={classNames('sku-btn', {
'active': spec.specId == selection[index],
'disabled': disabledSet.has(spec.specId),
})}
onClick={handleSelectSku.bind(this, spec, index)}
key={`sku-values-item__${idx}`}
>
<SpImage src={spec.specImgs[0]} width={130} height={90} mode='aspectFit' key={`sku-img__${idx}`} />
</View>
)
)}
</ScrollView>}
{index > 0 && item.skuValue.map((spec, idx) => (
<View <View
className={classNames('sku-btn', { className={classNames('sku-btn btn-noac', {
'active': spec.specId == selection[index], 'active': spec.specId == selection[index],
'btn-primary': spec.specId == selection[index],
'disabled': disabledSet.has(spec.specId), 'disabled': disabledSet.has(spec.specId),
'sku-img': spec.specImgs.length > 0 'sku-img': spec.specImgs.length > 0
})} })}
onClick={handleSelectSku.bind(this, spec, index)} onClick={handleSelectSku.bind(this, spec, index)}
key={`sku-values-item__${idx}`} key={`sku-values-item__${idx}`}
> >
{spec.specImgs.length > 0 && ( {/* {spec.specImgs.length > 0 && (
<SpImage src={spec.specImgs[0]} width={260} height={260} /> <SpImage src={spec.specImgs[0]} width={260} height={260} />
)} )} */}
{index !== 0 && <View className='spec-name'>{spec.specName}</View>} <View className={classNames('spec-name', { 'pad': index === 2 })}>{spec.specName}</View>
</View> </View>
))} ))}
</View> </View>
</View> </View>
))} ))}
{!hideInputNumber && renderLimitTip()} {!hideInputNumber && renderLimitTip()}
<View className="select">{skuText}</View>
</View> </View>
{/* </SpFloatLayout> */} {/* </SpFloatLayout> */}
</View> </View>
@ -392,4 +421,4 @@ SpSkuSelect.options = {
addGlobalClass: true addGlobalClass: true
} }
export default SpSkuSelect export default React.forwardRef(SpSkuSelect)

View File

@ -41,12 +41,20 @@
} }
.sku-list { .sku-list {
position: relative;
padding: 0 30px; padding: 0 30px;
margin: 0;
// margin-top: 30px; // margin-top: 30px;
// margin-bottom: 100px; // margin-bottom: 100px;
.select {
position: absolute;
top: 156px;
right: 100px;
font-size: 22px;
}
} }
.sku-group { .sku-group {
margin-bottom: 20px; margin: 30px 0 0;
} }
.buy-count { .buy-count {
margin-bottom: 20px; margin-bottom: 20px;
@ -70,23 +78,48 @@
.sku-values { .sku-values {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
margin-top: 20px; margin-top: 0px !important;
.spec-name { .spec-name {
display: block; display: block;
// max-width: 260px; // max-width: 260px;
// @include text-overflow(); // @include text-overflow();
} }
.sku-img-box {
width: 100%;
white-space: nowrap;
.sku-btn {
display: inline-block;
margin: 0 20px 0 0;
padding: 0;
background: #fff;
height: 90rpx;
overflow: hidden;
box-sizing: border-box;
// border: none;
&:last-child {
margin-right: 0;
}
.sp-image {
margin: auto 0;
display: inline-block;
box-sizing: border-box;
&-img {
display: inline-block;
}
}
}
}
} }
.sku-btn { .sku-btn {
padding: 0 16px; padding: 16px 10px;
// height: 60px; // height: 60px;
// line-height: 60px; // line-height: 60px;
background: #f5f5f5; background: #fff;
/* prettier-ignore */ /* prettier-ignore */
border: 1PX solid #f5f5f5; border: 1PX solid #fff;
border-radius: 4px; border-radius: 8px;
margin: 0 24px 24px 0; margin: 0 20px 20px 0;
color: #222; color: #333;
box-sizing: border-box; box-sizing: border-box;
&.sku-img { &.sku-img {
padding: 0; padding: 0;
@ -105,14 +138,31 @@
margin: 8px 0; margin: 8px 0;
} }
} }
&.active { &.btn-noac {
background: #fff;
/* prettier-ignore */ /* prettier-ignore */
border: 1PX solid var(--color-primary); border: 1PX solid #BCBCBC;
color: var(--color-primary); color: #222;
}
&.btn-primary {
background: var(--color-primary);
color: #fff;
}
.spec-name {
font-size: 22px;
line-height: 1;
&.pad {
padding: 0 4px;
}
}
&.active {
// background: #fff;
/* prettier-ignore */
border: 1PX solid #BCBCBC;
// color: var(--color-primary);
} }
&.disabled { &.disabled {
color: #cdcdcd; color: #bcbcbc;
opacity: 0.7;
} }
} }

View File

@ -18,4 +18,21 @@
height: 54px !important; height: 54px !important;
} }
} }
.at-tab-bar__item {
.at-badge {
&__num {
font-size: 16px;
width: 26px;
height: 26px;
line-height: 26px;
top: -4px;
right: 8px;
padding: 0;
border-radius: 50%;
overflow: hidden;
text-align: center;
padding-left: 2px;
}
}
}
} }

View File

@ -89,9 +89,10 @@ export const ITEM_LIST_GOODS = {
memberPrice: ({ member_price }) => member_price / 100, // 当前会员等级价 memberPrice: ({ member_price }) => member_price / 100, // 当前会员等级价
vipPrice: ({ vip_price }) => vip_price / 100, // vip价格 vipPrice: ({ vip_price }) => vip_price / 100, // vip价格
svipPrice: ({ svip_price }) => svip_price / 100, // svip价格 svipPrice: ({ svip_price }) => svip_price / 100, // svip价格
spec_images: 'spec_images',
// is_fav: ({ item_id }) => Boolean(favs[item_id]), // is_fav: ({ item_id }) => Boolean(favs[item_id]),
store: 'store' store: 'store',
tagList: 'tagList'
} }
export const ITEM_LIST_POINT_GOODS = { export const ITEM_LIST_POINT_GOODS = {
@ -233,6 +234,7 @@ export const GOODS_INFO = {
}) })
}, },
intro: 'intro', intro: 'intro',
introList: 'intro_list',
distributorInfo: ({ distributor_info }) => { distributorInfo: ({ distributor_info }) => {
return pickBy(distributor_info, { return pickBy(distributor_info, {
distributorId: 'distributor_id', distributorId: 'distributor_id',

View File

@ -5,12 +5,12 @@ import dayjs from 'dayjs'
import { updateUserInfo, fetchUserFavs, clearUserInfo } from '@/store/slices/user' import { updateUserInfo, fetchUserFavs, clearUserInfo } from '@/store/slices/user'
import { updateCount, clearCart } from '@/store/slices/cart' import { updateCount, clearCart } from '@/store/slices/cart'
import api from '@/api' import api from '@/api'
import { isWeixin, showToast, entryLaunch,isAlipay,alipayAutoLogin } from '@/utils' import { isWeixin, showToast, entryLaunch, isAlipay, alipayAutoLogin } from '@/utils'
import S from '@/spx' import S from '@/spx'
import { SG_POLICY } from '@/consts/localstorage' import { SG_POLICY } from '@/consts/localstorage'
export default (props = {}) => { export default (props = {}) => {
const { autoLogin = false, policyUpdateHook = () => {} } = props const { autoLogin = false, policyUpdateHook = () => { } } = props
const [isLogin, setIsLogin] = useState(false) const [isLogin, setIsLogin] = useState(false)
const [isNewUser, setIsNewUser] = useState(false) const [isNewUser, setIsNewUser] = useState(false)
const dispatch = useDispatch() const dispatch = useDispatch()
@ -40,28 +40,39 @@ export default (props = {}) => {
// 隐私协议 // 隐私协议
// const checkResult = await checkPolicyChange() // const checkResult = await checkPolicyChange()
// if (checkResult) { // if (checkResult) {
Taro.showLoading({ title: '' }) Taro.showLoading({ title: '' })
const { code } = await getCode() let code
try {
const { code: _code } = await getCode()
code = _code
} catch (error) {
Taro.hideLoading()
}
try { try {
const { token } = await getToken(code) if (!code) {
Taro.hideLoading() Taro.hideLoading()
setToken(token)
} catch (e) {
setIsNewUser(true) setIsNewUser(true)
Taro.hideLoading() return
console.error('[hooks useLogin] auto login is failed: ', e)
throw new Error(e)
} }
const { token } = await getToken(code)
Taro.hideLoading()
setToken(token)
} catch (e) {
Taro.hideLoading()
setIsNewUser(true)
console.error('[hooks useLogin] auto login is failed: ', e)
// throw new Error(e)
}
// } // }
} }
} }
const getCode = async () => { const getCode = async () => {
if(isWeixin){ if (isWeixin) {
return await Taro.login() return await Taro.login()
} }
if(isAlipay){ if (isAlipay) {
return await alipayAutoLogin() return await alipayAutoLogin()
} }
} }
@ -79,7 +90,7 @@ export default (props = {}) => {
const setToken = async (token) => { const setToken = async (token) => {
const { redirect_url } = $instance.router.params const { redirect_url } = $instance.router.params
console.log('redirect_url',redirect_url) console.log('redirect_url', redirect_url)
S.setAuthToken(token) S.setAuthToken(token)
setIsLogin(true) setIsLogin(true)
await getUserInfo() await getUserInfo()

View File

@ -34,7 +34,7 @@ const initialState = {
activeTimeId: '' activeTimeId: ''
} }
function CompDeliver(props, ref) { function CompDeliver (props, ref) {
const { const {
address = {}, address = {},
distributor_id, distributor_id,
@ -250,7 +250,7 @@ function CompDeliver(props, ref) {
return ( return (
<View className='page-comp-deliver'> <View className='page-comp-deliver'>
<View className='switch-box'> {/* <View className='switch-box'>
<View className={classNames(deliveryList.length > 0 && 'switch-tab')}> <View className={classNames(deliveryList.length > 0 && 'switch-tab')}>
{deliveryList.map((item) => { {deliveryList.map((item) => {
if (distributorInfo[item.key]) { if (distributorInfo[item.key]) {
@ -266,7 +266,7 @@ function CompDeliver(props, ref) {
} }
})} })}
</View> </View>
</View> </View> */}
{/** 普通快递 */} {/** 普通快递 */}
{receiptType === 'logistics' && <AddressChoose isAddress={address} />} {receiptType === 'logistics' && <AddressChoose isAddress={address} />}
{/** 同城配 */} {/** 同城配 */}

View File

@ -1,8 +1,8 @@
.page-comp-deliver { .page-comp-deliver {
width: 100%; width: 100%;
background: #fff; background: #f7f7f7;
padding: 10px 0px; // padding: 10px 0px;
box-shadow: 0px 2px 10px 0px #eae7e0; // box-shadow: 0px 2px 10px 0px #eae7e0;
.switch-box { .switch-box {
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;

View File

@ -10,16 +10,17 @@ import './comp-goodsitem.scss'
const initialState = { const initialState = {
localNum: 0 localNum: 0
} }
function CompGoodsItem(props) { function CompGoodsItem (props) {
const { const {
info, info,
children, children,
isShowAddInput = true, isShowAddInput = true,
isShowDeleteIcon = true, isShowDeleteIcon = true,
goodType, goodType,
onDelete = () => {}, onDelete = () => { },
onChange = () => {}, onChange = () => { },
onClickImgAndTitle = () => {} onClickImgAndTitle = () => { },
onChangeGoodsIsCheck = () => { }
} = props } = props
const { priceSetting } = useSelector((state) => state.sys) const { priceSetting } = useSelector((state) => state.sys)
const { userInfo = {}, vipInfo = {} } = useSelector((state) => state.user) const { userInfo = {}, vipInfo = {} } = useSelector((state) => state.user)
@ -77,19 +78,21 @@ function CompGoodsItem(props) {
className='comp-goodsitem-image' className='comp-goodsitem-image'
mode='aspectFill' mode='aspectFill'
src={info.pics} src={info.pics}
width={180} width={150}
height={180} height={150}
/> />
</View> </View>
<View className='comp-goodsitem-bd'> <View className='comp-goodsitem-bd'>
<View className='item-hd'> <View className='item-hd'>
<View className='goods-title'> <View className='goods-title' onClick={onChangeGoodsIsCheck}>
{/* {info.activity_type == 'package' && <Text className='goods-title__tag'>组合商品</Text>} */} {/* {info.activity_type == 'package' && <Text className='goods-title__tag'>组合商品</Text>} */}
{info.is_plus_buy && <Text className='goods-title__tag'>加价购</Text>} {info.is_plus_buy && <Text className='goods-title__tag'>加价购</Text>}
{info.item_name} {info.item_name}
</View> </View>
{isShowDeleteIcon && ( {isShowDeleteIcon && (
<Text className='iconfont icon-shanchu-01' onClick={() => onDelete(info)}></Text> // <Text className='iconfont icon-shanchu-01' onClick={() => onDelete(info)}></Text>
<View className='del-btn' onClick={() => onDelete(info)}>
<Image src='/assets/close.png' className='del-icon'></Image></View>
)} )}
</View> </View>
@ -115,24 +118,29 @@ function CompGoodsItem(props) {
</View> </View>
<View className='item-ft'> <View className='item-ft'>
<View className='item-fd-hd'></View>
<View className='item-ft-bd'> <View className='item-ft-bd'>
<View className='goods-price-wrap'> <View className='goods-price-wrap'>
<SpPrice value={_price / 100} /> <View className='num-box'>
<Text>数量</Text>
{isShowAddInput ? (
<SpInputNumber
value={localNum}
max={parseInt(info?.limitedBuy ? info?.limitedBuy?.limit_buy : info.store)}
min={1}
onChange={onChangeInputNumber}
/>
) : (
<Text className='item-num'>x {info.num}</Text>
)}
</View>
<SpPrice value={_price / 100} noDecimal={false} size={20} showSeparator />
{info.market_price > 0 && enMarketPrice && ( {info.market_price > 0 && enMarketPrice && (
<SpPrice className='mkt-price' lineThrough value={info.market_price / 100} /> <SpPrice className='mkt-price' lineThrough value={info.market_price / 100} />
)} )}
</View> </View>
{isShowAddInput ? ( </View>
<SpInputNumber <View className='item-fd-hd'>
value={localNum} <SpPrice value={_price / 100 * info.num} noDecimal={false} showSeparator />
max={parseInt(info?.limitedBuy ? info?.limitedBuy?.limit_buy : info.store)}
min={1}
onChange={onChangeInputNumber}
/>
) : (
<Text className='item-num'>x {info.num}</Text>
)}
</View> </View>
</View> </View>
</View> </View>

View File

@ -1,7 +1,10 @@
.comp-goodsitem { .comp-goodsitem {
display: flex; display: flex;
font-size: 26px;
line-height: 1;
color: #000;
&-hd { &-hd {
margin-right: 20px; margin-right: 40px;
} }
&-bd { &-bd {
flex: 1; flex: 1;
@ -15,16 +18,49 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
position: relative;
padding-bottom: 26px;
font-weight: bold;
// @include multi-ellipsis(2)
.del-btn {
padding: 14px;
position: absolute;
right: 0px;
top: -28rpx;
.del-icon {
width: 22px;
height: 22px;
}
}
} }
.item-ft { .item-ft {
// position: absolute; // position: absolute;
// bottom: 0; // bottom: 0;
// left: 0; // left: 0;
// right: 0; // right: 0;
margin-top: 26px;
.goods-price-wrap { .goods-price-wrap {
display: flex; display: flex;
align-items: center; align-items: center;
width: 100%;
justify-content: space-between;
.num-box {
font-size: 20px;
opacity: 0.9;
display: flex;
align-items: center;
.at-input-number {
height: 30px;
&__input {
top: -8px;
width: 36px;
}
&__btn {
width: 30px;
}
}
}
} }
.mkt-price { .mkt-price {
margin-left: 8px; margin-left: 8px;
@ -36,6 +72,11 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
margin-bottom: 26px;
}
.item-fd-hd {
text-align: end;
font-weight: bold;
} }
.vip-grade { .vip-grade {
/* prettier-ignore */ /* prettier-ignore */
@ -99,11 +140,11 @@
} }
} }
.spec-desc { .spec-desc {
background-color: #f5f5f5; font-size: 20px;
font-size: 24px; color: #000;
color: #999; opacity: 0.8;
padding: 5px 13px; // padding: 5px 13px;
max-width: 300px; max-width: 400px;
min-width: 100px; min-width: 100px;
display: inline-block; display: inline-block;
@include text-overflow(); @include text-overflow();

View File

@ -55,7 +55,8 @@ export const initialState = {
isNeedPackage: false, // 是否需要打包 isNeedPackage: false, // 是否需要打包
openCashier: false, openCashier: false,
isPointOpenModal: false, isPointOpenModal: false,
routerParams: {} routerParams: {},
orderTtems: []
} }
export const deliveryList = [ export const deliveryList = [

View File

@ -31,7 +31,8 @@ import {
isEmpty, isEmpty,
VERSION_STANDARD, VERSION_STANDARD,
VERSION_B2C, VERSION_B2C,
VERSION_PLATFORM VERSION_PLATFORM,
JumpGoodDetail
} from '@/utils' } from '@/utils'
import { useAsyncCallback, useLogin, usePayment, useDebounce } from '@/hooks' import { useAsyncCallback, useLogin, usePayment, useDebounce } from '@/hooks'
import { PAYMENT_TYPE, TRANSFORM_PAYTYPE } from '@/consts' import { PAYMENT_TYPE, TRANSFORM_PAYTYPE } from '@/consts'
@ -51,7 +52,7 @@ import CompPointUse from './comps/comp-pointuse'
import './espier-checkout.scss' import './espier-checkout.scss'
function CartCheckout(props) { function CartCheckout (props) {
const $instance = getCurrentInstance() const $instance = getCurrentInstance()
const { isLogin, isNewUser, getUserInfoAuth } = useLogin({ const { isLogin, isNewUser, getUserInfoAuth } = useLogin({
autoLogin: true autoLogin: true
@ -103,7 +104,8 @@ function CartCheckout(props) {
openCashier, openCashier,
buildingNumber, buildingNumber,
houseNumber, // 房号 houseNumber, // 房号
routerParams // 路由参数 routerParams, // 路由参数
orderTtems
} = state } = state
const { const {
@ -193,7 +195,7 @@ function CartCheckout(props) {
return return
} }
if(!payType) { if (!payType) {
showToast('请选择支付方式') showToast('请选择支付方式')
return return
} }
@ -622,6 +624,7 @@ function CartCheckout(props) {
/* 处理限购活动添加到对应的items里---结束 */ /* 处理限购活动添加到对应的items里---结束 */
setState((draft) => { setState((draft) => {
draft.detailInfo = pickBy(items, doc.checkout.CHECKOUT_GOODS_ITEM) draft.detailInfo = pickBy(items, doc.checkout.CHECKOUT_GOODS_ITEM)
draft.orderTtems = items
draft.totalInfo = total_info draft.totalInfo = total_info
draft.paramsInfo = { ...paramsInfo, ...cus_parmas } draft.paramsInfo = { ...paramsInfo, ...cus_parmas }
draft.pointInfo = point_info draft.pointInfo = point_info
@ -811,17 +814,17 @@ function CartCheckout(props) {
return ( return (
<View className='checkout-toolbar'> <View className='checkout-toolbar'>
<View className='checkout-toolbar__total'> <View className='checkout-toolbar__total'>
{`${totalInfo.items_count}件商品 总计:`} {/* {`共${totalInfo.items_count}件商品 总计:`} */}
<SpPrice unit='cent' className='primary-price' value={totalInfo.total_fee} /> <Text className='price-total'>订单总计</Text>
<SpPrice unit='cent' className='primary-price' value={totalInfo.total_fee} showSeparator noDecimal={false} />
</View> </View>
<AtButton <AtButton
circle
type='primary' type='primary'
loading={submitLoading} loading={submitLoading}
disabled={orderSubmitDisabled()} disabled={orderSubmitDisabled()}
onClick={onSubmitPayChange} onClick={onSubmitPayChange}
> >
提交订单 立即结算
</AtButton> </AtButton>
</View> </View>
) )
@ -833,17 +836,64 @@ function CartCheckout(props) {
<View className='cart-checkout__group'> <View className='cart-checkout__group'>
<View className='cart-group__cont'> <View className='cart-group__cont'>
<View className='sp-order-item__idx'> <View className='sp-order-item__idx'>
商品清单 <Text style={{ color: '#222' }}>{totalInfo.items_count}</Text> 订单商品
{/* <Text style={{ color: '#222' }}>{totalInfo.items_count}</Text> */}
</View> </View>
<View className='goods-list'> <View className='goods-list'>
{detailInfo.map((item, idx) => ( {detailInfo.map((item, idx) => (
<View className='sp-order-item__wrap' key={idx}> <View className='sp-order-item__wrap' key={idx}>
<SpGoodsCell info={item} /> <SpGoodsCell info={item} />
{/* <SpOrderItem
key={`${idx}1`}
info={item}
isShowNational
isPointitemGood={false}
onClick={() => {
if (info.order_class == 'pointsmall') {
Taro.navigateTo({
url: `/subpages/pointshop/espier-detail?id=${item.good_id}`
})
} else {
JumpGoodDetail(item.good_id, item.distributor_id)
}
}}
/> */}
</View> </View>
))} ))}
</View> </View>
<View className="gap"></View>
<View className="trade-detail-info-new">
<View className='line'>
<View className='left'>订单金额</View>
<SpPrice unit='cent' size={20} className='right' value={totalInfo.item_fee_new} showSeparator noDecimal={false}></SpPrice>
{/* <View className='right'>{`¥${parseFloat(totalInfo.item_fee_new / 100).toFixed(2)}`}</View> */}
{/* <View className='right'>
{totalInfo.item_fee_new}
{transformTextByPoint(this.isPointitemGood(), info.item_fee_new, info.item_point)}
</View> */}
</View>
<View className='line'>
<View className='left'>优惠金额</View>
{/* 促销 + 优惠券 */}
<View className='right'>{`¥${parseFloat(totalInfo.promotion_discount + totalInfo.coupon_discount).toFixed(2)}`}</View>
</View>
<View className='line'>
<View className='left'>运费</View>
<View className='right'>
{totalInfo.freight_type !== 'point'
? `¥${totalInfo.freight_fee}`
: `${totalInfo.freight_fee * 100}${this.props.pointName}`}
</View>
</View>
</View>
<View className="gap"></View>
<View className="trade-detail-info-bottom">
<View className='left'>订单总计</View>
<SpPrice unit='cent' className='right' value={totalInfo.total_fee} showSeparator noDecimal={false}></SpPrice>
</View>
</View> </View>
<View className='cart-group__cont cus-input'> {/* <View className='cart-group__cont cus-input'>
<SpCell className='trade-remark' border={false}> <SpCell className='trade-remark' border={false}>
<AtInput <AtInput
className='trade-remark__input' className='trade-remark__input'
@ -853,15 +903,15 @@ function CartCheckout(props) {
maxLength={50} maxLength={50}
/> />
</SpCell> </SpCell>
</View> </View> */}
</View> </View>
</View> </View>
) )
} }
console.log(couponInfo, 'couponInfo', coupon) // console.log(couponInfo, 'couponInfo', coupon)
console.log('invoiceTitle', invoiceTitle) // console.log('invoiceTitle', invoiceTitle)
console.log('payChannel', payChannel) // console.log('payChannel', payChannel)
const couponText = couponInfo ? couponInfo.title : '' const couponText = couponInfo ? couponInfo.title : ''
// couponInfo.type === 'member' // couponInfo.type === 'member'
// ? '会员折扣' // ? '会员折扣'
@ -935,7 +985,7 @@ function CartCheckout(props) {
{renderGoodsComp()} {renderGoodsComp()}
{type !== 'limited_time_sale' && type !== 'group' && type !== 'seckill' && !bargain_id && ( {/* {type !== 'limited_time_sale' && type !== 'group' && type !== 'seckill' && !bargain_id && (
<SpCell <SpCell
isLink isLink
className='cart-checkout__coupons' className='cart-checkout__coupons'
@ -943,8 +993,8 @@ function CartCheckout(props) {
onClick={handleCouponsClick} onClick={handleCouponsClick}
value={couponText || '请选择'} value={couponText || '请选择'}
/> />
)} )} */}
{isWeixin && !bargain_id && totalInfo.invoice_status && ( {/* {isWeixin && !bargain_id && totalInfo.invoice_status && (
<SpCell <SpCell
isLink isLink
title='开发票' title='开发票'
@ -962,7 +1012,7 @@ function CartCheckout(props) {
</View> </View>
} }
/> />
)} )} */}
{packInfo.is_open && ( {packInfo.is_open && (
<SpCell <SpCell
@ -1031,7 +1081,7 @@ function CartCheckout(props) {
</View> </View>
)} )}
<View className='cart-checkout__total'> {false && <View className='cart-checkout__total'>
<SpCell <SpCell
className='trade-sub__item' className='trade-sub__item'
title='原价:' title='原价:'
@ -1068,7 +1118,7 @@ function CartCheckout(props) {
value={<SpPrice unit='cent' primary value={0 - totalInfo.point_fee} />} value={<SpPrice unit='cent' primary value={0 - totalInfo.point_fee} />}
/> />
)} )}
</View> </View>}
<CompPointUse <CompPointUse
isOpened={isPointOpenModal} isOpened={isPointOpenModal}

View File

@ -1,20 +1,27 @@
$margin24: 24px; $margin24: 10px;
.page-cart-checkout { .page-cart-checkout {
box-sizing: border-box; box-sizing: border-box;
overflow-y: auto; overflow-y: auto;
padding: 0px 16px; padding: 0px 22px;
.checkout-toolbar { .checkout-toolbar {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: flex-end;
background: #fff; background: #fff;
padding: 0 20px; padding: 0 40px 90px 50px;
height: 100%; // height: 100%;
&__total { &__total {
white-space: nowrap; white-space: nowrap;
flex: 1; flex: 1;
margin-right: 0; margin-right: 0;
.at-button {
padding: 0 38px;
}
.price-total {
font-size: 26px;
mask-repeat: 12px;
}
.last_price { .last_price {
display: inline-block; display: inline-block;
.sp-price__append { .sp-price__append {
@ -57,16 +64,17 @@ $margin24: 24px;
} }
.sp-order-item { .sp-order-item {
position: relative; position: relative;
padding: 35px 0px; padding: 35px 24px;
background: #f7f7f7;
&__bd { &__bd {
flex: 1; flex: 1;
} }
&__idx { &__idx {
color: #666; color: #000;
height: 36px; height: 26px;
line-height: 36px; line-height: 26px;
display: block; display: block;
font-size: 30px; font-size: 26px;
} }
&__img { &__img {
width: 200px; width: 200px;
@ -119,8 +127,11 @@ $margin24: 24px;
font-size: 24px; font-size: 24px;
} }
.cart-checkout__address { .cart-checkout__address {
margin-bottom: $margin24; // margin-bottom: $margin24;
margin-top: 24px; // margin-top: 24px;
margin: 10px 0;
border-bottom: 6px;
overflow: hidden;
} }
.cart-checkout__coupons { .cart-checkout__coupons {
.sp-cell__value { .sp-cell__value {
@ -134,9 +145,12 @@ $margin24: 24px;
.cart-checkout__pay, .cart-checkout__pay,
.cart-checkout__total, .cart-checkout__total,
.cart-checkout__group { .cart-checkout__group {
box-shadow: 0px 2px 10px 0px #eae7e0; // box-shadow: 0px 2px 10px 0px #eae7e0;
margin: 0 0 $margin24; margin: 0 0 $margin24;
padding: 30px 16px; padding: 30px 24px;
background: #f7f7f7;
border-radius: 6px;
box-sizing: border-box;
} }
// .cart-checkout__pay { // .cart-checkout__pay {
@ -184,13 +198,60 @@ $margin24: 24px;
} }
.cart-checkout__group { .cart-checkout__group {
padding: 24px 16px; // padding: 24px 16px;
background: #fff;
.cart-group__shop { .cart-group__shop {
padding: 16px $edge-margin; padding: 16px $edge-margin;
} }
.cart-group__cont { .cart-group__cont {
background: #fff; // background: #fff;
.price-gp {
text-align: end;
font-weight: bold;
}
.sp-price__decimal {
font-weight: bold;
}
.gap {
padding: 0 54px;
width: calc(100% - 108px);
box-sizing: border-box;
height: 2px;
background: #fff;
margin: 20px auto;
}
.trade-detail-info-new {
padding: 20px 24px;
.line {
display: flex;
width: 100%;
justify-content: space-between;
align-items: center;
margin-bottom: 18px;
.left,
.right {
font-size: 20px;
color: #5b5b5b;
line-height: 1;
}
}
}
.trade-detail-info-bottom {
display: flex;
align-items: center;
justify-content: space-between;
padding: 20px 22px 50px;
.left {
font-size: 26px;
}
.right {
font-size: 32px;
}
.left,
.sp-price__symbol,
.sp-price__int {
font-weight: bold;
}
}
} }
.cus-input { .cus-input {
.sp-cell { .sp-cell {
@ -220,7 +281,8 @@ $margin24: 24px;
margin: 0 0 $margin24; margin: 0 0 $margin24;
.sp-cell { .sp-cell {
padding: 30px 16px; padding: 30px 16px;
box-shadow: 0px 2px 10px 0px #eae7e0; // box-shadow: 0px 2px 10px 0px #eae7e0;
background: #f7f7f7;
} }
.required { .required {
color: #e62424; color: #e62424;

View File

@ -1,3 +1,4 @@
export default { export default {
navigationBarTitleText: '购物车' navigationBarTitleText: '',
navigationStyle: 'custom',
} }

View File

@ -1,7 +1,7 @@
import Taro, { getCurrentInstance, useDidShow } from '@tarojs/taro' import Taro, { getCurrentInstance, useDidShow } from '@tarojs/taro'
import React, { useEffect, useState, useMemo } from 'react' import React, { useEffect, useState, useMemo } from 'react'
import { useSelector, useDispatch } from 'react-redux' import { useSelector, useDispatch } from 'react-redux'
import { View, Text } from '@tarojs/components' import { View, Text, ScrollView } from '@tarojs/components'
import { AtButton } from 'taro-ui' import { AtButton } from 'taro-ui'
import { useImmer } from 'use-immer' import { useImmer } from 'use-immer'
import qs from 'qs' import qs from 'qs'
@ -18,7 +18,9 @@ import {
SpLogin, SpLogin,
SpDefault, SpDefault,
SpCheckboxNew, SpCheckboxNew,
SpPrivacyModal SpPrivacyModal,
SpImage,
SpGoodsItem
} from '@/components' } from '@/components'
import CompGoodsItem from './comps/comp-goodsitem' import CompGoodsItem from './comps/comp-goodsitem'
@ -52,7 +54,7 @@ function CartIndex () {
const { current, recommendList, policyModal } = state const { current, recommendList, policyModal } = state
const { colorPrimary, openRecommend } = useSelector((state) => state.sys) const { colorPrimary, openRecommend } = useSelector((state) => state.sys)
const { validCart = [], invalidCart = [] } = useSelector((state) => state.cart) const { validCart = [], invalidCart = [], cartCount } = useSelector((state) => state.cart)
const { tabbar = 1 } = router?.params || {} const { tabbar = 1 } = router?.params || {}
// useDepChange(() => { // useDepChange(() => {
@ -70,8 +72,8 @@ function CartIndex () {
const fetch = () => { const fetch = () => {
if (openRecommend == 1) { if (openRecommend == 1) {
getRecommendList() // 猜你喜欢
} }
getRecommendList() // 猜你喜欢
if (isLogin) { if (isLogin) {
getCartList() getCartList()
} }
@ -164,6 +166,7 @@ function CartIndex () {
page: 1, page: 1,
pageSize: 1000 pageSize: 1000
}) })
console.log("🚀 ~ list:----169", list)
setState((draft) => { setState((draft) => {
draft.recommendList = list draft.recommendList = list
}) })
@ -254,7 +257,13 @@ function CartIndex () {
} }
const groupsList = resolveActiveGroup() const groupsList = resolveActiveGroup()
console.log(groupsList, 'list')
const handleClickStore = (item) => {
const url = `/subpages/store/index?id=${item.distributor_info?.distributor_id || item.goods_id}`
Taro.navigateTo({
url
})
}
return ( return (
<SpPage <SpPage
@ -262,15 +271,16 @@ function CartIndex () {
'has-tabbar': tabbar == 1 'has-tabbar': tabbar == 1
})} })}
renderFooter={tabbar == 1 && <SpTabbar />} renderFooter={tabbar == 1 && <SpTabbar />}
showNavLogo isBlack showNavkfIcon
> >
{!isLogin && ( {/* {!isLogin && (
<View className='login-header'> <View className='login-header'>
<View className='login-txt'>授权登录后同步购物车的商品</View> <View className='login-txt'>授权登录后同步购物车的商品</View>
<SpLogin onChange={() => { }}> <SpLogin onChange={() => { }}>
<View className='btn-login'>授权登录</View> <View className='btn-login'>授权登录</View>
</SpLogin> </SpLogin>
</View> </View>
)} )} */}
{isLogin && ( {isLogin && (
<View> <View>
{/* <SpTabs current={current} tablist={tablist} onChange={onChangeSpTab} /> */} {/* <SpTabs current={current} tablist={tablist} onChange={onChangeSpTab} /> */}
@ -281,8 +291,11 @@ function CartIndex () {
return ( return (
<View className='shop-cart-item' key={`shop-cart-item__${all_index}`}> <View className='shop-cart-item' key={`shop-cart-item__${all_index}`}>
<View className='shop-cart-item-hd'> <View className='shop-cart-item-hd'>
<Text className='iconfont icon-shop' /> {/* <Text className='iconfont icon-shop' /> */}
{all_item.shop_name || '自营'} {/* {all_item.shop_name || '自营'} */}
购物车
{/* <Text className="total">共{all_item.cart_total_num}件</Text> */}
<Text className="total">{cartCount}</Text>
</View> </View>
<View className='shop-cart-item-shadow'> <View className='shop-cart-item-shadow'>
{/** 店铺商品开始 */} {/** 店铺商品开始 */}
@ -338,6 +351,7 @@ function CartIndex () {
info={c_sitem} info={c_sitem}
onDelete={onDeleteCartGoodsItem.bind(this, c_sitem)} onDelete={onDeleteCartGoodsItem.bind(this, c_sitem)}
onChange={onChangeCartGoodsItem.bind(this, c_sitem)} onChange={onChangeCartGoodsItem.bind(this, c_sitem)}
onChangeGoodsIsCheck={onChangeGoodsIsCheck.bind(this, c_sitem, 'single', !c_sitem.is_checked)}
onClickImgAndTitle={onClickImgAndTitle.bind(this, c_sitem)} onClickImgAndTitle={onClickImgAndTitle.bind(this, c_sitem)}
/> />
</View> </View>
@ -382,12 +396,14 @@ function CartIndex () {
label='全选' label='全选'
onChange={onChangeGoodsIsCheck.bind(this, all_item, 'all')} onChange={onChangeGoodsIsCheck.bind(this, all_item, 'all')}
/> />
{/* <Text className='total-num'>共{all_item.cart_total_num}件</Text> */}
<Text className='total-num'>{cartCount}</Text>
</View> </View>
<View className='rg'> <View className='rg'>
<View> <View>
<View className='total-price-wrap'> <View className='total-price-wrap'>
合计 {/* 合计: */}
<SpPrice className='total-pirce' value={all_item.total_fee / 100} /> <SpPrice className='total-pirce' value={all_item.total_fee / 100} showSeparator noDecimal />
</View> </View>
{all_item.discount_fee > 0 && ( {all_item.discount_fee > 0 && (
<View className='discount-price-wrap'> <View className='discount-price-wrap'>
@ -402,11 +418,10 @@ function CartIndex () {
<AtButton <AtButton
className='btn-calc' className='btn-calc'
type='primary' type='primary'
circle
disabled={all_item.cart_total_num <= 0} disabled={all_item.cart_total_num <= 0}
onClick={() => handleCheckout(all_item)} onClick={() => handleCheckout(all_item)}
> >
结算({all_item.cart_total_num}) 立即结算
</AtButton> </AtButton>
</View> </View>
</View> </View>
@ -443,13 +458,65 @@ function CartIndex () {
)} )}
{validCart.length == 0 && invalidCart.length == 0 && ( {validCart.length == 0 && invalidCart.length == 0 && (
<SpDefault type='cart' message='购物车内暂无商品~'> <View className='empty-box'>
<AtButton type='primary' circle onClick={navigateTo.bind(this, '/pages/index', true)}> {/* <SpDefault type='cart' message=''>
去选购 <AtButton type='primary' circle onClick={navigateTo.bind(this, '/pages/index', true)}>
</AtButton> 去选购
</SpDefault> </AtButton>
</SpDefault> */}
<SpImage className='default-img' src='cart/logo-hui.png' width={160} isNew />
<View className="empty-box-tit">购物车还是空的</View>
<View className="empty-box-sub-tit">快去挑选自己喜欢的宝贝吧~</View>
<SpLogin onChange={() => { }}>
<AtButton type='primary' onClick={navigateTo.bind(this, '/pages/index', true)}>
前往选购
</AtButton>
</SpLogin>
<View className="gap"></View>
</View>
)} )}
{false && <sView className='bottom-box'>
<View className="bottom-box-tit" style={{ fontSize: validCart.length == 0 && invalidCart.length == 0 ? '40rpx' : '30rpx' }}>{validCart.length == 0 && invalidCart.length == 0 ? '商品推荐' : '专属推荐'}</View>
<ScrollView scrollX scrollWithAnimation showScrollbar={true} scrollLeft={0} className="shop-box">
{[
{
brief: "副标题",
itemName: "测试商品1",
price: "1099",
goods_id: 6,
pic: 'https://espier-oss-cdn.oss-cn-shanghai.aliyuncs.com/default_project/image/1/2024/01/15/46fe6ca52277038e39ee2c026a4af3c9xHQuJ96YIcZWtjRS0HBCTzp7dzXIs2pl'
},
{
brief: "副标题",
itemName: "测试商品2",
price: "1099",
goods_id: 6,
pic: 'https://espier-oss-cdn.oss-cn-shanghai.aliyuncs.com/default_project/image/1/2024/01/15/801c18d59d95ea26930fefc43bf66febTQjxb65cpnCqVLaOsYmiHdkDdYqBnXVm'
},
{
brief: "副标题",
itemName: "测试商品3",
price: "1099",
goods_id: 6,
pic: 'https://espier-oss-cdn.oss-cn-shanghai.aliyuncs.com/default_project/image/1/2024/01/15/46fe6ca52277038e39ee2c026a4af3c90XruENsSSAhRiz0HPI3PjR8XQNVgbxHb'
},
].map((item, idx) => (
<View className='goods-item-wrap' key={`goods-item-l__${idx}`}>
<SpGoodsItem
showSalePrice={false}
height={250}
width={250}
onStoreClick={handleClickStore}
info={{
...item
}}
/>
</View>
))}
</ScrollView>
</sView>}
{/* 猜你喜欢 */} {/* 猜你喜欢 */}
<SpRecommend className='recommend-block' info={recommendList} /> <SpRecommend className='recommend-block' info={recommendList} />

View File

@ -1,5 +1,6 @@
.page-cart-index { .page-cart-index {
&.has-tabbar { &.has-tabbar {
// padding-bottom: calc(#{$tabbar-height} + 140px);
padding-bottom: $tabbar-height; padding-bottom: $tabbar-height;
} }
.login-header { .login-header {
@ -30,19 +31,31 @@
} }
.shop-cart-item { .shop-cart-item {
padding: 0 16px; padding: 0 16px;
margin-top: 40px; margin-top: 10px;
/* #ifdef alipay */ /* #ifdef alipay */
margin-top: 0; margin-top: 0;
padding-top: 40px; padding-top: 40px;
/* #endif */ /* #endif */
margin-bottom: 36px;
&-shadow { &-shadow {
box-shadow: 0px 2px 10px 0px #eae7e0; // box-shadow: 0px 2px 10px 0px #eae7e0;
} }
&-hd { &-hd {
font-size: 30px; font-size: 40px;
color: #333; color: #000;
font-weight: bold; font-weight: bold;
margin-bottom: 10px; margin-bottom: 40px;
line-height: 1;
display: flex;
align-items: baseline;
padding-left: 6px;
.total {
font-size: 26px;
margin-left: 20px;
line-height: 1;
font-weight: normal;
// color: #999;
}
} }
&-bd { &-bd {
background: #fff; background: #fff;
@ -52,15 +65,45 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding: 20px; padding: 26px 40px 26px 60px;
position: fixed;
bottom: calc(#{$page-ipx-footer-height} - 2px);
z-index: 1080;
left: 0;
right: 0;
border-top: 1px solid #d9d9d9;
border-bottom: 1px solid #d9d9d9;
.lf {
display: flex;
align-items: flex-end;
.sp-checkbox-new {
align-items: flex-end;
.icon-my {
font-size: 32px;
color: #000;
}
}
.total-num {
font-size: 26px;
margin-left: 20px;
}
}
.rg { .rg {
display: flex; display: flex;
align-items: center; align-items: center;
.total-pirce { .total-pirce {
font-size: 40px; font-size: 40px;
font-weight: bold;
.sp-price__int {
margin-left: 8px;
}
} }
.btn-calc { .btn-calc {
margin-left: 16px; margin-left: 30px;
height: 74px;
line-height: 72px;
padding: 0px 28px;
border-radius: 6px;
} }
} }
} }
@ -111,10 +154,21 @@
} }
.cart-item-wrap { .cart-item-wrap {
padding: 16px; padding: 60px 36px;
display: flex; display: flex;
align-items: center; align-items: center;
background: #f7f7f7;
margin-bottom: 10px;
border-radius: 6px;
box-sizing: border-box;
// justify-content: space-around; // justify-content: space-around;
.sp-checkbox-new {
.icon-my {
font-size: 24px;
margin-right: 10px;
color: #000;
}
}
} }
.cart-item-warp-disabled { .cart-item-warp-disabled {
padding: 16px; padding: 16px;
@ -131,16 +185,16 @@
.cart-goods-item, .cart-goods-item,
.comp-goodsitem { .comp-goodsitem {
flex: 1; flex: 1;
width: 620px; width: 590px;
} }
.at-input-number { .at-input-number {
border: 1PX solid #999; border: 1px solid #999;
border-radius: 0; border-radius: 0;
height: 40px; height: 40px;
&__input { &__input {
/* prettier-ignore */ /* prettier-ignore */
border-left: 1PX solid #999; border-left: 1PX solid #999;
border-right: 1PX solid #999; border-right: 1px solid #999;
width: 60px; width: 60px;
height: 32px; height: 32px;
line-height: 32px; line-height: 32px;
@ -238,4 +292,64 @@
.sp-goods-item { .sp-goods-item {
border-radius: 2px; border-radius: 2px;
} }
.empty-box {
padding-top: 90px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.sp-image {
margin-bottom: 50px;
}
.at-button {
border-radius: 6px;
line-height: 1;
padding: 28px 82px;
height: auto;
font-size: 26px;
}
&-tit {
font-size: 30px;
color: #000;
}
&-sub-tit {
font-size: 22px;
color: #7f7f7f;
margin: 20px 0 40px;
}
.gap {
width: 100%;
height: 20px;
background: #f5f5f5;
margin-top: 90px;
}
}
.bottom-box {
margin-bottom: 50px;
&-tit {
font-size: 30px;
color: #000;
padding-left: 44px;
padding-top: 30px;
font-weight: 500;
line-height: 1;
}
.shop-box {
height: 466px;
width: 100%;
padding: 30px 30px 30px;
box-sizing: border-box;
transition: height 0.2s linear 0.2s;
white-space: nowrap;
.goods-item-wrap {
display: inline-block;
width: 250px;
height: 100%;
margin-right: 30px;
&:last-child {
margin-right: 0;
}
}
}
}
} }

View File

@ -20,7 +20,7 @@ const CompSeries = (props) => {
const handleClickItem = (item) => { const handleClickItem = (item) => {
const { category_id, main_category_id } = item const { category_id, main_category_id } = item
let url = '' let url = '/pages/item/list'
if (category_id) { if (category_id) {
url = `/pages/item/list?cat_id=${category_id}` url = `/pages/item/list?cat_id=${category_id}`
} }
@ -61,8 +61,9 @@ const CompSeries = (props) => {
const renderCategoryChildHandler = (item = selChild) => { const renderCategoryChildHandler = (item = selChild) => {
return ( return (
<View className=''> <View className='group-box'>
<View className='group' key={item.category_id} onClick={() => false && handleCustomClick(item.category_id)}> {/* handleCustomClick(item.category_id) */}
<View className='group' key={item.category_id} onClick={() => handleClickItem(item)}>
<View className='group-title'>探索全部 <View className='group-title'>探索全部
<Text className='iconfont icon-qianwang-01' style={{ fontSize: 'inherit', marginLeft: '4px' }}></Text> <Text className='iconfont icon-qianwang-01' style={{ fontSize: 'inherit', marginLeft: '4px' }}></Text>
</View> </View>

View File

@ -97,7 +97,10 @@
.new { .new {
width: 100%; width: 100%;
} }
.group-box {
}
.group { .group {
animation: fadeInAnimation 0.2s ease-in-out;
position: relative; position: relative;
width: 100%; width: 100%;
color: #fff; color: #fff;
@ -183,3 +186,12 @@
} }
} }
} }
@keyframes fadeInAnimation {
from {
opacity: 0;
}
to {
opacity: 1;
}
}

View File

@ -3,6 +3,9 @@
} }
page { page {
.sp-page { .sp-page {
.sp-loading {
margin-top: 100px;
}
// &.has-navbar { // &.has-navbar {
// padding-top: 0 !important; // padding-top: 0 !important;
// } // }
@ -69,6 +72,7 @@ page {
height: calc(100vh - #{$page-ipx-footer-height} - var(--status-bar-height)); height: calc(100vh - #{$page-ipx-footer-height} - var(--status-bar-height));
// height: calc(100vh - #{$tabbar-height}); // height: calc(100vh - #{$tabbar-height});
transition: height 0.3s ease-in-out; transition: height 0.3s ease-in-out;
animation: fadeInAnimation 0.35s ease-in;
&.swiper-narrow { &.swiper-narrow {
height: calc(100vh - 620px - #{$tabbar-height} - var(--status-bar-height)); height: calc(100vh - 620px - #{$tabbar-height} - var(--status-bar-height));
} }
@ -152,7 +156,7 @@ page {
.shop-box { .shop-box {
height: 520px; height: 520px;
width: 100%; width: 100%;
padding: 30px 50px 40px; padding: 30px 50px 20px;
box-sizing: border-box; box-sizing: border-box;
// background-color: aquamarine; // background-color: aquamarine;
transition: height 0.2s linear 0.2s; transition: height 0.2s linear 0.2s;
@ -164,6 +168,7 @@ page {
display: inline-block; display: inline-block;
width: 310px; width: 310px;
margin-right: 30px; margin-right: 30px;
// animation: fadeInAnimation 0.35s ease-in;
&:last-child { &:last-child {
margin-right: 0; margin-right: 0;
} }
@ -231,3 +236,11 @@ page {
} }
} }
} }
@keyframes fadeInAnimation {
from {
opacity: 0;
}
to {
opacity: 1;
}
}

View File

@ -18,7 +18,8 @@ import {
SpCouponPackage, SpCouponPackage,
SpNavBar, SpNavBar,
SpImage, SpImage,
SpGoodsItem SpGoodsItem,
SpChat
} from '@/components' } from '@/components'
import api from '@/api' import api from '@/api'
import { import {
@ -56,6 +57,7 @@ const initialState = {
fixedTop: false, fixedTop: false,
filterWgts: [], filterWgts: [],
isShowHomeHeader: false, isShowHomeHeader: false,
swiperList: [],
list: [ list: [
{ {
type: 'image', type: 'image',
@ -99,7 +101,8 @@ const initialState = {
goods_id: 6, goods_id: 6,
pic: 'https://espier-oss-cdn.oss-cn-shanghai.aliyuncs.com/default_project/image/1/2024/01/15/46fe6ca52277038e39ee2c026a4af3c90XruENsSSAhRiz0HPI3PjR8XQNVgbxHb' pic: 'https://espier-oss-cdn.oss-cn-shanghai.aliyuncs.com/default_project/image/1/2024/01/15/46fe6ca52277038e39ee2c026a4af3c90XruENsSSAhRiz0HPI3PjR8XQNVgbxHb'
}, },
] ],
goodList: []
} }
function Home () { function Home () {
@ -118,7 +121,7 @@ function Home () {
const { location } = useSelector((state) => state.user) const { location } = useSelector((state) => state.user)
const { setNavigationBarTitle } = useNavigation() const { setNavigationBarTitle } = useNavigation()
const { wgts, loading, searchComp, pageData, fixedTop, filterWgts, isShowHomeHeader, isUpOperation, showRecommend, shopList } = state const { wgts, loading, searchComp, pageData, fixedTop, filterWgts, isShowHomeHeader, isUpOperation, showRecommend, shopList, swiperList, goodList } = state
const dispatch = useDispatch() const dispatch = useDispatch()
@ -126,6 +129,7 @@ function Home () {
if (initState) { if (initState) {
init() init()
setNavigationBarTitle(appName) setNavigationBarTitle(appName)
getSwiperList()
} }
}, [initState]) }, [initState])
@ -167,8 +171,6 @@ function Home () {
if (dtid && !('dtid' in params)) { if (dtid && !('dtid' in params)) {
params = Object.assign(params, { dtid }) params = Object.assign(params, { dtid })
} }
console.log('useShareTimeline params:', params)
return { return {
title: title, title: title,
imageUrl: imageUrl, imageUrl: imageUrl,
@ -186,6 +188,33 @@ function Home () {
} }
} }
const getSwiperList = async () => {
const res = await api.shop.homeSwiperList({ page: 1, pageSize: 999 })
const list = res?.list?.map((item) => {
return {
type: item.type || 'image',
src: item.pic,
goods: (item.goods_info_detail || []).map((ite) => {
return {
itemName: ite.item_name,
price: ite.price,
goods_id: ite.item_id,
itemId: ite.item_id,
pic: ite.pics?.[0],
brief: ite.brief,
price: ite.price,
spec_images: ite.spec_images || [],
tagList: ite.tagList || []
}
})
}
}) || []
setState((draft) => {
draft.swiperList = list
draft.goodList = list[0].goods || []
})
}
const fetchWgts = async () => { const fetchWgts = async () => {
setState((draft) => { setState((draft) => {
draft.wgts = [] draft.wgts = []
@ -301,8 +330,10 @@ function Home () {
} }
} }
const onSwiperChange = (e) => { const onSwiperChange = (e) => {
const { current } = e.detail
setState((draft) => { setState((draft) => {
draft.currentIndex = e.detail.current draft.currentIndex = current
draft.goodList = swiperList[current].goods || []
}) })
} }
@ -313,6 +344,7 @@ function Home () {
}) })
} }
return ( return (
<SpPage <SpPage
className='page-index' className='page-index'
@ -377,7 +409,7 @@ function Home () {
autoplay={!isUpOperation} autoplay={!isUpOperation}
onChange={onSwiperChange} onChange={onSwiperChange}
> >
{state.list.map((item, index) => ( {state.swiperList.map((item, index) => (
<SwiperItem key={index} className="" style={{ height: "100%" }}> <SwiperItem key={index} className="" style={{ height: "100%" }}>
{item.type === "image" && ( {item.type === "image" && (
<Image <Image
@ -424,17 +456,17 @@ function Home () {
))} ))}
</Swiper> </Swiper>
{!isUpOperation && <View className='spot-pagination'> {!isUpOperation && <View className='spot-pagination'>
{state.list.map((_, index) => ( {swiperList.map((_, index) => (
<View key={index} className={'spot-pagination-bullet ' + ((state.currentIndex == index) ? 'spot-pagination-bullet-active' : "")} style={{ width: 1 / state.length * 100 + '%' }}></View> <View key={index} className={'spot-pagination-bullet ' + ((state.currentIndex == index) ? 'spot-pagination-bullet-active' : "")} style={{ width: 1 / state.length * 100 + '%' }}></View>
))} ))}
</View>} </View>}
{isUpOperation && <View className="icon-kf"> {isUpOperation && <View className="icon-kf">
<SpImage height="62" src='index/kf.png' isShowMenuByLongpress={false} lazyLoad isNew></SpImage> <SpChat><SpImage height="62" src='index/kf.png' isShowMenuByLongpress={false} lazyLoad isNew /></SpChat>
</View>} </View>}
</View> </View>
{isUpOperation && <ScrollView scrollX scrollWithAnimation showScrollbar={false} scrollLeft={0} className="shop-box"> {isUpOperation && <ScrollView scrollX scrollWithAnimation showScrollbar={false} scrollLeft={0} className="shop-box fadeIn" >
{shopList.map((item, idx) => ( {goodList.map((item, idx) => (
<View className='goods-item-wrap' key={`goods-item-l__${idx}`}> <View className='goods-item-wrap fadeIn' animation={{ duration: 500, timingFunction: 'ease-in-out', delay: 0 }} key={`goods-item-l__${idx + item.goods_id}`}>
<SpGoodsItem <SpGoodsItem
onStoreClick={handleClickStore} onStoreClick={handleClickStore}
info={{ info={{

View File

@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react'
import { useSelector, useDispatch } from 'react-redux' import { useSelector, useDispatch } from 'react-redux'
import Taro, { getCurrentInstance } from '@tarojs/taro' import Taro, { getCurrentInstance } from '@tarojs/taro'
import { View, Text } from '@tarojs/components' import { View, Text } from '@tarojs/components'
import { SpImage, SpLogin } from '@/components' import { SpImage, SpLogin, SpChat } from '@/components'
import { classNames, navigateTo, showToast, isWeb } from '@/utils' import { classNames, navigateTo, showToast, isWeb } from '@/utils'
import { addCart } from '@/store/slices/cart' import { addCart } from '@/store/slices/cart'
import { BUY_TOOL_BTNS, ACTIVITY_LIST } from '@/consts' import { BUY_TOOL_BTNS, ACTIVITY_LIST } from '@/consts'
@ -86,11 +86,11 @@ function CompGoodsBuyToolbar (props) {
} }
RenderBtns() RenderBtns()
console.log('btns:', btns) // console.log('btns:', btns)
const onChangeLogin = async ({ key }) => { const onChangeLogin = async ({ key }) => {
const { dtid, card_id, user_card_id } = $instance.router.params const { dtid, card_id, user_card_id } = $instance.router.params
console.log('onChangeLogin:', key) // console.log('onChangeLogin:', key)
if (key == 'notice') { if (key == 'notice') {
const { subscribe } = info const { subscribe } = info
if (subscribe) return false if (subscribe) return false
@ -149,7 +149,7 @@ function CompGoodsBuyToolbar (props) {
return ( return (
<View className='comp-goodsbuytoolbar'> <View className='comp-goodsbuytoolbar'>
<View className='comp-goodsbuytoolbar-flex'> <View className='comp-goodsbuytoolbar-flex'>
<SpImage height={54} src='index/kf.png' mode='heightFix' isShowMenuByLongpress={false} isNew></SpImage> <SpChat> <SpImage height={54} src='index/kf.png' mode='heightFix' isShowMenuByLongpress={false} isNew></SpImage></SpChat>
<SpLogin className='shoucang-wrap' onChange={onChangeCollection.bind(this)}> <SpLogin className='shoucang-wrap' onChange={onChangeCollection.bind(this)}>
<SpImage height={54} src={isFaved ? 'cart/star-full.png' : 'cart/star.png'} mode='heightFix' isShowMenuByLongpress={false} isNew></SpImage> <SpImage height={54} src={isFaved ? 'cart/star-full.png' : 'cart/star.png'} mode='heightFix' isShowMenuByLongpress={false} isNew></SpImage>
{/* <View className='toolbar-item'> {/* <View className='toolbar-item'>

View File

@ -128,6 +128,7 @@
} }
&__container { &__container {
width: 560px; width: 560px;
border-radius: 10px;
} }
&__header { &__header {
font-size: 40px; font-size: 40px;

View File

@ -5,9 +5,8 @@ import { View, Text, ScrollView } from '@tarojs/components'
import { SpPrice, SpLogin } from '@/components' import { SpPrice, SpLogin } from '@/components'
import './comp-couponlist.scss' import './comp-couponlist.scss'
function CompCouponList(props) { function CompCouponList (props) {
const { info, onClick = () => {} } = props const { info, onClick = () => { } } = props
console.log(info)
const onChangeLogin = () => { const onChangeLogin = () => {
Taro.navigateTo({ Taro.navigateTo({
url: `/subpage/pages/vip/vipgrades?grade_name=${info.vipgrade_name}` url: `/subpage/pages/vip/vipgrades?grade_name=${info.vipgrade_name}`

View File

@ -8,7 +8,7 @@ import Taro, {
} from '@tarojs/taro' } from '@tarojs/taro'
import { View, Text, Swiper, SwiperItem, Video, Canvas, ScrollView } from '@tarojs/components' import { View, Text, Swiper, SwiperItem, Video, Canvas, ScrollView } from '@tarojs/components'
import { useImmer } from 'use-immer' import { useImmer } from 'use-immer'
import { AtCountdown } from 'taro-ui' import { AtCountdown, AtAccordion, AtIcon } from 'taro-ui'
import { import {
SpPrice, SpPrice,
SpCell, SpCell,
@ -22,7 +22,8 @@ import {
SpLogin, SpLogin,
SpFloatMenuItem, SpFloatMenuItem,
SpChat, SpChat,
SpGoodsPrice SpGoodsPrice,
SpGoodsItem
} from '@/components' } from '@/components'
import api from '@/api' import api from '@/api'
import req from '@/api/req' import req from '@/api/req'
@ -94,7 +95,14 @@ const initialState = {
curItem: null, curItem: null,
recommendList: [], recommendList: [],
showSaleTotal: false, showSaleTotal: false,
showSku: true showSku: true,
isOpen: false,
historyList: [],
historyTotal: 0,
selSkuImg: '',
swiperList: [],
selColorIdx: 0,
introList: []
} }
function EspierDetail (props) { function EspierDetail (props) {
@ -107,6 +115,7 @@ function EspierDetail (props) {
const { colorPrimary, openRecommend } = useSelector((state) => state.sys) const { colorPrimary, openRecommend } = useSelector((state) => state.sys)
const { setNavigationBarTitle } = useNavigation() const { setNavigationBarTitle } = useNavigation()
const dispatch = useDispatch() const dispatch = useDispatch()
const skuSelectRef = useRef()
const [state, setState] = useImmer(initialState) const [state, setState] = useImmer(initialState)
const { const {
@ -133,7 +142,13 @@ function EspierDetail (props) {
curItem, curItem,
recommendList, recommendList,
showSaleTotal, showSaleTotal,
showSku showSku,
isOpen,
historyList,
selSkuImg,
swiperList,
selColorIdx,
introList
} = state } = state
useEffect(() => { useEffect(() => {
@ -150,8 +165,8 @@ function EspierDetail (props) {
useEffect(() => { useEffect(() => {
if (id) { if (id) {
fetch() fetch()
getPackageList() // getPackageList()
getEvaluationList() // getEvaluationList()
} }
}, [id]) }, [id])
@ -212,15 +227,16 @@ function EspierDetail (props) {
} }
const init = async () => { const init = async () => {
const { type, id, dtid } = await entryLaunch.getRouteParams() const pams = await entryLaunch.getRouteParams()
console.log("🚀 ~ type, id, dtid :", type, id, dtid) const { type, id, dtid, idx = 0 } = pams
setState((draft) => { setState((draft) => {
draft.id = id draft.id = id
draft.type = type draft.type = type
draft.dtid = dtid draft.dtid = dtid
draft.selColorIdx = +idx
}) })
if (S.getAuthToken()) { if (S.getAuthToken()) {
await dispatch(fetchUserFavs()) dispatch(fetchUserFavs())
} }
} }
@ -240,21 +256,29 @@ function EspierDetail (props) {
draft.defaultMsg = '商品已下架' draft.defaultMsg = '商品已下架'
}) })
} }
if (selColorIdx != 0) {
const spec_values = data.itemSpecDesc?.[0]?.spec_values || []
if (spec_values.length) {
const item = spec_values[selColorIdx]
setTimeout(() => {
skuSelectRef.current?.handleSelectSku({ specId: item.spec_value_id, specValueId: item.spec_value_id }, selColorIdx)
}, 100)
}
}
} catch (e) { } catch (e) {
setState((draft) => { setState((draft) => {
draft.isDefault = true draft.isDefault = true
draft.defaultMsg = e.res.data.data.message draft.defaultMsg = e.res.data.data.message
}) })
console.log(e.res)
} }
} }
// 是否订阅 // 是否订阅
const { user_id: subscribe = false } = await api.user.isSubscribeGoods(id, { distributor_id: dtid }) const { user_id: subscribe = false } = await api.user.isSubscribeGoods(id, { distributor_id: dtid })
setNavigationBarTitle(data?.itemName) // setNavigationBarTitle(data?.itemName)
console.log(ACTIVITY_LIST[data.activityType]) // console.log(ACTIVITY_LIST[data.activityType])
if (ACTIVITY_LIST[data.activityType]) { if (ACTIVITY_LIST[data.activityType]) {
Taro.setNavigationBarColor({ Taro.setNavigationBarColor({
frontColor: '#ffffff', frontColor: '#ffffff',
@ -265,11 +289,18 @@ function EspierDetail (props) {
} }
}) })
} }
console.log("🚀 ~ data.introList:", data.introList)
setState((draft) => { setState((draft) => {
draft.info = { draft.info = {
...data, ...data,
subscribe subscribe,
} }
draft.introList = (data.introList || []).map((item) => {
return {
...item,
isOpen: false
}
})
draft.promotionActivity = data.promotionActivity draft.promotionActivity = data.promotionActivity
}) })
@ -294,6 +325,15 @@ function EspierDetail (props) {
if (openRecommend == 1) { if (openRecommend == 1) {
getRecommendList() // 猜你喜欢 getRecommendList() // 猜你喜欢
} }
api.member.itemHistorySave(data.itemId)
const res = await api.member.itemHistory()
setState((draft) => {
draft.historyList = res.list.filter((item) => item.item_id !== data.itemId).map((item) => ({ ...item.itemData, pic: item.itemData.pics?.[0] || '' }))
draft.historyTotal = res.total_count
})
} }
const getRecommendList = async () => { const getRecommendList = async () => {
@ -346,6 +386,13 @@ function EspierDetail (props) {
draft.skuPanelOpen = true draft.skuPanelOpen = true
draft.selectType = key draft.selectType = key
}) })
if (key === 'addcart') {
skuSelectRef.current?.addToCart?.()
} else if (key === 'fastbuy') {
skuSelectRef.current?.fastBuy?.()
}
} }
const { windowWidth } = Taro.getSystemInfoSync() const { windowWidth } = Taro.getSystemInfoSync()
@ -358,6 +405,19 @@ function EspierDetail (props) {
} }
} }
const handleClickStore = (item) => {
const url = `/subpages/store/index?id=${item.distributor_info?.distributor_id || item.goods_id}`
Taro.navigateTo({
url
})
}
const onChangeImg = (img) => {
setState((draft) => {
draft.selSkuImg = img || ''
})
}
return ( return (
<SpPage <SpPage
className='page-item-espierdetail' className='page-item-espierdetail'
@ -395,21 +455,38 @@ function EspierDetail (props) {
{/* <Canvas id="canvas2" type="2d" onReady={onCanvasReady} /> */} {/* <Canvas id="canvas2" type="2d" onReady={onCanvasReady} /> */}
{!info && <SpLoading />} {!info && <SpLoading />}
{info && ( {info && (
<View className='goods-contents'> <ScrollView scrollY scrollWithAnimation showScrollbar={false} scrollTop={0} className='goods-contents' onScroll={(e) => {
// console.log('e', e.detail)
const { scrollTop } = e.detail
if (scrollTop >= 640) {
setState((draft) => {
draft.isShowScroll = true
})
} else {
setState((draft) => {
draft.isShowScroll = false
})
}
}}>
<View className='goods-pic-container'> <View className='goods-pic-container'>
<Swiper <Swiper
className='goods-swiper' className='goods-swiper'
// current={curImgIdx} // current={curImgIdx}
onChange={onChangeSwiper} onChange={onChangeSwiper}
style={{
height: windowWidth
}}
autoplay
interval={3000}
circular
> >
{console.log('info', info)} {(info.imgs || swiperList).map((img, idx) => (
{info.imgs.map((img, idx) => (
<SwiperItem key={`swiperitem__${idx}`}> <SwiperItem key={`swiperitem__${idx}`}>
<SpImage <SpImage
mode='aspectFill' mode='aspectFill'
src={img} src={img}
width={windowWidth * 2} width={windowWidth * 2}
height={900} height={windowWidth * 2}
></SpImage> ></SpImage>
{false && ( {false && (
<Video <Video
@ -641,26 +718,42 @@ function EspierDetail (props) {
{/* Sku选择器列表 */} {/* Sku选择器列表 */}
{/* Sku选择器 */} {/* Sku选择器 */}
<MSpSkuSelect <MSpSkuSelect
ref={skuSelectRef}
open={skuPanelOpen} open={skuPanelOpen}
type={selectType} type={selectType}
info={info} info={info}
hideInputNumber hideInputNumber
onChangeImg={onChangeImg}
onClose={() => { onClose={() => {
setState((draft) => { setState((draft) => {
draft.skuPanelOpen = false draft.skuPanelOpen = false
}) })
}} }}
onChange={(skuText, curItem) => { onChange={(skuText, curItem, idx) => {
console.log("🚀 ~ curItem:", curItem, idx)
setState((draft) => { setState((draft) => {
draft.skuText = skuText draft.skuText = skuText
draft.curItem = curItem draft.curItem = curItem
// 不切换顶部轮播图
// draft.swiperList = curItem?.specItem?.[idx]?.specImgs
draft.selSkuImg = curItem.specItem?.[0]?.specImgs?.[0]
}) })
}} }}
/> />
<View className='goods-desc'> <View className='goods-desc'>
<View className='desc-hd'> <View className='desc-hd'>
<Text className='desc-title'>宝贝详情</Text> <SpImage
className='sku-image'
src={selSkuImg || info?.specItem?.[0]?.specImgs?.[0]}
width={160}
height={160}
mode='aspectFit'
/>
<View className='desc-title'>
<Text className='desc-title-txt'>{info?.itemName}</Text>
<SpGoodsPrice info={curItem ? curItem : info} />
</View>
</View> </View>
{isArray(info.intro) ? ( {isArray(info.intro) ? (
<View> <View>
@ -676,10 +769,59 @@ function EspierDetail (props) {
))} ))}
</View> </View>
) : ( ) : (
<SpHtml content={info.intro} /> <>
{/* <SpHtml content={info.intro} /> */}
</>
)} )}
{introList.length ? introList.map((item, index) => <View className={classNames('sp-accordion')} key={`item__${index}`}>
<AtAccordion
open={item.isOpen}
isAnimation={false}
onClick={() => {
setState((draft) => {
// draft.introList[index].isOpen = !draft.introList[index].isOpen
draft.introList = draft.introList.map((v, i) => {
v.isOpen = (i === index)
return v
})
})
}}
title={item.title}
>
<SpHtml content={item.content} />
</AtAccordion>
<View onClick={() => {
setState((draft) => {
// draft.introList[index].isOpen = !draft.introList[index].isOpen
draft.introList = draft.introList.map((v, i) => {
v.isOpen = (i === index)
return v
})
})
}}>
{item.isOpen ? <AtIcon value='subtract' size='16' color='#000' /> :
<AtIcon value='add' size='16' color='#000' />}
{item.isOpen ? <></> : <View className="line"></View>}
</View>
</View>) : <View style={{ height: `calc(100% - 380px)` }}></View>}
{historyList.length && <View className='bottom-box'>
<View className="bottom-box-tit">浏览历史</View>
<ScrollView scrollX scrollWithAnimation showScrollbar={true} scrollLeft={0} className="shop-box">
{historyList.map((item, idx) => (
<View className='goods-item-wrap' key={`goods-item-l__${idx}`}>
<SpGoodsItem
showSalePrice={false}
height={250}
width={250}
onStoreClick={handleClickStore}
info={item}
/>
</View>
))}
</ScrollView>
</View>}
</View> </View>
</View> </ScrollView>
)} )}
<SpRecommend info={recommendList} /> <SpRecommend info={recommendList} />

View File

@ -3,7 +3,7 @@
position: relative; position: relative;
} }
.goods-swiper { .goods-swiper {
height: 900px; // height: 900px;
} }
.video-container { .video-container {
position: absolute; position: absolute;
@ -71,8 +71,9 @@
opacity: 0.5; opacity: 0.5;
} }
.goods-contents { .goods-contents {
height: calc(100vh - #{$page-ipx-footer-height} - var(--nav-height));
.goods-info { .goods-info {
margin: 24px 30px; margin: 20px 30px 10px;
background-color: #fff; background-color: #fff;
// padding: 20px 16px; // padding: 20px 16px;
// box-shadow: 0px 2px 10px 0px #eae7e0; // box-shadow: 0px 2px 10px 0px #eae7e0;
@ -86,16 +87,65 @@
color: #999; color: #999;
} }
} }
.goods-desc { .good-sku {
margin: 24px 16px; margin: 40px 30px;
background-color: #fff; box-sizing: border-box;
box-shadow: 0px 2px 10px 0px #eae7e0; .sku-img {
.desc-hd { white-space: nowrap;
height: 80px; width: 100%;
text-align: center; &-item {
line-height: 80px; width: 130px;
margin-right: 20px;
display: inline-block;
&:last-child {
margin-right: 0;
}
.sp-image {
width: 100%;
height: 100%;
}
}
} }
.desc-title { }
.goods-desc {
background-color: #fff;
// padding: 0 30px;
// box-shadow: 0px 2px 10px 0px #eae7e0;
height: calc(100vh - #{$page-ipx-footer-height} - var(--nav-height));
// padding-bottom: calc(#{$page-ipx-footer-height} + 30px);
box-sizing: border-box;
position: relative;
overflow-y: scroll;
&::-webkit-scrollbar {
width: 0px;
height: 0px;
}
.desc-hd {
height: 160px;
padding: 20px 30px 0;
display: flex;
align-items: center;
border-bottom: 1px solid #9e9e9e80;
position: sticky;
z-index: 2;
top: 0px;
left: 0;
right: 0;
padding-bottom: 2px;
background-color: #fff;
.desc-title {
font-size: 26px;
height: 160px;
display: flex;
align-items: flex-start;
justify-content: space-between;
flex-direction: column;
flex: 1;
padding: 24px 50px;
box-sizing: border-box;
}
}
.desc-title-no {
color: #222; color: #222;
position: relative; position: relative;
&:before { &:before {
@ -119,6 +169,80 @@
right: -24px; right: -24px;
} }
} }
.sp-accordion {
position: relative;
// padding: ;
.at-accordion__header {
padding: 26px 40px;
color: #000;
&::after {
border: none;
// border-bottom: 1px solid #9e9e9e80;
}
.at-accordion__info__title {
font-size: 26px;
}
.at-accordion__arrow {
display: none;
}
}
.at-accordion__content {
&::after {
border: none;
// border-bottom: 1px solid #9e9e9e80;
}
}
.at-accordion__body {
padding: 0 40px;
padding-bottom: 30px;
}
.at-icon {
position: absolute;
z-index: 0;
right: 40px;
top: 48px;
transform: translateY(-50%);
transition: all 0.2s ease-in-out;
}
.line {
display: block;
position: absolute;
width: 100%;
height: 1px;
background: #9e9e9e80;
top: 90px;
right: 0;
left: 0;
transition: all 0.2s ease-in-out;
}
}
.bottom-box {
border-top: 1px solid #9e9e9e80;
&-tit {
font-size: 30px;
color: #000;
padding-left: 44px;
padding-top: 50px;
font-weight: 500;
}
}
.shop-box {
height: 466px;
width: 100%;
padding: 30px 50px 40px;
box-sizing: border-box;
transition: height 0.2s linear 0.2s;
white-space: nowrap;
.goods-item-wrap {
display: inline-block;
width: 250px;
height: 100%;
margin-right: 30px;
&:last-child {
margin-right: 0;
}
}
}
} }
} }
.goods-name { .goods-name {

View File

@ -1,3 +1,3 @@
export default { export default {
navigationBarTitleText: '搜索结果' navigationBarTitleText: '搜索列表'
} }

View File

@ -151,7 +151,6 @@ function ItemList () {
const fetch = async ({ pageIndex, pageSize }) => { const fetch = async ({ pageIndex, pageSize }) => {
// card_id: 兑换券id // card_id: 兑换券id
// const { cat_id, main_cat_id, tag_id, card_id } = $instance.router.params // const { cat_id, main_cat_id, tag_id, card_id } = $instance.router.params
console.log(shopInfo)
let params = { let params = {
page: pageIndex, page: pageIndex,
pageSize, pageSize,
@ -161,19 +160,23 @@ function ItemList () {
item_type: 'normal', item_type: 'normal',
is_point: 'false', is_point: 'false',
tag_id, tag_id,
card_id card_id,
goodsSort: 6
} }
if (curFilterIdx == 1) { if (curFilterIdx) {
// 销量 params['goodsSort'] = curFilterIdx
params['goodsSort'] = 1
} else if (curFilterIdx == 2) {
// 价格升序
params['goodsSort'] = 3
} else if (curFilterIdx == 3) {
// 价格降序
params['goodsSort'] = 2
} }
// if (curFilterIdx == 1) {
// // 销量
// params['goodsSort'] = 1
// } else if (curFilterIdx == 2) {
// // 价格升序
// params['goodsSort'] = 3
// } else if (curFilterIdx == 3) {
// // 价格降序
// params['goodsSort'] = 2
// }
if (curTagIdx) { if (curTagIdx) {
params['tag_id'] = curTagIdx params['tag_id'] = curTagIdx
@ -200,6 +203,7 @@ function ItemList () {
brand_list brand_list
} = await api.item.search(params) } = await api.item.search(params)
console.time('list render') console.time('list render')
console.log('fetch list:', list)
const n_list = pickBy(list, doc.goods.ITEM_LIST_GOODS) const n_list = pickBy(list, doc.goods.ITEM_LIST_GOODS)
const resLeftList = n_list.filter((item, index) => { const resLeftList = n_list.filter((item, index) => {
if (index % 2 == 0) { if (index % 2 == 0) {
@ -282,7 +286,7 @@ function ItemList () {
} }
const handleFilterChange = async (e) => { const handleFilterChange = async (e) => {
await setState((draft) => { setState((draft) => {
draft.leftList = [] draft.leftList = []
draft.rightList = [] draft.rightList = []
draft.curFilterIdx = e.current || 0 draft.curFilterIdx = e.current || 0
@ -315,8 +319,9 @@ function ItemList () {
goodsRef.current.reset() goodsRef.current.reset()
} }
const handleClickStore = (item) => { const handleClickStore = (item, idx) => {
const url = `/subpages/store/index?id=${item.distributor_info.distributor_id}` // console.log("🚀 ~ item, idx:", item, idx)
const url = `/subpages/store/index?id=${item.distributor_info?.distributor_id}&idx=${idx}`
Taro.navigateTo({ Taro.navigateTo({
url url
}) })
@ -329,7 +334,9 @@ function ItemList () {
'has-tagbar': tagList.length > 0 'has-tagbar': tagList.length > 0
})} })}
> >
<View className='search-wrap'> <View className='search-wrap' style={{
'zIndex': isShowSearch ? 999 : 8
}}>
{/* 兑换券选择店铺 */} {/* 兑换券选择店铺 */}
{VERSION_STANDARD && card_id && ( {VERSION_STANDARD && card_id && (
<View <View
@ -345,8 +352,10 @@ function ItemList () {
</View> </View>
)} )}
<SpSearchBar <SpSearchBar
className='search-wrap'
keyword={keywords} keyword={keywords}
placeholder='搜索商品' placeholder='搜索商品'
isOpened={true}
onFocus={handleOnFocus} onFocus={handleOnFocus}
onChange={handleOnChange} onChange={handleOnChange}
onClear={handleOnClear} onClear={handleOnClear}

View File

@ -25,7 +25,7 @@
right: 0; right: 0;
top: 0; top: 0;
background: #fff; background: #fff;
z-index: 10; z-index: 8;
display: flex; display: flex;
align-items: center; align-items: center;
.store-picker { .store-picker {
@ -41,6 +41,11 @@
} }
} }
.sp-filter-bar { .sp-filter-bar {
position: fixed;
top: 260px;
z-index: 8;
left: 0;
right: 0;
&__item { &__item {
background: #f5f5f5; background: #f5f5f5;
&:first-child { &:first-child {
@ -62,9 +67,13 @@
.item-list-scroll { .item-list-scroll {
// @include page-scroll($tabs-height + $navigate-height + 10, 0); // @include page-scroll($tabs-height + $navigate-height + 10, 0);
@include page-scroll($tabs-height + $navigate-height + 168, $edge-margin);
// /* #ifdef h5 */ // /* #ifdef h5 */
// @include page-scroll($searchbar-height + $navigate-height + 16 * 2 + $tabs-height + 10, 0); // @include page-scroll($searchbar-height + $navigate-height + 16 * 2 + $tabs-height + 10, 0);
// /* #endif */ // /* #endif */
.sp-note {
margin-bottom: 50px;
}
} }
.filter-btn { .filter-btn {
font-size: 28px; font-size: 28px;
@ -90,7 +99,7 @@
.goods-list { .goods-list {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
padding: 30px 50px 50px; padding: 0px 50px;
.goods-list-wrap { .goods-list-wrap {
// width: 345px; // width: 345px;
margin-bottom: 28px; margin-bottom: 28px;

View File

@ -111,6 +111,7 @@ export default class ItemFav extends Component {
item_type: 'item_type', item_type: 'item_type',
distributor_id: 'distributor_id', distributor_id: 'distributor_id',
point: 'point', point: 'point',
fav_num: 'fav_num',
// price: ({ price }) => (price/100).toFixed(2), // price: ({ price }) => (price/100).toFixed(2),
price: ({ price, item_price }) => ((price || item_price) / 100).toFixed(2), price: ({ price, item_price }) => ((price || item_price) / 100).toFixed(2),
// is_fav: ({ item_id }) => this.hasFav(item_id) // is_fav: ({ item_id }) => this.hasFav(item_id)
@ -128,7 +129,8 @@ export default class ItemFav extends Component {
summary: 'summary', summary: 'summary',
head_portrait: 'head_portrait', head_portrait: 'head_portrait',
author: 'author', author: 'author',
item_type: 'item_type' item_type: 'item_type',
fav_num: 'fav_num',
}) })
total = res.total_count total = res.total_count
break break
@ -353,8 +355,9 @@ export default class ItemFav extends Component {
})} })}
</View> </View>
)} )}
{page.isLoading ? <Loading>正在加载...</Loading> : null} {/* {page.isLoading ? <Loading>正在加载...</Loading> : null} */}
{!page.isLoading && !page.hasNext && !list.length && ( {/* !page.isLoading && */}
{!page.hasNext && !list.length && (
<SpNote img='trades_empty.png'>暂无数据~</SpNote> <SpNote img='trades_empty.png'>暂无数据~</SpNote>
)} )}
</ScrollView> </ScrollView>

View File

@ -36,6 +36,15 @@
width: 40px; width: 40px;
height: 42px; height: 42px;
} }
.icon-delete,
.icon-share {
&::before {
content: ' ';
display: block;
width: 18px;
height: 18px;
}
}
.icon-share .option__text { .icon-share .option__text {
background: url('../../assets/fenxiang-icon.png') no-repeat; background: url('../../assets/fenxiang-icon.png') no-repeat;
background-size: 100% 100%; background-size: 100% 100%;

View File

@ -1,3 +1,3 @@
export default { export default {
navigationBarTitleText: '文章' navigationBarTitleText: ''
} }

View File

@ -48,7 +48,7 @@ export default class RecommendList extends Component {
} }
} }
componentDidMount() { componentDidMount () {
api.wx.shareSetting({ shareindex: 'planting' }).then((res) => { api.wx.shareSetting({ shareindex: 'planting' }).then((res) => {
this.setState({ this.setState({
shareInfo: res shareInfo: res
@ -56,7 +56,7 @@ export default class RecommendList extends Component {
}) })
} }
componentDidShow() { componentDidShow () {
const params = this.$instance.router.params const params = this.$instance.router.params
if (params) { if (params) {
const { id, name } = params const { id, name } = params
@ -81,7 +81,7 @@ export default class RecommendList extends Component {
// this.praiseNum() // this.praiseNum()
} }
onShareAppMessage() { onShareAppMessage () {
const res = this.state.shareInfo const res = this.state.shareInfo
const { userId } = Taro.getStorageSync('userinfo') const { userId } = Taro.getStorageSync('userinfo')
const query = userId ? `/pages/recommend/list?uid=${userId}` : '/pages/recommend/list' const query = userId ? `/pages/recommend/list?uid=${userId}` : '/pages/recommend/list'
@ -92,7 +92,7 @@ export default class RecommendList extends Component {
} }
} }
onShareTimeline() { onShareTimeline () {
const res = this.state.shareInfo const res = this.state.shareInfo
const { userId } = Taro.getStorageSync('userinfo') const { userId } = Taro.getStorageSync('userinfo')
const query = userId ? `uid=${userId}` : '' const query = userId ? `uid=${userId}` : ''
@ -103,7 +103,7 @@ export default class RecommendList extends Component {
} }
} }
async fetch(params) { async fetch (params) {
const { page_no: page, page_size: pageSize } = params const { page_no: page, page_size: pageSize } = params
const { columnList, areaList } = this.state const { columnList, areaList } = this.state
let { selectColumn } = this.state let { selectColumn } = this.state
@ -349,11 +349,11 @@ export default class RecommendList extends Component {
}) })
this.setState({ this.setState({
paramsList, paramsList,
selectParams, selectParams,
}) })
this.resetColumn() this.resetColumn()
} }
this.resetPage() this.resetPage()
this.setState( this.setState(
{ {
@ -365,15 +365,15 @@ export default class RecommendList extends Component {
) )
} }
resetColumn(){ resetColumn () {
this.setState({ this.setState({
selectColumn : Object.assign({}, { id: '', name: '全部', isChooseColumn: true }), selectColumn: Object.assign({}, { id: '', name: '全部', isChooseColumn: true }),
columnList : this.state.columnList.map((d,idx)=>{ columnList: this.state.columnList.map((d, idx) => {
d.isChooseColumn = idx == 0 ? true : false d.isChooseColumn = idx == 0 ? true : false
return d return d
}) })
}) })
} }
// 选定开户地区 // 选定开户地区
handleClickPicker = () => { handleClickPicker = () => {
@ -529,7 +529,7 @@ export default class RecommendList extends Component {
}) })
} }
render() { render () {
const { const {
list, list,
showBackToTop, showBackToTop,
@ -549,7 +549,7 @@ export default class RecommendList extends Component {
let address = info.province + info.city let address = info.province + info.city
return ( return (
<SpPage renderFooter={<SpTabbar />}> <SpPage renderFooter={<SpTabbar />} className='has-nav' title="鞋床故事">
<View className='page-recommend-list'> <View className='page-recommend-list'>
<View className='recommend-list__toolbar'> <View className='recommend-list__toolbar'>
<View <View
@ -593,9 +593,9 @@ export default class RecommendList extends Component {
{address ? ( {address ? (
<View <View
className='zoom-btn icon-close iconfont' className='zoom-btn icon-close iconfont'
onClick={this.handleRegionRefresh.bind(this)} onClick={this.handleRegionRefresh.bind(this)}
></View> ></View>
// <Text className='icon-close' onClick={this.handleRegionRefresh.bind(this)}>x</Text> // <Text className='icon-close' onClick={this.handleRegionRefresh.bind(this)}>x</Text>
) : ( ) : (
'' ''

View File

@ -1,8 +1,10 @@
@import "../../style/imports"; @import '../../style/imports';
.loading {
margin-top: 60px;
}
.page-recommend-list { .page-recommend-list {
/* #ifdef alipay */ /* #ifdef alipay */
.filter-bar{ .filter-bar {
position: absolute; position: absolute;
width: 100%; width: 100%;
z-index: 9999; z-index: 9999;
@ -12,14 +14,14 @@
.recommend-list { .recommend-list {
&__toolbar { &__toolbar {
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
width: 100%; width: 100%;
z-index: $z-index-level-4; z-index: $z-index-level-4;
background: #fff; background: #fff;
box-shadow: $box-shadow; box-shadow: $box-shadow;
padding-top: 10px; padding-top: 10px;
.icon-periscope{ .icon-periscope {
color: #ccc; color: #ccc;
display: inline-block; display: inline-block;
} }
@ -31,7 +33,7 @@
/* #ifdef alipay */ /* #ifdef alipay */
padding: 20px 0; padding: 20px 0;
/* #endif */ /* #endif */
&__focus{ &__focus {
.at-search-bar { .at-search-bar {
padding-right: 30px !important; padding-right: 30px !important;
} }
@ -65,32 +67,36 @@
} }
&__tabs { &__tabs {
display: flex; display: flex;
.filter-bar__item { .filter-bar__item {
flex: 1; flex: 1;
justify-content: center; justify-content: center;
text-align: center; text-align: center;
color: #666666; color: #666666;
font-size: 26px; font-size: 26px;
.icon-menu,.icon-periscope { .icon-menu,
.icon-periscope {
color: #ccc; color: #ccc;
display: inline-block; display: inline-block;
font-size: 28px; font-size: 28px;
} }
&.region-picker{ &.region-picker {
display: flex; display: flex;
line-height: 75rpx; line-height: 75rpx;
} }
.icon-close{ .icon-close {
line-height: 75px; line-height: 75px;
} }
} }
.filter-bar__item-active { .filter-bar__item-active {
color: $color-brand-primary; color: $color-brand-primary;
} }
} }
&__scroll { &__scroll {
@include page-scroll($tabs-height + $searchbar-height + $navigate-height + 10, $tabbar-height + floor($edge-margin / 2)); @include page-scroll(
$tabs-height + $searchbar-height + $navigate-height + 10,
$tabbar-height + floor($edge-margin / 2)
);
top: 155px; top: 155px;
} }
&__type-grid { &__type-grid {
@ -163,16 +169,16 @@
} }
} }
} }
.region-picker{ .region-picker {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
line-height: 75rpx; line-height: 75rpx;
.icon-close{ .icon-close {
margin-left: 10px; margin-left: 10px;
line-height: 75px; line-height: 75px;
} }
} }
.sp-float-layout { .sp-float-layout {
.icon-guanbi { .icon-guanbi {
line-height: 1; line-height: 1;

View File

@ -63,7 +63,7 @@ export default class DetailItem extends Component {
copyText(val) copyText(val)
S.toast('复制成功') S.toast('复制成功')
} }
handleSelectionChange(item_id, checked) { handleSelectionChange (item_id, checked) {
//选择要申请售后的商品 //选择要申请售后的商品
const { info } = this.props const { info } = this.props
info.orders.map((item) => { info.orders.map((item) => {
@ -73,7 +73,7 @@ export default class DetailItem extends Component {
info info
}) })
} }
handleQuantityChange(item, val) { handleQuantityChange (item, val) {
//改变售后商品的数量 //改变售后商品的数量
const { info } = this.props const { info } = this.props
info.orders.map((v) => { info.orders.map((v) => {
@ -84,16 +84,16 @@ export default class DetailItem extends Component {
}) })
} }
render() { render () {
const { customFooter, info, isPointitem, showType } = this.props const { customFooter, info, isPointitem, showType } = this.props
return ( return (
<View className='detail-item' style={styleNames(getThemeStyle())}> <View className='detail-item' style={styleNames(getThemeStyle())}>
<Text className='detail-item__title'>商品信息</Text>
{info && {info &&
info[showType] && info[showType] &&
info[showType].map((item, idx) => ( info[showType].map((item, idx) => (
<View className='detail-item-good' key={`${idx}1`}> <View className='detail-item-good' key={`${idx}1`}>
<View className='detail-item__fix'> <View className='detail-item__fix'>
<Text className='detail-item__title'>{idx + 1}件商品</Text>
{info.delivery_code ? null : item.delivery_code ? ( {info.delivery_code ? null : item.delivery_code ? (
<View className='detail-item__code'> <View className='detail-item__code'>
<Text className='code'>物流单号{item.delivery_code}</Text> <Text className='code'>物流单号{item.delivery_code}</Text>
@ -112,7 +112,7 @@ export default class DetailItem extends Component {
isShowNational isShowNational
isPointitemGood={isPointitem} isPointitemGood={isPointitem}
onClick={() => { onClick={() => {
if(info.order_class == 'pointsmall') { if (info.order_class == 'pointsmall') {
Taro.navigateTo({ Taro.navigateTo({
url: `/subpages/pointshop/espier-detail?id=${item.good_id}` url: `/subpages/pointshop/espier-detail?id=${item.good_id}`
}) })
@ -131,16 +131,16 @@ export default class DetailItem extends Component {
(info.delivery_code (info.delivery_code
? null ? null
: item.delivery_code && ( : item.delivery_code && (
<AtButton <AtButton
circle circle
type='text' type='text'
size='small' size='small'
className='delivery-btn' className='delivery-btn'
onClick={this.handleLookDelivery.bind(this, item)} onClick={this.handleLookDelivery.bind(this, item)}
> >
查看物流 查看物流
</AtButton> </AtButton>
))} ))}
{item.show_aftersales === 1 && ( {item.show_aftersales === 1 && (
<AtButton <AtButton
circle circle

View File

@ -5,11 +5,11 @@
&-good { &-good {
position: relative; position: relative;
} }
&__fix { // &__fix {
display: flex; // display: flex;
border-bottom: 1px solid #ececec; // border-bottom: 1px solid #ececec;
padding: 0 38px 0 27px; // padding: 0 38px 0 27px;
} // }
&__title { &__title {
flex: 0 0 200px 0; flex: 0 0 200px 0;
@ -21,7 +21,7 @@
} }
&__title { &__title {
display: block; display: block;
font-size: 22px; font-size: 26px;
line-height: 36px; line-height: 36px;
color: #333333; color: #333333;
padding: 0 38px 17px 17px; padding: 0 38px 17px 17px;

View File

@ -1,16 +1,16 @@
@import "@/style/imports"; @import '@/style/imports';
.trade-item { .trade-item {
background: #fff; background: #fff;
border-radius: $item-border-radius; border-radius: $item-border-radius;
padding:24px 0 32px 0; padding: 24px 0 32px 0;
margin:0 16px; margin: 0 16px;
margin-bottom: 24px; margin-bottom: 24px;
box-shadow: 0px 2px 10px 0px #EAE7E0; // box-shadow: 0px 2px 10px 0px #EAE7E0;
.icon-globe { .icon-globe {
font-size: 32px; font-size: 32px;
margin-right: 10px; margin-right: 10px;
} }
&__total { &__total {
padding: 0 $edge-size floor($edge-size/2); padding: 0 $edge-size floor($edge-size/2);
@ -18,27 +18,25 @@
} }
&__bd { &__bd {
padding:0 16px; padding: 0 16px;
} }
&__hd { &__hd {
padding:24px 16px; padding: 24px 16px;
line-height: 1.4; line-height: 1.4;
border-bottom: 1px solid #e4e4e4; border-bottom: 1px solid #e4e4e4;
color: #a6a6a6; color: #a6a6a6;
.item{ .item {
font-weight: 400; font-weight: 400;
font-size: 24px; font-size: 24px;
} }
.lineone{ .lineone {
color: #333333; color: #333333;
} }
.linetwo{ .linetwo {
color: #999999; color: #999999;
} }
} }
&__total { &__total {
padding: 20px 24px; padding: 20px 24px;

View File

@ -22,54 +22,57 @@ export default class TradeItem extends Component {
info: {}, info: {},
rateStatus: false, rateStatus: false,
isShowDistributorInfo: true, isShowDistributorInfo: true,
onClickBtn: () => {}, onClickBtn: () => { },
onClick: () => {} onClick: () => { }
} }
static options = { static options = {
addGlobalClass: true addGlobalClass: true
} }
handleClickBtn(type) { handleClickBtn (type) {
const { info } = this.props const { info } = this.props
this.props.onClickBtn && this.props.onClickBtn(type, info) this.props.onClickBtn && this.props.onClickBtn(type, info)
} }
computeTotalPrice() { computeTotalPrice () {
let total let total
const { const {
info: { point, order_class, freight_fee, freight_type, total_fee, payment, receipt_type }, info: { totalItems, point, order_class, freight_fee, freight_type, total_fee, payment, receipt_type },
payType, payType,
pointName pointName
} = this.props } = this.props
const [int, decimal] = String(payment || '').split('.')
if (order_class === 'pointsmall') { if (order_class === 'pointsmall') {
if (freight_type === 'point' || (freight_type === 'cash' && freight_fee == 0)) { if (freight_type === 'point' || (freight_type === 'cash' && freight_fee == 0)) {
total = `计:${point} ${pointName}` total = `计:${point} ${pointName}`
} else if (freight_type === 'cash' && freight_fee != 0) { } else if (freight_type === 'cash' && freight_fee != 0) {
total = `计:${point} ${pointName} + ¥${formatPriceToHundred(freight_fee)}` total = `计:${point} ${pointName} + ¥${formatPriceToHundred(freight_fee)}`
} }
} else { } else {
if (payType === 'dhpoint') { if (payType === 'dhpoint') {
total = `计:${total_fee}${pointName}` total = `计:${total_fee}${pointName}`
} else { } else {
total = `合计:¥${payment}` total = `总计:¥ ${parseInt(int).toLocaleString() + (decimal ? '.' + decimal : '')}`
} }
} }
return ( return (
<View className={`trade-item__total ${receipt_type === 'dada' && 'dadaTotal'}`}> <View className={`trade-item__total ${receipt_type === 'dada' ? 'dadaTotal' : ''}`}>
{receipt_type === 'dada' && ( {receipt_type === 'dada' && (
<View className='dada'> <View className='dada'>
<Text className='iconfont icon-peisongxiangguan'></Text> <Text className='iconfont icon-peisongxiangguan'></Text>
达达同城配送 达达同城配送
</View> </View>
)} )}
{total} <Text className="total-txt">{totalItems}件商品</Text>
{/* {total} */}
<Text className="total-txt" style={{ marginRight: '2rpx' }}>总计</Text>
<Text className='total-price'>{`${parseInt(int).toLocaleString() + (decimal ? '.' + decimal : '')}`}</Text>
</View> </View>
) )
} }
render() { render () {
const { const {
customFooter, customFooter,
onClick, onClick,
@ -95,7 +98,7 @@ export default class TradeItem extends Component {
)} )}
<View className='trade-item__msg'> <View className='trade-item__msg'>
<View className='item lineone'>订单编号{info.tid}</View> <View className='item lineone'>订单编号{info.tid}</View>
<View className='item linetwo'>单时间{info.create_date}</View> <View className='item linetwo'>单时间{info.create_date}</View>
</View> </View>
<View className='trade-item__bd' onClick={onClick}> <View className='trade-item__bd' onClick={onClick}>
{info && {info &&
@ -118,9 +121,9 @@ export default class TradeItem extends Component {
<View className='trade-item__ft-bd'> <View className='trade-item__ft-bd'>
<Text className='trade-item__status'>{info.status_desc}</Text> <Text className='trade-item__status'>{info.status_desc}</Text>
{(info.order_status_des === 'PAYED' || info.order_status_des === 'NOTPAY') && {(info.order_status_des === 'PAYED' || info.order_status_des === 'NOTPAY') &&
!info.is_logistics && !info.is_logistics &&
info.can_apply_cancel != 0 && info.can_apply_cancel != 0 &&
(info.receipt_type !== 'dada' || (info.dada && info.dada.dada_status === 0)) ? ( (info.receipt_type !== 'dada' || (info.dada && info.dada.dada_status === 0)) ? (
<Button <Button
className='btn-action' className='btn-action'
style={`box-shadow: 0 0 0 1PX ${colors.data[0].primary}; color: ${colors.data[0].primary}`} style={`box-shadow: 0 0 0 1PX ${colors.data[0].primary}; color: ${colors.data[0].primary}`}
@ -134,7 +137,7 @@ export default class TradeItem extends Component {
style={`background: ${colors.data[0].primary}`} style={`background: ${colors.data[0].primary}`}
onClick={this.handleClickBtn.bind(this, 'pay')} onClick={this.handleClickBtn.bind(this, 'pay')}
> >
立即支付 支付
</Button> </Button>
</View> </View>
</View> </View>
@ -145,9 +148,9 @@ export default class TradeItem extends Component {
<View className='trade-item__ft-bd'> <View className='trade-item__ft-bd'>
<Text className='trade-item__status'>{info.status_desc}</Text> <Text className='trade-item__status'>{info.status_desc}</Text>
{(info.order_status_des === 'PAYED' || info.order_status_des === 'NOTPAY') && {(info.order_status_des === 'PAYED' || info.order_status_des === 'NOTPAY') &&
info.can_apply_cancel != 0 && info.can_apply_cancel != 0 &&
!info.is_logistics && !info.is_logistics &&
(info.receipt_type !== 'dada' || (info.dada && info.dada.dada_status === 0)) ? ( (info.receipt_type !== 'dada' || (info.dada && info.dada.dada_status === 0)) ? (
<Button <Button
className='btn-action' className='btn-action'
style={`box-shadow: 0 0 0 1PX ${colors.data[0].primary}; color: ${colors.data[0].primary}`} style={`box-shadow: 0 0 0 1PX ${colors.data[0].primary}; color: ${colors.data[0].primary}`}

View File

@ -1,12 +1,12 @@
@import '@/style/imports'; @import '@/style/imports';
.trade-item { .trade-item {
background: #fff; border-radius: 6px;
border-radius: $item-border-radius; padding: 30px 26px 32px 20px;
padding: 24px 0 32px 0; margin: 0 22px;
margin: 0 16px;
margin-bottom: 24px; margin-bottom: 24px;
box-shadow: 0px 2px 10px 0px #eae7e0; background: #f7f7f7;
// box-shadow: 0px 2px 10px 0px #eae7e0;
.icon-globe { .icon-globe {
font-size: 32px; font-size: 32px;
@ -29,7 +29,14 @@
} }
} }
&__bd { &__bd {
padding: 0 16px; // padding: 0 16px;
.sp-order-item {
padding: 0;
margin-bottom: 10px;
&:last-of-type {
margin-bottom: 0;
}
}
} }
&__dist { &__dist {
margin-bottom: 24px; margin-bottom: 24px;
@ -39,7 +46,7 @@
margin-top: 0px; margin-top: 0px;
.item { .item {
font-weight: 400; font-weight: 400;
font-size: 24px; font-size: 20px;
} }
.lineone { .lineone {
color: #333333; color: #333333;
@ -49,8 +56,23 @@
} }
} }
&__total { &__total {
padding: 0 $edge-size floor($edge-size/2); // padding: 0 $edge-size floor($edge-size/2);
text-align: right; text-align: right;
color: #000;
font-size: 32px;
display: flex;
align-items: baseline !important;
padding: 0 !important;
margin-top: -14px;
.total-txt {
font-size: 20px;
color: #000;
opacity: 0.85;
margin-right: 10px;
}
.total-price {
font-size: 32px;
}
} }
&__hd { &__hd {
@ -106,9 +128,19 @@
/* #ifdef h5 */ /* #ifdef h5 */
button { button {
border: none; border: none;
margin-left: 15px; margin-left: 10px;
} }
/* #endif */ /* #endif */
.btn-action {
margin-left: 10px;
padding: 15px 20px;
line-height: 1;
border-radius: 6px;
font-size: 20px;
&::after {
border: none;
}
}
} }
} }
&__status { &__status {

View File

@ -1 +1,4 @@
export default {} export default {
navigationBarTitleText: '订单详情',
navigationStyle: 'custom',
}

View File

@ -3,7 +3,7 @@ import Taro, { getCurrentInstance } from '@tarojs/taro'
import { View, Text, Button, Image, ScrollView } from '@tarojs/components' import { View, Text, Button, Image, ScrollView } from '@tarojs/components'
import { connect } from 'react-redux' import { connect } from 'react-redux'
import { AtCountdown } from 'taro-ui' import { AtCountdown } from 'taro-ui'
import { Loading, SpNavBar, FloatMenuMeiQia, SpNewShopItem } from '@/components' import { Loading, SpNavBar, FloatMenuMeiQia, SpNewShopItem, SpPage, SpPrice } from '@/components'
import { import {
log, log,
pickBy, pickBy,
@ -88,20 +88,20 @@ export default class TradeDetail extends Component {
} }
} }
componentWillUnmount() { componentWillUnmount () {
clearInterval(this.state.interval) clearInterval(this.state.interval)
} }
componentDidShow() { componentDidShow () {
this.fetch() this.fetch()
} }
isPointitemGood() { isPointitemGood () {
const options = this.$instance.router.params const options = this.$instance.router.params
return options.type === 'pointitem' return options.type === 'pointitem'
} }
calcTimer(totalSec) { calcTimer (totalSec) {
let remainingSec = totalSec let remainingSec = totalSec
const dd = Math.floor(totalSec / 24 / 3600) const dd = Math.floor(totalSec / 24 / 3600)
remainingSec -= dd * 3600 * 24 remainingSec -= dd * 3600 * 24
@ -119,7 +119,7 @@ export default class TradeDetail extends Component {
} }
} }
async fetch() { async fetch () {
const { id } = this.$instance.router.params const { id } = this.$instance.router.params
const data = await api.trade.detail(id) const data = await api.trade.detail(id)
let sessionFrom = '' let sessionFrom = ''
@ -305,7 +305,7 @@ export default class TradeDetail extends Component {
await copyText(msg) await copyText(msg)
} }
async handlePay() { async handlePay () {
const { info } = this.state const { info } = this.state
// this.setState({ // this.setState({
@ -404,7 +404,7 @@ export default class TradeDetail extends Component {
// } // }
} }
async handleClickBtn(type, e) { async handleClickBtn (type, e) {
e.stopPropagation() e.stopPropagation()
const { info } = this.state const { info } = this.state
if (type === 'home') { if (type === 'home') {
@ -464,7 +464,7 @@ export default class TradeDetail extends Component {
} }
} }
async handleClickRefund(type, item_id) { async handleClickRefund (type, item_id) {
const { const {
info: { tid: order_id } info: { tid: order_id }
} = this.state } = this.state
@ -655,7 +655,7 @@ export default class TradeDetail extends Component {
// } // }
} }
render() { render () {
const { colors } = this.props const { colors } = this.props
const { const {
info, info,
@ -695,14 +695,16 @@ export default class TradeDetail extends Component {
const { market_price: enMarketPrice } = order_page const { market_price: enMarketPrice } = order_page
return ( return (
<View <SpPage
isBlack
className={classNames('page-trade-detail trade-detail', { className={classNames('page-trade-detail trade-detail', {
'islog': info.is_logistics, 'islog': info.is_logistics,
'trade-close': info.status == 'TRADE_CLOSED', 'trade-close': info.status == 'TRADE_CLOSED',
'has-navbar': isNavbar() 'has-navbar': isNavbar()
})} })}
showNavSearchIcon
> >
<SpNavBar title='订单详情' leftIconType='chevron-left' fixed='true' /> {/* <SpNavBar title='订单详情' leftIconType='chevron-left' fixed='true' /> */}
{info.is_logistics && ( {info.is_logistics && (
<View className='custabs'> <View className='custabs'>
@ -724,7 +726,7 @@ export default class TradeDetail extends Component {
)} )}
<ScrollView scroll-y className='scroll-view' scrollIntoView={scrollIntoView}> <ScrollView scroll-y className='scroll-view' scrollIntoView={scrollIntoView}>
<View className='trade-detail-header' id='order-0'> {false && <View className='trade-detail-header' id='order-0'>
<View className='trade-detail-waitdeliver'> <View className='trade-detail-waitdeliver'>
{info.is_logistics && <View className='oneline'>线上订单</View>} {info.is_logistics && <View className='oneline'>线上订单</View>}
{info.status === 'WAIT_BUYER_PAY' && ( {info.status === 'WAIT_BUYER_PAY' && (
@ -769,7 +771,7 @@ export default class TradeDetail extends Component {
</View> </View>
)} )}
</View> </View>
</View> </View>}
{info.dada && info.dada.id && info.dada.dada_status > 1 && info.dada.dada_status !== 5 && ( {info.dada && info.dada.id && info.dada.dada_status > 1 && info.dada.dada_status !== 5 && (
<View className='dadaInfo'> <View className='dadaInfo'>
<View className='name'> <View className='name'>
@ -812,7 +814,7 @@ export default class TradeDetail extends Component {
)} )}
</View> </View>
)} )}
<View className='trade-detail-address'> {/* <View className='trade-detail-address'>
{info.dada && info.dada.id && ( {info.dada && info.dada.id && (
<View className={`store ${info.dada && info.dada.id ? 'border' : ''}`}> <View className={`store ${info.dada && info.dada.id ? 'border' : ''}`}>
<Text <Text
@ -876,14 +878,14 @@ export default class TradeDetail extends Component {
</View> </View>
</View> </View>
)} )}
</View> </View> */}
<View className='trade-detail-goods'> <View className='trade-detail-goods'>
{VERSION_PLATFORM && ( {VERSION_PLATFORM && (
<SpNewShopItem info={distributor} canJump inOrderDetail hasLogo={false} /> <SpNewShopItem info={distributor} canJump inOrderDetail hasLogo={false} />
)} )}
<View className='line'> <View className='line'>
<View className='left'>订单</View> <View className='left'>订单编号 </View>
<View className='right'> <View className='right'>
{info.tid} {info.tid}
<Text className='fuzhi' onClick={this.copyOrderId.bind(this, info.tid)}> <Text className='fuzhi' onClick={this.copyOrderId.bind(this, info.tid)}>
@ -891,7 +893,69 @@ export default class TradeDetail extends Component {
</Text> </Text>
</View> </View>
</View> </View>
<View className='line'>
<View className='left'>订单时间 </View>
<View className='right'>
{info.created_time_str}
</View>
</View>
<View className="order_status_msg">{info.order_status_msg}</View>
<View className="address-txt">收货地址</View>
<View className='info-trade'>
<Text className='address-detail'>
{info.receiver_state}
{info.receiver_city}
{info.receiver_district}
{info.receiver_address}
</Text>
<View className='user-info-trade'>
<Text className='receiverName'>{info.receiver_name}</Text>
{!this.isPointitemGood() && <Text>{info.receiver_mobile}</Text>}
</View>
</View>
<>
<View className="address-txt info-trade">
<Text>物流信息</Text>
<Text className='right'>查看详情</Text>
</View>
<View className='address-detail' style={{ marginTop: '4rpx' }}>物流单号{info.receiver_name}</View>
<View className='address-detail'>物流公司{info.receiver_name}</View>
</>
<View className="address-txt info-trade">
<Text>支付方式</Text>
</View>
<View className='address-detail' style={{ marginTop: '4rpx' }}>{isDeposit ? '余额支付' : '微信支付'}</View>
</View>
<View className='trade-detail-box'>
<DetailItem info={info} isPointitem={this.isPointitemGood()} /> <DetailItem info={info} isPointitem={this.isPointitemGood()} />
<View className="gap"></View>
<View className="trade-detail-info-new">
<View className='line'>
<View className='left'>订单金额</View>
<View className='right'>
{transformTextByPoint(this.isPointitemGood(), info.item_fee_new, info.item_point)}
</View>
</View>
<View className='line'>
<View className='left'>优惠金额</View>
{/* 促销 + 优惠券 */}
<View className='right'>{`¥${parseFloat(info.promotion_discount + info.coupon_discount).toFixed(2)}`}</View>
</View>
<View className='line'>
<View className='left'>运费</View>
<View className='right'>
{info.freight_type !== 'point'
? `¥${info.freight_fee}`
: `${info.freight_fee * 100}${this.props.pointName}`}
</View>
</View>
</View>
<View className="gap"></View>
<View className="trade-detail-info-bottom">
<View className='left'>订单总计</View>
<SpPrice className='right' value={info.totalpayment} showSeparator noDecimal={false}></SpPrice>
</View>
</View> </View>
{info.is_logistics && ( {info.is_logistics && (
<View className='logConfirm'> <View className='logConfirm'>
@ -938,7 +1002,7 @@ export default class TradeDetail extends Component {
<Text className='trade-money__num'>{info.totalpayment}</Text> <Text className='trade-money__num'>{info.totalpayment}</Text>
)} )}
</View> */} </View> */}
{!info.is_logistics && {/* {!info.is_logistics &&
info.can_apply_cancel != 0 && info.can_apply_cancel != 0 &&
(info.status === 'WAIT_BUYER_PAY' || (info.status === 'WAIT_BUYER_PAY' ||
(info.status === 'WAIT_SELLER_SEND_GOODS' && (info.status === 'WAIT_SELLER_SEND_GOODS' &&
@ -950,15 +1014,15 @@ export default class TradeDetail extends Component {
取消订单 取消订单
</View> </View>
</View> </View>
)} )} */}
</View> </View>
{info.remark && ( {/* {info.remark && (
<View className='trade-detail-remark'> <View className='trade-detail-remark'>
<View className='trade-detail-remark__header'>订单备注</View> <View className='trade-detail-remark__header'>订单备注</View>
<View className='trade-detail-remark__body'>{info.remark}</View> <View className='trade-detail-remark__body'>{info.remark}</View>
</View> </View>
)} )} */}
<View className='trade-detail-info'> {false && <View className='trade-detail-info'>
<View className='line'> <View className='line'>
<View className='left'>下单时间</View> <View className='left'>下单时间</View>
<View className='right'>{info.created_time_str}</View> <View className='right'>{info.created_time_str}</View>
@ -1085,7 +1149,7 @@ export default class TradeDetail extends Component {
</View> </View>
</View> </View>
)} )}
</View> </View>}
{cancelData.cancel_id && ( {cancelData.cancel_id && (
<View className='cancelData'> <View className='cancelData'>
<View className='title'>取消理由</View> <View className='title'>取消理由</View>
@ -1149,7 +1213,7 @@ export default class TradeDetail extends Component {
? 'trade-detail__footer_allWidthBtn' ? 'trade-detail__footer_allWidthBtn'
: '' : ''
}`} }`}
style={`background: ${colors.data[0].primary}; border-color: ${colors.data[0].primary};`} // style={`background: ${colors.data[0].primary}; border-color: ${colors.data[0].primary};`}
onClick={this.handleClickBtn.bind(this, 'home')} onClick={this.handleClickBtn.bind(this, 'home')}
> >
继续购物 继续购物
@ -1217,7 +1281,7 @@ export default class TradeDetail extends Component {
</View> </View>
</View> </View>
)} )}
</View> </SpPage>
) )
} }
} }

View File

@ -3,7 +3,7 @@ $paddingBottom: 100px;
.page-trade-detail { .page-trade-detail {
box-sizing: border-box; box-sizing: border-box;
height: 100vh; height: 100%;
overflow: hidden; overflow: hidden;
&.paddingBottom { &.paddingBottom {
padding-bottom: $paddingBottom; padding-bottom: $paddingBottom;
@ -26,12 +26,12 @@ $paddingBottom: 100px;
} }
.scroll-view { .scroll-view {
@include page-scroll(0, $tabbar-height); @include page-scroll(var(--nav-height), 140px);
} }
&.has-navbar { &.has-navbar {
.scroll-view { .scroll-view {
top: $navigate-height; // top: $navigate-height;
} }
} }
@ -234,7 +234,7 @@ $paddingBottom: 100px;
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
font-size: 28px; font-size: 28px;
color: #666; color: #5b5b5b;
align-items: center; align-items: center;
margin-top: 24px; margin-top: 24px;
.receiverName { .receiverName {
@ -245,23 +245,73 @@ $paddingBottom: 100px;
font-size: 32px; font-size: 32px;
color: #333; color: #333;
font-weight: bold; font-weight: bold;
line-height: 1.2;
} }
} }
.trade-detail-goods { .trade-detail-goods {
margin: 0 20px; margin: 14px 22px 0;
padding-top: 16px; // padding-top: 16px;
padding: 40px 30px 40px 20px;
min-height: 100px; min-height: 100px;
background: #fff; background: #f7f7f7;
border-radius: 6px 6px 0 0; border-radius: 6px;
position: relative;
.line { .line {
display: flex; display: flex;
padding: 20px; // padding: 20px;;
font-size: 24px; font-size: 20px;
color: #333; color: #333;
.fuzhi { .right {
margin-left: 20px; margin-left: 4px;
color: #28a1ff; font-size: 20px;
} }
.left {
font-size: 20px;
}
.fuzhi {
margin-left: 30px;
// color: #28a1ff;
line-height: 1;
border-bottom: 1px solid #101010;
}
}
.order_status_msg {
font-size: 26px;
color: #000;
position: absolute;
top: 36px;
right: 30px;
}
.address-txt {
font-size: 26px;
margin-top: 56px;
color: #000;
line-height: 1;
display: flex;
align-items: center;
justify-content: space-between;
.right {
font-size: 20px;
color: #000;
border-bottom: 1px solid #000;
}
}
.user-info-trade {
display: flex;
justify-content: flex-start;
font-size: 20px;
color: #5b5b5b80;
align-items: center;
line-height: 1;
.receiverName {
margin-right: 20px;
font-size: inherit;
}
}
.address-detail {
font-size: 20px;
// line-height: 1;
color: #5b5b5b80;
} }
} }
.order-item__pay-type { .order-item__pay-type {
@ -273,7 +323,7 @@ $paddingBottom: 100px;
padding: 10px 38px; padding: 10px 38px;
margin: 0 20px 20px 20px; margin: 0 20px 20px 20px;
font-size: 26px; font-size: 26px;
color: #5b5b5b; color: #5b5b5b80;
background: #fff; background: #fff;
border-radius: 0 0 6px 6px; border-radius: 0 0 6px 6px;
&__num { &__num {
@ -355,29 +405,80 @@ $paddingBottom: 100px;
background: #fff; background: #fff;
} }
} }
.trade-detail-box {
background: #f7f7f7;
border-radius: 6px;
margin: 10px 22px;
.gap {
padding: 0 54px;
width: calc(100% - 108px);
box-sizing: border-box;
height: 2px;
background: #fff;
margin: 20px auto;
}
.trade-detail-info-new {
padding: 20px 24px;
.line {
display: flex;
width: 100%;
justify-content: space-between;
align-items: center;
margin-bottom: 18px;
.left,
.right {
font-size: 20px;
color: #5b5b5b;
line-height: 1;
}
}
}
.trade-detail-info-bottom {
display: flex;
align-items: center;
justify-content: space-between;
padding: 20px 22px 50px;
.left {
font-size: 26px;
}
.right {
font-size: 32px;
}
.left,
.sp-price__symbol,
.sp-price__int {
font-weight: bold;
}
}
}
.trade-detail__footer { .trade-detail__footer {
position: fixed; position: fixed;
left: 0; left: 0;
width: 100%; width: 100%;
height: 100px; height: 100px;
bottom: 0; bottom: $edge-margin;
background: #fff; background: #fff;
display: flex; display: flex;
justify-content: space-evenly; justify-content: space-evenly;
align-items: center; align-items: center;
&__btn { &__btn {
width: 338px; width: 338px;
height: 84px; height: 80px;
flex-shrink: 0; flex-shrink: 0;
line-height: 84px; line-height: 80px;
text-align: center; text-align: center;
border-radius: 40px; border-radius: 6px;
color: #333; color: #000;
border: 2px solid #bbb; border: 2px solid #000;
overflow: hidden; overflow: hidden;
font-size: 26px; font-size: 34px;
// font-weight: bold;
flex: 1; flex: 1;
margin: 0 20rpx; margin: 30px 50rpx;
margin-bottom: 80px;
box-sizing: border-box;
background: #fff;
&.left { &.left {
margin-left: 7%; margin-left: 7%;
width: 396px; width: 396px;
@ -399,7 +500,7 @@ $paddingBottom: 100px;
} }
} }
&_active { &_active {
color: #ffffff; // color: #ffffff;
} }
&_allWidthBtn { &_allWidthBtn {
// width: 100%; // width: 100%;
@ -542,7 +643,8 @@ $paddingBottom: 100px;
.detail-item { .detail-item {
padding: 0; padding: 0;
.detail-item__title { .detail-item__title {
padding: 10px 0; padding: 30px 22px 0px;
color: #000;
} }
.order-item__bd { .order-item__bd {
margin-bottom: 0; margin-bottom: 0;

View File

@ -0,0 +1,4 @@
export default {
navigationBarTitleText: '开票信息',
navigationStyle: 'custom',
}

View File

@ -0,0 +1,218 @@
import Taro, { getCurrentInstance } from '@tarojs/taro'
import { View, Text, ScrollView, Input } from '@tarojs/components'
import _mapKeys from 'lodash/mapKeys'
import { Loading, SpPage, SpPrice, SpCheckboxNew } from '@/components'
import api from '@/api'
import { classNames, navigateTo } from '@/utils'
import { AtModal, AtIcon } from 'taro-ui'
// import { log, pickBy, resolveOrderStatus, authSetting } from '@/utils'
import './invoice-info.scss'
import { useImmer } from 'use-immer'
const initState = {
formList: [
{
name: '抬头类型',
type: 'checkbox',
key: 'invoice_title',
required: true,
},
{
name: '发票抬头',
type: 'input',
key: 'invoice_title',
placeholder: '请填写抬头名称(必填)',
required: true,
},
{
name: '邮箱地址',
type: 'input',
key: 'email',
placeholder: '用于接收电子发票(必填)',
required: true,
},
{
name: '注册地址',
type: 'input',
key: 'addr',
placeholder: '(选填)',
},
{
name: '注册电话',
type: 'input',
key: 'tel',
placeholder: '(选填)',
},
{
name: '开户银行',
type: 'input',
key: 'yh',
placeholder: '(选填)',
},
{
name: '银行账号',
type: 'input',
key: 'zh',
placeholder: '(选填)',
},
],
form: {},
showModal: false,
visible: false,
showDetail: false
}
function InvoiceInfo (props) {
const [state, setState] = useImmer(initState)
const { formList, form, showModal, visible, showDetail } = state
const onChangeItemCheck = () => {
}
const hadnleInput = (val, item) => {
const { key } = item
setState((draft) => {
draft.form[key] = val
})
}
const onPickerCancel = () => {
setState((draft) => {
draft.visible = false
})
}
return <SpPage className='page-invoice-info has-navbar' navigationBarTitleText='开票信息'>
<View className="info-bd">
{showDetail && <View className="info-bd-tips">{0}张发票{1}个订单</View>}
<View className="info-item">
<View className="tit">发票类型</View>
<View className="content">
<Text>电子发票</Text>
{showDetail ? <View className='flex'>
<Text className='ck'>查看</Text>
<AtIcon value='chevron-right' size='18' color='#000'></AtIcon>
</View> : <Text className='sq'></Text>}
</View>
</View>
{showDetail && <View className="info-item">
<View className="tit">发票状态</View>
<View className="content">
<Text>已申请</Text>
</View>
</View>}
<View className="info-item">
<View className="tit">发票金额</View>
<View className="content">
<Text>¥9999</Text>
</View>
</View>
{formList.map((item) => <View className="info-item">
<View className="tit">{item.name}</View>
{showDetail ? <View className="content">{form[item.key] || '测试'}</View> : <>{item.type === 'checkbox' && <View className="content">
<View className="content-item">
<SpCheckboxNew checked={form.gr === '1'} onChange={() => onChangeItemCheck()} >
<Text className="">个人/非企业单位</Text>
</SpCheckboxNew>
</View>
<View className="content-item">
<SpCheckboxNew checked={form.gr === '2'} onChange={onChangeItemCheck()} >
<Text className="">企业</Text>
</SpCheckboxNew>
</View>
</View>}
{item.type === 'input' && <Input value={form[item.key]} onInput={(e) => hadnleInput(e.target.value, item)} className='ipt' placeholderClass='ipt-placeholder' placeholder={item.placeholder}></Input>}</>}
</View>)}
{!showDetail && <View className="tips">
<View className="tit">温馨提示</View>
<View className="tit">
1应国家税务总局要求您若开具增值税普通发票须同时提供
企业抬头及纳税人识别号否则发票将无法用于企业报销;
</View>
<View>2发票将由订单所属城市的公司为您开具;</View>
<View>
3配合国家税务总局推进全面数字化的电子发票部分城市已转
为全电发票发票处理时长为1-3个工作日请耐心等待
</View>
</View>}
</View>
<View className={classNames("bottom")}>
<View onClick={() => setState((draft) => {
draft.visible = true
})} className={classNames("btn", { "btn-disabled": true })}>提交申请</View>
</View>
<View className="sp-picker">
<View
className={classNames('mask', {
visible: visible
})}
onTap={onPickerCancel}
catchtouchmove
></View>
<View
className={classNames('sp-picker-cnt', {
visible: visible
})}
>
<View className={classNames('sp-picker-hd')} catchtouchmove>
<Text className='center'>{showDetail ? '确定邮箱地址' : '开具电子发票'}</Text>
<AtIcon onClick={onPickerCancel} value='close' size={14} color='#000' ></AtIcon>
</View>
<View className='sp-picker-bd'>
{!showDetail && <>
<View className='sp-picker-bd-item'>
<View className="tit">发票类型</View>
<View className="content">电子发票</View>
</View>
<View className='sp-picker-bd-item'>
<View className="tit">抬头类型</View>
<View className="content">电子发票</View>
</View>
<View className='sp-picker-bd-item'>
<View className="tit">发票抬头</View>
<View className="content">电子发票</View>
</View>
</>}
<View className='sp-picker-bd-item'>
<View className="tit">邮箱地址</View>
<View className="content">电子发票</View>
</View>
<View onClick={() => setState((draft) => {
draft.visible = false
draft.showModal = true
})} className={classNames("btn", { "notop": showDetail })}>提交申请</View>
</View>
</View>
</View>
<View className={classNames('toast', {
visible: false
})}>
<View>已超重开发票时限</View>
<View>不可操作重开发票</View>
</View>
<AtModal
isOpened={showModal}
title=''
cancelText='关闭'
confirmText='查看记录'
onClose={() => setState((draft) => {
draft.showModal = false
})}
onCancel={() => setState((draft) => {
draft.showModal = false
})}
onConfirm={() => {
setState((draft) => {
draft.showModal = false
})
navigateTo('/subpage/pages/trade/invoice-record')
}}
content='发票申请提交成功'
/>
</SpPage>
}
export default InvoiceInfo

View File

@ -0,0 +1,241 @@
@import '@/style/imports';
.page-invoice-info {
.info-bd {
margin: 10px 50px 60px;
padding-top: 10px;
&-tips {
color: #8e8e8e;
font-size: 20px;
text-align: center;
margin-bottom: 12px;
}
}
.info-item {
display: flex;
align-items: center;
color: #808080;
background: #e5e5e5;
border-radius: 6px;
margin-bottom: 2px;
padding-right: 40px;
box-sizing: border-box;
.tit {
color: #808080;
font-size: 26px;
line-height: 1;
padding: 28px 50px 28px 30px;
box-sizing: border-box;
}
.content {
display: flex;
flex: 1;
justify-content: space-between;
align-items: center;
font-size: 26px;
line-height: 1;
color: #000;
&-item {
display: flex;
align-items: center;
color: #808080;
font-size: 26px;
min-width: 120px;
.sp-checkbox-new__label {
font-size: 26px;
}
}
.sq {
font-size: 20px;
line-height: 1;
border-bottom: 1px solid #000;
}
.flex {
display: flex;
align-items: center;
.ck {
font-size: 26px;
color: #163586;
margin-right: 2px;
}
}
}
.ipt {
display: flex;
flex: 1;
font-size: 26px;
line-height: 1;
color: #000;
padding-right: 40px;
box-sizing: border-box;
&-placeholder {
color: #808080;
}
}
}
.tips {
padding: 60px 40px 40px;
view,
text {
font-size: 20px;
color: #999;
}
}
.bottom {
position: fixed;
bottom: 90px;
left: 0;
right: 0;
width: 100%;
.btn {
&-disabled {
background: #666;
}
}
}
.at-modal {
&__overlay {
background-color: rgba(0, 0, 0, 0.6);
}
&__container {
width: 560px;
border-radius: 10px;
}
&__header {
display: none;
}
&__content {
padding: 70px 80px 50px;
text-align: center;
min-height: auto;
display: flex;
.content-simple {
font-size: 30px;
}
}
.at-modal__footer--simple .at-modal__action > button:last-child:nth-child(2) {
color: #222;
}
}
.sp-picker {
.mask {
position: fixed;
z-index: 2;
top: 0;
right: 0;
left: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.6);
visibility: hidden;
opacity: 0;
transition: all 0.3s ease;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
color: #fff;
&.visible {
visibility: visible;
opacity: 1;
}
}
&-cnt {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
transition: all 0.3s ease-in-out;
transform: translateY(100%);
z-index: 13;
background-color: #fff;
border-radius: 30rpx 30rpx 0 0;
&.visible {
transform: translateY(0);
}
}
&-hd {
padding: 30px 50px;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: none;
position: relative;
font-size: 26px;
.center {
margin: auto;
}
.at-icon-close {
padding: 20px 30px;
position: absolute;
right: 20px;
}
}
&-bd {
padding-bottom: 90px;
&-item {
display: flex;
align-items: center;
border-bottom: none;
padding: 0 90px;
view {
color: #000;
font-size: 26px;
line-height: 1;
}
.tit {
padding: 28px 50px 28px 30px;
box-sizing: border-box;
}
.content {
display: flex;
flex: 1;
color: #000;
}
}
.btn {
margin-top: 60px;
}
}
}
.btn {
margin: 0 50px;
display: flex;
height: 80px;
align-items: center;
justify-content: center;
font-size: 32px;
line-height: 1;
background: #000;
color: #fff;
border-radius: 6px;
&.notop {
margin-top: 10px;
}
}
.toast {
position: fixed;
z-index: 2;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
opacity: 0;
visibility: hidden;
transition: all 0.3s ease;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
width: 400px;
height: 120px;
background: #666;
color: #fff;
border-radius: 10px;
view {
font-size: 30px;
}
&.visible {
visibility: visible;
opacity: 1;
}
}
}

View File

@ -2,11 +2,11 @@ import React, { Component } from 'react'
import Taro, { getCurrentInstance } from '@tarojs/taro' import Taro, { getCurrentInstance } from '@tarojs/taro'
import { View, Text, ScrollView } from '@tarojs/components' import { View, Text, ScrollView } from '@tarojs/components'
import _mapKeys from 'lodash/mapKeys' import _mapKeys from 'lodash/mapKeys'
import { Loading, SpNote, SpPage } from '@/components' import { Loading, SpNote, SpPage, SpPrice, SpCheckboxNew } from '@/components'
import api from '@/api' import api from '@/api'
import { withPager, withLogin } from '@/hocs' import { withPager, withLogin } from '@/hocs'
import { log, pickBy, resolveOrderStatus, authSetting } from '@/utils' import { log, pickBy, resolveOrderStatus, authSetting } from '@/utils'
import TradeItem from './comps/item' // import TradeItem from './comps/item'
import './invoice-list.scss' import './invoice-list.scss'
@ -65,7 +65,7 @@ export default class InvoiceList extends Component {
log.debug('[trade list] list fetched and processed: ', nList) log.debug('[trade list] list fetched and processed: ', nList)
this.setState({ this.setState({
list: [...this.state.list, ...nList] list: [...this.state.list, ...nList, {}, {}, {}, {}, {}, {}, {}, {}]
}) })
return { total } return { total }
@ -127,6 +127,9 @@ export default class InvoiceList extends Component {
) )
} }
} }
onChangeItemCheck = (item) => {
console.log(item, 'ckeck点击')
}
render () { render () {
const { list, page } = this.state const { list, page } = this.state
@ -136,23 +139,52 @@ export default class InvoiceList extends Component {
{/* <SpNavBar title='发票管理' leftIconType='chevron-left' fixed='true' /> */} {/* <SpNavBar title='发票管理' leftIconType='chevron-left' fixed='true' /> */}
<ScrollView scrollY className='trade-list__scroll' onScrollToLower={this.nextPage}> <ScrollView scrollY className='trade-list__scroll' onScrollToLower={this.nextPage}>
{list.map((item) => { {list.map((item, idx) => {
return ( return (
<TradeItem // <TradeItem
customFooter // customFooter
payType={item.pay_type} // payType={item.pay_type}
key={item.tid} // key={item.tid}
info={item} // info={item}
onClick={this.handleClickItem.bind(this, item)} // onClick={this.handleClickItem.bind(this, item)}
onClickBtn={this.handleClickItemBtn} // onClickBtn={this.handleClickItemBtn}
renderFooter={ // renderFooter={
<View className='trade-item__ft'> // <View className='trade-item__ft'>
<Text className='trade-item__status'>已开票</Text> // <Text className='trade-item__status'>已开票</Text>
// </View>
// }
// />
<View className='invoice-item' key={`invoice_item_${idx}`}>
<SpCheckboxNew
checked={item.is_checked}
onChange={this.onChangeItemCheck.bind(this, item)}
/>
<View className="right">
<View className="right-item">{idx + 1}开票金额
<SpPrice size={28} className='total-pirce' value={item.payment / 100} showSeparator noDecimal />
</View> </View>
} <View className="right-item">订单编号{item.tid}</View>
/> <View className="right-item">下单时间{item.create_date}</View>
</View>
</View>
) )
})} })}
{!page.isLoading && list?.length && <View className="bottom">
<View className="bottom-line">
<View className="left">已选{1}个订单共计
<SpPrice size={20} className='total-pirce' value={900900 / 100} showSeparator noDecimal />
</View>
<View className="right">开票金额以实际为准</View>
</View>
<View className='bottom-wrap'>
<SpCheckboxNew
checked={false}
onChange={this.onChangeItemCheck.bind(this, {})}
/>
<View className="bottom-txt">本页全选</View>
<View className="bottom-btn">下一步</View>
</View>
</View>}
{/*<AtButton {/*<AtButton
circle circle
type='primary' type='primary'
@ -161,7 +193,7 @@ export default class InvoiceList extends Component {
>下载</AtButton>*/} >下载</AtButton>*/}
{page.isLoading && <Loading>正在加载...</Loading>} {page.isLoading && <Loading>正在加载...</Loading>}
{!page.isLoading && !page.hasNext && !list.length && ( {!page.isLoading && !page.hasNext && !list.length && (
<SpNote img='trades_empty.png'>赶快去添加吧~</SpNote> <SpNote img='trades_empty.png'>已完成订单为空~</SpNote>
)} )}
</ScrollView> </ScrollView>
</SpPage> </SpPage>

View File

@ -4,10 +4,92 @@
.page-invoice-list { .page-invoice-list {
.trade-list { .trade-list {
&__scroll { &__scroll {
@include page-scroll($tabs-height + $navigate-height + 10px, 0); // @include page-scroll($tabs-height + $navigate-height + 10px, 0);
@include page-scroll(var(--nav-height), 140px);
padding-top: 20px;
padding-bottom: 210px;
}
}
.invoice-item {
margin: 20px;
margin-top: 0;
padding: 50px 30px;
box-sizing: border-box;
background: #f7f7f7;
border-radius: 6px;
display: flex;
align-items: center;
.right {
display: flex;
flex-direction: column;
margin-left: 10px;
&-item {
color: #000;
margin-bottom: 20px;
line-height: 1;
}
&-item:last-child {
margin-bottom: 0;
}
}
}
.bottom {
position: fixed;
bottom: 0;
left: 0;
right: 0;
width: 100%;
&-line {
width: 100%;
padding: 16px 36px 16px 50px;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: space-between;
background: #999;
color: #fff;
.left {
display: flex;
align-items: center;
font-size: 20px;
line-height: 1;
.sp-price__symbol,
.sp-price__int {
color: #fff;
margin-right: 0 !important;
}
}
.right {
font-size: 20px;
line-height: 1;
}
}
&-wrap {
width: 100%;
padding: 10px 36px 50px 50px;
display: flex;
align-items: center;
box-sizing: border-box;
background: #fff;
}
&-txt {
margin-left: 20px;
line-height: 1;
}
&-btn {
margin-left: auto;
display: flex;
width: 300px;
height: 80px;
align-items: center;
justify-content: center;
font-size: 32px;
line-height: 1;
background: #000;
color: #fff;
border-radius: 6px;
} }
} }
.trade-item { .trade-item {
&__ft { &__ft {
flex: 1; flex: 1;

View File

@ -0,0 +1,4 @@
export default {
navigationBarTitleText: ' ',
navigationStyle: 'custom',
}

View File

@ -0,0 +1,163 @@
import React, { Component } from 'react'
import Taro, { getCurrentInstance } from '@tarojs/taro'
import { View, Text, ScrollView } from '@tarojs/components'
import _mapKeys from 'lodash/mapKeys'
import { Loading, SpNote, SpPage, SpPrice, SpCheckboxNew } from '@/components'
import api from '@/api'
import { withPager, withLogin } from '@/hocs'
import { log, pickBy, resolveOrderStatus, authSetting } from '@/utils'
import { AtIcon } from 'taro-ui'
import './invoice-record.scss'
@withPager
@withLogin()
export default class InvoiceList extends Component {
constructor(props) {
super(props)
this.state = {
...this.state,
list: []
}
}
componentDidMount () {
this.nextPage()
}
componentWillUnmount () { }
async fetch (params) {
params = _mapKeys(
{
...params
},
function (val, key) {
if (key === 'page_no') return 'page'
if (key === 'page_size') return 'pageSize'
return key
}
)
const { list, total_count: total } = await api.trade.involiceList(params)
let nList = pickBy(list, {
tid: 'order_id',
status_desc: 'order_status_msg',
status: ({ order_status }) => resolveOrderStatus(order_status),
totalItems: ({ items }) => items.reduce((acc, item) => +item.num + acc, 0),
payment: ({ total_fee }) => (total_fee / 100).toFixed(2),
pay_type: 'pay_type',
point: 'point',
create_date: 'create_date',
order: ({ items }) =>
pickBy(items, {
order_id: 'order_id',
item_id: 'item_id',
pic_path: 'pic',
title: 'item_name',
price: ({ item_fee }) => (+item_fee / 100).toFixed(2),
point: 'item_point',
num: 'num'
})
})
log.debug('[trade list] list fetched and processed: ', nList)
this.setState({
list: [...this.state.list, ...nList, {}, {}, {}, {}, {}, {}, {}, {}]
})
return { total }
}
handleClickItem = (trade) => {
const { tid } = trade
Taro.navigateTo({
url: `/subpage/pages/trade/detail?id=${tid}`
})
}
handleClickItemBtn = async (type, trade) => {
const params = { ...trade }
// console.log(trade, 84)
switch (type) {
case 'add-card':
await Taro.addCard(params)
break
case 'open-card':
await Taro.openCard(params)
break
}
}
handleClickBtn = async (type) => {
if (type === 'add-card') {
const showErr = (title = '下载失败') => {
return Taro.showToast({
icon: 'none',
title
})
}
authSetting(
'writePhotosAlbum',
async () => {
const { tempFilePath } = await Taro.downloadFile({
url: 'http://mmbiz.qpic.cn/mmbiz_png/1nDJByqmW2drJSibeWL0bEib2rj4OxG6ep2Y8VggMzP2pSSHVGNW3eIEy9BUiaMfxD4MrWUQ2oVaNEZs4VfQg8tSw/0?wx_fmt=png'
})
try {
await Taro.saveImageToPhotosAlbum({
filePath: tempFilePath
})
Taro.showToast({
icon: 'success',
title: '成功保存照片'
})
} catch (e) {
console.log(e)
}
// this.handleClickLayer()
},
() => {
showErr()
}
)
}
}
onChangeItemCheck = (item) => {
console.log(item, 'ckeck点击')
}
render () {
const { list, page } = this.state
return (
<SpPage className='page-invoice-info has-navbar' navigationBarTitleText='发票记录'>
<ScrollView scrollY className='trade-list__scroll' onScrollToLower={this.nextPage}>
{list.map((item, idx) => {
return (
<View className='invoice-item' key={`invoice_item_${idx}`}>
<View className="right">
<View className="right-item">{idx + 1}发票金额
<SpPrice size={28} className='total-pirce' value={item.payment / 100} showSeparator noDecimal />
</View>
<View className="right-item">发票类型电子发票</View>
<View className="right-item">抬头类型{item.create_date}</View>
<View className="right-item">申请时间{item.create_date || '2023-12-18 10:10'}</View>
</View>
<View className="status">
<Text className="txt">已申请</Text>
<AtIcon value='chevron-right' size='18' color='#888'></AtIcon>
</View>
</View>
)
})}
{page.isLoading && <Loading>正在加载...</Loading>}
</ScrollView>
</SpPage>
)
}
}

View File

@ -0,0 +1,113 @@
@import '@/style/imports';
.page-invoice-info {
.trade-list {
&__scroll {
// @include page-scroll($tabs-height + $navigate-height + 10px, 0);
@include page-scroll(var(--nav-height), 140px);
padding-top: 20px;
padding-bottom: 210px;
}
}
.invoice-item {
margin: 0 20px 10px;
padding: 46px 36px 46px 50px;
box-sizing: border-box;
background: #f7f7f7;
border-radius: 6px;
display: flex;
align-items: center;
justify-content: space-between;
.right {
display: flex;
flex-direction: column;
margin-left: 10px;
&-item {
color: #000;
margin-bottom: 20px;
line-height: 1;
}
&-item:last-child {
margin-bottom: 0;
}
}
.status {
color: #888;
display: flex;
align-items: center;
.txt {
margin-right: 20px;
}
}
}
.bottom {
position: fixed;
bottom: 0;
left: 0;
right: 0;
width: 100%;
&-line {
width: 100%;
padding: 16px 36px 16px 50px;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: space-between;
background: #999;
color: #fff;
.left {
display: flex;
align-items: center;
font-size: 20px;
line-height: 1;
.sp-price__symbol,
.sp-price__int {
color: #fff;
margin-right: 0 !important;
}
}
.right {
font-size: 20px;
line-height: 1;
}
}
&-wrap {
width: 100%;
padding: 10px 36px 50px 50px;
display: flex;
align-items: center;
box-sizing: border-box;
background: #fff;
}
&-txt {
margin-left: 20px;
line-height: 1;
}
&-btn {
margin-left: auto;
display: flex;
width: 300px;
height: 80px;
align-items: center;
justify-content: center;
font-size: 32px;
line-height: 1;
background: #000;
color: #fff;
border-radius: 6px;
}
}
.trade-item {
&__ft {
flex: 1;
display: flex;
align-items: top;
justify-content: flex-end;
}
&__status {
font-size: $font-size-small;
color: #c1c1c1;
line-height: 40px;
}
}
}

View File

@ -35,8 +35,9 @@ export default class TradeList extends Component {
...this.state, ...this.state,
curTabIdx: 0, curTabIdx: 0,
tabList: [ tabList: [
{ title: '全部订单', status: '0' }, { title: '全部', status: '0' },
{ title: '待支付', status: '5' }, { title: '待付款', status: '5' },
{ title: '待发货', status: '6' },
{ title: '待收货', status: '1' } { title: '待收货', status: '1' }
], ],
// 是否显示待评价 // 是否显示待评价
@ -52,6 +53,7 @@ export default class TradeList extends Component {
const _tabList = JSON.parse(JSON.stringify(this.state.tabList)) const _tabList = JSON.parse(JSON.stringify(this.state.tabList))
if (evaluate == 1) { if (evaluate == 1) {
_tabList.push({ title: '待评价', status: '7', is_rate: 0 }) _tabList.push({ title: '待评价', status: '7', is_rate: 0 })
_tabList.push({ title: '售后', status: '---', is_rate: 0 })
} }
const tabIdx = _tabList.findIndex((tab) => tab.status === status) const tabIdx = _tabList.findIndex((tab) => tab.status === status)
if (tabIdx >= 0) { if (tabIdx >= 0) {
@ -312,6 +314,7 @@ export default class TradeList extends Component {
className={classNames('page-trade-list', { className={classNames('page-trade-list', {
'has-navbar': true || isNavbar() 'has-navbar': true || isNavbar()
})} })}
showNavSearchIcon
> >
<SpNavBar title='订单列表' leftIconType='chevron-left' fixed='true' /> <SpNavBar title='订单列表' leftIconType='chevron-left' fixed='true' />
<AtTabs <AtTabs
@ -349,8 +352,8 @@ export default class TradeList extends Component {
})} })}
{page.isLoading && <Loading>正在加载...</Loading>} {page.isLoading && <Loading>正在加载...</Loading>}
{!page.isLoading && !page.hasNext && !list.length && ( {!page.isLoading && !page.hasNext && !list.length && (
<SpNote isUrl img={`${process.env.APP_IMAGE_CDN}/empty_order.png`}> <SpNote isUrl img={`${process.env.APP_IMAGE_CDN_NEW}/cart/logo-hui.png`} height={144} width={144}>
还没有商城订单呦~ {curTabIdx != '0' ? tabList[curTabIdx].title : ''}订单为空
</SpNote> </SpNote>
)} )}
{!!curItemActionsId && <View className='layer' onClick={this.hideLayer} />} {!!curItemActionsId && <View className='layer' onClick={this.hideLayer} />}

View File

@ -23,7 +23,8 @@
} }
.trade-list { .trade-list {
&__scroll { &__scroll {
@include page-scroll($navigate-height-h5, $edge-margin); // @include page-scroll($navigate-height-h5, $edge-margin);
@include page-scroll(var(--nav-height), 40px);
} }
} }
} }
@ -39,10 +40,12 @@
&__item { &__item {
// height: $tabs-height; // height: $tabs-height;
color: $color-brand-accent-light; color: $color-brand-accent-light;
font-size: 26px;
padding: 24px 10px;
} }
&__item-underline { &__item-underline {
width: 40%; width: 70%;
left: 30%; left: 15%;
background: $color-brand-primary; background: $color-brand-primary;
} }
&__item--active { &__item--active {
@ -60,7 +63,8 @@
// $tabs-height + 30px, // $tabs-height + 30px,
// $edge-margin // $edge-margin
// ); // );
@include page-scroll($tabs-height + $navigate-height + 30px, $edge-margin); // @include page-scroll($tabs-height + $navigate-height + 30px, $edge-margin);
@include page-scroll(calc(var(--nav-height) + 110px), $edge-margin);
/* #ifdef h5 */ /* #ifdef h5 */
@include page-scroll($navigate-height-h5 + $tabs-height + 30px, $edge-margin); @include page-scroll($navigate-height-h5 + $tabs-height + 30px, $edge-margin);
/* #endif */ /* #endif */
@ -68,6 +72,17 @@
&.with-tabs-wx { &.with-tabs-wx {
@include page-scroll($navigate-height-h5, $edge-margin); @include page-scroll($navigate-height-h5, $edge-margin);
} }
.sp-note {
.sp-image {
margin-top: 400px;
}
&__text {
margin-top: 24px;
font-weight: bold;
font-size: 40px;
color: #000;
}
}
} }
.trade-cont { .trade-cont {
.more { .more {
@ -83,15 +98,17 @@
position: relative; position: relative;
.btn-action { .btn-action {
width: auto; width: auto;
margin-left: 20px; margin-left: 10px;
padding: 0 22px; padding: 15px 20px;
height: 42px; // height: 42px;
line-height: 42px; line-height: 22px;
border-radius: 8px; border-radius: 6px;
font-size: $font-size-small; font-size: 20px;
color: #fff; color: #fff;
background: #fff; background: #fff;
margin-top: 0px; margin-top: 0px;
box-sizing: border-box;
box-shadow: 0 0 0 1px #000000 !important;
&::after { &::after {
background: none; background: none;
border: none; border: none;

View File

@ -1 +1,4 @@
export default {} export default {
navigationBarTitleText: ' ',
navigationStyle: 'custom',
}

View File

@ -18,11 +18,11 @@ export default class RegRule extends Component {
} }
} }
componentDidMount() { componentDidMount () {
this.fetch() this.fetch()
} }
async fetch() { async fetch () {
let data = '' let data = ''
let navBarTitle = '协议' let navBarTitle = '协议'
const { type } = this.$instance.router.params const { type } = this.$instance.router.params
@ -65,14 +65,16 @@ export default class RegRule extends Component {
}) })
} }
render() { render () {
const { info, title } = this.state const { info, title } = this.state
return ( return (
<ScrollView enhanced scrollY showScrollbar={false} className='page-auth-reg-rule'> <SpPage className="has-navbar" navigationBarTitleText={title}>
{info && ( <ScrollView enhanced scrollY showScrollbar={false} className='page-auth-reg-rule'>
<SpHtml content={info} /> {info && (
)} <SpHtml content={info} />
</ScrollView> )}
</ScrollView>
</SpPage>
) )
} }
} }

View File

@ -2,5 +2,5 @@
padding: 30px; padding: 30px;
background: #fff; background: #fff;
box-sizing: border-box; box-sizing: border-box;
height: 100vh; height: calc(100vh - var(--nav-height) - 40px);
} }

View File

@ -108,7 +108,7 @@ function MemberIndex (props) {
// console.log('===>getCurrentPages==>', getCurrentPages(), getCurrentInstance()) // console.log('===>getCurrentPages==>', getCurrentPages(), getCurrentInstance())
const $instance = getCurrentInstance() const $instance = getCurrentInstance()
const { isLogin, isNewUser, login, getUserInfoAuth } = useLogin({ const { isLogin, isNewUser, login, getUserInfoAuth } = useLogin({
autoLogin: true, autoLogin: false,
// policyUpdateHook: (isUpdate) => { // policyUpdateHook: (isUpdate) => {
// // isUpdate && setPolicyModal(true) // // isUpdate && setPolicyModal(true)
// if (isUpdate) { // if (isUpdate) {
@ -457,11 +457,13 @@ function MemberIndex (props) {
> >
<View className='header-hd'> <View className='header-hd'>
<View className='header-hd__header' onClick={isLogin && handleClickLink.bind(this, '/subpages/member/user-info')}> <View className='header-hd__header' onClick={isLogin && handleClickLink.bind(this, '/subpages/member/user-info')}>
<SpImage <SpLogin newUser={isNewUser}>
className='usericon' <SpImage
src={(userInfo && userInfo.avatar) || ''} className='usericon'
width='110' src={(userInfo && userInfo.avatar) || `${process.env.APP_IMAGE_CDN_NEW}/member/user-icon.png`}
/> width='114'
/>
</SpLogin>
</View> </View>
<View className='header-hd__body' onClick={isLogin && handleClickLink.bind(this, '/subpages/member/user-info')}> <View className='header-hd__body' onClick={isLogin && handleClickLink.bind(this, '/subpages/member/user-info')}>
<View className='username-wrap'> <View className='username-wrap'>
@ -583,7 +585,7 @@ function MemberIndex (props) {
</SpLogin> </SpLogin>
<SpLogin <SpLogin
className='order-item' className='order-item'
onChange={handleClickLink.bind(this, '/subpage/pages/trade/list?status=1')} onChange={handleClickLink.bind(this, '/subpage/pages/trade/list?status=6')}
> >
<View className='order-item-view'> <View className='order-item-view'>
<SpImage src='member/daifahuo.png' className='icon-style' isNew /> <SpImage src='member/daifahuo.png' className='icon-style' isNew />
@ -611,7 +613,7 @@ function MemberIndex (props) {
</SpLogin> </SpLogin>
<SpLogin <SpLogin
className='order-item' className='order-item'
onChange={handleClickLink.bind(this, '/subpage/pages/trade/after-sale')} onChange={handleClickLink.bind(this, '/subpage/pages/trade/list?status=7')}
> >
<View className='order-item-view'> <View className='order-item-view'>
<SpImage src='member/yiwancheng.png' className='icon-style' isNew /> <SpImage src='member/yiwancheng.png' className='icon-style' isNew />
@ -625,7 +627,8 @@ function MemberIndex (props) {
</SpLogin> </SpLogin>
<SpLogin <SpLogin
className='order-item' className='order-item'
onChange={handleClickLink.bind(this, '/subpage/pages/trade/after-sale')} // /subpage/pages/trade/after-sale
onChange={handleClickLink.bind(this, '/subpage/pages/trade/list?status=7')}
> >
<View className='order-item-view'> <View className='order-item-view'>
<SpImage src='member/pingjia.png' className='icon-style' mode='aspectFit' height={42} isNew /> <SpImage src='member/pingjia.png' className='icon-style' mode='aspectFit' height={42} isNew />
@ -704,15 +707,15 @@ function MemberIndex (props) {
</View> </View>
</View> </View>
{state.isOpen && <View className={`${state.isOpen ? 'show ' : 'hide '}` + 'curtain'} onClick={() => setState((draft) => { draft.isOpen = false })}> {state.isOpen && <View className={`${state.isOpen ? 'show ' : 'hide '}` + 'curtain-block'} onClick={() => setState((draft) => { draft.isOpen = false })}>
<View className="curtain_mask"> <View className="curtain-block_mask">
<View className="curtain_content"> <View className="curtain-block_content">
<View className="curtain_content_title"> <View className="curtain-block_content_title">
<SpImage src={`member/logo-black.png`} height={32} mode='heightFix' isNew /> <SpImage src={`member/logo-black.png`} height={32} mode='heightFix' isNew />
<View className="">隐私政策</View> <View className="">隐私政策</View>
</View> </View>
<ScrollView scrollY <ScrollView scrollY
scrollWithAnimation className="curtain_content_text" showScrollbar={false} enhanced> scrollWithAnimation className="curtain-block_content_text" showScrollbar={false} enhanced>
亲爱的用户,感谢您使用Birkenstock微信小程序!为了加强对您个人信息的保护,我们根据最新法律的要求制定/更新了隐私政策,我们将基于合法以及正当必要的原则,按照本政策的规定向您提供各项服务 亲爱的用户,感谢您使用Birkenstock微信小程序!为了加强对您个人信息的保护,我们根据最新法律的要求制定/更新了隐私政策,我们将基于合法以及正当必要的原则,按照本政策的规定向您提供各项服务
本政策旨在向您说明休迪贸易 (上海)有限公司及其在中国大陆境内的线上线下门店如何收集使用传输和保护您的个人信息 本政策旨在向您说明休迪贸易 (上海)有限公司及其在中国大陆境内的线上线下门店如何收集使用传输和保护您的个人信息
通过隐私政策,我们向您主要说明: 通过隐私政策,我们向您主要说明:

View File

@ -16,9 +16,10 @@
} }
.usericon { .usericon {
border: 4px solid #fff; border: 4px solid #fff;
// border: none;
width: 110px; width: 110px;
height: 110px; height: 110px;
border-radius: 50px; border-radius: 50%;
margin-right: 20px; margin-right: 20px;
overflow: hidden; overflow: hidden;
} }
@ -217,7 +218,8 @@
.order-bradge { .order-bradge {
position: absolute; position: absolute;
top: -6px; top: -6px;
right: 45px; // right: 45px;
right: -16px;
font-size: 20px; font-size: 20px;
display: block; display: block;
border: 3px solid #fff; border: 3px solid #fff;
@ -321,7 +323,7 @@
} }
} }
} }
.curtain { .curtain-block {
display: block; display: block;
position: fixed; position: fixed;
top: 0; top: 0;

View File

@ -1,5 +1,5 @@
import React, { useEffect, useRef } from 'react' import React, { useEffect, useRef } from 'react'
import { useSelector } from 'react-redux' import { useSelector, useDispatch } from 'react-redux'
import { useImmer } from 'use-immer' import { useImmer } from 'use-immer'
import Taro from '@tarojs/taro' import Taro from '@tarojs/taro'
import { AtButton } from 'taro-ui' import { AtButton } from 'taro-ui'
@ -10,6 +10,7 @@ import { SG_POLICY } from '@/consts'
import { classNames, showToast, formatTime, isWeixin, isWeb, pickBy } from '@/utils' import { classNames, showToast, formatTime, isWeixin, isWeb, pickBy } from '@/utils'
import imgUploader from '@/utils/upload' import imgUploader from '@/utils/upload'
import { View, Input, Picker, Button, Text, Checkbox } from '@tarojs/components' import { View, Input, Picker, Button, Text, Checkbox } from '@tarojs/components'
import { updateUserInfo } from '@/store/slices/user'
import './user-info.scss' import './user-info.scss'
const initialState = { const initialState = {
@ -30,6 +31,7 @@ const initialState = {
function MemberUserInfo () { function MemberUserInfo () {
const [state, setState] = useImmer(initialState) const [state, setState] = useImmer(initialState)
const dispatch = useDispatch()
const { const {
formItems, formItems,
formUserInfo, formUserInfo,
@ -49,7 +51,6 @@ function MemberUserInfo () {
useEffect(() => { useEffect(() => {
getFormItem() getFormItem()
fetchData()
}, []) }, [])
useEffect(() => { useEffect(() => {
@ -68,30 +69,32 @@ function MemberUserInfo () {
label: 'label', label: 'label',
children: 'children' children: 'children'
}) })
let arrProvice = [] // let arrProvice = []
let arrCity = [] // let arrCity = []
let arrCounty = [] // let arrCounty = []
_nList.map((item, index) => { // _nList.map((item, index) => {
arrProvice.push(item.label) // arrProvice.push(item.label)
if (index === 0) { // if (index === 0) {
item.children.map((c_item, c_index) => { // item.children.map((c_item, c_index) => {
arrCity.push(c_item.label) // arrCity.push(c_item.label)
if (c_index === 0) { // if (c_index === 0) {
c_item.children.map((cny_item) => { // c_item.children.map((cny_item) => {
arrCounty.push(cny_item.label) // arrCounty.push(cny_item.label)
}) // })
} // }
}) // })
} // }
}) // })
setState((draft) => { // setState((draft) => {
draft.nList = _nList // draft.nList = _nList
draft.areaList = [arrProvice, arrCity, arrCounty] // draft.areaList = [arrProvice, arrCity, arrCounty]
// draft.multiIndex = [0, 0, 0] // // draft.multiIndex = [0, 0, 0]
}) // })
return _nList
} }
const getFormItem = async () => { const getFormItem = async () => {
const _areaList = await fetchData()
const data = await api.user.regParam({ const data = await api.user.regParam({
is_edite_page: true is_edite_page: true
}) })
@ -111,7 +114,6 @@ function MemberUserInfo () {
} }
Object.keys(data).forEach((key, i) => { Object.keys(data).forEach((key, i) => {
const value = custom_data[key] || userInfo[key] const value = custom_data[key] || userInfo[key]
console.log("🚀 ~ key:", key, formSort[key])
if (data[key].is_open) { if (data[key].is_open) {
// if (key !== 'mobile' && key !== 'username') { // if (key !== 'mobile' && key !== 'username') {
// } // }
@ -132,10 +134,52 @@ function MemberUserInfo () {
} }
}) })
_formItems.push({ name: "居住城市", required_message: "请输入居住城市", key: "city", element_type: "area", field_type: 7, placeholder: "请选择居住城市", range: [], sort: 999 }) _formItems.push({ name: "居住城市", required_message: "请输入居住城市", key: "city", element_type: "area", field_type: 7, placeholder: "请选择居住城市", range: [], sort: 999 })
console.log("🚀 ~ _formItems:", _formItems) const { life_province, life_city, life_county } = userInfo
_formUserInfo.life_province = life_province
_formUserInfo.life_city = life_city
_formUserInfo.life_county = life_county
// _formUserInfo.multiIndex = userInfo.multiIndex || [0, 0, 0]
let _multiIndex = [0, 0, 0]
let arrProvice = []
let arrCity = []
let arrCounty = []
_areaList.forEach((item, index) => {
arrProvice.push(item.label)
if (life_province && life_city && life_county) {
if (item.label === life_province) {
_multiIndex[0] = index
item.children.map((s_item, sIndex) => {
arrCity.push(s_item.label)
if (s_item.label === life_city) {
_multiIndex[1] = sIndex
s_item.children.map((th_item, thIndex) => {
arrCounty.push(th_item.label)
if (th_item.label === life_county) {
_multiIndex[2] = thIndex
}
})
}
})
}
} else {
if (index === 0) {
item.children.map((c_item, c_index) => {
arrCity.push(c_item.label)
if (c_index === 0) {
c_item.children.map((cny_item) => {
arrCounty.push(cny_item.label)
})
}
})
}
}
})
setState((draft) => { setState((draft) => {
draft.nList = _areaList
draft.formItems = _formItems.sort((a, b) => a.sort - b.sort) draft.formItems = _formItems.sort((a, b) => a.sort - b.sort)
draft.formUserInfo = _formUserInfo draft.formUserInfo = _formUserInfo
draft.areaList = [arrProvice, arrCity, arrCounty]
draft.multiIndex = _multiIndex
}) })
} }
@ -186,12 +230,14 @@ function MemberUserInfo () {
} }
const renderDatePicker = ({ key, required_message }) => { const renderDatePicker = ({ key, required_message }) => {
const disabled = key === 'birthday' && !userInfo.birthday_can_edit
return ( return (
<Picker mode='date' value={formUserInfo[key]} onChange={onChangePicker.bind(this, key)} start='1900-01-01' end={formatTime(new Date())}> <Picker mode='date' disabled={disabled} value={formUserInfo[key]} onChange={onChangePicker.bind(this, key)} start='1900-01-01' end={formatTime(new Date())}>
<View <View
className={classNames('picker-value', { className={classNames('picker-value', {
'placeholder': !formUserInfo[key] 'placeholder': !formUserInfo[key]
})} })}
style={{ 'color': disabled ? '#a5a5a5' : '#000' }}
> >
{formUserInfo[key] || required_message} {formUserInfo[key] || required_message}
</View> </View>
@ -278,9 +324,11 @@ function MemberUserInfo () {
}) })
} }
}) })
const { province: life_province, city: life_city, county: life_county } = _info
setState((draft) => { setState((draft) => {
draft.multiIndex = e.detail.value draft.multiIndex = e.detail.value
draft.info = _info draft.info = _info
draft.formUserInfo = { ...draft.formUserInfo, life_province, life_city, life_county, multiIndex }
}) })
} }
@ -342,7 +390,7 @@ function MemberUserInfo () {
value={multiIndex} value={multiIndex}
range={areaList} range={areaList}
> >
<View className='picker'> <View className='picker' style={{ 'color': multiIndex.length > 0 ? '#000' : '#a5a5a5' }}>
{info.address_id ? ( {info.address_id ? (
`${info.province}-${info.city}-${info.county}` `${info.province}-${info.city}-${info.county}`
) : ( ) : (
@ -380,16 +428,19 @@ function MemberUserInfo () {
const { avatar, username } = formUserInfo const { avatar, username } = formUserInfo
await api.member.updateMemberInfo({ await api.member.updateMemberInfo({
username, username,
avatar avatar,
...formUserInfo
}) })
await api.member.setMemberInfo({ await api.member.setMemberInfo({
...formUserInfo ...formUserInfo,
}) })
showToast('修改成功') showToast('修改成功')
await getUserInfo(true) await getUserInfo(true)
let memberRes = await api.member.memberInfo()
dispatch(updateUserInfo(memberRes))
setTimeout(() => { setTimeout(() => {
Taro.navigateBack() Taro.navigateBack()
}, 200) }, 300)
} }
const handleLogOff = async () => { const handleLogOff = async () => {
@ -469,7 +520,7 @@ function MemberUserInfo () {
if (isWeixin) { if (isWeixin) {
return ( return (
<Button class='avatar-wrapper' open-type='chooseAvatar' onChooseAvatar={onChooseAvatar}> <Button class='avatar-wrapper' open-type='chooseAvatar' onChooseAvatar={onChooseAvatar}>
<SpImage src={formUserInfo.avatar || 'user_icon.png'} width={110} height={110} circle /> <SpImage src={'cart/logo-hui.png'} width={110} height={110} circle isNew />
</Button> </Button>
) )
} else { } else {
@ -513,7 +564,7 @@ function MemberUserInfo () {
onInput={onChangeUsername} onInput={onChangeUsername}
onConfirm={onChangeUsername} onConfirm={onChangeUsername}
/> : renderFormItem(item)} /> : renderFormItem(item)}
{(item.element_type === 'select' || item.element_type === 'date') && <View className="iconfont icon-arrowRight"></View>} {(item.element_type === 'select' || item.element_type === 'date') && <View className="iconfont icon-arrowRight" style={{ color: item.key === 'birthday' && !userInfo.birthday_can_edit ? '#a5a5a5' : '#000' }}></View>}
</View> </View>
</View>)} </View>)}
</View> </View>