Merge branch 'feat/liujie'

This commit is contained in:
2025-09-08 21:22:53 +08:00
8 changed files with 135 additions and 92 deletions

View File

@@ -25,6 +25,7 @@ export interface UploadCoverProps {
source?: source source?: source
maxCount?: number maxCount?: number
align?: 'center' | 'left' align?: 'center' | 'left'
tag?: 'cover' | 'screenshot'
} }
// const values = [ // const values = [
@@ -34,7 +35,6 @@ export interface UploadCoverProps {
// ] // ]
const mergeCoverImages = (value: CoverImageValue[], images: CoverImageValue[]) => { const mergeCoverImages = (value: CoverImageValue[], images: CoverImageValue[]) => {
console.log(value, images, 11111)
// 根据id来更新url, 如果id不存在则添加到value中 // 根据id来更新url, 如果id不存在则添加到value中
const newImages = images const newImages = images
const updatedValue = value.map(item => { const updatedValue = value.map(item => {
@@ -55,6 +55,7 @@ export default function UploadCover(props: UploadCoverProps) {
source = ['album', 'history', 'preset'] as source, source = ['album', 'history', 'preset'] as source,
maxCount = 9, maxCount = 9,
align = 'center', align = 'center',
tag = 'cover',
} = props } = props
const [visible, setVisible] = useState(false) const [visible, setVisible] = useState(false)
@@ -111,7 +112,7 @@ export default function UploadCover(props: UploadCoverProps) {
} }
</View> </View>
</CommonPopup> </CommonPopup>
<UploadSourcePopup ref={uploadSourcePopupRef} onAdd={onAdd} /> <UploadSourcePopup tag={tag} ref={uploadSourcePopupRef} onAdd={onAdd} />
<div className={`upload-cover-root ${value.length === 0 && align === 'center' ? 'upload-cover-act-center' : ''}`}> <div className={`upload-cover-root ${value.length === 0 && align === 'center' ? 'upload-cover-act-center' : ''}`}>
{value.length < maxCount && ( {value.length < maxCount && (
<div className="upload-cover-act" onClick={() => setVisible(true)}> <div className="upload-cover-act" onClick={() => setVisible(true)}>

View File

@@ -4,17 +4,14 @@ import Taro from '@tarojs/taro'
import uploadApi from '@/services/uploadFiles' import uploadApi from '@/services/uploadFiles'
import './upload-from-wx.scss' import './upload-from-wx.scss'
import { CoverImageValue } from '.' import { CoverImageValue } from '.'
import { uploadFileResponseData } from '@/services/uploadFiles'
export interface UploadFromWxProps { export interface UploadFromWxProps {
onAdd: (images: CoverImageValue[], onFileUploaded: Promise<{ id: string, data: uploadFileResponseData }[]>) => void onAdd: (images: CoverImageValue[], onFileUploaded: Promise<{ id: string, url: string }[]>) => void
maxCount: number maxCount: number
} }
async function convert_to_jpg_and_compress (src: string, { width, height }): Promise<string> { async function convert_to_jpg_and_compress (src: string, { width, height }): Promise<string> {
console.log(width, height, '13123132')
const canvas = Taro.createOffscreenCanvas({ type: '2d', width, height }) const canvas = Taro.createOffscreenCanvas({ type: '2d', width, height })
console.log(canvas, canvas.width, canvas.height, 'canvas')
const ctx = canvas.getContext('2d') as CanvasRenderingContext2D const ctx = canvas.getContext('2d') as CanvasRenderingContext2D
const image = canvas.createImage() const image = canvas.createImage()
@@ -23,14 +20,13 @@ async function convert_to_jpg_and_compress (src: string, { width, height }): Pro
image.src = src image.src = src
}) })
ctx.clearRect(0, 0, width, height) ctx.clearRect(0, 0, width, height)
ctx.drawImage(image, 0, 0, width, height) ctx.drawImage(image as unknown as CanvasImageSource, 0, 0, width, height)
const imageData = ctx.getImageData(0, 0, width, height) // const imageData = ctx.getImageData(0, 0, width, height)
console.log(imageData, 'imageData')
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
Taro.canvasToTempFilePath({ Taro.canvasToTempFilePath({
canvas, canvas: canvas as unknown as Taro.Canvas,
fileType: 'jpg', fileType: 'jpg',
quality: 0.7, quality: 0.7,
success: res => resolve(res.tempFilePath), success: res => resolve(res.tempFilePath),
@@ -43,7 +39,6 @@ async function convert_to_jpg_and_compress (src: string, { width, height }): Pro
async function compressImage(files) { async function compressImage(files) {
const res: string[] = [] const res: string[] = []
for (const file of files) { for (const file of files) {
console.log(file, file.width, file.height, 'file frfdfsfds')
const compressed_image = await convert_to_jpg_and_compress(file.path, { width: file.width, height: file.height }) const compressed_image = await convert_to_jpg_and_compress(file.path, { width: file.width, height: file.height })
res.push(compressed_image) res.push(compressed_image)
} }
@@ -59,15 +54,14 @@ const IMAGE_MAX_SIZE = {
// 标准长宽比,判断标准 // 标准长宽比,判断标准
const STANDARD_ASPECT_RATIO = IMAGE_MAX_SIZE.width / IMAGE_MAX_SIZE.height const STANDARD_ASPECT_RATIO = IMAGE_MAX_SIZE.width / IMAGE_MAX_SIZE.height
type ChoosenImageRes = { path: string, size: number, width: number, height: number }
// 根据图片标准重新设置图片尺寸 // 根据图片标准重新设置图片尺寸
async function onChooseImageSuccess(tempFiles) { async function onChooseImageSuccess(tempFiles) {
console.log(tempFiles, 'tempFiles') const result: ChoosenImageRes[] = []
const result: { path: string, size: number, widht: number, height: number }[] = []
for (const tempFile of tempFiles) { for (const tempFile of tempFiles) {
console.count('tempFile')
const { width, height } = await Taro.getImageInfo({ src: tempFile.path }) const { width, height } = await Taro.getImageInfo({ src: tempFile.path })
const image_aspect_ratio = width / height const image_aspect_ratio = width / height
let fileRes: { path: string, size: number } = { path: tempFile.path, size: tempFile.size } let fileRes: ChoosenImageRes = { path: tempFile.path, size: tempFile.size, width: 0, height: 0 }
// 如果图片长宽比小于标准长宽比,则依照图片高度以及图片最大高度来重新设置图片尺寸 // 如果图片长宽比小于标准长宽比,则依照图片高度以及图片最大高度来重新设置图片尺寸
if (image_aspect_ratio < STANDARD_ASPECT_RATIO) { if (image_aspect_ratio < STANDARD_ASPECT_RATIO) {
fileRes = { fileRes = {

View File

@@ -18,6 +18,7 @@ type ImageItem = {
interface UploadImageProps { interface UploadImageProps {
onAdd: (images: ImageItem[]) => void onAdd: (images: ImageItem[]) => void
tag: 'cover' | 'screenshot'
} }
export const sourceMap = new Map<SourceType, string>([ export const sourceMap = new Map<SourceType, string>([
@@ -32,6 +33,7 @@ const checkImageSelected = (images: ImageItem[], image: ImageItem) => {
export default forwardRef(function UploadImage(props: UploadImageProps, ref) { export default forwardRef(function UploadImage(props: UploadImageProps, ref) {
const { const {
onAdd = () => void 0, onAdd = () => void 0,
tag = 'cover',
} = props } = props
const [visible, setVisible] = useState(false) const [visible, setVisible] = useState(false)
const [sourceType, setSourceType] = useState<SourceType>('history') const [sourceType, setSourceType] = useState<SourceType>('history')
@@ -62,7 +64,7 @@ export default forwardRef(function UploadImage(props: UploadImageProps, ref) {
})) }))
function fetchImages(st: SourceType) { function fetchImages(st: SourceType) {
publishService.getPictures({ type: st }).then(res => { publishService.getPictures({ type: st, tag }).then(res => {
if (res.code === 0) { if (res.code === 0) {
let start = 0 let start = 0
setImages(res.data.rows.map(item => ({ setImages(res.data.rows.map(item => ({

View File

@@ -51,7 +51,8 @@ export const publishBallFormSchema: FormFieldConfig[] = [
required: true, required: true,
props: { props: {
maxCount: 9, maxCount: 9,
source: ['album', 'history', 'preset'] source: ['album', 'history', 'preset'],
tag: 'cover',
} }
}, },
{ {

View File

@@ -87,26 +87,16 @@
} }
} }
.detail-page-bg-text {
width: 100%;
height: 100%;
position: fixed;
left: 0;
top: 0;
z-index: -1;
background-color: rgba(0, 0, 0, 0.3);
}
.detail-swiper-container { .detail-swiper-container {
height: 240px; height: 270px;
margin-top: 15px; width: 100%;
margin-left: 15px; padding: 15px 15px 0;
margin-right: 15px; box-sizing: border-box;
overflow-x: scroll; overflow-x: scroll;
.detail-swiper-scroll-container { .detail-swiper-scroll-container {
display: flex; display: flex;
height: 240px; height: 250px;
width: auto; width: auto;
align-items: center; align-items: center;
justify-content: flex-start; justify-content: flex-start;
@@ -115,13 +105,10 @@
.detail-swiper-item { .detail-swiper-item {
flex: 0 0 auto; flex: 0 0 auto;
max-width: calc(100vw - 30px); height: 250px;
max-height: 240px; display: flex;
align-items: center;
&-image { &-image {
max-width: 100%;
max-height: 100%;
width: 300px;
height: 300px;
border-radius: 12px; border-radius: 12px;
transition: transform 0.5s; transition: transform 0.5s;
} }

View File

@@ -1,4 +1,4 @@
import React, { useState, useRef, useImperativeHandle, forwardRef } from 'react' import React, { useState, useEffect, useRef, useImperativeHandle, forwardRef } from 'react'
import { View, Text, Image, Map, ScrollView } from '@tarojs/components' import { View, Text, Image, Map, ScrollView } from '@tarojs/components'
import { Avatar, Popover, ImagePreview } from '@nutui/nutui-react-taro' import { Avatar, Popover, ImagePreview } from '@nutui/nutui-react-taro'
import Taro, { useRouter, useShareAppMessage, useShareTimeline, useDidShow } from '@tarojs/taro' import Taro, { useRouter, useShareAppMessage, useShareTimeline, useDidShow } from '@tarojs/taro'
@@ -23,6 +23,106 @@ function insertDotInTags(tags: string[]) {
return tags.join('-·-').split('-') return tags.join('-·-').split('-')
} }
function GameTags(props) {
const { detail } = props
const tags = [{
name: '🕙 急招',
icon: '',
}, {
name: '🔥 本周热门',
icon: '',
}, {
name: '🎉 新活动',
icon: '',
}, {
name: '官方组织',
icon: '',
}]
return (
<View className='detail-page-content-avatar-tags'>
<View className='detail-page-content-avatar-tags-avatar'>
{/* network image mock */}
<Image className='detail-page-content-avatar-tags-avatar-image' src="https://img.yzcdn.cn/vant/cat.jpeg" />
</View>
<View className='detail-page-content-avatar-tags-tags'>
{tags.map((tag, index) => (
<View key={index} className='detail-page-content-avatar-tags-tags-tag'>
{tag.icon && <Image src={tag.icon} />}
<Text>{tag.name}</Text>
</View>
))}
</View>
</View>
)
}
type CourselItemType = {
url: string
width: number
height: number
}
function Coursel(props) {
const { detail } = props
const [list, setList] = useState<CourselItemType[]>([])
const [listWidth, setListWidth] = useState(0)
const { image_list } = detail
async function getImagesMsg (imageList) {
const latest_list: CourselItemType[] = []
const sys_info = await Taro.getSystemInfo()
console.log(sys_info, 'info')
const max_width = sys_info.screenWidth - 30
const max_height = 240
const current_aspect_ratio = max_width / max_height
let container_width = 0
for (const imageUrl of imageList) {
const { width, height } = await Taro.getImageInfo({ src: imageUrl })
if (width && height) {
const aspect_ratio = width / height
const latest_w_h = { width, height }
if (aspect_ratio < current_aspect_ratio) {
latest_w_h.width = max_height * aspect_ratio
latest_w_h.height = max_height
} else {
latest_w_h.width = max_width
latest_w_h.height = max_width / aspect_ratio
}
container_width += latest_w_h.width + 12
latest_list.push({
url: imageUrl,
width: latest_w_h.width,
height: latest_w_h.height,
})
}
}
setList(latest_list)
setListWidth(container_width)
}
useEffect(() => { getImagesMsg(image_list || []) }, [image_list])
return (
<View className="detail-swiper-container">
<View className="detail-swiper-scroll-container" style={{ width: listWidth + 'px' }}>
{
list.map((item, index) => {
return (
<View className='detail-swiper-item' key={index}>
<Image
src={item.url}
mode="aspectFill"
className='detail-swiper-item-image'
style={{ width: item.width + 'px', height: item.height + 'px' }}
/>
</View>
)
})
}
</View>
</View>
)
}
// 分享弹窗 // 分享弹窗
const SharePopup = forwardRef(({ id, from }: { id: string, from: string }, ref) => { const SharePopup = forwardRef(({ id, from }: { id: string, from: string }, ref) => {
const [visible, setVisible] = useState(false) const [visible, setVisible] = useState(false)
@@ -565,20 +665,6 @@ function Index() {
}) })
} }
const tags = [{
name: '🕙 急招',
icon: '',
}, {
name: '🔥 本周热门',
icon: '',
}, {
name: '🎉 新活动',
icon: '',
}, {
name: '官方组织',
icon: '',
}]
function handleBack() { function handleBack() {
const pages = Taro.getCurrentPages() const pages = Taro.getCurrentPages()
if (pages.length <= 1) { if (pages.length <= 1) {
@@ -609,40 +695,11 @@ function Index() {
</view> </view>
<View className='detail-page-bg' style={backgroundImage} /> <View className='detail-page-bg' style={backgroundImage} />
{/* swiper */} {/* swiper */}
<View className="detail-swiper-container"> <Coursel detail={detail} />
<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>
{/* content */} {/* content */}
<View className='detail-page-content'> <View className='detail-page-content'>
{/* avatar and tags */} {/* avatar and tags */}
<View className='detail-page-content-avatar-tags'> <GameTags detail={detail} />
<View className='detail-page-content-avatar-tags-avatar'>
{/* network image mock */}
<Image className='detail-page-content-avatar-tags-avatar-image' src="https://img.yzcdn.cn/vant/cat.jpeg" />
</View>
<View className='detail-page-content-avatar-tags-tags'>
{tags.map((tag, index) => (
<View key={index} className='detail-page-content-avatar-tags-tags-tag'>
{tag.icon && <Image src={tag.icon} />}
<Text>{tag.name}</Text>
</View>
))}
</View>
</View>
{/* title */} {/* title */}
<View className='detail-page-content-title'> <View className='detail-page-content-title'>
<Text className='detail-page-content-title-text'>{detail.title}</Text> <Text className='detail-page-content-title-text'>{detail.title}</Text>

View File

@@ -230,8 +230,9 @@ const StadiumDetail = forwardRef<StadiumDetailRef, StadiumDetailProps>(({
} }
}} }}
maxCount={9} maxCount={9}
source={['album', 'history', 'preset']} source={['album', 'history']}
align='left' align='left'
tag="screenshot"
/> />
</SectionContainer> </SectionContainer>
) )

View File

@@ -143,7 +143,7 @@ class PublishService {
}) })
} }
async getPictures(req) { async getPictures(req) {
const { type, otherReq = {} } = req const { type, tag, otherReq = {} } = req
if (type === 'history') { if (type === 'history') {
return this.getHistoryImageList({ return this.getHistoryImageList({
pageOption: { pageOption: {
@@ -151,7 +151,7 @@ class PublishService {
pageSize: 100, pageSize: 100,
}, },
seachOption: { seachOption: {
tag: 'cover', tag,
resource_type: 'image', resource_type: 'image',
dateRange: [], dateRange: [],
}, },