当前位置: 首页 > news >正文

pulp解析器测试开发排产

pulp解析器测试开发排产

    • 接口
    • 前端
    • 效果

接口

from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Form, status, Path
from app.algorithms.services import AlgorithmService
from app.algorithms.schemas import AlgorithmExecuteResponsefrom sqlalchemy.orm import Session
from typing import Listfrom app.db.session import get_dbimport jsonfrom datetime import datetime,timedelta
from pydantic import BaseModel
import pdb
import pulp
import pandas as pd# 引入日志
import loggingrouter = APIRouter(prefix="/schedule", tags=["schedule"])# 日志配置
logger = logging.getLogger(__name__)  # 使用当前模块名作为logger的名字
logger.setLevel(logging.DEBUG)  # 设置logger的级别
handler = logging.StreamHandler()  # 创建一个handler来输出日志到控制台
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')  # 设置日志格式
handler.setFormatter(formatter)  # 将格式设置应用到handler上
logger.addHandler(handler)  # 将handler添加到logger中##使用算法的日志
# CRUD 端点#创建模型日志功能
@router.post("/optimize", status_code=status.HTTP_201_CREATED)
def optimize_schedule(projects: str = Form(...),productionLines: str = Form(...),
):try:# 提取项目需求和生产线信息projects_data = json.loads(projects)lines_data = json.loads(productionLines)# 按优先级排序项目(sort值越小优先级越高)projects_data.sort(key=lambda x: x['sort'])switch_penalty = 1000  # 增加切换惩罚权重# 日期范围 - 接下来一个月start_date = datetime.now().date()end_date = (datetime.now() + timedelta(days=30)).date()date_range = pd.date_range(start=start_date, end=end_date)# 创建问题实例 - 最大化产能利用率prob = pulp.LpProblem("Production_Scheduling", pulp.LpMaximize)# 创建决策变量# x[i][j][d] 表示在第d天,生产线j分配给项目i的产能x = pulp.LpVariable.dicts("Allocation", ((p['id'], l['id'], d.strftime('%Y-%m-%d')) for p in projects_data for l in lines_data for d in date_range if p['id'] in l['supported_projects']),lowBound=0, cat='Continuous')# 二进制变量 y[i][j][d] 表示在第d天,生产线j是否分配给项目iy = pulp.LpVariable.dicts("Assignment",((p['id'], l['id'], d.strftime('%Y-%m-%d'))for p in projects_datafor l in lines_datafor d in date_rangeif p['id'] in l['supported_projects']),cat='Binary')# 新增变量: 项目在产线上的开始时间start_time = pulp.LpVariable.dicts("StartTime",((p['id'], l['id']) for p in projects_data for l in lines_data if p['id'] in l['supported_projects']),lowBound=0, upBound=len(date_range)-1,cat='Integer')# 新增变量: 项目在产线上的结束时间end_time = pulp.LpVariable.dicts("EndTime",((p['id'], l['id']) for p in projects_data for l in lines_data if p['id'] in l['supported_projects']),lowBound=0, upBound=len(date_range)-1,cat='Integer')# 新增变量: 项目在产线上是否被安排生产project_assigned = pulp.LpVariable.dicts("ProjectAssigned",((p['id'], l['id']) for p in projects_data for l in lines_data if p['id'] in l['supported_projects']),cat='Binary')# 目标函数:最大化总产能 + 优先完成高优先级项目total_capacity = pulp.lpSum([x[(p['id'], l['id'], d.strftime('%Y-%m-%d'))] for p in projects_data for l in lines_data for d in date_range if p['id'] in l['supported_projects']])# 添加优先级权重:高优先级项目尽早完成priority_weight = pulp.lpSum([(len(projects_data) - i) * 1000 * pulp.lpSum([x[(p['id'], l['id'], d.strftime('%Y-%m-%d'))] for l in lines_data for d in date_range if p['id'] in l['supported_projects']])for i, p in enumerate(projects_data)])prob += total_capacity + priority_weight# 约束1: 每个项目总产量满足需求for p in projects_data:prob += pulp.lpSum([x[(p['id'], l['id'], d.strftime('%Y-%m-%d'))] for l in lines_data for d in date_range if p['id'] in l['supported_projects']]) == p['demand']# 约束2: 每个生产线每天产能不超过最大产能for l in lines_data:for d in date_range:prob += pulp.lpSum([x[(p['id'], l['id'], d.strftime('%Y-%m-%d'))] for p in projects_data if p['id'] in l['supported_projects']]) <= l['capacity_per_day']# 约束3: 项目生产必须在交货日期前完成for p in projects_data:due_date = datetime.strptime(p['due_date'], '%Y-%m-%d').date()due_date_index = Nonefor idx, d in enumerate(date_range):if d.date() == due_date:due_date_index = idxbreakif due_date_index is not None:for l in lines_data:if p['id'] in l['supported_projects']:prob += end_time[(p['id'], l['id'])] <= due_date_index# 约束4: 连接连续变量和二进制变量M = 10000  # 一个大数for p in projects_data:for l in lines_data:if p['id'] in l['supported_projects']:for d in date_range:key = (p['id'], l['id'], d.strftime('%Y-%m-%d'))prob += x[key] <= M * y[key]# 约束5: 每天每条产线只能生产一款产品for l in lines_data:for d in date_range:prob += pulp.lpSum([y[(p['id'], l['id'], d.strftime('%Y-%m-%d'))]for p in projects_dataif p['id'] in l['supported_projects']]) <= 1# 约束6: 定义项目在产线上的开始和结束时间for p in projects_data:for l in lines_data:if p['id'] in l['supported_projects']:# 开始时间约束:如果某天有生产,那么开始时间不能晚于这一天for d_idx, d in enumerate(date_range):day_str = d.strftime('%Y-%m-%d')prob += start_time[(p['id'], l['id'])] <= d_idx + M * (1 - y[(p['id'], l['id'], day_str)])# 结束时间约束:如果某天有生产,那么结束时间不能早于这一天for d_idx, d in enumerate(date_range):day_str = d.strftime('%Y-%m-%d')prob += end_time[(p['id'], l['id'])] >= d_idx - M * (1 - y[(p['id'], l['id'], day_str)])# 结束时间不能早于开始时间prob += end_time[(p['id'], l['id'])] >= start_time[(p['id'], l['id'])]# 约束7: 严格的优先级约束 - 在同一条产线上,高优先级项目必须完成后才能开始低优先级项目for l in lines_data:# 获取该产线支持的所有项目,并按优先级排序supported_projects = [p for p in projects_data if p['id'] in l['supported_projects']]supported_projects.sort(key=lambda x: x['sort'])# 对每对相邻优先级项目添加约束for i in range(len(supported_projects) - 1):higher_priority = supported_projects[i]  # 高优先级项目lower_priority = supported_projects[i + 1]  # 低优先级项目# 低优先级项目的开始时间必须晚于高优先级项目的结束时间prob += start_time[(lower_priority['id'], l['id'])] >= end_time[(higher_priority['id'], l['id'])] + 1# 确保高优先级项目完成后,低优先级项目才能开始# 使用大M法确保约束只在两个项目都被安排时才生效M_priority = len(date_range) + 1prob += start_time[(lower_priority['id'], l['id'])] >= end_time[(higher_priority['id'], l['id'])] + 1 - M_priority * (2 - project_assigned[(higher_priority['id'], l['id'])] - project_assigned[(lower_priority['id'], l['id'])])# 约束8: 连接项目分配变量for p in projects_data:for l in lines_data:if p['id'] in l['supported_projects']:# 如果项目在产线上有生产,则分配变量为1prob += project_assigned[(p['id'], l['id'])] <= pulp.lpSum([y[(p['id'], l['id'], d.strftime('%Y-%m-%d'))] for d in date_range])prob += project_assigned[(p['id'], l['id'])] * M >= pulp.lpSum([y[(p['id'], l['id'], d.strftime('%Y-%m-%d'))] for d in date_range])# 求解问题prob.solve()# 检查解决方案状态if pulp.LpStatus[prob.status] != 'Optimal':logger.warning(f"求解状态: {pulp.LpStatus[prob.status]}")if pulp.LpStatus[prob.status] == 'Infeasible':# 尝试放松优先级约束,寻找可行解logger.info("尝试放松优先级约束...")# 这里可以添加放松约束的逻辑return {"status":"false","msg": "无法找到可行解决方案,请检查约束条件或调整优先级"}else:return {"status":"false","msg": "无法找到最优解决方案"}# 提取结果results = []total_capacity_utilization = 0total_possible_capacity = 0# 记录每个产线上项目的生产顺序line_production_sequence = {}for l in lines_data:line_result = {"line_id": l['id'],"line_name": l['name'],"production_sequence": [],  # 记录项目生产顺序"daily_allocations": []}# 收集该产线上安排的项目及其时间信息line_projects = []for p in projects_data:if p['id'] in l['supported_projects'] and project_assigned[(p['id'], l['id'])].varValue > 0.5:start_val = start_time[(p['id'], l['id'])].varValueend_val = end_time[(p['id'], l['id'])].varValueline_projects.append({'project': p,'start_day': int(start_val),'end_day': int(end_val),'sort_priority': p['sort']})# 按开始时间排序,显示生产顺序line_projects.sort(key=lambda x: x['start_day'])line_result['production_sequence'] = line_projectsfor d in date_range:daily_allocation = {"date": d.strftime('%Y-%m-%d'),"allocations": []}daily_total = 0for p in projects_data:if p['id'] in l['supported_projects']:key = (p['id'], l['id'], d.strftime('%Y-%m-%d'))if key in x and x[key].varValue > 0:allocation_value = x[key].varValuedaily_allocation['allocations'].append({"project_id": p['id'],"project_name": p['name'],"sort_priority": p['sort'],"allocation": allocation_value})daily_total += allocation_valuedaily_allocation['daily_total'] = daily_totaldaily_allocation['capacity_utilization'] = (daily_total / l['capacity_per_day']) * 100 if l['capacity_per_day'] > 0 else 0line_result['daily_allocations'].append(daily_allocation)total_capacity_utilization += daily_totaltotal_possible_capacity += l['capacity_per_day']results.append(line_result)overall_utilization = (total_capacity_utilization / total_possible_capacity) * 100 if total_possible_capacity > 0 else 0# 检查项目需求是否满足demand_fulfillment = []for p in projects_data:total_produced = 0start_days = []end_days = []for l in lines_data:if p['id'] in l['supported_projects']:for d in date_range:key = (p['id'], l['id'], d.strftime('%Y-%m-%d'))if key in x:total_produced += x[key].varValueif project_assigned[(p['id'], l['id'])].varValue > 0.5:start_days.append(int(start_time[(p['id'], l['id'])].varValue))end_days.append(int(end_time[(p['id'], l['id'])].varValue))demand_fulfillment.append({"project_id": p['id'],"project_name": p['name'],"sort_priority": p['sort'],"demand": p['demand'],"produced": total_produced,"fulfilled": total_produced >= p['demand'],"start_days": start_days,"end_days": end_days})# 按优先级排序需求满足情况demand_fulfillment.sort(key=lambda x: x['sort_priority'])return {"status":"true","schedule": results,"overall_utilization": overall_utilization,"demand_fulfillment": demand_fulfillment,"priority_sequence": [p['name'] for p in projects_data]  # 显示优先级顺序}except Exception as e:logger.error(f"Error in optimize_schedule: {str(e)}")return {"status": "false", "error": str(e)}

