diff --git a/package.json b/package.json index 207a0ff..bc2b6c8 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "typescript": "^5.6.3" }, "devDependencies": { + "decimal.js": "^10.4.3", "react-router-dom": "^6.28.0", "tailwindcss": "^3.4.15" }, diff --git a/src/FoodOrderer.tsx b/src/FoodOrderer.tsx index 370259d..9886b76 100644 --- a/src/FoodOrderer.tsx +++ b/src/FoodOrderer.tsx @@ -1,72 +1,100 @@ import React, { useState } from "react"; +import Decimal from 'decimal.js'; interface ShopItem { name: string, - need: number, // 需求数量 - provide: number, // 提供的数量 + need: number, // 需求数量 + provider: { + name: string + price: number + storage: number // 库存 + }, // 提供者的信息 image: { src: string } } + +const getNeedPrice = (item: ShopItem) => { + let result = new Decimal(item.provider.price).times(item.need) + return result.toNumber() +} + const shopItems: ShopItem[] = [ { name: "Apple", - need: 10, - provide: 5, + need: 999, + provider: { + name: "Fresh Farms", + price: 2.5, + storage: 1000, + }, image: { - src: "https://i.imgur.com/FsNUv2x.jpeg" - } + src: "https://i.imgur.com/FsNUv2x.jpeg", + }, }, { name: "Orange Jam", need: 8, - provide: 10, + provider: { + name: "Sweet Treats Co.", + price: 4.0, + storage: 50, + }, image: { - src: "https://i.imgur.com/hB46Z9s.png" - } + src: "https://i.imgur.com/hB46Z9s.png", + }, }, { name: "Milk (Gone bad)", need: 0, - provide: 3, + provider: { + name: "Dairy Delights", + price: 1.2, + storage: 20, + }, image: { - src: "https://i.imgur.com/ZV7vzDu.png" - } + src: "https://i.imgur.com/ZV7vzDu.png", + }, }, { name: "Bread", need: 12, - provide: 6, + provider: { + name: "Baker's Best", + price: 3.0, + storage: 30, + }, image: { - src: "https://i.imgur.com/qBn8jWS.jpeg" - } - } + src: "https://i.imgur.com/qBn8jWS.jpeg", + }, + }, ]; + function FoodList({ list, setList }: { list: ShopItem[], setList: React.Dispatch> }) { - enum ButtonOperation {INCREASE , DECREASE} - const handleVolumeButton = (item: ShopItem ,operation: ButtonOperation) => { + enum ButtonOperation { INCREASE, DECREASE } + const handleVolumeButton = (item: ShopItem, operation: ButtonOperation) => { const nowNeed = item.need switch (operation) { case ButtonOperation.INCREASE: - if (nowNeed >= item.provide){ + if (nowNeed >= item.provider.storage) { return } - setList(list.map((it)=> - it == item? {...it,need: nowNeed+1}:it + setList(list.map((it) => + it == item ? { ...it, need: nowNeed + 1 } : it )) break case ButtonOperation.DECREASE: - if (nowNeed <= 0){ + if (nowNeed <= 0) { return } - setList(list.map((it)=> - it == item? {...it,need: nowNeed-1}:it + setList(list.map((it) => + it == item ? { ...it, need: nowNeed - 1 } : it )) break } @@ -76,21 +104,51 @@ function FoodList({ list, setList }: { return (
{list.map((item) => -
+
-
+

{item.name}

-
- -

{item.need}

- +

{item.provider.name}

+

{item.provider.price} 元/个

+

库存: {item.provider.storage}

+ +
+ +
+

{getNeedPrice(item)} 元

+
+ + { + const value = parseInt(e.target.value, 10) || 0; + if (value <= item.provider.storage && value >= 0) { + setList(list.map((it) => + it == item ? { ...it, need: value } : it + )) + } + }} + className="text-center w-16 h-8 bg-gray-50 rounded-md border border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-400 focus:border-blue-400 text-base appearance-none pl-1.5" + /> +
+ )}
) @@ -100,8 +158,10 @@ function FoodList({ list, setList }: { const FoodOrderer = () => { const [items, setItems] = useState(shopItems) return ( -
-

点些什么

+
+

+ 点些什么 +

) diff --git a/yarn.lock b/yarn.lock index f0d7a7a..cc5c3dc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3616,7 +3616,7 @@ debug@^3.2.7: dependencies: ms "^2.1.1" -decimal.js@^10.2.1: +decimal.js@^10.2.1, decimal.js@^10.4.3: version "10.4.3" resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==