From 005278105db6ae9c7fd13e32f3183732ee0d1b3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=86=E6=B5=B7=E6=B3=A2?= Date: Wed, 20 May 2026 12:21:26 +0000 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=E9=A6=96=E9=A1=B5=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E7=BD=91=E7=AB=99=E5=8D=87=E7=BA=A7=E4=B8=AD=E6=8F=90?= =?UTF-8?q?=E7=A4=BA=E5=BC=B9=E7=AA=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在 MyIndex 组件 componentDidMount 中添加 Alert 弹窗, 提示用户网站正在升级中,部分功能可能暂时无法使用。 Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- js/project/MyIndex.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/js/project/MyIndex.js b/js/project/MyIndex.js index c9b371a..b2d014d 100644 --- a/js/project/MyIndex.js +++ b/js/project/MyIndex.js @@ -8,7 +8,8 @@ import React,{ TouchableHighlight, TouchableOpacity, NavigatorIOS, - Component + Component, + Alert } from 'react-native'; import Swiper from 'react-native-swiper'; import Dimensions from 'Dimensions'; @@ -45,6 +46,11 @@ export default class MyIndex extends Component{ } componentDidMount(){ + Alert.alert( + '温馨提示', + '本网站正在升级中,部分功能可能暂时无法使用,敬请谅解!', + [{text: '我知道了'}] + ); fetch('http://api.gujia007.com/v1/flash-data') .then((res) => { From 96247cab34b9922ca64939d154f97fae3f625d28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=86=E6=B5=B7=E6=B3=A2?= Date: Sat, 23 May 2026 07:33:39 +0000 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20=E9=A6=96=E9=A1=B5=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=AE=9A=E6=97=B6=E4=BB=BB=E5=8A=A1=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=EF=BC=8C=E6=AF=8F=E5=A4=A9=E6=97=A9=E4=B8=8A8=E7=82=B9?= =?UTF-8?q?=E6=8F=90=E7=A4=BA=E7=94=A8=E6=88=B7=E8=B4=AD=E4=B9=B0=E6=96=B0?= =?UTF-8?q?=E4=BA=A7=E5=93=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 _checkDailyReminder 方法,检查当前时间是否为早上8点 - 使用 setInterval 每60秒检查一次时间 - 监听 AppState 变化,应用回到前台时也检查提醒 - 使用日期标记避免同一天重复提醒 - 在 componentWillUnmount 中清理定时器和事件监听 Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- js/project/MyIndex.js | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/js/project/MyIndex.js b/js/project/MyIndex.js index b2d014d..afb83cd 100644 --- a/js/project/MyIndex.js +++ b/js/project/MyIndex.js @@ -9,7 +9,8 @@ import React,{ TouchableOpacity, NavigatorIOS, Component, - Alert + Alert, + AppState } from 'react-native'; import Swiper from 'react-native-swiper'; import Dimensions from 'Dimensions'; @@ -21,10 +22,10 @@ export default class MyIndex extends Component{ super(props); this.state = { - imageurls:[] } - + this._lastAlertDate = null; + this._handleAppStateChange = this._handleAppStateChange.bind(this); } banner(urls){ @@ -45,12 +46,35 @@ export default class MyIndex extends Component{ }); } + _checkDailyReminder(){ + var now = new Date(); + var hour = now.getHours(); + var todayStr = now.getFullYear() + '-' + (now.getMonth() + 1) + '-' + now.getDate(); + if (hour === 8 && this._lastAlertDate !== todayStr) { + this._lastAlertDate = todayStr; + Alert.alert( + '新品推荐', + '今日有新产品上线,欢迎前往线下门店选购!', + [{text: '知道了'}] + ); + } + } + _handleAppStateChange(appState){ + if (appState === 'active') { + this._checkDailyReminder(); + } + } componentDidMount(){ Alert.alert( '温馨提示', '本网站正在升级中,部分功能可能暂时无法使用,敬请谅解!', [{text: '我知道了'}] ); + this._checkDailyReminder(); + this._reminderTimer = setInterval(() => { + this._checkDailyReminder(); + }, 60000); + AppState.addEventListener('change', this._handleAppStateChange); fetch('http://api.gujia007.com/v1/flash-data') .then((res) => { @@ -68,6 +92,12 @@ export default class MyIndex extends Component{ } + componentWillUnmount(){ + if (this._reminderTimer) { + clearInterval(this._reminderTimer); + } + AppState.removeEventListener('change', this._handleAppStateChange); + } render() { let urls = this.state.imageurls; From 15537b9dcc38538ecab6940fb49f1098b58fbb15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=86=E6=B5=B7=E6=B3=A2?= Date: Mon, 25 May 2026 07:54:03 +0000 Subject: [PATCH 3/3] =?UTF-8?q?feat:=20=E9=A6=96=E9=A1=B5=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E7=83=9F=E8=8A=B1=E5=8A=A8=E7=94=BB=E6=95=88=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 Fireworks.js 组件,使用 Animated API 实现烟花动画 - 5个烟花交替发射,从底部升起后爆炸为12个粒子 - 随机颜色、位置和高度,循环播放 - 使用 pointerEvents='none' 不影响页面交互 - componentWillUnmount 中清理定时器 Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- js/project/Fireworks.js | 191 ++++++++++++++++++++++++++++++++++++++++ js/project/MyIndex.js | 2 + 2 files changed, 193 insertions(+) create mode 100644 js/project/Fireworks.js diff --git a/js/project/Fireworks.js b/js/project/Fireworks.js new file mode 100644 index 0000000..ad163ed --- /dev/null +++ b/js/project/Fireworks.js @@ -0,0 +1,191 @@ +'use strict' +import React,{ + StyleSheet, + View, + Animated, + Component +} from 'react-native'; +import Dimensions from 'Dimensions'; + +var screenWidth = Dimensions.get('window').width; +var screenHeight = Dimensions.get('window').height; + +var COLORS = ['#FF5252', '#FF4081', '#E040FB', '#7C4DFF', '#448AFF', '#40C4FF', '#69F0AE', '#FFFF00', '#FFD740', '#FF6E40']; +var PARTICLE_COUNT = 12; + +class SingleFirework extends Component { + constructor(props) { + super(props); + this._mounted = false; + this.riseAnim = new Animated.Value(0); + this.riseOpacity = new Animated.Value(1); + this.particles = []; + for (var i = 0; i < PARTICLE_COUNT; i++) { + this.particles.push({ + x: new Animated.Value(0), + y: new Animated.Value(0), + opacity: new Animated.Value(0), + }); + } + this.state = { + color: COLORS[Math.floor(Math.random() * COLORS.length)], + originX: Math.random() * (screenWidth - 60) + 30, + targetY: -(Math.random() * screenHeight * 0.3 + screenHeight * 0.15), + }; + } + + componentDidMount() { + this._mounted = true; + this._delayTimer = setTimeout(() => { + if (this._mounted) { + this._startAnimation(); + } + }, this.props.delay || 0); + } + + componentWillUnmount() { + this._mounted = false; + if (this._delayTimer) { + clearTimeout(this._delayTimer); + } + if (this._restartTimer) { + clearTimeout(this._restartTimer); + } + } + + _resetValues() { + this.riseAnim.setValue(0); + this.riseOpacity.setValue(1); + this.particles.forEach(function(p) { + p.x.setValue(0); + p.y.setValue(0); + p.opacity.setValue(0); + }); + } + + _startAnimation() { + if (!this._mounted) return; + + this._resetValues(); + + var newColor = COLORS[Math.floor(Math.random() * COLORS.length)]; + var newOriginX = Math.random() * (screenWidth - 60) + 30; + var newTargetY = -(Math.random() * screenHeight * 0.3 + screenHeight * 0.15); + this.setState({color: newColor, originX: newOriginX, targetY: newTargetY}); + + var riseDuration = 800 + Math.random() * 400; + + var riseAnimation = Animated.parallel([ + Animated.timing(this.riseAnim, { + toValue: 1, + duration: riseDuration, + }), + Animated.timing(this.riseOpacity, { + toValue: 0, + duration: riseDuration, + }), + ]); + + var explodeAnimations = this.particles.map(function(p, i) { + var angle = (i / PARTICLE_COUNT) * Math.PI * 2; + var distance = 30 + Math.random() * 60; + var dx = Math.cos(angle) * distance; + var dy = Math.sin(angle) * distance; + + return Animated.parallel([ + Animated.timing(p.x, {toValue: dx, duration: 700}), + Animated.timing(p.y, {toValue: dy + 20, duration: 700}), + Animated.sequence([ + Animated.timing(p.opacity, {toValue: 1, duration: 50}), + Animated.timing(p.opacity, {toValue: 0, duration: 650}), + ]), + ]); + }); + + var self = this; + Animated.sequence([ + riseAnimation, + Animated.parallel(explodeAnimations), + ]).start(function() { + if (self._mounted) { + self._restartTimer = setTimeout(function() { + self._startAnimation(); + }, Math.random() * 1000 + 500); + } + }); + } + + render() { + var color = this.state.color; + var originX = this.state.originX; + var targetY = this.state.targetY; + + var riseY = this.riseAnim.interpolate({ + inputRange: [0, 1], + outputRange: [0, targetY], + }); + + var particleViews = this.particles.map(function(p, i) { + return ( + + ); + }); + + return ( + + + + {particleViews} + + + ); + } +} + +export default class Fireworks extends Component { + render() { + return ( + + + + + + + + ); + } +} + +var styles = StyleSheet.create({ + container: { + position: 'absolute', + top: 0, + left: 0, + right: 0, + bottom: 0, + backgroundColor: 'transparent', + }, +}); diff --git a/js/project/MyIndex.js b/js/project/MyIndex.js index afb83cd..269cf77 100644 --- a/js/project/MyIndex.js +++ b/js/project/MyIndex.js @@ -16,6 +16,7 @@ import Swiper from 'react-native-swiper'; import Dimensions from 'Dimensions'; import ServiceType from './serviceType'; import Home from './Home.js'; +import Fireworks from './Fireworks.js'; var width = Dimensions.get('window').width; export default class MyIndex extends Component{ constructor(props){ @@ -130,6 +131,7 @@ export default class MyIndex extends Component{ + );