zhanghl
2025-04-25 8c613f17337c8e7fc68a12d02cafa05d0dca81ba
Merge remote-tracking branch 'origin/dev' into dev

# Conflicts:
# src/views/mainPlan/platePlanList/index.vue
已修改4个文件
已添加2个文件
820 ■■■■ 文件已修改
.env.development 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/mainPlan/gasPlanning.js 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/HxlhTable/index.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mainPlan/gasPlanning/index.vue 578 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mainPlan/gasProduceStatics/index.vue 209 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
vite.config.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.env.development
@@ -9,4 +9,5 @@
# æ ‡è¯†æœ¬åœ°å¼€å‘服务,用于GateWay转发到本地服务
# é…åˆåŽç«¯æœåŠ¡
# VITE_APP_LOCAL = 'int'
VITE_APP_LOCAL = 'zhl'
# VITE_APP_LOCAL = 'zhl'
VITE_APP_LOCAL = 'hjy'
src/api/mainPlan/gasPlanning.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
import request from '@/utils/request'
// æ°”体管路产能规划列表
export function listGasPlan(query) {
  return request({
    url: '/aps/gasPipelineCapacityPlan/list',
    method: 'get',
    params: query
  })
}
// æŸ¥è¯¢é’£é‡‘计划管理详细
export function getGasPlanSave(data) {
  return request({
    url: '/aps/gasPipelineCapacityPlan',
    method: 'post',
    data: data
  })
}
src/components/HxlhTable/index.vue
@@ -32,6 +32,7 @@
      :tree-config="treeConfig"
      :row-style="rowStyle"
      :virtualYConfig="virtualYConfig"
      :edit-config="editConfig"
      @sort-change="sortChange"
      @page-change="pagerChange"
      @form-submit="findList"
