update 1.4.1

main
wwl 2024-03-20 14:49:54 +08:00
parent a2778f0a24
commit 846b34afe1
9 changed files with 223 additions and 113 deletions

View File

@ -16,6 +16,7 @@ function SpCheckboxNew (props) {
const [isChecked, setChecked] = useState(checked)
const onChangeCheckbox = () => {
console.log("🚀 ~ file: index.js:23 ~ disabled:", disabled)
if (disabled) return
setChecked(!isChecked)
onChange && onChange(!isChecked)
@ -45,6 +46,7 @@ function SpCheckboxNew (props) {
)}
></Text> */}
<Text
style={{ color: disabled ? '#ccc !important' : '#000' }}
className={classNames(
{
// iconfont: true,

View File

@ -20,7 +20,7 @@ const initialState = {
agreeMentChecked: false
}
function SpLogin (props, ref) {
const { children, className, onChange, newUser = false } = props
const { children, className, onChange, newUser = false, url = '' } = props
const { isLogin, login, setToken, checkPolicyChange } = useLogin({
policyUpdateHook: (isUpdate) => {
// isUpdate && setPolicyModal(true)
@ -41,13 +41,11 @@ function SpLogin (props, ref) {
useEffect(() => {
if (loginModal) {
fetchPrivacyData()
Taro.login({
success: ({ code }) => {
codeRef.current = code
},
fail: (e) => {
console.error('[sp-login] taro login fail:', e)
}
})
}
@ -66,58 +64,69 @@ function SpLogin (props, ref) {
const handleBindPhone = async (e) => {
setLoginModal(false)
const { encryptedData, iv, cloudID } = e.detail
if (encryptedData && iv) {
const code = codeRef.current
let params = {
code,
encryptedData,
iv,
cloudID,
user_type: 'wechat',
auth_type: 'wxapp'
}
// 内购分享码
const { code: purchaseCode } = Taro.getStorageSync(SG_ROUTER_PARAMS)
if (purchaseCode) {
params = {
...params,
purchanse_share_code: purchaseCode
}
}
Taro.showLoading({ title: '' })
// const { uid } = entryLaunch.getLaunchParams()
const { uid, dtid } = Taro.getStorageSync(SG_ROUTER_PARAMS)
const { gu_user_id } = Taro.getStorageSync(SG_GUIDE_PARAMS)
if (uid) {
// 分销绑定
params['uid'] = uid
}
if (dtid) {
params['distributor_id'] = dtid
}
// gu_user_id: 欢迎语上带过来的员工编号, 同work_user_id
if (gu_user_id) {
params['channel'] = 1
params['work_userid'] = gu_user_id
}
try {
const { token, is_new } = await api.wx.newlogin(params)
if (token) {
setToken(token)
Taro.hideLoading()
setLoginModal(false)
showToast('恭喜您,注册成功')
onChange && onChange()
} else {
showToast('注册失败')
}
} catch (error) {
// const code = codeRef.current
const auth_type = isWeixin ? 'wxapp' : 'aliapp'
api.wx.login({ code: codeRef.current, showError: false, auth_type }).then(async ({ token }) => {
if (token) {
Taro.showLoading({ title: '' })
await setToken(token)
onChange && onChange()
Taro.hideLoading()
}
}
}).catch(async () => {
const { code } = await Taro.login()
const { encryptedData, iv, cloudID } = e.detail
if (encryptedData && iv) {
let params = {
code,
encryptedData,
iv,
cloudID,
user_type: 'wechat',
auth_type: 'wxapp'
}
// 内购分享码
const { code: purchaseCode } = Taro.getStorageSync(SG_ROUTER_PARAMS)
if (purchaseCode) {
params = {
...params,
purchanse_share_code: purchaseCode
}
}
Taro.showLoading({ title: '' })
// const { uid } = entryLaunch.getLaunchParams()
const { uid, dtid } = Taro.getStorageSync(SG_ROUTER_PARAMS)
const { gu_user_id } = Taro.getStorageSync(SG_GUIDE_PARAMS)
if (uid) {
// 分销绑定
params['uid'] = uid
}
if (dtid) {
params['distributor_id'] = dtid
}
// gu_user_id: 欢迎语上带过来的员工编号, 同work_user_id
if (gu_user_id) {
params['channel'] = 1
params['work_userid'] = gu_user_id
}
try {
const { token, is_new } = await api.wx.newlogin(params)
if (token) {
setToken(token)
Taro.hideLoading()
setLoginModal(false)
showToast('恭喜您,注册成功')
onChange && onChange()
} else {
showToast('注册失败')
}
} catch (error) {
Taro.hideLoading()
}
}
})
}
const handleCloseModal = useCallback(() => {
@ -155,6 +164,7 @@ function SpLogin (props, ref) {
if (isLogin) {
onChange && onChange()
} else {
await fetchPrivacyData()
setLoginModal(true)
}
}
@ -259,13 +269,16 @@ function SpLogin (props, ref) {
</View>
</ScrollView>
<View className='btn-wrap'>
{isNewUser && <AtButton className='btn' type='primary' openType="getPhoneNumber" onGetPhoneNumber={handleBindPhone
<AtButton className='btn' type='primary' openType="getPhoneNumber" onGetPhoneNumber={handleBindPhone
}> 同意并继续
</AtButton>
{/* {isNewUser && <AtButton className='btn' type='primary' openType="getPhoneNumber" onGetPhoneNumber={handleBindPhone
}>
同意并继续
</AtButton>}
{!isNewUser && <AtButton className='btn' type='primary' onClick={handleUserLogin}>
同意并继续
</AtButton>}
</AtButton>} */}
</View>
<View className="no-btn" onClick={() => setLoginModal(false)}>不同意</View>
<View className="no-text">

View File

@ -53,6 +53,7 @@ function SpPage (props, ref) {
showNavHomeIcon = false,
showNavSearchIcon = false,
showLogoLoading = false,
alwaysBackUrl = '',
} = props
let { renderTitle } = props
const wrapRef = useRef(null)
@ -299,9 +300,15 @@ function SpPage (props, ref) {
<Text
className={classNames('iconfont', {
// 'icon-home1': cusCurrentPage == 1,
'icon-fanhui': cusCurrentPage != 1
'icon-fanhui': alwaysBackUrl ? true : cusCurrentPage != 1
})}
onClick={() => {
if (alwaysBackUrl) {
Taro.redirectTo({
url: alwaysBackUrl,
})
return
}
if (cusCurrentPage == 1) {
Taro.redirectTo({
url: isGoodsShelves() ? '/subpages/guide/index' : '/pages/index'

View File

@ -41,23 +41,23 @@ export default (props = {}) => {
// 隐私协议
// const checkResult = await checkPolicyChange()
// if (checkResult) {
Taro.showLoading({ title: '' })
// Taro.showLoading({ title: '' })
let code
try {
const { code: _code } = await getCode()
code = _code
} catch (error) {
Taro.hideLoading()
// Taro.hideLoading()
}
try {
if (!code) {
Taro.hideLoading()
// Taro.hideLoading()
setIsNewUser(true)
return
}
const { token } = await getToken(code)
Taro.hideLoading()
// Taro.hideLoading()
setToken(token)
} catch (e) {
Taro.hideLoading()
@ -91,7 +91,6 @@ export default (props = {}) => {
const setToken = async (token) => {
const { redirect_url } = $instance.router.params
console.log('redirect_url', redirect_url)
S.setAuthToken(token)
setIsLogin(true)
await getUserInfo()
@ -177,15 +176,15 @@ export default (props = {}) => {
*/
const getUserInfoAuth = (validate = true) => {
return new Promise((resolve, reject) => {
console.log('getUserInfoAuth:获取用户信息授权(小程序)')
const token = S.getAuthToken()
console.log('getUserInfoAuth:获取用户信息授权(小程序)', token, userInfo)
if (!token && validate) {
showToast('请先登录')
return
// reject()
}
if (isWeixin) {
const { avatar, username } = userInfo
const { avatar, username } = userInfo || {}
if (avatar && username) {
resolve()
} else {

View File

@ -19,7 +19,8 @@ import {
SpNavBar,
SpImage,
SpGoodsItem,
SpChat
SpChat,
SpLogin
} from '@/components'
import api from '@/api'
import {
@ -112,6 +113,7 @@ function Home () {
const [startY, setStartY] = useState(0)
const [startX, setStartX] = useState(0)
const [likeList, setLikeList] = useImmer([])
const { isLogin, isNewUser } = useLogin()
const { initState, openRecommend, openLocation, openStore, appName, openScanQrcode } = useSelector(
(state) => state.sys
@ -387,7 +389,6 @@ function Home () {
// params.distributor_id = undefined
}
const res = await api.shop.getShop(params)
console.log('fetchStoreInfo:', res)
dispatch(updateShopInfo(res))
}
@ -431,6 +432,33 @@ function Home () {
}
}
}
const [recommendTouch, setRecommendTouch] = useImmer({
recommendStartY: 0,
recommendStartX: 0,
recommendEndY: 0,
recommendEndX: 0,
})
const onRecommendTouch = (e) => {
const { clientY, clientX } = e.touches[0]
setRecommendTouch(v => v.recommendStartX = clientX)
setRecommendTouch(v => v.recommendStartY = clientY)
}
const onRecommendTouchEnd = (e) => {
const { clientY, clientX } = e.changedTouches[0]
const { recommendStartY, recommendStartX } = recommendTouch
const deltaY = clientY - recommendStartY
const deltaX = clientX - recommendStartX
if (Math.abs(deltaY) < 50) return
if (deltaY > 0) {
// 下滑操作
console.log("🚀 ~ file: index.js:456 ~ 下滑操作:", '下滑操作')
} else if (deltaY < 0) {
// 上滑操作
console.log("🚀 ~ file: index.js:460 ~ 上滑操作:", '上滑操作')
}
}
const onSwiperChange = (e) => {
const { current } = e.detail
setState((draft) => {
@ -449,6 +477,7 @@ function Home () {
const { activeInfo = {}, currentIndex } = state
const handleApply = () => {
// if (!isLogin) return
let url = '/pages/recommend/detail?id='
if (activeInfo.total_count) {
url = `/pages/recommend/status?id=`
@ -570,10 +599,12 @@ function Home () {
{!isUpOperation && <>
{currentIndex === 0 ? <View className="item-btns">
<View className="item-tit">{activeInfo.activity_name}</View>
{activeInfo.end_time * 1000 >= Date.now() && <View className="item-btn" style={{ paddingRight: 0 }} onClick={handleApply}>
<View className="item-btn-txt">{activeInfo.total_count ? '已报名' : '活动申请'}</View>
<Image className="jiantou" mode="aspectFit" src={require('../assets/hengjiantou.gif')}></Image>
</View>}
<SpLogin newUser={isNewUser} onChange={handleApply}>
{activeInfo.end_time * 1000 >= Date.now() && <View className="item-btn" style={{ paddingRight: 0 }} onClick={() => isLogin && handleApply()}>
<View className="item-btn-txt">{activeInfo.total_count ? '已报名' : '活动申请'}</View>
<Image className="jiantou" mode="aspectFit" src={require('../assets/hengjiantou.gif')}></Image>
</View>}
</SpLogin>
</View> :
<View className="item-img-box">
<View className="item-img-txt"> </View>
@ -603,7 +634,7 @@ function Home () {
</ScrollView>}
{/* 推荐图片+商品 */}
{isUpOperation && <>
{recommend.length > 0 && recommend.map((_item, id) => <View key={id + '__item'}>
{recommend.length > 0 && recommend.map((_item, id) => <View key={id + '__item'} >
<SpImage width={windowWidth * 2} height={windowWidth >= 400 ? 920 : 800} mode='scaleToFill' src={_item.img} isShowMenuByLongpress={false} lazyLoad isNew >
{/* <View className="recommend_btn" style={{ [_item.postions]: '70rpx' }}>
<View className="recommend_btn-title">{_item.text}</View>

View File

@ -110,7 +110,7 @@ function EspierDetail (props) {
const $instance = getCurrentInstance()
// const { type, id, dtid } = $instance.router.params
// const { type, id, dtid } = await entryLaunch.getRouteParams()
const { getUserInfoAuth } = useLogin()
const { getUserInfoAuth, isLogin } = useLogin()
const pageRef = useRef()
const { userInfo } = useSelector((state) => state.user)
const { colorPrimary, openRecommend } = useSelector((state) => state.sys)
@ -327,14 +327,14 @@ function EspierDetail (props) {
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 && !!item.itemData?.item_id)?.map((item) => ({ ...item.itemData, pic: item.itemData.pics?.[0] || '' })) || []
draft.historyTotal = res.total_count
})
if (isLogin) {
api.member.itemHistorySave(data.itemId)
const res = await api.member.itemHistory()
setState((draft) => {
draft.historyList = res.list.filter((item) => item.item_id !== data.itemId && !!item.itemData?.item_id)?.map((item) => ({ ...item.itemData, pic: item.itemData.pics?.[0] || '' })) || []
draft.historyTotal = res.total_count
})
}
}
const getRecommendList = async () => {

View File

@ -1,6 +1,6 @@
import React, { useEffect } from 'react'
import { View, Text, Input, Image } from '@tarojs/components'
import Taro, { getCurrentInstance, useDidShow } from '@tarojs/taro'
import { View, Text, Input, Image, Button } from '@tarojs/components'
import Taro, { getCurrentInstance, useDidShow, useShareAppMessage } from '@tarojs/taro'
import { SpPage, SpHtml, SpCheckbox } from '@/components'
import { useSelector } from 'react-redux'
import { getActiveDetail } from '@/api/community'
@ -17,7 +17,9 @@ const initState = {
visible: false,
checked: false,
formInfo: {},
status: ''
status: '',
isShare: false,
alwaysBackUrl: "/pages/index"
}
export default function detail () {
const $instance = getCurrentInstance()
@ -39,28 +41,43 @@ export default function detail () {
}, [userInfo])
const getActiveDetail = async () => {
const { id: activity_id } = $instance.router.params
const { id: activity_id, alwaysBackUrl } = $instance.router.params
if (!activity_id) return
const { status, activity_info = {}, total_count, user_code } = await api.user.registrationActivity({ activity_id })
const { status, activity_info = {}, total_count, user_code, recordList = {} } = await api.user.registrationActivity({ activity_id })
if (total_count > 0 && !alwaysBackUrl) {
Taro.redirectTo({ url: '/pages/recommend/status?&id=' + activity_id })
return
}
const _start = dayjs(activity_info.start_time * 1000)
const _end = dayjs(activity_info.end_time * 1000)
if (alwaysBackUrl) {
setState(draft => {
draft.alwaysBackUrl = alwaysBackUrl + "?id=" + activity_id
})
}
const _item = recordList.list?.[0] || {}
setState(draft => {
draft.isLoading = false,
draft.activeInfo = {
...activity_info,
user_code,
total_count,
start: `${_start.month() + 1}${_start.date()}`,
end: `${_end.month() + 1}${_end.date()}`,
status,
isLoading: false
}
draft.isLoading = false
draft.activeInfo = {
...activity_info,
user_code,
total_count,
start: `${_start.month() + 1}${_start.date()}`,
end: `${_end.month() + 1}${_end.date()}`,
status: _item.is_write_off === '1' ? 'done' : _item.status,
isLoading: false
}
draft.checked = !!_item
})
}
const { isLoading, activeInfo = {}, visible, formInfo, checked, status } = state
const { isLoading, activeInfo = {}, visible, formInfo, checked, status, isShare, alwaysBackUrl } = state
const handleConfirm = async () => {
if (activeInfo.status) {
Taro.navigateTo({ url: '/pages/recommend/status?success=true&id=' + activeInfo.activity_id })
return
}
if (!checked) {
const res = await Taro.showModal({
title: '提示',
@ -89,9 +106,9 @@ export default function detail () {
}
return <View className={"bottom"}>
<View className='check-box'>
<SpCheckbox checked={checked} colors="#000" onChange={() => setState((draft) => { draft.checked = !checked })} />
<SpCheckbox disabled={!!activeInfo.status} checked={checked} colors="#000" onChange={() => setState((draft) => { draft.checked = !checked })} />
<View>
<Text onClick={() => setState((draft) => { draft.checked = !checked })} >我已经阅读并同意</Text>
<Text onClick={() => !activeInfo.status && setState((draft) => { draft.checked = !checked })} >我已经阅读并同意</Text>
<Text
onClick={() => Taro.navigateTo({ url: '/subpages/auth/reg-rule?type=member_logout' })}
style={`color: #000000;text-decoration: underline;`}
@ -100,7 +117,8 @@ export default function detail () {
</Text>
</View>
</View>
<View onClick={handleConfirm} className={"btn"}>{!status ? '确认报名' : status === 'pending' ? '报名中' : '已报名'}</View>
{/* <View onClick={handleConfirm} className={"btn"}>{!status ? '确认报名' : status === 'pending' ? '报名中' : '已报名'}</View> */}
<View onClick={handleConfirm} className={"btn"}>{!activeInfo.status ? '确认报名' : '报名详情'}</View>
</View>
}
@ -112,6 +130,10 @@ export default function detail () {
}
const handleSubmit = async () => {
if (isShare) {
handeleShare()
return
}
if (!formInfo.username?.trim()) {
Taro.showToast({
title: '请输入姓名',
@ -150,13 +172,11 @@ export default function detail () {
source_type: 'activity'
}
const { template_id } = await api.user.newWxaMsgTmpl(templeparams)
console.log("🚀 ~ template_id:", template_id)
Taro.requestSubscribeMessage({
tmplIds: template_id,
success: () => {
},
fail: (err) => {
console.log("🚀 ~ err:", err)
},
complete: () => {
Taro.navigateTo({ url: '/pages/recommend/status?success=true&id=' + activeInfo.activity_id })
@ -164,11 +184,39 @@ export default function detail () {
})
}
}
const onClickShare = () => {
setState((draft) => {
draft.visible = true
draft.isShare = true
})
}
useShareAppMessage(() => {
return {
title: activeInfo.activity_name,
path: `/pages/recommend/detail?id=${activeInfo.activity_id}`,
// imageUrl: activeInfo.pics[0]
imageUrl: `${process.env.APP_IMAGE_CDN_NEW}/index/logo.png`
}
})
const handleClose = () => {
setState((draft) => {
draft.visible = false
})
setTimeout(() => {
setState((draft) => {
draft.isShare = false
})
}, 800)
}
const formItem = activeInfo.formdata?.key_index || []
// !!activeInfo?.total_count ? <></> :
return (
<SpPage renderFooter={!!activeInfo?.total_count ? <></> : renderFooter()} loading={isLoading} className='page-recommend-detail' isBlack>
<View className="activity_name">{activeInfo.activity_name}</View>
<SpPage renderFooter={!!activeInfo?.total_count ? <></> : renderFooter()} loading={isLoading} className='page-recommend-detail' alwaysBackUrl={alwaysBackUrl} isBlack>
<View className="name-box">
<View className="activity_name">{activeInfo.activity_name}</View>
<Image onClick={onClickShare} className="share_icon" src={require('../../assets/share.jpg')} mode='widthFix' ></Image>
</View>
<View className="activity_time">{activeInfo.start} - {activeInfo.end}</View>
<View className="activity_addr">
<Image mode="widthFix" src={require('@/assets/icon/map.png')}></Image>
@ -180,9 +228,7 @@ export default function detail () {
className={classNames('mask', {
visible: visible
})}
onTap={() => setState((draft) => {
draft.visible = false
})}
onTap={handleClose}
catchtouchmove
></View>
<View
@ -191,13 +237,11 @@ export default function detail () {
})}
>
<View className={classNames('sp-picker-hd')} catchtouchmove>
<Text className='center'>{'报名信息'}</Text>
<AtIcon onClick={() => setState((draft) => {
draft.visible = false
})} value='close' size={14} color='#000' ></AtIcon>
<Text className='center'>{isShare ? '分享' : '报名信息'}</Text>
<AtIcon onClick={handleClose} value='close' size={14} color='#000' ></AtIcon>
</View>
<View className='sp-picker-bd'>
{formItem.map((item, index) => (
{!isShare && formItem.map((item, index) => (
<View className="user-form-item" key={`userinfo-item__${index}`}>
<View className="user-form-item-title">{item.field_title}</View>
<View className="user-form-item-input">
@ -211,7 +255,8 @@ export default function detail () {
</View>
</View>
))}
<View onClick={handleSubmit} className={"btn"}>确认报名信息</View>
{isShare ? <Button openType="share" className={"btn share"} onClick={handleClose} plain>发送给朋友</Button> :
<View onClick={handleSubmit} className={"btn"}>{'确认报名信息'}</View>}
</View>
</View>
</View>

View File

@ -2,6 +2,16 @@
.sp-page-body {
padding: 30px 58px;
}
.name-box {
display: flex;
align-items: flex-start;
justify-content: space-between;
.share_icon {
height: 40px;
width: 60px;
padding: 10px 0 10px 20px;
}
}
.activity_name {
font-size: 40px;
font-weight: bold;
@ -119,6 +129,9 @@
&-disabled {
background: #666;
}
&.share {
margin: 80px 0;
}
}
.user-form {
margin-top: 30px;

View File

@ -128,7 +128,7 @@ export default function status () {
navigateTo('/pages/index')
}
return (
<SpPage loading={loading} title={activeInfo.status === 'pending' ? '待审核' : '预约成功'} className='page-recommend-status' isBlack>
<SpPage loading={loading} title={activeInfo.status === 'pending' ? '待审核' : '预约成功'} className='page-recommend-status' alwaysBackUrl="/pages/index" isBlack>
<View className="">
<SpCheckbox checked={true} colors="#000" label={activeInfo.status === 'pending' ? '待审核' : activeInfo.status === 'done' ? '已签到' : "已预约"}></SpCheckbox>
</View>
@ -153,7 +153,7 @@ export default function status () {
<Image mode="widthFix" src={require('@/assets/icon/map.png')}></Image>
<Text className='value'>{activeInfo?.address}</Text></View>
</View>
<View className="activity_intro" onClick={() => Taro.navigateTo({ url: '/pages/recommend/detail?id=' + activeInfo?.activity_id })}>活动介绍</View>
<View className="activity_intro" onClick={() => Taro.navigateTo({ url: '/pages/recommend/detail?id=' + activeInfo?.activity_id + '&alwaysBackUrl=/pages/recommend/status' })}>活动介绍</View>
{activeInfo.status === 'passed' && activeInfo.status !== 'done' ? <View className="code-box flex-col">
<SpImage src={`member/logo-lan.png`} height={40} mode='heightFix' isNew />
<View className="img-box">