فهرست منبع

feat(生产排程): 优化班次时间表和总工序时间组件功能

yusheng 9 ماه پیش
والد
کامیت
c725d5d413

+ 1 - 0
src/views/productionScheduling/productionShift/components/addOrEditDialog.vue

@@ -263,6 +263,7 @@
           ...defForm
         };
         this.form.list = [];
+        this.$refs.timeTable.form.list = [];
       }
     }
   };

+ 35 - 12
src/views/productionScheduling/productionShift/components/timeTable.vue

@@ -5,7 +5,7 @@
     :rules="rules"
     label-width="140px"
     class="el-form-box"
-    :disabled="type == '详情'"
+    :disabled="title == '详情'"
   >
     <ele-pro-table
       :columns="columns"
@@ -14,7 +14,6 @@
       height="300px"
       full-height="calc(100vh - 116px)"
       :needPage="false"
-      :selection.sync="selection"
     >
       <template v-slot:toolbar v-if="title != '详情'">
         <el-button
@@ -27,7 +26,7 @@
         >
           新增
         </el-button>
-        <el-popconfirm
+        <!-- <el-popconfirm
           class="ele-action"
           title="确定要删除选中的信息吗?"
           @confirm="remove()"
@@ -42,7 +41,7 @@
               删除
             </el-button>
           </template>
-        </el-popconfirm>
+        </el-popconfirm> -->
       </template>
       <template v-slot:dutyName="{ row, $index }">
         <el-form-item
@@ -108,7 +107,7 @@
             placeholder="开始时间"
             v-model="row.startTime"
             @change="changeTime(row, $index, 'startTime')"
-            :disabled="form.list[$index - 1]?.endTime"
+            :disabled="!!form.list[$index - 1]?.endTime"
             :picker-options="{
               ...defTime,
               ...(form.list[$index - 1]
@@ -153,11 +152,23 @@
       <template v-slot:note="{ row }">
         <el-input clearable v-model="row.note" placeholder="请输入" />
       </template>
+      <template v-slot:action="{ row, $index }">
+        <el-popconfirm
+          class="ele-action"
+          title="确定要删除此信息吗?"
+          @confirm="remove($index)"
+        >
+          <template v-slot:reference>
+            <el-link type="danger" :underline="false" icon="el-icon-delete">
+              删除
+            </el-link>
+          </template>
+        </el-popconfirm>
+      </template>
     </ele-pro-table>
   </el-form>
 </template>
 <script>
-
   const defForm = {
     list: [] //表格数据
   };
@@ -233,6 +244,16 @@
             align: 'center',
             showOverflowTooltip: true,
             minWidth: 200
+          },
+          {
+            columnKey: 'action',
+            label: '操作',
+            width: 150,
+            align: 'center',
+            resizable: false,
+            slot: 'action',
+            showOverflowTooltip: true,
+            fixed: 'right'
           }
         ],
         selection: [],
@@ -308,7 +329,9 @@
             this.form.list[this.form.list.length - 1].endTime;
           let totalWorkingMinutes = 0;
           let restDurationMinutes = 0;