前端

/*** 排产计划测试页面*/
<template><div id="app"><el-container><el-main class="app-container"><!-- 头部 --><div class="header"><h1><i class="el-icon-s-platform"></i> 项目排产优化系统</h1><p>最大化产能利用率,满足项目交货日期要求</p></div><!-- 统计卡片 --><el-row :gutter="20" class="card-container"><el-col :span="8"><div class="stat-card"><div class="stat-icon el-icon-s-order"></div><div class="stat-label">项目总数</div><div class="stat-value">{{ projects.length }}</div></div></el-col><el-col :span="8"><div class="stat-card"><div class="stat-icon el-icon-s-marketing"></div><div class="stat-label">生产线数量</div><div class="stat-value">{{ productionLines.length }}</div></div></el-col><el-col :span="8"><div class="stat-card"><div class="stat-icon el-icon-s-claim"></div><div class="stat-label">产能利用率</div><div class="stat-value" v-if="optimizationResult">{{ optimizationResult.overall_utilization.toFixed(1) }}%</div><div class="stat-value" v-else>0%</div></div></el-col></el-row><!-- 项目需求表格 --><!-- <div class="table-container"><div class="card-title"><h2><i class="el-icon-s-order"></i> 项目需求</h2></div><el-table :data="projects" stripe style="width: 100%"><el-table-column prop="id" label="ID" width="80"></el-table-column><el-table-column prop="name" label="项目名称"></el-table-column><el-table-column prop="demand" label="需求量"></el-table-column><el-table-column prop="due_date" label="交货日期"></el-table-column><el-table-column label="剩余天数"><template slot-scope="scope"><el-tag :type="getDaysRemainingType(scope.row.due_date)">{{ calculateDaysRemaining(scope.row.due_date) }}</el-tag></template></el-table-column><el-table-column label="项目颜色"><template slot-scope="scope"><el-color-pickerv-model="scope.row.color"show-alpha:predefine="predefineColors"></el-color-picker></template></el-table-column></el-table></div> --><!-- 生产线配置表格 --><!-- <div class="table-container"><div class="card-title"><h2><i class="el-icon-s-marketing"></i> 生产线配置</h2></div><el-table :data="productionLines" stripe style="width: 100%"><el-table-column prop="id" label="ID" width="80"></el-table-column><el-table-column prop="name" label="生产线名称"></el-table-column><el-table-columnprop="capacity_per_day"label="日产能"></el-table-column><el-table-column label="支持项目"><template slot-scope="scope"><el-tagv-for="projId in scope.row.supported_projects":key="projId"type="info"style="margin-right: 5px">{{ getProjectName(projId) }}</el-tag></template></el-table-column></el-table></div> --><!-- 需求-产线表格 --><el-row :gutter="20" class="card-container"><el-col :span="12"><div class="card-title"><h2><i class="el-icon-s-order"></i> 项目需求</h2></div><scalable-box :border="true" @changeBoxSize="changeBoxSize" :boxShadow="true"><el-table :data="projects" stripe style="width: 100%" :height="heightLeft"><el-table-column prop="id" label="ID" width="80"></el-table-column><el-table-column prop="name" label="项目名称"></el-table-column><el-table-column prop="demand" label="需求量"></el-table-column><el-table-column prop="due_date" label="交货日期"></el-table-column><el-table-column label="剩余天数"><template slot-scope="scope"><el-tag :type="getDaysRemainingType(scope.row.due_date)">{{ calculateDaysRemaining(scope.row.due_date) }}</el-tag></template></el-table-column><el-table-column label="项目颜色"><template slot-scope="scope"><el-color-pickerv-model="scope.row.color"show-alpha:predefine="predefineColors"></el-color-picker></template></el-table-column></el-table></scalable-box></el-col><el-col :span="12"><div class="card-title"><h2><i class="el-icon-s-marketing"></i> 生产线配置</h2></div><scalable-box :border="true" @changeBoxSize="changeBoxSize1" :boxShadow="true"><el-table :data="productionLines" stripe style="width: 100%" :height="heightRight"><el-table-column prop="id" label="ID" width="80"></el-table-column><el-table-column prop="name" label="生产线名称"></el-table-column><el-table-columnprop="capacity_per_day"label="日产能"></el-table-column><el-table-column label="支持项目"><template slot-scope="scope"><el-tagv-for="projId in scope.row.supported_projects":key="projId"type="info"style="margin-right: 5px">{{ getProjectName(projId) }}</el-tag></template></el-table-column></el-table></scalable-box></el-col></el-row><!-- 优化按钮 --><div class="optimize-button"><el-buttontype="primary"@click="optimizeSchedule":loading="optimizing"size="large"><i class="el-icon-s-promotion"></i>{{ optimizing ? "优化中..." : "开始排产优化" }}</el-button></div><!-- 优化结果 --><div class="result-container" v-if="optimizationResult"><h2><i class="el-icon-s-claim"></i> 排产优化结果</h2><!-- 总体利用率 --><el-alerttitle="总体产能利用率"type="info":description="`${optimizationResult.overall_utilization}%`"show-icon></el-alert><div class="progress-container"><el-progress:text-inside="true":stroke-width="20":percentage="optimizationResult.overall_utilization":color="getUtilizationProgressColor(optimizationResult.overall_utilization)"></el-progress></div><!-- 需求满足情况 --><h3>需求满足情况</h3><el-table:data="optimizationResult.demand_fulfillment"stripestyle="width: 100%"><el-table-columnprop="project_name"label="项目名称"align="center"></el-table-column><el-table-column prop="demand" label="需求量" align="center"></el-table-column><el-table-column prop="produced" label="已排产" align="center"><template slot-scope="scope">{{ scope.row.produced }}</template></el-table-column><el-table-column label="完成度" align="center"><template slot-scope="scope"><el-progress:text-inside="true":stroke-width="20":percentage="Math.min((scope.row.produced / scope.row.demand) * 100, 100)":status="scope.row.fulfilled ? 'success' : 'exception'"></el-progress></template></el-table-column><el-table-column label="状态" align="center"><template slot-scope="scope"><el-tag :type="scope.row.fulfilled ? 'success' : 'danger'">{{ scope.row.fulfilled ? "已满足" : "未满足" }}</el-tag></template></el-table-column></el-table><!-- 详细排产计划 --><h3>详细排产计划</h3><el-table:data="optimizationResult.schedule"stripestyle="width: 100%"><el-table-columnprop="line_name"label="生产线"fixedwidth="150"align="center"></el-table-column><el-table-columnv-for="date in dateRange":key="date+''":label="formatDate(date)"width="100"align="center"><template slot-scope="scope"><divv-for="daily in scope.row.daily_allocations":key="daily.date+''"><divv-if="formatDate(date) === formatDate1(daily.date)":class="['utilization-cell',getUtilizationClass(daily.capacity_utilization),]":title="getDailyAllocationTooltip(daily)":style="{fontSize:'10px',textAlign:'center',backgroundColor:getProjectBg(daily),}"><!-- daily.daily_total > 0 ? daily.daily_total.toFixed(0) : "" --><div v-for="xiangmu in daily.allocations" :key="xiangmu+''">{{daily.daily_total > 0 ? (xiangmu.project_name +'-'+ xiangmu.allocation) : ""}}</div></div></div></template></el-table-column></el-table></div><!-- 加载遮罩 --><div class="loading-overlay" v-if="optimizing"><el-card shadow="always" style="text-align: center; width: 300px"><i class="el-icon-loading" style="font-size: 30px"></i><p>正在优化排产计划,请稍候...</p><el-progress:percentage="progressPercent":stroke-width="15":text-inside="true"></el-progress></el-card></div><!-- 帮助按钮 --><el-buttonclass="help-button"type="primary"icon="el-icon-question"circle@click="showHelpDialog"></el-button></el-main></el-container><!-- 帮助对话框 --><el-dialogtitle="系统使用帮助":visible.sync="helpDialogVisible"width="60%"><h3>系统功能</h3><p>本项目排产优化系统可以帮助您将多个项目合理地分配到12条生产线上,最大化产能利用率并满足交货日期要求。</p><h3>使用步骤</h3><ol><li>查看"项目需求"部分,了解各项目的需求量和交货日期</li><li>查看"生产线配置"部分,了解各生产线的日产能和支持的项目类型</li><li>点击"开始排产优化"按钮,系统将自动计算最优排产方案</li><li>查看"排产优化结果",了解产能利用率和各项目完成情况</li></ol><h3>优化算法</h3><p>系统使用线性规划算法进行优化,目标函数是最大化总产能利用率,同时满足以下约束条件:</p><ul><li>每个项目的总产量必须满足需求</li><li>每个生产线每天的产能不能超过最大产能</li><li>项目生产必须在交货日期前完成</li></ul><span slot="footer" class="dialog-footer"><el-button type="primary" @click="helpDialogVisible = false">确 定</el-button></span></el-dialog></div>
</template><script>
// 导入请求方法
import Pagination from "../../components/Pagination";
//引入自定义组件缩放
import ScalableBox from '@/components/scalableBox/scalableBox.vue'
export default {data() {return {heightLeft:300,heightRight:300,projects: [{ id: 1, name: "智能手机", demand: 1200, due_date: "2025-10-05", color: "#ff4500",sort: 1 },{ id: 2, name: "平板电脑", demand: 1000, due_date: "2025-10-05", color: "#ff8c00",sort: 2 },{ id: 3, name: "智能手表", demand: 700, due_date: "2025-10-05", color: "#ffd700",sort: 1 },{ id: 4, name: "笔记本电脑", demand: 880, due_date: "2025-10-05", color: "#90ee90",sort: 2 },// { id: 5, name: "智能音箱", demand: 600, due_date: "2025-10-01", color: "#00ced1" },],productionLines: [{id: 1,name: "高速SMT线",capacity_per_day: 100,setup_time: 1,supported_projects: [1, 2],},{id: 2,name: "精密组装线",capacity_per_day: 120,setup_time: 1,supported_projects: [2, 4],},{id: 3,name: "小型设备线",capacity_per_day: 80,setup_time: 2,supported_projects: [3, 4],},{id: 4,name: "多功能线A",capacity_per_day: 100,setup_time: 1,supported_projects: [4,1],},// {//   id: 5,//   name: "多功能线B",//   capacity_per_day: 90,//   setup_time: 2,//   supported_projects: [5, 1],// },// {//   id: 6,//   name: "通用生产线",//   capacity_per_day: 110,//   setup_time: 1,//   supported_projects: [1, 2],// },// {//   id: 7,//   name: "专用设备线",//   capacity_per_day: 95,//   setup_time: 1,//   supported_projects: [2, 3],// },// {//   id: 8,//   name: "高产能线",//   capacity_per_day: 130,//   setup_time: 1,//   supported_projects: [3, 4],// },// {//   id: 9,//   name: "精密加工线",//   capacity_per_day: 70,//   setup_time: 2,//   supported_projects: [3, 4],// },// {//   id: 10,//   name: "快速响应线",//   capacity_per_day: 105,//   setup_time: 1,//   supported_projects: [1, 2, 5],// },// {//   id: 11,//   name: "重型设备线",//   capacity_per_day: 115,//   setup_time: 2,//   supported_projects: [2, 3, 4],// },// {//   id: 12,//   name: "柔性制造线",//   capacity_per_day: 125,//   setup_time: 1,//   supported_projects: [1, 3, 4, 5],// },],optimizing: false,optimizationResult: null,dateRange: [],helpDialogVisible: false,progressPercent: 0,progressInterval: null,predefineColors: [//默认颜色'#ff4500','#ff8c00','#ffd700','#90ee90','#00ced1','#1e90ff','#c71585','rgba(255, 69, 0, 0.68)','rgb(255, 120, 0)','hsv(51, 100, 98)','hsva(120, 40, 94, 0.5)','hsl(181, 100%, 37%)','hsla(209, 100%, 56%, 0.73)','#c7158577'],};},computed: {},// 注册组件components: {Pagination,ScalableBox},/*** 数据发生改变*/watch: {},/*** 创建完毕*/created() {},mounted() {// 生成日期范围 (接下来30天)const today = new Date();for (let i = 0; i < 30; i++) {const date = new Date();date.setDate(today.getDate() + i);this.dateRange.push(date);}},/*** 里面的方法只有被调用才会执行*/methods: {//获取项目显示的颜色getProjectBg(daily){console.log("输出显示颜色背景",daily)var temp = {}this.projects.map((pro,index) => {temp[pro.id] = pro.color})if(daily.allocations.length>0){var pro_id = daily.allocations[0].project_idconsole.log("输出显示颜色背景",daily,temp[pro_id])return temp[pro_id]}else{return '#fff'}},getProjectName(projectId) {const project = this.projects.find((p) => p.id === projectId);return project ? project.name : "未知项目";},calculateDaysRemaining(dueDate) {const today = new Date();const due = new Date(dueDate);const diffTime = due - today;return Math.ceil(diffTime / (1000 * 60 * 60 * 24));},getDaysRemainingType(dueDate) {const days = this.calculateDaysRemaining(dueDate);if (days > 14) return "success";if (days > 7) return "warning";return "danger";},optimizeSchedule() {this.optimizing = true;this.progressPercent = 0;// 模拟进度条this.progressInterval = setInterval(() => {if (this.progressPercent < 90) {this.progressPercent += 10;}}, 500);let formData = new FormData()formData.append("projects",JSON.stringify(this.projects))formData.append("productionLines",JSON.stringify(this.productionLines))// 发送数据到后端APIthis.$axios({method:"post",url:"http://localhost:8000/api/v1/schedule/optimize",data:formData,}).then((response) => {console.log("输出排产结果",response)if(response.data.status=="true"){console.log("输出排产结果",response)clearInterval(this.progressInterval);this.progressPercent = 100;setTimeout(() => {this.optimizationResult = response.data;this.optimizing = false;console.log("输出日期列表",this.dateRange)}, 200);}else{this.optimizing = false;this.$message.error(response.data.msg);}}).catch((error) => {clearInterval(this.progressInterval);this.optimizing = false;this.$message.error(// "排产优化失败: " + (error.response?.data?.error || "服务器错误"));});},formatDate(date) {var time = new Date(date).toLocaleDateString("zh-CN", {month: "2-digit",day: "2-digit",})// console.log("输出时间转换前后结果",date,time)return time;},//格式化接口返回的日期formatDate1(date){var temp = date.split("-")var time = temp[1]+"/"+temp[2]return time;},getUtilizationClass(utilization) {// if (utilization >= 90) return "utilization-high";// if (utilization >= 70) return "utilization-medium";// return "utilization-low";},getUtilizationProgressColor(utilization) {if (utilization >= 90) return "#67c23a";if (utilization >= 70) return "#e6a23c";return "#f56c6c";},getDailyAllocationTooltip(daily) {if (daily.is_setup) return `切换时间: ${this.formatNumber(daily.setup_time)}`;if (daily.allocations.length === 0) return "无生产安排";let tooltip = `利用率: ${daily.capacity_utilization}%\n`;daily.allocations.forEach((alloc) => {tooltip += `${alloc.project_name}: ${alloc.allocation}\n`;});return tooltip;},showHelpDialog() {this.helpDialogVisible = true;},changeBoxSize(res){var _that = thisconsole.log("输出表格的缩放结果,",res)if(res.type=='in'){_that.heightLeft = res.height}else{_that.heightLeft = 300}},changeBoxSize1(res){var _that = thisconsole.log("输出表格的缩放结果,",res)if(res.type=='in'){_that.heightRight = res.height}else{_that.heightRight = 300}},},
};
</script><style scoped>
.app{margin-left: 15px;
}
.app-container {padding: 20px;
}
.header {background: linear-gradient(135deg, #409eff 0%, #64b5ff 100%);color: white;padding: 15px 20px;margin-bottom: 20px;border-radius: 4px;/* box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); */box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
.card-container {margin-bottom: 20px;
}
.card-title {display: flex;justify-content: space-between;align-items: center;
}
.stat-card {text-align: center;padding: 20px;border-radius: 4px;background: white;box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
.stat-value {font-size: 24px;font-weight: bold;margin: 10px 0;
}
.stat-icon {font-size: 40px;margin-bottom: 10px;
}
.table-container {background: white;border-radius: 4px;box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);padding: 20px;margin-bottom: 20px;
}
.utilization-high {background-color: #f0f9eb !important;color: #67c23a !important;
}
.utilization-medium {background-color: #fdf6ec !important;color: #e6a23c !important;
}
.utilization-low {background-color: #fef0f0 !important;color: #f56c6c !important;
}
.optimize-button {text-align: center;margin: 20px 0;
}
.result-container {background: white;border-radius: 4px;box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);padding: 20px;margin-top: 20px;
}
.progress-container {margin: 10px 0;
}
.loading-overlay {position: fixed;top: 0;left: 0;right: 0;bottom: 0;background-color: rgba(255, 255, 255, 0.8);display: flex;justify-content: center;align-items: center;z-index: 9999;
}
.help-button {position: fixed;right: 20px;bottom: 20px;z-index: 1000;
}
</style>

效果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

http://www.dtcms.com/a/406084.html

相关文章:

  • 【开题答辩全过程】以 “辛巴克餐饮”小程序为例,包含答辩的问题和答案
  • bazel编译
  • 7、微服务中 DTO、VO、PO、BO 的设计规范
  • 建工之家祁阳seo
  • 自动跳转手机网站代码在线生成网站地图
  • 公司网站建设 邮箱潍坊网站开发
  • Redisson和Zookeeper实现的分布式锁
  • 基于51单片机宠物喂食系统设计
  • 游戏外挂和游戏逆向的关系
  • 【Vue3 ✨】Vue3 入门之旅 · 第九篇:Vue3 插槽机制
  • linux系统(ubuntu)安装mysql8详细教程
  • web微服务介绍
  • MongoDB副本集
  • 408操作系统复习笔记——关于IO层次结构与执行流程-冲刺120+
  • 微信认证 网站wordpress音乐插件歌词
  • Ansible Playbook
  • ARM—时钟(CLOCK)—定时器(EPIT / GPT)
  • 基于IMX6ULL的时钟,定时器(EPIT,GPT)
  • HCIE 的云计算方向容易考过吗?该怎么准备考试?
  • 凤山县住房和城乡建设局网站wordpress中国能用吗
  • 从 EFI 到 GPT:深入理解现代计算机启动与磁盘分区技术
  • 计算机网络的性能指标和体系结构
  • 性能怪兽:GPT-5-Codex三大核心进化,重新定义AI编程
  • 网络通信协议全解析:HTTP/UDP/TCP核心要点
  • 郴州网站建设软件定制开发平台e盘网站建设
  • 在Unix/Linux中bash/sh/source以及./执行脚本的区别
  • 宜春公司做网站双语网站建设定制开发
  • Spring Boot 应用启动组件加载顺序与优先级详解
  • Spring Boot 事件发布与监听 观察者模式的实际应用
  • Sui Stack Messaging SDK:为 Web3 打造可编程通信