获取订单的product_id 和订单的数量

本文介绍了一种使用PHP遍历订单组并获取产品ID及其对应数量的方法,并通过jQuery实现了客户端的产品信息抓取。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

php 获取订单的product_id 和相对id的数量

 

 <?php foreach ($val->groupResults(2) as $key2=>$val2):?>
     <tr class="eveData" shoppingCartId="<?=$val2->id?>" productId="<?=$val2->product()->id?>" freightId="<?=$val2->product()->freight_id?>">
       <td width="10%"><a href="<?=$val2->product()->strUrl()?>" target="_blank"><img src="<?=$val2->strPic()?>" class="img75" /></a></td>
       <td width="33%">
          <a href="<?=$val2->product()->strUrl()?>" target="_blank"><?=$val2->product()->title?></a><br/>
          <?php if($val2->shop()->isVip()):?>
         <a href="javascript:void(0)" title="VIP商家" class="shop_ico_vip"></a>
         <?php endif;?>
         <?php if($val2->product()->is_24h>0):?>
                <a href="javascript:void(0)" title="<?=$val2->product()->is_24h?>小时内发货" class="shop_ico_24h"></a>
         <?php endif;?>
         <?php if($val2->product()->is_aftermarket>0):?>
                <a href="javascript:void(0)" title="售后保障" class="shop_ico_baozhang"></a>
         <?php endif;?>
         <?php if($val2->product()->is_7goodsreturn>0):?>
                <a href="javascript:void(0)" title="<?=$val2->product()->is_7goodsreturn?>+天包退" class="shop_ico_7"></a>
         <?php endif;?>
         <?php if($val2->product()->is_15renew>0):?>
                <a href="javascript:void(0)" title="<?=$val2->product()->is_15renew?>+天换新" class="shop_ico_15"></a>
         <?php endif;?>
         <?php if($val2->product()->is_wholesale>0):?>
                <a href="javascript:void(0)" title="批发" class="shop_ico_pifa"></a>
         <?php endif;?>
       </td>
       <td width="13%">
          <i class="i_gray">型号:</i><?=$val2->attriModel()->title?><br/>
          <i class="i_gray">分类:</i><?=$val2->attriCategory()->title?>
       </td>
       <td><b class="eveUnitPrice"><?=$val2->product()->price?>a<?=$val2->product()->id?></b></td>
       <td>
          <input type="text" class="num eveNum" shoppingCartId="<?=$val2->id?>" value="<?=$val2->number?>" /><br/>
          <i class="i_gray">库存:</i><?=$val2->product()->inventorySurplus()?>
       </td>
       <td><i class="i_16red evePrice"><?=$val2->priceSum()?></i></td>
       <?php if($key2==0):?>
       <td rowspan="3">
          方式:
          <select name="logistics_type" onchange="freightPrice()">
              <option value="1">自取</option>
              <option value="2">配送</option>
          </select>
          <br/>
          费用:<span class="eveLogisticsPrice">0.00</span>
       </td>
       <?php endif;?>
     </tr>

 

jquery获取的方法

/*获取产品的id和产品的数量*/
            var data=[];
            $('.eveData').each(function(k,v){
                var tmp = {
                    'prodcut_id':$(this).attr('productId'),
                    'count':$(this).find('.eveNum').val(),
                };
                data.push(tmp);
            });
            param.product = data;

 

