HuaTian.vue 27 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037
  1. <template>
  2. <!--
  3. 设定:
  4. suo:锁;
  5. flower:花,共7种,图片分别为flower1.png flower2.png flower7.png;
  6. zacao:杂草;
  7. tian:田地,如果是待解锁的田地,图片用tian_suo.png,如果是已解锁就用tian.png;
  8. souhuo:收获标识;
  9. select_zz:7种花的view,默认应该隐藏,点击播种时显示,播种结束后隐藏
  10. 4个按钮:
  11. 解锁荒地:点击时,将第一块待解锁的田地转换为已解锁地
  12. 除草:点击时,让杂草隐藏
  13. 播种:点击时,需要先将7种花显示出来,选择其中一种,然后再点击除去杂草的地,然后该块地上显示种子,然后10分钟倒计时,然后显示对应的花,以及收获标识
  14. 收获:点击后,有收获标识的土地上的收获标识图片隐藏,花隐藏,出现杂草
  15. 操作流程:
  16. 默认显示待解锁的田地(其他几个图标都隐藏),点击"解锁荒地",点击"除草",点击"播种",到时间后点击"收获" -->
  17. <view class="page" v-if="show">
  18. <view class="task-board">
  19. <view class="task_day" @click="handleTaskDayClick" :class="{'task-day-active': taskDayActive}">
  20. <image src="../../static/island/huatian/btn_task_day.png" class="task"></image>
  21. </view>
  22. <view class="board-title">
  23. </view>
  24. <view class="bodyContent">
  25. <block v-for="(field, index) in fields" :key="index">
  26. <view class="blank" v-if="index == 0 || index == 7 || index == 10"></view>
  27. <view class="item" :class="{
  28. 'locked': !field.isUnlocked,
  29. 'weedy': field.hasWeed,
  30. 'weed-blink': weedMode && field.hasWeed,
  31. 'planted': field.flower,
  32. 'growing': field.isGrowing,
  33. 'ready': field.canHarvest,
  34. 'harvest-blink': harvestMode && field.canHarvest
  35. }" @click="handleFieldClick(index)">
  36. <image v-if="!field.isUnlocked" src="../../static/island/huatian/suo.png" class="suo"></image>
  37. <image v-if="field.flower && field.growthCompleted"
  38. :src="`../../static/island/huatian/flower${field.flowerType}.png`" class="flower"></image>
  39. <image v-if="field.seedStage && field.isGrowing" src="../../static/island/huatian/zongzi.png"
  40. class="flower"></image>
  41. <image v-if="field.hasWeed && field.isUnlocked" src="../../static/island/huatian/zacao.png"
  42. class="zacao"></image>
  43. <image
  44. :src="field.isUnlocked ? '../../static/island/huatian/tian.png' : '../../static/island/huatian/tian_suo.png'"
  45. class="tian"></image>
  46. <image v-if="field.canHarvest" src="../../static/island/huatian/souhuo.png" class="souhuo">
  47. </image>
  48. <view class="timer" v-if="field.isGrowing">
  49. <image src="../../static/island/huatian/timer.png" class="icon"></image>
  50. <text>{{formatTime(field.remainingTime)}}</text>
  51. </view>
  52. </view>
  53. <view class="blank" v-if="index == 2 || index == 9 || index == 12"></view>
  54. </block>
  55. </view>
  56. <view class="close" @click="onClose">
  57. <image src="../../static/island/UI/btn_close.png" class="close"></image>
  58. </view>
  59. <view class="btn_list">
  60. <view class="item item1" @click="showUnlockConfirm">
  61. 解锁荒地
  62. </view>
  63. <view class="item item2" @click="removeWeed">
  64. 除草
  65. </view>
  66. <view class="item item3" @click="showFlowerSelect">
  67. 播种
  68. </view>
  69. <view class="item item4" @click="enterHarvestMode">
  70. 收获
  71. </view>
  72. </view>
  73. <view class="select_zz" v-if="showFlowerSelection">
  74. <view class="item" v-for="(flower, idx) in flowers" :key="idx" @click="selectFlower(idx)"
  75. v-if="flower.count > 0">
  76. <view class="img">
  77. <image :src="`../../static/island/huatian/flower${idx+1}.png`"></image>
  78. </view>
  79. <view class="foot">
  80. {{flower.count}}
  81. </view>
  82. </view>
  83. <view class="jiantou">
  84. <image class="jiantou" src="../../static/island/huatian/jiantou.png"></image>
  85. </view>
  86. </view>
  87. </view>
  88. <!-- 解锁确认对话框 -->
  89. <view class="confirm-dialog" v-if="showUnlockDialog">
  90. <view class="dialog-content">
  91. <view class="dialog-title">解锁荒地</view>
  92. <view class="dialog-text">是否支付{{nextLandPrice}}铃钱解锁荒地?</view>
  93. <view class="dialog-buttons">
  94. <view class="btn-cancel" @click="cancelUnlock">取消</view>
  95. <view class="btn-confirm" @click="confirmUnlock">确认</view>
  96. </view>
  97. </view>
  98. </view>
  99. <view class="guild" v-if="showGuide">
  100. <view class="content">
  101. "欢迎来到花田!在这里,你将成为农场的主人,体验种植和经营农场的乐趣。首先,让我们来开垦一块土地吧。只需支付铃钱即可解锁!"
  102. </view>
  103. <view class="title">
  104. 罗奇
  105. </view>
  106. <view class="npc">
  107. <image src="../../static/island/npc.png"></image>
  108. </view>
  109. </view>
  110. </view>
  111. </template>
  112. <script>
  113. export default {
  114. name: 'TaskDialog',
  115. components: {
  116. },
  117. props: {
  118. visible: {
  119. type: Boolean,
  120. default: false
  121. }
  122. },
  123. data() {
  124. return {
  125. show: false,
  126. dataLoaded: false,
  127. // 用户ID
  128. ssoId: 0,
  129. // 田地数据
  130. fields: Array(20).fill().map(() => ({
  131. id: 0, // 后端数据库ID
  132. tid: 0, // 对应的土地表ID
  133. isUnlocked: false,
  134. hasWeed: false,
  135. flower: false,
  136. flowerType: null,
  137. isGrowing: false,
  138. growthCompleted: false,
  139. canHarvest: false,
  140. remainingTime: 0,
  141. timer: null,
  142. seedStage: false,
  143. plantTime: '',
  144. state: 0 // 与后端对应的状态
  145. })),
  146. // 花的数据
  147. flowers: [],
  148. // 种子数据
  149. seeds: [],
  150. // 用户铃钱
  151. money: 0,
  152. // 下一块要解锁的土地价格
  153. nextLandPrice: 100,
  154. // 选择状态
  155. selectedFlowerIndex: -1,
  156. showFlowerSelection: false,
  157. showGuide: false,
  158. plantMode: false,
  159. showUnlockDialog: false, // 解锁确认对话框显示状态
  160. // 当前选择的土地ID
  161. selectedLandId: 0,
  162. // 成长检查定时器
  163. growthCheckTimer: null,
  164. weedMode: false, // 添加除草模式状态
  165. weedyFields: [], // 添加可除草的地块列表
  166. harvestMode: false, // 添加收获模式状态
  167. harvestableFields: [], // 添加可收获的地块列表
  168. taskDayActive: false,
  169. // 主岛引用
  170. mainLand: null,
  171. }
  172. },
  173. watch: {
  174. visible: {
  175. immediate: true,
  176. handler(val) {
  177. if (val) {
  178. this.fetchData();
  179. } else {
  180. this.show = false;
  181. this.dataLoaded = false;
  182. }
  183. }
  184. }
  185. },
  186. onLoad() {
  187. // 初始化获取数据
  188. this.fetchData();
  189. },
  190. onShow() {
  191. // 重新获取数据
  192. this.fetchData();
  193. },
  194. beforeDestroy() {
  195. // 清除所有定时器
  196. this.fields.forEach(field => {
  197. if (field.timer) {
  198. clearInterval(field.timer);
  199. }
  200. });
  201. // 清除生长检查定时器
  202. if (this.growthCheckTimer) {
  203. clearInterval(this.growthCheckTimer);
  204. }
  205. },
  206. methods: {
  207. // 关闭界面
  208. onClose() {
  209. this.show = false;
  210. this.$emit('update:visible', false);
  211. this.$emit('close');
  212. },
  213. // 初始化获取数据
  214. async fetchData() {
  215. console.log("uuid", getApp().globalData.uuid)
  216. try {
  217. uni.request({
  218. url: this.$apiHost + '/Game/huatian/index',
  219. method: 'POST',
  220. data: {
  221. uuid: getApp().globalData.uuid,
  222. },
  223. header: {
  224. 'Content-Type': 'application/x-www-form-urlencoded',
  225. 'sign': getApp().globalData.headerSign,
  226. },
  227. success: (res) => {
  228. if (res.data && res.data.code === 0) {
  229. // 更新用户铃钱
  230. this.money = res.data.money;
  231. // 更新种子数据
  232. this.seeds = res.data.seeds || [];
  233. // 更新背包数据
  234. const bagItems = res.data.bag_list || [];
  235. // 更新花的数据(背包中type=1的是种子)
  236. this.flowers = [];
  237. for (let i = 1; i <= 7; i++) {
  238. // 找到对应的种子数量
  239. const seedBag = bagItems.find(item => item.type === 1 && item.tid === i);
  240. this.flowers.push({
  241. id: i,
  242. name: this.seeds[i - 1]?.name || `花${i}`,
  243. count: seedBag ? seedBag.num : 0
  244. });
  245. }
  246. // 更新土地数据
  247. const tudiList = res.data.tudi_list || [];
  248. // 重置田地数据
  249. this.fields = Array(20).fill().map((_, index) => ({
  250. id: 0,
  251. tid: index + 1,
  252. isUnlocked: false,
  253. hasWeed: false,
  254. flower: false,
  255. flowerType: null,
  256. isGrowing: false,
  257. growthCompleted: false,
  258. canHarvest: false,
  259. remainingTime: 0,
  260. timer: null,
  261. seedStage: false,
  262. plantTime: '',
  263. state: 0
  264. }));
  265. // 更新已解锁的田地状态
  266. tudiList.forEach(land => {
  267. const fieldIndex = land.tid - 1;
  268. if (fieldIndex >= 0 && fieldIndex < this.fields.length) {
  269. const field = this.fields[fieldIndex];
  270. field.id = land.id;
  271. field.tid = land.tid;
  272. field.isUnlocked = true;
  273. field.state = land.state;
  274. field.plantTime = land.plant_time;
  275. // 根据状态设置不同的显示
  276. if (land.state === -1) {
  277. // 杂草地
  278. field.hasWeed = true;
  279. } else if (land.state === 0) {
  280. // 待播种的空地
  281. field.hasWeed = false;
  282. } else if (land.state >= 1 && land.state <= 7) {
  283. // 种植了花
  284. field.hasWeed = false;
  285. field.flowerType = land.zzid;
  286. // 计算是否已经成熟
  287. if (land.plant_time) {
  288. const plantTime = new Date(land.plant_time);
  289. const now = new Date();
  290. const growthHours = (now - plantTime) / (1000 * 60 * 60);
  291. // 获取对应种子的生长周期
  292. const seed = this.seeds.find(s => s.id === land.state);
  293. const limitHours = seed ? seed.limit_time : 0;
  294. if (growthHours >= limitHours) {
  295. // 已成熟
  296. field.flower = true;
  297. field.growthCompleted = true;
  298. field.canHarvest = true;
  299. } else {
  300. // 未成熟,显示生长中
  301. field.isGrowing = true;
  302. field.seedStage = true;
  303. field.remainingTime = Math.ceil((limitHours - growthHours) * 60 * 60);
  304. this.startGrowthTimer(fieldIndex);
  305. }
  306. }
  307. } else if (land.state === 99) {
  308. // 成熟待收割
  309. field.hasWeed = false;
  310. field.flower = true;
  311. field.flowerType = land.flowerType || land.zzid;
  312. field.growthCompleted = true;
  313. field.canHarvest = true;
  314. }
  315. }
  316. });
  317. // 找到下一块可解锁土地的价格
  318. for (let i = 0; i < this.fields.length; i++) {
  319. if (!this.fields[i].isUnlocked) {
  320. console.log("this.landpric", i + 1)
  321. // 从服务端获取土地价格
  322. uni.request({
  323. url: this.$apiHost + '/Game/huatian/get_land_price',
  324. method: 'POST',
  325. data: {
  326. uuid: getApp().globalData.uuid,
  327. land_id: i + 1
  328. },
  329. header: {
  330. 'Content-Type': 'application/x-www-form-urlencoded',
  331. 'sign': getApp().globalData.headerSign,
  332. uuid: getApp().globalData.uuid,
  333. },
  334. success: (res) => {
  335. console.log('res.data', res.data);
  336. if (res.data && res.data.code === 0) {
  337. this.nextLandPrice = res.data.data.price;
  338. } else {
  339. // 如果获取失败,使用默认值
  340. this.nextLandPrice = 100;
  341. }
  342. // 数据加载完成,显示界面
  343. this.dataLoaded = true;
  344. this.show = true;
  345. },
  346. fail: (err) => {
  347. console.error('获取土地价格异常', err);
  348. // 如果获取失败,使用默认值
  349. this.nextLandPrice = 100;
  350. // 数据加载完成,显示界面
  351. this.dataLoaded = true;
  352. this.show = true;
  353. }
  354. });
  355. break;
  356. }
  357. }
  358. // 启动定时检查植物生长状态
  359. this.startGrowthCheck();
  360. } else {
  361. uni.showToast({
  362. title: res.data?.msg || '获取数据失败',
  363. icon: 'none'
  364. });
  365. this.dataLoaded = true;
  366. this.show = true;
  367. }
  368. },
  369. fail: (err) => {
  370. console.error('获取数据异常', err);
  371. uni.showToast({
  372. title: '网络异常,请重试',
  373. icon: 'none'
  374. });
  375. this.dataLoaded = true;
  376. this.show = true;
  377. }
  378. });
  379. } catch (error) {
  380. console.error('获取数据异常', error);
  381. uni.showToast({
  382. title: '网络异常,请重试',
  383. icon: 'none'
  384. });
  385. this.dataLoaded = true;
  386. this.show = true;
  387. }
  388. },
  389. // 显示解锁确认对话框
  390. showUnlockConfirm() {
  391. this.harvestMode = false;
  392. this.weedMode = false;
  393. this.showUnlockDialog = true;
  394. },
  395. // 取消解锁
  396. cancelUnlock() {
  397. this.showUnlockDialog = false;
  398. },
  399. // 确认解锁
  400. async confirmUnlock() {
  401. try {
  402. uni.request({
  403. url: this.$apiHost + '/Game/huatian/unlock_land',
  404. method: 'POST',
  405. data: {
  406. uuid: getApp().globalData.uuid,
  407. },
  408. header: {
  409. 'Content-Type': 'application/x-www-form-urlencoded',
  410. 'sign': getApp().globalData.headerSign,
  411. uuid: getApp().globalData.uuid,
  412. },
  413. success: (res) => {
  414. if (res.data && res.data.code === 0) {
  415. uni.showToast({
  416. title: '解锁成功',
  417. icon: 'success'
  418. });
  419. // 更新用户铃钱
  420. this.money = res.data.data.money;
  421. // 重新获取数据
  422. this.fetchData();
  423. } else {
  424. uni.showToast({
  425. title: res.data?.msg || '解锁失败',
  426. icon: 'none'
  427. });
  428. }
  429. },
  430. fail: (err) => {
  431. console.error('解锁土地异常', err);
  432. uni.showToast({
  433. title: '网络异常,请重试',
  434. icon: 'none'
  435. });
  436. }
  437. });
  438. } catch (error) {
  439. console.error('解锁土地异常', error);
  440. uni.showToast({
  441. title: '网络异常,请重试',
  442. icon: 'none'
  443. });
  444. }
  445. this.showUnlockDialog = false;
  446. },
  447. // 除草
  448. async removeWeed() {
  449. this.harvestMode = false;
  450. if (this.weedMode) {
  451. // 如果已经在除草模式,则退出
  452. this.weedMode = false;
  453. this.weedyFields = [];
  454. return;
  455. }
  456. // 找到所有有杂草的已解锁土地
  457. this.weedyFields = this.fields.filter(field => field.isUnlocked && field.hasWeed);
  458. if (this.weedyFields.length === 0) {
  459. uni.showToast({
  460. title: '没有需要除草的土地',
  461. icon: 'none'
  462. });
  463. return;
  464. }
  465. // 进入除草模式
  466. this.weedMode = true;
  467. uni.showToast({
  468. title: '请点击需要除草的土地',
  469. icon: 'none'
  470. });
  471. },
  472. // 进入收获模式
  473. enterHarvestMode() {
  474. this.weedMode = false;
  475. if (this.harvestMode) {
  476. // 如果已经在收获模式,则退出
  477. this.harvestMode = false;
  478. this.harvestableFields = [];
  479. return;
  480. }
  481. // 找到所有可收获的土地
  482. this.harvestableFields = this.fields.filter(field => field.canHarvest);
  483. if (this.harvestableFields.length === 0) {
  484. uni.showToast({
  485. title: '没有可收获的花',
  486. icon: 'none'
  487. });
  488. return;
  489. }
  490. // 进入收获模式
  491. this.harvestMode = true;
  492. uni.showToast({
  493. title: '请点击需要收获的土地',
  494. icon: 'none'
  495. });
  496. },
  497. // 显示花的选择
  498. showFlowerSelect() {
  499. this.harvestMode = false;
  500. this.weedMode = false;
  501. if (this.showFlowerSelection) {
  502. this.showFlowerSelection = false;
  503. return;
  504. }
  505. // 检查是否有可播种的土地
  506. const canPlantFields = this.fields.filter(field => field.isUnlocked && !field.hasWeed && !field.flower && !
  507. field.isGrowing);
  508. if (canPlantFields.length === 0) {
  509. uni.showToast({
  510. title: '没有可播种的土地',
  511. icon: 'none'
  512. });
  513. return;
  514. }
  515. this.showFlowerSelection = true;
  516. this.plantMode = false;
  517. this.selectedFlowerIndex = -1;
  518. },
  519. // 选择花
  520. selectFlower(idx) {
  521. this.selectedFlowerIndex = idx;
  522. this.showFlowerSelection = false;
  523. this.plantMode = true;
  524. },
  525. // 点击田地
  526. handleFieldClick(index) {
  527. if (this.weedMode) {
  528. // 在除草模式下,只处理有草的地块
  529. if (this.fields[index].hasWeed) {
  530. this.removeWeedFromField(index);
  531. }
  532. return;
  533. }
  534. if (this.harvestMode) {
  535. // 在收获模式下,只处理可收获的地块
  536. if (this.fields[index].canHarvest) {
  537. this.harvestField(this.fields[index].id);
  538. }
  539. return;
  540. }
  541. if (this.plantMode) {
  542. if (this.fields[index].canHarvest) {
  543. }
  544. this.handleFieldClickBZ(index);
  545. return;
  546. }
  547. // 原有的种植逻辑
  548. if (!this.fields[index].isUnlocked) {
  549. uni.showToast({
  550. title: '该地块未解锁',
  551. icon: 'none'
  552. });
  553. return;
  554. }
  555. if (this.fields[index].flower) {
  556. if (this.fields[index].canHarvest) {
  557. this.harvestField(this.fields[index].id);
  558. } else {
  559. uni.showToast({
  560. title: '花朵正在生长中',
  561. icon: 'none'
  562. });
  563. }
  564. return;
  565. }
  566. // 打开种子选择弹窗
  567. this.currentFieldIndex = index;
  568. this.showSeedSelector = true;
  569. },
  570. // 点击田地
  571. async handleFieldClickBZ(index) {
  572. const field = this.fields[index];
  573. // 已解锁土地且处于播种模式
  574. if (this.plantMode && field.isUnlocked && !field.hasWeed && !field.flower && !field.isGrowing) {
  575. // 设置当前选中的土地
  576. this.selectedLandId = field.id;
  577. // 播种
  578. try {
  579. uni.request({
  580. url: this.$apiHost + '/Game/huatian/plant_seed',
  581. method: 'POST',
  582. data: {
  583. uuid: getApp().globalData.uuid,
  584. land_id: field.id,
  585. seed_id: this.selectedFlowerIndex + 1
  586. },
  587. header: {
  588. 'Content-Type': 'application/x-www-form-urlencoded',
  589. 'sign': getApp().globalData.headerSign,
  590. uuid: getApp().globalData.uuid,
  591. },
  592. success: (res) => {
  593. if (res.data && res.data.code === 0) {
  594. // 更新土地状态
  595. field.isGrowing = true;
  596. field.seedStage = true;
  597. field.flowerType = this.selectedFlowerIndex + 1;
  598. field.state = this.selectedFlowerIndex + 1;
  599. field.plantTime = res.data.data.plantTime;
  600. // 计算剩余生长时间
  601. const limitTimeHours = res.data.data.limitTime;
  602. field.remainingTime = limitTimeHours * 60 * 60;
  603. // 开始计时
  604. this.startGrowthTimer(index);
  605. // 更新种子数量
  606. const flowerData = this.flowers[this.selectedFlowerIndex];
  607. if (flowerData && flowerData.count > 0) {
  608. flowerData.count--;
  609. }
  610. // 退出播种模式
  611. this.plantMode = false;
  612. uni.showToast({
  613. title: '播种成功',
  614. icon: 'success'
  615. });
  616. } else {
  617. uni.showToast({
  618. title: res.data?.msg || '播种失败',
  619. icon: 'none'
  620. });
  621. this.plantMode = false;
  622. }
  623. },
  624. fail: (err) => {
  625. console.error('播种异常', err);
  626. uni.showToast({
  627. title: '网络异常,请重试',
  628. icon: 'none'
  629. });
  630. this.plantMode = false;
  631. }
  632. });
  633. } catch (error) {
  634. console.error('播种异常', error);
  635. uni.showToast({
  636. title: '网络异常,请重试',
  637. icon: 'none'
  638. });
  639. this.plantMode = false;
  640. }
  641. } else if (field.canHarvest) {
  642. // 收获花朵
  643. this.harvestField(field.id);
  644. }
  645. },
  646. // 从特定地块移除杂草
  647. removeWeedFromField(index) {
  648. // 调用除草API
  649. uni.request({
  650. url: this.$apiHost + '/Game/huatian/remove_weed',
  651. method: 'POST',
  652. data: {
  653. uuid: getApp().globalData.uuid,
  654. land_id: this.fields[index].id
  655. },
  656. header: {
  657. 'Content-Type': 'application/x-www-form-urlencoded',
  658. 'sign': getApp().globalData.headerSign,
  659. uuid: getApp().globalData.uuid,
  660. },
  661. success: (res) => {
  662. if (res.data && res.data.code === 0) {
  663. // 更新地块状态
  664. this.fields[index].hasWeed = false;
  665. this.fields[index].state = 0;
  666. // 从可除草地块列表中移除
  667. this.weedyFields = this.weedyFields.filter(f => f.id !== this.fields[index].id);
  668. uni.showToast({
  669. title: '除草成功',
  670. icon: 'success'
  671. });
  672. // 如果所有草都已清除,退出除草模式
  673. if (this.weedyFields.length === 0) {
  674. this.weedMode = false;
  675. uni.showToast({
  676. title: '所有杂草已清除',
  677. icon: 'success'
  678. });
  679. }
  680. } else {
  681. uni.showToast({
  682. title: res.data?.msg || '除草失败',
  683. icon: 'none'
  684. });
  685. }
  686. },
  687. fail: (err) => {
  688. console.error('除草异常', err);
  689. uni.showToast({
  690. title: '网络异常,请重试',
  691. icon: 'none'
  692. });
  693. }
  694. });
  695. },
  696. // 开始生长计时器
  697. startGrowthTimer(fieldIndex) {
  698. const field = this.fields[fieldIndex];
  699. // 清除可能存在的旧定时器
  700. if (field.timer) {
  701. clearInterval(field.timer);
  702. }
  703. field.timer = setInterval(() => {
  704. field.remainingTime--;
  705. if (field.remainingTime <= 0) {
  706. // 生长完成
  707. clearInterval(field.timer);
  708. field.isGrowing = false;
  709. field.seedStage = false;
  710. field.growthCompleted = true;
  711. field.flower = true;
  712. field.canHarvest = true;
  713. }
  714. }, 1000);
  715. },
  716. // 收获特定地块
  717. async harvestField(landId) {
  718. console.log("land", landId);
  719. try {
  720. uni.request({
  721. url: this.$apiHost + '/Game/huatian/harvest',
  722. method: 'POST',
  723. data: {
  724. uuid: getApp().globalData.uuid,
  725. land_id: landId
  726. },
  727. header: {
  728. 'Content-Type': 'application/x-www-form-urlencoded',
  729. 'sign': getApp().globalData.headerSign,
  730. uuid: getApp().globalData.uuid,
  731. },
  732. success: (res) => {
  733. if (res.data && res.data.code === 0) {
  734. // 找到对应的田地
  735. const fieldIndex = this.fields.findIndex(f => f.id === landId);
  736. if (fieldIndex >= 0) {
  737. const field = this.fields[fieldIndex];
  738. // 重置状态
  739. field.flower = false;
  740. field.flowerType = null;
  741. field.growthCompleted = false;
  742. field.canHarvest = false;
  743. field.hasWeed = true;
  744. field.state = -1;
  745. // 如果有定时器,清除它
  746. if (field.timer) {
  747. clearInterval(field.timer);
  748. field.timer = null;
  749. }
  750. }
  751. // 重新获取数据以更新背包
  752. this.fetchData();
  753. uni.showToast({
  754. title: `收获了${res.data.data.harvestNum}朵花`,
  755. icon: 'success'
  756. });
  757. // 从可收获地块列表中移除
  758. this.harvestableFields = this.harvestableFields.filter(f => f.id !==
  759. landId);
  760. // 如果所有花都已收获,退出收获模式
  761. if (this.harvestableFields.length === 0) {
  762. this.harvestMode = false;
  763. uni.showToast({
  764. title: '所有花已收获',
  765. icon: 'success'
  766. });
  767. }
  768. } else {
  769. uni.showToast({
  770. title: res.data?.msg || '收获失败',
  771. icon: 'none'
  772. });
  773. }
  774. },
  775. fail: (err) => {
  776. console.error('收获异常', err);
  777. uni.showToast({
  778. title: '网络异常,请重试',
  779. icon: 'none'
  780. });
  781. }
  782. });
  783. } catch (error) {
  784. console.error('收获异常', error);
  785. uni.showToast({
  786. title: '网络异常,请重试',
  787. icon: 'none'
  788. });
  789. }
  790. },
  791. // 收获所有可收获的花
  792. async harvest() {
  793. const harvestFields = this.fields.filter(field => field.canHarvest);
  794. if (harvestFields.length === 0) {
  795. uni.showToast({
  796. title: '没有可收获的花',
  797. icon: 'none'
  798. });
  799. return;
  800. }
  801. try {
  802. for (const field of harvestFields) {
  803. await this.harvestField(field.id);
  804. }
  805. } catch (error) {
  806. console.error('批量收获异常', error);
  807. }
  808. },
  809. // 格式化时间显示
  810. formatTime(seconds) {
  811. const hours = Math.floor(seconds / 3600);
  812. const minutes = Math.floor((seconds % 3600) / 60);
  813. const secs = seconds % 60;
  814. // 获取当前时间,用于控制冒号闪烁
  815. const now = new Date();
  816. const blinkState = now.getSeconds() % 2 === 0;
  817. // 格式化为 "HH:MM" 格式
  818. return `${hours.toString().padStart(2, '0')}${blinkState ? ':' : ' '}${minutes.toString().padStart(2, '0')}`;
  819. },
  820. // 开始定时检查植物生长状态
  821. startGrowthCheck() {
  822. // 清除可能存在的旧定时器
  823. if (this.growthCheckTimer) {
  824. clearInterval(this.growthCheckTimer);
  825. }
  826. // 每分钟检查一次植物生长状态
  827. this.growthCheckTimer = setInterval(async () => {
  828. try {
  829. uni.request({
  830. url: this.$apiHost + '/Game/huatian/check_growth',
  831. method: 'POST',
  832. data: {
  833. uuid: getApp().globalData.uuid,
  834. },
  835. header: {
  836. 'Content-Type': 'application/x-www-form-urlencoded',
  837. 'sign': getApp().globalData.headerSign,
  838. uuid: getApp().globalData.uuid,
  839. },
  840. success: (res) => {
  841. if (res.data && res.data.code === 0) {
  842. const growthData = res.data.data || [];
  843. // 更新每块土地的状态
  844. growthData.forEach(item => {
  845. if (item.isReady) {
  846. // 找到对应的田地
  847. const field = this.fields.find(f => f.id ===
  848. item.landId);
  849. if (field) {
  850. // 更新为可收获状态
  851. field.isGrowing = false;
  852. field.seedStage = false;
  853. field.growthCompleted = true;
  854. field.flower = true;
  855. field.canHarvest = true;
  856. field.state = 99;
  857. // 清除定时器
  858. if (field.timer) {
  859. clearInterval(field.timer);
  860. field.timer = null;
  861. }
  862. }
  863. }
  864. });
  865. }
  866. },
  867. fail: (err) => {
  868. console.error('检查生长状态异常', err);
  869. }
  870. });
  871. } catch (error) {
  872. console.error('检查生长状态异常', error);
  873. }
  874. }, 60000); // 60秒检查一次
  875. },
  876. handleTaskDayClick() {
  877. this.taskDayActive = true;
  878. setTimeout(() => {
  879. this.taskDayActive = false;
  880. }, 200);
  881. // 如果mainLand存在,调用其onTaskClick方法
  882. if (this.mainLand) {
  883. // 关闭当前花田界面
  884. // this.onClose();
  885. // 打开任务对话框
  886. this.mainLand.onTaskClick();
  887. }
  888. },
  889. // 设置mainLand引用
  890. setMainLand(mainLand) {
  891. this.mainLand = mainLand;
  892. },
  893. },
  894. }
  895. </script>
  896. <style lang="scss">
  897. @import './HuaTian.scss';
  898. @keyframes weedBlink {
  899. 0% {
  900. opacity: 1;
  901. transform: scale(1);
  902. }
  903. 50% {
  904. opacity: 0.5;
  905. transform: scale(1.1);
  906. }
  907. 100% {
  908. opacity: 1;
  909. transform: scale(1);
  910. }
  911. }
  912. .weed-blink {
  913. animation: weedBlink 1s infinite;
  914. z-index: 10;
  915. }
  916. @keyframes harvestBlink {
  917. 0% {
  918. opacity: 1;
  919. transform: scale(1);
  920. }
  921. 50% {
  922. opacity: 0.5;
  923. transform: scale(1.1);
  924. }
  925. 100% {
  926. opacity: 1;
  927. transform: scale(1);
  928. }
  929. }
  930. .harvest-blink {
  931. animation: harvestBlink 1s infinite;
  932. z-index: 10;
  933. }
  934. .task-day-active {
  935. transform: scale(0.95);
  936. opacity: 0.8;
  937. transition: all 0.2s ease;
  938. }
  939. </style>