feat: fix CommonPopup nesting use and fix some style problem
This commit is contained in:
50
analyze.js
Normal file
50
analyze.js
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
// dist 目录路径,根据你项目实际情况修改
|
||||||
|
const DIST_DIR = path.join(__dirname, 'dist');
|
||||||
|
|
||||||
|
// 递归统计文件大小
|
||||||
|
function getFiles(dir) {
|
||||||
|
let results = [];
|
||||||
|
const list = fs.readdirSync(dir);
|
||||||
|
list.forEach(file => {
|
||||||
|
const filePath = path.join(dir, file);
|
||||||
|
const stat = fs.statSync(filePath);
|
||||||
|
if (stat && stat.isDirectory()) {
|
||||||
|
results = results.concat(getFiles(filePath));
|
||||||
|
} else {
|
||||||
|
results.push({ path: filePath, size: stat.size });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatSize(bytes) {
|
||||||
|
if (bytes < 1024) return bytes + ' B';
|
||||||
|
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(2) + ' KB';
|
||||||
|
return (bytes / (1024 * 1024)).toFixed(2) + ' MB';
|
||||||
|
}
|
||||||
|
|
||||||
|
function analyze() {
|
||||||
|
if (!fs.existsSync(DIST_DIR)) {
|
||||||
|
console.error('dist 目录不存在,请先执行 taro build --type weapp');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const files = getFiles(DIST_DIR);
|
||||||
|
const total = files.reduce((sum, f) => sum + f.size, 0);
|
||||||
|
|
||||||
|
console.log('文件大小分析(按从大到小排序):');
|
||||||
|
files
|
||||||
|
.sort((a, b) => b.size - a.size)
|
||||||
|
.forEach(f => {
|
||||||
|
console.log(
|
||||||
|
`${formatSize(f.size)} | ${(f.size / total * 100).toFixed(2)}% | ${path.relative(DIST_DIR, f.path)}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(`\n总大小: ${formatSize(total)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
analyze();
|
||||||
@@ -54,7 +54,7 @@ const CommonPopup: React.FC<CommonPopupProps> = ({
|
|||||||
closeable={false}
|
closeable={false}
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
className={`${styles['common-popup']} ${className ? className : ''}`}
|
className={`${styles['common-popup']} ${className ? className : ''}`}
|
||||||
style={{ ...style, zIndex: zIndex ? zIndex : undefined }}
|
style={{ zIndex: zIndex ? zIndex : undefined, ...style }}
|
||||||
>
|
>
|
||||||
{showHeader && (
|
{showHeader && (
|
||||||
<View className={styles['common-popup__header']}>
|
<View className={styles['common-popup__header']}>
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
|
width: 240px;
|
||||||
height: 60px;
|
height: 60px;
|
||||||
padding: 8px 6px;
|
padding: 8px 6px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@@ -34,7 +35,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
width: 76px;
|
width: 76px;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
padding: 14px 22px;
|
// padding: 14px 0;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -50,7 +51,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
width: 76px;
|
width: 76px;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
padding: 14px 22px;
|
// padding: 14px 22px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React, { useCallback, useState } from 'react'
|
import React, { useCallback, useRef, useState } from 'react'
|
||||||
import { Image, View, Text } from '@tarojs/components'
|
import { Image, View, Text } from '@tarojs/components'
|
||||||
import img from '../../config/images'
|
import img from '../../config/images'
|
||||||
import UploadSourcePopup from './upload-source-popup'
|
import UploadSourcePopup, { sourceMap } from './upload-source-popup'
|
||||||
import UploadFromWx from './upload-from-wx'
|
import UploadFromWx from './upload-from-wx'
|
||||||
import { CommonPopup } from '../'
|
import { CommonPopup } from '../'
|
||||||
|
|
||||||
@@ -58,6 +58,9 @@ export default function UploadCover(props: UploadCoverProps) {
|
|||||||
} = props
|
} = props
|
||||||
|
|
||||||
const [visible, setVisible] = useState(false)
|
const [visible, setVisible] = useState(false)
|
||||||
|
const uploadSourcePopupRef = useRef<{
|
||||||
|
show: (sourceType: sourceType, maxCount: number) => void
|
||||||
|
}>(null)
|
||||||
|
|
||||||
const onAdd = useCallback((images: CoverImageValue[]) => {
|
const onAdd = useCallback((images: CoverImageValue[]) => {
|
||||||
// FIXME: prev is not latest value
|
// FIXME: prev is not latest value
|
||||||
@@ -86,6 +89,7 @@ export default function UploadCover(props: UploadCoverProps) {
|
|||||||
round
|
round
|
||||||
position="bottom"
|
position="bottom"
|
||||||
hideFooter
|
hideFooter
|
||||||
|
zIndex={1000}
|
||||||
>
|
>
|
||||||
<View className="upload-source-popup-container" style={{ height: source.length * 56 + 52 + 'px' }}>
|
<View className="upload-source-popup-container" style={{ height: source.length * 56 + 52 + 'px' }}>
|
||||||
{
|
{
|
||||||
@@ -96,7 +100,9 @@ export default function UploadCover(props: UploadCoverProps) {
|
|||||||
item === 'album' ? (
|
item === 'album' ? (
|
||||||
<UploadFromWx onAdd={onWxAdd} maxCount={maxCount - value.length} />
|
<UploadFromWx onAdd={onWxAdd} maxCount={maxCount - value.length} />
|
||||||
) : (
|
) : (
|
||||||
<UploadSourcePopup sourceType={item} onAdd={onAdd} maxCount={maxCount - value.length} />
|
<View className="upload-source-popup-item-text" onClick={() => uploadSourcePopupRef.current?.show(item, maxCount - value.length)}>
|
||||||
|
<Text>{sourceMap.get(item)}</Text>
|
||||||
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</View>
|
</View>
|
||||||
@@ -105,6 +111,7 @@ export default function UploadCover(props: UploadCoverProps) {
|
|||||||
}
|
}
|
||||||
</View>
|
</View>
|
||||||
</CommonPopup>
|
</CommonPopup>
|
||||||
|
<UploadSourcePopup 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)}>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect } from 'react'
|
import React, { useState, useEffect, forwardRef, useImperativeHandle } from 'react'
|
||||||
import { Image, View, Text, ScrollView, Button } from '@tarojs/components'
|
import { Image, View, Text, ScrollView, Button } from '@tarojs/components'
|
||||||
import Taro from '@tarojs/taro'
|
import Taro from '@tarojs/taro'
|
||||||
import img from '../../config/images'
|
import img from '../../config/images'
|
||||||
@@ -17,12 +17,10 @@ type ImageItem = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface UploadImageProps {
|
interface UploadImageProps {
|
||||||
sourceType: SourceType
|
|
||||||
onAdd: (images: ImageItem[]) => void
|
onAdd: (images: ImageItem[]) => void
|
||||||
maxCount: number
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const sourceMap = new Map<SourceType, string>([
|
export const sourceMap = new Map<SourceType, string>([
|
||||||
['history', '历史图库'],
|
['history', '历史图库'],
|
||||||
['preset', '预设图库']
|
['preset', '预设图库']
|
||||||
])
|
])
|
||||||
@@ -31,13 +29,13 @@ const checkImageSelected = (images: ImageItem[], image: ImageItem) => {
|
|||||||
return images.some(item => item.id === image.id)
|
return images.some(item => item.id === image.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function UploadImage(props: UploadImageProps) {
|
export default forwardRef(function UploadImage(props: UploadImageProps, ref) {
|
||||||
const {
|
const {
|
||||||
sourceType = 'history',
|
|
||||||
onAdd = () => void 0,
|
onAdd = () => void 0,
|
||||||
maxCount = 9,
|
|
||||||
} = props
|
} = props
|
||||||
const [visible, setVisible] = useState(false)
|
const [visible, setVisible] = useState(false)
|
||||||
|
const [sourceType, setSourceType] = useState<SourceType>('history')
|
||||||
|
const [maxCount, setMaxCount] = useState(9)
|
||||||
const [images, setImages] = useState<ImageItem[]>([])
|
const [images, setImages] = useState<ImageItem[]>([])
|
||||||
const [selectedImages, setSelectedImages] = useState<ImageItem[]>([])
|
const [selectedImages, setSelectedImages] = useState<ImageItem[]>([])
|
||||||
|
|
||||||
@@ -54,36 +52,50 @@ export default function UploadImage(props: UploadImageProps) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useImperativeHandle(ref, () => ({
|
||||||
if (visible) {
|
show: (sourceType: SourceType, maxCount: number) => {
|
||||||
publishService.getPictures({
|
setVisible(true)
|
||||||
pageOption: {
|
setSourceType(sourceType)
|
||||||
page: 1,
|
setMaxCount(maxCount)
|
||||||
pageSize: 100,
|
fetchImages()
|
||||||
},
|
|
||||||
seachOption: {
|
|
||||||
tag: '',
|
|
||||||
resource_type: 'image',
|
|
||||||
dateRange: [],
|
|
||||||
},
|
|
||||||
}).then(res => {
|
|
||||||
if (res.success) {
|
|
||||||
setImages(res.data.data.rows.map(item => ({
|
|
||||||
id: Date.now().toString(),
|
|
||||||
url: item.thumbnail_url,
|
|
||||||
})))
|
|
||||||
} else {
|
|
||||||
// TODO: 显示错误信息
|
|
||||||
Taro.showToast({
|
|
||||||
title: res.message,
|
|
||||||
icon: 'none'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
setSelectedImages([])
|
|
||||||
}
|
}
|
||||||
}, [visible])
|
}))
|
||||||
|
|
||||||
|
function fetchImages() {
|
||||||
|
publishService.getPictures({
|
||||||
|
pageOption: {
|
||||||
|
page: 1,
|
||||||
|
pageSize: 100,
|
||||||
|
},
|
||||||
|
seachOption: {
|
||||||
|
tag: '',
|
||||||
|
resource_type: 'image',
|
||||||
|
dateRange: [],
|
||||||
|
},
|
||||||
|
}).then(res => {
|
||||||
|
if (res.success) {
|
||||||
|
let start = 0
|
||||||
|
setImages(res.data.data.rows.map(item => ({
|
||||||
|
id: (Date.now() + start++).toString(),
|
||||||
|
url: item.thumbnail_url,
|
||||||
|
})))
|
||||||
|
} else {
|
||||||
|
// TODO: 显示错误信息
|
||||||
|
Taro.showToast({
|
||||||
|
title: res.message,
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function onClose() {
|
||||||
|
setVisible(false)
|
||||||
|
setSelectedImages([])
|
||||||
|
setImages([])
|
||||||
|
setSourceType('history')
|
||||||
|
setMaxCount(9)
|
||||||
|
}
|
||||||
|
|
||||||
const handleConfirm = () => {
|
const handleConfirm = () => {
|
||||||
if (selectedImages.length > 0) {
|
if (selectedImages.length > 0) {
|
||||||
@@ -103,10 +115,11 @@ export default function UploadImage(props: UploadImageProps) {
|
|||||||
<>
|
<>
|
||||||
<CommonPopup
|
<CommonPopup
|
||||||
visible={visible}
|
visible={visible}
|
||||||
onClose={() => setVisible(false)}
|
onClose={onClose}
|
||||||
round
|
round
|
||||||
hideFooter
|
hideFooter
|
||||||
position='bottom'
|
position='bottom'
|
||||||
|
zIndex={1001}
|
||||||
>
|
>
|
||||||
<View className="upload-popup">
|
<View className="upload-popup">
|
||||||
<View className="upload-popup-title">{sourceMap.get(sourceType)}</View>
|
<View className="upload-popup-title">{sourceMap.get(sourceType)}</View>
|
||||||
@@ -154,8 +167,7 @@ export default function UploadImage(props: UploadImageProps) {
|
|||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
</CommonPopup>
|
</CommonPopup>
|
||||||
<View className="upload-source-popup-text" onClick={() => setVisible(true)}>{sourceMap.get(sourceType)}选取</View>
|
{/* <View className="upload-source-popup-text" onClick={() => setVisible(true)}>{sourceMap.get(sourceType)}选取</View> */}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -124,6 +124,7 @@
|
|||||||
&-tags {
|
&-tags {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
|
|
||||||
&-tag {
|
&-tag {
|
||||||
@@ -546,6 +547,7 @@
|
|||||||
|
|
||||||
&-scroll {
|
&-scroll {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
|
width: calc(100% - 116px);
|
||||||
|
|
||||||
&-content {
|
&-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -814,7 +816,7 @@
|
|||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
border: 1px solid rgba(33, 178, 0, 0.20);
|
border: 1px solid rgba(33, 178, 0, 0.20);
|
||||||
background: rgba(255, 255, 255, 0.16);
|
background: rgba(255, 255, 255, 0.16);
|
||||||
padding: 12px 15px;
|
padding: 12px 0 12px 15px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
&-title {
|
&-title {
|
||||||
|
|||||||
@@ -414,7 +414,7 @@ function Index() {
|
|||||||
</View>
|
</View>
|
||||||
{/* participants list */}
|
{/* participants list */}
|
||||||
<ScrollView className='participants-list-scroll' scrollX>
|
<ScrollView className='participants-list-scroll' scrollX>
|
||||||
<View className='participants-list-scroll-content' style={{ width: `${(participants.length + 1) * 108 + (participants.length) * 8 - 30}px` }}>
|
<View className='participants-list-scroll-content' style={{ width: `${participants.length * 103 + (participants.length - 1) * 8}px` }}>
|
||||||
{participants.map((participant) => (
|
{participants.map((participant) => (
|
||||||
<View key={participant.id} className='participants-list-item'>
|
<View key={participant.id} className='participants-list-item'>
|
||||||
{/* <Avatar className='participants-list-item-avatar' src={participant.user.avatar_url} /> */}
|
{/* <Avatar className='participants-list-item-avatar' src={participant.user.avatar_url} /> */}
|
||||||
@@ -509,7 +509,7 @@ function Index() {
|
|||||||
<Avatar className='recommend-games-list-item-addon-avatar' src={game.avatar} />
|
<Avatar className='recommend-games-list-item-addon-avatar' src={game.avatar} />
|
||||||
<View className='recommend-games-list-item-addon-message'>
|
<View className='recommend-games-list-item-addon-message'>
|
||||||
<View className='recommend-games-list-item-addon-message-applications'>
|
<View className='recommend-games-list-item-addon-message-applications'>
|
||||||
<Text>报名人数 {game.checkedApplications} / {game.applications}</Text>
|
<Text>报名人数 {game.checkedApplications}/{game.applications}</Text>
|
||||||
</View>
|
</View>
|
||||||
<View className='recommend-games-list-item-addon-message-level-requirements'>
|
<View className='recommend-games-list-item-addon-message-level-requirements'>
|
||||||
<Text>{game.levelRequirements}</Text>
|
<Text>{game.levelRequirements}</Text>
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ const LoginPage: React.FC = () => {
|
|||||||
<View className="background_image">
|
<View className="background_image">
|
||||||
<Image
|
<Image
|
||||||
className="bg_img"
|
className="bg_img"
|
||||||
src={require('../../../static/login/login_bg.png')}
|
src="http://bimwe.oss-cn-shanghai.aliyuncs.com/front/ball/images/2e00dea1-8723-42fe-ae42-84fe38e9ac3f.png"
|
||||||
mode="aspectFill"
|
mode="aspectFill"
|
||||||
/>
|
/>
|
||||||
<View className="bg_overlay"></View>
|
<View className="bg_overlay"></View>
|
||||||
|
|||||||
Reference in New Issue
Block a user