阅读视图

立冬虽已过,仍要小心蛇出没。

晚饭时分,窗外突然传来一阵急促的防空警报响声,一脸疑惑,常识里,厦门固定的防空警报试鸣时间是5月10日,为了铭记1938年5月10日厦门沦陷的历史而设立。

所以这不太对劲,赶紧凑到窗前探头观望远处海峡的天空,当下第一反应是,难道是远处海峡上空有敌机入侵或导弹来袭?

认真判断下警报声,是地震警报音,循着声音,才探到楼下高中的同学们有序撤离到操场上,呃,应该是学校的地震撤离演练吧!

虚惊一场,不过趁这个时候,给娃儿们科普一下各类警报音,也是一个好机会。

在给娃儿看抖音各类警报音的时候,突然接到丈母娘打来的微信语音通话,接起来,她很慌张的说,小区电动车停车棚的后门台阶有眼镜蛇。

我第一时间也有些慌,赶紧问下丈母娘有没有被咬到,得到否定回答后,才松一口气,让丈母娘迅速离开,物业群里通知工作人员尽快处理。

舟山眼镜蛇,听闻小区里最近已经捕获了两条,这是第三条,我本身是不太怕蛇的,小时候头铁,徒手抓蛇是基操。不过现在,呃,怕死,所以我不会再像小时候那么头铁。

物业主任效率还不能,没一会就抓到蛇了,他在群里面说打死了,呃,我好心给他圆了下说辞,他愣是没听懂我的意思。

舟山眼镜蛇,已被列入中国国家林业局2023年6月30日发布的《国家保护的有益的或者有重要经济、科学研究价值的陆生野生动物名录》;列入《世界自然保护联盟濒危物种红色名录》——易危(VU);列入《中国生物多样性红色名录》——易危(VU);列入《濒危野生动植物种国际贸易公约》附录Ⅱ。

所以……

丈母娘回到家中,惊魂未定,她说她差点踩到了,在小区后台台阶上准备扫人脸开门的时候,听到扑哧扑哧的声音,才低头一看,吓破了魂。一只流浪猫正和眼镜蛇对峙,所以眼镜蛇才立起来攻击状态,发出扑哧扑哧的声音。

群里人说撒雄黄,其实应该意义不大,小区里有定期撒雄黄粉,作用有限。

最有效的方式可能就是放养几条菜花大王蛇在附近,因为它会把其他毒蛇都吞掉,不然就是保持小区周边有流浪猫,流浪猫发现异物会主动挑逗,便于发现警示。

这都入冬了,南方的天气还是相当变态的三十几度,可能是因为台风凤凰的影响,副热带低压气旋笼罩着,白天闷热,晚上大风,一点都没有冬天的影子。

越是冬天,还能遇见的蛇类,绝大部分是越凶恶的蛇种,这是老人家传下来的口传知识,有没有依据我没搞过调研,所以我也不知道对不对,但是老人言应该还是有所依据的。

这里补一个蛇类应急的处理方式,遇到蛇类,不要去碰,不要太自信自己可以,还有对蛇类的认知判断是什么蛇,然后就准备上手,那是蠢,之前就有刷到过一群户外爱好者,抓了一只小五步蛇在手里把玩,还让驴友们都摸一下,智障至极。

最好的方式就是尽快远离,如果不幸被蛇类咬伤,尽快拿出手机拍下蛇类的照片,毕竟自己死在谁手上,还是要知道的,不然来世报仇都不知道找谁。

开玩笑的,其实就是便于医院判断是什么蛇类咬伤,要用什么血清,神经毒素还是混合毒素,好在第一时间确定。

如果不幸被蛇咬伤,可以搜索微信小程序【赛伦100】,里面可以查看到离你最近的支持血清治疗的医院。

  •  

奶奶落寞的背影

今天这篇文章,其实我并不是很想写下来,不是它不值得我深夜花时间来敲键盘,而是我怕陷入这样的感伤情绪,然后抽不开身。本来已经填上了标题,又关了电脑,深夜泡了一杯苦咖啡,抿上几口,我想,我还是把这篇写完吧,因为这也是我该直面的问题,比如我自己没有顾及的全面,比如我目前做得不够的地方,我需要自我审视。

我的奶奶,今年九十几岁了,是一位性格固执或者可以称得上偏执的老太太,照片是家里四小只和他们的太奶奶。

按照姑姑们曾经的总结,所有的后辈里只有我可以降得住她,其他人要是跟她说点什么,她不高兴了,就发火了,唯独我,她怕我。

当下,这个评价我还是挺受用的,因为我可以解决很多问题,至少她还算听我的话。此刻,我反过来一想,似乎这样的我,我都有点无法原谅自己,因为可能我太强势了,似乎让奶奶受委屈了。

这是个很矛盾的对立问题,如果顺着老太太自己的意愿,有时候真的很折腾人。我可能看起来比较坏,比较霸道,所以她好像真的有点怕我,怕我发火,所以老太太会妥协,会顺着我们的意,最终大家都好。

这里我举个过往发生过的实例。

去年冬天,天气挺冷的,家乡流感盛行,应该还是口罩病毒的变种,后来统称流感了,发烧感冒,父亲是医生,每天早中晚都会回老房子给奶奶查看病情,看体温变化,一开始奶奶还算是听话的,会按照父亲的要求进行吃药,可能因为病毒真的折腾得她一个老人家很累,奶奶开始抵抗,不接受治疗,父亲就很无奈,但也苦口婆心的劝说,奶奶根本不听,还会骂父亲,这里父亲也是很委屈,做也不行,不管她顺着她也不行。

父亲晚上9点多回老房子想要给她量一下体温,她就是不,坚决不开门,最后父亲无奈,只能说:你要是这样,我只能把他们(叔叔和姑姑们)都叫回来,看怎么办?最后她开门了,父亲进房间给她量体温,体温又升高了,需要给她处理降温,需要给她服用抗病毒的药物,奶奶赌气,就是不吃药,而且大冬天的穿着单薄的睡衣就坐在门厅的椅子上搞对抗,给她拿衣服,不穿,给她倒开水,不喝,给她泡药,不服用。

父亲只能把在家的二姑和三姑都喊回来,一起劝她,她还是很强硬,就是不听,还发火,一直以来,她比较关注小姑姑,小姑姑家在深圳,只能给她打视频,劝她要穿衣服,要吃药,她直接当作没听到,不搭理,连小姑姑都搞不定。最后只能找奶奶娘家的侄子侄女(父亲舅舅家的表哥表姐),平时奶奶还是挺在意她娘家人的劝告的的,表舅表姑打电话来,她没发火,就是也不听。

父亲没办法了,只能给我打电话,让我接上三叔,现在马上回老家一趟,听到要叫我们两个回去,她就更火大了,情绪更不好了,谁劝她就跟谁过不去。

我载上三叔,从厦门连夜飞奔回去,心想着奶奶没穿外套,大冬天坐在天井边的椅子上受凉,我一路的超速冲回去,到家已经十一点多了,她已经这样和大家耗了一个多小时,真的,大家都很无奈。

我进门,她直接说我,你回来干什么,为什么要回来。

我耍耍贱说:我不回来不行啊,我就一个奶奶啊,她生病了,不吃药,还不穿外套,还要在这吹风受凉,我不回来,要是没奶奶了怎么办?

她就说一些,我听了很不爽的话,家有一老,如有一宝,我们肯定是希望她长命百岁的,她就专门对着干,说一些反话。

三叔去劝她,要把她扶起来,扶她回房间,她反手就要打人的样子,就是和我们耗着。

到这里,我确实情绪也上来了,想要强制她回房间,那段时间因为腰椎盘突出,右腿酸痛,根本就站不住,而且开车赶回来,坐都坐不住,去扶她的时候,她没动手打我,但是我腰一酸,腿一软,自己就先唉一声坐下去了。

她立马警觉的看了我一眼,然后说了句,你们都出去,都走。

我说:你不吃药不进房间,我们怎么走,传出去,我们这些后代子孙多不孝顺。

她说:我就要坐在这里,我起床后,就没有再回床上去睡的习惯。

我说:现在才十一点多,你是不是发烧懵了,以为现在是凌晨天亮。PS:奶奶的作息很规律,傍晚五点多睡觉,凌晨四点左右起床煮早餐,然后凌晨五点左右,出门散步,回来再吃早餐。

她没搭理我,就要跟我们耗下去,我故意转头跟二姑和二姑父说我腰锥盘突出,现在站不起来,走不了,坐也坐不了,现在就得躺着,不然太疼了。

这话我是故意说给奶奶听的,因为我发现她在意这个,我必须加大PUA她的力度。

我对奶奶说:你确定你不听话,不穿衣服,不进房间睡觉吗?那行,那我陪你,我腰疼,我现在得躺着,你要是要跟我耗,行,我陪你耗着。

这个时候,姑姑跟上了我的节奏,又拿我的腰疼说事,说你看你孙子腰疼得躺着,你这样,他肯定很疼。

看她盯着我看,没有反驳情绪,三叔就走上去,三叔扶住奶奶的手,把她从椅子上扶起来,看她有点意志松动的状态,我也去扶她,嗯,其实不是我们拉她起来的,是她自己站起来的,哈哈。

然后我说:奶奶坐太久了,头会晕,还是先站一会再走。姑姑看她站起来了,立马拿着衣服给她披上,这会她听话了,主动的把外套袖子套进去。

然后就回房间了,她这几十年来都是住的老房子二楼,父亲给她喂药,她吃了。姑姑在房间陪着她,我们在前厅坐了半个多小时,姑姑说她睡下了,体温也正常了,我们才离开。

我一直想把奶奶的房间搬到一楼,这样她就不用爬楼梯回房间睡觉了,之前她一直是拒绝的,第二天跟她说,我说一楼哪一间,你想睡哪间,就给你清理哪一间,找了一下边房是最合适的,房间比较干燥,而且早先是三叔的婚房,里面墙壁和物品都保持较好。其实,她知道自己的年纪和目前的身体状态,她自己爬楼梯也确实很吃力,就说换床她不习惯。我说那简单,把你房间整体搬下来就行。

下午父亲就喊来二姑父,和我和三叔,我们四个就把房间搬空腾出来了,接下来就是搬楼上奶奶睡的床和衣柜箱子。

闽南的古床,全实木的,底座应该有一百多斤吧,要从楼梯搬下来实在麻烦,只能从二楼放下来,我用的腰在楼下硬撑着,他们在从楼上下来接,为此,我多躺了两个月,我的腰啊,路都不太能走了。

好在把房间给她搬下来,按照她在楼上的格局和布置,一模一样,连老黄历放在哪个位置都一模一样。

经过这次的病一场,奶奶的状态变得很差,体力也不好,整天坐在椅子上昏昏沉沉的,病好了之后,母亲就每天给奶奶炖人参鸡汤或者人参瘦肉汤,让父亲带回去给奶奶喝,补身体。

奶奶是个很固执的人,嘴硬得很,我不喝,我不会喝你们一口水,我不会吃你们一口饭,就是坚决的杠着,父亲拿给她,她不喝就是不喝,父亲实在无奈,又拿回家去,母亲知道了,训了父亲一顿,说,明天我给她送过去,看她喝不喝。

第二天开始,母亲每天炖好汤,亲自给奶奶送上去,她们的关系还和年轻时候一样,彼此不怎么说话,但是交流还是有的。

以下内容是我室内监控里看到的:

母亲从保温瓶给她盛在碗里,递给奶奶,奶奶问,这是什么汤?母亲说人参汤,喝了补气血。奶奶说,不用给她弄,会浪费。母亲说,喝了人就有气力,哪里会浪费,你就喝就是了。

然后递给奶奶,看着她,奶奶接过去就咕噜咕噜喝下去了。

然后第二天第三天第四天……反正喝到了奶奶又可以日行散步十公里了,元气终于补回来了,恢复起身体。

对此,我是很敬重我的母亲的,不管婆媳关系当时是怎么样的,想象得到奶奶年轻的时候,有多霸道刁钻,母亲又是大户人家的大小姐,初入这样的家庭,恶婆婆应该可以称呼一下,但是那是她俩之间的婆媳问题,她俩自己处理。母亲尽到了自己的义务和责任,该做的一样都不会落下。

看到奶奶的布鞋底磨平了,会安排我们给奶奶买鞋子,但是要想说让母亲自己给她买鞋子,那我估计母亲肯定不会,毕竟还是有当年心结的,反正每次都是安排我们。

但是对于吃食来讲,就不会,三四天就会给奶奶买面条,买菜,买肉,切好一份份,然后分装成一人份一份一份,让父亲带回去给奶奶放冰箱里,按次自己拿出来煮,买过一次六鳌地瓜,听奶奶说这个地瓜煮地瓜粥好吃,嗯,母亲已经买过好多次了,以前美团优选没倒闭的时候,就自己给她下单买,还能掐指算到她还有没有库存继续补货,后来美团优选倒闭了,多多买菜送不到村子里,就让我们从厦门给奶奶买回去。

这里,我要表扬一下我母亲,其实她一直在以身作则,而我们三个也确实是收到了她的影响,我问过母亲,为啥以前不愉快,现在还能这样做,母亲说,你奶奶现在还能自己做饭自己生活自己照顾自己,就是我们的福气,如果她不能自理,那能不回去照顾她起居吗?还不是我要回去,她们两个(大伯母和三婶)可能会管她吗?

同时,我要讲一个小插曲,对比之下,立见分明。

我婶婶回老家,因为她房子那边冰箱塞不下,所以两颗花菜就放在我家的冰箱里,冰箱奶奶在用,有次我哥哥回去,看到,就想着拿出来给我奶奶把花菜切一切,分成一小份一小份,婶婶看到了,说,不是,这个不是奶奶的,是她的,然后拿回去了,两颗都拿回去了……

除了无语,What can I say?

呃,上面的实例故事,可见奶奶是一个多固执多偏执的老太太。

爷爷1994年9月就走了,她一个人自己生活了这么久,她也不跟我们住,自己做饭自己生活,除了十几年前有次摔断了手,没办法做饭,母亲回去照顾了她两三个月,摔断手之前,她本来和母亲有点口角,关系并不好,但是母亲还是履行了自己的责任,给她做饭,侍候她,但是两个人不说话,母亲负责煮,煮好给她盛起来,她负责吃。

十年前,叔叔一家也都搬到了厦门,我们这些子孙,也都买在了厦门,在厦门生活,平时就是抽空回去看望她。

坦白讲,奶奶是最疼她小儿子的,就是三叔,明眼人都看得出来,但是孙子辈,我敢直接评说,就只有我们兄妹三个,和三姑的儿子(一个小表弟),我们四个对她比较友孝,这话是奶奶自己讲的,她经常跟我埋怨大堂弟电话都没给她打一个,除了全家都回,平时基本不回去看她。我也私下暗示堂弟要给奶奶打电话问侯,但是无果,可能书读多了,就傻了。

两个堂弟,从小就是奶奶带大的,所以可能奶奶觉得比较在意吧。我父亲最早自己独立出来建房子,所以我们从小分家生活,应该说,我们三个孩子,小时候奶奶都没有全职照看过,这个我小时候没啥记忆,是母亲说的。

这里,我不是说就我们孝顺,别人不孝顺,可能每个人表达的方式不一样,我认为的陪伴比较重要,所以我会经常回去看她,喊一句奶奶,她乐呵乐呵,我也心情很好。

早几年,我都在国外生活,只能是偶尔给她打打电话唠唠嗑,她还会念叨说我国际长途电话贵,不要一直给她打。我回来后,可能也因为这几年房子翻建,我经常回去工地,所以我回家的次数,应该是每周回去两三次,最少也是每周必回。其实回去我也不是住老房子那边,开车需要10分钟,我都会回去看看她,和她唠一会天,受我们的影响,我们兄弟两个的孩子们,也很喜欢回去找太奶奶,一回去就冲上去抱住太奶奶太奶奶的喊,奶奶很开心,但是奶奶还是多次跟我埋怨说,堂弟的两个孩子,都不敢靠近她,很怕她老人家。我也只能说,她们还小,比较少回来,不熟悉,所以陌生不敢靠近。

其实,就是大人没有引导。
这话,我也只敢在这里说,毕竟讲出来,徒增家族纷扰。

奶奶的后裔,大伯(非她血脉)、大姑姑(非她血脉)、父亲、二姑、三姑、三叔、小姑姑。

大伯有一子三女,内孙两个,外孙六个。
大姑有一子二女,外孙四个。
我爸有二子一女,内孙四个。
二姑有一子二女,外孙二个。
三姑有一子。
三叔有二子,内孙两个。
小姑姑有一子一女。

这样算下来,奶奶的孙子辈目前有我们十八个,目前玄孙辈二十个,我表哥,我姐,一个堂弟,三个表弟,两个表妹暂时未婚。

其实也是大家族,老太太啊,就是不要太固执,其实也是挺好的。我全篇都没有提伯父家,是因为伯父非她血脉,然后以前分家的时候,伯母确实做了很多事,如今虽然较少纷扰,但是赡养费都不是很想给的那种,所以无需多言。

今天这篇的文章的主题,因为一件事。

叔叔是木匠老师傅,我这次房子翻建,木作就是让三叔手工现场做的,所以三叔回老家做了三个多月的木工,这三个月,就在奶奶的身边,每天都能看得到三叔,三叔性格比较冷,虽然可能话不多,但是看到自己最疼爱的小儿子在身边,奶奶应该也是很满足的。

木工工作竣工了,小堂弟因为脊椎血管畸形,导致神经坏死,十五岁开始坐了轮椅,离不开人照顾,所以跟着三叔回了老家,我想这样出行不便,就回去接他们回厦门。

昨天下午一点多,三叔在自己的房子收拾行李,奶奶自己一个人在老房子的客厅黯然神伤,我进老房子的时候,感觉到奶奶的状态不对,我问她怎么了,她说:这附近七座房子,就她一个人,连蚊子苍蝇都没有(夸大形容的一句方言俗语),我说不会啊,工地不是还在做油漆,天天都有人在的啊,而且我爸每天都会回来的啊,我以为她是因为周边没有人会害怕。

奶奶说,工人五六点做完工就回去了,不是也没人。
我说,等房子都好了,我爸妈肯定会回来住一阵子的。
奶奶说,你爸妈肯定要住药房那边的房子,不会回这里住。
我说,肯定会的,房子建了就是要住,怎么可能不回来这里住。
这个时候,我还没反应过来,还以为她是因为没人害怕。
奶奶突然说:你三叔做完工,要出去厦门了。
我这才突然反应过来,看着她的眼里泪水婆娑,我心疼的握着她的手。
我不知道我应该怎么安慰她,因为我可以经常会来看她,但是她此刻是因为三叔要回厦门而在难过。
我说,那要不你跟我们去厦门住。
奶奶:不要,我都这么老了,我不去。
我说,那我经常回来看你不就好了。

其实,我说这句话的时候,我自己也很清楚,我不是她的小儿子。

但是,我又能做什么呢?愿不愿意,那是我三叔的安排,我能说什么做什么。

搬好行李上车,我启动了车,从后视镜看到奶奶往老房子走的背影,我很心酸,因为我感觉到她的落寞,我不知道三叔有没有注意到,他的母亲的难过。

我发此文,一是深刻反省自己,我对于奶奶,哪里做得还不够,二是我真的想要提醒一下其他人,你们也该做点什么,可是我又不能说,说了就是,你是在指责我吗?然后徒增纷扰。

人,其实挺复杂的,人和人之间其实挺无奈的。每个人都会有自己的生活,我一样也需要在厦门照顾我的家庭我的小孩,我也会有自己的工作,我不能时时刻刻的去陪着奶奶,可能,其他人也一样,这就是理由,或是借口。但是我真的希望,我们,都能为了她,多做一点,比如堂弟能够偶尔给她打打电话唠唠嗑,不像我可以陪她胡扯海侃,至少也可以问一下她在干嘛?吃了吗?

我给家门口和客厅室内都装上了监控,也把监控分发给其他人了,我几乎每天都会刷刷监控,看看奶奶在干什么,父亲每天早上醒来第一件事就是躺床上打开监控看看奶奶在干嘛,有一天奶奶起床比较早,早上还没四点就出门走村里的马路溜达去,父亲六点多醒来,查了监控,看到怎么出去那么久还没回来,不同平常,立马冲回去,到处找奶奶,奶奶坐在电厂的石凳边休息,她说她起太早了,走得比较远,有点累,休息一下。

我也经常凌晨没睡刷一刷即时监控,我可爱的固执的奶奶在干啥,拆假牙下来洗,漱口,吃早餐,倒夜壶,坐在前厅自言自语。

