廖井涛
6 小时以前 f7a2fcdda7f1120498c5c5f75c5a99955fc54b43
north-glass-erp/northglass-erp/src/views/pp/glassOptimize/page/Compute.vue
@@ -1,5 +1,5 @@
<script setup>
import {reactive, ref, watch} from "vue";
import {onMounted, reactive, ref, watch, inject} from "vue";
import {useI18n} from "vue-i18n";
import {Platform, Search, SuccessFilled} from "@element-plus/icons-vue";
import useUserInfoStore from "@/stores/userInfo";
@@ -16,30 +16,101 @@
//获取工程号
const props = defineProps({
  projectNo : String,
  project: null,
  state:null,
  data: {
    type: Array,
    default: () => []
  }
});
// 定义响应式数据,用于绑定工程号输入框的值
const inputValue = ref(props.projectNo);
// 注入 projectNo
const injectedProjectNo = inject('projectNo', null);
const selectOptions = [
  {
    value: '0',
    label: '默认'
  },
  {
    value: '1',
    label: '优先竖排'
  },
  {
    value: '2',
    label: '优先横排'
  }
]
// 定义混排等级
const optionVal = ref('')
const optionVal = ref(50)
// 定义装载率
const percentage1 = ref(80)
const percentage1 = ref(50)
const percentage2 = ref(50)
// 定义其他表单数据
const furnaceWidth = ref('') // 炉宽
const furnaceLength = ref('') // 炉长
const heatingTime = ref('') // 加热时间
const heatingTime = ref('') // 钢化加热时间
const rotateMode = ref({value: '0', label: '默认'}) // 钢化旋转模式
const spacingLong = ref('') // 长轴间隔
const spacingWidth = ref('') // 宽轴间隔
const quantity = ref('') // 工程片数
// 定义响应式数据,用于绑定工程号输入框的值
let inputValue=ref(null)
if(props.project!==undefined){
  inputValue = ref(props.project.projectNumber);
  quantity.value = props.project.quantity
} else if(props.projectNo) {
  inputValue.value = props.projectNo;
} else if(injectedProjectNo) {
  // 从 provide/inject 获取 projectNo
  inputValue.value = injectedProjectNo.value || injectedProjectNo;
}else {
  // 从 localStorage 获取
  const storedProjectNo = localStorage.getItem('currentProjectNo');
  if (storedProjectNo) {
    inputValue.value = storedProjectNo;
  }
}
// 添加 watch 监听注入的 projectNo
watch(() => injectedProjectNo, (newVal) => {
  if(newVal && !inputValue.value) {
    inputValue.value = newVal.value || newVal;
  }
}, { immediate: true });
const fetchSettings = async (username) => {
  try {
    const response = await request.post(`/glassOptimize/selectOptimizeParms/${username}`);
    if (response.code == 200) {
      if (!response.data) {
        console.error('响应数据为空');
        return;
      }
      const parsedData = JSON.parse(response.data);
      if (parsedData.tempering) {
        furnaceLength.value = parsedData.tempering.furnaceLength;
        furnaceWidth.value = parsedData.tempering.furnaceWidth;
        spacingWidth.value=parsedData.tempering.xAxisInterval;
        spacingLong.value=parsedData.tempering.yAxisInterval;
        heatingTime.value=parsedData.tempering.temperingTime;
      }
    } else {
      console.error('请求失败,状态码:', response.code);
    }
  } catch (error) {
    console.error('请求发生错误:', error);
  }
};
fetchSettings(username);
const gridOptions = reactive({
  height: '100%',
@@ -86,23 +157,40 @@
  ],//表头参数
  data: null,//表格数据
  toolbarConfig: {
    buttons: [],
    slots: {
      buttons: "toolbar_buttons"
    },
  },
})
onMounted(async() => {
  await firstLoading()
})
onMounted(async () => {
  if (props.project && props.project.projectNumber) {
    await fetchProjectData(props.project.projectNumber);
  }
});
const firstLoading = async() => {
    request.post(`/glassOptimize/selectOptimizeParms/${username}`).then((res) => {
      if (res.code == "200") {
        const parsedData = JSON.parse(res.data);
          furnaceWidth.value=parsedData.tempering.furnaceWidth
          furnaceLength.value=parsedData.tempering.furnaceLength
          spacingLong.value=parsedData.tempering.xAxisInterval
          spacingWidth.value=parsedData.tempering.yAxisInterval
      } else {
        ElMessage.warning(res.msg)
      }
    })
}
// 监听父组件传递的数据变化
watch(() => props.data, (newValue) => {
  if (newValue) {
    // 处理数据并更新表格
    const processData = newValue.data[0];
    console.log('Processed Data:', processData);
    const processedData = [
      {
        id: "1",
@@ -114,7 +202,6 @@
      }
    ];
    gridOptions.data = processedData;
    console.log(gridOptions.data)
  } else {
    console.error("数据格式不正确或为空");
    gridOptions.data = [];
@@ -122,61 +209,144 @@
})
const options = [
  {
    value: '0',
    label: '不混排',
  },
  {
    value: '1',
    label: '轻度混排',
  },
  {
    value: '2',
    label: '中度混排',
  },
  {
    value: '3',
    label: '高度混排',
  },
]
// let emit = defineEmits(['fetch-data']);
let emit = defineEmits(['fetch-data', 'sendData'])
const inputValues = {
  project_no:inputValue,
    glass_thickness:"",
    glass_type:"",
    chaos_pct: optionVal.value*0.01,//混排等级
    cage_free:percentage2.value*0.01,//理片龙空闲度
    tempering_time:heatingTime.value,//钢化加热时间
    heat_mode: 0,//模式选择
    max_load_pct: percentage1.value*0.01,//最大装载率
    max_area: 0,//最大面积
    max_qty:0,//最大片数
    load_width:furnaceWidth,
    load_length: furnaceLength,
  x_space: spacingWidth,
  y_space: spacingLong,
const emit = defineEmits(['fetch-data', 'sendData', 'simulate-click']);
const inputValues =  reactive({
  project_no:inputValue.value,
  glass_thickness:"",
  glass_type:"",
  chaos_pct: optionVal.value*0.01,//混排等级
  cage_free:percentage2.value*0.01,//理片龙空闲度
  tempering_time:heatingTime.value,//钢化加热时间
  heat_mode: 0,//模式选择
  max_load_pct: percentage1.value*0.01,//最大装载率
  max_area: 0,//最大面积
  max_qty:0,//最大片数
  load_width:null,
  load_length: null,
  x_space: null,
  y_space: null,
  load_rate: null,
  furnaces_qty:"",
  rotate_mode:0,
  polys_allow_rotate: 0,
  process_cards:[]
});
const fetchProjectData = async (projectNumber) => {
  try {
    const res = await request.post(`/glassOptimize/getProjectByProjectNo/${projectNumber}`);
    if (Number(res.code) === 200 && res.data && res.data.data && res.data.data.length > 0) {
      const projectData = res.data.data[0];
      // 更新 inputValues
      inputValues.glass_thickness = projectData.glass_thickness || '';
      inputValues.glass_type = projectData.glass_type || '';
      console.log('更新后的 inputValues:', inputValues);
    } else {
      ElMessage.warning('未找到项目信息或数据格式不正确');
    }
  } catch (error) {
    console.error('请求失败:', error);
    ElMessage.error('获取项目信息失败');
  }
};
const handleSearchClick = () => {
  const projectNumber = inputValue.value;
  if (!projectNumber) {
    ElMessage.warning('请输入工程号');
    return;
  }
  // 通知父组件更新(可选)
  emit('fetch-data', projectNumber);
  // 子组件自己调用接口更新数据
  fetchProjectData(projectNumber);
};
const handleSimulationClick = async () => {
  try {
    const projectNumber = inputValue.value;
    if (!projectNumber) {
      ElMessage.warning('请输入工程号');
      return;
    }
    const res = await request.post(`/glassOptimize/getProjectState/${projectNumber}`);
    if (Number(res.code) === 200) {
      const projectData = res.data.data;
      // 检查 tempering_state 状态
      if (projectData.tempering_state === 1) {
        // 如果已完成模拟计算,提示用户并阻止继续执行
        ElMessage.warning('已完成模拟计算,不允许重复计算');
        return;
      }
    } else {
      ElMessage.warning(res.msg);
      return;
    }
  } catch (error) {
    ElMessage.error('检查工程状态失败,请稍后重试');
    console.error('检查工程状态失败:', error);
    return;
  }
  inputValues.project_no = inputValue.value;
  inputValues.chaos_pct = optionVal.value * 0.01; // 混排等级
  inputValues.cage_free = percentage2.value * 0.01; // 理片龙空闲度
  inputValues.heat_mode = 0; // 模式选择(默认值)
  inputValues.max_load_pct = percentage1.value * 0.01; // 最大装载率
  inputValues.max_area = 0; // 最大面积(默认值)
  inputValues.max_qty = 0; // 最大片数(默认值)
  inputValues.load_width = furnaceWidth.value;
  inputValues.load_length = furnaceLength.value;
  inputValues.x_space = spacingWidth.value;
  inputValues.y_space = spacingLong.value;
  inputValues.polys_allow_rotate = parseInt(rotateMode.value.value);
  inputValues.tempering_time = heatingTime.value || inputValues.tempering_time || 0;
  const sendData = {
    project_no: inputValues.project_no,
    glass_thickness: inputValues.glass_thickness,
    glass_type: inputValues.glass_type,
    chaos_pct: inputValues.chaos_pct, // 混排等级
    cage_free: inputValues.cage_free, // 理片龙空闲度
    tempering_time: inputValues.tempering_time,
    heat_mode: inputValues.heat_mode, // 模式选择
    max_load_pct: inputValues.max_load_pct, // 最大装载率
    max_area: inputValues.max_area, // 最大面积
    max_qty: inputValues.max_qty, // 最大片数
    load_width: inputValues.load_width,
    load_length: inputValues.load_length,
    x_space: inputValues.x_space,
    y_space: inputValues.y_space,
    load_rate: inputValues.load_rate, // 装载率(可能为空)
    furnaces_qty: inputValues.furnaces_qty, // 炉子数量(可能为空)
    rotate_mode: inputValues.rotate_mode, // 钢化旋转模式(可能为空)
    polys_allow_rotate: inputValues.polys_allow_rotate,
    process_cards: inputValues.process_cards || [] // 流程卡列表(默认空数组)
  };
  // 发送所有数据到父组件
  emit('sendData', sendData);
      inputValues.project_no = inputValue.value;
  emit('sendData', {
    ...inputValues
  });
const handleSearchClick = () => {
  // 通过 $emit 触发自定义事件,将工程号传递给父组件,由父组件去调用接口获取数据
  emit('fetch-data', inputValue.value);
};
const handleSimulationClick = () => {
  })
  // 触发父组件的 simulate-click 事件
  emit('simulate-click');
};
@@ -184,137 +354,178 @@
const handleSave = () => {
  if (props.data) {
  console.log('当前保存的数据:', props.data);
  if(props.state==3){
    let projectData = ref({
      projectdetail: props.data,
      userName : username,
      inputValues:inputValues
    })
    request.post(`/glassOptimize/simulationSave`, projectData.value).then((res) => {
      if (res.code == 200 && res.data === true) {
        ElMessage.success(t('basicData.msg.saveSuccess'))
      } else {
        ElMessage.warning(res.msg)
      }
    })
      let projectData = ref({
        inputValues:inputValues,
        userName : username,
        state:props.state
      })
      request.post(`/glassOptimize/simulationSave`, projectData.value).then((res) => {
        if (res.code == 200 && res.data === true) {
          ElMessage.success(t('basicData.msg.saveSuccess'))
        } else {
          ElMessage.warning(res.msg)
        }
      })
  }else{
    if (props.data) {
      let projectData = ref({
        projectdetail: props.data.data[0].glass_details,
        ratioResult: props.data.data[0].ratioResult,
        rackinfos: props.data.data[0].rackinfos,
        resultSum: props.data.data[0].resultSum,
        guidance: props.data.data[0].guidance,
        userName : username,
        inputValues:inputValues,
        state:props.state
      })
      request.post(`/glassOptimize/simulationSave`, projectData.value).then((res) => {
        if (res.code == 200 && res.data === true) {
          ElMessage.success(t('basicData.msg.saveSuccess'))
        } else {
          ElMessage.warning(res.msg)
        }
      })
    }
  }
}
</script>
<template>
  <div style="width: 100%;height: 100%">
<div style="width: 100%;height: 100%">
    <!--模拟计算表头-->
    <div id="title" style="margin-top: -10px">
  <span>
    工程编号
    <el-input style="width:150px;margin-left: 30px" clearable v-model="inputValue" placeholder="请输入工程号"></el-input>
    <el-button
        type="primary"
        :icon="Search"
        style="margin-left: 20px"
        @click="handleSearchClick"
    >{{ $t('basicData.search') }}
    </el-button>
  </span>
  <span style="float: right ; margin-right: 120px">
    工程混排等级
      <el-select
          placeholder="选择混排等级"
          style="margin-left:10px; width: 200px; "
          ref="getSelect"
          v-model="optionVal"
          clearable
          class="m-2"
          @change="getWorkOrder"
      >
        <el-option
            v-for="item in options"
            :key="item.value"
            :label="item.label"
            :value="item.value"
        />
      </el-select>
    <el-button type="primary" style="margin-left: 10px" :icon="Platform"  @click="handleSimulationClick">模拟计算</el-button>
    <el-button type="primary" style="margin-left: 20px" :icon="SuccessFilled"  @click="handleSave">保存</el-button>
  </span><br>
  <div class="demo-progress" style="margin-top: 5px">
    <div style="display: flex; align-items: center">
      <span>钢化最大装载</span>
      <!-- 进度条设置 -->
      <el-slider
          style="max-width: 400px; flex: 1; margin-left: 10px"
          v-model="percentage1"
          :min="0"
          :max="100"
          :step="1"/>
      <span style="margin-left: 20px ; width: 30px;">{{ percentage1 }}%</span>
      <span style="float: right ; margin-left: 150px;">
            宽轴间隔 <vxe-input size="small" class="input" clearable v-model="spacingWidth"></vxe-input>
            炉宽(mm) <vxe-input size="small" class="input" clearable v-model="furnaceWidth"></vxe-input>
      </span>
<div id="title" style="margin-top: -10px;height: 50%">
  <div style="display: flex">
    <div style="width: 850px">
      工程编号
      <el-input style="width:150px;margin-left: 30px" clearable v-model="inputValue" placeholder="请输入工程号"></el-input>
      <el-button
          type="primary"
          :icon="Search"
          style="margin-left: 20px"
          @click="handleSearchClick"
      >{{ $t('basicData.search') }}
      </el-button>
    </div>
  </div>
  <br>
  <div class="demo-progress" style="margin-top: -10px">
    <div style="display: flex; align-items: center">
      <span>理片笼空闲度</span>
      <!-- 进度条设置 -->
    <div style="display: flex ; width: 700px;align-items: center;">
      <span>工程混排等级</span>
      <el-slider
          style="max-width: 400px; flex: 1; margin-left: 10px"
          v-model="percentage2"
          style="max-width: 200px; flex: 1; margin-left: 10px"
          v-model="optionVal"
          :min="0"
          :max="100"
          :step="1"/>
      <span style="margin-left: 20px ; width: 30px;">{{ percentage2 }}%</span>
      <span style="float: right ; margin-left: 150px;">
              加热时间(秒)<vxe-input size="small" class="input" clearable v-model="heatingTime"></vxe-input>
              长轴间隔 <vxe-input size="small" class="input" clearable v-model="spacingLong"></vxe-input>
              炉长(mm) <vxe-input size="small" class="input" clearable v-model="furnaceLength"></vxe-input>
      </span>
      <span style="margin-left: 20px ; width: 35px;">{{ optionVal }}%</span>
      <el-button type="primary" style="margin-left: 10px" :icon="Platform"  @click="handleSimulationClick">模拟计算</el-button>
      <el-button type="primary" style="margin-left: 20px" :icon="SuccessFilled"  @click="handleSave">保存</el-button>
    </div>
  </div><br>
  <div style="display:flex">
    <div class="demo-progress" style="margin-top: 5px;width: 50%">
      <div style="display: flex; align-items: center">
        <span>钢化最大装载</span>
        <!-- 进度条设置 -->
        <el-slider
            style="max-width: 400px; flex: 1; margin-left: 10px"
            v-model="percentage1"
            :min="0"
            :max="100"
            :step="1"/>
        <span style="margin-left: 20px ; width: 35px;">{{ percentage1 }}%</span>
        <!--      <span style="float: right ; margin-left: 150px;">
                    工程片数 <vxe-input size="small" disabled class="input"  v-model="quantity"></vxe-input>
                    宽轴间隔 <vxe-input size="small" class="input" clearable v-model="spacingWidth"></vxe-input>
                    炉宽(mm) <vxe-input size="small" class="input" clearable v-model="furnaceWidth"></vxe-input>
              </span>-->
      </div>
      <div style="display: flex; align-items: center">
        <span>理片笼空闲度</span>
        <!-- 进度条设置 -->
        <el-slider
            style="max-width: 400px; flex: 1; margin-left: 10px"
            v-model="percentage2"
            :min="0"
            :max="100"
            :step="1"/>
        <span style="margin-left: 20px ; width: 35px;">{{ percentage2 }}%</span>
      </div>
    </div>
    <div class="demo-progress" style="display: flex;font-size: 15px">
      <div style="height: 35px;line-height: 35px">
        <div>工程片数 <el-input size="small" disabled class="input"  v-model="quantity"></el-input></div>
        <div>钢化旋转方式
          <el-select style="width: 100px;height: 30px" v-model="rotateMode">
            <el-option
                v-for="item in selectOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
            />
          </el-select>
        </div>
      </div>
      <div style="margin-left: 15px;height: 35px;line-height: 35px">
        <div>宽轴间隔 <el-input size="small" class="input" clearable v-model="spacingWidth"></el-input></div>
        <div>长轴间隔 <vxe-input size="small" class="input" clearable v-model="spacingLong"></vxe-input></div>
      </div>
      <div style="margin-left: 15px;height: 35px;line-height: 35px">
        <div>炉宽(mm) <el-input size="small" class="input" clearable v-model="furnaceWidth"></el-input></div>
        <div>炉长(mm) <vxe-input size="small" class="input" clearable v-model="furnaceLength"></vxe-input></div>
      </div>
    </div>
  </div>
</div>
    <vxe-grid
        size="small"
        @filter-change="filterChanged"
        height="100%"
        class="mytable-scrollbar"
        ref="xGrid"
        v-bind="gridOptions"
        v-on="gridEvents"
    >
      <template #num2_filter="{ column, $panel }">
        <div>
          <div v-for="(option, index) in column.filters" :key="index">
            <vxe-select v-model="option.data" :placeholder="$t('processCard.pleaseSelect')"
                        @change="changeFilterEvent($event, option, $panel)">
              <vxe-option value="0" :label="$t('basicData.unchecked')"></vxe-option>
              <vxe-option value="1" :label="$t('basicData.selected')"></vxe-option>
            </vxe-select>
          </div>
<div style="height: 50%">
  <vxe-grid
      size="small"
      @filter-change="filterChanged"
      height="50%"
      class="mytable-scrollbar"
      ref="xGrid"
      v-bind="gridOptions"
      v-on="gridEvents"
  >
    <template #num2_filter="{ column, $panel }">
      <div>
        <div v-for="(option, index) in column.filters" :key="index">
          <vxe-select v-model="option.data" :placeholder="$t('processCard.pleaseSelect')"
                      @change="changeFilterEvent($event, option, $panel)">
            <vxe-option value="0" :label="$t('basicData.unchecked')"></vxe-option>
            <vxe-option value="1" :label="$t('basicData.selected')"></vxe-option>
          </vxe-select>
        </div>
      </template>
      </div>
    </template>
      <template #num1_filter="{ column, $panel }">
        <div>
          <div v-for="(option, index) in column.filters" :key="index">
            <input
                type="type"
                v-model="option.data"
                @keyup.enter.native="$panel.confirmFilter()"
                @input="changeFilterEvent($event, option, $panel)"/>
          </div>
    <template #num1_filter="{ column, $panel }">
      <div>
        <div v-for="(option, index) in column.filters" :key="index">
          <input
              type="type"
              v-model="option.data"
              @keyup.enter.native="$panel.confirmFilter()"
              @input="changeFilterEvent($event, option, $panel)"/>
        </div>
      </template>
    </vxe-grid>
      </div>
    </template>
  </vxe-grid>
</div>
  </div>
</template>
@@ -322,7 +533,7 @@
.input {
  width: 80px;
  margin-left: 20px;
  height: 30px;
}
</style>