@@ -181,6 +182,12 @@
    default: () => {
      return {};
    },
  },
  editConfig:{
    type: Object,
    default: () => {
      return {};
    },
  }
});
src/views/mainPlan/gasPlanning/index.vue
@@ -1,89 +1,501 @@
<template>
    <HxlhTable
      style="width: 100%"
      :columns="columns"
      :data="gasPlanList"
      :loading="loading"
      :height="height"
  <div class="app-container">
    <el-form
      class="responsive-form"
      :model="queryParams"
      ref="queryRef"
      :inline="true"
      label-width="68px"
    >
    </HxlhTable>
      <el-row type="flex" justify="left">
        <el-col :span="6">
          <el-form-item label="选择月份" prop="description">
            <el-date-picker
              clearable
              v-model="queryParams.date"
              type="month"
              value-format="YYYY-MM"
              placeholder="选择月份"
            >
            </el-date-picker>
          </el-form-item>
        </el-col>
        <el-col :span="18" style="text-align: right">
          <el-form-item class="column-with-margin">
            <el-button type="primary" icon="Search" @click="handleQuery"
              >查询</el-button
            >
            <el-button icon="Refresh" @click="resetQuery">重置</el-button>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <div class="box_container">
      <div class="title_text">管路规划产能</div>
      <div class="tabel_container">
        <!-- <HxlhTable
          style="width: 100%"
          :columns="columns"
          :data="routePlanList"
          :loading="loading"
          :height="height"
          :editConfig="editConfig"
        >
          <template #edit_role="{ row }">
            <vxe-select
              v-model="row.dayProduceType"
              :options="dayProduceTypeOptions"
              filterable
            ></vxe-select>
          </template>
        </HxlhTable> -->
        <vxe-table
          border
          ref="xTable"
          show-overflow
          :loading="loading"
          :height="height"
          :edit-config="{ mode: 'row', trigger: 'click', showStatus: true }"
          :data="routePlanList"
          @cell-click="cellClickEvent"
        >
          <vxe-column field="processName" title="标准工序名称" min-width="150">
          </vxe-column>
          <!--             :edit-render="sexEditRender" -->
          <vxe-column
            field="dayProduceType"
            title="日产出类型"
            min-width="160"
            :edit-render="{ }"
          >
            <template #edit="{ row }">
              <vxe-select v-model="row.dayProduceType" :options="dayProduceTypeOptions"></vxe-select>
            </template>
            <template #default="{ row }">
              <span>{{ formatTypeLabel([row.dayProduceType]) }}</span>
            </template>
          </vxe-column>
          <vxe-column
            field="dayProduceNum"
            title="日产出数量"
            min-width="200"
            :edit-render="{ autoFocus: 'input' }"
          >
            <template #edit="{ row }">
              <el-input-number
                v-model="row.dayProduceNum"
                size="mini"
              />
            </template>
          </vxe-column>
          <vxe-column
            field="dayProduceUnit"
            title="日产出单位"
            min-width="200"
            :edit-render="{ autoFocus: 'input' }"
          >
            <template #edit="{ row }">
              <el-input v-model="row.dayProduceUnit" />
            </template>
          </vxe-column>
          <vxe-column
            field="personnelNumber"
            title="人员数量"
            min-width="200"
            :edit-render="{ autoFocus: 'input' }"
          >
            <template #edit="{ row }">
              <el-input-number
                v-model="row.personnelNumber"
              />
            </template>
          </vxe-column>
          <vxe-column
            field="dayProduceAllNum"
            title="日产出总数量"
            min-width="200"
            :edit-render="{ autoFocus: 'input' }"
          >
            <template #edit="{ row }">
              <el-input-number
                v-model="row.dayProduceAllNum"
                disabled
              />
            </template>
          </vxe-column>
          <vxe-column
            field="days"
            title="天数"
            min-width="200"
            :edit-render="{ autoFocus: 'input' }"
          >
            <template #edit="{ row }">
              <el-input-number v-model="row.days" />
            </template>
          </vxe-column>
          <vxe-column
            field="monthProduceAllNum"
            title="月产出数量"
            min-width="200"
            :edit-render="{ autoFocus: 'input' }"
          >
            <template #edit="{ row }">
              <el-input-number v-model="row.monthProduceAllNum" disabled/>
            </template>
          </vxe-column>
          <vxe-column
            field="remark"
            title="备注"
            min-width="200"
            :edit-render="{ autoFocus: 'input' }"
          >
            <template #edit="{ row }">
              <el-input type="textarea" v-model="row.remark" />
            </template>
          </vxe-column>
        </vxe-table>
      </div>
    </div>
    <div class="box_container">
      <div class="title_text">气体规划产能</div>
      <div class="tabel_container">
        <!-- <HxlhTable
          style="width: 100%"
          :columns="columns"
          :data="gasPlanList"
          :loading="loading"
          :height="height"
        >
        </HxlhTable> -->
         <vxe-table
          border
          ref="xTable"
          show-overflow
          :loading="loading"
          :height="height"
          :edit-config="{ mode: 'row', trigger: 'click', showStatus: true }"
          :data="gasPlanList"
          @cell-click="cellClickEvent"
        >
          <vxe-column field="processName" title="标准工序名称" min-width="150">
          </vxe-column>
          <!--             :edit-render="sexEditRender" -->
          <vxe-column
            field="dayProduceType"
            title="日产出类型"
            min-width="160"
            :edit-render="{ }"
          >
            <template #edit="{ row }">
              <vxe-select v-model="row.dayProduceType" :options="dayProduceTypeOptions"></vxe-select>
            </template>
            <template #default="{ row }">
              <span>{{ formatTypeLabel([row.dayProduceType]) }}</span>
            </template>
          </vxe-column>
          <vxe-column
            field="dayProduceNum"
            title="日产出数量"
            min-width="200"
            :edit-render="{ autoFocus: 'input' }"
          >
            <template #edit="{ row }">
              <el-input-number
                v-model="row.dayProduceNum"
                size="mini"
              />
            </template>
          </vxe-column>
          <vxe-column
            field="dayProduceUnit"
            title="日产出单位"
            min-width="200"
            :edit-render="{ autoFocus: 'input' }"
          >
            <template #edit="{ row }">
              <el-input v-model="row.dayProduceUnit" />
            </template>
          </vxe-column>
          <vxe-column
            field="personnelNumber"
            title="人员数量"
            min-width="200"
            :edit-render="{ autoFocus: 'input' }"
          >
            <template #edit="{ row }">
              <el-input-number
                v-model="row.personnelNumber"
              />
            </template>
          </vxe-column>
          <vxe-column
            field="dayProduceAllNum"
            title="日产出总数量"
            min-width="200"
            :edit-render="{ autoFocus: 'input' }"
          >
            <template #edit="{ row }">
              <el-input-number
                v-model="row.dayProduceAllNum"
              />
            </template>
          </vxe-column>
          <vxe-column
            field="days"
            title="天数"
            min-width="200"
            :edit-render="{ autoFocus: 'input' }"
          >
            <template #edit="{ row }">
              <el-input-number v-model="row.days"  />
            </template>
          </vxe-column>
          <vxe-column
            field="monthProduceAllNum"
            title="月产出数量"
            min-width="200"
            :edit-render="{ autoFocus: 'input' }"
          >
            <template #edit="{ row }">
              <el-input-number v-model="row.monthProduceAllNum" />
            </template>
          </vxe-column>
          <vxe-column
            field="remark"
            title="备注"
            min-width="200"
            :edit-render="{ autoFocus: 'input' }"
          >
            <template #edit="{ row }">
              <el-input type="textarea" v-model="row.remark" />
            </template>
          </vxe-column>
        </vxe-table>
        <div class="btn_center">
          <el-button type="primary" @click="handleSave">保存</el-button>
        </div>
      </div>
    </div>
  </div>
  <!--  -->
