练习即生产,让正确的用法称为唯一的用法

/**
复制代码
* 菜单循环+方法化+输入校验+三档单价+输出明细(材料/人工/总价)。完成后关掉参考代码,从零再写一遍 * <p> * 注意: * 1、Quote 类(9 字段)+ static 编号自增 + 日期 * 2、printQuote(quote) 输出编号/日期/面积/档次/单价/材料/人工/总价 * 3、验收三关 + 连续出 3 单看编号递增 * 4、【从零重写】关参考、凭笔记默写、计时只记录 * <p> * class Quote { * int seq; // 对应未来主键 id(现为内存序号) * String quoteNo; // 报价单编号 BJ2026-0001(业务编号) * String createDate; // 对应 create_time * double area; // 对应 area * int level; // 对应 level * double unitPrice; * double materialCost; * double laborCost; * double totalPrice; // 对应 total_price * // userId 字段先空着——那是 W26 用户系统的事,TODO 标注 * } * static void printQuote(Quote q) { * String bill = """ * ============ 装修报价单 ============ * 报价编号:%s * 报价日期:%s * ------------------------------------ * 房屋面积:%.2f m² * 装修套餐:%s * 套餐单价:%,.2f 元/m² * ------------------------------------ * 材料费用:%,.2f 元 * 人工费用:%,.2f 元 * ==================================== * 总价:%,.2f 元 * ==================================== * """.formatted(q.quoteNo, q.createDate, q.area, * q.desc, q.unitPrice, q.materialCost, * q.laborCost, q.totalPrice); * System.out.print(bill); * } * */ import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Scanner; public class Day27QuoteTextBlock { private static final int MENU_NUMBER_ZERO = 0; private static final int MENU_NUMBER_ECONOMY = 1; // 菜单编号:1 private static final int MENU_NUMBER_COMFORT = 2; // 菜单编号:2 private static final int MENU_NUMBER_LUXURY = 3; // 菜单编号:3 private static final String LEVEL_ECONOMY_DESC = "经济套餐"; // 套餐描述 private static final String LEVEL_COMFORT_DESC = "舒适套餐"; // 套餐描述 private static final String LEVEL_LUXURY_DESC = "豪华套餐"; // 套餐描述 private static final double LEVEL_ECONOMY_UNIT_PRICE = 800; // 经济套餐单价:800 private static final double LEVEL_COMFORT_UNIT_PRICE = 1200; // 舒适套餐单价:1200 private static final double LEVEL_LUXURY_UNIT_PRICE = 1800; // 豪华套餐单价:1800 private static final String DOUBLE_REGEX = "^[0-9]+(\\.[0-9]+)?$"; // 面积输入的正则表达式 private static final String MENU_INT_REGEX = "^[0123]$"; // 装修档次菜单编号输入的正则表达式 private static final String PREFIX_ORDER_NO = "BJ2026"; // 订单编号的前缀 private static final String ORDER_NUMBER_FORMAT = "-%04d"; // 订单编号的格式 private static final DateTimeFormatter DATE_TIME_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); private static final double MATERIAL_RATIO = 0.6; // 设置材料费用在总价中的占比 private static int orderNumberCount = 0; // 订单号码自动编号计数器 private static int seq = 0; // 对应未来主键 id(现为内存序号) private static String quoteNo = ""; // 报价单编号 BJ2026-0001(业务编号) private static String createDate = ""; // 对应 create_time 报价单创建日期 private static double area = 0; // 对应 area 房屋面积 private static int level = 0; // 对应 level 装修档次 private static double unitPrice = 0; // 对应 unitPrice 装修单价 private static double materialCost = 0; // 对应 level 材料费用 private static double laborCost = 0; // 对应 level 人工费用 private static double otherCost = 0; // 对应 level 其他费用 private static double totalPrice = 0; // 对应 total_price 总金额 // private static final userId TODO:字段先空着——那是 W26 用户系统的事 private static final int RETURN_VALUE_INPUT_ZERO = 0; // 返回值为0,就是输入为0 private static final int RETURN_VALUE_INPUT_EXIT = -1; // 返回值为-1,就是要退出程序 private static final int RETURN_VALUE_INPUT_IS_BLANK = -2; // 返回值为-2,就是没有输入 private static final int RETURN_VALUE_INPUT_INVALID = -3; // 返回值为-3,就是输入无效 private static final int RETURN_VALUE_INPUT_INVALID_MENU_NUMBER = -3; // 返回值为-3,就是菜单编号输入无效 private static final String PRINT_TITEL = "----------------------------------装修报价单----------------------------------"; private static final String PRINT_LINE = "-----------------------------------------------------------------------------"; private static final String INPUT_AREA_TIP = "请输入房屋面积(m²),回车确定|exit退出:"; private static final String INPUT_MENU_TIP = "请选择装修套餐(1-经济|2-舒适|3-豪华):"; private static final String AREA_EXIT_TIP = "感谢使用,See you next time."; // 程序退出的提示 private static final String AREA_IS_BLANK_TIP = "没有输入,请重新输入面积(m²)!"; // 没有输入面积的提示 private static final String AREA_INVALID_TIP = "输入了无效的面积,请重新输入面积(m²)!"; // 面积输入无效的提示 private static final String AREA_ZERO_TIP = "面积要大于0,请重新输入面积(m²)!"; // 面积为0的提示 private static final String MENU_NUMBER_INVALID_TIP = "菜单编号输入无效,请输入装修套餐(1-经济|2-舒适|3-豪华)!"; // 装修档次菜单编号输入无效的提示 private static final String INPUT_MENU_ZERO_TIP = "返回上一层,请输入房屋面积(m²),回车确定|exit退出:"; ; // 从套餐输入返回到面积输入的提示 private static final String PRINT_BILL = """ ================================================= 装修报价单 ================================================= 报价编号:%s 报价日期:%s ------------------------------------------------------------------------------------------------------------ 房屋面积:%.2f m² 装修套餐:%s 套餐单价:%,.2f 元/m² ------------------------------------------------------------------------------------------------------------ 材料费用:%,.2f 元 人工费用:%,.2f 元 其他费用:%,.2f 元 ============================================================================================================ 总 价:%,.2f 元 ============================================================================================================ """; public static void main(String[] args) { Scanner in = new Scanner(System.in); while (true) { System.out.print(PRINT_TITEL + "\n"); System.out.print(INPUT_AREA_TIP); // 请输入面积,exit-退出 String line = in.nextLine().strip(); // 判断面积,合法的话(返回值为>0)就进行菜单展示和选择 double houseArea = getHouseArea(line); if (houseArea == RETURN_VALUE_INPUT_INVALID) { // 判断返回值,-3就提示“输入了无效的面积,请重新输入面积(m²)!” System.out.println(AREA_INVALID_TIP); continue; } if (houseArea == RETURN_VALUE_INPUT_IS_BLANK) { // 判断返回值,-2就提示“没有输入,请重新输入面积(m²)!” System.out.println(AREA_IS_BLANK_TIP); continue; } if (houseArea == RETURN_VALUE_INPUT_EXIT) { // 判断返回值,-1就退出 System.out.println(AREA_EXIT_TIP); break; } if (houseArea == RETURN_VALUE_INPUT_ZERO) { // 判断面积,输出面积为0(返回值为0)的提示“面积要大于0,请重新输入面积(m²)!” System.out.println(AREA_ZERO_TIP); continue; } // 菜单流程 int menuNum; while (true) { System.out.print("\n" + INPUT_MENU_TIP); String num = in.nextLine(); level = getMenuNumber(num); if (level >= MENU_NUMBER_ECONOMY && level <= MENU_NUMBER_LUXURY) { unitPrice = getUnitPrice(level); // 获取单价 break; } System.out.print(MENU_NUMBER_INVALID_TIP); } // 字段计算 quoteNo = getOrderNumber(); // 订单编号 createDate = LocalDateTime.now().format(DATE_TIME_FORMAT); String levelDesc = getLevelDesc(level); // 装修套餐(描述) area = houseArea; // 获取面积 totalPrice = calcTotalAmount(houseArea, unitPrice); // 总金额 materialCost = totalPrice * MATERIAL_RATIO; // 材料费用 laborCost = totalPrice - materialCost; // 报价单输出 String quoteText = String.format(PRINT_BILL, quoteNo, createDate, area, levelDesc, unitPrice, materialCost, laborCost, otherCost, totalPrice); System.out.println(quoteText); } } // TODO:获取面积的方法 public static double getHouseArea(String area) { double houseArea = RETURN_VALUE_INPUT_INVALID; if (area.strip().isBlank()) { houseArea = RETURN_VALUE_INPUT_IS_BLANK; // 面积的返回值设定为-2(无输入) } if ("EXIT".equalsIgnoreCase(area.strip())) { houseArea = RETURN_VALUE_INPUT_EXIT; } else { if (area.strip().matches(DOUBLE_REGEX)) { houseArea = Double.parseDouble(area); } } return houseArea; } /** * 获取装修档次装修套餐的菜单编号 * * @param selected * @return */ public static int getMenuNumber(String selected) { int menuNumber = RETURN_VALUE_INPUT_INVALID_MENU_NUMBER; if (selected.strip().isBlank()) { menuNumber = RETURN_VALUE_INPUT_IS_BLANK; } else { if (selected.strip().matches(MENU_INT_REGEX)) { // 正则判断selected的值为 0-3的数字,1-3为对应的套餐 int num = Integer.parseInt(selected); if (num > MENU_NUMBER_ZERO && num <= MENU_NUMBER_LUXURY) { menuNumber = switch (num) { case 1 -> MENU_NUMBER_ECONOMY; // 经济套餐的菜单编号 case 2 -> MENU_NUMBER_COMFORT; // 舒适套餐的菜单编号 case 3 -> MENU_NUMBER_LUXURY; // 豪华套餐的菜单编号 default -> RETURN_VALUE_INPUT_INVALID_MENU_NUMBER; }; } } } return menuNumber; } /** * 获取装修档次的描述 * @param num * @return */ public static String getLevelDesc(int num) { return switch (num) { case 1 -> LEVEL_ECONOMY_DESC; case 2 -> LEVEL_COMFORT_DESC; case 3 -> LEVEL_LUXURY_DESC; default -> ""; }; } /** * 获取装修档次对应的单价 * @param num * @return */ public static double getUnitPrice(int num) { return switch (num) { case 1 -> LEVEL_ECONOMY_UNIT_PRICE; // 经济套餐的菜单编号 case 2 -> LEVEL_COMFORT_UNIT_PRICE; // 舒适套餐的菜单编号 case 3 -> LEVEL_LUXURY_UNIT_PRICE; // 豪华套餐的菜单编号 default -> 0; }; } /** * 计算装修档次对应的总金额 * @param houseArea * @param unitPrice * @return */ public static double calcTotalAmount(double houseArea, double unitPrice) { return houseArea * unitPrice; } /** * 获取订单编号 * @return */ public static String getOrderNumber() { // 获取订单号码的编号,并产生订单号 // 订单编号:BJ2026-0001、BJ2026-0002 orderNumberCount++; String str = String.format(ORDER_NUMBER_FORMAT,orderNumberCount); return (PREFIX_ORDER_NO + str); } }
0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
鱼友0258
下载 APP