呃,最早装监控,奶奶说我是要监视她,说她又不会偷我家东西……

我说,你肯定不会偷啊,但是防止别人偷啊,毕竟请了这么多外地的工人,肯定要装一个。

然后她就没有念叨监控的事了,其实就是为了守护她。

我不能要求别人像我一样,按照我的标准,我甚至不能多说,我只能尽我能,我能做什么我就去做,我得好好想想,我还可以多做点什么了。

天亮了,我睡觉去了,絮叨完,我可能表达得太啰嗦,看客们随意看看,只是这是我的真实心情记述。

  •  

消失的一百块

法定假期,我不喜出游,因为到哪都有一亿人,最优的选择是回山上避暑,嗯,山上也有几千人,路上车来车往,中秋佳节回乡团圆的人也是很多很多。

月亮是华为手机拍的,扩图是豆包干的,和文章主题没多大关系,拍都拍了,就发一发吧!

今年21号麦德姆台风的原因,虽未直接对福建地区产生影响,但是加强了副热带高压,副热带高压下沉气流空气增温非常明显,八闽大地热得不要不要的,室内温度都有33度以上,一点都不秋天。村里的夜幕晚霞,也是极美的。

邻居家的傍晚炊烟袅袅,这个景象我挺喜欢的,从小看到大。

太阳很晒,娃儿回家挖地瓜,挺好玩的,他也很喜欢玩。

山顶的一个水库,闲着就带娃上山晃一晃,森林区现在已经没有手动割防火带,改成了在山区中间开一条防火的水泥路,把山体森林给分隔开,后期如果山火的话,可以起到隔离火带的作用,所以现在爬山都可以顺着马路走了,挺方便。

媳妇儿拍风景,她是我的风景,哈哈。

太阳实在是毒辣,这几天下来,娃儿们都黑了一圈。

贝勒爷到哪都是这样痞痞的,跟我小时候,一毛一样。

黑衣斜包的就是在下,最近减肥成效非常明显,过几天再专门更新一篇减肥大业。

山上的野柿子是真的甜,其实这不是野柿子,野柿子都是小小颗的,这应该是农村公社化时代开荒的先辈们种下的,后来没有路,也没有去管理和采摘,成了野柿子。

趁着回乡的人多,佛事、结婚、宴请这些活动都挤在这个节日,图人多图热闹,宗族里有多场喜宴,10月3日二房一场订婚,10月6日二房一场结婚,10月8日大房一场结婚。

我们对宗族的定义可能比较严谨和清晰,以我多次和长者交流总结出来的经验,以父系血缘为基础,倒数五代兄弟为堂亲,再往上三代为大宗亲,再再往上为小宗亲。此处我可以画个图,嗯,对,我画个图,之后可以讲解给我的小孩了解,这样他们才能延续宗族脉络传承。

我就画出了从我开始往上的八代,也只按照脉承标注,当然其他的分支都各有各的传承,我就没去细分画出来了,齐安祖后我的先人是第几子我一时想不起来了,得回去翻翻族谱才能确定,我就这样先标注下来了,我的太叔公及伯公下南洋是因为当时国内环境极其恶劣,民国政府还有抓壮丁,所以从这一代开始,兄弟抓阄,抓到阄的人,举家支持他们离家开支,同时放弃家中财产继承,当时最好的去处就是下南洋闯荡,所以他们就出门去了,后裔都在新加坡和马来西亚。

齐安祖祠,每年都会祭祖,从这里出来的都是大宗亲,按我的辈分,第二十一世算,齐安祖应该是我们的第十四世,我们村的第十四代,第一代为颜德公,明永乐年间,自厦门钟宅迁居至此,祖以晒盐为业。

光前祖祠,这里应该是第十五世,这里出来的后人关系又更亲近了,结婚宴请的话,这里出来的人都要相互支持,红白事都要给份子钱。

再接下来的埔后祖,这里就是堂亲了,五代内,兄弟三条脉承,我的太太公(我爷爷的爷爷)是老三,这里出来的人,红白事都要互相帮忙,不止份子钱,还得出人工,必须到场帮忙的那种。

标题故事从这里开始,10月6日婚礼的是埔后祖的次子的后裔,常年居住在深圳,我和他并不是很熟悉,但是他的父亲岁数比我大不了多少,儿时还算是熟识,10月5日,我们就得出人工去帮忙,父亲医院有个会要开,叔叔还在给我的房子木作做收尾工作,所以我和堂弟就代长辈去帮忙了,其实现在婚宴都是承包给别人了,不需要像以前一样要到处去找人借桌子椅子,要去出工人扛座椅,场景布置也都是交给婚庆公司布置了,需要做的也仅仅是采买一些物品以及收红包、记账、手写贺联这些,主人家是不需要动手干活的,全程看着就行。

妇女们比较辛苦,需要煮点心给来帮忙的人吃,要煮四餐大锅饭,来帮忙的人应该有三十几个吧,里面包括妇女们,妇女们从一大早就在厨房切菜做饭,热火朝天的。汉子们相对而言只有三个岗位会比较累人,第一泡茶、第二写帖、第三收账, 也不是说体力劳动辛苦,这三个岗位需要从早上8点待到晚上8点,因为中途会有亲朋来贺礼,流程就是进门先到泡茶区喝一杯喜茶,然后走过来登记写贴,最后给红包记账,收了钱,给递一下喜烟和喜糖。

我又起了个大早,8点多就和堂弟一起过去了,其实路上我也犯嘀咕,这三个差事千万不要叫我们做啊,我也想像他们一样摸鱼,混个脸,打个卡,溜达一下,就跑啦,哈哈。我们一到,那些年长的长辈(老油条)立马把收钱的背包甩给我,那会一阵商业吹捧,说我生意做那么大,收钱最合适了,说我们堂弟是大先生,写贴最合适了…

呃,他们说啥,我们都不暗爽,因为,哈哈,摸不了鱼了,长辈安排的工作总不能不接吧,好吧,那就挽起袖子开干。

这就是我们的工位,我背着一个斜挎包,我们这家家都有一本《人情簿》,里面要记上谁谁谁贺礼多少,这样以后到对方有喜事的时候,就可以翻阅一下,当时人家拿了多少份子钱过来,要高于当时回份子。

绝大部分的人随份子都是现金装红包,但是也有部分人是扫码发红包,我找主人家要了个收款二维码,每次遇到扫码付款的话,我就给新郎的父亲微信发一下名字金额信息报账,一开始还算顺利,但是一会儿新郎的父亲突然坐到我的身边说他那边挺多朋友直接微信给他转账,然后他就在那边念名字和金额,我脑壳嗡嗡的,这样我等下怎么统计和核对我的收支呢?好吧,用最蠢的方法,就是他坐在那边回忆谁谁谁给他转账,告诉我,我就用微信再编辑一下信息发给他,然后我按照我微信聊天记录的内容一条一条的写入《人情簿》,同时堂弟负责写请柬帖子,这总不至于出错吧。

记账的过程中发现了一个问题,就是同样都是从埔后出来的人,怎么只有我们三家(我父亲三兄弟)有随份子钱,其他的大房二房的人都没有随份子,这个留着等下再叙。

收到了晚上8点多,陆陆续续的亲朋好友都来了,我们到了结算时刻,我统计过手的金额,堂弟统计他登记的金额,然后我们再同时报出自己的金额,嗯,现金流未差分毫,其中新郎父亲自己微信收的红包未经我手,我就不知道对不对了,反正他有跟我说,我就微信发一条登记给他,再综合起来,我们放出去的请柬和《人情簿》一摸一样,总计随份子的人有两三百多位,最后一道工序就是把这些人的名字写到《嘉宾名录》里,张贴到主人家客厅墙上。

我把收起来的钱,和单独分成两类的账单都统计出来了,亲手交到新郎父亲的手里,并报数给他,我说你要不要点一下钱,他说:三八啊自己人,你们能来帮忙已经很辛苦你们了,不用点了。其实我的想法是,我们经手的现金,和《人情簿》对上了,并且非现金的部分我们在《人情簿》上也做了个小圆圈的标识,我们核准没出入,那就是对的了,然后我们就回家了。

第二天,因为我有个姨表弟,他们村信奉的里主尊王诞辰,佛事宴请,英济庙始建于宋熙宁元年(1068年),庙内奉祀里主尊王,相传系北宋名将杨延昭的化身。在酒店摆宴,我和这个姨表弟比较熟悉,就我去赴宴了,这条线是亲戚,亲戚如果佛事摆宴请客的话,不需要带份子钱,只需要买一个大鞭炮或者大烟花,还要一份食材(比如一包香菇,或者一捆米粉,或者一箱泡面都可以。)然后我就扛着个大鞭炮去吃宴席,改换兄长去10月6日的婚宴这里帮忙。

中秋夜,先去丈母娘家,订了个蛋糕,带娃儿去给丈母娘过生日,在丈母娘家吃了晚饭,然后再回山上,带娃和爷爷奶奶团圆吃月饼,家里组团再博饼了一回,现金1000给娃儿们玩,抢到的就是给他们的额外零花钱,郡主的状元9,贝勒的状元8。

兄长从这场婚宴回来,也发现了为什么就只收我们三房的随份子钱,他们长房和二房的人都没有随份子,父亲解释说是几年前长房那边有一个结婚的,当时都收了份子钱,但是第二天说埔后厝的都是自己人,就不收来收去的了(实则是因为那家的人只有一个儿子,他儿子就结婚一次,但是别人家儿子多的话,他也要随份子的话,觉得自己特别吃亏。)然后他们就把长房和二房的份子钱都退了,唯独没有退我们三房的,所以我们也都是家家随份子,他们都照收。

10月8日的婚宴是长房那边的,就是上述宗族第一个退份子钱的这个人的弟弟的二儿子结婚,轮到我哥去帮忙。昨天,就是10月7日,他带着份子就去了,晚上回来跟父亲说长房那边说退份子钱,不收红包,说是昨天二房那场婚礼后,他们长房和二房的谈好了,就这么确定了,接下来就不互相收红包了。父亲表示没什么意见,随便吧,母亲就生气了,因为他们那边人丁也不少,这些年我们份子也随了几万块,我们三房因为有两代人下南洋,在家里的就我们三家,所以我们婚宴并不多,眼下我也还没有办酒席,如果我今年办酒席的话,那他们就在这喊不互相随份子了,我们早几年付出去的这部分,不属我们三房最亏吗?

我也生气了,我生气的点并不是因为早前付出去的份子钱,而是,你们大房二房商量这个决定,也没跟我们三房的说啊,还直接说我们三房的年轻人同意了,也没人问我们啊,同意个毛,我和堂弟在二房那天帮忙的时候,我们话都没讲一句,我们又不傻,我们付出去那么多,说不收就不收,是不是傻。

但是我的辈分只到这里了,我也没身份去和他们交涉,对吧,辈分低就等着辈分高的长者商量个结果吧,假期也要结束了,怕明天高速会大堵车,所以提前收拾一下,就回厦门了。

刚到厦门,父亲就给我发来微信,问是不是昨天给二房的婚宴记账,记错了,漏掉了一个人,没给人家记上去,我一脸懵逼。说是刚才二房喜事的新郎父亲晚上来我们家说,说是有一个宗亲,兄弟有三人,只登记了两个名字,漏掉了一个,人家第二天正宴的时候来了,看到墙上的贵宾名录里没有他的名字,搞得很尴尬,像是来蹭吃的一样,问是不是我们给人家漏掉了。

我就反问,那他有收到请柬吗?我有给他请柬吗?如果有请柬,那我肯定收到份子钱了,如果没有收到请柬,那肯定没交份子钱。

二房那个人跟父亲说是,漏掉的那个人是托别人来随的份子,可能自己觉得有随,所以第二天婚宴就直接来了,才看到没他的名字,所以很尴尬。

我做事这么一丝不苟的人,怎么可能犯这个错误,如果这里有出入了,然后我还跟主人家说钱都是对得上的,那不是在影射我做的账有问题嘛,不行不行,我必须掰扯掰扯。

二房那个人,一口咬着说是人家兄弟三人,怎么可能就一个不来随份子呢,我就很不高兴了,这个是小宗亲,随份子就100块钱,我不至于吧,我说我肯定我们的钱和账是对得上的,只要核对一下《人情簿》就行,上面如果没有这个人的名字,那肯定就是这个人没来随份子,如果《人情簿》上有,但是《嘉宾名录》上没有,那就是我堂弟抄写名录的时候漏掉了,但是钱和账是对的。

父亲就去问二房那个人,让他翻阅一下《人情簿》有没有这个漏掉的人的名字,对方表现出来的就是,哎呀,又不是什么大问题,不用去翻看了,这个事就过了啊。

过个毛,这不明摆着就是故意的嘛,你倒是查啊,你不查,还追到我家来说这个事,不介意?

最后我让父亲去问,问来代交份子钱的那个人,他一个人来代交了六份,请柬是6张,请柬没有转交的话,就在他那里,是不是有这个人,主人家不告知《人情簿》里面有没有,那就只能用这个方法了。

最后对方给我打来了电话,说是《人情簿》里面没有,就是那个来代交的人忘记了,少报了名字,也没有给这个人的份子钱。跟我道歉说不好意思,他没有查验,多嘴一说。

我也不能直接表达不满,毕竟大家堂亲关系还是要保持的,我说:没事没事,核对了就可以啦,既然做一件事,肯定是要做好做完整。

末了还得客气的说,如果深圳回来有经过厦门,电话联系一下,来家里坐一下泡茶啊。

其实,就是因为大房退了份子钱,他二房的前一天收份子钱,没退,这就下不来台了,所以找个事情来我们家扑腾一下,好像我都对不起他似的,唉。

吃力不讨好,唉,总结一句,人啊,真丑陋,在宗族交际这件事情上,不是所有人都像我一样,。

  •  

又是一年博饼时,迎中秋庆国庆•叙乡情促公益

时光飞逝,唰一下,一年又一年,去年刚更新的日记《公益促进会晚宴,迎中秋庆国庆,叙乡情促公益。》好像也没过多久,又临近中秋了。

第二届安溪县官桥镇善坛公益促进会第四次会员大会暨中秋联谊活动在厦门牡丹港都圆满举行。

会长致辞:中秋节是团圆的节日,是丰收的节日,也是感恩的节日。今夜,我们虽然身处他乡,但我们的心与故乡紧密相连。今晚,让我们共同品尝美食美酒,共同享受团圆的喜悦,也共同感受由血脉和乡情编织的温暖。安溪县官桥镇善坛村公益促进会成立9年来,积极为厦门和善坛村的发展架起一座合作的桥梁,努力促成在厦善坛宗亲们的互动互联、互帮互助、共同进步,致力于让每位在厦宗亲感受到大家庭的关爱与温暖。在过去的一年里,我们先后组织了高考助学奖学、环善坛公益跑等活动,实实在在为父老乡亲办了一些事。

在今后的日子,善坛公益促进会将继续秉持并发扬“善”的精神,努力为善坛宗亲服务,为家乡善坛村的发展鼓舞与欢呼,并在建设宗亲共同心灵家园的过程中,将善坛公益促进会的“公益”两个字擦得更加响亮。

监事报告:2024年先后开展如下公益活动:

1)  春节敬老扶助活动;

2)  “迎春接福,环村公益跑”;

3)  奖学助学活动;

4)  漳州海澄祭祖活动等。

5) 组织并赞助篮球队参与新春篮球赛。

领导祝酒,举杯共饮家乡情。

晚宴联谊,嗯,突然发现,好多新一代的小伙子,呃,我不认识,侧面反映我开始步入中年,青年一代突起了。

魔术表演,手法,呃,还行。

凤舞舞蹈表演,我们畲族的图腾是凤凰,这个节目挺贴近。

川剧变脸,气氛不错,高潮不断。

小朋友们很喜欢这个节目。

萨克斯演奏,很优雅,我以前学过,但是技艺就上不了台了。

舞蹈节目名称我没记住,但是,哈哈,跳得挺好看,哈哈哈哈。

宴席结束后开启博饼活动。

博饼规则介绍,挺好玩的,不是福建人,也可以试着组织玩一下,博到状元代表接下来的一年都会好运连连。

博饼起源于厦门,是闽南地区特有的中秋民俗活动,相传由明末清初郑成功为解士兵思乡之情、鼓舞士气而创设,将科举制度的功名等级融入掷骰子游戏中。

博饼核心是用6粒骰子掷出不同组合,对应“状元”“榜眼”“探花”等不同奖项,奖品多为月饼或日常用品,如今已成为亲友、同事间中秋聚会的趣味互动。

活动奖品清单,虽然都是些生活用品,但是实用,图中骰子开出来的就是状元插金花,四个四,两个一,天牌的存在。

此次战利品,四个三红奖品,我们拿了三个回家,哈哈,还有几个四进,我已经好多年没有博出状元了,反正乐在参与。

过几天还有几场博饼宴要参加,祝我好运,哈哈,嗯,就这么水了一篇文章。

  •  

又没有车,为什么要等红灯,是不是傻。

昨晚,八九点的时候,接到朋友的电话,问我晚上有空吗?约我喝茶,应约了。

陪娃儿看了部好电影《姥姥的外孙》,泰剧,剧情情节就不透了,可以去看看,潮汕族裔和我们闽南一脉相传的一致,所以剧情代入感极强,几次眼泪婆娑,差点滴落,娃儿在身旁,嗯,故作坚强。

看完电影,催娃洗漱,哄娃睡觉,这是每天的常规流程,折腾完十一点多了,才想起有约,溜达出门,心想也不远,就不开车了,机车在小区车棚里,要步行一段路,小毛驴在小区门口,就骑小毛驴吧,其实我很不喜欢骑小毛驴,总觉得底盘太轻,过弯就晃着飘,当然也许是我太重了。

慢慢悠悠的溜达,前方绿灯倒数12秒,目测距离,小毛驴25km/h可能连黄灯都追不上,呃,也许可能勉强可以,还是算了,等吧,停着等红灯的时候,右后方来了一辆小毛驴,一对中年夫妇,因我在前停车等候,他们从右转道直行闯红灯通过,后座的女的,回头看我一眼,念叨一句:又没有车,为什么要等红灯,是不是傻。

尽管她说的很小声,但是夜太静了,我字字句句都听得很清楚,呃,同是闽南话,她的口音明显是本地土著,听到这句话,我没有感觉到被冒犯,我只是突然间想到了,对哦,都没有车,为什么我还要遵守规则等着红绿灯呢?

然后,我还是等到了绿灯亮起,呃,我觉得遵守交通规则,是一位公民基本的素养,我不能看别人没素质,我也跟着没素质吧,哈哈,再着,万一路口也来一台不礼让的车呢,故事就悲伤了。

读书的时候《道德与法治》里面教的:无规矩不成方圆,我隐约记得是孟子说的。我是一个固守规则的人,生活中一些小小细节,我总是遵从规则,所以我应该是挺无趣的一个人。

到了公司,等了快一个小时,他才来,和另外一个认识的小伙伴一起来的,我在泡茶区泡着茶,大家唠了一会嗑,后来小伙伴先走了,就剩我俩,也没啥主题,就他泡茶,我打一会游戏玩玩手机,气氛看似很正常,平时也经常就这状态,我并没有想多什么。

快三点的时候,他问我,打完了吗?

呃,这是有事聊啊!

我赶紧收起手机,一本正经的,来,啥事?

Ps:其实,我猜到了些什么,他还没开口的时候。

他:想开口再跟你借点钱,这次真的要死了,资金转不过来了。

听到这句话的时候,我有点儿不高兴了,我直接怼回去了。

我:我话就直说了,你也别不高兴,你去年就开始叫要死了要死了,这么久了,还是要死了,你咋不去死?去年说第二天按揭还不上,我就帮你安排了,你说后面还给我,你也没还我,后来你说要再创业,我也入资帮扶你了,一毛钱也没见给我分过,这次又要死了要死了,逮着我造是吗?对不起,我不接受这样的事,救急不救穷,你这不是急,你这是穷,穷还是你自己造的,我帮不上你了。

他一脸的不好意思,任凭我输出,末了还是坚持着希望我能帮帮他:我那个房子想卖,但是现在的行情不好,而且学区房,新学校,没有高年级的班,转学的转不了,所以最近都没有人来看房,有两三组带看的客户,都说考虑一下。

我:来看房就是要买房,你真的想解决问题,就降价赶紧把房子卖了,不然一个月还要一万八的按揭,越拖越死。

他:有啊,我都比别人挂的价格低了。

