Merge branch 'feat/liujie'

This commit is contained in:
2025-09-04 18:59:48 +08:00
7 changed files with 151 additions and 48 deletions

View File

@@ -27,8 +27,8 @@ export default function UploadFromWx(props: UploadFromWxProps) {
let count = 0 let count = 0
const files = res.tempFiles.map(item => ({ const files = res.tempFiles.map(item => ({
filePath: item.path, filePath: item.path,
description: 'test', description: '封面图',
tags: 'test', tags: 'cover',
is_public: 1 as unknown as 0 | 1, is_public: 1 as unknown as 0 | 1,
id: (Date.now() + count++).toString(), id: (Date.now() + count++).toString(),
})) }))

View File

@@ -57,27 +57,17 @@ export default forwardRef(function UploadImage(props: UploadImageProps, ref) {
setVisible(true) setVisible(true)
setSourceType(sourceType) setSourceType(sourceType)
setMaxCount(maxCount) setMaxCount(maxCount)
fetchImages() fetchImages(sourceType)
} }
})) }))
function fetchImages() { function fetchImages(st: SourceType) {
publishService.getPictures({ publishService.getPictures({ type: st }).then(res => {
pageOption: { if (res.code === 0) {
page: 1,
pageSize: 100,
},
seachOption: {
tag: '',
resource_type: 'image',
dateRange: [],
},
}).then(res => {
if (res.success) {
let start = 0 let start = 0
setImages(res.data.data.rows.map(item => ({ setImages(res.data.rows.map(item => ({
id: (Date.now() + start++).toString(), id: (Date.now() + start++).toString(),
url: item.thumbnail_url, url: item.file_url,
}))) })))
} else { } else {
// TODO: 显示错误信息 // TODO: 显示错误信息

View File

@@ -81,6 +81,38 @@
background-color: rgba(0, 0, 0, 0.3); background-color: rgba(0, 0, 0, 0.3);
} }
.detail-swiper-container {
height: 240px;
margin-top: 15px;
margin-left: 15px;
margin-right: 15px;
overflow-x: scroll;
.detail-swiper-scroll-container {
display: flex;
height: 240px;
width: auto;
align-items: center;
justify-content: flex-start;
flex-wrap: nowrap;
gap: 12px;
.detail-swiper-item {
flex: 0 0 auto;
max-width: calc(100vw - 30px);
max-height: 240px;
&-image {
max-width: 100%;
max-height: 100%;
width: 300px;
height: 300px;
border-radius: 12px;
transition: transform 0.5s;
}
}
}
}
.detail-swiper { .detail-swiper {
height: 240px; height: 240px;
margin-top: 15px; margin-top: 15px;

View File

@@ -4,6 +4,8 @@ import { Cell, Avatar, Progress, Popover } from '@nutui/nutui-react-taro'
import Taro, { useRouter, useShareAppMessage, useShareTimeline, useDidShow } from '@tarojs/taro' import Taro, { useRouter, useShareAppMessage, useShareTimeline, useDidShow } from '@tarojs/taro'
// 导入API服务 // 导入API服务
import DetailService from '../../services/detailService' import DetailService from '../../services/detailService'
import { updateUserProfile } from '../../services/loginService'
import { getCurrentLocation } from '../../utils/locationUtils'
import { import {
useUserStats, useUserStats,
useUserActions useUserActions
@@ -94,7 +96,7 @@ function Index() {
// const { incrementRequestCount, resetUserStats } = useUserActions() // const { incrementRequestCount, resetUserStats } = useUserActions()
const [current, setCurrent] = useState(0) const [current, setCurrent] = useState(0)
const [colors, setColors] = useState<string []>([]) // const [textColor, setTextColor] = useState<string []>([])
const [detail, setDetail] = useState<any>(null) const [detail, setDetail] = useState<any>(null)
const { params } = useRouter() const { params } = useRouter()
const { id, autoShare, from } = params const { id, autoShare, from } = params
@@ -111,11 +113,22 @@ function Index() {
// calcBgMainColors() // calcBgMainColors()
// }, []) // }, [])
useDidShow(() => { useDidShow(async () => {
fetchDetail() await updateLocation()
calcBgMainColors() await fetchDetail()
// calcBgMainColors()
}) })
const updateLocation = async () => {
try {
const location = await getCurrentLocation()
await updateUserProfile({ latitude: location.latitude, longitude: location.longitude })
console.log('用户位置更新成功')
} catch (error) {
console.error('用户位置更新失败', error)
}
}
const fetchDetail = async () => { const fetchDetail = async () => {
const res = await DetailService.getDetail(Number(id)) const res = await DetailService.getDetail(Number(id))
if (res.code === 0) { if (res.code === 0) {
@@ -124,14 +137,18 @@ function Index() {
} }
} }
const calcBgMainColors = async () => { // const calcBgMainColors = async () => {
const textcolors: string[] = [] // const textcolors: string[] = []
for (const index in images) { // // for (const index in images) {
const { textColor } = await getTextColorOnImage(images[index]) // // const { textColor } = await getTextColorOnImage(images[index])
textcolors[index] = textColor // // textcolors[index] = textColor
} // // }
setColors(textcolors) // if (detail?.image_list?.length > 0) {
} // const { textColor } = await getTextColorOnImage(detail.image_list[0])
// textcolors[0] = textColor
// }
// setColors(textcolors)
// }
function handleShare() { function handleShare() {
sharePopupRef.current.show() sharePopupRef.current.show()
@@ -241,10 +258,27 @@ function Index() {
</View> </View>
</View> </View>
</view> </view>
<View className='detail-page-bg' style={{ backgroundImage: `url(${images[current]})` }} /> <View className='detail-page-bg' style={{ backgroundImage: `url(${images[0]})` }} />
<View className='detail-page-bg-text' /> <View className='detail-page-bg-text' />
{/* swiper */} {/* swiper */}
<Swiper <View className="detail-swiper-container">
<View className="detail-swiper-scroll-container">
{
detail?.image_list?.length > 0 && detail?.image_list.map((item, index) => {
return (
<View className='detail-swiper-item' key={index}>
<Image
src={item}
mode="aspectFill"
className='detail-swiper-item-image'
/>
</View>
)
})
}
</View>
</View>
{/* <Swiper
className='detail-swiper' className='detail-swiper'
indicatorDots={false} indicatorDots={false}
circular circular
@@ -266,7 +300,7 @@ function Index() {
/> />
</SwiperItem> </SwiperItem>
))} ))}
</Swiper> </Swiper> */}
{/* content */} {/* content */}
<View className='detail-page-content'> <View className='detail-page-content'>
{/* avatar and tags */} {/* avatar and tags */}
@@ -552,10 +586,10 @@ function Index() {
</View> </View>
</View> </View>
{/* share popup */} {/* share popup */}
<SharePopup ref={sharePopupRef} id={id} from={from} /> <SharePopup ref={sharePopupRef} id={id as string} from={from as string} />
</View> </View>
</View> </View>
) )
} }
export default Index export default Index

View File

@@ -58,7 +58,7 @@ class HttpService {
// 构建完整URL // 构建完整URL
private buildUrl(url: string, params?: Record<string, any>): string { private buildUrl(url: string, params?: Record<string, any>): string {
const fullUrl = url.startsWith('http') ? url : `${this.baseURL}${url}` const fullUrl = url.startsWith('http') ? url : `${this.baseURL}${url.startsWith('/') ? url.slice(1) : url}`
if (params) { if (params) {
const searchParams = new URLSearchParams() const searchParams = new URLSearchParams()

View File

@@ -43,7 +43,7 @@ export const wechat_auth_login = async (phone_code?: string): Promise<LoginRespo
try { try {
// 先进行微信登录获取code // 先进行微信登录获取code
const login_result = await Taro.login(); const login_result = await Taro.login();
if (!login_result.code) { if (!login_result.code) {
return { return {
success: false, success: false,
@@ -93,7 +93,7 @@ export const phone_auth_login = async (params: PhoneLoginParams): Promise<LoginR
phone: params.phone, phone: params.phone,
code: params.verification_code code: params.verification_code
}); });
if (verify_response.code===0) { if (verify_response.code===0) {
return { return {
success: true, success: true,
@@ -130,7 +130,7 @@ export const send_sms_code = async (phone: string): Promise<SmsResponse> => {
const response = await httpService.post('user/sms/send', { const response = await httpService.post('user/sms/send', {
phone: phone phone: phone
}); });
// 修复响应检查逻辑:检查 code === 0 或 success === true // 修复响应检查逻辑:检查 code === 0 或 success === true
if (response.code === 0 || response.success === true) { if (response.code === 0 || response.success === true) {
return { return {
@@ -159,7 +159,7 @@ export const verify_sms_code = async (phone: string, code: string): Promise<Veri
phone: phone, phone: phone,
code: code code: code
}); });
return { return {
success: response.success, success: response.success,
message: response.message || '验证失败', message: response.message || '验证失败',
@@ -207,7 +207,7 @@ export const save_login_state = (token: string, user_info: WechatUserInfo) => {
accessToken: token, accessToken: token,
expiresAt: expires_at expiresAt: expires_at
}); });
// 保存用户信息 // 保存用户信息
Taro.setStorageSync('user_info', user_info); Taro.setStorageSync('user_info', user_info);
Taro.setStorageSync('is_logged_in', true); Taro.setStorageSync('is_logged_in', true);
@@ -222,7 +222,7 @@ export const clear_login_state = () => {
try { try {
// 使用 tokenManager 清除令牌 // 使用 tokenManager 清除令牌
tokenManager.clearTokens(); tokenManager.clearTokens();
// 清除其他登录状态 // 清除其他登录状态
Taro.removeStorageSync('user_info'); Taro.removeStorageSync('user_info');
Taro.removeStorageSync('is_logged_in'); Taro.removeStorageSync('is_logged_in');
@@ -240,7 +240,7 @@ export const check_login_status = (): boolean => {
clear_login_state(); clear_login_state();
return false; return false;
} }
const is_logged_in = Taro.getStorageSync('is_logged_in'); const is_logged_in = Taro.getStorageSync('is_logged_in');
return !!is_logged_in; return !!is_logged_in;
} catch (error) { } catch (error) {
@@ -265,7 +265,7 @@ export const get_token_status = () => {
const is_valid = tokenManager.hasValidToken(); const is_valid = tokenManager.hasValidToken();
const remaining_time = tokenManager.getTokenRemainingTime(); const remaining_time = tokenManager.getTokenRemainingTime();
const is_expired = tokenManager.isTokenExpired(); const is_expired = tokenManager.isTokenExpired();
return { return {
is_valid, is_valid,
remaining_time, remaining_time,
@@ -317,17 +317,28 @@ export const refresh_login_status = async (): Promise<boolean> => {
try { try {
// 检查微信登录状态 // 检查微信登录状态
const is_valid = await check_wechat_login(); const is_valid = await check_wechat_login();
if (!is_valid) { if (!is_valid) {
// 微信登录已过期,需要重新登录 // 微信登录已过期,需要重新登录
clear_login_state(); clear_login_state();
return false; return false;
} }
// 检查本地存储的登录状态 // 检查本地存储的登录状态
return check_login_status(); return check_login_status();
} catch (error) { } catch (error) {
console.error('刷新登录状态失败:', error); console.error('刷新登录状态失败:', error);
return false; return false;
} }
}; };
// 更新用户信息
export const updateUserProfile = async (payload: Partial<WechatUserInfo> & { latitude?: number; longitude?: number; }) => {
try {
const response = await httpService.post('user/update', payload);
return response;
} catch (error) {
console.error('更新用户信息失败:', error);
throw error;
}
};

View File

@@ -129,12 +129,48 @@ class PublishService {
loadingText: '发布中...' loadingText: '发布中...'
}) })
} }
async getPictures(req: getPicturesReq): Promise<ApiResponse<getPicturesRes>> { async getHistoryImageList(req: getPicturesReq): Promise<getPicturesRes> {
return httpService.post('/gallery/list', req, {
showLoading: false,
showToast: false,
})
}
async getPresetImageList(req: getPicturesReq): Promise<getPicturesRes> {
return httpService.post('/gallery/sys_img_list', req, { return httpService.post('/gallery/sys_img_list', req, {
showLoading: false, showLoading: false,
showToast: false, showToast: false,
}) })
} }
async getPictures(req) {
const { type, otherReq = {} } = req
if (type === 'history') {
return this.getHistoryImageList({
pageOption: {
page: 1,
pageSize: 100,
},
seachOption: {
tag: 'cover',
resource_type: 'image',
dateRange: [],
},
...otherReq,
})
} else {
return this.getPresetImageList({
pageOption: {
page: 1,
pageSize: 100,
},
seachOption: {
tag: '',
resource_type: 'image',
dateRange: [],
},
...otherReq,
})
}
}
} }
// 导出认证服务实例 // 导出认证服务实例