1/* 2 * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import router from '@ohos.router'; 17import call from '@ohos.telephony.call'; 18import BusinessController from '../../controller/BusinessController'; 19import CommodityController from '../../controller/CommodityController'; 20import Logger from '../../utils/Logger'; 21import Car from '../../data/Car' 22import { getStringData } from '../../utils/ResourceDataHandle'; 23import { CommentInfo, CommodityInfo } from '../../data/Server'; 24import { BusinessError } from '@ohos.base'; 25 26const TAG: string = '[Commodity]'; 27const CAR_NUM = 1; // 初始化数量 28const RESET = 0; // 重置 29@Extend(Row) function rowStyleShop() { 30 .width('95%') 31 .height(170) 32 .borderRadius(8) 33 .margin({ top: 12 }) 34 .padding(12) 35} 36 37@Entry 38@Component 39struct Commodity { 40 @State isShow: boolean = false; 41 @State isPanel: boolean = false; 42 @State isShop: boolean = true; 43 @State isLogin: boolean = false; 44 @State money: number = 0; 45 @State count: number = 0; 46 @State commodityList: Array<CommodityInfo> = []; // 商品列表 47 @State commentList: Array<CommentInfo> = []; // 评论列表 48 @State buyCarList: Array<Car> = []; // 购物车列表 49 @State businessId: string = (router.getParams() as Record<string, Object>).businessId as string; 50 @State businessName: string = (router.getParams() as Record<string, Object>).businessName as string; 51 @State businessScore: string = (router.getParams() as Record<string, Object>).businessScore as string; 52 @State businessSale: string = (router.getParams() as Record<string, Object>).businessSale as string; 53 @State businessTime: string = (router.getParams() as Record<string, Object>).businessTime as string; 54 @State businessRank: string = (router.getParams() as Record<string, Object>).businessRank as string; 55 private commodityController: CommodityController = new CommodityController(); 56 private businessController: BusinessController = new BusinessController(); 57 58 callUp(phoneNumber: string): void { 59 let isSupport = call.hasVoiceCapability(); 60 Logger.info(TAG, `callUp isSupport = ${isSupport}`); 61 call.makeCall(phoneNumber, err => { 62 if (!err) { 63 Logger.info(TAG, 'callUp make call success'); 64 } else { 65 Logger.info(TAG, `callUp make call fail, err is: = ${JSON.stringify(err)}`); 66 } 67 }) 68 } 69 70 addCar(name: string, price: number): void { 71 let cars: Car = new Car(); 72 cars.name = name; 73 cars.price = Number(price); 74 cars.num = CAR_NUM; 75 this.buyCarList.push(cars); 76 } 77 78 aboutToAppear() { 79 Logger.info(TAG, 'Commodity aboutToAppear'); 80 // 商品列表 81 this.commodityController.getCommodityList(this.businessId).then((res: CommodityInfo[]) => { 82 this.commodityList = res; 83 Logger.info(TAG, `commodityList then res= ${JSON.stringify(this.commodityList)}`); 84 }).catch((err: BusinessError) => { 85 Logger.info(TAG, `commodityList catch err= ${JSON.stringify(err)}`); 86 }) 87 // 商家评论列表 88 this.businessController.getCommentList(this.businessId).then((res: CommentInfo[]) => { 89 this.commentList = res; 90 Logger.info(TAG, `commentList then res= ${JSON.stringify(this.commentList)}`); 91 }).catch((err: BusinessError) => { 92 Logger.info(TAG, `commentList catch err= ${JSON.stringify(err)}`); 93 }) 94 } 95 96 build() { 97 Stack() { 98 Column() { 99 Row() { 100 Image($r('app.media.icon')) 101 .width(24) 102 .height(24) 103 .onClick(() => { 104 router.back(); 105 }) 106 Blank() 107 Image($r('app.media.icon')) 108 .width(24) 109 .height(24) 110 .onClick(() => { 111 this.isShow = !this.isShow; 112 }) 113 } 114 .width('90%') 115 .height('8%') 116 117 Row() { 118 Column() { 119 Row() { 120 Text(this.businessName) 121 .fontSize(24) 122 .fontWeight(5) 123 } 124 .width('100%') 125 126 Row() { 127 Text(this.businessScore + getStringData($r('app.string.business_score'))) 128 .fontColor($r('app.color.business_score')) 129 .fontSize(20) 130 .fontWeight(5) 131 Row() { 132 Text($r('app.string.business_delivery')) 133 .fontColor($r('app.color.business_delivery')) 134 .fontSize(12) 135 .fontWeight(5) 136 .margin({ left: 6, right: 6 }) 137 } 138 .margin({ left: 6 }) 139 .borderWidth(2) 140 .border({ color: $r('app.color.comm_border') }) 141 142 Text(getStringData($r('app.string.business_distribution')) + this.businessTime + getStringData($r('app.string.business_min'))) 143 .fontSize(12) 144 .fontWeight(5) 145 .margin({ left: 12 }) 146 Text(getStringData($r('app.string.commodity_month')) + this.businessSale) 147 .fontSize(12) 148 .fontWeight(5) 149 .margin({ left: 6 }) 150 } 151 .width('100%') 152 .margin({ top: 4 }) 153 154 Row() { 155 Row() { 156 Text(this.businessRank) 157 .fontSize(12) 158 .fontWeight(5) 159 }.backgroundColor($r('app.color.index_bg')) 160 161 Blank() 162 } 163 .width('100%') 164 .margin({ top: 12 }) 165 166 Row() { 167 Text($r('app.string.business_reduce')) 168 .fontColor(Color.Red) 169 .fontSize(12) 170 .fontWeight(5) 171 .borderWidth(2) 172 .border({ color: Color.Red }) 173 } 174 .width('100%') 175 .margin({ top: 12 }) 176 } 177 .justifyContent(FlexAlign.Start) 178 .height('90%') 179 .width('90%') 180 .margin({ left: 12, right: 12 }) 181 } 182 .height('17%') 183 .margin({ top: 12 }) 184 185 Row() { 186 Tabs({ barPosition: BarPosition.Start }) { 187 // 点菜 188 TabContent() { 189 Scroll() { 190 Column() { 191 ForEach(this.commodityList, (commodity: CommodityInfo, index) => { 192 Row() { 193 Image($r('app.media.icon')) 194 .width(150) 195 .height(150) 196 Column() { 197 Row() { 198 Text(commodity.name) 199 .fontSize(20) 200 .fontWeight(5) 201 } 202 .width('100%') 203 204 Row() { 205 Button(commodity.standards + getStringData($r('app.string.commodity_right'))) 206 .fontColor($r('app.color.pd_standard')) 207 .backgroundColor($r('app.color.pd_standard_bg')) 208 .margin({ top: 6, bottom: 6 }) 209 Blank() 210 } 211 .width('100%') 212 .margin({ top: 4 }) 213 214 Row() { 215 Text(getStringData($r('app.string.commodity_month')) + commodity.salesNumber) 216 .fontColor($r('app.color.pd_font_gray')) 217 Text(getStringData($r('app.string.commodity_good'))) 218 .fontColor($r('app.color.pd_font_gray')) 219 .margin({ left: 12 }) 220 Blank() 221 } 222 .width('100%') 223 .margin({ top: 4 }) 224 225 Row() { 226 Text(getStringData($r('app.string.commodity_money')) + commodity.price) 227 .fontSize(20) 228 Blank() 229 Text($r('app.string.commodity_plus')) 230 .textAlign(TextAlign.Center) 231 .width(28) 232 .height(28) 233 .fontColor(Color.Black) 234 .fontSize(20) 235 .fontWeight(15) 236 .borderRadius(24) 237 .backgroundColor($r('app.color.comm_plus')) 238 .onClick(() => { 239 this.money = this.money + Number(commodity.price); 240 this.count++; 241 if (this.buyCarList.length <= this.commentList.length && this.count === 1) { 242 this.addCar(commodity.name, Number(commodity.price)); 243 } else { 244 for (let index = 0; index < this.buyCarList.length; index++) { 245 const element = this.buyCarList[index]['name']; 246 if (element === commodity.name) { 247 // 更新数据 248 Logger.info(TAG, 'cars this.commentList.length==' + JSON.stringify(this.buyCarList[index]['num'])); 249 let carsL: Car = new Car(); 250 carsL.num = this.buyCarList[index]['num'] + 1; 251 Logger.info(TAG, 'cars carsL.num==' + JSON.stringify(carsL.num)); 252 carsL.name = commodity.name; 253 carsL.price = Number(commodity.price); 254 this.buyCarList[index] = carsL; 255 break; 256 } else { 257 if (index == this.buyCarList.length - 1) { 258 this.addCar(commodity.name, Number(commodity.price)); 259 break; 260 } else { 261 continue; 262 } 263 } 264 } 265 } 266 Logger.info(TAG, 'this.buyCarList==' + JSON.stringify(this.buyCarList)) 267 }) 268 .id('commodity' + index) 269 } 270 .width('90%') 271 .width('100%') 272 .margin({ top: 4 }) 273 } 274 .justifyContent(FlexAlign.Start) 275 .height('100%') 276 .width('58%') 277 .margin({ left: 12 }) 278 } 279 .rowStyleShop() 280 .id('commentList' + index) 281 .onClick(() => { 282 router.push({ 283 url: 'pages/takeaway/ProductDetails', 284 params: { 285 commodityId: commodity.id 286 } 287 }); 288 }) 289 }, (commodity: CommodityInfo) => JSON.stringify(commodity)) 290 } 291 .margin({ bottom: 55 }) 292 } 293 .width('90%') 294 .height('95%') 295 } 296 .tabBar($r('app.string.commodity_tabs_order')) 297 .id('order') 298 // 评价 299 TabContent() { 300 Column() { 301 Row() { 302 Text($r('app.string.commodity_all_in')) 303 .padding({ left: 12, right: 12, top: 6, bottom: 6 }) 304 .backgroundColor($r('app.color.pd_standard')) 305 .height(38) 306 .borderRadius(8) 307 308 Text($r('app.string.commodity_best_new')) 309 .padding({ left: 12, right: 12, top: 6, bottom: 6 }) 310 .backgroundColor($r('app.color.comm_good')) 311 .height(38) 312 .borderRadius(8) 313 .margin({ left: 12 }) 314 315 Text($r('app.string.commodity_good_reviews')) 316 .padding({ left: 12, right: 12, top: 6, bottom: 6 }) 317 .backgroundColor($r('app.color.comm_good')) 318 .height(38) 319 .borderRadius(8) 320 .margin({ left: 12 }) 321 322 Text($r('app.string.commodity_bad_reviews')) 323 .fontSize(16) 324 .padding({ left: 12, right: 12, top: 6, bottom: 6 }) 325 .backgroundColor($r('app.color.comm_bad')) 326 .height(38) 327 .borderRadius(8) 328 .margin({ left: 12 }) 329 330 Text($r('app.string.commodity_video')) 331 .padding({ left: 12, right: 12, top: 6, bottom: 6 }) 332 .backgroundColor($r('app.color.comm_video')) 333 .height(38) 334 .borderRadius(8) 335 .margin({ left: 12 }) 336 } 337 338 Scroll() { 339 Column() { 340 ForEach(this.commentList, (comment: CommentInfo) => { 341 Column() { 342 Row() { 343 Image($r('app.media.icon')) 344 .width(70) 345 .height(70) 346 Column() { 347 Row() { 348 Text(comment.userName) 349 .fontSize(18) 350 351 Text($r('app.string.commodity_vip')) 352 .margin({ left: 12 }) 353 .padding(4) 354 .borderRadius(8) 355 .textAlign(TextAlign.Center) 356 .fontColor($r('app.color.comm_vip')) 357 .backgroundColor($r('app.color.comm_vip_bg')) 358 } 359 .justifyContent(FlexAlign.Start) 360 .width('100%') 361 362 Text(comment.createTime) 363 .width('100%') 364 .textAlign(TextAlign.Start) 365 .fontColor($r('app.color.pd_font_gray')) 366 .margin({ top: 6 }) 367 } 368 .width('100%') 369 .margin({ left: 12 }) 370 371 Blank() 372 } 373 .margin({ top: 24 }) 374 .width('90%') 375 376 Column() { 377 Text(comment.content) 378 .width('100%') 379 .textAlign(TextAlign.Start) 380 .maxLines(3) 381 Row() { 382 Image($r('app.media.icon')) 383 .margin({ top: 12 }) 384 .width(200) 385 .height(200) 386 } 387 .justifyContent(FlexAlign.Start) 388 .width('100%') 389 } 390 .margin({ top: 24 }) 391 .width('90%') 392 } 393 .width('100%') 394 }) 395 } 396 .margin({ bottom: 55 }) 397 } 398 .width('90%') 399 .height('95%') 400 } 401 } 402 .tabBar($r('app.string.pd_tabs_appraise')) 403 .id('appraise') 404 } 405 .onChange((index: number) => { 406 if (index === 0) { 407 this.isShop = true; 408 } else { 409 this.isShop = false; 410 } 411 }) 412 } 413 .width('100%') 414 .height('70%') 415 } 416 .width('100%') 417 .height('100%') 418 419 // 去结 420 Column() { 421 Column() { 422 if (this.isShop) { 423 Row() { 424 Text($r('app.string.commodity_des')) 425 } 426 .padding({ top: 6, bottom: 6 }) 427 .height('4%') 428 429 Row() { 430 Row() { 431 Image($r('app.media.icon')) 432 .width(38) 433 .height(38) 434 Text(getStringData($r('app.string.commodity_money')) + this.money) 435 .fontSize(24) 436 .fontColor(Color.White) 437 .fontWeight(5) 438 .margin({ left: 12 }) 439 Divider() 440 .height(24) 441 .vertical(true) 442 .color($r('app.color.comm_fee')) 443 .margin({ left: 6 }) 444 Text($r('app.string.commodity_fee')) 445 .fontColor($r('app.color.comm_fee')) 446 .margin({ left: 6 }) 447 } 448 .width('75%') 449 .borderRadius({ topLeft: 24, bottomLeft: 24 }) 450 .padding({ left: 24 }) 451 .onClick(() => { 452 this.isPanel = !this.isPanel; 453 Logger.info(TAG, 'isPanel make call success ' + this.isPanel) 454 }) 455 .id('panel') 456 457 Row() { 458 if (this.money !== 0) { 459 Text($r('app.string.commodity_to_pay')) 460 .fontSize(20) 461 .fontColor($r('app.color.comm_fee')) 462 .onClick(() => { 463 this.callUp(getStringData($r('app.string.commodity_tell'))) 464 }) 465 .id('pay') 466 } else { 467 Text($r('app.string.commodity_to_give')) 468 .fontColor($r('app.color.comm_fee')) 469 } 470 } 471 .padding({ left: 24 }) 472 .height('100%') 473 .width('25%') 474 .backgroundColor(this.money == 0 ? $r('app.color.comm_car') : $r('app.color.comm_plus')) 475 .borderRadius({ topRight: 24, bottomRight: 24 }) 476 } 477 .borderRadius(24) 478 .backgroundColor($r('app.color.comm_car')) 479 .width('100%') 480 .height('8%') 481 } 482 } 483 .borderRadius(8) 484 .width('90%') 485 .backgroundColor($r('app.color.comm_to_pay')) 486 } 487 .justifyContent(FlexAlign.Center) 488 .position({ y: '88%' }) 489 .width('100%') 490 .zIndex(3) 491 492 // 购物车 493 Panel(this.isPanel) { // 展示购物车 494 Column() { 495 Text($r('app.string.commodity_reduce_money')) 496 .fontSize(18) 497 .margin({ top: 12, bottom: 12 }) 498 .width('100%') 499 .backgroundColor($r('app.color.pd_standard_bg')) 500 .textAlign(TextAlign.Center) 501 Row() { 502 Blank() 503 Image($r('app.media.icon')) 504 .width(18) 505 .height(18) 506 Text($r('app.string.commodity_clear_car')) 507 .fontColor($r('app.color.pd_font_gray')) 508 .margin({ left: 12 }) 509 } 510 .width('90%') 511 .margin({ left: 12 }) 512 .padding({ right: 24, left: 24, top: 12, bottom: 12 }) 513 .onClick(() => { 514 this.buyCarList = []; 515 this.isPanel = false; 516 this.money = RESET; // 重置金额 517 this.count = RESET; 518 }) 519 520 Divider() 521 .width('90%') 522 523 Scroll() { 524 Column() { 525 ForEach(this.buyCarList, (buyCar: Car, index) => { 526 Row() { 527 Image($r('app.media.icon')) 528 .width(100) 529 .height(100) 530 Column() { 531 Row() { 532 Text(buyCar.name) 533 .fontWeight(10) 534 .fontSize(24) 535 } 536 .width('100%') 537 538 Row() { 539 Text($r('app.string.commodity_one')) 540 .fontColor($r('app.color.pd_font_gray')) 541 } 542 .width('100%') 543 544 Row() { 545 Text(getStringData($r('app.string.commodity_money')) + buyCar.price) 546 .fontWeight(10) 547 .fontColor($r('app.color.pd_money')) 548 .fontSize(24) 549 Blank() 550 Text($r('app.string.commodity_reduce')) 551 .fontSize(18) 552 .borderRadius(24) 553 .borderWidth(2) 554 .border({ color: $r('app.color.comm_plus') }) 555 .width(28) 556 .height(28) 557 .backgroundColor(Color.White) 558 .textAlign(TextAlign.Center) 559 .onClick(() => { 560 this.money = this.money - Number(buyCar.price); 561 let carsL: Car = new Car(); 562 carsL.num = this.buyCarList[index]['num'] - 1; 563 carsL.name = buyCar.name; 564 carsL.price = Number(buyCar.price); 565 this.buyCarList[index] = carsL; 566 if (buyCar.num === 1) { 567 this.buyCarList.splice(index, 1); 568 } 569 if (this.buyCarList.length === 0) { 570 this.isPanel = false; 571 this.count = RESET; 572 } 573 }) 574 Text(String(buyCar.num)) 575 .margin({ left: 12 }) 576 Text($r('app.string.commodity_plus')) 577 .borderRadius(24) 578 .fontSize(18) 579 .width(28) 580 .height(28) 581 .backgroundColor($r('app.color.comm_plus')) 582 .textAlign(TextAlign.Center) 583 .margin({ left: 12 }) 584 .onClick(() => { 585 this.money = this.money + Number(buyCar.price); 586 let carsL: Car = new Car(); 587 carsL.num = this.buyCarList[index]['num'] + 1; 588 carsL.name = buyCar.name; 589 carsL.price = Number(buyCar.price); 590 this.buyCarList[index] = carsL; 591 }) 592 } 593 .margin({ top: 12 }) 594 .width('100%') 595 } 596 .width('70%') 597 .margin({ left: 12 }) 598 } 599 .width('100%') 600 .padding({ top: 12, bottom: 12 }) 601 }) 602 } 603 .margin({ bottom: 200 }) 604 } 605 .height('100%') 606 .width('90%') 607 } 608 } 609 .type(PanelType.Foldable) 610 .dragBar(false) 611 .halfHeight(500) 612 .width('100%') 613 .mode(PanelMode.Half) 614 .zIndex(2) 615 616 if (this.isShow) { 617 Stack() { 618 Column() { 619 Row() { 620 Image($r('app.media.icon')) 621 .width(24) 622 .height(24) 623 Text($r('app.string.commodity_car')) 624 .margin({ left: 12 }) 625 } 626 .width('100%') 627 .height('33%') 628 .padding(12) 629 630 Row() { 631 Image($r('app.media.icon')) 632 .width(24) 633 .height(24) 634 Text($r('app.string.commodity_share')) 635 .margin({ left: 12 }) 636 } 637 .onClick(() => { 638 Logger.info(TAG, 'onClick onClick '); 639 this.callUp(getStringData($r('app.string.commodity_tell'))); 640 }) 641 .width('100%') 642 .height('33%') 643 .padding(12) 644 645 Row() { 646 Image($r('app.media.icon')) 647 .width(24) 648 .height(24) 649 Text($r('app.string.commodity_call')) 650 .margin({ left: 12 }) 651 } 652 .onClick(() => { 653 Logger.info(TAG, 'onClick onClick '); 654 this.callUp(getStringData($r('app.string.commodity_tell'))); 655 }) 656 .width('100%') 657 .height('33%') 658 .padding(12) 659 } 660 .borderRadius(8) 661 .opacity(1) 662 .backgroundColor($r('app.color.comm_bg')) 663 .height('20%') 664 .width('32%') 665 } 666 .position({ x: '65%', y: '6%' }) 667 } 668 } 669 .onClick(() => { 670 this.isShow = false; 671 }) 672 .width('100%') 673 .height('100%') 674 } 675} 676