我:不是挂的价格问题,你就直接一口价,直接别人的成交价再降20万,我不相信还会没人买,你从去年就说你要把这套房子卖了,说了一年你也没卖,你就想着能翻身,然后让别人帮你度难关,你信不信这次我拿给你,你就拿去先解决自己的问题了,房子你还是不会卖。

他:这次不会了,我肯定是要卖的,就是这两三个月比较没什么人看房,过年那会应该价格会比较好出手。

我:你这就很过分了,你手握着房产资产,然后遇到难关就要别人帮你,你如果觉得我说的有道理,你就尽快把房子出手了,你也不是说只有这一套房,卖了就没地方住。

他:你这次再帮我一下,你相信我,我年底肯定把房子卖了,马上把你的钱还你。

我:这无关相不相信,你还是这几天就去操作吧,如果我这次再帮你,你又可以拖一段时间,有得拖,你也不会去做,等把这钱再用完了,你又会是今天这状态。

我拒绝得很坚决,其实内心多少还有些不好意思的,但是我觉得不能一而再再而三了,那我就是冤大头了。认识两年多,受朋友所托,让我多多帮扶,我也挺用心的帮扶了,但这,就有点过分了。

我这一生至此,有欠过别人钱,那也只是生意上的亏损欠款,想法设法都要还清,我从来没有找别人借钱用来度生活,口袋只有十块钱,我都会掰着花,熬过去。

他不止一套房,说要卖掉的房子,还是投资房没有住,按揭还不上,怕断供,就要借钱,为什么不自己去承担呢?把压力给到朋友帮他担着,所谓朋友,这是朋友吗?

然后三点多,我就回家了,四点多他截图和他媳妇的聊天记录给我看,对话中意思是这次他们真的要破产了,他媳妇想到这个点烦死了还睡不着。然后他说他也是没办法才又找我的,希望我能再帮帮他。

我直接已读不回,呃,你睡不着,关我什么事,你破不破产关我什么事,又不是我害你破产的。

我想,朋友,应该是资源上互相整合促进共同发展,而不是,朋友,借点钱花花。

我想,我的坚持是对的,这一次。

  •  

我们终有老的那一天。

这个暑假唰一下就过了,小郡主钢琴考级集训陪练了半个月,贝勒爷奥数班特训接送了半个月,各种补习培训班排满满,所以这个暑假就没有带娃出远途玩了,只是在同城周边的一些小景点晃悠一下,带娃去深山里溯溪,玩是挺好玩的,就是山涧里的石头爬满青苔太滑溜,出去玩,其实就是时刻盯着保护着娃儿。八月中才想起带贝勒爷去噶了下包皮,然后临近开学了。

趁着暑期的尾巴,带娃回老家山里住了几天,刚好镇区医院进行年度公卫体检下乡活动,给村里的老人家做体检,闲着也闲着,我做了志愿者义工,每天早上6点多就起床Standby,连续五天,呃,起床太早,确实有些不太习惯,但是好在坚持住了,每天都准时到岗。

村里常住人口也就七百多个吧,都是些留守老人,总共给537位65岁以上的老人家做了综合体检,验血象、B超、肺部拍片、心电图、血压、血糖、白内障筛查、尿检、中医问诊。检查项目比较多,年长的老人有近百岁,很多都是不识字的,医生叫到普通话名字反应不过来的,好在都是同村老人,我的作用就体现了,穿过来跑过去的扶这位过来这里检查,扶那位到那边检查。

第一天,刚开始,比较没经验,现场才收身份证,导致很多老人家总想着占便宜,想要插队串队排到前面去,整个村委会的会场乱糟糟,明明喊到的名字不是他,就给人家坐下去要抽血,护士小姐姐解释说要按照名字打的条码来抽血,人家就是不听劝,硬要插队。形形色色的人,各种丑态,甚至恶心的嘴脸都有,因为要抽血检查,所以通知的就是空腹抽血,但是人比较多,怕老人家会肚子饿,我爸掏钱买了两千多块钱的牛奶和面包,分成一份份,准备给老人家抽完血垫肚子充饥的,看到有免费的东西拿,竟然有人偷拿(未达65周岁,没有体本次体检资格的人),还有走一圈过来拿一份,不注意,又来拿一份。唉,无奈,甚是无奈。第一天就在这样乱糟糟的状态下,顺利完成了任务。

第二天开始,按照名单,排队一道一道项目检查下去,终于捋顺,除了行动不便的老人,或者近百高龄,和基础慢性病的老人,由我搀扶着的优先可以做项目检查,其他的全部一律按照名单,想插队的直接告知,你可以选择自己去镇区医院做检查,我们不提供服务。一般想插队的都是六十五出头,还行动很健全的人,嗯,我凶起来还是有用的,毕竟江湖传说我年少的时候,也是个小流氓来着。

之后,我发现了一个问题,就是没有一个年轻人,或者后辈陪同这些老人,一个都没有,没有人陪他们来体检,看着有些心疼,看到一个个白发苍苍,步履阑珊的老人,这些都是留守孤寡…  我甚至有些想问候他们的孩子,用最脏的脏话。

第二天开始,我就多了个业务,接送老人,开着车在村子里串来串去的,让老人自发的组织人员在某个位置等我,我去接他们,我们村子挺大的,最远的距离有三公里多,丘陵地貌,环山公路,老人家徒步来去实在太远和不方便,因为开车接送,所以和老人们接触就多了,得到最多赞美是:你人真好,你好善良,还接送我们。

嗯,内心是有些窃喜的,至少是被赞扬了嘛!

前后五天,最后一天的检查,终于在会场看到一位年轻家属,唯一一个,大概三十出头,虽然长相一般,但是我觉得她很美,因为她全程搀扶着一位老奶奶做检查,听到边上的人讨论,说那是老奶奶的孙媳妇。

我们终有老的一天,我站在这个角度上,尽心用心耐心的服务他们,搀扶着,温柔的解释指导,搀扶着,我也闻到了所谓的老人味,这是我未曾闻过的,嗯,味道确实很不好,但是我就是个服务志愿者,我上手了,我也因为我直接上手而给自己一个赞,同时也获得到老人们的真诚夸赞,这是双向的情感互动,我乐在其中。

我们终有老的一天,我希望那时候,我的孩子们可以有人陪着我做体检,不然我依然会骂最脏的脏话,我也希望那时候我能遇见另一个我。

呃,此文不表我的爱心,我只是帮助完成我父亲卫健的医院工作,当然,我不否认在当下,我的爱心确实存在。

  •  

装修记:石材进度完成,接下来木作进场。

电子垃圾堆柜子里有三台电脑,一台华为Matebook 14,网卡坏了,驱动怎么更新都无果,搜不到WiFi ,可能重装一下系统就可以了,但是我懒啊,丢进柜子里了;一台MacBook Pro 2017,呃,十次有九次硬盘读取错误,开机显示文件夹,听说是版本通病,半年前被我扔进冷宫了;整理家里老旧物件的时候,淘出来一台微软Surface Book 2,这台老家伙应该是N多年前路过香港买的,原本开不了机,在海鲜市场买了电池和电源,它启动起来的那一刻,我有点感动,心想这不得再伴我苦战个两三年,看来期望值还是太高了,上个月偶发键盘N/M键故障,敲打带一堆符号,呃,而后不是偶发,是完全坏透,心想要不再闲鱼买个键盘回来自己换吧,呃,我懒,我不想再折腾了,丢进去柜子了。

所以已经好久没有敲电脑了,好久没有更新博客了,我叨叨了这么长篇幅,就是为了解释我为啥最近没更新,呃,不是我偷懒,是没电脑用啊,现在用手机更新,真的很不习惯,也很不方便。

最近工地比较忙,所以在老家待了很长一段时间跟进,直到娃儿要期末考了,提前一周回厦门窝家里,待命辅导。

……

上面的内容是7月4号打的文字,没打完就草稿了,嗯,七月份的工期不能拖到8月份更新,好吧,续写。

客厅公区效果图

先更新下石材部分内容吧,这个装修基本亲力亲为,都有参与到。

这些背景奢石真心搞得我有点累,加工厂问题不断,石英材质太硬又脆,版面又大,运输只能分成好几车好几趟运输,单运输和保险就花了一万多。

运过来一路坎坷,卸下来更是头疼得很,农村丘陵地方,虽然路修到了家门口,路却是又弯又陡,7米多长的货车根本就开不下去,其实可能司机师傅胆子大一点点就开下去了,但是人家看了下边上的悬崖,愣是不敢,咱也不敢逼人家不是。

只能想办法找了台农用车卸装分趟运到家门口,想用吊车,吊车可以在大路上卸装到小车上,但是小车上要卸下来,吊车也下不去,所以作罢。叫来了叉车,叉车师傅也是看了一下路,说它的刹车刹不住,太陡了,他也下不去,然后扭头就说要走了,空车来没工作,还得给他500元加油费。

然后叫来一台轮拐,就是挖掘机,我们这叫怪手,司机是敢,但是它的机械臂拉伸的力度不够,石头太重,差点就把石头给磕碎了。

最后,叫来了装载机,就是推土车,呃,好不容易,唉。

大家都不专业,一群人忙活了四个多小时才弄完,唉,然后磕破磕断了好多大理石,呃,加上原来大理石有些阴阳色,版面不好看的切掉,只能去买新的白玉兰石材,又补了几万块的石头材料费。

好吧,好事多磨,慢慢来吧!

石头卸下来了,就火急火燎的要弄背景灯板,之前想着直接找给我做楼梯感应灯带的小伙子做吧,人还算实诚,妈蛋,实诚,实诚个鬼,我想用品牌的灯源,他硬给我安利推荐一个我也没听过的牌子,而且价格也不算便宜。

中间还闹了不愉快,我送娃儿去上钢琴课的时候,得闲就搜了一下,他介绍的品牌,唉,小公司小杂牌,我就想说要不用外墙灯光的光源吧,三雄极光,人家好歹是上市公司,应该比较有保障。

所以就找三雄极光询了价,人家产品价格便宜一半,安装费也很行情,只要2000元。这个小伙子要安装费6000元,我又不傻,我也是会比价的好吧,心想找人家跑现场看了,优先想让他做,看我买三雄极光的灯带,安装费也2000元,他做吗?他不同意,我就答应三雄极光的人了,鉴于此情况,我还发了300红包给那师傅,人家还不高兴了,意思是我不厚道,说给他做,最后不给他做,还给我闹脾气了,说红包他不收,不收个毛,最后红包和订货的运费,他都收了。

算了算了算了,格局太小,不和他计较了,他这得罪我了,我们村的项目,他是一个都别想拿了。

灯光效果我自己设计的,我弄了两个色温,一个3000k,一个4000K,灯带底板用的亚克力瓷白板,然后每隔5cm跳着贴一条灯带,这样同色温的每条灯带距离10cm,底板和石材距离10cm,出光效果不错不错。

辛苦三雄极光的两位小兄弟了,我们一起弄了两天才完成,唉,2000安装费,那他们俩的工薪就每人每天500元,确实不好赚。

灯光好了,就到石材上墙了,呃,这个我虽然我没有参与,因为我怕我碍手碍脚的帮倒忙。

各位师傅辛苦了,每块石头500多斤,好几个个师傅一二一二的才弄好,一块石头的上墙费5000元,这五块奢石就花了25000元,好吧,好吧,这钱该人家赚,真的太不容易。

师傅安装完工后,露出了好高兴的表情,终于完工了。

接下来,嗯,半成品展示时间,我是挺满意的。

客厅背景白色潘多拉发光效果,呃,照片像素损了。

门厅入户潘多拉,这块最贵,上面好多玉化的云母片。

门厅的紫气东来,这块也是可以透光的,但是如果透光就和大理石门框不搭配了,算了,这块就没透光,也很好看,到时候放一块玄关几,上面打射灯也行。

楼梯的这块蓝天玉奢石太赞了,完全满足我期待的效果,这块石头刚出来,那会没什么设计师采用,最近发现抖音很多设计师开始用上了这块石材,价格也水涨船高了,嘿嘿,我眼光可以。

视频像素还是压缩丢了,唉,不然真真好看,等后面竣工再用好设备出片不压缩。

木作师傅是我亲三叔,他做木工三十几年了,我就全部交给他负责了,买的几套房子装修也都是他负责,住了这么久,一点毛病都挑不出来的那种,所以我就比较没回去巡查了,交给他就好了,过几天再回去看看,家具柜子也准备全部手工制作,不想用全屋定制。

  •  

夜色属于孤独的盛宴,黑暗与光影交织,灵魂在低沉中沉淀。

夜幕低垂,夜色将城市浸染成一片深邃的黑。很久没有听哥特金属类的歌单了,落地窗外街灯昏黄的光晕,就像一朵开败了的花,我知道它还是花,只是它还可以是花吗?随着风吹动的枝芽,让光影渐渐的迷离,我以为我能看清,只是我以为。

我的世界里,哥特音乐的低沉旋律缓缓流淌,如同夜色本身的呼吸,低回、缠绵、又带着一丝无法言喻的悲怆。低音如同深夜里幽灵的叹息,高音则像寒风中孤寂的哭泣。那些尖锐的音符,刺破了夜的宁静,却又精准地触碰到了我灵魂深处最阴暗的角落。

无法言说的孤独,放大、渲染,直至凝成实体。

我好像迷路了,在迷离的世界里游荡,我找不到人和我说话,连自己的影子都找不到。

  •  

早知道当初… 呃,电台新版发布了。

书到用时方恨少,早知道当初年少就不应该沉迷于QQ聊天泡妞,就应该多买几本技术类教程书籍多看看…

我不知道今天抽什么风,突然间就想把电台的PC端和H5端给完善一下,然后,我太自信了,呃,这完全是在我能力之外的工作啊!

从昨天AM10:42到现在AM3:40,几个小时我算算,呃,十六还是十七个小时,啊啊啊,我现在脑壳短路,算不明白了。中途就吃了晚饭半个小时,然后辅导娃儿作业一个小时,其余时间我就抱着电脑死命磕磕磕,我的老腰啊……

想法一大堆,但是奈何水平不够,总是碰到一大堆问题,借助Gemini才勉勉强强完成。

电台页面:https://www.edzbe.com/fm/top

去年搞了这个电台页面,用的还是七八九年前的jplayer播放器,直接用代码套来套去整出来的,但是这个播放器源码太老了,总是能遇到一大堆乱七八糟的问题,索性就用Jquery从新搞一个,前端后端的水平都有限,UI啥的也是这里找那里抄,唉。

电台切换页面也得弄一下,我个小破站,为什么要弄这么多歌曲分类,唉,我真的是服了自己。

这个页面抄的QQ音乐的界面,呃,老实交代了。

因为歌曲较多,每次加载json,如果全部加载的话,那网页就卡得不要不要的,设置了获取100首歌,每次刷新随机替换一批。

封装成桌面端了,下载地址:EdzbeFm_0.0.1_x64-setup.exe

H5版折腾了最长时间,还有个问题就是滑动歌曲列表的时候,悬浮的播放器没办法移到最底部,会遮挡到歌曲列表,这个我实在是搞不定,唉,就这样将就吧!

20250606补充,呃,说将就吧,浑身不得劲,唉,这该死的强迫症。

H5版播放器增加了响应式自适应,现在可以把悬浮的播放器根据页面滑动加载缩放到网页底部了,不会遮挡了,呃,果然,方法总比问题多,再坚持坚持就解决了。

H5手机版首页做了个电台的入口,按照喜怒哀乐四种情绪把电台分类给分开。

分享下电脑端和手机端的播放器源码吧,需要的自取。