-          this.form.list.forEach((v) => {
+
+          this.form.list.forEach((v, index) => {
+            v.key = index;
             if (v.timeType == '1') {
               totalWorkingMinutes += v.totalDuration;
             } else {
@@ -334,11 +357,11 @@
           newSeconds
         ).padStart(2, '0')}`;
       },
-      remove() {
-        let keys = this.selection.map((item) => item.key);
-        this.form.list = this.form.list.filter(
-          (item) => !keys.includes(item.key)
-        );
+      remove(index) {
+        if (index != 0) {
+          this.removeFormtime(index);
+        }
+        this.form.list.splice(index, 1);
         this.setFormtime();
         this.selection = [];
       },

+ 371 - 334
src/views/productionScheduling/totalProcessTime/components/addOrEditDialog.vue

@@ -15,264 +15,220 @@
       ref="form"
       :model="form"
       :rules="rules"
-      label-width="140px"
+      label-width="120px"
       class="el-form-box"
       :disabled="title == '详情'"
     >
+      <headerTitle title="产品信息"> </headerTitle>
       <el-row>
         <el-col :span="12">
-          <el-form-item label="班次编码" prop="code">
+          <el-form-item label="编码" prop="code">
             <el-input
               clearable
-              disabled
+              readonly
               v-model="form.code"
+              @click.native="$refs.produceRef.open()"
               placeholder="请选择"
             />
           </el-form-item>
         </el-col>
         <el-col :span="12">
-          <el-form-item label="班次名称" prop="shiftName">
-            <el-input clearable v-model="form.shiftName" placeholder=" " />
+          <el-form-item label="名称" prop="name">
+            <el-input clearable disabled v-model="form.name" placeholder=" " />
           </el-form-item>
         </el-col>
         <el-col :span="12">
-          <el-form-item label="出勤开始时间" prop="attendanceStartTime">
-            <el-input
-              clearable
-              disabled
-              v-model="form.attendanceStartTime"
-              placeholder=" "
-            />
+          <el-form-item label="BOM类型" prop="bomCategory">
+            <el-select
+              v-model="form.bomCategory"
+              @change="changeProductType"
+              style="width: 100%"
+            >
+              <el-option
+                v-for="item of bomCategoryList"
+                :key="item.code"
+                :label="item.name"
+                :value="item.code"
+              ></el-option>
+            </el-select>
           </el-form-item>
         </el-col>
         <el-col :span="12">
-          <el-form-item label="出勤结束时间" prop="attendanceEndTime">
-            <el-input
-              clearable
-              disabled
-              v-model="form.attendanceEndTime"
-              placeholder=" "
-            />
+          <el-form-item label="BOM版本" prop="bomId">
+            <el-select
+              v-model="form.bomId"
+              @change="changeBomId"
+              style="width: 100%"
+            >
+              <el-option
+                v-for="item of bomVersionList"
+                :key="item.id"
+                :label="item.name + '(V' + item.versions + '.0)'"
+                :value="item.id"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="工艺路线" prop="produceRoutingId">
+            <el-select
+              v-model="form.produceRoutingId"
+              @change="changeRoutingList"
+              style="width: 100%"
+            >
+              <el-option
+                v-for="item of routingList"
+                :key="item.id"
+                :label="item.name"
+                :value="item.id"
+              ></el-option>
+            </el-select>
           </el-form-item>
         </el-col>
         <el-col :span="12">
-          <el-form-item label="工作总时长(分钟)" prop="totalWorkingMinutes">
+          <el-form-item label="工厂名称:" prop="factoriesId">
+            <el-select
+              style="width: 100%"
+              clearable
+              v-model="form.factoriesId"
+              placeholder="请选择所属工厂"
+            >
+              <el-option
+                v-for="item in factoryList"
+                :label="item.name"
+                :value="item.id"
+                :key="item.id"
+                @click.native="change_factoryId(item)"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <headerTitle title="工位节拍"> </headerTitle>
+      <ele-pro-table
+        :columns="columns"
+        :datasource="form.list"
+        ref="table"
+        height="400px"
+        full-height="calc(100vh - 116px)"
+        :needPage="false"
+        :selection.sync="selection"
+      >
+
+        <template v-slot:stationCycleTime="{ row, $index }">
+          <el-form-item
+            label-width="0"
+            :prop="'list.' + $index + '.stationCycleTime'"
+            :rules="[{ required: true, message: '请输入', trigger: 'blur' }]"
+          >
             <el-input
               clearable
-              disabled
-              v-model="form.totalWorkingMinutes"
-              placeholder=" "
+              v-model.number="row.stationCycleTime"
+              placeholder="请输入"
             />
           </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="休息时间(分钟)" prop="restDurationMinutes">
+        </template>
+        <template v-slot:priority="{ row, $index }">
+          <el-form-item
+            label-width="0"
+            :prop="'list.' + $index + '.priority'"
+            :rules="[{ required: true, message: '请输入', trigger: 'blur' }]"
+          >
             <el-input
               clearable
-              disabled
-              v-model="form.restDurationMinutes"
-              placeholder=" "
+              v-model.number="row.priority"
+              placeholder="请输入"
             />
           </el-form-item>
-        </el-col>
-        <el-col :span="24">
-          <el-form-item label="时间设置:">
-            <ele-pro-table
-              :columns="columns"
-              :datasource="form.list"
-              ref="table"
-              height="300px"
-              full-height="calc(100vh - 116px)"
-              :needPage="false"
-              :selection.sync="selection"
-            >
-              <template v-slot:toolbar v-if="title != '详情'">
-                <el-button
-                  size="small"
-                  type="primary"
-                  icon="el-icon-plus"
-                  class="ele-btn-icon"
-                  @click="handAdd()"
-                  style="margin-bottom: 5px"
-                >
-                  新增
-                </el-button>
-                <el-popconfirm
-                  class="ele-action"
-                  title="确定要删除选中的信息吗?"
-                  @confirm="remove()"
-                >
-                  <template v-slot:reference>
-                    <el-button
-                      type="danger"
-                      :underline="false"
-                      icon="el-icon-delete"
-                      :disabled="selection?.length === 0"
-                    >
-                      删除
-                    </el-button>
-                  </template>
-                </el-popconfirm>
-              </template>
-              <template v-slot:dutyName="{ row, $index }">
-                <el-form-item
-                  label-width="0"
-                  :prop="'list.' + $index + '.dutyName'"
-                  :rules="[
-                    {
-                      required: true,
-                      message: '出勤名称不能为空',
-                      trigger: 'blur'
-                    }
-                  ]"
-                >
-                  <DictSelection
-                    dictName="班次出勤名称"
-                    clearable
-                    v-model="row.dutyName"
-                    filterable
-                    valueName="dictValue"
-                    allow-create
-                    default-first-option
-                    :isOne="$index === 0"
-                  >
-                  </DictSelection>
-                </el-form-item>
-              </template>
-              <template v-slot:timeType="{ row, $index }">
-                <el-form-item
-                  label-width="0"
-                  :prop="'list.' + $index + '.timeType'"
-                  :rules="[
-                    {
-                      required: true,
-                      message: '请选择时间类型',
-                      trigger: 'blur'
-                    }
-                  ]"
-                >
-                  <el-select
-                    v-model="row.timeType"
-                    clearable
-                    style="width: 100%"
-                    @change="setFormtime"
-                  >
-                    <el-option :value="'1'" label="工作时间"></el-option>
-                    <el-option :value="'2'" label="休息时间"></el-option>
-                  </el-select>
-                </el-form-item>
+        </template>
 
-                <!-- <DictSelection
-                  dictName="班次时间类型"
-                  clearable
-                  v-model="row.timeType"
-                  filterable
-                  allow-create
-                  valueName="dictValue"
-                  default-first-option
-                >
-                </DictSelection> -->
-              </template>
-              <template v-slot:startTime="{ row, $index }">
-                <el-form-item
-                  label-width="0"
-                  :prop="'list.' + $index + '.startTime'"
-                  :rules="[
-                    {
-                      required: true,
-                      message: '请选择时间类型',
-                      trigger: 'blur'
-                    }
-                  ]"
-                >
-                  <el-time-select
-                    placeholder="开始时间"
-                    v-model="row.startTime"
-                    @change="changeTime(row, $index, 'startTime')"
-                    :picker-options="{
-                      ...defTime,
-                      ...(form.list[$index - 1]
-                        ? {
-                            minTime: form.list[$index - 1].endTime
-                          }
-                        : {})
-                    }"
-                  >
-                  </el-time-select>
-                </el-form-item>
-              </template>
-              <template v-slot:endTime="{ row, $index }">
-                <el-form-item
-                  label-width="0"
-                  :prop="'list.' + $index + '.endTime'"
-                  :rules="[
-                    {
-                      required: true,
-                      message: '请选择时间类型',
-                      trigger: 'blur'
-                    }
-                  ]"
-                >
-                  <el-time-select
-                    placeholder="结束时间"
-                    v-model="row.endTime"
-                    @change="changeTime(row, $index, 'endTime')"
-                    :picker-options="{
-                      ...defTime,
-                      ...{
-                        minTime: row.startTime
-                      }
-                    }"
-                  >
-                  </el-time-select>
-                </el-form-item>
-              </template>
-              <template v-slot:columnRequired="{ column }">
-                <span class="is-required">{{ column.label }}</span>
-              </template>
-              <template v-slot:note="{ row }">
-                <el-input clearable v-model="row.note" placeholder="请输入" />
-              </template>
-            </ele-pro-table>
-          </el-form-item>
-        </el-col>
-      </el-row>
+        <template v-slot:remark="{ row }">
+          <el-input clearable v-model="row.remark" placeholder="请输入" />
+        </template>
+        <template v-slot:columnRequired="{ column }">
+          <span class="is-required">{{ column.label }}</span>
+        </template>
+      </ele-pro-table>
     </el-form>
     <div slot="footer">
-      <el-button type="primary" @click="save()" v-lodading="loading"
+      <el-button
+        type="primary"
+        @click="save()"
+        v-lodading="loading"
+        v-if="title != '详情'"
         >保存</el-button
       >
 
       <el-button @click="cancel">返回</el-button>
     </div>
+    <ProductModal
+      ref="produceRef"
+      @changeParent="produceConfirm"
+    ></ProductModal>
   </ele-modal>
 </template>
 <script>
   const defForm = {
-    code: '', //名称
-    shiftName: '', //类型
-    attendanceStartTime: '', //	出勤开始时间
-    attendanceEndTime: '', //	出勤结束时间
-    totalWorkingMinutes: '', //	总工作时长
-    restDurationMinutes: '', //	休息时长
-    status: 0,
+    code: '', //编码
+    name: '', //名称
+    productId: '', //物品id
+    factoriesId: '', //工厂id
+    factoriesName: '', //工厂名称
+    bomVersion: '', //bom版本
+    bomId: '', //bom版本id
+    bomCategory: '', //bom类型
+    brandNo: '', //品牌
+    specification: '', //规格
+    modelType: '', //型号
+    produceRoutingId: '', //	工艺路线
+    produceRoutingName: '', //	工艺路线名称
+    cycleTime: '', //	工序节拍
+    operationName: '', //	工序名称
+    operationId: '', //	工序id
     list: [] //表格数据
   };
-  import { getCode } from '@/api/codeManagement';
+  import { getFactoryarea } from '@/api/factoryModel';
+  import ProductModal from '@/components/productList/product-list.vue';
   import {
     saveOrUpdate,
-    getById
-  } from '@/api/productionScheduling/productionShift';
+    getById,
+    listBomType,
+    bomListByPlan,
+    bomRoutingList,
+    listByRoutingIds,
+    selectFactoryWorkstation
+  } from '@/api/productionScheduling/stationBeat';
+
   export default {
-    components: {},
+    components: { ProductModal },
     computed: {},
     data() {
       return {
-        defTime: {
-          step: '00:01',
-          start: '00:00',
-          end: '23:59'
+        lodading: false,
+        title: '',
+        addOrEditDialogFlag: false,
+        form: { ...defForm },
+        rules: {
+          name: [
+            { required: true, message: '名称不能为空', trigger: 'change' }
+          ],
+          factoriesId: [
+            { required: true, message: '请选择工厂', trigger: 'change' }
+          ],
+          bomId: [
+            { required: true, message: '请选择BOM版本', trigger: 'change' }
+          ],
+          bomCategory: [
+            { required: true, message: '请选择BOM类型', trigger: 'change' }
+          ],
+          produceRoutingId: [
+            { required: true, message: '请选择工艺路线', trigger: 'change' }
+          ],
+          code: [{ required: true, message: '编码不能为空', trigger: 'change' }]
         },
+        factoryList: [],
+        selection: [],
+        productionLineList: [],
         columns: [
           {
             width: 60,
@@ -283,188 +239,265 @@
             fixed: 'left'
           },
           {
-            width: 45,
-            type: 'selection',
-            columnKey: 'selection',
-            align: 'center'
+            prop: 'workstationName',
+            label: '工位名称',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 180
+          },
+          {
+            prop: 'deviceCode',
+            label: '设备编码',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 180
           },
           {
-            prop: 'dutyName',
-            slot: 'dutyName',
-            headerSlot: 'columnRequired',
-            label: '出勤名称',
+            prop: 'deviceName',
+            label: '设备名称',
             align: 'center',
             showOverflowTooltip: true,
             minWidth: 180
           },
           {
-            slot: 'timeType',
-            prop: 'timeType',
-            headerSlot: 'columnRequired',
-            label: '时间类型',
+            prop: 'model',
+            label: '型号',
             align: 'center',
             showOverflowTooltip: true,
-            minWidth: 110
+            minWidth: 180
           },
           {
-            prop: 'startTime',
-            label: '开始时间',
+            prop: 'deviceType',
+            label: '设备类型',
             align: 'center',
-            headerSlot: 'columnRequired',
-            slot: 'startTime',
             showOverflowTooltip: true,
-            minWidth: 170
+            minWidth: 180
           },
+
           {
-            prop: 'endTime',
-            minWidth: 170,
+            prop: 'stationCycleTime',
+            slot: 'stationCycleTime',
             headerSlot: 'columnRequired',
-            slot: 'endTime',
-            label: '结束时间',
-            align: 'center'
+            label: '工位节拍(分钟)',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 180
           },
           {
-            width: 160,
-            prop: 'totalDuration',
-            label: '总时长(分钟)',
-            align: 'center'
+            prop: 'priority',
+            slot: 'priority',
+            headerSlot: 'columnRequired',
+            label: '优先顺序',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 120
           },
           {
-            prop: 'note',
-            slot: 'note',
+            prop: 'remark',
+            slot: 'remark',
             label: '备注',
             align: 'center',
             showOverflowTooltip: true,
             minWidth: 200
           }
         ],
-        selection: [],
-        lodading: false,
-        title: '',
-        addOrEditDialogFlag: false,
-        form: { ...defForm },
         loading: false,
-        rules: {
-          shiftName: [
-            { required: true, message: '名称不能为空', trigger: 'change' }
-          ]
-        }
+        bomCategoryList: [],
+        bomVersionList: [],
+        routingList: [],
+        taskList: []
       };
     },
     mounted() {},
-    created() {},
+    created() {
+      this.getFactoryList();
+    },
+    computed: {
+      cycleTime() {
+        let cycleTime = this.form.list.reduce((pre, cur) => {
+          return pre + Number(cur.stationCycleTime);
+        }, 0);
+        this.form.cycleTime =
+          cycleTime / this.form.list.length / this.form.list.length;
+        return cycleTime / this.form.list.length / this.form.list.length || 0;
+      }
+    },
 
     methods: {
       //初始化
-      async open(row = {}, type) {
+      async open(row = {}) {
         this.addOrEditDialogFlag = true;
-        console.log(type);
-        this.title = type == 'add' ? '新增' : type == 'edit' ? '修改' : '详情';
+        this.title = '详情';
+
+        this.form = row;
 
-        if (type !== 'add') {
-          this.form = await getById(row.id);
-          this.form.list.forEach((item, index) => {
-            item.key = index;
-          });
-        } else {
-          this.form.code = await getCode('workShift_code');
+        this.getBomInfo(this.form.productId);
+        this.changeProductType('init');
+
+        if (this.form.factoriesId) {
+          this.change_factoryId({ id: this.form.factoriesId });
         }
       },
-      handAdd() {
-        if (
-          this.form.list?.length &&
-          !this.form.list[this.form.list?.length - 1].endTime
-        ) {
-          this.$message.error('请先填写前一条数据的结束时间');
-          return;
-        }
+      handParent() {
         this.form.list.push({
-          startTime: this.incrementTime(
-            this.form.list[this.form.list?.length - 1]?.endTime
-          ),
-          endTime: '',
-          note: '',
-          totalDuration: '',
-          dutyName: '',
-          timeType: '1',
+          productionLineName: '',
+          productionLineId: '',
+          stationCycleTime: '',
+          remark: '',
           key: this.form.list?.length || 0
         });
       },
-      changeTime(row, index, type) {
-        if (type == 'startTime') {
-          this.$set(this.form.list[index], 'endTime', '');
-        }
-        if (type == 'endTime') {
-          if (!row.startTime) {
-            this.$set(this.form.list[index], 'endTime', '');
-            this.$message.error('请先选择开始时间');
-            return;
+      async getFactoryList() {
+        const { list } = await getFactoryarea({
+          pageNum: 1,
+          size: 999,
+          type: 1,
+          enable: 1
+        });
+        this.factoryList = list || [];
+      },
+      async change_factoryId(item) {
+        const { list } = await getFactoryarea({
+          pageNum: 1,
+          size: 999,
+          type: 4,
+          factoryId: item.id,
+          enable: 1
+        });
+        this.productionLineList = list || [];
+        this.form.factoriesName = item.name;
+      },
+      change_productionLineId(item, index) {
+        this.$set(this.form.list[index], 'productionLineName', item.name);
+      },
+      produceConfirm(data) {
+        this.form.name = data[0].name;
+        this.form.code = data[0].code;
+        this.form.productId = data[0].id;
+        this.form.brandNo = data[0].brandNum;
+        this.form.modelType = data[0].modelType;
+        this.form.specification = data[0].specification;
+        this.produceCancel();
+        this.getBomInfo(data[0].id);
+      },
+      produceCancel() {
+        this.form.bomCategory = '';
+        this.bomCategoryList = [];
+        this.form.bomVersion = '';
+        this.form.bomId = '';
+        this.bomVersionList = [];
+        this.routingList = [];
+        this.form.produceRoutingId = '';
+        this.form.produceRoutingName = '';
+        this.produceRoutingList = [];
+        this.form.operationId = '';
+        this.form.operationName = '';
+        this.taskList = [];
+        this.form.list = [];
+      },
+
+      // 获取bom信息
+      async getBomInfo(id) {
+        const res = await listBomType({ categoryId: id });
+        if (!res || res.length == 0) return;
+        let bomMap = {
+          2: { code: '2', name: 'MBOM' },
+          3: { code: '3', name: 'ABOM' }
+        };
+        let arr = [];
+        res.map((item) => {
+          if (bomMap[item.bomType]) {
+            arr.push(bomMap[item.bomType]);
           }
-        }
-        this.removeFormtime(index);
-        if (row.startTime && row.endTime) {
-          let val =
-            (new Date('2025-01-01 ' + row.endTime).getTime() -
-              new Date('2025-01-01 ' + row.startTime).getTime()) /
-            60000;
+        });
+        this.bomCategoryList = arr;
+      },
 
-          this.$set(this.form.list[index], 'totalDuration', val);
-        } else {
-          this.$set(this.form.list[index], 'totalDuration', 0);
+      // 根据bom类型和产品id获取bom版本
+      async changeProductType(type) {
+        let data = await bomListByPlan({
+          bomType: this.form.bomCategory,
+          categoryId: this.form.productId
+        });
+        this.bomVersionList = data;
+        if (data.length) {
+          if (type != 'init') {
+            this.form.bomId = data[0].id;
+            this.form.bomVersion = data[0].versions;
+          }
+          this.changeBomId(type);
         }
-        this.setFormtime();
-      },
-      removeFormtime(i) {
-        this.form.list.splice(i+1, this.form.list.length - i);
-        // this.form.list.forEach((item, index) => {
-        //   if (index > i) {
-        //     this.$set(this.form.list[index], 'startTime', '');
-        //     this.$set(this.form.list[index], 'endTime', '');
-        //   }
-        // });
       },
-      setFormtime() {
-        if (this.form.list?.length) {
-          this.form.attendanceStartTime = this.form.list[0].startTime;
-          this.form.attendanceEndTime =
-            this.form.list[this.form.list.length - 1].endTime;
-          this.form.totalWorkingMinutes = 0;
-          this.form.restDurationMinutes = 0;
-          this.form.list.forEach((v) => {
-            if (v.timeType == '1') {
-              this.form.totalWorkingMinutes += v.totalDuration;
-            } else {
-              this.form.restDurationMinutes += v.totalDuration;
-            }
-          });
+      async changeBomId(type) {
+        const res = await bomRoutingList(this.form.bomId);
+        let arr = res || [];
+        this.routingList = arr;
+        if (type != 'init') {
+          this.form.bomVersion = this.bomVersionList.find(
+            (item) => item.id == this.form.bomId
+          )?.versions;
+          this.taskList = [];
+          this.form.produceRoutingId = '';
+          this.form.produceRoutingName = '';
+          this.form.operationName = '';
+          this.form.operationId = '';
+          this.form.list = [];
+        }
+
+        if (arr.length) {
+          if (type != 'init') {
+            this.form.produceRoutingId = arr[0].id;
+            this.form.produceRoutingName = arr[0].name;
+          }
+          this.changeRoutingList(type);
         }
       },
-      incrementTime(time) {
-        if (!time) {
-          return '';
+      async changeRoutingList(type) {
+        const res = await listByRoutingIds([this.form.produceRoutingId]);
+        let arr = res || [];
+        this.taskList = arr;
+        if (type != 'init') {
+          this.form.operationName = '';
+          this.form.operationId = '';
+          this.form.list = [];
         }
-        const [minutes, seconds] = time.split(':').map(Number);
-        let newSeconds = (seconds + 1) % 60;
-        let newMinutes = minutes + Math.floor((seconds + 1) / 60);
-        return `${String(newMinutes).padStart(2, '0')}:${String(
-          newSeconds
-        ).padStart(2, '0')}`;
       },
-      remove() {
-        let keys = this.selection.map((item) => item.key);
-        this.form.list = this.form.list.filter(
-          (item) => !keys.includes(item.key)
-        );
-        this.setFormtime();
-        this.selection = [];
+      async changeOperationId(item) {
+        this.form.operationName = item.name;
+        const res = await selectFactoryWorkstation({
+          taskId: this.form.operationId
+        });
+        let arr = res || [];
+        this.form.list = arr.map((item) => {
+          return {
+            deviceId: item.extInfo?.assetId,
+            deviceName: item.extInfo?.assetName,
+            deviceCode: item.extInfo?.assetCode,
+            workstationName: item.name,
+            workstationId: item.id,
+            model: item.modelType,
+            deviceType: item.categoryLevelName,
+            stationCycleTime: '',
+            remark: '',
+            priority: ''
+            // deviceType: item.extInfo?.assetType,
+          };
+        });
       },
+
       save() {
         this.$refs.form.validate((valid) => {
           if (!this.form.list?.length) {
-            this.$message.error('时间设置不能为空');
+            this.$message.error('节拍信息不能为空');
             return;
           }
           if (valid) {
+            let priorityList = this.form.list.map((item) => item.priority);
+
+            if (new Set(priorityList).size !== priorityList.length) {
+              this.$message.error('优先顺序不能重复');
+              return;
+            }
             this.loading = true;
             saveOrUpdate(this.form)
               .then((res) => {
@@ -490,4 +523,8 @@
     }
   };
 </script>
-<style scoped lang="scss"></style>
+<style scoped lang="scss">
+  // :deep(.el-form-item--medium) {
+  //   display: none;
+  // }
+</style>

+ 10 - 5
src/views/productionScheduling/totalProcessTime/index.vue

@@ -117,7 +117,14 @@
             prop: 'bomCategory',
             label: 'BOM分类',
             align: 'center',
-            showOverflowTooltip: true
+            showOverflowTooltip: true,
+            formatter: (row, column) => {
+              return row.bomCategory == 2
+                ? 'MBOM'
+                : row.bomCategory == 3
+                ? 'ABOM'
+                : '';
+            }
           },
           {
             minWidth: 150,
@@ -156,7 +163,6 @@
             showOverflowTooltip: true
           },
 
-
           {
             minWidth: 100,
             prop: 'updateUserName',
@@ -170,8 +176,7 @@
             label: '设置时间',
             align: 'center',
             showOverflowTooltip: true
-          },
-
+          }
         ]
       };
     },
@@ -185,7 +190,7 @@
       //新增、修改
       handleAddOrEdit(row = {}, type) {
         this.$nextTick(() => {
-          this.$refs.addOrEditDialogRef.open(row, type);
+          this.$refs.addOrEditDialogRef.open(row);
         });
       },
 

+ 17 - 5
src/views/productionScheduling/workCalendar/components/searchTable.vue

@@ -3,19 +3,20 @@
   <seekPage :seekList="seekList" :formLength="3" @search="search"></seekPage>
 </template>
 <script>
+  import { getFactoryworkstation } from '@/api/factoryModel';
   export default {
     data() {
-      return {};
+      return { workStationList: [] };
     },
     props: {
       productionLineList: {
         type: Array,
         default: () => []
       },
-      workStationList: {
-        type: Array,
-        default: () => []
-      },
+      // workStationList: {
+      //   type: Array,
+      //   default: () => []
+      // },
       productionShiftList: {
         type: Array,
         default: () => []
@@ -64,7 +65,18 @@
         ];
       }
     },
+    created() {
+      this.getFactoryworkstation();
+    },
     methods: {
+      /* 获取工位 */
+      async getFactoryworkstation() {
+        const data = await getFactoryworkstation({
+          pageNum: 1,
+          size: 999
+        });
+        this.workStationList = data.list || [];
+      },
       /* 搜索 */
       search(e) {
         this.$emit('search', {

+ 56 - 26
src/views/productionScheduling/workCalendar/components/timeTable.vue

@@ -38,6 +38,7 @@
         </el-button>
       </div>
       <ele-pro-table
+      style="margin-top: 5px;"
         :columns="columns"
         :datasource="item.list"
         v-for="(item, index) in form.list"
@@ -47,7 +48,7 @@
         @cell-click="cellClick"
         :needPage="false"
       >
-        <template v-slot:action="{ row }">
+        <template v-slot:checked="{ row }">
           <el-radio class="radio" v-model="radio" :label="row.key">
             <i></i>
           </el-radio>
@@ -158,6 +159,19 @@
         <template v-slot:columnRequired="{ column }">
           <span class="is-required">{{ column.label }}</span>
         </template>
+        <template v-slot:action="{ row, $index }">
+          <el-popconfirm
+            class="ele-action"
+            title="确定要删除此信息吗?"
+            @confirm="remove($index, index)"
+          >
+            <template v-slot:reference>
+              <el-link type="danger" :underline="false" icon="el-icon-delete">
+                删除
+              </el-link>
+            </template>
+          </el-popconfirm>
+        </template>
       </ele-pro-table>
     </el-form>
     <div slot="footer">
@@ -191,8 +205,7 @@
         },
         columns: [
           {
-            action: 'action',
-            slot: 'action',
+            slot: 'checked',
             align: 'center',
             label: '选择',
             reserveSelection: true
@@ -283,6 +296,16 @@
             prop: 'totalDuration',
             label: '总时长(分钟)',
             align: 'center'
+          },
+          {
+            columnKey: 'action',
+            label: '操作',
+            width: 150,
+            align: 'center',
+            resizable: false,
+            slot: 'action',
+            showOverflowTooltip: true,
+            fixed: 'right'
           }
         ],
         selection: [],
@@ -300,15 +323,14 @@
       async init(ids = [], type) {
         this.addOrEditDialogFlag = true;
         this.title = type == 'add' ? '新增' : type == 'edit' ? '修改' : '详情';
-        this.form.list = await getTApsWorkdayCalendarMaster(ids);
-        // row.forEach((item, index) => {
-        //   item.list.forEach((item1, index1) => {
-
-        //     item1.key = item.dayDate + index + '' + index1;
-        //     item1.parentKey = index;
-        //   });
-        // });
-        // this.form.list = JSON.parse(JSON.stringify(row));
+        let row = await getTApsWorkdayCalendarMaster(ids);
+        row.forEach((item, index) => {
+          item.list.forEach((item1, index1) => {
+            item1.key = item.dayDate + index + '' + index1;
+            item1.parentKey = index;
+          });
+        });
+        this.form.list = JSON.parse(JSON.stringify(row));
       },
       handleAddOrEdit() {
         if (!this.current.endTime) {
@@ -386,21 +408,26 @@
           this.form.list[parentIndex].list.length - i
         );
       },
+      remove(index, parentIndex) {
+        if (index != 0) {
+          this.removeFormtime(index,parentIndex);
+        }
+        this.form.list[parentIndex].list.splice(index, 1);
+      },
       setFormtime() {
-        if (this.form.list?.length) {
-          this.form.attendanceStartTime = this.form.list[0].startTime;
-          this.form.attendanceEndTime =
-            this.form.list[this.form.list.length - 1].endTime;
-          this.form.totalWorkingMinutes = 0;
-          this.form.restDurationMinutes = 0;
-          this.form.list.forEach((v) => {
-            if (v.timeType == '1') {
-              this.form.totalWorkingMinutes += v.totalDuration;
+        this.form.totalWorkingMinutes = 0;
+        this.form.restDurationMinutes = 0;
+        this.form.list.forEach((v) => {
+          v.workingHours = 0;
+          v.restTime = 0;
+          v.list.forEach((v1) => {
+            if (v1.timeType == '1') {
+              v.workingHours += v1.totalDuration;
             } else {
-              this.form.restDurationMinutes += v.totalDuration;
+              v.restTime += v1.totalDuration;
             }
           });
-        }
+        });
       },
 
       getValidate() {
@@ -417,10 +444,13 @@
       },
       save() {
         this.$refs.form.validate((valid) => {
-          console.log(valid);
           if (valid) {
-            this.cancel();
-          } else {
+            this.setFormtime();
+            saveOrUpdate(this.form.list).then((res) => {
+              this.$message.success('保存成功');
+              this.$emit('reload');
+              this.cancel();
+            });
           }
         });
       },

+ 29 - 20
src/views/productionScheduling/workCalendar/index.vue

@@ -26,16 +26,12 @@
           </el-form-item>
 
           <el-form-item label="产线名称:" prop="productionLineId">
-            <el-select
-              v-model="form.productionLineId"
-              placeholder="请选择"
-              @change="change_productionLine"
-            >
+            <el-select v-model="form.productionLineId" placeholder="请选择">
               <el-option
                 v-for="item in productionLineList"
                 :label="item.name"
                 :value="item.id"
-                @click.native="form.productionLineName = item.name"
+                @click.native="change_productionLine(item)"
                 :key="item.id"
               ></el-option>
             </el-select>
@@ -127,7 +123,7 @@
           size="small"
           type="primary"
           class="ele-btn-icon"
-          @click="edit"
+          @click="edit()"
         >
           编辑
         </el-button>
@@ -135,7 +131,6 @@
       <searchTable
         :productionLineList="productionLineList"
         :productionShiftList="productionShiftList"
-        :workStationList="workStationList"
         @search="search"
       ></searchTable>
 
@@ -151,18 +146,18 @@
         @columns-change="handleColumnChange"
         :cache-key="cacheKeyUrl"
         style="margin-top: 10px"
-        row-key="key"
+        row-key="id"
       >
-        <!-- <template v-slot:action="{ row }">
+        <template v-slot:action="{ row }">
           <el-link
             type="primary"
             :underline="false"
             icon="el-icon-edit"
-            @click="handleAddOrEdit(row)"
+            @click="edit(row)"
           >
-            修改班次
+            修改
           </el-link></template
-        > -->
+        >
       </ele-pro-table>
     </el-card>
 
@@ -178,7 +173,7 @@
       @reload="reload"
       :isNotNeedProcess="false"
     ></process-submit-dialog> -->
-    <timeTable ref="timeTableRef"></timeTable>
+    <timeTable ref="timeTableRef" @reload="reload"></timeTable>
   </div>
 </template>
 
@@ -393,11 +388,23 @@
       }
     },
     methods: {
-      edit() {
-        this.$refs.timeTableRef.init(this.selection.map(item=>item.id), 'edit');
+      edit(row) {
+        if (row?.id) {
+          this.$refs.timeTableRef.init([row?.id], 'edit');
+        } else {
+          this.$refs.timeTableRef.init(
+            this.selection.map((item) => item.id),
+            'edit'
+          );
+        }
       },
       /* 表格数据源 */
       datasource({ page, limit, where, order }) {
+        if (this.selectedDates.length) {
+          where.dayDate = this.selectedDates.map(
+            (item) => item.toISOString().split('T')[0]
+          );
+        }
         return getTableList({
           pageNum: page,
           size: limit,
@@ -493,10 +500,13 @@
         this.form.productionLineName = '';
         this.getProductionLine();
       },
-      change_productionLine() {
+      change_productionLine(item) {
         this.form.workStationId = '';
         this.form.workStationName = '';
-        this.getFactoryworkstation();
+        this.form.productionLineName = item.name;
+        if (item.productionSchedulingDimension) {
+          this.getFactoryworkstation();
+        }
       },
       //根据排程维度获取初始化列表
       async getInitList() {
@@ -599,8 +609,7 @@
         saveOrUpdate(this.list).then((res) => {
           this.search({
             productionLineId: this.form.productionLineId,
-            workStationId: this.form.workStationId,
-            dayDate: this.form.dayDate
+            workStationId: this.form.workStationId
           });
         });
       },