添加地址
This commit is contained in:
parent
64cb883ebb
commit
eaee69667c
@ -32,7 +32,9 @@ const config = {
|
|||||||
alias: {
|
alias: {
|
||||||
'@/components': path.resolve(__dirname, '..', 'src/components'),
|
'@/components': path.resolve(__dirname, '..', 'src/components'),
|
||||||
'@/assets': path.resolve(__dirname, '..', 'src/assets'),
|
'@/assets': path.resolve(__dirname, '..', 'src/assets'),
|
||||||
'@/images': path.resolve(__dirname, '..', 'src/assets/images')
|
'@/images': path.resolve(__dirname, '..', 'src/assets/images'),
|
||||||
|
'@/config': path.resolve(__dirname, '..', 'src/config'),
|
||||||
|
'@/utils': path.resolve(__dirname, '..', 'src/utils'),
|
||||||
},
|
},
|
||||||
mini: {
|
mini: {
|
||||||
postcss: {
|
postcss: {
|
||||||
|
@ -31,6 +31,7 @@ export default defineAppConfig({
|
|||||||
'pages/message/index',
|
'pages/message/index',
|
||||||
'pages/message-list/index',
|
'pages/message-list/index',
|
||||||
'pages/message-detail/index',
|
'pages/message-detail/index',
|
||||||
|
'/pages/login-quick/index'
|
||||||
],
|
],
|
||||||
window: {
|
window: {
|
||||||
backgroundTextStyle: 'light',
|
backgroundTextStyle: 'light',
|
||||||
@ -39,11 +40,5 @@ export default defineAppConfig({
|
|||||||
navigationBarTextStyle: 'black',
|
navigationBarTextStyle: 'black',
|
||||||
navigationStyle: 'custom'
|
navigationStyle: 'custom'
|
||||||
},
|
},
|
||||||
components: [
|
|
||||||
'pages/index/index',
|
|
||||||
'pages/login/index',
|
|
||||||
'pages/register/index',
|
|
||||||
'pages/forgot/index',
|
|
||||||
'pages/goods-detail/index',
|
|
||||||
]
|
|
||||||
})
|
})
|
||||||
|
5
src/config/config.js
Normal file
5
src/config/config.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export default {
|
||||||
|
api: "http://1.14.121.134:9101",
|
||||||
|
debugApi: "http://1.14.121.134:9101",
|
||||||
|
debug: false
|
||||||
|
}
|
@ -11,6 +11,9 @@ import checked from '@/images/checked.png'
|
|||||||
import Taro from '@tarojs/taro';
|
import Taro from '@tarojs/taro';
|
||||||
import { useRouter } from '@tarojs/taro';
|
import { useRouter } from '@tarojs/taro';
|
||||||
import { Button, Textarea, Address } from '@nutui/nutui-react-taro';
|
import { Button, Textarea, Address } from '@nutui/nutui-react-taro';
|
||||||
|
import { cities, createAddress, getAddress, updateAddress } from '../../utils/api';
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
import { backOrGo, closeLoading, errorNotice, loading, redirectTo } from '../../utils/utils';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -19,7 +22,7 @@ function Index() {
|
|||||||
const param = useRouter().params
|
const param = useRouter().params
|
||||||
const [id] = useState(param.id)
|
const [id] = useState(param.id)
|
||||||
const [home] = useState(param.home)
|
const [home] = useState(param.home)
|
||||||
const [addrId, setAddrId] = useState(0)
|
const [addrId, setAddrId] = useState([])
|
||||||
const [isDefault, setIsDefault] = useState(false)
|
const [isDefault, setIsDefault] = useState(false)
|
||||||
const [user, setUser] = useState('')
|
const [user, setUser] = useState('')
|
||||||
const [phone, setPhone] = useState('')
|
const [phone, setPhone] = useState('')
|
||||||
@ -28,13 +31,8 @@ function Index() {
|
|||||||
|
|
||||||
const [text, setText] = useState('请选择地址')
|
const [text, setText] = useState('请选择地址')
|
||||||
const [normal, setNormal] = useState(false)
|
const [normal, setNormal] = useState(false)
|
||||||
const [province, setProvince] = useState([
|
const [cityList, setCityList] = useState([])
|
||||||
{ id: 1, name: '北京', title: 'B' },
|
const [province, setProvince] = useState([])
|
||||||
{ id: 2, name: '广西', title: 'G' },
|
|
||||||
{ id: 3, name: '江西', title: 'J' },
|
|
||||||
{ id: 4, name: '四川', title: 'S' },
|
|
||||||
{ id: 5, name: '浙江', title: 'Z' },
|
|
||||||
])
|
|
||||||
|
|
||||||
const [city, setCity] = useState([])
|
const [city, setCity] = useState([])
|
||||||
|
|
||||||
@ -46,27 +44,60 @@ function Index() {
|
|||||||
city,
|
city,
|
||||||
country,
|
country,
|
||||||
town,
|
town,
|
||||||
|
addressIdStr: '0_0_0_0',
|
||||||
})
|
})
|
||||||
|
|
||||||
const onChange = (cal) => {
|
useEffect(() => {
|
||||||
|
cities().then(res => {
|
||||||
|
if (!res) return
|
||||||
|
setCityList(res.items)
|
||||||
|
setProvince(res.items?.filter(item => item.deep == 0))
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!id) return
|
||||||
|
getAddress().then(re => {
|
||||||
|
if (!re) return
|
||||||
|
const data = re.items.filter(item => item.id == id)
|
||||||
|
if (data.length < 1) return
|
||||||
|
const addr = data[0]
|
||||||
|
console.log(addr)
|
||||||
|
setAddrId([addr.province_id, addr.city_id, addr.county_id])
|
||||||
|
setText(`${addr.province.name}${addr.city.name}${addr.county.name}`)
|
||||||
|
setAddrInfo(addr.address)
|
||||||
|
setUser(addr.recipient_name)
|
||||||
|
setPhone(addr.recipient_phone)
|
||||||
|
setAddress({ province: addr.province, city: addr.city, country: addr.county, town: [], addressIdStr: `${addr.province_id}_${addr.city_id}_${addr.county_id}_0` })
|
||||||
|
if (addr.province_id && addr.city_id) {
|
||||||
|
cities(addr.province_id).then(r => {
|
||||||
|
setCity(r.items)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (addr.city_id && addr.county_id) {
|
||||||
|
cities(addr.city_id).then(r => {
|
||||||
|
console.log(r.items, addr, addrId)
|
||||||
|
setCountry(r.items)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, [id])
|
||||||
|
|
||||||
|
const onChange = async (cal) => {
|
||||||
|
const re = await cities(cal.value.id)
|
||||||
|
const d = re.items
|
||||||
|
if (!d.length) {
|
||||||
|
setNormal(false)
|
||||||
|
return
|
||||||
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
switch (cal.next) {
|
switch (cal.next) {
|
||||||
case 'city':
|
case 'city':
|
||||||
setCity([
|
|
||||||
{ id: 7, name: '朝阳区', title: 'C' },
|
setCity(d)
|
||||||
{ id: 8, name: '崇文区', title: 'C' },
|
|
||||||
{ id: 9, name: '昌平区', title: 'C' },
|
|
||||||
{ id: 6, name: '石景山区', title: 'S' },
|
|
||||||
{ id: 3, name: '八里庄街道', title: 'B' },
|
|
||||||
{ id: 10, name: '北苑', title: 'B' },
|
|
||||||
])
|
|
||||||
break;
|
break;
|
||||||
case 'country':
|
case 'country':
|
||||||
setCountry([
|
setCountry(d)
|
||||||
{ id: 3, name: '八里庄街道', title: 'B' },
|
|
||||||
{ id: 9, name: '北苑', title: 'B' },
|
|
||||||
{ id: 4, name: '常营乡', title: 'C' },
|
|
||||||
])
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
setNormal(false)
|
setNormal(false)
|
||||||
@ -74,35 +105,61 @@ function Index() {
|
|||||||
}, 200)
|
}, 200)
|
||||||
}
|
}
|
||||||
const close = (val) => {
|
const close = (val) => {
|
||||||
console.log(val, "Data")
|
|
||||||
setNormal(false)
|
setNormal(false)
|
||||||
|
|
||||||
if (val.data && !!val.data.addressStr) {
|
if (val.data && !!val.data.addressStr) {
|
||||||
setText((val.data).addressStr)
|
setText((val.data).addressStr)
|
||||||
setAddress({ province: val.data.province, city: val.data.city, country: val.data.country, town: val.data.town })
|
setAddress({ province: val.data.province, city: val.data.city, country: val.data.country, town: val.data.town, addressIdStr: val.data.addressIdStr })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
|
|
||||||
|
|
||||||
}, [id])
|
|
||||||
|
|
||||||
|
|
||||||
// 跳转
|
|
||||||
const navDetailFn = (id) => {
|
|
||||||
Taro.navigateTo({
|
|
||||||
url: `/pages/pay-success/index?id=${id}`
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 返回页面
|
// 返回页面
|
||||||
const backFn = () => {
|
const backFn = () => {
|
||||||
Taro.getCurrentPages().length > 0 && Taro.navigateBack()
|
Taro.getCurrentPages().length > 0 && Taro.navigateBack({ delta: 1 })
|
||||||
|
}
|
||||||
|
|
||||||
|
const submit = async () => {
|
||||||
|
const addressId = address.addressIdStr.split('_')
|
||||||
|
if (!phone || !user || !addrInfo || address.addressIdStr == '0_0_0_0') {
|
||||||
|
errorNotice('请填写地址完整信息')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addrInfo.length < 6) {
|
||||||
|
errorNotice('详细地址信息错误')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
zipcode: '000000',
|
||||||
|
recipient_phone: phone,
|
||||||
|
recipient_name: user,
|
||||||
|
address: addrInfo,
|
||||||
|
province_id: Number(addressId[0]),
|
||||||
|
city_id: Number(addressId[1]),
|
||||||
|
county_id: Number(addressId[2]),
|
||||||
|
is_default: isDefault
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id) {
|
||||||
|
loading('地址编辑中...')
|
||||||
|
const re = await updateAddress(id, data)
|
||||||
|
closeLoading()
|
||||||
|
if (re) {
|
||||||
|
backOrGo('/pages/address/index')
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
loading('地址新增中...')
|
||||||
|
const re = await createAddress(data)
|
||||||
|
closeLoading()
|
||||||
|
if (re) {
|
||||||
|
backOrGo('/pages/address/index')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View className='addr-container'>
|
<View className='addr-c-container'>
|
||||||
<View className='addr-detail-title'>
|
<View className='addr-detail-title'>
|
||||||
<Image src={backNav} className="square-35 absolute left-10 nav-icon" onClick={backFn} />
|
<Image src={backNav} className="square-35 absolute left-10 nav-icon" onClick={backFn} />
|
||||||
{
|
{
|
||||||
@ -111,36 +168,36 @@ function Index() {
|
|||||||
|
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View className='addr-body' >
|
<View className='addr-c-body' >
|
||||||
<View className='addr-item'>
|
<View className='addr-c-item'>
|
||||||
<View className='addr-form'>
|
<View className='addr-c-form'>
|
||||||
<View className='addr-form-name'>收货人</View>
|
<View className='addr-c-form-name'>收货人</View>
|
||||||
<Input className='addr-form-input' placeholder='请输入收货人' value={user} onInput={(e) => {
|
<Input className='addr-c-form-input' placeholder='请输入收货人' value={user} onInput={(e) => {
|
||||||
setUser(e.detail.value)
|
setUser(e.detail.value)
|
||||||
}} />
|
}} />
|
||||||
</View>
|
</View>
|
||||||
<View className='addr-form'>
|
<View className='addr-c-form'>
|
||||||
<View className='addr-form-name'>电话</View>
|
<View className='addr-c-form-name'>电话</View>
|
||||||
<Input className='addr-form-input' placeholder='请输入收货人' value={phone} onInput={(e) => {
|
<Input className='addr-c-form-input' placeholder='请输入收货电话' value={phone} onInput={(e) => {
|
||||||
setPhone(e.detail.value)
|
setPhone(e.detail.value)
|
||||||
}} />
|
}} />
|
||||||
</View>
|
</View>
|
||||||
<View className='addr-form'>
|
<View className='addr-c-form'>
|
||||||
<View className='addr-form-name'>所在地区</View>
|
<View className='addr-c-form-name'>所在地区</View>
|
||||||
<View className='flex justify-between items-center addr-form-input' onClick={() => { setNormal(true) }}>
|
<View className='flex justify-between items-center addr-c-form-input' onClick={() => { setNormal(true) }}>
|
||||||
<Label>{text}</Label>
|
<Label>{text}</Label>
|
||||||
<Image src={next} className='next-icon' />
|
<Image src={next} className='next-icon' />
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<View className='addr-form bt-none'>
|
<View className='addr-c-form bt-none'>
|
||||||
<View className='addr-form-name '>详细地址</View>
|
<View className='addr-c-form-name '>详细地址</View>
|
||||||
</View>
|
</View>
|
||||||
<Textarea placeholder='请输入详细地址' autosize rows="4" maxlength={100} defaultValue={addrInfo} onChange={(e) => {
|
<Textarea placeholder='请输入详细地址' autosize rows="4" maxlength={100} defaultValue={addrInfo} onChange={(e) => {
|
||||||
setAddrInfo(e)
|
setAddrInfo(e)
|
||||||
}} />
|
}} />
|
||||||
</View>
|
</View>
|
||||||
<View className=' mt-22 addr-item'>
|
<View className=' mt-22 addr-c-item'>
|
||||||
<View className='addr-form bt-none' onClick={() => {
|
<View className='addr-c-form bt-none' onClick={() => {
|
||||||
setIsDefault(x => !x)
|
setIsDefault(x => !x)
|
||||||
}}>
|
}}>
|
||||||
<View className='text-black'>设为默认地址</View>
|
<View className='text-black'>设为默认地址</View>
|
||||||
@ -148,14 +205,14 @@ function Index() {
|
|||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<Button className='addr-btn' >保存地址</Button>
|
<Button className='addr-c-btn' onClick={submit} >保存地址</Button>
|
||||||
|
|
||||||
<Address
|
<Address
|
||||||
modelValue={normal}
|
modelValue={normal}
|
||||||
|
modelSelect={addrId}
|
||||||
province={province}
|
province={province}
|
||||||
city={city}
|
city={city}
|
||||||
country={country}
|
country={country}
|
||||||
town={town}
|
|
||||||
customAddressTitle="请选择所在地区"
|
customAddressTitle="请选择所在地区"
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
onClose={close}
|
onClose={close}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.addr-container {
|
.addr-c-container {
|
||||||
font-family: Source Han Sans CN-Bold, Source Han Sans CN;
|
font-family: Source Han Sans CN-Bold, Source Han Sans CN;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
background: #FBFBFD;
|
background: #FBFBFD;
|
||||||
@ -11,7 +11,7 @@
|
|||||||
border-radius: 16px 16px 16px 16px;
|
border-radius: 16px 16px 16px 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.addr-detail-title {
|
.addr-c-detail-title {
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
height: 60px;
|
height: 60px;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
@ -24,7 +24,7 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.addr-body {
|
.addr-c-body {
|
||||||
padding: 21px;
|
padding: 21px;
|
||||||
height: auto;
|
height: auto;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@ -34,7 +34,7 @@
|
|||||||
align-content: center;
|
align-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.addr-box {
|
.addr-c-box {
|
||||||
width: 333px;
|
width: 333px;
|
||||||
background: #FFFFFF;
|
background: #FFFFFF;
|
||||||
box-shadow: 4px 7px 9px 0px rgba(56, 63, 68, 0.03);
|
box-shadow: 4px 7px 9px 0px rgba(56, 63, 68, 0.03);
|
||||||
@ -43,7 +43,7 @@
|
|||||||
padding: 0 12px;
|
padding: 0 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.addr-item {
|
.addr-c-item {
|
||||||
width: 333px;
|
width: 333px;
|
||||||
background: #FFFFFF;
|
background: #FFFFFF;
|
||||||
box-shadow: 4px 7px 9px 0px rgba(56, 63, 68, 0.03);
|
box-shadow: 4px 7px 9px 0px rgba(56, 63, 68, 0.03);
|
||||||
@ -60,7 +60,7 @@
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.addr-form {
|
.addr-c-form {
|
||||||
width: 308px;
|
width: 308px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
@ -73,18 +73,18 @@
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.addr-form-name {
|
.addr-c-form-name {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.addr-form-input {
|
.addr-c-form-input {
|
||||||
width: 230px;
|
width: 230px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.addr-btn {
|
.addr-c-btn {
|
||||||
width: 233px;
|
width: 233px;
|
||||||
height: 55px;
|
height: 55px;
|
||||||
border-radius: 107px 107px 107px 107px;
|
border-radius: 107px 107px 107px 107px;
|
||||||
@ -98,12 +98,21 @@
|
|||||||
left: calc((100vw - 233px)/2);
|
left: calc((100vw - 233px)/2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.addr-item>.nut-textarea {
|
.addr-c-item>.nut-textarea {
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.addr-item .weui-input {
|
.addr-c-item .weui-input {
|
||||||
color: var(--nutui-textarea-text-color, var(--nutui-gray-1, #1a1a1a));
|
color: var(--nutui-textarea-text-color, var(--nutui-gray-1, #1a1a1a));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.addr-c-container .nut-popup {
|
||||||
|
background-color: #FFFFFF !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.addr-c-container textarea:-internal-autofill-selected,
|
||||||
|
.addr-c-container input:-internal-autofill-selected {
|
||||||
|
background-color: none !important;
|
||||||
}
|
}
|
@ -12,6 +12,10 @@ import edit from '@/images/edit.png'
|
|||||||
import Taro from '@tarojs/taro';
|
import Taro from '@tarojs/taro';
|
||||||
import { useRouter } from '@tarojs/taro';
|
import { useRouter } from '@tarojs/taro';
|
||||||
import { Button } from '@nutui/nutui-react-taro';
|
import { Button } from '@nutui/nutui-react-taro';
|
||||||
|
import { deleteAddress, getAddress } from '../../utils/api';
|
||||||
|
import { backTo, closeLoading, loading, redirectTo, successNotice } from '../../utils/utils';
|
||||||
|
import { SetData } from '../../utils/storage';
|
||||||
|
import { useDidShow } from '@tarojs/taro';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -20,11 +24,21 @@ function Index() {
|
|||||||
const param = useRouter().params
|
const param = useRouter().params
|
||||||
const [id] = useState(param.id)
|
const [id] = useState(param.id)
|
||||||
const [home] = useState(param.home)
|
const [home] = useState(param.home)
|
||||||
|
const [gid] = useState(param.gid)
|
||||||
const [addrId, setAddrId] = useState(0)
|
const [addrId, setAddrId] = useState(0)
|
||||||
|
const [list, setList] = useState([])
|
||||||
|
const [ref, setRef] = useState(0)
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
}, [id])
|
getAddress().then(re => {
|
||||||
|
if (!re) return
|
||||||
|
setList(re.items)
|
||||||
|
})
|
||||||
|
if (!!id) {
|
||||||
|
setAddrId(id)
|
||||||
|
}
|
||||||
|
}, [id, ref])
|
||||||
|
|
||||||
|
|
||||||
// 跳转
|
// 跳转
|
||||||
@ -33,6 +47,26 @@ function Index() {
|
|||||||
url: `/pages/address-create/index?id=${id}`
|
url: `/pages/address-create/index?id=${id}`
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onSelect = (aid) => {
|
||||||
|
if (!!gid && !!aid) {
|
||||||
|
// redirectTo(`/pages/settle/index?id=${gid}&aid=${aid}`)
|
||||||
|
SetData(gid, aid, 5)
|
||||||
|
backTo()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除
|
||||||
|
const deleteAddr = async (id) => {
|
||||||
|
if (!id) return
|
||||||
|
loading('正在删除中')
|
||||||
|
const re = await deleteAddress(id).finally(() => {
|
||||||
|
closeLoading()
|
||||||
|
})
|
||||||
|
successNotice('删除成功')
|
||||||
|
setRef(d => d + 1)
|
||||||
|
}
|
||||||
|
|
||||||
// 返回页面
|
// 返回页面
|
||||||
const backFn = () => {
|
const backFn = () => {
|
||||||
Taro.getCurrentPages().length > 0 && Taro.navigateBack()
|
Taro.getCurrentPages().length > 0 && Taro.navigateBack()
|
||||||
@ -49,27 +83,32 @@ function Index() {
|
|||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View className='addr-body' >
|
<View className='addr-body' >
|
||||||
<View className='addr-item'>
|
{
|
||||||
<View className='addr-icon w-6 h-6' onClick={() => {
|
list.map((item, index) => {
|
||||||
setAddrId(1)
|
return <View className='addr-item' key={item.id}>
|
||||||
}}>
|
<View className='addr-icon w-6 h-6' onClick={() => {
|
||||||
<Image src={addrId == 1 ? checked : uncheck} className="w-6 h-6" />
|
setAddrId(item.id)
|
||||||
</View>
|
}}>
|
||||||
<View className='addr-item-content' onClick={() => {
|
<Image src={addrId == item.id ? checked : uncheck} className="w-6 h-6" />
|
||||||
setAddrId(1)
|
</View>
|
||||||
}}>
|
<View className='addr-item-content' onClick={() => {
|
||||||
<View className='addr-item-title'>
|
setAddrId(item.id)
|
||||||
<View className='addr-item-name'>李四 18080093730</View>
|
onSelect(item.id)
|
||||||
<View className='addr-default'>默认地址</View>
|
}}>
|
||||||
|
<View className='addr-item-title'>
|
||||||
|
<View className='addr-item-name'>{item.recipient_name} {item.recipient_phone}</View>
|
||||||
|
{item.id_default && <View className='addr-default'>默认地址</View>}
|
||||||
|
</View>
|
||||||
|
<View className='addr-item-info'>{item.province?.name}{item.city?.name}{item.county?.name}{item.address}</View>
|
||||||
|
</View>
|
||||||
|
<View className='addr-edit-icon' onClick={() => {
|
||||||
|
navDetailFn(item.id)
|
||||||
|
}}>
|
||||||
|
<Image src={edit} />
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<View className='addr-item-info'>四川省成都市天府二街</View>
|
})
|
||||||
</View>
|
}
|
||||||
<View className='addr-edit-icon' onClick={() => {
|
|
||||||
navDetailFn('')
|
|
||||||
}}>
|
|
||||||
<Image src={edit} />
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
</View>
|
</View>
|
||||||
<Button className='addr-btn' onClick={() => {
|
<Button className='addr-btn' onClick={() => {
|
||||||
|
@ -7,6 +7,7 @@ import './index.scss'
|
|||||||
import { Button } from "@nutui/nutui-react-taro"
|
import { Button } from "@nutui/nutui-react-taro"
|
||||||
import { useState } from "react"
|
import { useState } from "react"
|
||||||
import Taro from "@tarojs/taro"
|
import Taro from "@tarojs/taro"
|
||||||
|
import { sendCode } from "../../utils/api"
|
||||||
|
|
||||||
const activeEye = eye
|
const activeEye = eye
|
||||||
|
|
||||||
@ -47,7 +48,7 @@ const Login = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 倒计时
|
// 倒计时
|
||||||
const countDown = () => {
|
const countDown = async () => {
|
||||||
if (!mobile) {
|
if (!mobile) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -65,6 +66,9 @@ const Login = () => {
|
|||||||
setIntervalTime(start)
|
setIntervalTime(start)
|
||||||
}
|
}
|
||||||
}, 1000)
|
}, 1000)
|
||||||
|
const re = await sendCode(mobile)
|
||||||
|
if (!re) return
|
||||||
|
Taro.showToast({ title: '验证码发送成功', icon: 'success' })
|
||||||
}
|
}
|
||||||
|
|
||||||
return <View className="login-frame bg-slate-50 h-screen text-base">
|
return <View className="login-frame bg-slate-50 h-screen text-base">
|
||||||
|
@ -11,6 +11,8 @@ import Taro from '@tarojs/taro';
|
|||||||
import { useRouter } from '@tarojs/taro';
|
import { useRouter } from '@tarojs/taro';
|
||||||
import { useDidShow } from '@tarojs/taro';
|
import { useDidShow } from '@tarojs/taro';
|
||||||
import { Button } from '@nutui/nutui-react-taro';
|
import { Button } from '@nutui/nutui-react-taro';
|
||||||
|
import { mallDetail } from '../../utils/api';
|
||||||
|
import { ImagePreview } from '@nutui/nutui-react-taro';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -20,25 +22,37 @@ function Index() {
|
|||||||
const [id] = useState(param.id)
|
const [id] = useState(param.id)
|
||||||
|
|
||||||
const [swiperProgress, setSwiperProgress] = useState(1)
|
const [swiperProgress, setSwiperProgress] = useState(1)
|
||||||
const list = [
|
const [thumbnails, setThumbnails] = useState([])
|
||||||
'https://storage.360buyimg.com/jdc-article/NutUItaro34.jpg',
|
const [info, setInfo] = useState({})
|
||||||
'https://storage.360buyimg.com/jdc-article/NutUItaro2.jpg',
|
const [showReview, setShowReview] = useState(false)
|
||||||
'https://storage.360buyimg.com/jdc-article/welcomenutui.jpg'
|
const [imageNum, setImageNum] = useState(1)
|
||||||
]
|
|
||||||
|
|
||||||
useDidShow(() => {
|
|
||||||
console.log(12)
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (!id) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
detail(id)
|
||||||
|
|
||||||
}, [id])
|
}, [id])
|
||||||
|
|
||||||
|
|
||||||
|
const detail = async () => {
|
||||||
|
const re = await mallDetail(id)
|
||||||
|
if (!re) return
|
||||||
|
setInfo(re)
|
||||||
|
if (re.thumbnails?.length) {
|
||||||
|
let images = re.thumbnails
|
||||||
|
if (!!re.cover_image) {
|
||||||
|
images.shift(re.cover_image)
|
||||||
|
}
|
||||||
|
setThumbnails(images)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 跳转
|
// 跳转
|
||||||
@ -53,7 +67,7 @@ function Index() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View className='home-container'>
|
<View className='home-container' catchMove>
|
||||||
<View className='goods-detail-title'>
|
<View className='goods-detail-title'>
|
||||||
<Image src={backNav} className="square-35 absolute left-10 " onClick={backFn} />
|
<Image src={backNav} className="square-35 absolute left-10 " onClick={backFn} />
|
||||||
商品详情
|
商品详情
|
||||||
@ -75,7 +89,7 @@ function Index() {
|
|||||||
setSwiperProgress(x => x % 3 + 1)
|
setSwiperProgress(x => x % 3 + 1)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{list.map((item) => {
|
{thumbnails.map((item) => {
|
||||||
return (
|
return (
|
||||||
<SwiperItem key={item} className='goods-swiper-item'>
|
<SwiperItem key={item} className='goods-swiper-item'>
|
||||||
<Image src={item} alt="" />
|
<Image src={item} alt="" />
|
||||||
@ -84,27 +98,37 @@ function Index() {
|
|||||||
})}
|
})}
|
||||||
</Swiper>
|
</Swiper>
|
||||||
<View className='goods-swiper-progress'>
|
<View className='goods-swiper-progress'>
|
||||||
<View style={{ backgroundColor: '#F67952', height: '100%', width: list.length ? ((swiperProgress / list.length) > 1 ? 1 : (swiperProgress / list.length)) * 100 + '%' : 0 }}></View>
|
<View style={{ backgroundColor: '#F67952', height: '100%', width: thumbnails.length ? ((swiperProgress / thumbnails.length) > 1 ? 1 : (swiperProgress / thumbnails.length)) * 100 + '%' : 0 }}></View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<View className='goods-content'>
|
<View className='goods-content'>
|
||||||
<View className='line-clamp-2 goods-name'>
|
<View className='line-clamp-2 goods-name'>
|
||||||
银美孚1号 全合成油5w全合成油 5W-30 SN级 4L
|
{info.name}
|
||||||
</View>
|
|
||||||
<View className='goods-desc line-clamp-2'>
|
|
||||||
<View>规格</View>
|
|
||||||
</View>
|
</View>
|
||||||
|
{/* <View className='goods-desc line-clamp-2'>
|
||||||
|
<View>规格</View>
|
||||||
|
</View> */}
|
||||||
<View className='goods-item-price'>
|
<View className='goods-item-price'>
|
||||||
<Text className='goods-item-price-sale'>¥199</Text>
|
<Text className='goods-item-price-sale'>¥{info.price}</Text>
|
||||||
<Text className='goods-item-price-origin'>原价888</Text>
|
{/* <Text className='goods-item-price-origin'>原价888</Text> */}
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View className='goods-content-box'>
|
<View className='goods-content-box'>
|
||||||
图文内容专区
|
{
|
||||||
|
info.content_images?.map((item, index) => {
|
||||||
|
return (
|
||||||
|
<Image src={item} alt="" key={item} style={{ width: '100%' }} onClick={() => {
|
||||||
|
setImageNum(index + 1)
|
||||||
|
// setShowReview(true)
|
||||||
|
}} />
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<Button className='buy-btn' onClick={navDetailFn}>立即购买</Button>
|
<Button className='buy-btn' onClick={navDetailFn}>立即购买</Button>
|
||||||
|
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@
|
|||||||
|
|
||||||
.goods-name {
|
.goods-name {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 48px;
|
height: auto;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #10254E;
|
color: #10254E;
|
||||||
|
@ -1,36 +1,41 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { Image, Text, View } from '@tarojs/components'
|
import { Image, Text, View } from '@tarojs/components'
|
||||||
import {
|
|
||||||
Button
|
|
||||||
} from "@nutui/nutui-react-taro";
|
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
import TabbarAction from '@/components/action';
|
import TabbarAction from '@/components/action';
|
||||||
import { Infiniteloading } from '@nutui/nutui-react-taro';
|
import { Infiniteloading } from '@nutui/nutui-react-taro';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
import { mallList } from '../../utils/api';
|
||||||
import Taro from '@tarojs/taro';
|
import Taro from '@tarojs/taro';
|
||||||
|
|
||||||
|
|
||||||
function Index() {
|
function Index() {
|
||||||
|
const limit = 10
|
||||||
const [list, setList] = useState([])
|
const [list, setList] = useState([])
|
||||||
|
const [total, setTotal] = useState(0)
|
||||||
const [page, setPage] = useState(1)
|
const [page, setPage] = useState(1)
|
||||||
const [hasMore, setHasMore] = useState(true)
|
const [hasMore, setHasMore] = useState(true)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (list.length > 50) {
|
if (page < 1) {
|
||||||
setHasMore(false)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let l = []
|
fetchList(page)
|
||||||
for (let i = list.length; i < 10 + list.length; i++) {
|
|
||||||
l.push(i)
|
|
||||||
}
|
|
||||||
setList([...list, ...l])
|
|
||||||
|
|
||||||
}, [page])
|
}, [page])
|
||||||
|
|
||||||
|
const fetchList = async (page) => {
|
||||||
|
const offset = (page - 1) * limit
|
||||||
|
const res = await mallList('mall', offset, limit)
|
||||||
|
|
||||||
|
if (!res) return
|
||||||
|
if (res.items?.length + list.length >= res.total) {
|
||||||
|
setHasMore(false)
|
||||||
|
}
|
||||||
|
setList(res.items)
|
||||||
|
setTotal(res.total)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 跳转
|
// 跳转
|
||||||
const navDetailFn = (id) => {
|
const navDetailFn = (id) => {
|
||||||
@ -48,7 +53,7 @@ function Index() {
|
|||||||
containerId="customScroll"
|
containerId="customScroll"
|
||||||
useWindow={false}
|
useWindow={false}
|
||||||
loadTxt="loading"
|
loadTxt="loading"
|
||||||
loadMoreTxt="没有数据啦~"
|
loadMoreTxt={<View></View>}
|
||||||
loadIcon='loading'
|
loadIcon='loading'
|
||||||
hasMore={hasMore}
|
hasMore={hasMore}
|
||||||
onLoadMore={(x) => {
|
onLoadMore={(x) => {
|
||||||
@ -59,21 +64,21 @@ function Index() {
|
|||||||
<View className='goods-container '>
|
<View className='goods-container '>
|
||||||
{
|
{
|
||||||
list.map(item => {
|
list.map(item => {
|
||||||
return <View className='goods-item' key={item} onClick={() => {
|
return <View className='goods-item' key={item.id} onClick={() => {
|
||||||
navDetailFn(item)
|
navDetailFn(item.id)
|
||||||
}}>
|
}}>
|
||||||
<View className='goods-item-image'>
|
<View className='goods-item-image'>
|
||||||
<Image src='https://img.yzcdn.cn/vant/cat.jpeg' />
|
<Image src={item.cover_image} />
|
||||||
</View>
|
</View>
|
||||||
<View className='goods-item-name line-clamp-2'>
|
<View className='goods-item-name line-clamp-2'>
|
||||||
这个是商品的名称,但是可能有一点点的长
|
{item.name}
|
||||||
</View>
|
</View>
|
||||||
<View className='goods-item-desc line-clamp-2 '>
|
{/* <View className='goods-item-desc line-clamp-2 '>
|
||||||
这个是商品的介绍
|
这个是商品的介绍
|
||||||
</View>
|
</View> */}
|
||||||
<View className='goods-item-price'>
|
<View className='goods-item-price'>
|
||||||
<Text className='goods-item-price-sale'>¥199</Text>
|
<Text className='goods-item-price-sale'>¥{item.price}</Text>
|
||||||
<Text className='goods-item-price-origin'>原价888</Text>
|
{/* <Text className='goods-item-price-origin'>原价888</Text> */}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
})
|
})
|
||||||
|
@ -33,8 +33,8 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: space-around;
|
justify-content: space-between;
|
||||||
padding: 0 8px;
|
padding: 0 12px;
|
||||||
margin-top: 24px;
|
margin-top: 24px;
|
||||||
// column-count: 2;
|
// column-count: 2;
|
||||||
// column-gap: 10px;
|
// column-gap: 10px;
|
||||||
|
3
src/pages/login-quick/index.config.js
Normal file
3
src/pages/login-quick/index.config.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export default definePageConfig({
|
||||||
|
navigationBarTitleText: '登录'
|
||||||
|
})
|
116
src/pages/login-quick/index.jsx
Normal file
116
src/pages/login-quick/index.jsx
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
import { Image, Input, Text, View } from "@tarojs/components"
|
||||||
|
import back from '@/images/back.png'
|
||||||
|
import checked from '@/images/checked.png'
|
||||||
|
import eyeClose from '@/images/eyeClose.png'
|
||||||
|
import eye from '@/images/eye.png'
|
||||||
|
import './index.scss'
|
||||||
|
import { Button } from "@nutui/nutui-react-taro"
|
||||||
|
import { useState } from "react"
|
||||||
|
import Taro from "@tarojs/taro"
|
||||||
|
import { useDidShow } from "@tarojs/taro"
|
||||||
|
import { login, sendCode } from "../../utils/api"
|
||||||
|
import { JWT, JWTEXPIRE, SetData, USERINFO } from "../../utils/storage"
|
||||||
|
|
||||||
|
|
||||||
|
const activeEye = eye
|
||||||
|
|
||||||
|
const Login = () => {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const [mobile, setMobile] = useState('')
|
||||||
|
const [smsCode, setSmsCode] = useState('')
|
||||||
|
const [interval, setIntervalTime] = useState(0)
|
||||||
|
|
||||||
|
|
||||||
|
// 返回页面
|
||||||
|
const backFn = () => {
|
||||||
|
Taro.getCurrentPages().length > 0 && Taro.navigateBack()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 倒计时
|
||||||
|
const countDown = async () => {
|
||||||
|
if (!mobile) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setIntervalTime(60)
|
||||||
|
if (interval > 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let start = 60
|
||||||
|
const timer = setInterval(() => {
|
||||||
|
if (start > 0) {
|
||||||
|
start--
|
||||||
|
if (start <= 0) {
|
||||||
|
clearInterval(timer)
|
||||||
|
}
|
||||||
|
setIntervalTime(start)
|
||||||
|
}
|
||||||
|
}, 1000)
|
||||||
|
const re = await sendCode(mobile)
|
||||||
|
if (!re) return
|
||||||
|
Taro.showToast({ title: '验证码发送成功', icon: 'success' })
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const loginSubmit = async () => {
|
||||||
|
console.log(mobile, smsCode, "code")
|
||||||
|
if (!mobile || !smsCode) {
|
||||||
|
Taro.showToast({ title: '请完善登陆参数', icon: 'error' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Taro.showLoading({ title: '登陆中,请稍后' })
|
||||||
|
const re = await login(mobile, '', smsCode)
|
||||||
|
Taro.hideLoading()
|
||||||
|
if (re) {
|
||||||
|
SetData(JWT, re.token, JWTEXPIRE)
|
||||||
|
SetData(USERINFO, re.user)
|
||||||
|
Taro.redirectTo({ url: '/pages/index/index' })
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return <View className="login-frame bg-slate-50 h-screen text-base">
|
||||||
|
<View className="login-header flex justify-center items-center text-lg font-bold">
|
||||||
|
<Image src={back} className="square-35 absolute left-7" onClick={backFn} />
|
||||||
|
<View>新起点</View>
|
||||||
|
</View>
|
||||||
|
<View className="login-container relative">
|
||||||
|
<View className="relative font-bold text-lg block h-6 ">登录</View>
|
||||||
|
<View>
|
||||||
|
<View className="form-item mt-58">
|
||||||
|
<View className="form-label">手机号</View>
|
||||||
|
<View className="form-control relative">
|
||||||
|
<Input className="form-input" name="mobile" placeholder="请输手机号" id='mobile' onInput={(v) => {
|
||||||
|
setMobile(v.detail.value)
|
||||||
|
}} />
|
||||||
|
{
|
||||||
|
mobile && <Image className="w-6 h-6 absolute right-0 bottom-16" src={checked} />
|
||||||
|
}
|
||||||
|
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View className="form-item mt-22">
|
||||||
|
<View className="form-label">验证码</View>
|
||||||
|
<View className="form-control relative">
|
||||||
|
<Input className="form-input" name="smsCode" type="text" placeholder="请输入验证码" id='code' value={smsCode} onInput={(v) => {
|
||||||
|
setSmsCode(v.detail.value)
|
||||||
|
}} />
|
||||||
|
<Button className="code-btn" disabled={interval > 0} onClick={countDown}>{interval ? interval + 's' : '获取验证码'}</Button>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View className="login-footer flex flex-col justify-center">
|
||||||
|
<Button className="login-btn" onClick={loginSubmit}>登录</Button>
|
||||||
|
<View className="quick-login" onClick={() => {
|
||||||
|
Taro.redirectTo({ url: '/pages/login/index' })
|
||||||
|
}}>密码登录</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
</View>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default Login
|
123
src/pages/login-quick/index.scss
Normal file
123
src/pages/login-quick/index.scss
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
.login-header {
|
||||||
|
height: 86px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-frame {
|
||||||
|
height: auto;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: Source Han Sans CN-Bold, Source Han Sans CN;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-container {
|
||||||
|
width: 375px;
|
||||||
|
height: calc(100vh - 86px);
|
||||||
|
background: #FFFFFF;
|
||||||
|
border-radius: 20px 20px 0 0;
|
||||||
|
box-shadow: 0px 8px 51px 0px rgba(230, 234, 238, 0.8);
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 38px 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item {
|
||||||
|
height: 68px;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-label {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: bold;
|
||||||
|
font-family: Source Han Sans CN-Bold, Source Han Sans CN;
|
||||||
|
color: #2a2b2d;
|
||||||
|
line-height: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-input>.weui-input {
|
||||||
|
border: none;
|
||||||
|
height: 52px;
|
||||||
|
line-height: 52px;
|
||||||
|
border-bottom: 1px solid #262A34;
|
||||||
|
position: relative;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-input>.weui-input:focus {
|
||||||
|
border-bottom: 2px solid #F67952;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-input-placeholder,
|
||||||
|
.form-input>.weui-input::placeholder {
|
||||||
|
font-size: 16px;
|
||||||
|
font-family: Source Han Sans CN-Regular, Source Han Sans CN;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #aeafb4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control {
|
||||||
|
height: 52px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.forgot-password {
|
||||||
|
height: 24px;
|
||||||
|
font-size: 16px;
|
||||||
|
font-family: Source Han Sans CN-Regular, Source Han Sans CN;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #666;
|
||||||
|
line-height: 24px;
|
||||||
|
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.form-helper {
|
||||||
|
margin-top: 16px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-btn {
|
||||||
|
width: 253px;
|
||||||
|
height: 55px;
|
||||||
|
background: #F67952;
|
||||||
|
border-radius: 68px 68px 68px 68px;
|
||||||
|
opacity: 1;
|
||||||
|
border: none;
|
||||||
|
color: white;
|
||||||
|
font-size: 16px;
|
||||||
|
font-family: Source Han Sans CN-Bold, Source Han Sans CN;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-footer {
|
||||||
|
margin-top: 50px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-login {
|
||||||
|
font-size: 16px;
|
||||||
|
font-family: Source Han Sans CN-Regular, Source Han Sans CN;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #000000;
|
||||||
|
line-height: 24px;
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-btn {
|
||||||
|
width: 83px;
|
||||||
|
height: 30px;
|
||||||
|
background: #F67952;
|
||||||
|
border-radius: 4px 4px 4px 4px;
|
||||||
|
opacity: 1;
|
||||||
|
font-size: 12px;
|
||||||
|
font-family: Source Han Sans CN-Bold, Source Han Sans CN;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #FFFFFF;
|
||||||
|
border: none;
|
||||||
|
padding: 0;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
bottom: 12px;
|
||||||
|
}
|
@ -8,23 +8,22 @@ import { Button } from "@nutui/nutui-react-taro"
|
|||||||
import { useState } from "react"
|
import { useState } from "react"
|
||||||
import Taro from "@tarojs/taro"
|
import Taro from "@tarojs/taro"
|
||||||
import { useDidShow } from "@tarojs/taro"
|
import { useDidShow } from "@tarojs/taro"
|
||||||
|
import { login, sendCode } from "../../utils/api"
|
||||||
|
import { JWT, JWTEXPIRE, SetData, USERINFO } from "../../utils/storage"
|
||||||
|
import { successNotice } from "../../utils/utils"
|
||||||
|
|
||||||
|
|
||||||
const activeEye = eye
|
const activeEye = eye
|
||||||
|
|
||||||
const Login = () => {
|
const Login = () => {
|
||||||
|
|
||||||
const [account, setAccount] = useState('')
|
|
||||||
const [pwd, setPwd] = useState()
|
|
||||||
const [showPwd, setShowPwd] = useState(false)
|
|
||||||
const [loginMode, setLoginMode] = useState('account')
|
|
||||||
|
|
||||||
const [mobile, setMobile] = useState('')
|
const [mobile, setMobile] = useState('')
|
||||||
const [smsCode, setSmsCode] = useState('')
|
const [smsCode, setSmsCode] = useState('')
|
||||||
|
const [pwd, setPwd] = useState('')
|
||||||
const [interval, setIntervalTime] = useState(0)
|
const [interval, setIntervalTime] = useState(0)
|
||||||
|
const [showPwd, setShowPwd] = useState()
|
||||||
useDidShow(() => {
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
// 返回页面
|
// 返回页面
|
||||||
@ -32,33 +31,8 @@ const Login = () => {
|
|||||||
Taro.getCurrentPages().length > 0 && Taro.navigateBack()
|
Taro.getCurrentPages().length > 0 && Taro.navigateBack()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 注册页面
|
|
||||||
const registerFn = () => {
|
|
||||||
Taro.navigateTo({
|
|
||||||
url: '/pages/register/index'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 忘记密码
|
|
||||||
const forgotPasswordFn = () => {
|
|
||||||
Taro.navigateTo({
|
|
||||||
url: '/pages/forgot/index'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
//清理数据
|
|
||||||
const cleanFn = () => {
|
|
||||||
if (loginMode === 'account') {
|
|
||||||
setAccount('')
|
|
||||||
setPwd('')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
setMobile('')
|
|
||||||
setSmsCode('')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 倒计时
|
// 倒计时
|
||||||
const countDown = () => {
|
const countDown = async () => {
|
||||||
if (!mobile) {
|
if (!mobile) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -76,6 +50,26 @@ const Login = () => {
|
|||||||
setIntervalTime(start)
|
setIntervalTime(start)
|
||||||
}
|
}
|
||||||
}, 1000)
|
}, 1000)
|
||||||
|
const re = await sendCode(mobile)
|
||||||
|
if (!re) return
|
||||||
|
Taro.showToast({ title: '验证码发送成功', icon: 'success' })
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const loginSubmit = async () => {
|
||||||
|
if (!mobile || !pwd) {
|
||||||
|
Taro.showToast({ title: '请完善登陆参数', icon: 'error' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Taro.showLoading({ title: '登陆中,请稍后' })
|
||||||
|
const re = await login(mobile, pwd)
|
||||||
|
Taro.hideLoading()
|
||||||
|
if (re) {
|
||||||
|
SetData(JWT, re.token, JWTEXPIRE)
|
||||||
|
SetData(USERINFO, re.user)
|
||||||
|
Taro.redirectTo({ url: '/pages/index/index' })
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return <View className="login-frame bg-slate-50 h-screen text-base">
|
return <View className="login-frame bg-slate-50 h-screen text-base">
|
||||||
@ -85,75 +79,38 @@ const Login = () => {
|
|||||||
</View>
|
</View>
|
||||||
<View className="login-container relative">
|
<View className="login-container relative">
|
||||||
<View className="relative font-bold text-lg block h-6 ">登录</View>
|
<View className="relative font-bold text-lg block h-6 ">登录</View>
|
||||||
{
|
<View>
|
||||||
loginMode === 'account' ? <View>
|
<View className="form-item mt-58">
|
||||||
<View className="form-item mt-58">
|
<View className="form-label">手机号</View>
|
||||||
<View className="form-label">账号</View>
|
<View className="form-control relative">
|
||||||
<View className="form-control relative">
|
<Input className="form-input" name="mobile" placeholder="请输手机号" id='mobile' onInput={(v) => {
|
||||||
<Input className="form-input" placeholder="请输入账号" onInput={(v) => {
|
setMobile(v.detail.value)
|
||||||
setAccount(v.detail.value)
|
}} />
|
||||||
}} />
|
{
|
||||||
{
|
mobile && <Image className="w-6 h-6 absolute right-0 bottom-16" src={checked} />
|
||||||
!!account && <Image className="w-6 h-6 absolute right-0 bottom-16" src={checked} />
|
}
|
||||||
}
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
<View className="form-item mt-22">
|
|
||||||
<View className="form-label">密码</View>
|
|
||||||
<View className="form-control relative">
|
|
||||||
<Input className="form-input" type={showPwd ? 'text' : 'password'} placeholder="请输入密码" onInput={(v) => {
|
|
||||||
setPwd(v.detail.value)
|
|
||||||
}} />
|
|
||||||
<Image className="w-6 h-6 absolute right-0 bottom-16" src={showPwd ? activeEye : eyeClose} onClick={() => {
|
|
||||||
setShowPwd(v => !v)
|
|
||||||
}} />
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
<View className="form-helper">
|
|
||||||
<View className="forgot-password" onClick={registerFn}>注册账号</View>
|
|
||||||
<View className="forgot-password" onClick={forgotPasswordFn}>忘记密码</View>
|
|
||||||
</View>
|
|
||||||
<View className="login-footer flex flex-col justify-center">
|
|
||||||
<Button className="login-btn">登录</Button>
|
|
||||||
<View className="quick-login" onClick={() => {
|
|
||||||
setLoginMode('mobile')
|
|
||||||
cleanFn()
|
|
||||||
}}>快捷登录</View>
|
|
||||||
</View>
|
|
||||||
</View> : <View>
|
|
||||||
<View className="form-item mt-58">
|
|
||||||
<View className="form-label">手机号</View>
|
|
||||||
<View className="form-control relative">
|
|
||||||
<Input className="form-input" placeholder="请输手机号" placeholderClass="form-input-placeholder" onInput={(v) => {
|
|
||||||
setMobile(v.detail.value)
|
|
||||||
}} />
|
|
||||||
{
|
|
||||||
mobile && <Image className="w-6 h-6 absolute right-0 bottom-16" src={checked} />
|
|
||||||
}
|
|
||||||
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
<View className="form-item mt-22">
|
|
||||||
<View className="form-label">验证码</View>
|
|
||||||
<View className="form-control relative">
|
|
||||||
<Input className="form-input" maxlength={6} placeholder="请输入验证码" onInput={(v) => {
|
|
||||||
setSmsCode(v.detail.value)
|
|
||||||
}} />
|
|
||||||
<Button className="code-btn" disabled={interval > 0} onClick={countDown}>{interval ? interval + 's' : '获取验证码'}</Button>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<View className="login-footer flex flex-col justify-center">
|
|
||||||
<Button className="login-btn">登录</Button>
|
|
||||||
<View className="quick-login" onClick={() => {
|
|
||||||
setLoginMode('account')
|
|
||||||
cleanFn()
|
|
||||||
}}>密码登录</View>
|
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
}
|
<View className="form-item mt-22">
|
||||||
|
<View className="form-label">密码</View>
|
||||||
|
<View className="form-control relative">
|
||||||
|
<Input className="form-input" name="pwd" type={showPwd ? 'text' : 'password'} id='pwd' placeholder="请输入密码" value={pwd} onInput={(v) => {
|
||||||
|
setPwd(v.detail.value)
|
||||||
|
}} />
|
||||||
|
<Image className="w-6 h-6 absolute right-0 bottom-16" src={showPwd ? activeEye : eyeClose} onClick={() => {
|
||||||
|
setShowPwd(v => !v)
|
||||||
|
}} />
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View className="login-footer flex flex-col justify-center">
|
||||||
|
<Button className="login-btn" onClick={loginSubmit}>登录</Button>
|
||||||
|
<View className="quick-login" onClick={() => {
|
||||||
|
Taro.redirectTo({ url: '/pages/login-quick/index' })
|
||||||
|
}}>快捷登录</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
</View>
|
</View>
|
||||||
|
@ -7,6 +7,7 @@ import './index.scss'
|
|||||||
import { Button } from "@nutui/nutui-react-taro"
|
import { Button } from "@nutui/nutui-react-taro"
|
||||||
import { useState } from "react"
|
import { useState } from "react"
|
||||||
import Taro from "@tarojs/taro"
|
import Taro from "@tarojs/taro"
|
||||||
|
import { register, sendCode } from "../../utils/api"
|
||||||
|
|
||||||
const activeEye = eye
|
const activeEye = eye
|
||||||
|
|
||||||
@ -32,7 +33,7 @@ const Login = () => {
|
|||||||
|
|
||||||
|
|
||||||
// 倒计时
|
// 倒计时
|
||||||
const countDown = () => {
|
const countDown = async () => {
|
||||||
if (!mobile) {
|
if (!mobile) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -50,6 +51,33 @@ const Login = () => {
|
|||||||
setIntervalTime(start)
|
setIntervalTime(start)
|
||||||
}
|
}
|
||||||
}, 1000)
|
}, 1000)
|
||||||
|
const re = await sendCode(mobile)
|
||||||
|
if (!re) return
|
||||||
|
Taro.showToast({ title: '验证码发送成功', icon: 'success' })
|
||||||
|
}
|
||||||
|
|
||||||
|
const registerFn = async () => {
|
||||||
|
if (!mobile || !smsCode || !pwd || !confirmPassword || !payPassword || !confirmPayPassword) {
|
||||||
|
Taro.showToast({ title: '请完善注册参数', icon: 'error' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Taro.showLoading({ title: '正在注册中~', })
|
||||||
|
const re = await register({
|
||||||
|
nick_name: mobile,
|
||||||
|
phone: mobile,
|
||||||
|
verification_code: smsCode,
|
||||||
|
password: pwd,
|
||||||
|
confirm_password: confirmPassword,
|
||||||
|
pay_password: payPassword,
|
||||||
|
confirm_pay_pwd: confirmPayPassword
|
||||||
|
})
|
||||||
|
Taro.hideLoading()
|
||||||
|
if (re) {
|
||||||
|
Taro.showToast({ title: '注册成功', icon: 'success' })
|
||||||
|
setTimeout(() => {
|
||||||
|
Taro.redirectTo({ url: '/pages/login/index' })
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return <View className="login-frame bg-slate-50 h-screen text-base">
|
return <View className="login-frame bg-slate-50 h-screen text-base">
|
||||||
@ -61,7 +89,7 @@ const Login = () => {
|
|||||||
<View className="form-item ">
|
<View className="form-item ">
|
||||||
<View className="form-label">手机号</View>
|
<View className="form-label">手机号</View>
|
||||||
<View className="form-control relative">
|
<View className="form-control relative">
|
||||||
<Input className="form-input" placeholder="请输手机号" placeholderClass="form-input-placeholder" onInput={(v) => {
|
<Input className="form-input" placeholder="请输手机号" required placeholderClass="form-input-placeholder" onInput={(v) => {
|
||||||
setMobile(v.detail.value)
|
setMobile(v.detail.value)
|
||||||
}} />
|
}} />
|
||||||
{
|
{
|
||||||
@ -124,7 +152,7 @@ const Login = () => {
|
|||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<View className="login-footer flex flex-col justify-center">
|
<View className="login-footer flex flex-col justify-center">
|
||||||
<Button className="login-btn">注册</Button>
|
<Button className="login-btn" onClick={registerFn}>注册</Button>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
@ -9,6 +9,9 @@ import next from '@/images/next.png'
|
|||||||
import Taro from '@tarojs/taro';
|
import Taro from '@tarojs/taro';
|
||||||
import { useRouter } from '@tarojs/taro';
|
import { useRouter } from '@tarojs/taro';
|
||||||
import { Button } from '@nutui/nutui-react-taro';
|
import { Button } from '@nutui/nutui-react-taro';
|
||||||
|
import { getAddress, mallDetail } from '../../utils/api';
|
||||||
|
import { GetData } from '../../utils/storage';
|
||||||
|
import { useDidShow } from '@tarojs/taro';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -16,20 +19,40 @@ function Index() {
|
|||||||
|
|
||||||
const param = useRouter().params
|
const param = useRouter().params
|
||||||
const [id] = useState(param.id)
|
const [id] = useState(param.id)
|
||||||
|
const [aid, setAid] = useState(param.aid)
|
||||||
const [swiperProgress, setSwiperProgress] = useState(1)
|
const [addrData, setAddrData] = useState({})
|
||||||
const list = [
|
const [info, setInfo] = useState({})
|
||||||
'https://storage.360buyimg.com/jdc-article/NutUItaro34.jpg',
|
|
||||||
'https://storage.360buyimg.com/jdc-article/NutUItaro2.jpg',
|
|
||||||
'https://storage.360buyimg.com/jdc-article/welcomenutui.jpg'
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
mallDetail(id).then(re => {
|
||||||
|
if (!re) return
|
||||||
|
setInfo(re)
|
||||||
|
})
|
||||||
|
if (!aid && !!addrData.id) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
getAddress().then(re => {
|
||||||
|
if (!re) return
|
||||||
|
const addr = re.items.filter(item => {
|
||||||
|
if (aid) {
|
||||||
|
return item.id == aid
|
||||||
|
}
|
||||||
|
return item.is_default
|
||||||
|
})
|
||||||
|
if (!!addr.length) {
|
||||||
|
setAddrData(addr[0])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
}, [id])
|
}, [id, aid])
|
||||||
|
|
||||||
|
useDidShow(() => {
|
||||||
|
const aa = GetData(id)
|
||||||
|
setAid(aa)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
// 跳转
|
// 跳转
|
||||||
@ -45,9 +68,9 @@ function Index() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 选择地址
|
// 选择地址
|
||||||
const goAddr = (id) => {
|
const goAddr = (aid) => {
|
||||||
Taro.navigateTo({
|
Taro.navigateTo({
|
||||||
url: '/pages/address/index?id=' + id
|
url: `/pages/address/index?gid=${id}&id=` + aid
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,9 +86,9 @@ function Index() {
|
|||||||
<View className='address-title'>选择收货地址</View>
|
<View className='address-title'>选择收货地址</View>
|
||||||
<View className='address-area' onClick={() => { goAddr('') }}>
|
<View className='address-area' onClick={() => { goAddr('') }}>
|
||||||
<View className='address-item'>
|
<View className='address-item'>
|
||||||
<View className='address-item-name'>李四 18080093730</View>
|
{!!addrData.id && <View className='address-item-name'>{addrData.recipient_name} {addrData.recipient_phone}</View>}
|
||||||
<View className='address-info'>四川省 成都市 天府二街</View>
|
{!!addrData.id && <View className='address-info'>{addrData.province?.name}{addrData.city.name}{addrData.county.name}{addrData.address}</View>}
|
||||||
{/* <View className='address-item-name text-gold'>选择地址</View> */}
|
{!addrData.id && <View className='address-item-name text-gold'>选择地址</View>}
|
||||||
</View>
|
</View>
|
||||||
<View className='address-next'>
|
<View className='address-next'>
|
||||||
<Image src={next} />
|
<Image src={next} />
|
||||||
@ -76,11 +99,11 @@ function Index() {
|
|||||||
<View className='settle-goods'>
|
<View className='settle-goods'>
|
||||||
<View className='settle-goods-title'>商品信息</View>
|
<View className='settle-goods-title'>商品信息</View>
|
||||||
<View className='settle-goods-info'>
|
<View className='settle-goods-info'>
|
||||||
<Image className='settle-goods-img' />
|
<Image className='settle-goods-img' src={info.cover_image} />
|
||||||
<View className='settle-goods-content'>
|
<View className='settle-goods-content'>
|
||||||
<View className='settle-goods-content-title line-clamp-1'>商品名称</View>
|
<View className='settle-goods-content-title line-clamp-1'>{info.name}</View>
|
||||||
<View className='settle-goods-content-price'>
|
<View className='settle-goods-content-price'>
|
||||||
<View className='settle-goods-content-price-1'>¥199</View>
|
<View className='settle-goods-content-price-1'>¥{info.price}</View>
|
||||||
<View className='settle-goods-content-price-num'>x1</View>
|
<View className='settle-goods-content-price-num'>x1</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
@ -89,7 +112,7 @@ function Index() {
|
|||||||
|
|
||||||
<View className='settle-price-container'>
|
<View className='settle-price-container'>
|
||||||
<View>总价:</View>
|
<View>总价:</View>
|
||||||
<View className='settle-price-p'>¥199</View>
|
<View className='settle-price-p'>¥{info.price * 1}</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<Button className='buy-btn' onClick={navDetailFn}>去支付</Button>
|
<Button className='buy-btn' onClick={navDetailFn}>去支付</Button>
|
||||||
|
47
src/utils/api.js
Normal file
47
src/utils/api.js
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import { d, put } from './request'
|
||||||
|
import { g, p } from './request'
|
||||||
|
|
||||||
|
export const mallList = async (channel = 'mall', offset = 0, limit = 10) => {
|
||||||
|
return await g(`/products/${channel}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const mallDetail = async (id) => {
|
||||||
|
return await g(`/products/detail/${id}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export const login = async (account, pwd, code) => {
|
||||||
|
return await p(`/users/login`, { phone: account, password: pwd, verification_code: code })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const register = async (data = {}) => {
|
||||||
|
return await p(`/users/register`, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const sendCode = async (phone) => {
|
||||||
|
return await p('/users/sms-verification-code', { phone })
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 创建地址
|
||||||
|
export const createAddress = async (data = {}) => {
|
||||||
|
return await p(`/users/addresses`, data)
|
||||||
|
}
|
||||||
|
export const updateAddress = async (id, data = {}) => {
|
||||||
|
return await put(`/users/addresses/${id}`, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const deleteAddress = async (id) => {
|
||||||
|
return await d(`/users/addresses/${id}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const getAddress = async (data = {}) => {
|
||||||
|
return await g(`/users/addresses`, data)
|
||||||
|
}
|
||||||
|
// 获取城市
|
||||||
|
export const cities = async (pid = 0) => {
|
||||||
|
return await g('/cities', { pid })
|
||||||
|
}
|
135
src/utils/request.js
Normal file
135
src/utils/request.js
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
import Taro from '@tarojs/taro';
|
||||||
|
import config from '../config/config';
|
||||||
|
import {
|
||||||
|
DelData,
|
||||||
|
GetData,
|
||||||
|
JWT
|
||||||
|
} from './storage';
|
||||||
|
|
||||||
|
const loginPages = '/pages/login/index';
|
||||||
|
|
||||||
|
function RequestError(message, code) {
|
||||||
|
this.name = 'RequestError'
|
||||||
|
this.message = message || '请求失败'
|
||||||
|
this.code = code
|
||||||
|
}
|
||||||
|
// 基础请求
|
||||||
|
// api/user/center_show , get param == contribution , base
|
||||||
|
export function baseRequest(
|
||||||
|
url,
|
||||||
|
method = 'GET',
|
||||||
|
data = {},
|
||||||
|
base = config.api // https://api.yidongpaidui.com/
|
||||||
|
) {
|
||||||
|
if (config.debug) { // false
|
||||||
|
base = config.debugApi
|
||||||
|
}
|
||||||
|
let jwt = GetData(JWT);
|
||||||
|
jwt = typeof jwt === 'string' ? jwt : ''
|
||||||
|
let header = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Jwt': `Bearer ${jwt}`,
|
||||||
|
'Authorization': 'Bearer ' + jwt
|
||||||
|
}
|
||||||
|
|
||||||
|
return Taro.request({
|
||||||
|
url: base + url,
|
||||||
|
data: data,
|
||||||
|
dataType: "json",
|
||||||
|
method: method,
|
||||||
|
header: header
|
||||||
|
}).then(re => {
|
||||||
|
if (config.debug) {
|
||||||
|
console.log(`1、${method} debug request url is: ${url}\r\n2、request Data : `, data, '\r\n3、request header:', header, '\r\n4、response Data is :', re);
|
||||||
|
}
|
||||||
|
let msg = '请求失败'
|
||||||
|
if (re.statusCode !== 200 || re.data.error.code != 0) {
|
||||||
|
msg = re.data.error.message
|
||||||
|
if (!!msg) {
|
||||||
|
Taro.showModal({
|
||||||
|
"title": "信息提示",
|
||||||
|
showCancel: false,
|
||||||
|
"content": msg,
|
||||||
|
mask: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (re.data.error.code.toString() === '40101') {
|
||||||
|
DelData(JWT)
|
||||||
|
const current = Taro.getCurrentPages()
|
||||||
|
const route = current[0].route
|
||||||
|
if (route != 'pages/login/index') {
|
||||||
|
Taro.navigateTo({
|
||||||
|
url: loginPages
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RequestError.prototype = Object.create(Error.prototype)
|
||||||
|
RequestError.prototype.constructor = RequestError
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return re.data.data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// post
|
||||||
|
export function p(url, data, base) {
|
||||||
|
return baseRequest(url, 'POST', data, base)
|
||||||
|
}
|
||||||
|
|
||||||
|
// get
|
||||||
|
export function g(url, data, base) {
|
||||||
|
// api/user/center_show , get param == contribution , base
|
||||||
|
return baseRequest(url, 'GET', data, base)
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete
|
||||||
|
export function d(url, data, base) {
|
||||||
|
return baseRequest(url, 'DELETE', data, base)
|
||||||
|
}
|
||||||
|
|
||||||
|
//put
|
||||||
|
export function put(url, data, base) {
|
||||||
|
return baseRequest(url, 'PUT', data, base)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 上传图片
|
||||||
|
export const upload = async (file) => {
|
||||||
|
let base = config.api
|
||||||
|
if (config.debug) {
|
||||||
|
base = config.debugApi
|
||||||
|
}
|
||||||
|
let jwt = GetData(JWT);
|
||||||
|
jwt = typeof jwt === 'string' ? jwt : ''
|
||||||
|
let header = {
|
||||||
|
// 'Jwt': `Bearer ${jwt}`,
|
||||||
|
'Authorization': 'Bearer ' + jwt
|
||||||
|
}
|
||||||
|
const re = await Taro.uploadFile({
|
||||||
|
url: `${base}api/camp_chat/upload_image`,
|
||||||
|
filePath: file,
|
||||||
|
name: 'image',
|
||||||
|
header: header,
|
||||||
|
})
|
||||||
|
if (re.statusCode == 200) {
|
||||||
|
const resp = JSON.parse(re.data)
|
||||||
|
if (resp.hasOwnProperty("data")) {
|
||||||
|
return resp.data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Taro.showModal({
|
||||||
|
"title": "信息提示",
|
||||||
|
showCancel: false,
|
||||||
|
"content": re.errMsg,
|
||||||
|
mask: true
|
||||||
|
})
|
||||||
|
RequestError.prototype = Object.create(Error.prototype)
|
||||||
|
RequestError.prototype.constructor = RequestError
|
||||||
|
throw new RequestError(re.errMsg, re.statusCode)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
66
src/utils/storage.js
Normal file
66
src/utils/storage.js
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import Taro from '@tarojs/taro';
|
||||||
|
|
||||||
|
// storage key
|
||||||
|
export const JWT = '_jujwt'; // jwt
|
||||||
|
export const JWTEXPIRE = 24 * 3600; // jwt 过期时间
|
||||||
|
export const OPENDATA = '_d' // 微信开放数据 openid unionId sessionKey
|
||||||
|
export const WXUSERINFO = '_wu' // 微信GetUserInfo 数据
|
||||||
|
export const USERINFO = '_u' // 用户信息
|
||||||
|
export const TASKKEY = "_task" // 任务key
|
||||||
|
|
||||||
|
// 同步设置缓存
|
||||||
|
export function SetData(key, data, t = 0) {
|
||||||
|
if (t > 0) {
|
||||||
|
let time = (new Date()).getTime()
|
||||||
|
time = Number(String(time).substr(0, 10))
|
||||||
|
t = time + t
|
||||||
|
}
|
||||||
|
let storage = {
|
||||||
|
expire: t,
|
||||||
|
_data: data
|
||||||
|
}
|
||||||
|
return Taro.setStorageSync(key, storage)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 异步设置缓存
|
||||||
|
export function SetAsyncData(key, data, t = 0) {
|
||||||
|
if (t > 0) {
|
||||||
|
let time = (new Date()).getTime()
|
||||||
|
time = Number(String(time).substr(0, 10))
|
||||||
|
t = time + t
|
||||||
|
}
|
||||||
|
let storage = {
|
||||||
|
expire: t,
|
||||||
|
_data: data
|
||||||
|
}
|
||||||
|
return Taro.setStorage({
|
||||||
|
key: key,
|
||||||
|
data: storage
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取出缓存 -- _jujwt
|
||||||
|
export function GetData(key) {
|
||||||
|
let storage = Taro.getStorageSync(key)
|
||||||
|
if (!storage) {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
if (storage.expire > 0) {
|
||||||
|
let time = (new Date()).getTime()
|
||||||
|
time = Number(String(time).substr(0, 10))
|
||||||
|
if (time > storage.expire) {
|
||||||
|
DelData(key)
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return storage._data
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除缓存
|
||||||
|
export function DelData(key) {
|
||||||
|
return Taro.removeStorage({
|
||||||
|
key: key
|
||||||
|
})
|
||||||
|
}
|
36
src/utils/utils.js
Normal file
36
src/utils/utils.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import Taro from "@tarojs/taro"
|
||||||
|
|
||||||
|
export const successNotice = (content) => {
|
||||||
|
Taro.showToast({ title: content, icon: 'success' })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const errorNotice = (content) => {
|
||||||
|
Taro.showToast({ title: content, icon: 'error' })
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const loading = (title = '加载中') => {
|
||||||
|
Taro.showLoading({ title })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const closeLoading = () => {
|
||||||
|
Taro.hideLoading()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const redirectTo = (url) => {
|
||||||
|
Taro.redirectTo({ url })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const navigateTo = (url) => {
|
||||||
|
Taro.navigateTo({ url })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const backTo = () => {
|
||||||
|
Taro.navigateBack({ delta: 1 })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const backOrGo = (url) => {
|
||||||
|
Taro.getCurrentPages().length > 0 ? Taro.navigateBack() : redirectTo(url)
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user