电脑端:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8"/>
  <title>电脑版黑胶唱片音乐播放器</title>
  <style>
    @import url(https://fonts.googleapis.com/css?family=Raleway:400,300,700);
    *, *:before, *:after {
      box-sizing: border-box;
    }

    body {
      background-color: #fef29c;
     color: #515044;
     font-family: "Raleway", sans-serif;
      min-height: 100vh;
      display: flex;
      justify-content: center;
      align-items: center;
      margin: 0;
    }

    .music-player-container {
      -webkit-transform: translate(-50%, -50%);
      -moz-transform: translate(-50%, -50%);
      -ms-transform: translate(-50%, -50%);
      -o-transform: translate(-50%, -50%);
      transform: translate(-50%, -50%);
      display: inline-block;
      height: 370px;
      position: absolute;
      min-width: 460px;
      left: 50%;
      top: 50%;
    }
    .music-player-container:after {
      -webkit-filter: blur(8px);
      filter: blur(8px);
      background-color: rgba(0, 0, 0, 0.8);
      bottom: -2px;
      content: " ";
      display: block;
      height: 10px;
      left: 19px;
      position: absolute;
      transform: rotate(-3deg);
      width: 70%;
      z-index: 0;
    }

    .music-player {
      background-color: #fff;
     height: 370px;
      padding: 40px 250px 40px 40px;
      position: absolute;
      text-align: right;
      width: 460px;
      z-index: 3;
    }

    .player-content-container {
      -webkit-transform: translateY(-50%);
      -moz-transform: translateY(-50%);
      -ms-transform: translateY(-50%);
      -o-transform: translateY(-50%);
      transform: translateY(-50%);
      top: 50%;
      position: relative;
    }

    .artist-name {
      font-size: 24px;
      font-weight: 200;
      margin: 0 0 0.75em 0;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      max-width: 170px;
    }

    .album-title {
      font-weight: 200;
      font-size: 18px;
      margin: 0 0 1.75em 0;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      max-width: 170px;
    }

    .song-title {
      font-size: 28px;
      font-weight: normal;
      margin: 0 0 0.5em 0;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      max-width: 170px;
      cursor: pointer;
      transition: all 0.3s ease;
      position: relative;
      padding: 5px 0;
    }
   
    .song-title:hover {
      color: #878787;
   }
   
    .song-title::after {
      content: "点击打开链接";
      position: absolute;
      bottom: -20px;
      left: 0;
      font-size: 10px;
      opacity: 0;
      transition: opacity 0.3s ease;
      background: rgba(0,0,0,0.7);
      color: white;
      padding: 2px 5px;
      border-radius: 3px;
      white-space: nowrap;
    }
   
    .song-title:hover::after {
      opacity: 1;
    }

    .album {
      box-shadow: 3px 3px 15px rgba(0, 0, 0, 0.65);
      height: 315px;
      margin-left: 250px;
      margin-top: 27px;
      position: relative;
      width: 315px;
      z-index: 10;
    }

    .album-art {
      height: 315px;
      position: relative;
      width: 315px;
      z-index: 10;
      background-size: cover;
      background-position: center;
    }

    .vinyl {
      -webkit-animation: spin 2s linear infinite;
      -moz-animation: spin 2s linear infinite;
      animation: spin 2s linear infinite;
      -webkit-transition: all 500ms;
      -moz-transition: all 500ms;
      transition: all 500ms;
      background-position: center, center;
      background-size: cover, 40% auto;
      background-repeat: no-repeat;
      border-radius: 100%;
      box-shadow: 0 0 10px rgba(0, 0, 0, 0.8);
      height: 300px;
      left: 0;
      position: absolute;
      top: 5px;
      width: 300px;
      z-index: 5;
      will-change: transform, left;
      animation-play-state: paused; /* 初始状态为暂停 */
    }
    .is-playing .vinyl {
      left: 52%;
      animation-play-state: running; /* 播放时运行动画 */
    }

    .music-player-controls {
      text-align: center;
    }

    [class^=control-] {
      -webkit-filter: brightness(95%);
      filter: brightness(95%);
      border-radius: 100%;
      display: inline-block;
      height: 44px;
      margin: 0 3px;
      width: 44px;
    }
    [class^=control-]:hover {
      -webkit-filter: brightness(85%);
      filter: brightness(85%);
      cursor: pointer;
    }

    .control-play {
      background: transparent url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/83141/play.svg") center/cover no-repeat;
    }
    .is-playing .control-play {
      background: transparent url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/83141/pause.svg") center/cover no-repeat;
    }

    .control-forwards {
      background: transparent url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/83141/forwards.svg") center/cover no-repeat;
    }

    .control-back {
      background: transparent url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/83141/backwards.svg") center/cover no-repeat;
    }

    @-webkit-keyframes spin {
      0% {
        -webkit-transform: rotate(0deg);
      }
      100% {
        -webkit-transform: rotate(360deg);
      }
    }
    @-moz-keyframes spin {
      0% {
        -moz-transform: rotate(0deg);
      }
      100% {
        -moz-transform: rotate(360deg);
      }
    }
    @keyframes spin {
      0% {
        -webkit-transform: rotate(0deg);
        -moz-transform: rotate(0deg);
        -ms-transform: rotate(0deg);
        -o-transform: rotate(0deg);
        transform: rotate(0deg);
      }
      100% {
        -webkit-transform: rotate(360deg);
        -moz-transform: rotate(360deg);
        -ms-transform: rotate(360deg);
        -o-transform: rotate(360deg);
        transform: rotate(360deg);
      }
    }
   
    /* 播放控制面板 */
    .player-controls {
      margin-top: 20px;
      display: flex;
      flex-direction: column;
      align-items: center;
    }
   
    .progress-container {
      width: 200px;
      height: 4px;
      background: #d3d3d3;
     border-radius: 2px;
      margin-bottom: 8px;
      cursor: pointer;
      position: relative;
    }
   
    .progress-bar {
      height: 100%;
      background: #515044;
     border-radius: 2px;
      transition: width 0.1s linear;
    }
   
    .time-display {
      font-size: 14px;
      color: #666;
     width: 100%;
      display: flex;
      justify-content: space-between;
    }
   
    .volume-container {
      display: flex;
      align-items: center;
      margin-top: 10px;
      width: 200px;
    }
   
    .volume-icon {
      margin-right: 10px;
      width: 20px;
      text-align: center;
    }
   
    .volume-slider {
      flex: 1;
      height: 4px;
      background: #d3d3d3;
     border-radius: 2px;
      cursor: pointer;
      position: relative;
    }
   
    .volume-level {
      height: 100%;
      background: #515044;
     border-radius: 2px;
    }
   
    .playlist-btn {
      background: none;
      border: none;
      color: #515044;
     cursor: pointer;
      font-size: 14px;
      margin-top: 15px;
      text-decoration: underline;
      padding: 5px 10px;
      border-radius: 4px;
      transition: all 0.3s ease;
    }
   
    .playlist-btn:hover {
      background: rgba(52, 152, 219, 0.1);
    }
   
    /* 播放列表样式 */
    .playlist-container {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background: rgba(0,0,0,0.7);
      display: flex;
      justify-content: center;
      align-items: center;
      z-index: 100;
      opacity: 0;
      pointer-events: none;
      transition: opacity 0.3s ease;
    }
   
    .playlist-container.active {
      opacity: 1;
      pointer-events: all;
    }
   
    .playlist-content {
      background: #fff;
     width: 80%;
      max-width: 500px;
      max-height: 80vh;
      padding: 20px;
      border-radius: 8px;
      overflow-y: auto;
      box-shadow: 0 5px 25px rgba(0,0,0,0.5);
    }
   
    .playlist-header {
      font-size: 24px;
      margin-bottom: 15px;
      color: #515044;
     border-bottom: 1px solid #ddd;
     padding-bottom: 10px;
      display: flex;
      justify-content: space-between;
      align-items: center;
    }
   
    .playlist-item {
      padding: 12px;
      border-bottom: 1px solid #eee;
     cursor: pointer;
      display: flex;
      justify-content: space-between;
      align-items: center;
    }
   
    .playlist-item:hover {
      background: #f0f0f0;
   }
   
    .playlist-item.active {
      background: #fef29c;
     font-weight: bold;
    }
   
    .playlist-info {
      flex: 1;
    }
   
    .song-name {
      font-size: 16px;
      margin-bottom: 5px;
      cursor: pointer;
      color: #000000;
     transition: all 0.2s ease;
    }
   
    .song-name:hover {
      text-decoration: underline;
      color: #878787;
   }
   
    .song-singer {
      font-size: 14px;
      color: #666;
   }
   
    .close-btn {
      position: absolute;
      top: 20px;
      right: 20px;
      background: transparent;
      border: none;
      color: white;
      font-size: 24px;
      cursor: pointer;
      transition: all 0.3s ease;
    }
   
    .close-btn:hover {
      transform: scale(1.2);
      color: #f1c40f;
   }
   
    .song-link-btn {
      background: #5c5c5c;
     color: white;
      border: none;
      border-radius: 4px;
      padding: 5px 10px;
      cursor: pointer;
      font-size: 12px;
      transition: all 0.3s ease;
    }
   
    .song-link-btn:hover {
      background: #000000;
   }
   
    /* 响应式设计 */
    @media (max-width: 600px) {
      .music-player-container {
        transform: translate(-50%, -50%) scale(0.8);
      }
     
      .playlist-content {
        width: 90%;
      }
    }
     /* 提示信息 */
    .click-outside-hint {
      position: absolute;
      bottom: 15px;
      left: 0;
      width: 100%;
      text-align: center;
      font-size: 12px;
      color: #999;
     font-style: italic;
    }
  </style>
</head>
<body>
  <!-- 移除了初始的 is-playing 类 -->
  <div class="music-player-container">
    <div class="music-player">
      <div class="player-content-container">
        <h1 class="song-title">歌曲标题</h1>
        <h2 class="artist-name">歌手</h2>
        <h3 class="album-title">专辑</h3>
       
        <div class="music-player-controls">
          <div class="control-back"></div>
          <div class="control-play"></div>
          <div class="control-forwards"></div>
        </div>
       
        <div class="player-controls">
          <div class="progress-container">
            <div class="progress-bar" style="width: 0%"></div>
          </div>
          <div class="time-display">
            <span class="current-time">0:00</span>
            <span class="total-time">0:00</span>
          </div>
         
          <div class="volume-container">
            <div class="volume-icon">🔊</div>
            <div class="volume-slider">
              <div class="volume-level" style="width: 80%"></div>
            </div>
          </div>
         
          <button class="playlist-btn">播放列表 (4)</button>
        </div>
      </div>
    </div>

    <div class="album">
      <div class="album-art"></div>
      <div class="vinyl"></div>
    </div>
  </div>
 
  <div class="playlist-container">
    <button class="close-btn">×</button>
    <div class="playlist-content">
      <div class="playlist-header">
        <span>播放列表</span>
        <span>当前歌曲: <span id="current-song-indicator">1</span></span>
      </div>
      <div class="playlist-items">
        <!-- 播放列表内容由JS生成 -->
      </div>
      <div class="click-outside-hint">点击播放列表外部区域关闭</div>
    </div>
  </div>

  <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
  <script>
   // 歌曲数据
    const songs = [
      {
        name: "归",
        singer: "龙井",
        album: "龙井摇滚1",
        path: "https://edzbecom.edzbe.com/Music/2014031305281167131.mp3",
        image: "https://www.edzbe.com/wp-content/uploads/2010/10/15102-150x150.jpg",
        url: "https://www.example.com/song1"
      },
      {
        name: "Tu Phir Se Aana",
        singer: "Raftaar x Salim Merchant x Karma",
        album: "龙井摇滚2",
        path: "https://mp3.vlcmusic.com/download.php?track_id=34213&format=320",
        image: "https://1.bp.blogspot.com/-kX21dGUuTdM/X85ij1SBeEI/AAAAAAAAKK4/feboCtDKkls19cZw3glZWRdJ6J8alCm-gCNcBGAsYHQ/s16000/Tu%2BAana%2BPhir%2BSe%2BRap%2BSong%2BLyrics%2BBy%2BRaftaar.jpg",
        url: "https://www.example.com/song2"
      },
      {
        name: "时间里的",
        singer: "马頔",
        album: "龙井摇滚3",
        path: "https://edzbecom.edzbe.com/Music/2015080304061065494.mp3",
        image: "https://www.edzbe.com/wp-content/uploads/2015/08/13116882321422539101.jpg",
        url: "https://www.example.com/song15"
      },
      {
        name: "Feeling You",
        singer: "Raftaar x Harjas",
        album: "龙井摇滚4",
        path: "https://mp3.filmisongs.com/go.php?id=Damn%20Song%20Raftaar%20Ft%20KrSNa.mp3",
        image: "https://a10.gaanacdn.com/gn_img/albums/YoEWlabzXB/oEWlj5gYKz/size_xxl_1586752323.webp",
        url: "https://www.example.com/song18"
      }
    ];
    </script>
  <script>
    (function($) {
      $(document).ready(function() {
        // 创建音频对象
        const audio = new Audio();
        let currentSongIndex = 0;
        let isPlaying = false;
       
        // 获取DOM元素
        const playerContainer = $('.music-player-container');
        const artistName = $('.artist-name');
        const albumTitle = $('.album-title');
        const songTitle = $('.song-title');
        const albumArt = $('.album-art');
        const vinyl = $('.vinyl');
        const backBtn = $('.control-back');
        const playBtn = $('.control-play');
        const forwardBtn = $('.control-forwards');
        const progressBar = $('.progress-bar');
        const progressContainer = $('.progress-container');
        const currentTimeEl = $('.current-time');
        const totalTimeEl = $('.total-time');
        const volumeSlider = $('.volume-level');
        const volumeContainer = $('.volume-slider');
        const playlistBtn = $('.playlist-btn');
        const playlistContainer = $('.playlist-container');
        const playlistItems = $('.playlist-items');
        const currentSongIndicator = $('#current-song-indicator');
       
        // 初始化播放器
        function initPlayer() {
          // 确保初始状态正确
          playerContainer.removeClass('is-playing');
          vinyl.css('animation-play-state', 'paused');
         
          // 加载第一首歌
          loadSong(currentSongIndex);
         
          // 初始化播放列表
          renderPlaylist();
         
          // 为歌曲标题添加点击事件
          songTitle.on('click', function() {
            const currentSong = songs[currentSongIndex];
            window.open(currentSong.url, '_blank');
          });
         
          // 添加点击外部关闭播放列表的功能
          addClickOutsideClose();
        }
       
        // 添加点击外部关闭播放列表的功能
        function addClickOutsideClose() {
          // 点击播放列表外部区域关闭
          playlistContainer.on('click', function(e) {
            // 如果点击的是背景(不是播放列表内容区域)
            if (e.target === this) {
              togglePlaylist();
            }
          });
         
          // 阻止播放列表内容区域的点击事件冒泡
          $('.playlist-content').on('click', function(e) {
            e.stopPropagation();
          });
        }
       
        // 加载歌曲
        function loadSong(index) {
          currentSongIndex = index;
          const song = songs[index];
         
          // 更新UI
          artistName.text(song.singer);
          albumTitle.text(song.album);
          songTitle.text(`"${song.name}"`);
          albumArt.css('background-image', `url(${song.image})`);
         
          // 更新唱片背景
          vinyl.css('background-image',
                    `url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/83141/vinyl.png'), url('${song.image}')`);
         
          // 设置音频源
          audio.src = song.path;
         
          // 重置进度条
          progressBar.css('width', '0%');
          currentTimeEl.text('0:00');
         
          // 更新当前歌曲指示器
          currentSongIndicator.text(index + 1);
         
          // 加载完成后更新总时长
          audio.addEventListener('loadedmetadata', function() {
            const totalMinutes = Math.floor(audio.duration / 60);
            const totalSeconds = Math.floor(audio.duration % 60);
            totalTimeEl.text(`${totalMinutes}:${totalSeconds < 10 ? '0' : ''}${totalSeconds}`);
          });
         
          // 更新播放列表高亮
          updatePlaylistHighlight();
         
          // 自动播放当前歌曲(如果正在播放)
          if (isPlaying) {
            audio.play();
          }
        }
       
        // 播放/暂停功能
        function togglePlayback() {
          if (isPlaying) {
            audio.pause();
            playerContainer.removeClass('is-playing');
            vinyl.css('animation-play-state', 'paused');
          } else {
            audio.play();
            playerContainer.addClass('is-playing');
            vinyl.css('animation-play-state', 'running');
          }
          isPlaying = !isPlaying;
        }
       
        // 上一首
        function prevSong() {
          currentSongIndex = (currentSongIndex - 1 + songs.length) % songs.length;
          loadSong(currentSongIndex);
          if (isPlaying) {
            audio.play();
          }
        }
       
        // 下一首
        function nextSong() {
          currentSongIndex = (currentSongIndex + 1) % songs.length;
          loadSong(currentSongIndex);
          if (isPlaying) {
            audio.play();
          }
        }
       
        // 更新进度条
        function updateProgress(e) {
          const { duration, currentTime } = e.target;
          const progressPercent = (currentTime / duration) * 100;
          progressBar.css('width', `${progressPercent}%`);
         
          // 更新当前时间
          const currentMinutes = Math.floor(currentTime / 60);
          const currentSeconds = Math.floor(currentTime % 60);
          currentTimeEl.text(`${currentMinutes}:${currentSeconds < 10 ? '0' : ''}${currentSeconds}`);
        }
       
        // 设置进度
        function setProgress(e) {
          const width = progressContainer.width();
          const clickX = e.offsetX;
          const duration = audio.duration;
         
          audio.currentTime = (clickX / width) * duration;
        }
       
        // 设置音量
        function setVolume(e) {
          const width = volumeContainer.width();
          const clickX = e.offsetX;
          const volume = clickX / width;
         
          audio.volume = volume;
          volumeSlider.css('width', `${volume * 100}%`);
        }
       
        // 渲染播放列表
        function renderPlaylist() {
          playlistItems.empty();
         
          songs.forEach((song, index) => {
            const playlistItem = $('<div>').addClass('playlist-item').data('index', index).html(`
              <div class="playlist-info">
                <div class="song-name" data-url="${song.url}">${song.name}</div>
                <div class="song-singer">${song.singer}</div>
              </div>
              <button class="song-link-btn" data-url="${song.url}">歌曲详情</button>
            `);
           
            // 绑定播放列表项的点击事件
            playlistItem.on('click', function() {
              const index = $(this).data('index');
              loadSong(index);
              if (!isPlaying) {
                togglePlayback();
              }
            });
           
            // 绑定歌曲名称的点击事件  这个我先隐藏了
    //        playlistItem.find('.song-name').on('click', function(e) {
    //          e.stopPropagation();
    //          window.open($(this).data('url'), '_blank');
    //        });
           
            // 绑定按钮的点击事件
            playlistItem.find('.song-link-btn').on('click', function(e) {
              e.stopPropagation();
              window.open($(this).data('url'), '_blank');
            });
           
            playlistItems.append(playlistItem);
          });
         
          // 更新播放列表高亮
          updatePlaylistHighlight();
        }
       
        // 更新播放列表高亮
        function updatePlaylistHighlight() {
          $('.playlist-item').removeClass('active');
          $('.playlist-item').eq(currentSongIndex).addClass('active');
        }
       
        // 显示/隐藏播放列表
        function togglePlaylist() {
          playlistContainer.toggleClass('active');
        }
       
        // 事件监听
        playBtn.on('click', togglePlayback);
        backBtn.on('click', prevSong);
        forwardBtn.on('click', nextSong);
        playlistBtn.on('click', togglePlaylist);
        $('.close-btn').on('click', togglePlaylist);
       
        // 进度条控制
        progressContainer.on('click', setProgress);
        volumeContainer.on('click', setVolume);
       
        // 音频事件
        audio.addEventListener('timeupdate', updateProgress);
        audio.addEventListener('ended', nextSong);
       
        // 初始化播放器
        initPlayer();
      });
    })(jQuery);
  </div></script>
</body>
</html>

手机端:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8"/>
  <title>耳朵电台手机端播放器</title>
  <link rel="stylesheet" href="./style.css"/>

</head>
<body>
<!-- partial:index.partial.html -->
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css" integrity="sha512-HK5fgLBL+xu6dm/Ii3z4xhlSUyZgTT9tuc/hSrtw6uzJOvgRr2a9jyxxT1ely+B+xFAmJKVSTbpM/CuL7qxO8w==" crossorigin="anonymous" />
<link rel="preconnect" href="https://fonts.gstatic.com"/>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet"/>

<div class="player">
  <!-- Dashboard -->
  <div class="dashboard">
    <!-- Header -->
    <header>
      <h4>Now playing:</h4>
      <h2>String 57th & 9th</h2>
    </header>

    <!-- CD -->
    <div class="cd">
      <div class="cd-thumb">
      </div>
    </div>

    <!-- Control -->
    <div class="control">
      <div class="btn btn-repeat">
        <i class="fas fa-redo"></i>
      </div>
      <div class="btn btn-prev">
        <i class="fas fa-step-backward"></i>
      </div>
      <div class="btn btn-toggle-play">
        <i class="fas fa-pause icon-pause"></i>
        <i class="fas fa-play icon-play"></i>
      </div>
      <div class="btn btn-next">
        <i class="fas fa-step-forward"></i>
      </div>
      <div class="btn btn-random">
        <i class="fas fa-random"></i>
      </div>
    </div>

    <input id="progress" class="progress" type="range" value="0" step="1" min="0" max="100"/>

    <audio id="audio" src=""></audio>
  </div>

  <!-- Playlist -->
  <div class="playlist">
  </div>
</div>

<!-- partial -->

<script>
const songs = [
  {
    name: "镜子中",
    singer: "扭曲的机器",
    path: "https://edzbecom.oss-cn-hangzhou.aliyuncs.com/Music/2014031305281167131.mp3",
    image: "https://www.edzbe.com/wp-content/uploads/2010/10/15102-150x150.jpg"
  },
  {
    name: "Tu Phir Se Aana",
    singer: "Raftaar x Salim Merchant x Karma",
    path: "https://mp3.vlcmusic.com/download.php?track_id=34213&format=320",
    image:
      "https://1.bp.blogspot.com/-kX21dGUuTdM/X85ij1SBeEI/AAAAAAAAKK4/feboCtDKkls19cZw3glZWRdJ6J8alCm-gCNcBGAsYHQ/s16000/Tu%2BAana%2BPhir%2BSe%2BRap%2BSong%2BLyrics%2BBy%2BRaftaar.jpg"
  },
  {
    name: "时间里的",
    singer: "马頔",
    path: "https://edzbecom.oss-cn-hangzhou.aliyuncs.com/Music/2015080304061065494.mp3",
    image: "https://www.edzbe.com/wp-content/uploads/2015/08/13116882321422539101.jpg"
  },
  {
    name: "Feeling You",
    singer: "Raftaar x Harjas",
    path: "https://mp3.filmisongs.com/go.php?id=Damn%20Song%20Raftaar%20Ft%20KrSNa.mp3",
    image:
      "https://a10.gaanacdn.com/gn_img/albums/YoEWlabzXB/oEWlj5gYKz/size_xxl_1586752323.webp"
  }
];

</script>

<!--音频数据一定要在APP.JS之前加载-->
<script src="./app.js"></script>
</body>
</html>

手机端 App.js 文件代码:

const $ = document.querySelector.bind(document);
const $$ = document.querySelectorAll.bind(document);

const PlAYER_STORAGE_KEY = "F8_PLAYER";

const player = $(".player");
const cd = $(".cd");
const heading = $("header h2");
const cdThumb = $(".cd-thumb");
const audio = $("#audio");
const playBtn = $(".btn-toggle-play");
const progress = $("#progress");
const prevBtn = $(".btn-prev");
const nextBtn = $(".btn-next");
const randomBtn = $(".btn-random");
const repeatBtn = $(".btn-repeat");
const playlist = $(".playlist");

const app = {
  currentIndex: 0,
  isPlaying: false,
  isRandom: false,
  isRepeat: false,
  config: {},
  // (1/2) 解注释以下代码行以使用localStorage
  // config: JSON.parse(localStorage.getItem(PlAYER_STORAGE_KEY)) || {},
  songs: [], // 从data.js文件中导入歌曲数据
  setConfig: function (key, value) {
    this.config[key] = value;
    // (2/2) 解注释以下代码行以使用localStorage
    // localStorage.setItem(PlAYER_STORAGE_KEY, JSON.stringify(this.config));
  },
  render: function () {
    const htmls = this.songs.map((song, index) => {
      return `
                        <div class="song ${
                          index === this.currentIndex ? "
active" : ""
                        }"
data-index="${index}">
                            <div class="thumb"
                                style="background-image: url('${song.image}')">
                            </div>
                            <div class="body">
                                <h3 class="title">${song.name}</h3>
                                <p class="author">${song.singer}</p>
                            </div>
                            <div class="option">
                                <i class="fas fa-ellipsis-h"></i>
                            </div>
                        </div>
                    `;
    });
    playlist.innerHTML = htmls.join("");
  },
  defineProperties: function () {
    Object.defineProperty(this, "currentSong", {
      get: function () {
        return this.songs[this.currentIndex];
      }
    });
  },
  handleEvents: function () {
    const _this = this;
    const cdWidth = cd.offsetWidth;

    // 处理CD旋转/停止
    const cdThumbAnimate = cdThumb.animate([{ transform: "rotate(360deg)" }], {
      duration: 10000, // 10秒
      iterations: Infinity
    });
    cdThumbAnimate.pause();

    // 处理CD放大/缩小
    document.onscroll = function () {
      const scrollTop = window.scrollY || document.documentElement.scrollTop;
      const newCdWidth = cdWidth - scrollTop;

      cd.style.width = newCdWidth > 0 ? newCdWidth + "px" : 0;
      cd.style.opacity = newCdWidth / cdWidth;
    };

    // 处理点击播放
    playBtn.onclick = function () {
      if (_this.isPlaying) {
        audio.pause();
      } else {
        audio.play();
      }
    };

    // 当歌曲播放时
    audio.onplay = function () {
      _this.isPlaying = true;
      player.classList.add("playing");
      cdThumbAnimate.play();
    };

    // 当歌曲暂停时
    audio.onpause = function () {
      _this.isPlaying = false;
      player.classList.remove("playing");
      cdThumbAnimate.pause();
    };

    // 当歌曲进度改变时
    audio.ontimeupdate = function () {
      if (audio.duration) {
        const progressPercent = Math.floor(
          (audio.currentTime / audio.duration) * 100
        );
        progress.value = progressPercent;
      }
    };

    // 处理歌曲拖动
    progress.onchange = function (e) {
      const seekTime = (audio.duration / 100) * e.target.value;
      audio.currentTime = seekTime;
    };

    // 下一首歌曲
    nextBtn.onclick = function () {
      if (_this.isRandom) {
        _this.playRandomSong();
      } else {
        _this.nextSong();
      }
      audio.play();
      _this.render();
      _this.scrollToActiveSong();
    };

    // 上一首歌曲
    prevBtn.onclick = function () {
      if (_this.isRandom) {
        _this.playRandomSong();
      } else {
        _this.prevSong();
      }
      audio.play();
      _this.render();
      _this.scrollToActiveSong();
    };

    // 处理随机播放开关
    randomBtn.onclick = function (e) {
      _this.isRandom = !_this.isRandom;
      _this.setConfig("isRandom", _this.isRandom);
      randomBtn.classList.toggle("active", _this.isRandom);
    };

    // 处理单曲循环
    repeatBtn.onclick = function (e) {
      _this.isRepeat = !_this.isRepeat;
      _this.setConfig("isRepeat", _this.isRepeat);
      repeatBtn.classList.toggle("active", _this.isRepeat);
    };

    // 处理音频播放结束后的下一首歌曲
    audio.onended = function () {
      if (_this.isRepeat) {
        audio.play();
      } else {
        nextBtn.click();
      }
    };

    // 监听播放列表点击事件
    playlist.onclick = function (e) {
      const songNode = e.target.closest(".song:not(.active)");

      if (songNode || e.target.closest(".option")) {
        // 处理点击歌曲
        if (songNode) {
          _this.currentIndex = Number(songNode.dataset.index);
          _this.loadCurrentSong();
          _this.render();
          audio.play();
        }

        // 处理点击歌曲选项
        if (e.target.closest(".option")) {
        }
      }
    };
  },
  scrollToActiveSong: function () {
    setTimeout(() => {
      $(".song.active").scrollIntoView({
        behavior: "smooth",
        block: "nearest"
      });
    }, 300);
  },
  loadCurrentSong: function () {
    heading.textContent = this.currentSong.name;
    cdThumb.style.backgroundImage = `url('${this.currentSong.image}')`;
    audio.src = this.currentSong.path;
  },
  loadConfig: function () {
    this.isRandom = this.config.isRandom;
    this.isRepeat = this.config.isRepeat;
  },
  nextSong: function () {
    this.currentIndex++;
    if (this.currentIndex >= this.songs.length) {
      this.currentIndex = 0;
    }
    this.loadCurrentSong();
  },
  prevSong: function () {
    this.currentIndex--;
    if (this.currentIndex < 0) {
      this.currentIndex = this.songs.length - 1;
    }
    this.loadCurrentSong();
  },
  playRandomSong: function () {
    let newIndex;
    do {
      newIndex = Math.floor(Math.random() * this.songs.length);
    } while (newIndex === this.currentIndex);

    this.currentIndex = newIndex;
    this.loadCurrentSong();
  },
  start: function () {
    // 从data.js加载歌曲数据
    this.songs = songs;

    // 将配置从config赋值给应用
    this.loadConfig();

    // 定义对象的属性
    this.defineProperties();

    // 监听/处理事件(DOM事件)
    this.handleEvents();

    // 运行应用时将第一首歌曲信息加载到UI
    this.loadCurrentSong();

    // 渲染播放列表
    this.render();

    // 显示重复和随机按钮的初始状态
    randomBtn.classList.toggle("active", this.isRandom);
    repeatBtn.classList.toggle("active", this.isRepeat);
  }
};

app.start();

手机端 style.css 样式代码:

:root {
  --primary-color: #ec1f55;
 --text-color: #333;
}

* {
  padding: 0;
  margin: 0;
  box-sizing: inherit;
}

body {
  background-color: #f5f5f5;
}

html {
  box-sizing: border-box;
  font-family: "Poppins", sans-serif;
}

.player {
  position: relative;
  max-width: 480px;
  margin: 0 auto;
}

.player .icon-pause {
  display: none;
}

.player.playing .icon-pause {
  display: inline-block;
}

.player.playing .icon-play {
  display: none;
}

.dashboard {
  padding: 16px 16px 14px;
  background-color: #fff;
 position: fixed;
  top: 0;
  width: 100%;
  max-width: 480px;
  border-bottom: 1px solid #ebebeb;
}

/* HEADER */
header {
  text-align: center;
  margin-bottom: 10px;
}

header h4 {
  color: var(--primary-color);
  font-size: 12px;
}

header h2 {
  color: var(--text-color);
  font-size: 20px;
}

/* CD */
.cd {
  display: flex;
  margin: auto;
  width: 200px;
}

.cd-thumb {
  width: 100%;
  padding-top: 100%;
  border-radius: 50%;
  background-color: #333;
 background-size: cover;
  margin: auto;
}

/* CONTROL */
.control {
  display: flex;
  align-items: center;
  justify-content: space-around;
  padding: 18px 0 8px 0;
}

.control .btn {
  color: #666;
 padding: 18px;
  font-size: 18px;
}

.control .btn.active {
  color: var(--primary-color);
}

.control .btn-toggle-play {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  font-size: 24px;
  color: #fff;
 display: flex;
  align-items: center;
  justify-content: center;
  background-color: var(--primary-color);
}

.progress {
  width: 100%;
  -webkit-appearance: none;
  height: 6px;
  background: #d3d3d3;
 outline: none;
  opacity: 0.7;
  -webkit-transition: 0.2s;
  transition: opacity 0.2s;
}

.progress::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 12px;
  height: 6px;
  background-color: var(--primary-color);
  cursor: pointer;
}