</template>
<script setup>
const height = ref(document.documentElement.clientHeight - 270 + "px;");
const loading = ref(true);
import HxlhTable from "@/components/HxlhTable";
import { ElMessage } from "element-plus";
import { listGasPlan, getGasPlanSave } from "@/api/mainPlan/gasPlanning";
const height = ref(document.documentElement.clientHeight - 400 + "px;");
const loading = ref(false);
const data = reactive({
  queryParams: {
    date: "",
  },
});
const { queryParams } = toRefs(data);
const gasPlanList = ref([]);
// è¡¨æ ¼é…ç½®
const columns = ref([
  {
    title: "主件料号",
    field: "mainPartNumber",
    width: 150,
  },
  {
    title: "业务类型",
    field: "businessType",
  },
  {
    title: "单据号",
    field: "documentNumber",
    width: 100,
  },
  {
    title: "当前工序号",
    field: "currentProcessNumberTxt",
    width: 100,
  },
  {
    title: "需求分类",
    field: "requirementType",
    width: 80,
  },
  {
    title: "单据状态",
    field: "documentStatus",
    width: 80,
  },
  {
    title: "当前工序",
    field: "workCenter",
    width: 80,
  },
  {
    title: "计划开工日",
    field: "processPlanStartDaytxt",
    width: 140,
    type: "html",
  },
  {
    title: "料号",
    field: "itemNumber",
    width: 140,
    type: "html",
  },
  {
    title: "图号",
    field: "drawingNo",
    width: 120,
    // format: 'YYYY-MM-DD'
  },
  {
    title: "版本号",
    field: "versionNumber",
    width: 140,
    type: "html",
  },
  {
    title: "生产数量",
    field: "productionQuantity",
    width: 140,
    type: "html",
  },
  {
    title: "计划完工日",
    field: "planEndDay",
    width: 140,
    format: "YYYY-MM-DD hh:mm:ss",
  },
const routePlanList = ref([]);
const dayProduceTypeOptions = ref([
  { label: "单人日产出", value: "1" },
  { label: "固定日产出", value: "2" },
]);
</script>
const formatTypeLabel = (list) => {
  if (list) {
    return list.map(type => {
      const item = dayProduceTypeOptions.value.find(item => item.value === type)
      return item ? item.label : type
    }).join(',')
  }
  return ''
}
// è¡¨æ ¼é…ç½®
// const columns = ref([
//   // {
//   //   title: "规划年份",
//   //   field: "year",
//   //   width: 150,
//   // },
//   // {
//   //   title: "规划月份",
//   //   field: "month",
//   // },
//   // {
//   //   title: "专业",
//   //   field: "major",
//   //   width: 100,
//   // },
//   {
//     title: "标准工序名称",
//     field: "processName",
//     width: 100,
//   },
//   {
//     title: "日产出类型",
//     field: "dayProduceType",
//     width: 140,
//     editRender: {},
//     slots: { edit: "edit_role", default: "default_role" },
//   },
//   {
//     title: "日产出数量",
//     field: "dayProduceNum",
//     width: 140,
//     // editRender: { autoFocus: "input" },
//     // slots: { edit: "edit_name", default: "default_name" },
//   },
//   {
//     title: "日产出数量单位",
//     field: "dayProduceUnit",
//     width: 140,
//   },
//   {
//     title: "人员数量",
//     field: "personnelNumber",
//     width: 140,
//     type: "html",
//   },
//   {
//     title: "日产出总数量",
//     field: "dayProduceAllNum",
//     width: 140,
//     type: "html",
//   },
//   {
//     title: "天数",
//     field: "days",
//     width: 120,
//     // format: 'YYYY-MM-DD'
//   },
//   {
//     title: "月产出总数量",
//     field: "monthProduceAllNum",
//     width: 140,
//     type: "html",
//   },
//   {
//     title: "备注",
//     field: "remark",
//     width: 140,
//     type: "html",
//   },
// ]);
async function getRouteList(year, month) {
  const res = await listGasPlan({
    major: "管路",
    year,
    month,
  });
  console.log(res.rows, "getList");
  routePlanList.value = res.rows;
  routePlanList.value = routePlanList.value.map((item, index) => {
    return {
      ...item,
      dayProduceType: item.dayProduceType == null ? "" : item.dayProduceType,
      dayProduceNum: item.dayProduceNum == null ? "0" : item.dayProduceNum,
      dayProduceUnit: item.dayProduceUnit == null ? "个" : item.dayProduceUnit,
      personnelNumber:
        item.personnelNumber == null ? "1" : item.personnelNumber,
      dayProduceAllNum:
        item.dayProduceAllNum == null ? "0" : item.dayProduceNum*item.personnelNumber,
      days: item.days == null ? "22" : item.days,
      monthProduceAllNum:
        item.monthProduceAllNum == null ? "0" : item.dayProduceAllNum*item.days,
    };
  });
  loading.value = false;
}
async function getGasList(year, month) {
  const res = await listGasPlan({
    major: "气体",
    year,
    month,
  });
  console.log(res.rows, "getList");
  gasPlanList.value = res.rows;
  gasPlanList.value = gasPlanList.value.map((item, index) => {
    return {
      ...item,
      dayProduceType: item.dayProduceType == null ? "" : item.dayProduceType,
      dayProduceNum: item.dayProduceNum == null ? "0" : item.dayProduceNum,
      dayProduceUnit: item.dayProduceUnit == null ? "个" : item.dayProduceUnit,
      personnelNumber:
        item.personnelNumber == null ? "1" : item.personnelNumber,
      dayProduceAllNum:
        item.dayProduceAllNum == null ? "0" : item.dayProduceNum*item.personnelNumber,
      days: item.days == null ? "22" : item.days,
      monthProduceAllNum:
        item.monthProduceAllNum == null ? "0" : item.dayProduceAllNum*item.days,
    };
  });
  loading.value = false;
}
function cellClickEvent ({ row, column }){
  console.log(column,row)
  row.dayProduceAllNum = row.dayProduceNum*row.personnelNumber
  row.monthProduceAllNum = row.dayProduceAllNum*row.days
}
function handleQuery() {
  console.log(queryParams.value.date, "scsciciisc");
  const year = queryParams.value.date.split("-")[0];
  const month = parseInt(queryParams.value.date.split("-")[1]);
  getRouteList(year, month);
  getGasList(year, month);
}
async function handleSave() {
  const year = queryParams.value.date.split("-")[0];
  const month = parseInt(queryParams.value.date.split("-")[1]);
  gasPlanList.value = gasPlanList.value.map((item)=>{
    return {
      ...item,
      major: "气体",
      year,
      month
    }
  })
  routePlanList.value = routePlanList.value.map((item)=>{
    return {
      ...item,
      major: "管路",
      year,
      month
    }
  })
 const res = await getGasPlanSave([
  ...gasPlanList.value,
  ...routePlanList.value
 ])
 ElMessage({
    message: "数据保存成功",
    type: "success",
  });
  handleQuery()
 console.log(res,"akiwjciwj")
}
onMounted(() => {
  // getRouteList();
  // getGasList();
});
</script>
<style lang="scss" scoped>
.box_container {
  width: 100%;
  margin: 20px auto;
  background: #fff;
  border-radius: 5px;
  box-shadow: 1px 1px 1px 4px#f1f1f1;
  .title_text {
    padding-top: 20px;
    margin-left: 20px;
  }
  .tabel_container {
    width: 98%;
    margin: 20px auto;
  }
}
.btn_center{
  display: flex;
  justify-content: center;
  align-items: center;
  margin-top:20px;
  padding-bottom:20px;
}
</style>
src/views/mainPlan/gasProduceStatics/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,209 @@
<template>
  <div class="app-container">
    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="warning"
          plain
          icon="Download"
          @click="handleExport"
          v-hasPermi="['apsPartRouteStat:export']"
        >导出</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="info"
          plain
          icon="Refresh"
          @click="handleRefresh"
          v-hasPermi="['apsPartRouteStat:edit']"
        >更新</el-button>
      </el-col>
      <right-toolbar @queryTable="getList" :search="false"></right-toolbar>
    </el-row>
    <vxe-grid ref="gridRef" v-bind="gridOptions" :loading="loading"></vxe-grid>
  </div>
</template>
<script setup name="apsPartRouteStat">
import { query,updateStat } from "@/api/mainPlan/partRouteStat.js";
import { ref } from "vue";
import * as XLSX from 'xlsx';
const { proxy } = getCurrentInstance();
const loading = ref(true);
const gridRef = ref();
const height = ref(document.documentElement.clientHeight - 130 + "px;")
const headers = ref([]);
const exportData = ref([]);
const gridOptions = reactive({
  border: true,
  stripe: true,
  loading: false,
  showOverflow: true,
  showHeaderOverflow: true,
  showFooterOverflow: true,
  height: height,
  columnConfig: {
    resizable: true
  },
  scrollX: {
    enabled: true,
    gt: 0,
    threshold: 50
  },
  scrollY: {
    enabled: true,
    gt: 0,
    threshold: 50
  }
});
let tableColumn = []
let tableData = []
let merges = [];
/** æŸ¥è¯¢é›¶ä»¶ç»Ÿè®¡è¡¨åˆ—表 */
function getList() {
  let rowKey = 0
  let colKey = 0
  headers.value = []
  exportData.value = []
  tableColumn = []
  tableData = []
  loading.value = true;
  query().then(response => {
    const colList = []
    let headersOne = []
    let headersTwo = []
    if(response.code == '200'){
      if (!response.planTitle) {
        loading.value = false;
        return;
      }
      headersOne.push('日期');
      headersTwo.push('资源组');
      colList.push({
          field: 'dateCol',
          title: '日期',
          fixed: 'left',
          children: [
            { field: `resourceName`, title: '资源组', width: 250, type: 'html'},
          ],
          width: 160
        })
      response.planTitle.forEach(item => {
        headersOne.push(item);
        headersOne.push('');
        headersOne.push('');
        headersTwo.push('设计工时');
        headersTwo.push('需求工时');
        headersTwo.push('产能负荷');
        colKey++
        colList.push({
          field: `dateColTime${colKey}`,
          title: item,
          children: [
          { field: `designTimes${colKey}`, title: '设计工时', width: 80},
          { field: `requireTimes${colKey}`, title: '需求工时', width: 80},
          { field: `capacityLoad${colKey}`, title: '产能负荷', width: 80, type: 'html'},
          ],
          width: 160
        })
      });
      headers.value.push(headersOne);
      headers.value.push(headersTwo);
      const columnList = [...tableColumn, ...colList]
      const dataList = []
      let startCol = 1;
      //获取map
      response.planTable.forEach(mapItem => {
        rowKey++
        let lastCol = startCol + 2;
        merges.push({ s: { r: 0, c: startCol }, e: { r: 0, c:  lastCol} });
        startCol = lastCol + 1;
        let data = [];
        const item = {
          id: `${rowKey}`
        }
        for (const [key, listValue] of Object.entries(mapItem)) {
          data.push(key);
          let tableKey = 0;
          let flag = false;
          listValue.forEach(listItem => {
            tableKey++
            item[`designTimes${tableKey}`] = listItem.designTimes;
            item[`requireTimes${tableKey}`] = listItem.requireTimes;
            item[`capacityLoad${tableKey}`] = listItem.capacityLoad > 100 ? `<font color="red">${listItem.capacityLoad}%</font>` :listItem.capacityLoad+'%';
            data.push(listItem.designTimes);
            data.push(listItem.requireTimes);
            data.push(listItem.capacityLoad+'%');
            if (listItem.capacityLoad > 100) {
              flag = true;
            }
          });
          item[`resourceName`] = flag ? `<div class='el-badge'><sup class="el-badge__content is-fixed is-dot"></sup>${key}</div>` : key;
        }
        exportData.value.push(data);
        dataList.push(item);
      });
      const $grid = gridRef.value
      if ($grid) {
        tableColumn = columnList
        tableData = [...tableData, ...dataList]
        $grid.loadColumn(tableColumn)
        $grid.loadData(tableData)
        gridOptions.loading = false
      }
      loading.value = false;
    }
  });
}
/** å¯¼å‡ºæŒ‰é’®æ“ä½œ */
function handleExport() {
  // åˆå¹¶è¡¨å¤´å’Œæ•°æ®
  const finalData = [...headers.value, ...exportData.value];
  // å°†æ•°æ®è½¬æ¢ä¸º worksheet
  const ws = XLSX.utils.aoa_to_sheet(finalData);
  // åˆå¹¶å•元格(如果需要)
  /* ws['!merges'] = [
    { s: { r: 0, c: 1 }, e: { r: 0, c: 3 } },
    { s: { r: 0, c: 0 }, e: { r: 0, c: 0 } }
  ]; */
  ws['!merges'] = merges;
  // åˆ›å»º workbook
  const wb = XLSX.utils.book_new();
  // å°† worksheet æ·»åŠ åˆ° workbook ä¸­
  XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');
  // å¯¼å‡ºæ–‡ä»¶
  XLSX.writeFile(wb, `apsPartRouteStat_${new Date().getTime()}.xlsx`);
}
/** åˆ·æ–°æŒ‰é’®æ“ä½œ */
function handleRefresh(){
  updateStat().then(response => {
    if(response.code == '200'){
      getList();
    }
  });
}
getList();
</script>
vite.config.js
@@ -17,7 +17,7 @@
  const proxyConfig = () => {
    const personProxy = {
      "/prod-api": {
        target: "http://192.168.50.13:8080", // å¼€å‘环境的后端地址
        target: "http://192.168.50.160:8080",//"http://192.168.50.13:8080", // å¼€å‘环境的后端地址
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/prod-api/, ""),
      },
@@ -48,7 +48,7 @@
    switch (VITE_APP_ENV) {
      case "development":
        return devProxy;
        return personProxy;
      case "int":
        return devProxy;
      case "uat":