import pandas as pd import numpy as np from datetime import datetime, timedelta, time import os 基础参数(文档约束) CHANGE_TIME = 3.5 # 换模时间(小时) REST_PERIODS = [ # 每日休息时段(小时) (12, 12.5), # 12:00-12:30 (16.5, 17), # 16:30-17:00 (0, 1) # 0:00-1:00 ] class Order: “”“订单类:封装订单属性与计算逻辑”“” def init(self, order_id, product_id, quantity, delivery_date, capacity, attr): self.order_id = order_id # 订单号 self.product_id = product_id # 产品号 self.quantity = quantity # 数量(pcs) self.delivery_date = delivery_date # 发货日期(datetime) self.capacity = capacity # 产能(pcs/h) self.processing_hours = quantity / capacity # 生产工时(h) self.start_time = None # 开始时间 self.end_time = None # 结束时间 self.machine = None # 分配机台 self.delay_days = 0 # 延期天数 self.satisfaction = 10.0 # 满意度(初始10分) self.attr = attr # 产品属性(1:易搭配,3:难生产) self.merged_orders = [order_id] # 合单包含的原始订单ID(合单专用") class MergedOrder: “”“合单任务类:封装合并后的生产任务”“” def init(self, product_id, total_quantity, delivery_dates, capacity, attr, original_orders): self.product_id = product_id # 产品号 self.total_quantity = total_quantity # 合并后总数量 self.delivery_dates = delivery_dates # 原始订单发货日期列表 self.capacity = capacity # 产能 self.processing_hours = total_quantity / capacity # 总生产工时 self.attr = attr # 产品属性 self.original_orders = original_orders # 原始订单对象列表 self.start_time = None # 开始时间 self.end_time = None # 结束时间 self.machine = None # 分配机台 class Machine: “”“机台类:封装机台属性与状态”“” def init(self, machine_id, initial_time=None): self.machine_id = machine_id # 机台号 # 设置初始可用时间 if initial_time is None: self.available_time = datetime(2025, 3, 1) else: self.available_time = initial_time self.last_product = None # 上一生产产品 self.adjacent = [] # 相邻机台列表 self.schedule = [] # 排程计划(任务列表) def load_official_data(): “”“加载正式数据(使用相对路径)”“” try: # 1. 读取附件1(1)数据 attachment1 = pd.ExcelFile(r"C:\Users\彭婉\Desktop\2025-08\附件1(1).xlsx") # 1.1 订单表 orders_df = attachment1.parse( sheet_name=“订单表”, parse_dates=[“发货日期(DeliveryDate)”] ) # 1.2 机台初始工作状态表 machine_initial_df = attachment1.parse( sheet_name=“机台初始工作状态表”, parse_dates=[“生产开始时间”] ) machine_initial_times = { row[“机台号”]: row[“生产开始时间”] for _, row in machine_initial_df.iterrows() } # 1.3 放假日期表 holidays_df = attachment1.parse(sheet_name=“放假日期表”) holidays = # 2. 读取附件2(1)数据 attachment2 = pd.ExcelFile(r"C:\Users\彭婉\Desktop\2025-08\附件2(1).xlsx") # 2.1 产品工时计算参数表 product_capacity_df = attachment2.parse(sheet_name="产品工时计算参数表") product_capacity = { row["产品号"]: row["Capacity(pcs/h)"] for _, row in product_capacity_df.iterrows() } # 2.2 产品机台生产关系表 product_machine_df = attachment2.parse(sheet_name="产品机台生产关系表") product_machines = {} for _, row in product_machine_df.iterrows(): product_id = row["产品号"] # 找出值为1的机台列 valid_machines = [col for col in product_machine_df.columns if col != "产品号" and row[col] == 1] product_machines[product_id] = valid_machines # 2.3 机台关系表 machine_relation_df = attachment2.parse(sheet_name="机台关系表") machine_adjacent = {} for _, row in machine_relation_df.iterrows(): machine_id = row["机台号"] # 找出值为1的相邻机台列 adjacent_machines = [col for col in machine_relation_df.columns if col != "机台号" and row[col] == 1] machine_adjacent[machine_id] = adjacent_machines # 2.4 产品属性表 product_attr_df = attachment2.parse(sheet_name="产品属性表") product_attrs = { row["产品号"]: row["属性"] for _, row in product_attr_df.iterrows() } # 3. 初始化订单数据(补充产能列) orders_df["Capacity(pcs/h)"] = orders_df["产品号"].map(product_capacity) # 4. 初始化机台对象 machines = [] for mid in machine_initial_times.keys(): # 确保每个机台都有初始时间 initial_time = machine_initial_times.get(mid, datetime(2025, 3, 1)) machine = Machine(mid, initial_time) # 设置相邻机台关系 machine.adjacent = machine_adjacent.get(mid, []) machines.append(machine) return orders_df, product_machines, product_attrs, machines, holidays except Exception as e: print(f"加载数据错误: {e}") # 返回空数据集避免崩溃 return pd.DataFrame(), {}, {}, [], set() def merge_orders(orders, merge_days): “”“合单逻辑:相同产品号的订单,发货日期在merge_days内的合并为一个生产任务”“” merged_tasks = [] merge_count = 0 # 合单次数(合并的组数) # 按产品号分组 product_groups = {} for order in orders: if order.product_id not in product_groups: product_groups[order.product_id] = [] product_groups[order.product_id].append(order) # 对每个产品组内的订单按发货日期排序并合单 for product_id, group_orders in product_groups.items(): # 按发货日期升序排序 group_orders.sort(key=lambda x: x.delivery_date) if len(group_orders) == 1: # 单个订单无需合单,直接作为一个任务 merged_tasks.append(MergedOrder( product_id=product_id, total_quantity=group_orders[0].quantity, delivery_dates=[group_orders[0].delivery_date], capacity=group_orders[0].capacity, attr=group_orders[0].attr, original_orders=[group_orders[0]] )) continue # 合并逻辑:滑动窗口检查发货日期差 current_merge = [group_orders[0]] for i in range(1, len(group_orders)): # 计算当前订单与组内第一个订单的发货日期差 date_diff = (group_orders[i].delivery_date - current_merge[0].delivery_date).days if date_diff <= merge_days: current_merge.append(group_orders[i]) else: # 超过合单窗口,生成合并任务 merged_tasks.append(MergedOrder( product_id=product_id, total_quantity=sum(o.quantity for o in current_merge), delivery_dates=[o.delivery_date for o in current_merge], capacity=current_merge[0].capacity, attr=current_merge[0].attr, original_orders=current_merge )) merge_count += 1 # 记录一次合单 current_merge = [group_orders[i]] # 处理最后一组合单 if len(current_merge) >= 1: merged_tasks.append(MergedOrder( product_id=product_id, total_quantity=sum(o.quantity for o in current_merge), delivery_dates=[o.delivery_date for o in current_merge], capacity=current_merge[0].capacity, attr=current_merge[0].attr, original_orders=current_merge )) if len(current_merge) > 1: merge_count += 1 # 仅多订单合并才计数 return merged_tasks, merge_count def calculate_end_time(start_time, processing_hours, holidays): “”“计算考虑休息放假后的生产结束时间”“” current = start_time remaining = processing_hours while remaining > 0: # 跳过放假日期 if current.date() in holidays: # 直接跳到第二天0点 current = datetime.combine(current.date() + timedelta(days=1), time(0, 0)) continue # 计算当前时间点 current_time = current.time() current_date = current.date() day_start = datetime.combine(current_date, time(0, 0)) # 计算剩余工作时间 work_hours_today = 24.0 for rest_start, rest_end in REST_PERIODS: work_hours_today -= (rest_end - rest_start) # 如果剩余工时小于一天工作量 if remaining <= work_hours_today: # 按小时累加,跳过休息时间 for hour in np.arange(0, 24, 0.1): # 检查是否在休息时间 in_rest = False for rest_start, rest_end in REST_PERIODS: if rest_start <= hour < rest_end: in_rest = True break if not in_rest: current += timedelta(hours=0.1) remaining -= 0.1 if remaining <= 0: return current else: # 直接消耗全天工作时间 remaining -= work_hours_today # 跳到第二天0点 current = datetime.combine(current_date + timedelta(days=1), time(0, 0)) return current def problem3_scheduling(merged_tasks, product_machines, product_attrs, machines, holidays): “”“问题三排程:考虑产品属性、机台关系及合单”“” # 排序:优先易搭配>难生产>无限制,同属性按最早发货日期排序 merged_tasks.sort(key=lambda x: ( x.attr, # 1:易搭配优先,3:难生产其次,2:无限制最后 min(x.delivery_dates) # 按最早发货日期排序 )) # 机台映射表(便于查询相邻机台) machine_map = {m.machine_id: m for m in machines} for task in merged_tasks: # 筛选可生产该产品的机台 candidate_machines = [ m for m in machines if m.machine_id in product_machines.get(task.product_id, []) ] # 易搭配产品优先分配M03机台 if task.attr == 1: m03 = next((m for m in candidate_machines if m.machine_id == "M03"), None) if m03: candidate_machines = [m03] + [m for m in candidate_machines if m.machine_id != "M03"] best_machine = None best_end = None best_start = None for machine in candidate_machines: # 计算换模时间(首单或不同产品需换模) change = CHANGE_TIME if machine.last_product != task.product_id else 0 initial_start = machine.available_time + timedelta(hours=change) end_time = calculate_end_time(initial_start, task.processing_hours, holidays) adjusted_start = initial_start # 难生产产品约束:相邻机台不能同时生产难生产产品 if task.attr == 3: for adj_id in machine.adjacent: adj_machine = machine_map.get(adj_id) if not adj_machine: continue # 检查相邻机台当前任务(如果有) if adj_machine.schedule: last_task = adj_machine.schedule[-1] # 如果相邻机台正在生产难生产产品且时间冲突 if last_task["product_attr"] == 3 and not (end_time <= last_task["start"] or adjusted_start >= last_task["end"]): # 调整开始时间至冲突任务结束后 adjusted_start = max(adjusted_start, last_task["end"]) end_time = calculate_end_time(adjusted_start, task.processing_hours, holidays) # 更新最优机台(最早结束时间) if best_end is None or end_time < best_end: best_end = end_time best_start = adjusted_start best_machine = machine # 分配机台并更新状态 if best_machine: task.start_time = best_start task.end_time = best_end task.machine = best_machine.machine_id # 更新原始订单的延期满意度 for original_order in task.original_orders: original_order.start_time = best_start original_order.end_time = best_end original_order.machine = best_machine.machine_id original_order.delay_days = max(0, (best_end.date() - original_order.delivery_date.date()).days) # 按文档公式计算满意度 original_order.satisfaction = max(0, 10.0 - (original_order.delay_days // 3) * 0.1) # 更新机台状态 best_machine.available_time = best_end best_machine.last_product = task.product_id best_machine.schedule.append({ "product": task.product_id, "start": best_start, "end": best_end, "product_attr": task.attr, "original_orders": [o.order_id for o in task.original_orders] }) # 收集所有原始订单用于统计 all_original_orders = [] for task in merged_tasks: all_original_orders.extend(task.original_orders) # 统计结果 delay_orders = [o for o in all_original_orders if o.delay_days > 0] max_delay = max([o.delay_days for o in delay_orders]) if delay_orders else 0 avg_delay = round(np.mean([o.delay_days for o in delay_orders]) if delay_orders else 0, 1) avg_satisfaction = round(np.mean([o.satisfaction for o in all_original_orders]), 2) min_satisfaction = round(min([o.satisfaction for o in all_original_orders]), 2) return all_original_orders, { "延期订单总数": len(delay_orders), "最长延期天数": max_delay, "平均延期天数": avg_delay, "订单平均满意度": avg_satisfaction, "订单最差满意度": min_satisfaction } def export_problem3_results(results, output_path=r"C:\Users\彭婉\Desktop\2025-08\工作簿1.xlsx"): “”“导出问题三结果到Excel(按指定格式)”“” # 创建结果DataFrame result_df = pd.DataFrame(results) # 重命名列以符合要求 result_df.rename(columns={ "合单类别": "合单类别", "合单次数": "合单次数", "延期订单总数": "延期订单总数", "最长延期天数": "最长前期天数", # 注意这里按要求改为"最长前期天数" "平均延期天数": "平均延期天数", "订单平均满意度": "订单平均满意度", "订单最差满意度": "订单最差满意度" }, inplace=True) # 设置列顺序 column_order = [ "合单类别", "合单次数", "延期订单总数", "最长前期天数", "平均延期天数", "订单平均满意度", "订单最差满意度" ] result_df = result_df[column_order] # 导出到Excel with pd.ExcelWriter(output_path, engine="openpyxl") as writer: result_df.to_excel(writer, sheet_name="生产排程结果", index=False) print(f"结果已导出至:{os.path.abspath(output_path)}") return result_df def main(): # 加载数据 orders_df, product_machines, product_attrs, original_machines, holidays = load_official_data() # 检查数据是否加载成功 if orders_df.empty or not original_machines: print("数据加载失败,请检查文件路径格式") return # 初始化原始订单对象 original_orders = [] for _, row in orders_df.iterrows(): try: order = Order( row["订单号PO"], row["产品号"], row["订单数量"], row["发货日期(DeliveryDate)"], row["Capacity(pcs/h)"], product_attrs.get(row["产品号"], 2) # 默认属性为2(无限制) ) original_orders.append(order) except Exception as e: print(f"订单初始化错误: {e} - 行数据: {row}") # 问题三:分别处理7天、15天、30天合单 merge_days_list = [7, 15, 30] problem3_results = [] for merge_days in merge_days_list: print(f"\n===== 处理 {merge_days} 天合单 =====") # 复制机台(避免状态污染) machines = [] for m in original_machines: # 正确复制机台初始时间 new_machine = Machine(m.machine_id, m.available_time) new_machine.adjacent = m.adjacent.copy() new_machine.last_product = m.last_product machines.append(new_machine) # 1. 合单 merged_tasks, merge_count = merge_orders(original_orders.copy(), merge_days) print(f"合单次数:{merge_count}") # 2. 排程 try: all_orders, stats = problem3_scheduling( merged_tasks, product_machines, product_attrs, machines, holidays ) except Exception as e: print(f"排程错误: {e}") continue # 3. 收集结果 problem3_results.append({ "合单类别": f"{merge_days}天合单", "合单次数": merge_count, "延期订单总数": stats["延期订单总数"], "最长延期天数": stats["最长延期天数"], "平均延期天数": stats["平均延期天数"], "订单平均满意度": stats["订单平均满意度"], "订单最差满意度": stats["订单最差满意度"] }) # 打印结果 print("\n===== 问题三最终结果 =====") result_df = export_problem3_results(problem3_results) # 控制台输出表格 print("\n生产排程结果表:") print(result_df.to_string(index=False)) if name == “main”: main() 补充修改一下这个代码,这个代码本身会输出一个内容,不要修改,它会输出的,但是增加一些,它可以多输出的一些东西,就满足我上述的这个要求,最终结果呈应该要有订单号PO,产品号,需要工时 (Requested Time--Hours),生产计划开始时间(Plan Start Time),生产计划预计完成时间(Plan Finish Time),发货日期(DeliveryDate),订单数量,Weight/pcs(g),Capacity(pcs/h),最迟开始时间 (Late Start Time),合单序号(Joined Order Number),前置任务生产计划序号(Forward Plan Number),是否延期,延期天数
最新发布
08-05
import pandas as pd import numpy as np from datetime import datetime, timedelta, time import os from typing import List, Dict, Optional # ====================== 基础参数 ====================== CHANGE_TIME = 3.5 # 换模时间(小时) REST_PERIODS = [ # 每日休息时段(小时) (12, 12.5), # 12:00-12:30 (16.5, 17), # 16:30-17:00 (0, 1) # 0:00-1:00 ] # ====================== 类定义 ====================== class Order: def __init__(self, order_id, product_id, quantity, delivery_date, capacity, weight, attr): self.order_id = order_id # 订单号 self.product_id = product_id # 产品号 self.quantity = quantity # 数量(pcs) self.delivery_date = delivery_date # 发货日期(datetime) self.capacity = capacity # 产能(pcs/h) self.weight = weight # 产品重量(g) self.processing_hours = quantity / capacity # 生产工时(h) self.start_time = None # 开始时间 self.end_time = None # 结束时间 self.machine = None # 分配机台 self.delay_days = 0 # 延期天数 self.attr = attr # 产品属性(1:易搭配,3:难生产) self.merged_id = None # 合单序号 self.plan_number = None # 计划序号 self.forward_plan = None # 前置任务计划序号 class MergedOrder: def __init__(self, product_id, total_quantity, delivery_dates, capacity, weight, attr, original_orders, merged_id): self.product_id = product_id # 产品号 self.total_quantity = total_quantity # 合并后总数量 self.delivery_dates = delivery_dates # 原始订单发货日期列表 self.capacity = capacity # 产能 self.weight = weight # 产品重量 self.processing_hours = total_quantity / capacity # 总生产工时 self.attr = attr # 产品属性 self.original_orders = original_orders # 原始订单对象列表 self.start_time = None # 开始时间 self.end_time = None # 结束时间 self.machine = None # 分配机台 self.merged_id = merged_id # 合单序号 self.plan_number = None # 计划序号 class Machine: def __init__(self, machine_id, initial_time=None): self.machine_id = machine_id # 机台号 self.available_time = initial_time or datetime(2025, 3, 1) # 初始可用时间 self.last_product = None # 上一生产产品 self.adjacent = [] # 相邻机台列表 self.schedule = [] # 排程计划(任务列表) self.last_plan_number = None # 上一任务计划序号 # ====================== 数据加载 ====================== def load_official_data(data_dir: str = "."): """ 加载附件数据 需修改data_dir为附件所在目录(例如:"C:/Users/你的用户名/Desktop/附件") """ try: # 读取附件1 attachment1 = pd.ExcelFile(os.path.join(data_dir, "附件1(1).xlsx")) orders_df = attachment1.parse( sheet_name="订单表", parse_dates=["发货日期(DeliveryDate)"], usecols=["订单号", "产品号", "订单数量", "发货日期(DeliveryDate)", "Weight/pcs(g)"] ) machine_initial_df = attachment1.parse( sheet_name="机台初始工作状态表", parse_dates=["生产开始时间"] ) holidays_df = attachment1.parse(sheet_name="放假日期表") holidays = {pd.to_datetime(row["放假日期"]).date() for _, row in holidays_df.iterrows()} # 读取附件2 attachment2 = pd.ExcelFile(os.path.join(data_dir, "附件2(1).xlsx")) product_capacity_df = attachment2.parse(sheet_name="产品工时计算参数表") product_machine_df = attachment2.parse(sheet_name="产品机台生产关系表") machine_relation_df = attachment2.parse(sheet_name="机台关系表") product_attr_df = attachment2.parse(sheet_name="产品属性表") # 构建数据映射 product_capacity = {row["产品号"]: row["Capacity(pcs/h)"] for _, row in product_capacity_df.iterrows()} product_weight = {row["产品号"]: row["Weight/pcs(g)"] for _, row in product_capacity_df.iterrows()} product_machines = {} for _, row in product_machine_df.iterrows(): valid_machines = [col for col in product_machine_df.columns if col != "产品号" and row[col] == 1] product_machines[row["产品号"]] = valid_machines machine_adjacent = {} for _, row in machine_relation_df.iterrows(): adjacent_machines = [col for col in machine_relation_df.columns if col != "机台号" and row[col] == 1] machine_adjacent[row["机台号"]] = adjacent_machines product_attrs = {row["产品号"]: row["属性"] for _, row in product_attr_df.iterrows()} # 补充订单表产能重量 orders_df["Capacity(pcs/h)"] = orders_df["产品号"].map(product_capacity) orders_df["Weight/pcs(g)"] = orders_df["产品号"].map(product_weight) # 初始化机台 machine_initial_times = {row["机台号"]: row["生产开始时间"] for _, row in machine_initial_df.iterrows()} machines = [] for mid in machine_initial_times.keys(): machine = Machine(mid, machine_initial_times[mid]) machine.adjacent = machine_adjacent.get(mid, []) machines.append(machine) return orders_df, product_machines, product_attrs, machines, holidays except Exception as e: print(f"数据加载失败,请检查附件路径格式:{e}") raise # ====================== 合单逻辑 ====================== def merge_orders(orders: List[Order], merge_days: int) -> tuple[List[MergedOrder], int]: merged_tasks = [] merge_count = 0 merged_id_counter = 1 product_groups = {} for order in orders: if order.product_id not in product_groups: product_groups[order.product_id] = [] product_groups[order.product_id].append(order) for product_id, group_orders in product_groups.items(): group_orders.sort(key=lambda x: x.delivery_date) current_merge = [group_orders[0]] for i in range(1, len(group_orders)): date_diff = (group_orders[i].delivery_date - current_merge[0].delivery_date).days if date_diff <= merge_days: current_merge.append(group_orders[i]) else: merged_tasks.append(MergedOrder( product_id=product_id, total_quantity=sum(o.quantity for o in current_merge), delivery_dates=[o.delivery_date for o in current_merge], capacity=current_merge[0].capacity, weight=current_merge[0].weight, attr=current_merge[0].attr, original_orders=current_merge, merged_id=merged_id_counter )) merge_count += 1 if len(current_merge) > 1 else 0 merged_id_counter += 1 current_merge = [group_orders[i]] merged_tasks.append(MergedOrder( product_id=product_id, total_quantity=sum(o.quantity for o in current_merge), delivery_dates=[o.delivery_date for o in current_merge], capacity=current_merge[0].capacity, weight=current_merge[0].weight, attr=current_merge[0].attr, original_orders=current_merge, merged_id=merged_id_counter )) if len(current_merge) > 1: merge_count += 1 merged_id_counter += 1 return merged_tasks, merge_count # ====================== 排程逻辑 ====================== def calculate_end_time(start_time: datetime, processing_hours: float, holidays: set) -> datetime: current = start_time remaining = processing_hours while remaining > 0: if current.date() in holidays: current = datetime.combine(current.date() + timedelta(days=1), time(0, 0)) continue day_start = datetime.combine(current.date(), time(0, 0)) intervals = [] prev_end = day_start for rest_start, rest_end in REST_PERIODS: rest_start_time = day_start + timedelta(hours=rest_start) rest_end_time = day_start + timedelta(hours=rest_end) if prev_end < rest_start_time: intervals.append((prev_end, rest_start_time)) prev_end = rest_end_time if prev_end < day_start + timedelta(hours=24): intervals.append((prev_end, day_start + timedelta(hours=24))) for (s, e) in intervals: if current < s: current = s if current >= e: continue available = (e - current).total_seconds() / 3600 use = min(remaining, available) current += timedelta(hours=use) remaining -= use if remaining <= 0: return current current = datetime.combine(current.date() + timedelta(days=1), time(0, 0)) return current def problem3_scheduling(merged_tasks: List[MergedOrder], product_machines: Dict, machines: List[Machine], holidays: set) -> tuple[List[Order], List[Dict]]: merged_tasks.sort(key=lambda x: (x.attr, min(x.delivery_dates))) machine_map = {m.machine_id: m for m in machines} plan_number = 1 detailed_results = [] for task in merged_tasks: candidate_machines = [m for m in machines if m.machine_id in product_machines.get(task.product_id, [])] if task.attr == 1: m03 = next((m for m in candidate_machines if m.machine_id == "M03"), None) if m03: candidate_machines = [m03] + [m for m in candidate_machines if m.machine_id != "M03"] best_machine = None best_end = None best_start = None for machine in candidate_machines: change = CHANGE_TIME if machine.last_product != task.product_id else 0 initial_start = machine.available_time + timedelta(hours=change) end_time = calculate_end_time(initial_start, task.processing_hours, holidays) adjusted_start = initial_start if task.attr == 3: for adj_id in machine.adjacent: adj_machine = machine_map.get(adj_id) if adj_machine and adj_machine.schedule: last_task = adj_machine.schedule[-1] if (last_task["product_attr"] == 3 and not (end_time <= last_task["start"] or adjusted_start >= last_task["end"])): adjusted_start = max(adjusted_start, last_task["end"]) end_time = calculate_end_time(adjusted_start, task.processing_hours, holidays) if best_end is None or end_time < best_end: best_end = end_time best_start = adjusted_start best_machine = machine if best_machine: task.start_time = best_start task.end_time = best_end task.machine = best_machine.machine_id task.plan_number = plan_number for original_order in task.original_orders: original_order.start_time = best_start original_order.end_time = best_end original_order.machine = best_machine.machine_id original_order.merged_id = task.merged_id original_order.plan_number = plan_number original_order.forward_plan = best_machine.last_plan_number original_order.delay_days = max(0, (best_end.date() - original_order.delivery_date.date()).days) detailed_results.append({ "计划序号(Plan Number)": plan_number, "生产计划安排机台号": best_machine.machine_id, "订单号PO": original_order.order_id, "产品号": original_order.product_id, "需要工时 (Requested Time--Hours)": round(original_order.processing_hours, 2), "生产计划开始时间": original_order.start_time.strftime("%Y-%m-%d %H:%M:%S"), "生产计划预计完成时间": original_order.end_time.strftime("%Y-%m-%d %H:%M:%S"), "发货日期(DeliveryDate)": original_order.delivery_date.strftime("%Y-%m-%d"), "订单数量": original_order.quantity, "Weight/pcs(g)": original_order.weight, "Capacity(pcs/h)": original_order.capacity, "最迟开始时间 (Late Start Time)": (original_order.delivery_date - timedelta( hours=original_order.processing_hours )).strftime("%Y-%m-%d %H:%M:%S"), "合单序号(Joined Order Number)": task.merged_id, "前置任务生产计划序号": original_order.forward_plan or "", "是否延期": "是" if original_order.delay_days > 0 else "否", "延期天数": original_order.delay_days }) best_machine.available_time = best_end best_machine.last_product = task.product_id best_machine.last_plan_number = plan_number best_machine.schedule.append({ "product": task.product_id, "start": best_start, "end": best_end, "product_attr": task.attr }) plan_number += 1 return detailed_results # ====================== 导出结果 ====================== def export_results(detailed_results: List[Dict], output_path: str = "附件5_生产排程计划表.xlsx"): """ 导出完整排程结果到Excel 需修改output_path为期望的导出路径(例如:"C:/Users/你的用户名/Desktop/附件5_结果.xlsx") """ df = pd.DataFrame(detailed_results) column_order = [ "计划序号(Plan Number)", "生产计划安排机台号", "订单号PO", "产品号", "需要工时 (Requested Time--Hours)", "生产计划开始时间", "生产计划预计完成时间", "发货日期(DeliveryDate)", "订单数量", "Weight/pcs(g)", "Capacity(pcs/h)", "最迟开始时间 (Late Start Time)", "合单序号(Joined Order Number)", "前置任务生产计划序号", "是否延期", "延期天数" ] df = df[column_order] df.to_excel(output_path, index=False) print(f"结果已导出至:{os.path.abspath(output_path)}") # ====================== 主函数 ====================== def main(): # ---------------------- 需要您修改的部分 ---------------------- # 1. 附件所在目录:将"."改为附件实际存放路径(例如:"C:/Users/你的用户名/Desktop/附件") DATA_DIR = "." # 2. 导出文件路径:将"附件5_生产排程计划表.xlsx"改为期望的导出路径(例如:"C:/Users/你的用户名/Desktop/结果.xlsx") OUTPUT_PATH = "附件5_生产排程计划表.xlsx" # 3. 合单天数:可根据需要修改(当前为7天,可改为15或30天) MERGE_DAYS = 7 # ------------------------------------------------------------- try: orders_df, product_machines, product_attrs, machines, holidays = load_official_data(DATA_DIR) original_orders = [] for _, row in orders_df.iterrows(): try: order = Order( order_id=row["订单号"], product_id=row["产品号"], quantity=row["订单数量"], delivery_date=row["发货日期(DeliveryDate)"], capacity=row["Capacity(pcs/h)"], weight=row["Weight/pcs(g)"], attr=product_attrs.get(row["产品号"], 2) ) original_orders.append(order) except Exception as e: print(f"订单初始化失败: {e} - 行数据: {row}") if not original_orders: raise ValueError("没有有效订单,请检查数据格式") merged_tasks, merge_count = merge_orders(original_orders, MERGE_DAYS) print(f"合单完成,共合并 {merge_count} 次") detailed_results = problem3_scheduling(merged_tasks, product_machines, machines, holidays) print(f"排程完成,共生成 {len(detailed_results)} 条计划") export_results(detailed_results, OUTPUT_PATH) except Exception as e: print(f"程序执行失败: {e}") if __name__ == "__main__": main() 最终结果呈应该要有计划序号生产计划安排机台号,订单号,产品号需要工时生产,计划开始时间,生产计划预计完成时间,发货日期,订单数量,重量,产能,最迟开始时间,合单序号,前置任务生产计划序号,是否延期,延期天数
08-05
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define MAX_PRODUCTS 1000 #define MAX_USERS 500 #define MAX_ORDERS 5000 #define MAX_NAME_LENGTH 50 #define MAX_ADDRESS_LENGTH 100 #define MAX_CATEGORY_LENGTH 30 #define RESTOCK_THRESHOLD 10 #define CLEANUP_DAYS 30 // 商品信息结构体 typedef struct { int id; // 商品ID char name[MAX_NAME_LENGTH]; // 商品名称 char category[MAX_CATEGORY_LENGTH]; // 商品类别 float price; // 商品价格 int stock; // 库存数量 int sales; // 销售数量统计 } Product; // 用户信息结构体 typedef struct { int id; // 用户ID char name[MAX_NAME_LENGTH]; // 用户姓名 char address[MAX_ADDRESS_LENGTH]; // 用户地址 char contact[MAX_NAME_LENGTH]; // 联系方式 } User; // 订单状态枚举 typedef enum { PENDING_PAYMENT, // 待付款 PAID, // 已付款 SHIPPED, // 已发货 COMPLETED // 已完成 } OrderStatus; // 订单信息结构体 typedef struct { int id; // 订单ID int user_id; // 用户ID int product_id; // 商品ID int quantity; // 商品数量 time_t order_time; // 下单时间 OrderStatus status; // 订单状态 } Order; // 补货任务结构体 typedef struct { int product_id; // 商品ID int priority; // 优先级(1-高优先级, 2-中优先级, 3-低优先级) } RestockTask; // 商品类别树节点 typedef struct CategoryNode { char name[MAX_CATEGORY_LENGTH]; // 类别名称 struct CategoryNode *parent; // 父类别 struct CategoryNode *children[MAX_PRODUCTS]; // 子类别 int child_count; // 子类别数量 int product_count; // 该类别下商品数量 float sales_total; // 该类别销售总额 } CategoryNode; // 全局数据存储 Product products[MAX_PRODUCTS]; // 商品数组 int product_count = 0; // 商品数量 User users[MAX_USERS]; // 用户数组 int user_count = 0; // 用户数量 Order orders[MAX_ORDERS]; // 订单数组 int order_count = 0; // 订单数量 RestockTask restock_queue[MAX_PRODUCTS]; // 补货任务队列 int restock_count = 0; // 补货任务数量 // 栈结构用于订单状态变更历史 typedef struct { int order_id; // 订单ID OrderStatus old_status; // 原状态 time_t timestamp; // 变更时间 } OrderHistoryItem; OrderHistoryItem order_history[MAX_ORDERS]; // 订单历史记录 int history_count = 0; // 历史记录数量 // 哈希表结构用于用户信息快速查找 typedef struct HashNode { int key; // 键(用户ID) User *user; // 用户指针 struct HashNode *next; // 链表指针 } HashNode; HashNode *user_hash_table[100]; // 用户哈希表 // 文件路径定义 const char *PRODUCTS_FILE = "D:\\c\\text\\products.csv"; const char *USERS_FILE = "D:\\c\\text\\users.csv"; const char *ORDERS_FILE = "D:\\c\\text\\orders.csv"; // 函数声明 void initialize_system(); // 初始化系统 void initialize_hash_table(); // 初始化哈希表 int add_product(int id, const char *name, const char *category, float price, int stock); // 添加商品 int find_product_by_id(int id); // 根据ID查找商品 int find_product_by_name(const char *name); // 根据名称查找商品 void sort_products_by_name(); // 按名称排序商品 void print_product(int index); // 打印商品信息 int add_user(int id, const char *name, const char *address, const char *contact); // 添加用户 User* find_user_by_id(int id); // 根据ID查找用户 int find_user_by_name(const char *name); // 根据名称查找用户 void print_user(int index); // 打印用户信息 int create_order(int user_id, int product_id, int quantity); // 创建订单 int process_payment(int order_id); // 处理付款 int process_shipment(int order_id); // 处理发货 int confirm_receipt(int order_id); // 确认收货 Order* find_order_by_id(int id); // 根据ID查找订单 void sort_orders_by_time(); // 按时间排序订单 void print_order(int index); // 打印订单信息 int update_stock(int product_id, int quantity); // 更新库存 void check_low_stock(); // 检查低库存 void process_restock_tasks(); // 处理补货任务 void push_order_history(int order_id, OrderStatus old_status); // 记录订单历史 OrderHistoryItem pop_order_history(); // 获取订单历史 int has_order_history(int order_id); // 检查订单是否有历史记录 void enqueue_restock_task(int product_id, int priority); // 添加补货任务 RestockTask dequeue_restock_task(); // 获取补货任务 int is_restock_queue_empty(); // 检查补货队列是否为空 CategoryNode* create_category_node(const char *name); // 创建类别节点 void add_child_category(CategoryNode *parent, CategoryNode *child); // 添加子类别 void traverse_category_tree(CategoryNode *node, int depth); // 遍历类别树 void update_category_stats(CategoryNode *node, Product *product, float sales_amount); // 更新类别统计 unsigned int hash_function(int key); // 哈希函数 void hash_table_insert(int key, User *user); // 哈希表插入 User* hash_table_lookup(int key); // 哈希表查找 void print_system_status(); // 打印系统状态 void cleanup_old_orders(); // 清理旧订单 void show_menu(); // 显示菜单 void input_product(); // 输入商品信息 void list_products(); // 列出所有商品 void input_user(); // 输入用户信息 void list_users(); // 列出所有用户 void input_order(); // 输入订单信息 void list_orders(); // 列出所有订单 void search_product(); // 搜索商品 void search_user(); // 搜索用户 void search_order(); // 搜索订单 void wait_for_user(); // 等待用户输入 // 从文件加载商品数据 int load_products_from_file() { FILE *file = fopen(PRODUCTS_FILE, "r"); if (file == NULL) { printf("警告: 商品文件不存在,将使用空数据初始化\n"); return 0; } char line[512]; int count = 0; // 跳过标题行 if (fgets(line, sizeof(line), file) == NULL) { fclose(file); return 0; } while (fgets(line, sizeof(line), file) != NULL && product_count < MAX_PRODUCTS) { Product p; char *token; // 解析ID token = strtok(line, ","); if (token == NULL) continue; p.id = atoi(token); // 解析名称 token = strtok(NULL, ","); if (token == NULL) continue; strncpy(p.name, token, MAX_NAME_LENGTH-1); p.name[MAX_NAME_LENGTH-1] = '\0'; // 解析类别 token = strtok(NULL, ","); if (token == NULL) continue; strncpy(p.category, token, MAX_CATEGORY_LENGTH-1); p.category[MAX_CATEGORY_LENGTH-1] = '\0'; // 解析价格 token = strtok(NULL, ","); if (token == NULL) continue; p.price = atof(token); // 解析库存 token = strtok(NULL, ","); if (token == NULL) continue; p.stock = atoi(token); // 解析销量 token = strtok(NULL, ",\n"); if (token != NULL) { p.sales = atoi(token); } else { p.sales = 0; } // 添加商品 if (add_product(p.id, p.name, p.category, p.price, p.stock) != -1) { // 更新销量 products[product_count-1].sales = p.sales; count++; } } fclose(file); printf("从文件加载了 %d 个商品\n", count); return count; } // 从文件加载用户数据 int load_users_from_file() { FILE *file = fopen(USERS_FILE, "r"); if (file == NULL) { printf("警告: 用户文件不存在,将使用空数据初始化\n"); return 0; } char line[512]; int count = 0; // 跳过标题行 if (fgets(line, sizeof(line), file) == NULL) { fclose(file); return 0; } while (fgets(line, sizeof(line), file) != NULL && user_count < MAX_USERS) { User u; char *token; // 解析ID token = strtok(line, ","); if (token == NULL) continue; u.id = atoi(token); // 解析名称 token = strtok(NULL, ","); if (token == NULL) continue; strncpy(u.name, token, MAX_NAME_LENGTH-1); u.name[MAX_NAME_LENGTH-1] = '\0'; // 解析地址 token = strtok(NULL, ","); if (token == NULL) continue; strncpy(u.address, token, MAX_ADDRESS_LENGTH-1); u.address[MAX_ADDRESS_LENGTH-1] = '\0'; // 解析联系方式 token = strtok(NULL, ",\n"); if (token != NULL) { strncpy(u.contact, token, MAX_NAME_LENGTH-1); u.contact[MAX_NAME_LENGTH-1] = '\0'; } else { u.contact[0] = '\0'; } // 添加用户 if (add_user(u.id, u.name, u.address, u.contact) != -1) { count++; } } fclose(file); printf("从文件加载了 %d 个用户\n", count); return count; } // 从文件加载订单数据 int load_orders_from_file() { FILE *file = fopen(ORDERS_FILE, "r"); if (file == NULL) { printf("警告: 订单文件不存在,将使用空数据初始化\n"); return 0; } char line[512]; int count = 0; // 跳过标题行 if (fgets(line, sizeof(line), file) == NULL) { fclose(file); return 0; } while (fgets(line, sizeof(line), file) != NULL && order_count < MAX_ORDERS) { Order o; char *token; // 解析ID token = strtok(line, ","); if (token == NULL) continue; o.id = atoi(token); // 解析用户ID token = strtok(NULL, ","); if (token == NULL) continue; o.user_id = atoi(token); // 解析商品ID token = strtok(NULL, ","); if (token == NULL) continue; o.product_id = atoi(token); // 解析数量 token = strtok(NULL, ","); if (token == NULL) continue; o.quantity = atoi(token); // 解析下单时间 token = strtok(NULL, ","); if (token == NULL) continue; o.order_time = (time_t)atol(token); // 解析状态 token = strtok(NULL, ",\n"); if (token == NULL) continue; int status = atoi(token); if (status >= PENDING_PAYMENT && status <= COMPLETED) { o.status = (OrderStatus)status; } else { o.status = PENDING_PAYMENT; } // 检查用户商品是否存在 User *user = find_user_by_id(o.user_id); if (user == NULL) { printf("警告: 订单 %d 的用户ID %d 不存在,跳过此订单\n", o.id, o.user_id); continue; } if (find_product_by_id(o.product_id) == -1) { printf("警告: 订单 %d 的商品ID %d 不存在,跳过此订单\n", o.id, o.product_id); continue; } // 添加订单(绕过库存检查,直接添加) orders[order_count] = o; order_count++; count++; } fclose(file); printf("从文件加载了 %d 个订单\n", count); return count; } // 添加商品 int add_product(int id, const char *name, const char *category, float price, int stock) { // 检查商品ID是否已存在 if (find_product_by_id(id) != -1) { printf("错误: 商品ID %d 已存在\n", id); return -1; } // 检查商品数量是否超过最大值 if (product_count >= MAX_PRODUCTS) { printf("错误: 商品数量已达到最大值\n"); return -1; } // 添加商品 products[product_count].id = id; strncpy(products[product_count].name, name, MAX_NAME_LENGTH-1); strncpy(products[product_count].category, category, MAX_CATEGORY_LENGTH-1); products[product_count].price = price; products[product_count].stock = stock; products[product_count].sales = 0; product_count++; return 0; } // 根据ID查找商品 int find_product_by_id(int id) { for (int i = 0; i < product_count; i++) { if (products[i].id == id) { return i; } } return -1; // 未找到 } // 根据名称查找商品 int find_product_by_name(const char *name) { for (int i = 0; i < product_count; i++) { if (strcmp(products[i].name, name) == 0) { return i; } } return -1; // 未找到 } // 按名称排序商品 void sort_products_by_name() { for (int i = 0; i < product_count - 1; i++) { for (int j = i + 1; j < product_count; j++) { if (strcmp(products[i].name, products[j].name) > 0) { // 交换商品 Product temp = products[i]; products[i] = products[j]; products[j] = temp; } } } } // 打印商品信息 void print_product(int index) { if (index < 0 || index >= product_count) { printf("错误: 无效的商品索引\n"); return; } printf("商品ID: %d\n", products[index].id); printf("商品名称: %s\n", products[index].name); printf("商品类别: %s\n", products[index].category); printf("商品价格: %.2f\n", products[index].price); printf("库存数量: %d\n", products[index].stock); printf("销售数量: %d\n", products[index].sales); printf("------------------------\n"); } // 添加用户 int add_user(int id, const char *name, const char *address, const char *contact) { // 检查用户ID是否已存在 if (find_user_by_id(id) != NULL) { printf("错误: 用户ID %d 已存在\n", id); return -1; } // 检查用户数量是否超过最大值 if (user_count >= MAX_USERS) { printf("错误: 用户数量已达到最大值\n"); return -1; } // 添加用户 users[user_count].id = id; strncpy(users[user_count].name, name, MAX_NAME_LENGTH-1); strncpy(users[user_count].address, address, MAX_ADDRESS_LENGTH-1); strncpy(users[user_count].contact, contact, MAX_NAME_LENGTH-1); // 添加到哈希表 hash_table_insert(id, &users[user_count]); user_count++; return 0; } // 根据ID查找用户 User* find_user_by_id(int id) { return hash_table_lookup(id); } // 根据名称查找用户 int find_user_by_name(const char *name) { for (int i = 0; i < user_count; i++) { if (strcmp(users[i].name, name) == 0) { return i; } } return -1; // 未找到 } // 打印用户信息 void print_user(int index) { if (index < 0 || index >= user_count) { printf("错误: 无效的用户索引\n"); return; } printf("用户ID: %d\n", users[index].id); printf("用户姓名: %s\n", users[index].name); printf("用户地址: %s\n", users[index].address); printf("联系方式: %s\n", users[index].contact); printf("------------------------\n"); } // 创建订单 int create_order(int user_id, int product_id, int quantity) { // 检查用户是否存在 if (find_user_by_id(user_id) == NULL) { printf("错误: 用户ID %d 不存在\n", user_id); return -1; } // 检查商品是否存在 int product_index = find_product_by_id(product_id); if (product_index == -1) { printf("错误: 商品ID %d 不存在\n", product_id); return -1; } // 检查库存是否充足 if (products[product_index].stock < quantity) { printf("错误: 商品库存不足,有库存: %d\n", products[product_index].stock); return -1; } // 检查订单数量是否超过最大值 if (order_count >= MAX_ORDERS) { printf("错误: 订单数量已达到最大值\n"); return -1; } // 创建订单 orders[order_count].id = order_count + 1; // 订单ID从1开始 orders[order_count].user_id = user_id; orders[order_count].product_id = product_id; orders[order_count].quantity = quantity; orders[order_count].order_time = time(NULL); // 当前时间 orders[order_count].status = PENDING_PAYMENT; // 初始状态为待付款 // 更新库存 update_stock(product_id, -quantity); order_count++; printf("订单创建成功,订单ID: %d\n", orders[order_count-1].id); return orders[order_count-1].id; } // 处理付款 int process_payment(int order_id) { Order *order = find_order_by_id(order_id); if (order == NULL) { printf("错误: 订单ID %d 不存在\n", order_id); return 0; } if (order->status != PENDING_PAYMENT) { printf("错误: 订单状态不是未付款状态,当前状态: "); switch (order->status) { case PAID: printf("已付款\n"); break; case SHIPPED: printf("已发货\n"); break; case COMPLETED: printf("已完成\n"); break; default: printf("未知状态\n"); } return 0; } // 记录历史 push_order_history(order_id, order->status); // 更新状态 order->status = PAID; printf("订单 %d 付款处理成功,当前状态: 已付款\n", order_id); return 1; } // 处理发货 int process_shipment(int order_id) { Order *order = find_order_by_id(order_id); if (order == NULL) { printf("错误: 订单ID %d 不存在\n", order_id); return 0; } if (order->status != PAID) { printf("错误: 订单状态不是已付款状态,当前状态: "); switch (order->status) { case PENDING_PAYMENT: printf("未付款\n"); break; case SHIPPED: printf("已发货\n"); break; case COMPLETED: printf("已完成\n"); break; default: printf("未知状态\n"); } return 0; } // 记录历史 push_order_history(order_id, order->status); // 更新状态 order->status = SHIPPED; printf("订单 %d 发货处理成功,当前状态: 已发货\n", order_id); return 1; } // 确认收货 int confirm_receipt(int order_id) { Order *order = find_order_by_id(order_id); if (order == NULL) { printf("错误: 订单ID %d 不存在\n", order_id); return 0; } if (order->status != SHIPPED) { printf("错误: 订单状态不是已发货状态,当前状态: "); switch (order->status) { case PENDING_PAYMENT: printf("未付款\n"); break; case PAID: printf("已付款\n"); break; case COMPLETED: printf("已完成\n"); break; default: printf("未知状态\n"); } return 0; } // 记录历史 push_order_history(order_id, order->status); // 更新状态 order->status = COMPLETED; // 更新商品销量 int product_index = find_product_by_id(order->product_id); if (product_index != -1) { products[product_index].sales += order->quantity; } printf("订单 %d 收货确认成功,当前状态: 已完成\n", order_id); return 1; } // 根据ID查找订单 Order* find_order_by_id(int id) { for (int i = 0; i < order_count; i++) { if (orders[i].id == id) { return &orders[i]; } } return NULL; // 未找到 } // 按时间排序订单 void sort_orders_by_time() { for (int i = 0; i < order_count - 1; i++) { for (int j = i + 1; j < order_count; j++) { if (orders[i].order_time > orders[j].order_time) { // 交换订单 Order temp = orders[i]; orders[i] = orders[j]; orders[j] = temp; } } } } // 打印订单信息 void print_order(int index) { if (index < 0 || index >= order_count) { printf("错误: 无效的订单索引\n"); return; } char status_str[20]; switch (orders[index].status) { case PENDING_PAYMENT: strcpy(status_str, "待付款"); break; case PAID: strcpy(status_str, "已付款"); break; case SHIPPED: strcpy(status_str, "已发货"); break; case COMPLETED: strcpy(status_str, "已完成"); break; default: strcpy(status_str, "未知状态"); } User *user = find_user_by_id(orders[index].user_id); int product_index = find_product_by_id(orders[index].product_id); printf("订单ID: %d\n", orders[index].id); printf("用户信息: %s (ID: %d)\n", user ? user->name : "未知用户", orders[index].user_id); printf("商品信息: %s (ID: %d)\n", product_index != -1 ? products[product_index].name : "未知商品", orders[index].product_id); printf("数量: %d\n", orders[index].quantity); if (product_index != -1) { printf("总价: %.2f\n", products[product_index].price * orders[index].quantity); } printf("下单时间: %s", ctime(&orders[index].order_time)); printf("订单状态: %s\n", status_str); printf("------------------------\n"); } // 更新库存 int update_stock(int product_id, int quantity) { int index = find_product_by_id(product_id); if (index == -1) { printf("错误: 商品ID %d 不存在\n", product_id); return -1; } // 检查库存是否充足(仅当减少库存时) if (quantity < 0 && products[index].stock < (-quantity)) { printf("错误: 商品库存不足,有库存: %d\n", products[index].stock); return -1; } products[index].stock += quantity; return 0; } // 检查低库存 void check_low_stock() { printf("低库存商品列表:\n"); int low_stock_count = 0; for (int i = 0; i < product_count; i++) { if (products[i].stock <= RESTOCK_THRESHOLD) { printf("商品ID: %d, 商品名称: %s, 库存: %d\n", products[i].id, products[i].name, products[i].stock); // 添加补货任务 int priority = (products[i].stock == 0) ? 1 : 2; // 缺货为高优先级 enqueue_restock_task(products[i].id, priority); low_stock_count++; } } if (low_stock_count == 0) { printf("所有商品库存充足\n"); } } // 处理补货任务 void process_restock_tasks() { if (is_restock_queue_empty()) { printf("没有需要处理的补货任务\n"); return; } printf("处理补货任务:\n"); while (!is_restock_queue_empty()) { RestockTask task = dequeue_restock_task(); int product_index = find_product_by_id(task.product_id); if (product_index != -1) { // 增加库存(模拟补货100个) update_stock(task.product_id, 100); printf("已补货: 商品ID %d, 商品名称: %s, 优先级: %d\n", task.product_id, products[product_index].name, task.priority); } else { printf("错误: 商品ID %d 不存在,无法补货\n", task.product_id); } } } // 记录订单历史 void push_order_history(int order_id, OrderStatus old_status) { if (history_count >= MAX_ORDERS) { printf("错误: 订单历史记录已满\n"); return; } order_history[history_count].order_id = order_id; order_history[history_count].old_status = old_status; order_history[history_count].timestamp = time(NULL); history_count++; } // 获取订单历史 OrderHistoryItem pop_order_history() { OrderHistoryItem item; item.order_id = -1; item.old_status = PENDING_PAYMENT; item.timestamp = 0; if (history_count <= 0) { printf("错误: 订单历史记录为空\n"); return item; } history_count--; return order_history[history_count]; } // 检查订单是否有历史记录 int has_order_history(int order_id) { for (int i = 0; i < history_count; i++) { if (order_history[i].order_id == order_id) { return 1; } } return 0; } // 添加补货任务 void enqueue_restock_task(int product_id, int priority) { if (restock_count >= MAX_PRODUCTS) { printf("错误: 补货任务队列已满\n"); return; } restock_queue[restock_count].product_id = product_id; restock_queue[restock_count].priority = priority; restock_count++; // 按优先级排序 for (int i = 0; i < restock_count - 1; i++) { for (int j = i + 1; j < restock_count; j++) { if (restock_queue[i].priority > restock_queue[j].priority) { // 交换任务 RestockTask temp = restock_queue[i]; restock_queue[i] = restock_queue[j]; restock_queue[j] = temp; } } } } // 获取补货任务 RestockTask dequeue_restock_task() { RestockTask task; task.product_id = -1; task.priority = 0; if (restock_count <= 0) { printf("错误: 补货任务队列为空\n"); return task; } // 获取优先级最高的任务(队列头部) task = restock_queue[0]; // 将后面的任务前移 for (int i = 0; i < restock_count - 1; i++) { restock_queue[i] = restock_queue[i + 1]; } restock_count--; return task; } // 检查补货队列是否为空 int is_restock_queue_empty() { return restock_count == 0; } // 创建类别节点 CategoryNode* create_category_node(const char *name) { CategoryNode *node = (CategoryNode*)malloc(sizeof(CategoryNode)); if (node == NULL) { printf("错误: 内存分配失败\n"); return NULL; } strncpy(node->name, name, MAX_CATEGORY_LENGTH-1); node->parent = NULL; node->child_count = 0; node->product_count = 0; node->sales_total = 0.0; for (int i = 0; i < MAX_PRODUCTS; i++) { node->children[i] = NULL; } return node; } // 添加子类别 void add_child_category(CategoryNode *parent, CategoryNode *child) { if (parent == NULL || child == NULL) { return; } if (parent->child_count >= MAX_PRODUCTS) { printf("错误: 类别子节点数量已达到最大值\n"); return; } child->parent = parent; parent->children[parent->child_count] = child; parent->child_count++; } // 遍历类别树 void traverse_category_tree(CategoryNode *node, int depth) { if (node == NULL) { return; } // 缩进显示层级 for (int i = 0; i < depth; i++) { printf(" "); } printf("%s (商品数量: %d, 销售总额: %.2f)\n", node->name, node->product_count, node->sales_total); // 递归遍历子类别 for (int i = 0; i < node->child_count; i++) { traverse_category_tree(node->children[i], depth + 1); } } // 更新类别统计 void update_category_stats(CategoryNode *node, Product *product, float sales_amount) { if (node == NULL || product == NULL) { return; } // 更新当前类别统计 node->product_count++; node->sales_total += sales_amount; // 递归更新父类别统计 if (node->parent != NULL) { update_category_stats(node->parent, product, sales_amount); } } // 哈希函数 unsigned int hash_function(int key) { return key % 100; } // 哈希表插入 void hash_table_insert(int key, User *user) { unsigned int index = hash_function(key); HashNode *new_node = (HashNode*)malloc(sizeof(HashNode)); if (new_node == NULL) { printf("错误: 内存分配失败\n"); return; } new_node->key = key; new_node->user = user; new_node->next = user_hash_table[index]; user_hash_table[index] = new_node; } // 哈希表查找 User* hash_table_lookup(int key) { unsigned int index = hash_function(key); HashNode *current = user_hash_table[index]; while (current != NULL) { if (current->key == key) { return current->user; } current = current->next; } return NULL; // 未找到 } // 打印系统状态 void print_system_status() { printf("===== 系统状态报告 =====\n"); printf("商品总数: %d\n", product_count); printf("用户总数: %d\n", user_count); printf("订单总数: %d\n", order_count); int pending_count = 0, paid_count = 0, shipped_count = 0, completed_count = 0; for (int i = 0; i < order_count; i++) { switch (orders[i].status) { case PENDING_PAYMENT: pending_count++; break; case PAID: paid_count++; break; case SHIPPED: shipped_count++; break; case COMPLETED: completed_count++; break; } } printf("订单状态统计:\n"); printf(" 待付款: %d\n", pending_count); printf(" 已付款: %d\n", paid_count); printf(" 已发货: %d\n", shipped_count); printf(" 已完成: %d\n", completed_count); printf("补货任务数量: %d\n", restock_count); printf("订单历史记录数量: %d\n", history_count); printf("=======================\n"); } // 清理旧订单 void cleanup_old_orders() { time_t current_time = time(NULL); time_t cutoff_time = current_time - (CLEANUP_DAYS * 24 * 60 * 60); // N天前 int cleaned_count = 0; int moved_count = 0; // 创建临时数组存储需要保留的订单 Order temp_orders[MAX_ORDERS]; int temp_count = 0; for (int i = 0; i < order_count; i++) { // 只清理已完成的订单 if (orders[i].status == COMPLETED && orders[i].order_time < cutoff_time) { cleaned_count++; } else { // 保留的订单移动到临时数组 temp_orders[temp_count] = orders[i]; temp_count++; } } // 将临时数组复制回原数组 if (temp_count != order_count) { memcpy(orders, temp_orders, temp_count * sizeof(Order)); order_count = temp_count; moved_count = cleaned_count; } printf("清理完成: 共清理 %d 个旧订单\n", moved_count); } // 初始化系统 void initialize_system() { product_count = 0; user_count = 0; order_count = 0; restock_count = 0; history_count = 0; initialize_hash_table(); // 从文件加载数据 load_products_from_file(); load_users_from_file(); load_orders_from_file(); printf("系统初始化完成\n"); // 如果文件加载失败或为空,添加一些测试数据 if (product_count == 0) { add_product(101, "智能手机", "电子产品", 4999.0, 50); add_product(102, "笔记本电脑", "电子产品", 7999.0, 30); add_product(103, "T恤", "服装", 99.0, 100); } if (user_count == 0) { add_user(1, "张三", "北京市朝阳区", "13800138000"); add_user(2, "李四", "上海市浦东新区", "13900139000"); } } // 初始化哈希表 void initialize_hash_table() { for (int i = 0; i < 100; i++) { user_hash_table[i] = NULL; } } // 显示菜单 void show_menu() { printf("\n===== 电商平台管理系统 =====\n"); printf("1. 添加商品\n"); printf("2. 查看所有商品\n"); printf("3. 搜索商品\n"); printf("4. 添加用户\n"); printf("5. 查看所有用户\n"); printf("6. 搜索用户\n"); printf("7. 创建订单\n"); printf("8. 查看所有订单\n"); printf("9. 搜索订单\n"); printf("10. 处理付款\n"); printf("11. 处理发货\n"); printf("12. 确认收货\n"); printf("13. 检查低库存商品\n"); printf("14. 处理补货任务\n"); printf("15. 查看系统状态\n"); printf("16. 清理旧订单\n"); printf("0. 退出系统\n"); printf("===========================\n"); } // 等待用户输入,按任意键返回菜单 void wait_for_user() { printf("\n按Enter键返回菜单..."); while (getchar() != '\n'); // 清除输入缓冲区 getchar(); // 等待用户按下Enter键 } // 输入商品信息 void input_product() { int id; char name[MAX_NAME_LENGTH]; char category[MAX_CATEGORY_LENGTH]; float price; int stock; printf("请输入商品ID: "); scanf("%d", &id); getchar(); // 消耗换行符 printf("请输入商品名称: "); fgets(name, MAX_NAME_LENGTH, stdin); name[strcspn(name, "\n")] = 0; // 去除换行符 printf("请输入商品类别: "); fgets(category, MAX_CATEGORY_LENGTH, stdin); category[strcspn(category, "\n")] = 0; // 去除换行符 printf("请输入商品价格: "); scanf("%f", &price); getchar(); // 消耗换行符 printf("请输入商品库存: "); scanf("%d", &stock); getchar(); // 消耗换行符 if (add_product(id, name, category, price, stock) == 0) { printf("商品添加成功\n"); } } // 列出所有商品 void list_products() { if (product_count == 0) { printf("没有商品记录\n"); return; } sort_products_by_name(); // 按名称排序 printf("商品列表:\n"); for (int i = 0; i < product_count; i++) { printf("%d. %s (ID: %d, 价格: %.2f, 库存: %d)\n", i + 1, products[i].name, products[i].id, products[i].price, products[i].stock); } } // 输入用户信息 void input_user() { int id; char name[MAX_NAME_LENGTH]; char address[MAX_ADDRESS_LENGTH]; char contact[MAX_NAME_LENGTH]; printf("请输入用户ID: "); scanf("%d", &id); getchar(); // 消耗换行符 printf("请输入用户姓名: "); fgets(name, MAX_NAME_LENGTH, stdin); name[strcspn(name, "\n")] = 0; // 去除换行符 printf("请输入用户地址: "); fgets(address, MAX_ADDRESS_LENGTH, stdin); address[strcspn(address, "\n")] = 0; // 去除换行符 printf("请输入联系方式: "); fgets(contact, MAX_NAME_LENGTH, stdin); contact[strcspn(contact, "\n")] = 0; // 去除换行符 if (add_user(id, name, address, contact) == 0) { printf("用户添加成功\n"); } } // 列出所有用户 void list_users() { if (user_count == 0) { printf("没有用户记录\n"); return; } printf("用户列表:\n"); for (int i = 0; i < user_count; i++) { printf("%d. %s (ID: %d, 联系方式: %s)\n", i + 1, users[i].name, users[i].id, users[i].contact); } } // 输入订单信息 void input_order() { int user_id, product_id, quantity; printf("请输入用户ID: "); scanf("%d", &user_id); getchar(); // 消耗换行符 printf("请输入商品ID: "); scanf("%d", &product_id); getchar(); // 消耗换行符 printf("请输入商品数量: "); scanf("%d", &quantity); getchar(); // 消耗换行符 create_order(user_id, product_id, quantity); } // 列出所有订单 void list_orders() { if (order_count == 0) { printf("没有订单记录\n"); return; } sort_orders_by_time(); // 按时间排序 printf("订单列表:\n"); for (int i = 0; i < order_count; i++) { printf("%d. 订单ID: %d, 用户ID: %d, 商品ID: %d, 数量: %d, 状态: ", i + 1, orders[i].id, orders[i].user_id, orders[i].product_id, orders[i].quantity); switch (orders[i].status) { case PENDING_PAYMENT: printf("待付款\n"); break; case PAID: printf("已付款\n"); break; case SHIPPED: printf("已发货\n"); break; case COMPLETED: printf("已完成\n"); break; default: printf("未知状态\n"); } } } // 搜索商品 void search_product() { int choice; printf("搜索方式:\n"); printf("1. 按ID搜索\n"); printf("2. 按名称搜索\n"); printf("请选择: "); scanf("%d", &choice); getchar(); // 消耗换行符 if (choice == 1) { int id; printf("请输入商品ID: "); scanf("%d", &id); getchar(); // 消耗换行符 int index = find_product_by_id(id); if (index != -1) { print_product(index); } else { printf("未找到商品ID为 %d 的记录\n", id); } } else if (choice == 2) { char name[MAX_NAME_LENGTH]; printf("请输入商品名称: "); fgets(name, MAX_NAME_LENGTH, stdin); name[strcspn(name, "\n")] = 0; // 去除换行符 int index = find_product_by_name(name); if (index != -1) { print_product(index); } else { printf("未找到商品名称为 %s 的记录\n", name); } } else { printf("无效的选择\n"); } } // 搜索用户 void search_user() { int choice; printf("搜索方式:\n"); printf("1. 按ID搜索\n"); printf("2. 按名称搜索\n"); printf("请选择: "); scanf("%d", &choice); getchar(); // 消耗换行符 if (choice == 1) { int id; printf("请输入用户ID: "); scanf("%d", &id); getchar(); // 消耗换行符 User *user = find_user_by_id(id); if (user != NULL) { // 查找用户在数组中的索引 int index = -1; for (int i = 0; i < user_count; i++) { if (users[i].id == id) { index = i; break; } } if (index != -1) { print_user(index); } } else { printf("未找到用户ID为 %d 的记录\n", id); } } else if (choice == 2) { char name[MAX_NAME_LENGTH]; printf("请输入用户姓名: "); fgets(name, MAX_NAME_LENGTH, stdin); name[strcspn(name, "\n")] = 0; // 去除换行符 int index = find_user_by_name(name); if (index != -1) { print_user(index); } else { printf("未找到用户姓名为 %s 的记录\n", name); } } else { printf("无效的选择\n"); } } // 搜索订单 void search_order() { int id; printf("请输入订单ID: "); scanf("%d", &id); getchar(); // 消耗换行符 Order *order = find_order_by_id(id); if (order != NULL) { // 查找订单在数组中的索引 int index = -1; for (int i = 0; i < order_count; i++) { if (orders[i].id == id) { index = i; break; } } if (index != -1) { print_order(index); } } else { printf("未找到订单ID为 %d 的记录\n", id); } } // 主函数 int main() { initialize_system(); int choice; do { show_menu(); printf("请输入您的选择: "); if (scanf("%d", &choice) != 1) { printf("输入错误,请输入一个数字\n"); while (getchar() != '\n'); // 清除错误输入 continue; } getchar(); // 消耗换行符 switch (choice) { case 1: input_product(); wait_for_user(); break; case 2: list_products(); wait_for_user(); break; case 3: search_product(); wait_for_user(); break; case 4: input_user(); wait_for_user(); break; case 5: list_users(); wait_for_user(); break; case 6: search_user(); wait_for_user(); break; case 7: input_order(); wait_for_user(); break; case 8: list_orders(); wait_for_user(); break; case 9: search_order(); wait_for_user(); break; case 10: printf("请输入要处理付款的订单ID: "); int order_id; scanf("%d", &order_id); getchar(); // 消耗换行符 process_payment(order_id); wait_for_user(); break; case 11: printf("请输入要处理发货的订单ID: "); scanf("%d", &order_id); getchar(); // 消耗换行符 process_shipment(order_id); wait_for_user(); break; case 12: printf("请输入要确认收货的订单ID: "); scanf("%d", &order_id); getchar(); // 消耗换行符 confirm_receipt(order_id); wait_for_user(); break; case 13: check_low_stock(); wait_for_user(); break; case 14: process_restock_tasks(); wait_for_user(); break; case 15: print_system_status(); wait_for_user(); break; case 16: cleanup_old_orders(); wait_for_user(); break; case 0: printf("退出系统...\n"); break; default: printf("无效的选择,请重新输入\n"); } } while (choice != 0); return 0; }
06-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值