/* PLAYLIST */
.playlist {
  margin-top: 408px;
  padding: 12px;
}

.song {
  display: flex;
  align-items: center;
  margin-bottom: 12px;
  background-color: #fff;
 padding: 8px 16px;
  border-radius: 5px;
  box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1);
}

.song.active {
  background-color: var(--primary-color);
}

.song:active {
  opacity: 0.8;
}

.song.active .option,
.song.active .author,
.song.active .title {
  color: #fff;
}

.song .thumb {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background-size: cover;
  margin: 0 8px;
}

.song .body {
  flex: 1;
  padding: 0 16px;
}

.song .title {
  font-size: 18px;
  color: var(--text-color);
}

.song .author {
  font-size: 12px;
  color: #999;
}

.song .option {
  padding: 16px 8px;
  color: #999;
 font-size: 18px;
}

啊啊啊啊啊啊啊,我又想到了,安卓版好久没维护更新了,啊啊啊啊啊啊啊啊啊,当时弄的安卓版还是独立的系统,需要我博客更新一篇音频,安卓后台在更新一遍,啊,双遍工作量,我不玩了,我不玩了。

哎呀,唉,我不玩了,我好饿,我叫了份霸王牛肉面,三点多送来了,凉了,我要去吃了。

  •  

我的浪迹地图

原计划端午节带娃回趟老家,下午哄娃睡午觉的时候,手一伸摸到脖子,感觉温度不太对,应该是有轻微的低烧,拿体温计一验,37.1°,今天是学校的六一活动节,有很多好玩的节目,贝勒爷不想错过,但是出于对别人负责的态度,算了,请个假,候着,看体温变化,美团上顺便买了核酸检测剂,唉,两条杠。

所以回老家的计划取消了,也好在有三天假期,希望这三天尽快养好,不要耽误了上课。

前几日,在周天记看到博友弄的足迹地图,抄作业我还是会的,想想我也搞个页面吧,折腾了两天,代码类的都能照抄了,没啥难度,就是在同步云盘里找之前手机的备份照片,这些年换了N+1台手机,照片一大堆,而且当初备份的时候,没有选择按照手机备份,全部叠放在一起,找得脑袋瓜子嗡嗡的,到晚上哄娃吃完药睡下后,才有时间收尾。

反正站点是自己的,新建页面又不要钱,好吧,新开一个页面,我放到 浪迹地图 这里来了,用不同的年份照片做图标,整理也是件苦力活。

发现了一个问题,会不会是因为我导入的数组太多了,百度地图的API加载会有受限,有时候前端不能完全显示我的足迹标签,我的完整版是这样的,如下图:

(我图都截不到…)

算了,我还是分成两版试试吧!

国内版:大图链接…

世界版:大图链接…

果然,分成两版就正常了,全部显示了,哎呀,这搞得,没啥意思了啊!

生在泉州,活在厦门,这一生脚步迷乱,路过很多座城,也留下很多故事和事故,我是出走了半生,但是归来时已不是少年摸样。

这里就大概的记录了这些年的足迹,多的也许我故意遗落了,也许我自己也忘了,所以那是不重要的。标注的都是停留超过7天或有特殊意义的,时间更短的地方,就不提说去过了。

不过这个还是可以看出的,这些年我一直在往南走,嗯,此情此景,应该配乐一首。

一路往南走(种完麦子我就往南走) – 卢润泽

  •  

回山里,窝两天。

前天晚上哄娃睡觉,哄着哄着,他没睡着,我先打呼了,昨天就起了个大早,一起早我就很慌,我这一天要干点啥…八点多的时候,接到了村干部打来的微信,说是现在有个政策,农村生活污水提升治理项目,自建房可以提要求,由公家出人工和材料,给弄污水管道和化粪池,他帮我登记上去了,一会施工方就来现场查勘,看我方便回老家一趟不,看下怎么安排。

本着不要白不要的理念,我立马就下车库启动,不然自己后面折腾这些不得再花个三五千块,房子的化粪池之前做地基回填的时候,已经安装预埋了,我爸的逻辑是够用就好,我的逻辑是能大尽量大,省得后期抽粪更麻烦。

本以为这些公家工程都是很应付很敷衍的,没想到还挺靠谱的,管路走向和挖槽回填硬化这些,和施工方沟通后,必须竖个大拇指,完全按照我的需求,怎么走管道,怎么放检修口,怎么排放,完全按照我的要求确定。因为我房子弄了三种污水管道单独走管,所以屋顶阳台空调雨水走一路管,厨房污水走一路管,洗手间单独走一路管,这样确保后期不会返味,污水要对接到最近的一条小水渠,单条管道就得120米左右,三条加转角接口,怎么也得近四百米,我对材料也有要求,我想用伟星管,但是他们招标材料只有中财管,那我要中财得110排水管A型,施工方说这个材料可以申请,不需要额外付费,默认是用B型管,管壁厚2.8mm,A型管,管壁厚3mm,厚度厚一点,强度也高点。

既然回来了,顺便把坡屋顶的内隔热层的事情也落实了一下,要把坡屋顶的隔层做成娃娃们的秘密基地,所以隔热保温还是要做好的,材料加运费46元/m²,安装师傅只收工钱,按工时每人每天500元,两个人四天可以完成,约计4000元。

这些事情都落实好,就在老房子那里和奶奶唠唠嗑聊聊天,奶奶午饭做的手工面,还哈拉我要不要吃一碗,哈哈,我都没有报餐,她就做了自己的份,我要是吃了,她就没得吃了。奶奶这几十年来自己做饭自己生活,现在九十多岁了,也是个很要强的老人家,想带她去城里住,她坚决不肯,带她出去玩,也不愿意,嗯,很顽固。

她每天都会定时去散步,每天四公里左右,上午一趟,下午一趟,想扶她,那是不被允许的,拉拉手可以。这个视频是上个月回老家门口监控拍的。视频里,我脚踢了一下小石子,因为她又说了句我不爱听的话。说让她走马路要靠边安全点,她说这么多岁了,去世了也不亏。唉,老人家啊,我们希望她长命百岁,她天天跟你唠活够本了,真的很烦人啊。

好在奶奶平时的生活作息习惯都相当有规律,几点起床,几点吃饭,几点出门,几点回来,几点睡觉,都是掐分掐秒的准时,所以我在她的活动区域都装了监控,随时都可以看下她的状况,人形移动侦测,还是挺好用的。

下午闲着无事,嗯,钓鱼去吧,带上我的小装备和折叠椅,披上防晒服,嗯,出发。姑姑家的小鱼塘,平时都没有喂养,草鱼吃草,其他的鱼吃啥就不知道了,反正没有饲料喂养,私人野塘,别人都不能钓,专门等我回老家嚯嚯,风油精没有带,只好从姑姑家拿一瓶六神花露水了,因为蚊虫是真的多。

钓了一个多小时,拌的饵料用完我就收工了,我懒,用完就下一趟,我不可能再拌一次。罗非鱼,非洲鲫,嗯,这条一斤多,还不错,带回去煮鱼鱼汤,其他的都再倒回去养着,等我下次回来再嚯嚯。

姑姑家的苦桃熟了,嗯,不摘一些总觉得有点亏,顺手摘了几十颗回来,视频对面那座山,我家在那边。摘桃子的时候,我很谨慎的,很认真的先看看树上脚边有没有蛇啥的,毕竟玩归玩闹归闹,别拿生命开玩笑。

下午本地新闻刷出了个眼镜蛇的新闻,新闻链接 ,小区群里好热闹啊,让物业要响应起来,毕竟去年夏天,我们小区跑进来了三次蛇,绿化好的结果就是这点不好。

哈哈,这句哇操不是我说的,小区业主拍的视频,如果是我,看清楚是什么蛇后,我就下车追上去拍特写了。

厦漳泉分布有42种蛇。其中,蟒蛇、赤链蛇、黄链蛇、棱鳞锦蛇等30种属于无毒蛇,而金环蛇、银环蛇、丽纹蛇、眼镜蛇、眼镜王蛇、圆斑蝰蛇、竹叶青、白唇竹叶青、龟壳花蛇、山烙铁头、尖吻蝮蛇、蝮蛇等12种属有毒蛇。根据地域分布,山区拥有的蛇类最多,并不是所有地方都有毒蛇分布,但它们的迁徙也难以保证不会出现。

我们这蛇非常多,像剧毒的银环蛇,金环蛇,眼镜蛇,竹叶青这些都是很常见的。小时候的,遇到一条银环蛇慢悠悠的爬过来,一慌就想拿东西砸它,没有称手的武器,我直接上脚了,皮靴的底够硬,然后我也踩得准,正对蛇头,一脚下去它就懵逼了,要是踩不准,那就是另外一个故事了。

本来想着下午无事就回厦门了,老爸跑到隔壁村去买猪肉了,说让我等等他。上次刷视频说外面买的烤肠材料差不能吃,但是娃儿又爱吃,他去买了30斤的土猪肉,带到镇子里让别人加工成烤肠,嗯,趁热来一根,香。土猪肉一斤17元,烤肠加工费一斤15元,30斤猪肉做出来36斤的香肠,这一堆算下来,30*17+30*15=960元,960/36=26.666666元,折算下来一斤香肠26.7元,不知道贵不贵。

这下娃儿近阶段的烤肠自由实现了,晚点看下,如果没啥事,就多在老家睡一晚,明天是肯定要回厦门的,明晚学校家长会。

  •  

哎呦,我的好大儿,不错哦。

呃,先恭喜下我的好大儿,顺利竞选上少先队。

昨天下午睡得迷迷糊糊的,媳妇儿有事要出门,喊醒我,让我找找贝勒爷一年级的奖状,拍照打包发给班主任老师,说是老师找她要的。咱也不知道有啥用,赶紧起床洗漱一下,找找他的奖状放哪里,最后在贝勒爷的小基地里找到,叠得整整齐齐的一大本,分出一年级获得的。

[envira-gallery id=”12851″]

找了找一年级的奖状只有这些了,发给媳妇,说不是这些,要校级的奖状,娃儿去上课了,家里我翻了一遍也没找到其他的,问媳妇要干什么用,她说竞选入少先队,我就很疑惑,以前不都是一年级到二年级期间就自动入队的吗?怎么现在还要竞选名额?

说是老师群里公告,第一期教育局说限定名额,只有十三个优选。心想这下没戏了,只有十三个,呃,怎么排队也轮不到咱家啊。

问老师,说贝勒爷下午已经把校级的带去交了,这些班级的奖状不参与评选加分。回来也不说一声,自己滴滴摸摸的带去交给老师了。

哈哈,没想到啊,竟然以第一名成绩入选,真是小看了我的好大儿。平常看着吊儿郎当没个正形,关键时刻还是蛮给力的嘛,为父甚慰!

我不是个很追求内卷的家长,娃儿的学习就是回家后有不懂的我就辅导,在学校的话,那是老师的事,我都是让娃儿自己去问老师。晚上放学回来,瞧贝勒爷那个得瑟样,嗯,感觉自信心十足,整个人都力挺起来了,我在思考一个问题,以其在娃儿做错事的时候训诫,不如多夸夸他的优点,这样他可以更阳光更自信更有活力。

孩子的学习过程中,如果是有条件参与的比赛,应该鼓励他多去参加,这不获奖可以加分的嘛!

  •  

欲望也好,得失也罢,不必太多计较,人生总该归于平静。

又是一个深夜,独自坐在茶台前,冲上一壶正味的高山野茶铁观音,野茶味苦,像极了人生的苦感,好在最后浅浅的回甘。以下文字仅仅是因为今夜这壶茶,瞬悟,不代表明天天亮以后。

人生行至中年,过往的喧嚣逐渐褪去,取而代之的是一种沉淀后的淡然,回首在这之前那些执念的欲望、牵挂的得失,悻悻怅然。过往回忆种种似过眼云烟,此刻似乎也不能再掀起我内心的波澜。

我之认为的欲望,是裹挟我往前冲的驱动力,它无形中要求着我要不断追寻探索所有未知的可能。然而,当欲望膨胀到一定程度,便成一种负累,吞噬我的本心,使我陷入无尽的追逐,像极了一颗临爆的气球,而我无奈的只能继续拼命的吹着气。得失,是我欲望的另一面,它主导着我的喜怒哀乐,也因得失而患得患失。

年少时,我总想拥有更多,得到更多,以此来肯定自己的存在意义以及幸福感受。这样的想法似乎没有明显的逻辑问题。然而,在这过程中我未曾感觉快乐,无休止的欲望时刻紧绷着我的神经,吞噬了我。也在此一瞬间,我恍然觉得真正的舒服状态并非物质的丰盈,而是内心的平静。那些看似遥不可及的目标,往往在追逐的过程中就已经失去了原本的意义。

人生是一场修行,不过是一趟探寻自我的旅程,学会放下执念,放下对欲望和得失的过度计较,才能真正感受到生命的沉重和轻盈,并且我觉得它只是一种状态,不会负累。

平静并不是消极,是一种中庸市侩的人生态度。或许它可以让我得以摆脱欲望的束缚,不受得失的左右,从容自在地面对一切。平静的心境,就像一汪清澈的湖水,无论外界如何波澜起伏,它始终保持着宁静安详。归于平静,也不是逃避现实,而是以一种佛系豁达的心胸去面对人生的起起落落。或许它能让我明白,生命中最重要的不是拥有多少,而是活得是否充实。

或许当我卸下欲望的枷锁,放下得失的执念,人生便会归于平静。在这个平静的状态中,或许我也可细细品味当下的每一刻,享受生活的简单美好。

记住在喧嚣中保持一颗平静的心,在得失面前泰然自若,这是我此刻对自己的劝诫。人生总归要归于平静,那就从现在起,就让心灵安住于此?

上述我用了很多“此刻”和“或许”字眼,因为我也不知道我是不是又在给自己立Flag,而我是不是可以如同上述这般,但总归,我有这样的想法出现了,或许对我来说,会是一个好的开始。瞧,我又用上了或许,一切总还是如此未知。

我从来都不是一个为了自己而活着的人,我也并不想做一个自私的人。但是此刻我更想我能在我与别人之间寻求一个平衡支点,以最舒服的状态相处并且活着。

戾气使人癫狂,无尽的求胜欲望只会让自己更不服输,转而无限的上升矛盾,敌意螺旋飙涨直至无法调停。这一句是目前我想对媳妇开导的话,但是我并没有跟她讲,因为多一事不如少一事,也因为我上文说的淡然。

学会和解,和身边的人和解,和自我和解,和世间万物和解,茶凉了,该续水了。

仅此。

  •  

哎呦,三八了。

自从当了爹,看着娃儿渐长,时光像是开启了加速器,一晃一年又一年,刚刚在刷自己多年以前发的朋友圈内容,娃儿那会还牙牙学语,这会都一个上四年级、一个上一年级了,所有的旧事都记忆犹新,恍若昨日。

我不回避步入中年,日渐衰老的命运。这几年来,我内敛,我稳重,我市侩,我俗,只是想把生活越过越好,终极目标如此。

其实昨晚刚过十二点我就收到了一位年少故人的微信祝福生日快乐,因为要摆正自己的身份立场,尽量避免纷争,我基本不联系不互动,她从2009年至今,每年我的生日都会给我发信息祝福,我有些好奇,她是怎么做到的,我过的是农历生日,连我妈都忘记两次,一次我22岁,一次今天。

好奇归好奇,我也不会问为什么…

聊天截图就放这里吧,不直接贴上来了,因为排版不好看(我这个理由,你信就好)。其实吧,我知道以朋友立场,天是可以聊下去的,但是想想,算了,注意边界,我也在一瞬间想要不要删记录呢?然后,算了,不删,我很坦荡。

一觉起来,本来计划是不想过生日的,但是怕媳妇事后说我明明记得自己过生日,不跟她讲。下午五点多的时候,拿起手机给自己定了个蛋糕,选蛋糕的时候,也都是参照娃儿喜欢吃的口味下单,仪式感啥的不重要,给娃儿一些参与感就行。内心其实是有些期待的,期待媳妇儿会记得,因为我从来没有忘记过她的生日,每次都是提前计划布置。当然,有期待就会有失望,但也只是一瞬间的情绪,马上就被自己抹平了,因为自己觉得也不重要。跟媳妇讲,我定了个蛋糕,她反问定蛋糕干啥,然后才突然反应过来说你生日,哈哈。

媳妇可能也觉得内心有亏,讲说去丰巢取快递,然后出去给我买了些喜欢的吃食,回来给我下了一碗长寿面,还为我发了一条朋友圈,感动的。

小贝勒要赶着去上钢琴课,回来还有学校的作业没完成,抽空临时给我做了张贺卡,哈哈,他说画的小人儿是爸爸和妈妈,虽然有点敷衍,哈哈,但是有心了。之前的贺卡我都收藏起来了,在书房抽屉里,小郡主也要做手工给我,被我阻止了,因为她还有一大堆的作业没完成,还没练琴,不要花时间在这件事上,她说,那等周末再补给我,嗯,我同意了。

补上大宝手作的贺卡,哈哈,写错别字了,教。(2025-04-29)

郡主的画画天份随她妈,这是幼儿园的小班的画作。

这是幼儿园中班的画作。

郡主和贝勒的字都写得还可以,随他们的母亲,也得益于她的坚持,附上贝勒爷田字格字,让我得瑟一下,不过还是郡主比较强,硬笔字写得更好,反正全家我字最丑。

嗯,这就是我的三八生日了。

  •  

稚子何仇画影谏 老父捧腹莞尔篇

本王幸蒙天眷,膝下承欢,有女乳名郡主,有子小字贝勒。近日案牍劳形,慵懒日甚,竟使驿传之物久滞丰巢,遂启璇玑之器小天才,欲命小女代为取之。

然见贝勒郎旬日前所呈画影,恍然忆及上朔月曜日事,其影中似有愠色。

嗟乎!稚子怯于面陈,乃假璇玑图影以微谏,观其状若张牙舞爪,实寓孺慕之思,本王览之,不觉捧腹莞尔。

本王编不下去了,就这样。

  •  

装修 – 石头记

一直以来对石头有特殊的偏爱,不论家里摆设的工艺品抑或是山野间形状各异的石头,因年少时期从事过珠宝玉石和硅化木相关行业,便和石头结下了缘分,零七年在丽江浪荡的时候开的店:石缘坊,丽江大研古城新义街积善巷1号,一开始主要做翡翠珠宝,后来偶然机会接触到了树化石(硅化木)便嗅到了商机,开始做石头生意。

当年进货回来送加工厂打磨抛光,第一件事就是等天黑的时候,拿强光手电筒,整棵材料上找虫眼,只要找到虫化石,一只虫子加价10万,两只就加20万,哈哈。那会注册了淘宝:三生玉缘,当初怎么会取这么个名字,真不潮流,真六零七零后。

也在那时候开始接触了网购,网上找了开源的商城程序,应该是shopex,自建站搭建了石缘坊商城,这个商城还成交了两笔大单,那会不懂得对接线上支付,交易都是邮件传清单资料,传真合同,互相盖章,飞到北京和长沙当面交货收款。后来的互联网发展太快了,想想当年,一对比,真的是。

这次自建房,外墙全部选的石材干挂,内装部分,纠结了许久,除房间外,公区部分最终还是选了大理石,米黄色的大理石主要有三款比较比较流行,莎安娜/奥特曼/白玉兰,莎安娜对比过后,版面好看的,价格都没天良,一平方2000元/㎡起,有点性价比的版面都极丑,毛病极多,600-1000元/㎡的预算,还不如挑奥特曼和白玉兰,宁当鸡头不做凤尾,我是个很实诚的人,哈哈。

对比过后,奥特曼奶油底色,最有性价比的是这款大理石,硬度罕见、光度极高、体积密度高,其中属土耳其捷程矿以底色最为白皙、通透,冰裂纹最少,最接近玉石质感的为上等料,平均售价最高。但结晶体比较多,版面看起来会有点花,媳妇很不喜欢,好吧,她不喜欢,那我也不喜欢。

最后选了白玉兰,在天一集团买奢石的时候,和业务员提起白玉兰,她说她们公司也有白玉兰产品,然后就顺道去别的馆区看了一下,因为板材缺了点小角,做出口工装的话,出材会浪费掉一些材料,所以不懂货的人都不会选这颗荒料,我算了一下,石材的加工损耗大概在20%左右,这颗荒料会在30%左右,如果价格上合适,我买下来,调整下加工规格,怎么算都不亏。原本售价1900元/㎡,硬生生被我砍成了860元/㎡,加上额外10%的加工损耗,算下来我材料也就差不多1000/㎡买到手,属于大大的捡漏,业务员怎么的都不肯卖给我,最后就是加上三块潘多拉奢石一起下单,报请她们的负责人才批下来,这颗料,版面线条优质,色泽油润,无补胶点和裂缝,堪称完美,期待上墙效果。嗯,这个白玉兰只能做墙面,白玉兰大理石硬度高、密度大、结晶度高,其硬度达到6.5级以上,因为硬所以加工过程容易崩边,做地面的话,容易断裂产生渗透黑纹,还会因为地面水泥吐碱破坏美观。

Ps:有装修准备用大理石的小伙伴可以参考我上述内容,我可是做了相当足的功课。

奢石背景墙,需要四片大板,一块用于门厅入户玄关,选了好多种类,最后被一幅潘多拉奢石给吸引住了脚步,东升立信买的,精品版面,不按平方卖,这款折算下来一平方5600元/㎡。

我看上了它的意境,像是树枝枝干从伸出,然后亮光效果下,开花结果,金色的果实,放在门厅入户玄关,应该不错。

因为玄关选了潘多拉,主题还是要协调的,所以沙发背景墙选的也是潘多拉巴西奢石。

客厅挑空6.3米高,只能选三块叠加拼接的。这个去了国际石都水头镇逛了好几天才在天一奢石馆选中这一款,三拼板不单卖,这一幅背景45000元。

它展示效果的背景灯带是蓝/紫/白,我到时候安装的时候,灯带只用3000K/4500K/6000K三色温就行,才不会那么花里胡哨。

最最最难选的当属楼梯踏步石了,最早在抖音被巴西鱼肚灰给种草了,一直想找这样的效果的大板,跑了不下十个市场去找,巴西的有,但是性价比实在不高,一套楼梯算下来,石材材料就得20万起,还不包括加工费安装费,我是个很讲实惠的人,所以我想着可以找一些平替的石材来实现这个效果,找了土耳其的鱼肚灰,线纹太细,看着像开裂;意大利的鱼肚灰,灰蓝色底色太朦;国产鱼肚灰,上面基本都有一些大纹路的白色钙化线,整体看起来像是堆成一堆未晒干的蚝肉,希腊的鱼肚灰,呃,算了,我看到样品拐头就走。

这巴西鱼肚灰真真真的太好看了,奈何一平方1200元/㎡,我毛料得买200平方左右,掐算一下,算了算了,太贵,不买不买。

逛各大石材市场,走到背都直不起来,腰椎压迫到腿发麻,终于在石锦记看到了一块蓝天玉天然奢石,是我的菜。

这款也是来自巴西的天然奢石,石英质岩,新矿口,还没有很出名,比较少设计师会使用它,所以价格还没被炒起来,上面的云母片在灯光下布灵不灵的,奢石是石英岩比大理石硬度更高,日常使用过程中,做楼梯踏步不会因为使用而产生划痕,刷上防水背胶,也不用担心楼梯的水泥会返碱变色,好吧,我就大胆吃螃蟹,希望不要翻车,哈哈。550元/㎡,这一颗料我全买回来了,剩余的部分,可以做洗手间的台盆。

还要给媳妇做网红踏步楼梯灯,自动感应逐级亮灯,提前预埋好灯带线路,有两种方式。

一种是一根主线的走线方法,这种比较便宜,76个台阶需要4套系统,系统每套大概1600元-1900元。但是这种有个问题,如果某个台阶的灯带坏了,楼梯已经铺上去了,就只能重新对码配灯带,要写码才能修复,叫O什么系统来着,我忘记了,这种如果主线出点问题,等于踏步灯全没了。

还有一种就是每条灯带单独放一条1.5平的带皮铜线,后期维护的话,如果哪条灯灭了,都可以自己随便买一条同色温的灯带回来自己卡扣更换,缺点就是初期耗材花费比较多,我是直接承包给一个小伙子,12000元一整套给他做。他安装的过程中,我有很严谨的检查材料和施工工艺,嗯,做事挺认真,人很靠谱,好评。

这块石头名字叫:莫奈花园,是东升股份的控矿产品,市场上只有他们家有,之前在厦门国际石材展看了一眼,媳妇就喜欢上了,先买了两块大板,13.8平方,用来做订制餐桌台面,如果效果好的话,到时候多买两块来做厨房转交吧台,这个控价1200元/㎡,但是我实际购买是999元/㎡,这个虽然是奢石,但是没有透光,就吃那一条绿纹,要问我喜欢吗?我并没有很喜欢,但是媳妇喜欢,那就喜欢吧。

也准备开始折腾花园的布景了,心想到邻居家搜刮一两个猪槽,然后还有以前的那种石磨来布景,问一下邻居,人家直接送,让我有用就扛走,扛我是扛不走,太重了,但是我还是弄回家了。

这副石墨,年代就久远了,大从我记事起,它们就在,这家人比较那个啥,见不得别人好的那种,所以我在纠结要不要找他要,买也行。

上次到山里去找泉水眼的时候,还看到了几块红色的石头,嗯,且不管是什么石,这颜色挺好看,抛光起来应该挺好看,我专程去拉了几块回来,后来查了下,应该是铝矿石。哈哈,挖挖宝,万一是宝贝呢?唉,想起小的时候,去河边,挖到了一块黑色的石头,上面有很明显的一只鱼的完整骨架纹路,是化石无疑,四年级的时候,被自然老师给骗走了,他说他拿去展览,然后没有然后了…

  •  

年报 – 甲辰龙年大概总结。

南方人,岁数算虚岁,今年虚岁38岁,所以在过去的甲辰龙年,正是我的36周岁本命年,从年初穿到年尾的红内裤,辟没辟邪我不知道,这一年,发生了很多事,也做了很多事,生活好像是充实的,又好像一晃而过,无处细念,我们追不上时间的刻度,一直迈向前。

亲人

送别了一位亲人,一位对我性格养成影响巨大的长辈,之前碎碎念只说经常回老家,一两天就回去一趟的原因,其实就是为了回去多陪陪外公,之前媳妇还埋怨念叨说我干脆直接住老家就好了,那天送别了外公,我还打趣跟媳妇说,以后不会了。

总归是有尽到陪伴的责任,我也在医院陪过床,也给他洗过脚,每次去看他都拉着他的手不舍得放开……我能想到我能做的我也都做了。

到现在,我依旧是尽量回避这个话题,现在打上这些文字,我就想收尾了,我不能陷在这样的情绪里,我回避这个话题。

家庭

这一年来,最用心的事,莫过于居家辅导小孩作业,每天定时完成任务,在我和闺女的共同努力下,效果不错,闺女现在在班级里新得外号:学霸,上学期期末考,年级第一,为父甚慰。

因我小学语文水平太差,山区娃儿没有受过好的启蒙教育,什么韵母声母我至今也还是不会,所以辅导儿子一年级的作业都是媳妇的活,除了数学,某些题目媳妇教不会,我再来讲解,儿子目前水平也可,字写得是真的很好看,老师经常拿他的作业当范本发钉钉班级群,也是一种肯定,目前全家字最丑的当属我自己了。

辅导完作业就是练琴,两娃都在学钢琴,闺女今年就让她考5级,之前寒暑假他们都会出国伴我,都没有认真去考级,就去年考了个3级。钢琴我不懂,但是以前读书的时候,我学过乐器和乐理,所以我多了一份工作,就是坐在边上听音,弹错了,及时提出更正。

和媳妇的关系,咋说呢,应该讲越来越和谐吧,虽然有时候总想送她四个字:恃宠而骄。可是,呃,这个不是我自己的行为吗?算了,和谐就好。

家里盖的房子,外观部分已经全部完成,耗时已经两年了,目前正在做内装,也是一样一样的慢慢搞,因为无地,只能建成一栋,过年那会,我主动提出该和兄长分一分这栋新建的房子,得到了父母的肯定答复,兄长的意思是不需要分,而我的认为,我和他是兄弟,但是下一代就是堂兄弟了,还是该说明清楚各自的权属。

底层车库和二楼整层都给我兄长,一楼和三楼是我的,我单独分出一间房给我姐姐,因为我姐姐并未出嫁,该给她也留一间。

我母亲是个贼聪明的人,先把我的路都堵死了,说装修全部一视同仁,不是说分了之后各自负责自己的装修。其实她实在没必要堵我这条路,我的本意就是全部给他弄完成,全部一样的内装修,用的同样的材料。

兄长表示他没意见,他说他赚了,因为我分给他的,但是嫂子故意拿出一种姿态,像是她听不懂我母亲的闽南话,表示异议,然后母亲就又用普通话再跟她解释一遍,对此,我对这样的嘴脸,着实是有一些不爽的,不过这件事也算是有了一个确定的方案,以后,实在不行,就各自生活。

工作

这一年,看似无所事事,因为一些特殊的情况,我没办法全身心的投入再创业,煎炸餐饮连锁店的项目除了商标已注册,其他进程停留在企划之中。

在发小同学的引领下,开始接触股权私募,对接了几个不错的项目。

有一个儿童绘本租赁项目,估值颇高,没有下手。

有一家跨境平衡车项目,虽然代工订单业务不错,但是自主品牌的竞争力太差综合考量之后,选择放弃。

有一家国家级专精特新“小巨人”的公司,专注自动化温控系统,这家未来前景非常乐观,因为还在切商对接中,不便多说。

在Pre-A轮成功入股一家智能机器人公司,经历多轮溢价谈判,终于达成所愿,期待未来三年科创板上市敲钟,双手比个大拇指上台露个脸。目前量产产品已经批量出口海外,估值三年翻了十倍,竞品分析后,行业竞品无对手,两家大型国企也追投,这就是我选择的底气。这一年来,成绩斐然,已经获得省级专精特新称号,在广交会大放异彩,获得CF最高奖项,并受CCTV-13专题播报。利好,利好,我相信我的眼光是毒辣的。

有位小伙伴被“泛茶”卷走了身家,(泛茶 相关新闻报导),去年七月份的时候,我从一些渠道了解到即将暴雷的信息,并把信息分享给他,劝诫他退场,但是人呢,贪欲作祟,他和他媳妇依旧坚信,他媳妇是这样回我的,现在什么都不好做,闲钱留着也无用,倒不如做一些投资,这个稳赚。既然人家夫妻一心,我总不能挡着人家发财吧,末了,八月初,直接暴雷,血本无归,这下只能卖房卖车再创业了,看别人做抖音电商,他又一窍不通,拉我合伙一起做了个带货直播,我也是初涉这个行业,在学习中成长,50天左右,请了两个主播,平播卖高端玻璃茶具,目前日发货量100件左右,营业额每天12000-15000区间,也算给我无所事事的生活状态一个溜达的地方,每天晚上辅导完小孩作业,就跑去公司溜达一圈,泡泡茶,吃个宵夜再回家。

我一直以来是不会碰山寨Coin的,去年十一月份的时候,不知道哪根筋抽风,这个锅也要盖给博友圈某位小伙伴一点点,之前在他博文里讨论过这个话题,想起他的埋伏,然后,我抽风了,以为自己抄到底了,在2412回调到1880的时候入场,自视我1898抄底成功了,呃,今天pepe的价格,呃,889。好吧,889….算了,不动它,丢着吧,万一再飙涨呢,但是呢,我知道,短期内几乎不可能。还好,我不合约,不然就真没了。

大概就是这些了,一些琐碎的杂事篇章,这就是这一年了,新的一年的计划,呃,没有计划。

  •  

我知道,离别是人间常态,生老病死,我们都无法例外。

请您原谅我,最后还是没有做好准备与您告别,我尽量保持理性,在您灵前尽量保持释然,可是再也找不到您一起品茶,再也不能给您递根烟,再也不能站大门口喊一声外公就得到您的回应了。

对不起,一想到这里,我就止不住眼泪,已经两个多月了,我还是一直在逃避这个问题,没有办法面对,虽然我接受了结果。

愿您一路走好,天堂安详。

  •  

朴素充实的一日vlog

最近一直两地跑,厦门~老家,老家~厦门,差不多两天跑一趟,回厦门主要的任务是辅导小孩的作业,这件事情上,我耐性较好,所以这活我接了,忙完家里的事,我就立马开拔回村里。

回山路上的行车轨迹,沿途记录,环山公路好多弯,算了一下,从高速出口到家里,八公里的山路总的有三十几个弯,360度的回头弯应该有十几个,开车走乡间小道还是有别样驾驶感受的,当然因为我路熟,所以开起来没压力,很多城里小伙伴开不惯这种路况。

路边的一棵树,没注意是玉兰花还是芒果树,突然发现一只小松鼠,观察了它一会,弹跳力不错,掏出手机拍它,它不给面子,警惕不动了。

视频后半段的那座小山,我小的时候,差点就在这座山上建寨当山大王了,打小就听说这座山有一只两百多斤的大蟒蛇,很多人目睹过,小时候听得一愣一愣的,反正我没遇到过,心想是长者不想我们整天上山造反,所以编的哄吓小孩的桥段故事。

大蟒蛇是没遇到过,但是大老鹰就经常见,最近也经常看到在空中盘旋,目测翼展有门板宽,张开翅膀一米多宽应该有,有两只,不知道是不是我小时候见过的,小时候目睹过老鹰低空盘旋,蹭的一下抓走伯母家的小鸡,一爪可以抓两只。

停下来拍山的时候,看到这棵竹子,这种竹子品种是麻哩竹,哈哈,这是一道福建小孩的童年噩梦美食的原材料,菜名:竹笋炒肉,一般是由母亲大人掌厨,我们童年快乐的成长离不开它的付出,此乃上古神器,效果比北方的鸡毛掸子不妨多让。

村子里有各种品种的竹子,龙竹、绿竹、麻竹、麻哩竹……其中当属麻哩竹的竹杆韧性最佳,打不断的那种。

守村人,平时都挺熟悉的,路过看我停车在路边,很热情的问我要干啥,我说想折两根竹条,他兴冲冲的爬上去帮我折回来了。

心想家里的鞭子都不翼而飞了,该补货了,请家法,哈哈,回厦门后,绑上红绳,放在厅头。为啥要绑红绳,哈哈,因为小朋友挨揍也是要有仪式感的,毕竟这才是完整的童年。

弟弟一根,姐姐一根,豆豆三根,哈哈。

它是豆豆,家里的新成员,咖色边牧,媳妇说要情绪价值,所以就买回来养了,其实我是想养带刀侍卫-罗威纳的,但是城里禁养烈犬,我的第二选择是拉布拉多或金毛,但是媳妇不喜欢,她就想要边牧或者八嘎-柴犬,可能被抖音上的那只陈贝拉给带坑里去了,好吧,她喜欢就好。

边牧,智商确实高,教什么一学就会,但是这种狗,太鸡贼了,整天要和它斗智斗勇,唉。明明定点如厕都会了,心情好就很规矩的自己到狗厕大小号,偶尔就是故意趁你不注意,在哪个小角落给你来上一坨,所以鞭子是应该必备的。

一开始我揍它,媳妇和闺女还跟我翻脸,我的解释是:狗就是家畜,家畜就是畜生,我们才是主人,不要养只狗,变成狗奴才,那没有必要。

其实我也挺喜欢养狗的,但是我比较理性,家里从小就有养小黄土狗,后来搬去县城里才没有养,高中毕业那年收养了两只流浪狗,一只蝴蝶犬叫小可,一只串串叫小白,两只都养了十几年,直到终老。

它叫Money,中文名:旺财,之前在国外养的赛级拉布拉多,口罩期间,实在无聊,就买来养着,听话就赏它一口吃的,不听话就揍它玩,也陪伴了我一段时间,本来联系好航空物流,想要运送回国的,可惜它狗命不长,保姆拉它出去溜达的时候,遇到老鼠,去追老鼠,被老鼠反咬一口,感染了犬勾端螺旋体病毒,发病后紧急送医,第二天就嘎了,唉,保姆哭了好几天,我也挺伤心的,但我没哭,这是它的命。

忙完工地的事,还有一个多小时天黑,嗯,抓紧时间,钓鱼佬上线,带上简陋装备,开搞。

竹林边的小野塘,蚊蠓挺多的,还好我随身带有风油精,毕竟我现在细皮嫩肉的,哈哈哈。

鱼获不错,数了一下,27条,大部分是白鲫鱼和鲤鱼,钓完就倒回去塘里了,拜拜了您了,我们下次见。

暮色降临,回工地逛一圈,收拾一下,赶在8点之前回到厦门辅导作业。这就是我的一天vlog,朴素充实。

  •  

什么玩意儿?| 网站新增暗夜模式,AI搓出来的代码分享

东西坏了,靠我修,其实我也很不喜欢修东西,只是我还不想扔了它,所以我坚持坏了就修,这就显得我很主动,东西就觉得我离不开它了,它就可以一直坏一直坏,然后我一直修一直修。有没有一种可能?有一天,我不想修了呢?或者它不配了呢?我不要它了,那它是个什么玩意儿?

— 源于2025-10-09更新的一段内容。

那天我挺憋屈的,缘由说来也很搞笑,鸡毛蒜皮的一丁点小事,就这样燃起来的家庭纷争,我自身也是很诧异,为什么就这么点小事我压不住自己的怒火了,可能因为情绪总有一个临界点,我一直是忍让型的追求家和万事兴的态度,但是当下,有一个认知突然占据了我的思想,凭什么赚钱养家的是我,忍气吞声的还是我,所以我就炸了。

我本不想吵架,因为吵赢了只是把矛盾推向更高的地方,无法调和。所以大晚上的我就到操场上快走慢跑了8公里发泄自己的情绪,跑着跑着,越跑越不对劲,情绪更沮丧了,累瘫了坐在十字路口的小石墩上看着红绿灯变换读秒,挺落寞的,也挺心疼自己。

末了,我跟自己说:算了,都是自己惯的,能过就过,不能过就算了,这次我绝不先认怂。

闹矛盾之前,有听她念叨说 iPhone 17 Pro Max 京东本地都没货,所以我记在心里了,贝勒爷的同学家长有位是卖apple周边设备的,所以就跟他讲有货跟我说一声,找他拿一台。

闹矛盾之后,卖手机的说是手机有货了,溢价450元,问我要什么颜色,这都吵架冷战了,我也不好认怂去问她喜欢什么颜色啊,本来想问的,但是,呃,先开口不就输了吗?好,我不问。

不知道她喜欢什么颜色,就拿橙色和银色两台512GB回家,丢在桌子上。这次我对自己大方起来了,以往都是给她追新款,然后我自己随意将就,两台手机13和14用了好多年了,我也没舍得给自己换。心想让她先挑,剩下的我自己用,我也要开始自己享受消费了,这种心理有点变态,呃,为啥我赚钱给她优质生活,然后我自己对自己这么抠,然后她还可以这么高高在上的理所应当的不照顾我的感受。

手机在餐边柜桌子上放了两天,她也没动,我也没动,其实她动了,就是没拆封,因为装在袋子里的叠放顺序变了,肯定是我不在家的时候,自己拿起来纠结了半天,到底拆不拆呢,拆了不就认输了吗?

第三天早上,我还在睡觉,她到房间来,叫醒我,要我给她贴贴膜,拿着橙色和银色比划了半天,纠结要选什么颜色,我说你随便,你选好一台,另一台给我留着,然后我继续睡觉,十一点多起床后,她说要不她拿橙色吧,好的,那我就用修炼了十几年的贴膜技术完美的给她贴好了,但是这时候我还是端着呢,我话不多说,贴完橙色贴银色,贴好后,她拿走银色对比了一下,说银色比较商务,还是你拿吧。

一切好像从未发生过,呃,吵架,呃,根本没有发生过。晚上回房的时候,主动贴贴了,假装无意的翻个身靠着我,在试探我是不是不生气了,其实我早不生气了,真没骨气,唉。我内心其实很清楚,她的性格都是这些年我给她娇惯出来的,我当面指责她恃宠而骄,她并不否认。

但是日子总要过下去的吧,其实她还不错,就是这个家传的性格,有些太蛮横不讲理,事事都要顺遂她的心意,逆反她就是跟她势不两立。但是也相对收敛了很多,可能她也采集到我不忍了的想法,所以不敢再危险边缘来回试探蹦跶了。

果然,修东西,我还是一如既往的专业。


叨叨完,开始下一个主题,关于网站新增暗夜模式。

之前有博友评论说网站没有暗夜模式,可能体验感不佳吧,我现在对于修改网站主题有相当大的心理阴影,因为我的主题都是仿的,看到这个好看我就扒了,然后套进去自己的主题里,导致主题代码垒得跟屎山一样,一个主题里有七八个CSS样式文件,和一大堆可能无用可能有用的js文件,我主张,能用就行。但是这就给修改增加了很大的难度,有时候改一点点小东西,完犊子,前端垮了,垮在哪里,我也不知道,我再找找,就很难。

前几天逛 Jeffer.Z 的新作站点 FindBlog 觉得他的暗夜模式配色挺好看的,嗯,蠢蠢欲动的参照他站点的配色开始折腾了,他说站点黑夜模式是一个第三方的js库,直接调用就行。/npm/darkreader@4.9.80/darkreader.js

听不懂,一点都听不懂,想到用插件来实现,因为我主题魔改的东西太多,所以导致插件装上去后,各种惨不忍睹的前端画面出现了,算了,我用我最简单暴力的方式来折腾吧。

我的想法是这样,我创建两个不同的配色方案样式文件,一个style-dark.css,一个style-light.css,然后通过js判断来识别加载哪一个文件,按道理说这个应该就可以满足我的需求,我打开了Gemini对接的聊天框,https://chat.erduo.tech,搭建来自己用的,因为对比之下,元宝的Deepseek和混元产出的代码内容,总是有各种问题出现,当然,可能是我站着尿尿的姿势不对,也可能是对准的方向不对,总之,我还是用的Gemini 2.5 Flash模型解决。

最早生成的插件php代码如下:

<?php
/**
 * Plugin Name: 日夜模式切换器
 * Plugin URI: https://www.edzbe.com
 * Description: 为您的WordPress站点添加日夜模式切换功能,默认根据当地时间判断,并支持手动切换。
 * Version: 1.0.1
 * Author: 耳朵的主人
 * Author URI: https://www.edzbe.com
 * License: GPL-2.0+
 * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
 * Text Domain: daynight-switcher
 * Domain Path: /languages
 */

// 阻止直接访问文件,增强安全性
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * 注册并加载日夜模式样式和脚本
 */

function dns_enqueue_styles_scripts() {
    // 获取主题目录URI(确保CSS文件位于主题的/css/子目录)
    $theme_css_dir_uri = get_template_directory_uri() . '/css/';

    // 注册白天模式样式(WordPress会自动生成ID:daynight-switcher-light-style-css)
    wp_enqueue_style(
        'daynight-switcher-light-style',
        $theme_css_dir_uri . 'style-light.css',
        array(),
        '1.0.0'
    );

    // 注册暗夜模式样式(WordPress会自动生成ID:daynight-switcher-dark-style-css)
    wp_enqueue_style(
        'daynight-switcher-dark-style',
        $theme_css_dir_uri . 'style-dark.css',
        array(),
        '1.0.0'
    );

    // 注册切换脚本(在页脚加载,确保DOM就绪)
    wp_enqueue_script(
        'daynight-switcher-script',
        plugins_url( 'js/daynight-switcher.js', __FILE__ ),
        array(),
        '1.0.0',
        true
    );

    // 将PHP数据传递给JS(如样式表ID、按钮ID)
    wp_localize_script(
        'daynight-switcher-script',
        'dns_data',
        array(
            'lightStyleId' => 'daynight-switcher-light-style-css',
            'darkStyleId' => 'daynight-switcher-dark-style-css',
            'buttonId'    => 'daynight-toggle',
      //     'textLight'   => esc_html__( '切换到暗夜模式', 'daynight-switcher' ),
      //        'textDark'    => esc_html__( '切换到白天模式', 'daynight-switcher' ),
        )
    );
}
add_action( 'wp_enqueue_scripts', 'dns_enqueue_styles_scripts' );

/**
 * 在页面<body>开头添加切换按钮(兼容WP5.2+)
 */

function dns_add_toggle_button() {
    if ( is_admin() ) return; // 排除后台
    ?>
    <button id="daynight-toggle" class="daynight-toggle-button" aria-label="<?php esc_attr_e( '切换日夜模式', 'daynight-switcher' ); ?>">
        <?php esc_html_e( '加载中...', 'daynight-switcher' ); ?>
    </button>
    <?php
}
add_action( 'wp_body_open', 'dns_add_toggle_button' );

/**
 * 关键修复:提前在页面头部禁用非必要样式表,避免初始闪烁
 * 逻辑:根据本地存储或系统时间,立即禁用不需要的样式表
 */

function dns_early_disable_unnecessary_styles() {
    ?>
    <script>
        (function() {
            // 1. 获取用户偏好或系统默认模式
            const savedMode = localStorage.getItem('theme-mode');
            let initialMode;
           
            if (savedMode && (savedMode === 'light' || savedMode === 'dark')) {
                initialMode = savedMode;
            } else {
                const hour = new Date().getHours();
                initialMode = (hour >= 6 && hour < 18) ? 'light' : 'dark'; // 6-18点白天
            }

            // 2. 禁用不需要的样式表(避免页面初始渲染错误)
            const lightStyle = document.getElementById('<?php echo esc_js('daynight-switcher-light-style-css'); ?>');
            const darkStyle = document.getElementById('<?php echo esc_js('daynight-switcher-dark-style-css'); ?>');
           
            if (lightStyle && darkStyle) {
                if (initialMode === 'light') {
                    darkStyle.disabled = true; // 禁用暗夜样式
                } else {
                    lightStyle.disabled = true; // 禁用白天样式
                }
            }
        })();
    </script>
    <?php
}
// 在<head>标签内优先执行(优先级1,确保最早运行)
add_action( 'wp_head', 'dns_early_disable_unnecessary_styles', 1 );
</head></body>

Js源码如下:

document.addEventListener('DOMContentLoaded', function() {
    // 检查本地化数据是否正常
    if (typeof dns_data === 'undefined') {
        console.error('日夜模式切换器:未获取到本地化数据,请检查PHP的wp_localize_script调用!');
        return;
    }

    // 解构本地化数据
    const { lightStyleId, darkStyleId, buttonId, textLight, textDark } = dns_data;

    // 获取DOM元素
    const lightStyle = document.getElementById(lightStyleId);
    const darkStyle = document.getElementById(darkStyleId);
    const toggleButton = document.getElementById(buttonId);

    // 元素存在性检查
    if (!lightStyle || !darkStyle || !toggleButton) {
        console.error('日夜模式切换器:未找到核心元素,请检查样式表/按钮ID是否正确!');
        return;
    }

    console.log('日夜模式切换器:核心元素加载完成!');

    /**
     * 设置主题模式(更新样式、按钮文本、body类)
     * @param {string} mode - 'light'或'dark'
     * @param {boolean} save - 是否保存到localStorage
     */

    function setMode(mode, save = true) {
        // 更新样式表状态
        if (mode === 'light') {
            lightStyle.disabled = false;
            darkStyle.disabled = true;
            toggleButton.textContent = textLight;
            toggleButton.setAttribute('aria-pressed', 'false');
        } else {
            lightStyle.disabled = true;
            darkStyle.disabled = false;
            toggleButton.textContent = textDark;
            toggleButton.setAttribute('aria-pressed', 'true');
        }

        // 更新body类(方便扩展CSS)
        document.body.classList.remove('light-mode', 'dark-mode');
        document.body.classList.add(`${mode}-mode`);

        // 保存用户偏好(可选)
        if (save) localStorage.setItem('theme-mode', mode);
    }

    /**
     * 获取系统默认模式
     * @returns {string} 'light'或'dark'
     */

    function getSystemMode() {
        const hour = new Date().getHours();
        return (hour >= 6 && hour < 18) ? 'light' : 'dark';
    }

    // --- 初始化 ---
    const savedMode = localStorage.getItem('theme-mode');
    const initialMode = savedMode && (savedMode === 'light' || savedMode === 'dark')
        ? savedMode
        : getSystemMode();

    setMode(initialMode, false); // 初始化模式(不保存)
    console.log(`日夜模式切换器:初始模式为${initialMode}`);

    // --- 切换按钮点击事件 ---
    toggleButton.addEventListener('click', function() {
        const currentMode = document.body.classList.contains('light-mode') ? 'light' : 'dark';
        const newMode = currentMode === 'light' ? 'dark' : 'light';
        setMode(newMode); // 切换并保存偏好
        console.log(`日夜模式切换器:已切换至${newMode}`);
    });
});

如上方式实现了暗夜模式的识别和切换,根据用户端的时间,采用“用户偏好优先,无偏好时根据本地时间自动判断,并支持手动切换和保存偏好”的模式。设定6点-18点为白天模式,18-次日6点为暗夜模式。

这个版本有一个问题出现了。

初始页面加载时的优化 (防止闪烁 FOUC):

1.dns_early_disable_unnecessary_styles 这个PHP函数非常关键。它在页面标签中以最高优先级(wp_head, 1)执行一个小的JavaScript片段。

2.这个JS片段会立即检查 localStorage 或根据时间判断初始模式,然后直接禁用不需要的CSS文件(style-light.cssstyle-dark.css)。

3.这样做的好处是,在浏览器开始渲染页面之前,已经确定并加载了正确的样式,有效避免了页面先显示一种模式然后迅速切换到另一种模式的“闪烁”现象 (Flash Of Unstyled Content)。

页面前端依然很不给面子的闪烁,白天和暗夜模式底色反差太大,一闪一闪让人很不舒服,本想着退而求其次,将就就好,管它白天闪晚上,还是晚上闪白天。然后,这两三天来,白天都在看房,跟着中介看这套看那套的,折腾得累半死,回家洗完澡一躺就睡了,这个问题也就这样搁置了几天。晚上得闲,一打开页面,页面切换的时候,闪得我自己都很不舒服,算了算了,我还是再修一修吧。

出现这个闪烁的原因,很可能是因为浏览器在解析HTML并应用内联JS脚本禁用CSS之前,已经短暂地加载并应用了所有样式表。如果 style-dark.css 中的样式优先级更高,或者它定义的默认颜色在没有其他限制的情况下会覆盖 style-light.css,就会导致先显示深色。

解决这个问题的更健壮方法是利用 link 标签的 media 属性,它在CSS加载层面就阻止了不必要的样式表被应用,而不是在JS加载后才去禁用。

产生了第二版插件代码:

  1. wp_enqueue_style 中使用 media=”not all”:
    • 通过在PHP中将 style-dark.css 的 media 属性设置为 ‘not all’,我们告诉浏览器,这个样式表在任何媒体类型下都不适用。这意味着浏览器在解析HTML时,根本不会加载和应用 style-dark.css 的内容,从而避免了它在初始渲染时可能造成的深色闪烁。
    • style-light.css 仍然保持 media=”all”,确保默认的白天模式样式能被加载。
  2. 早期JS脚本中切换 media 属性:
    • 在 dns_early_disable_unnecessary_styles 中,我们不再使用 style.disabled = true/false,而是修改 style.media 属性。
    • link.media = ‘all’ 会让浏览器立即应用该样式表。
    • link.media = ‘not all’ 会让浏览器立即禁用该样式表。
    • 这种方法比 disabled 属性更可靠,因为它在CSS加载和应用机制的更底层进行控制,通常能更快、更彻底地防止不希望的样式被渲染。
  3. setMode 函数中切换 media 属性:
    • 手动切换模式时,JavaScript也需要同步地修改样式表的 media 属性,以确保页面动态地更新为正确的模式。

php代码如下:

<?php
/**
 * Plugin Name: 日夜模式切换器
 * Plugin URI: https://www.edzbe.com
 * Description: 为您的WordPress站点添加日夜模式切换功能,默认根据当地时间判断,并支持手动切换。
 * Version: 1.0.2
 * Author: 耳朵的主人
 * Author URI: https://www.edzbe.com
 * License: GPL-2.0+
 * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
 * Text Domain: daynight-switcher
 * Domain Path: /languages
 */

// 阻止直接访问文件,增强安全性
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * 注册并加载日夜模式样式和脚本
 */

function dns_enqueue_styles_scripts() {
    // 获取主题目录URI(确保CSS文件位于主题的/css/子目录)
    $theme_css_dir_uri = get_template_directory_uri() . '/css/';

    // 注册白天模式样式(默认 media="all",提供一个稳定的基线,避免布局错乱)
    wp_enqueue_style(
        'daynight-switcher-light-style',
        $theme_css_dir_uri . 'style-light.css',
        array(),
        '1.0.0',
        'all' // 白天模式默认加载,作为页面的基础颜色模式
    );

    // 注册暗夜模式样式(默认 media="not all",仅在需要时激活)
    wp_enqueue_style(
        'daynight-switcher-dark-style',
        $theme_css_dir_uri . 'style-dark.css',
        array(),
        '1.0.0',
        'not all' // 暗夜模式初始不加载,避免闪烁
    );

    // 注册切换脚本(在页脚加载,确保DOM就绪)
    wp_enqueue_script(
        'daynight-switcher-script',
        plugins_url( 'js/daynight-switcher.js', __FILE__ ),
        array(),
        '1.0.0',
        true
    );

    // 将PHP数据传递给JS(如样式表ID、按钮ID)
    wp_localize_script(
        'daynight-switcher-script',
        'dns_data',
        array(
            'lightStyleId' => 'daynight-switcher-light-style-css',
            'darkStyleId' => 'daynight-switcher-dark-style-css',
            'buttonId'    => 'daynight-toggle',
            'textLight'   => esc_html__( '切换到暗夜模式', 'daynight-switcher' ),
            'textDark'    => esc_html__( '切换到白天模式', 'daynight-switcher' ),
        )
    );
}
add_action( 'wp_enqueue_scripts', 'dns_enqueue_styles_scripts' );

/**
 * 在页面<body>开头添加切换按钮(兼容WP5.2+)
 */

function dns_add_toggle_button() {
    if ( is_admin() ) return; // 排除后台
    ?>
    <button id="daynight-toggle" class="daynight-toggle-button" aria-label="<?php esc_attr_e( '切换日夜模式', 'daynight-switcher' ); ?>">
        <?php esc_html_e( '加载中...', 'daynight-switcher' ); ?>
    </button>
    <?php
}
add_action( 'wp_body_open', 'dns_add_toggle_button' );

/**
 * 关键修复:提前在页面头部设置正确的样式表和body类,避免初始闪烁
 * 逻辑:根据本地存储或系统时间,在初始加载时,如果需要暗色模式,则立即激活暗色模式并禁用白天模式。
 * 否则(即需要白天模式),白天模式已经默认加载,只需设置body类。
 */

function dns_early_disable_unnecessary_styles() {
    ?>
    <script>
        (function() {
            // 1. 获取用户偏好或系统默认模式
            const savedMode = localStorage.getItem('theme-mode');
            let initialMode;
           
            if (savedMode && (savedMode === 'light' || savedMode === 'dark')) {
                initialMode = savedMode;
            } else {
                const hour = new Date().getHours();
                initialMode = (hour >= 6 && hour < 18) ? 'light' : 'dark'; // 6-18点白天
            }

            // 2. 只有在初始模式是“dark”时才需要立即操作样式表,
            // 因为“light”模式的样式表已经默认加载 media="all"
            if (initialMode === 'dark') {
                const lightStyle = document.getElementById('<?php echo esc_js('daynight-switcher-light-style-css'); ?>');
                const darkStyle = document.getElementById('<?php echo esc_js('daynight-switcher-dark-style-css'); ?>');
               
                if (lightStyle && darkStyle) {
                    lightStyle.media = 'not all'; // 禁用白天样式
                    darkStyle.media = 'all';      // 激活暗夜样式
                }
            }
           
            // 3. 设置 body 的 class,确保全局背景色等样式同步
            // 这一步在任何模式下都执行,以确保 body 类始终是正确的
            document.body.classList.remove('light-mode', 'dark-mode'); // 移除可能的旧类
            document.body.classList.add(`${initialMode}-mode`); // 添加当前模式类

        })();
    </script>
    <?php
}
// 在<head>标签内优先执行(优先级1,确保最早运行)
add_action( 'wp_head', 'dns_early_disable_unnecessary_styles', 1 );


</head></body>

js代码如下:

document.addEventListener('DOMContentLoaded', function() {
    // 检查本地化数据是否正常
    if (typeof dns_data === 'undefined') {
        console.error('日夜模式切换器:未获取到本地化数据,请检查PHP的wp_localize_script调用!');
        return;
    }

    // 解构本地化数据
    const { lightStyleId, darkStyleId, buttonId, textLight, textDark } = dns_data;

    // 获取DOM元素
    const lightStyle = document.getElementById(lightStyleId);
    const darkStyle = document.getElementById(darkStyleId);
    const toggleButton = document.getElementById(buttonId);

    // 元素存在性检查
    if (!lightStyle || !darkStyle || !toggleButton) {
        console.error('日夜模式切换器:未找到核心元素,请检查样式表/按钮ID是否正确!');
        return;
    }

    console.log('日夜模式切换器:核心元素加载完成!');

    /**
     * 设置主题模式(更新样式、按钮文本、body类)
     * @param {string} mode - 'light'或'dark'
     * @param {boolean} save - 是否保存到localStorage
     */

    function setMode(mode, save = true) {
        // 更新样式表状态,通过修改 media 属性来激活/禁用样式
        if (mode === 'light') {
            lightStyle.media = 'all';     // 激活白天样式
            darkStyle.media = 'not all';  // 禁用暗夜样式
            toggleButton.textContent = textLight;
            toggleButton.setAttribute('aria-pressed', 'false');
        } else { // mode === 'dark'
            lightStyle.media = 'not all'; // 禁用白天样式
            darkStyle.media = 'all';      // 激活暗夜样式
            toggleButton.textContent = textDark;
            toggleButton.setAttribute('aria-pressed', 'true');
        }

        // 更新body类(方便扩展CSS)
        document.body.classList.remove('light-mode', 'dark-mode');
        document.body.classList.add(`${mode}-mode`);

        // 保存用户偏好(可选)
        if (save) localStorage.setItem('theme-mode', mode);
    }

    /**
     * 获取系统默认模式
     * @returns {string} 'light'或'dark'
     */

    function getSystemMode() {
        const hour = new Date().getHours();
        return (hour >= 6 && hour < 18) ? 'light' : 'dark';
    }

    // --- 初始化 ---
    // 页面加载时的初始化逻辑已经由PHP中的dns_early_disable_unnecessary_styles处理,
    // 这里再次调用setMode主要是为了同步按钮文本和body class,
    // 并且确保在JS完全加载后,如果有未被早期脚本处理的逻辑(虽然现在应该没有了),也能正确执行。
    const savedMode = localStorage.getItem('theme-mode');
    const initialMode = savedMode && (savedMode === 'light' || savedMode === 'dark')
        ? savedMode
        : getSystemMode();

    // 注意:这里的 setMode(initialMode, false) 仅仅是确保DOM加载完成后,按钮文本等细节能够正确初始化。
    // 真正避免闪烁的样式切换,由 dns_early_disable_unnecessary_styles 中的内联脚本处理。
    setMode(initialMode, false);
    console.log(`日夜模式切换器:初始模式为${initialMode}`);

    // --- 切换按钮点击事件 ---
    toggleButton.addEventListener('click', function() {
        const currentMode = document.body.classList.contains('light-mode') ? 'light' : 'dark';
        const newMode = currentMode === 'light' ? 'dark' : 'light';
        setMode(newMode); // 切换并保存偏好
        console.log(`日夜模式切换器:已切换至${newMode}`);
    });
});

 

如上代码,其实应该是正常解决方案的,就是创建的 style-light.css style-dark.css 文件如果只有配色方案,网页加载的时候,先加载 style.css 框架样式文件,这样页面就正常显示,只是配色根据选择加载,但是我又失败了,因为我开始弄的时候,把默认的style.css 框架样式直接套到 style-light.css style-dark.css 这两个文件里了,要修改,又要重新开始分离出配色单独创建样式表,不行,不行,这工作量太大了,我不要。

我给Gemini发送了我的想法解决这个问题: 先加载页面的判断设置,直接屏蔽不加载另一种模式。Gemini很给力的给出了解决方案。

只加载所需的模式样式,而不是先加载一个再切换,避免任何形式的“闪烁”或“布局混乱”。

我之前的方案试图通过 `media` 属性和内联 JS 来解决,但在某些浏览器或加载条件下,即使是极快的切换,也可能出现视觉上的延迟。实现“直接屏蔽不加载另一种模式”的最彻底方法是:在 PHP 生成 HTML 的 `<head>` 部分时,就根据用户的偏好或时间判断,只输出当前所需模式的 `<link>` 标签,而完全不输出另一个模式的 `<link>` 标签。

但这有个挑战:PHP 在服务器端运行,它无法直接读取用户浏览器中的 `localStorage`。它只能读取 `$_COOKIE`。所以,为了让 PHP 在第一次加载页面时就知道用户偏好,JavaScript 必须在每次模式切换时,除了更新 `localStorage`,还要同时更新一个 Cookie

最终版本php代码如下:

<?php
/**
 * Plugin Name: 日夜模式切换器
 * Plugin URI: https://www.edzbe.com
 * Description: 为您的WordPress站点添加日夜模式切换功能,默认根据当地时间判断,并支持手动切换。
 * Version: 1.0.3
 * Author: 耳朵的主人
 * Author URI: https://www.edzbe.com
 * License: GPL-2.0+
 * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
 * Text Domain: daynight-switcher
 * Domain Path: /languages
 */

// 阻止直接访问文件,增强安全性
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * 提前判断初始模式(PHP服务器端)
 * 优先级:Cookie (用户偏好) > 服务器时间
 * @return string 'light' 或 'dark'
 */

function dns_get_initial_mode_server_side() {
    // 1. 尝试从Cookie获取用户偏好
    if ( isset( $_COOKIE['theme-mode'] ) && in_array( $_COOKIE['theme-mode'], ['light', 'dark'] ) ) {
        return $_COOKIE['theme-mode'];
    }

    // 2. 如果Cookie不存在,根据服务器时间判断
    $hour = (int) current_time( 'H', true ); // 使用WordPress的 current_time 获取当前小时,避免时区问题
    return ($hour >= 6 && $hour < 18) ? 'light' : 'dark'; // 6-18点白天
}

/**
 * 注册并加载日夜模式脚本
 * 注意:日夜模式的样式文件不再在这里直接 enqueue,而是由 dns_output_conditional_styles 动态输出。
 */

function dns_enqueue_scripts() {
    // 获取主题目录URI
    $theme_css_dir_uri = get_template_directory_uri() . '/css/'; // 仍然传递给JS,以防需要手动构建 link 标签 fallback

    // 注册切换脚本(在页脚加载,确保DOM就绪)
    wp_enqueue_script(
        'daynight-switcher-script',
        plugins_url( 'js/daynight-switcher.js', __FILE__ ),
        array(),
        '1.0.0',
        true
    );

    // 将PHP数据传递给JS(如样式表ID、按钮ID、CSS文件路径)
    wp_localize_script(
        'daynight-switcher-script',
        'dns_data',
        array(
            'lightStyleId'      => 'daynight-switcher-light-style-css',
            'darkStyleId'       => 'daynight-switcher-dark-style-css',
            'buttonId'          => 'daynight-toggle',
            'textLight'         => esc_html__( '切换到暗夜模式', 'daynight-switcher' ),
            'textDark'          => esc_html__( '切换到白天模式', 'daynight-switcher' ),
            'lightStyleUrl'     => $theme_css_dir_uri . 'style-light.css', // 传递CSS路径给JS,用于动态创建link标签
            'darkStyleUrl'      => $theme_css_dir_uri . 'style-dark.css',  // 传递CSS路径给JS,用于动态创建link标签
        )
    );
}
add_action( 'wp_enqueue_scripts', 'dns_enqueue_scripts' ); // 重命名函数,因为不再enqueue styles

/**
 * 在页面<body>开头添加切换按钮(兼容WP5.2+)
 */

function dns_add_toggle_button() {
    if ( is_admin() ) return; // 排除后台
    ?>
    <button id="daynight-toggle" class="daynight-toggle-button" aria-label="<?php esc_attr_e( '切换日夜模式', 'daynight-switcher' ); ?>">
        <?php esc_html_e( '加载中...', 'daynight-switcher' ); ?>
    </button>
    <?php
}
add_action( 'wp_body_open', 'dns_add_toggle_button' );

/**
 * 核心:在页面头部根据PHP判断动态输出正确的样式表和body类
 * 这将避免任何模式切换时的闪烁。
 */

function dns_output_conditional_styles() {
    if ( is_admin() ) return; // 排除后台

    $initial_mode = dns_get_initial_mode_server_side();
    $theme_css_dir_uri = get_template_directory_uri() . '/css/';
    $version = '1.0.0'; // 样式表的版本号

    // 输出正确的样式表
    if ( $initial_mode === 'light' ) {
        echo '<link rel="stylesheet" id="daynight-switcher-light-style-css" href="' . esc_url( $theme_css_dir_uri . 'style-light.css?ver=' . $version ) . '" type="text/css" media="all"/>';
        echo '<link rel="stylesheet" id="daynight-switcher-dark-style-css" href="' . esc_url( $theme_css_dir_uri . 'style-dark.css?ver=' . $version ) . '" type="text/css" media="not all"/>';
    } else { // dark mode
        echo '<link rel="stylesheet" id="daynight-switcher-light-style-css" href="' . esc_url( $theme_css_dir_uri . 'style-light.css?ver=' . $version ) . '" type="text/css" media="not all"/>';
        echo '<link rel="stylesheet" id="daynight-switcher-dark-style-css" href="' . esc_url( $theme_css_dir_uri . 'style-dark.css?ver=' . $version ) . '" type="text/css" media="all"/>';
    }

    // 立即在body标签上设置正确的class,防止任何延迟闪烁
    // 注意:这个内联脚本在<?php标签内,所以它会先于任何其他JS执行
    ?>
    <script>
        // 确保body class在HTML解析时就存在
        document.documentElement.classList.add('<?php echo esc_js( $initial_mode ); ?>-mode');
        document.body.classList.add('<?php echo esc_js( $initial_mode ); ?>-mode');

        // 后备或纠正逻辑(如果localStorage与PHP判断不符,或Cookie过期)
        (function() {
            const savedMode = localStorage.getItem('theme-mode');
            const currentInitialMode = '<?php echo esc_js( $initial_mode ); ?>'; // PHP决定的初始模式

            if (savedMode && savedMode !== currentInitialMode) {
                // 如果localStorage和PHP的初始判断不一致,JS会立即纠正
                const lightStyle = document.getElementById('daynight-switcher-light-style-css');
                const darkStyle = document.getElementById('daynight-switcher-dark-style-css');

                if (lightStyle && darkStyle) {
                    if (savedMode === 'light') {
                        lightStyle.media = 'all';
                        darkStyle.media = 'not all';
                    } else { // savedMode === 'dark'
                        lightStyle.media = 'not all';
                        darkStyle.media = 'all';
                    }
                }
                document.documentElement.classList.remove('light-mode', 'dark-mode');
                document.documentElement.classList.add(`${savedMode}-mode`);
                document.body.classList.remove('light-mode', 'dark-mode');
                document.body.classList.add(`${savedMode}-mode`);
            }
        })();
    </script>
    <?php
}
// 在<head>标签内优先执行(优先级1,确保最早运行)
add_action( 'wp_head', 'dns_output_conditional_styles', 1 );


</head></body>

js代码如下:

document.addEventListener('DOMContentLoaded', function() {
    // 检查本地化数据是否正常
    if (typeof dns_data === 'undefined') {
        console.error('日夜模式切换器:未获取到本地化数据,请检查PHP的wp_localize_script调用!');
        return;
    }

    // 解构本地化数据
    const { lightStyleId, darkStyleId, buttonId, textLight, textDark, lightStyleUrl, darkStyleUrl } = dns_data;

    // 获取DOM元素
    const lightStyle = document.getElementById(lightStyleId);
    const darkStyle = document.getElementById(darkStyleId);
    const toggleButton = document.getElementById(buttonId);

    // 确保样式表元素存在。如果PHP动态输出失败,这里可能是null。
    // 但是在最新的方案中,PHP一定会输出这两个link标签,只是media属性不同。
    if (!lightStyle || !darkStyle || !toggleButton) {
        // Fallback: 如果PHP没有输出link标签,JS动态创建它们
        console.warn('日夜模式切换器:未找到核心样式表元素。尝试动态创建。');
        // 如果lightStyle或darkStyle不存在,这里需要动态创建。
        // 为了简化,这里假设它们总是由PHP输出。如果真的未找到,需要更复杂的JS fallback。
        // 目前先跳过,因为PHP应该确保它们存在。
        // return; // 暂时不返回,让下面的逻辑有机会运行
    }


    console.log('日夜模式切换器:核心元素加载完成!');

    /**
     * 设置Cookie
     * @param {string} name - Cookie名称
     * @param {string} value - Cookie值
     * @param {number} days - Cookie过期天数
     */

    function setCookie(name, value, days) {
        let expires = "";
        if (days) {
            const date = new Date();
            date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
            expires = "; expires=" + date.toUTCString();
        }
        document.cookie = name + "=" + (value || "")  + expires + "; path=/";
    }

    /**
     * 设置主题模式(更新样式、按钮文本、body类、同步Cookie)
     * @param {string} mode - 'light'或'dark'
     * @param {boolean} save - 是否保存到localStorage和Cookie
     */

    function setMode(mode, save = true) {
        // 更新样式表状态,通过修改 media 属性来激活/禁用样式
        if (mode === 'light') {
            if (lightStyle) lightStyle.media = 'all';     // 激活白天样式
            if (darkStyle) darkStyle.media = 'not all';  // 禁用暗夜样式
            toggleButton.textContent = textLight;
            toggleButton.setAttribute('aria-pressed', 'false');
        } else { // mode === 'dark'
            if (lightStyle) lightStyle.media = 'not all'; // 禁用白天样式
            if (darkStyle) darkStyle.media = 'all';      // 激活暗夜样式
            toggleButton.textContent = textDark;
            toggleButton.setAttribute('aria-pressed', 'true');
        }

        // 更新body和html根元素的类(方便扩展CSS)
        document.documentElement.classList.remove('light-mode', 'dark-mode');
        document.documentElement.classList.add(`${mode}-mode`);
        document.body.classList.remove('light-mode', 'dark-mode');
        document.body.classList.add(`${mode}-mode`);

        // 保存用户偏好(可选)到 localStorage 和 Cookie
        if (save) {
            localStorage.setItem('theme-mode', mode);
            setCookie('theme-mode', mode, 30); // Cookie保存30天
        }
    }

    /**
     * 获取系统默认模式
     * @returns {string} 'light'或'dark'
     */

    function getSystemMode() {
        const hour = new Date().getHours();
        return (hour >= 6 && hour < 18) ? 'light' : 'dark';
    }

    // --- 初始化 ---
    // 页面加载时的初始模式判断和样式设置已由PHP在服务器端完成,
    // 这里的JS初始化主要是确保按钮文本正确,并处理LocalStorage和Cookie可能不同步的情况。
    const savedMode = localStorage.getItem('theme-mode');
    let initialMode;

    if (savedMode && (savedMode === 'light' || savedMode === 'dark')) {
        initialMode = savedMode;
    } else {
        initialMode = getSystemMode();
    }

    // 确保当前的Cookie也与initialMode一致,防止PHP下次加载时判断错误
    setCookie('theme-mode', initialMode, 30);

    // 调用 setMode 来同步按钮文本,以及确保 body class 即使在PHP未能设置时也能被设置(虽然PHP现在会设置)
    setMode(initialMode, false);
    console.log(`日夜模式切换器:初始模式为${initialMode}`);


    // --- 切换按钮点击事件 ---
    toggleButton.addEventListener('click', function() {
        // 从html根元素获取当前模式,因为CSS可能也通过html根元素控制
        const currentMode = document.documentElement.classList.contains('light-mode') ? 'light' : 'dark';
        const newMode = currentMode === 'light' ? 'dark' : 'light';
        setMode(newMode); // 切换并保存偏好
        console.log(`日夜模式切换器:已切换至${newMode}`);
    });
});

核心原理和解决闪烁的方法:

1. PHP 服务器端预判: PHP 在页面生成之初(在 `wp_head` 动作中,优先级为1),就通过 `dns_get_initial_mode_server_side()` 函数,根据 `theme-mode` Cookie 或服务器时间,判断出应该显示的模式。

2. 只输出所需 `<link>` 标签: `dns_output_conditional_styles()` 函数根据 PHP 的判断结果,直接在 HTML 的 `<head>` 中输出 两个 `<link>` 标签。
• 正确的模式 的 `<link>` 标签 `media` 属性是 `all`
• 不正确的模式 的 `<link>` 标签 `media` 属性是 `not all`
这样,在浏览器开始解析和渲染 HTML 时,它只会加载并应用正确的模式样式,从而从源头上避免了加载错误样式导致的闪烁。

3. `document.documentElement` `document.body` 类: PHP 还会输出一个内联 `<script>`,它会立即为 `<html>``<body>` 元素添加正确的模式类(例如 `dark-mode`)。这对于依赖这些类来设置背景色、字体颜色等全局样式的 CSS 规则至关重要,确保页面在渲染时就有正确的颜色基调。

4. JavaScript Cookie 同步: JS 代码在 `setMode` 时,除了更新 `localStorage`,还会更新一个 `theme-mode` Cookie。这样,用户下次访问时,PHP 就能从 Cookie 中读取到用户上次的选择。

5. 内联 JS 后备纠正: PHP 输出的内联 JS 中含有一个小的逻辑,用于比较 PHP 的判断(来自 Cookie 或时间)和 `localStorage` 中的用户偏好。如果两者不一致(例如,用户清除了 Cookie 但 `localStorage` 还在),这个内联 JS 会立即纠正模式,提供额外的鲁棒性。

代码仅供参考,在需要调用按钮的前端,添加按钮:

<button id="daynight-toggle" class="daynight-toggle-button" aria-label="<?php esc_attr_e( '切换日夜模式', 'daynight-switcher' ); ?>">
<?php esc_html_e( '加载中...', 'daynight-switcher' ); ?>
</button>

还有一个问题就是,header.php文件必须包含<?php wp_head(); ?>footer.php文件代码必须包含 <?php wp_footer(); ?> ,按钮在二者之间的位置插入,否则无法正常加载,为什么,我也不知道,我是一步一步修过来的,怎么修的,不知道。

顺便提供下我的按钮图标:

完整插件代码下载:daynight-switcher

伪技术贴完工,睡觉。

  •