浏览代码

feaute/维修页面构建

dy 1 年之前
父节点
当前提交
395156864a

+ 1 - 1
.env.development

@@ -13,7 +13,7 @@ VITE_APP_UPLOAD_URL = 'http://192.168.101.4:9000'
 # 线上接口地址
 # VITE_APP_API_URL = http://vapi.youlai.tech
 # 开发接口地址
- VITE_APP_API_URL = 'http://192.168.101.90:8079'
+ VITE_APP_API_URL = 'http://192.168.101.4:8079'
 
 ``
 # 是否启用 Mock 服务

+ 24 - 0
src/api/repair/index.ts

@@ -0,0 +1,24 @@
+import request from "@/utils/request";
+
+/**
+ * 通过id获取报故详情
+ *
+ * @param queryParams
+ */
+export function getEscalationFaultById(id: any) {
+  return request({
+    url: "/api/v1/process/escalationFault/get/" + `${id}`,
+    method: "get",
+  });
+}
+/**
+ * 获取报故列表
+ *
+ */
+export function getEscalationFaultList(data: any) {
+  return request({
+    url: "/api/v1/process/escalationFault/processInfo/list",
+    method: "post",
+    data,
+  });
+}

+ 6 - 19
src/layout/components/header.vue

@@ -1,12 +1,7 @@
 <template>
   <div class="commonHeader">
     <div style="width: 155px">
-      <svg-icon
-        v-if="routeMeta.back"
-        icon-class="back"
-        size="48"
-        @click="commonBack"
-      />
+      <svg-icon v-if="routeMeta.back" icon-class="back" size="48" @click="commonBack" />
       <svg-icon v-else icon-class="LOGO" style="height: 48px; width: 155px" />
     </div>
     <div v-if="routeMeta.back && routeMeta.title" class="middle-title">
@@ -19,11 +14,7 @@
     <div>
       <el-space>
         <div class="task">
-          <el-progress
-            :percentage="processCount"
-            :show-text="false"
-            :stroke-width="10"
-          />
+          <el-progress :percentage="processCount" :show-text="false" :stroke-width="10" />
           <div class="process">任务进度: {{ processCount }}%</div>
         </div>
         <div>
@@ -31,11 +22,7 @@
           <div class="work">gongwei</div>
         </div>
 
-        <el-dropdown
-          ref="dropdown1"
-          trigger="contextmenu"
-          @command="handleCommand"
-        >
+        <el-dropdown ref="dropdown1" trigger="contextmenu" @command="handleCommand">
           <img v-if="headUrl" :src="headUrl" alt="" @click="showClick" />
           <svg-icon v-else icon-class="head" size="48" @click="showClick" />
           <template #dropdown>
@@ -176,9 +163,9 @@ const handleCommand = (command: string | number | object) => {
   }
 }
 
-:deep(.el-dropdown__popper .el-dropdown__list) {
-  width: 292px !important;
-  background: #f1f3f5;
+:deep(.el-popper) {
+  width: 400px !important;
+  background: #red;
   box-shadow: 0px 0px 29px 4px rgba(0, 0, 0, 0.25);
   border-radius: 30px;
   overflow: hidden;

+ 1 - 0
src/store/index.ts

@@ -19,4 +19,5 @@ export * from "./modules/user";
 export * from "./modules/common";
 export * from "./modules/processView";
 export * from "./modules/dictionary";
+export * from "./modules/repair";
 export { store };

+ 17 - 0
src/store/modules/repair.ts

@@ -0,0 +1,17 @@
+import { store } from "@/store";
+export const useRepairStore = defineStore(
+  "repair",
+  () => {
+    const odersData = ref<any>({});
+    const repairInfo = ref<any>({});
+    const scanInfo = ref<any>({});
+    return { odersData, repairInfo, scanInfo };
+  },
+  {
+    //开启持久化存储
+    persist: true,
+  }
+);
+export function useRepairStoreHook() {
+  return useRepairStore(store);
+}

+ 2 - 3
src/views/pro-steps/components/shebeijilu.vue

@@ -10,7 +10,7 @@
       </div>
       <!-- 变量控制样式 -->
       <div class="footerBtn">
-        <el-button v-if="true" class="bottomBtn" style="background-color: #0a59f7">点击扫描设备</el-button>
+        <el-button v-if="!item.equitCode" class="bottomBtn" style="background-color: #0a59f7">点击扫描设备</el-button>
         <div v-else class="infoBox">
           <div class="info">
             <div>
@@ -51,7 +51,6 @@ const getEquitList = async () => {
     pageSize: 9999,
     pageNo: 1,
   });
-  equitListData.value = [...data, ...data];
 };
 const equitCheck = async () => {
   await equitUpdate({});
@@ -63,7 +62,7 @@ onMounted(() => {
 
 <style lang="scss" scoped>
 .recordBox {
-  width: 600px;
+  min-width: 600px;
   height: 210px;
   background-color: white;
   border-radius: 16px;

+ 3 - 1
src/views/pro-steps/index.vue

@@ -126,7 +126,9 @@ const getNameClass = (index) => {
 };
 //获取当前tags列表
 const getOpCompentArray = async () => {
-  const { data } = await getOpCompent("/129/12");
+  const { data } = await getOpCompent(
+    "/" + `${store.odersData.operationId}` + "/" + `${store.scanInfo.id}`
+  );
   stepComponents.value = setStepComponents(data);
   router.replace({ name: stepComponents.value[0].name });
 };

+ 146 - 0
src/views/repair/components/info.vue

@@ -0,0 +1,146 @@
+<template>
+  <div class="commonTitle">故障详情</div>
+  <el-scrollbar class="barHeight">
+    <div class="textItem" v-for="(item, index) in infoTopData" :key="index">
+      <div class="left describeText">{{ item.bond }}</div>
+      <div class="right describeText">
+        {{ showInfoValue(item.value) ? showInfoValue(item.value) : "-" }}
+      </div>
+    </div>
+    <el-divider />
+    <div class="textItem" v-for="(item, index) in infoBottomData" :key="index">
+      <div class="left describeText">{{ item.bond }}</div>
+      <div class="right describeText">
+        {{ showInfoValue(item.value) ? showInfoValue(item.value) : "-" }}
+      </div>
+    </div>
+  </el-scrollbar>
+</template>
+<script lang="ts" setup>
+import { getEscalationFaultById } from "@/api/repair";
+const ordersDataArray = inject("ordersDataArray");
+const selectOrderIndex = inject("selectOrderIndex");
+const infoData = ref({  });
+const showInfoValue = (value: string) => {
+  return infoData.value[value];
+};
+const getInfoData = async (id: any) => {
+  const { data } = await getEscalationFaultById(id);
+  infoData.value = data;
+};
+const infoTopData = [
+  {
+    bond: "产品名称",
+    value: "materialName",
+  },
+  {
+    bond: "型号",
+    value: "spec",
+  },
+  {
+    bond: "产品图号",
+    value: "faultNumber",
+  },
+  {
+    bond: "产品代号",
+    value: "materialCode",
+  },
+  {
+    bond: "阶段",
+    value: "stageDictValue",
+  },
+];
+const infoBottomData = [
+  {
+    bond: "单据编号",
+    value: "",
+  },
+  {
+    bond: "归档编号",
+    value: "archiveNumber",
+  },
+  {
+    bond: "工作令号",
+    value: "workOrderNumber",
+  },
+  {
+    bond: "批次",
+    value: "",
+  },
+  {
+    bond: "跟踪卡号",
+    value: "",
+  },
+  {
+    bond: "日期",
+    value: "created",
+  },
+  {
+    bond: "生产数量",
+    value: "planNum",
+  },
+  {
+    bond: "不合格品数量",
+    value: "unqualifiedNum",
+  },
+  {
+    bond: "不合格品分布情况及工序",
+    value: "processes",
+  },
+  {
+    bond: "不合格原因分类",
+    value: "reason",
+  },
+  {
+    bond: "责任/经办者",
+    value: "personResponsible",
+  },
+  {
+    bond: "检验员",
+    value: "userName",
+  },
+  {
+    bond: "是否首检",
+    value: "firstInspection",
+  },
+  {
+    bond: "特征和程度",
+    value: "",
+  },
+  {
+    bond: "处置措施",
+    value: "disposalMeasures",
+  },
+];
+
+watch(selectOrderIndex, () => {
+  getInfoData(ordersDataArray[selectOrderIndex].id);
+});
+</script>
+
+<style lang="scss" scoped>
+.describeText {
+  line-height: 30px;
+}
+
+.barHeight {
+  height: calc(100vh - 184px);
+}
+
+.textItem {
+  width: 100%;
+  display: flex;
+
+  .left {
+    width: 220px;
+    display: inline-block;
+    text-align: right;
+  }
+
+  .right {
+    flex: 1;
+    margin-left: $p10;
+    color: black;
+  }
+}
+</style>

+ 123 - 0
src/views/repair/main/components/currentOrderInfo.vue

@@ -0,0 +1,123 @@
+<template>
+  <div class="commonTitle">不合格品状况</div>
+  <div class="body">
+    <div class="box">
+      <div class="boxContent">
+        <div class="contentHeader">
+          <img class="imgIcon" src="@/assets/icons/jinrijihua.svg" />
+          <span class="headerText">待处理报故</span>
+        </div>
+        <div class="contentNum">100</div>
+      </div>
+    </div>
+    <div class="box">
+      <div class="boxContent">
+        <div class="contentHeader">
+          <img class="imgIcon" src="@/assets/icons/jinriwancheng.svg" />
+          <span class="headerText">审理中</span>
+        </div>
+        <div class="contentNum">100</div>
+      </div>
+    </div>
+    <div class="box" style="position: absolute; left: 0; bottom: 0">
+      <div class="boxContent">
+        <div class="contentHeader">
+          <img class="imgIcon" src="@/assets/icons/zhuliaoqitao.svg" />
+          <span class="headerText">待维修产品</span>
+        </div>
+        <div class="contentNum">100</div>
+      </div>
+    </div>
+    <div class="box" style="position: absolute; right: 0; bottom: 0">
+      <div class="boxContent activeBoxContent">
+        <div class="contentHeader">
+          <img class="imgIcon" src="@/assets/icons/jinribaogu.svg" />
+          <span class="headerText">维修历史</span>
+        </div>
+        <div class="contentNum">100</div>
+      </div>
+    </div>
+    <div class="horizontalLine"></div>
+    <div class="verticalLine"></div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { reactive, ref } from "vue";
+</script>
+
+<style lang="scss" scoped>
+.body {
+  width: 100%;
+  height: calc(100% - 60px);
+  position: relative;
+
+  .box {
+    display: inline-block;
+    box-sizing: border-box;
+    width: 50%;
+    height: 50%;
+    padding: 10px;
+
+    .boxContent {
+      border-radius: 16px;
+
+      width: calc(100% - 5px);
+      height: calc(100% - 5px);
+      position: relative;
+
+      .contentHeader {
+        display: flex;
+        align-items: center;
+        width: 100%;
+        height: 30px;
+        position: absolute;
+        top: 5px;
+        left: 5px;
+
+        //控制icon大小
+        .imgIcon {
+          width: 32px;
+          height: 32px;
+        }
+
+        .headerText {
+          font-size: $f20;
+          color: $font-default-60;
+          margin-left: 5px;
+        }
+      }
+
+      .contentNum {
+        font-size: $f60;
+        line-height: 60px;
+        position: absolute;
+        bottom: 1px;
+        width: 100%;
+        text-align: center;
+      }
+    }
+
+    .activeBoxContent {
+      background-color: white;
+    }
+  }
+
+  .horizontalLine {
+    width: 100%;
+    height: 1px;
+    border-bottom: 1px solid #00000020;
+    position: absolute;
+    top: 50%;
+  }
+
+  .verticalLine {
+    height: 80%;
+    width: 1px;
+    border-right: 1px solid #00000020;
+    position: absolute;
+    top: 10%;
+    right: 50%;
+  }
+}
+</style>

+ 56 - 0
src/views/repair/main/components/currentProduction.vue

@@ -0,0 +1,56 @@
+<template>
+  <div class="setFlex">
+    <el-row :gutter="20">
+      <el-col :span="12" class="elColClasss" style="height: 310px" >
+        <CurrentOrderInfo />
+      </el-col>
+      <el-col :span="12" class="elColClasss" style="height: 310px">
+        <Operate />
+      </el-col>
+    </el-row>
+    <ScanCode />
+  </div>
+</template>
+<script lang="ts" setup>
+import CurrentOrderInfo from "@/views/repair/main/components/currentOrderInfo.vue";
+import Operate from "@/views/repair/main/components/operate.vue";
+import ScanCode from "@/views/repair/main/components/scanCode.vue";
+import { useRepairStore } from "@/store";
+
+const store = useRepairStore();
+const router = useRouter();
+const orderData = {};
+
+</script>
+
+<style lang="scss" scoped>
+.barHeight {
+  height: calc(100vh - 270px);
+}
+
+.setFlex {
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  height: calc(100vh - 120px);
+  overflow: hidden;
+}
+
+.bottomBtn {
+  height: 80px;
+  margin-top: 10px;
+  width: 100%;
+  display: flex;
+
+  .btn {
+    width: 100%;
+    height: 80px;
+    border-radius: 40px;
+
+    .btnText {
+      font-size: $f24;
+      color: white;
+    }
+  }
+}
+</style>

+ 56 - 0
src/views/repair/main/components/operate.vue

@@ -0,0 +1,56 @@
+<template>
+
+  <div class="commonTitle">操作</div>
+  <div class="body">
+    <div class="operateBox">
+      <span class="operateText">物料流转</span>
+      <svg-icon icon-class="liuzhuan" size="30" />
+    </div>
+    <div class="operateBox">
+      <span class="operateText">取暂存料</span>
+      <div class="operateSum">
+        <span>0</span>
+      </div>
+    </div>
+    <div class="operateBox">
+      <span class="operateText">生产履历</span>
+      <svg-icon icon-class="shengchanlvli" size="30" />
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { reactive, ref } from "vue";
+</script>
+
+<style lang="scss" scoped>
+.body {
+  width: 100%;
+  height: 250px;
+
+  .operateBox {
+    height: 76px;
+    width: 100%;
+    margin-bottom: 10px;
+    background-color: white;
+    border-radius: 16px;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 0 20px;
+
+    .operateText {
+      font-size: $f24;
+    }
+
+    .operateSum {
+      @include flex;
+
+      span {
+        font-size: $f24;
+        font-weight: bold;
+      }
+    }
+  }
+}
+</style>

+ 120 - 0
src/views/repair/main/components/order.vue

@@ -0,0 +1,120 @@
+<template>
+  <div :class="hoverStatus ? 'body bodyHover ' : 'body'">
+    <div class="box">
+      <div>
+        <div class="productName">{{ item.materialName }}</div>
+        <div class="productMsg">
+          <span :class="hoverStatus ? 'msgName msgNameHover' : 'msgName'">产品型号</span>
+          <span class="msgValue">{{ item.materialCode }}</span>
+        </div>
+      </div>
+
+      <div>
+        <div style="display: flex; width: 100%; justify-content: space-between">
+          <div class="productMsg" style="width: 50%">
+            <span :class="hoverStatus ? 'msgName msgNameHover' : 'msgName'">不合格数</span>
+            <span class="msgValue">{{ item.unqualifiedNum }}</span>
+          </div>
+          <div class="productMsg" style="width: 50%">
+            <span :class="hoverStatus ? 'msgName msgNameHover' : 'msgName'">已维修数</span>
+            <span class="msgValue">{{ item.endNum }}</span>
+          </div>
+        </div>
+
+        <div class="productMsg">
+          <span :class="hoverStatus ? 'msgName msgNameHover' : 'msgName'">审理时间</span>
+          <span class="msgValue">{{ item.handleTime }}</span>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { reactive, ref } from "vue";
+
+defineProps<{
+  hoverStatus?: boolean;
+  item: object;
+}>();
+</script>
+
+<style lang="scss" scoped>
+.body {
+  position: relative;
+  width: 100%;
+  height: 244px;
+  border-radius: 16px;
+  margin-bottom: 10px;
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  padding: 30px;
+  background-color: #ffffff;
+}
+
+.box {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+}
+
+.bodyHover {
+  background-color: $select-hover;
+  color: white;
+}
+
+.boxTextHover {
+  color: white !important;
+}
+
+.productName {
+  font-size: $f24;
+}
+
+.msgName {
+  font-size: $f20;
+  color: $font-default-60;
+}
+
+.msgNameHover {
+  color: white !important;
+}
+
+.msgValue {
+  margin-left: 5px;
+  font-size: $f20;
+}
+
+.bottomArea {
+  height: 60px;
+}
+
+.bottomBox {
+  width: 80px;
+  display: inline-block;
+}
+
+.textDivider {
+  display: inline-block;
+
+  .dividerBox {
+    height: 60px;
+    display: flex;
+  }
+}
+
+.boxNum {
+  text-align: center;
+  line-height: 38px;
+  font-size: $f38;
+}
+
+.boxText {
+  text-align: center;
+  font-size: $f20;
+  line-height: 20px;
+  color: $font-default-60;
+}
+</style>

+ 46 - 0
src/views/repair/main/components/orders.vue

@@ -0,0 +1,46 @@
+<template>
+  <div class="commonTitle">待维修产品[{{ ordersSum }}]</div>
+  <el-scrollbar class="barHeight">
+    <Order v-for="(item, index) in ordersDataArray" :key="index" @click="setSlectIndex(index)"
+      :hoverStatus="index == selectIndex ? true : false" :item="item" />
+    <el-empty v-if="!ordersDataArray" description="暂无数据" />
+  </el-scrollbar>
+</template>
+<script lang="ts" setup>
+import Order from "@/views/repair/main/components/order.vue";
+import { useRepairStore } from "@/store";
+
+const store = useRepairStore();
+const props = defineProps<{
+  ordersSum?: number;
+}>();
+const emit = defineEmits(["getindex"]);
+const ordersDataArray = inject("ordersDataArray");
+const selectIndex = ref(0);
+const setSlectIndex = (value: number) => {
+  selectIndex.value = value;
+  emit("getindex", value);
+};
+
+watch(ordersDataArray, () => {
+  if (ordersDataArray.value.length > 0) setSlectIndex(0);
+});
+</script>
+
+<style lang="scss" scoped>
+.barHeight {
+  height: calc(100vh - 170px);
+}
+
+.scrollbar-demo-item {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  height: 50px;
+  margin: 10px;
+  text-align: center;
+  border-radius: 4px;
+  background: var(--el-color-primary-light-9);
+  color: var(--el-color-primary);
+}
+</style>

+ 54 - 0
src/views/repair/main/components/scanCode.vue

@@ -0,0 +1,54 @@
+<template>
+  <!-- 扫码板块 -->
+  <div class="commonTitle">扫码</div>
+  <div class="icon">
+    <img class="imgIcon" src="@/assets/icons/shaoma.svg" @click="toProSteps" />
+  </div>
+  <div class="body">
+    <ScanCodeInput v-model="inputValue" @setinputvalue="setInputValue" @enterfnc="toProSteps" />
+  </div>
+</template>
+
+<script lang="ts" setup>
+import ScanCodeInput from "@/components/ScanCodeInput/index.vue";
+import { useRepairStore } from "@/store";
+
+
+import { getScan } from "@/api/process";
+const store = useRepairStore();
+const router = useRouter();
+const inputValue = ref("12020100000052404100011");
+const toProSteps = () => {
+  store.odersData.qrCode = inputValue.value;
+  getScanData();
+};
+const setInputValue = (value: any) => {
+  inputValue.value = value;
+};
+const getScanData = async () => {
+  // const { code, data, msg } = await getScan({
+  //   operationId: Number(store.odersData.operationId),
+  //   qrCode: store.odersData.qrCode,
+  //   workOrderCode: store.odersData.workOrderCode,
+  //   //stationId暂时随便传一个
+  //   stationId: 1,
+  // });
+  // if (code == "200") {
+  //   store.scanInfo = data;
+  //   router.push({ path: "/pro-steps" });
+  // }
+  router.push({ path: "/repair/operation" });
+};
+</script>
+
+<style lang="scss" scoped>
+.icon {
+  @include flex;
+  height: 120px;
+
+  .imgIcon {
+    width: 100px;
+    height: 100px;
+  }
+}
+</style>

+ 58 - 3
src/views/repair/main/index.vue

@@ -1,7 +1,62 @@
 <template>
-  <div>src/views/repair/main /index</div>
+  <div class="mainContentBox">
+    <el-row :gutter="20">
+      <el-col :span="6" class="elColClasss">
+        <Orders :ordersSum="ordersSum" @getindex="setSelectOrderIndex" />
+      </el-col>
+      <el-col :span="6" class="elColClasss">
+        <div class="grid-content ep-bg-purple">
+          <Info />
+        </div>
+      </el-col>
+      <el-col :span="12" class="elColClasss">
+        <div class="grid-content ep-bg-purple">
+          <CurrentProduction />
+        </div>
+      </el-col>
+    </el-row>
+  </div>
 </template>
 
-<script lang="ts" setup></script>
+<script lang="ts" setup>
+import Orders from "@/views/repair/main/components/orders.vue";
+import Info from "@/views/repair/components/info.vue";
+import CurrentProduction from "@/views/repair/main/components/currentProduction.vue";
+import { getEscalationFaultList } from "@/api/repair";
+import { useRepairStore } from "@/store";
+const store = useRepairStore();
 
-<style lang="scss" scoped></style>
+defineOptions({ name: "RepairMain" });
+const ordersDataArray = ref([]);
+const ordersSum = ref(0);
+const selectOrderIndex = ref(NaN);
+const setSelectOrderIndex = (value: number) => {
+  selectOrderIndex.value = value;
+};
+provide("ordersDataArray", ordersDataArray);
+provide("selectOrderIndex", selectOrderIndex);
+const ordersQuery = ref({
+  orders: [],
+  pageNo: 1,
+  pageSize: 9999,
+  state: "1", //'1'待处理'2'已处理
+});
+
+//获取待处理Data
+const getOrdersData = async () => {
+  const { code, data } = await getEscalationFaultList(ordersQuery.value);
+  if (code == "200") {
+    ordersDataArray.value = data.records;
+    ordersSum.value = data.totalCount;
+  }
+};
+onMounted(() => {
+  getOrdersData();
+});
+</script>
+
+<style lang="scss" scoped>
+.elColClasss {
+  height: calc(100vh - 130px);
+}
+</style>

+ 26 - 0
src/views/repair/operation/components/Jiluxiang.vue

@@ -0,0 +1,26 @@
+<template>
+  <!-- <MaterialCollectionDG ref="MaterialCollectionDGRef" />
+  <el-button @click="handleClick">物料采集</el-button>
+  <el-input v-model="input" style="width: 240px" placeholder="Please input" /> -->
+
+  <el-scrollbar style="padding-bottom: 24px">
+    <LeftBarInfo />
+    <Operates />
+  </el-scrollbar>
+</template>
+
+<script lang="ts" setup>
+// import MaterialCollectionDG from "@/components/CommonDialogs/MaterialCollectionDG.vue";
+import LeftBarInfo from "./leftBarInfo.vue";
+import Operates from "./operates.vue";
+const input = ref("aa");
+// const MaterialCollectionDGRef = ref<any>(null);
+// const handleClick = () => {
+//   MaterialCollectionDGRef.value &&
+//     MaterialCollectionDGRef.value.showMCDG("", () => {
+//       console.log("采集成功");
+//     });
+// };
+</script>
+
+<style lang="scss" scoped></style>

+ 89 - 0
src/views/repair/operation/components/leftBarInfo.vue

@@ -0,0 +1,89 @@
+<template>
+  <div class="containerBox">
+    <div class="textBox">
+      <el-tooltip class="box-item" effect="dark" :content="processInfo.materialName" placement="left" trigger="click">
+        <div class="titleText blackColor">
+          {{ processInfo.materialName }}
+        </div>
+      </el-tooltip>
+      <el-tooltip class="box-item" effect="dark" :content="processInfo.materialModel" placement="left" trigger="click">
+        <div class="simpleText greyColor">
+          {{ processInfo.materialModel }}
+        </div>
+      </el-tooltip>
+    </div>
+    <div class="textBox" style="margin: 10px 0">
+      <div class="simpleText greyColor">序列号</div>
+      <el-tooltip class="box-item" effect="dark" :content="processInfo.operationCode" placement="left" trigger="click">
+        <div class="simpleText blackColor">
+          {{ processInfo.operationCode }}
+        </div>
+      </el-tooltip>
+    </div>
+    <div class="textBox">
+      <div class="simpleText greyColor">当前工序</div>
+      <el-tooltip class="box-item" effect="dark" :content="processInfo.operationName" placement="left" trigger="click">
+        <div class="simpleText blackColor">维修</div>
+      </el-tooltip>
+    </div>
+    <svg-icon icon-class="jiaobiao" size="25" class="svgStyle" />
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { useProcessStore } from "@/store";
+const store = useProcessStore();
+const processInfo = ref({ materialName: "...", materialModel: "..." });
+onMounted(() => {
+  processInfo.value = store.processInfo;
+});
+</script>
+
+<style lang="scss" scoped>
+.svgStyle {
+  position: absolute;
+  bottom: 0;
+  right: 0;
+}
+
+.containerBox {
+  width: 100%;
+  height: 200px;
+  border-radius: 16px;
+  background-color: white;
+  padding: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: space-around;
+  position: relative;
+
+  .textBox {
+    .titleText {
+      font-size: $f24;
+      line-height: 24px;
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      cursor: pointer;
+    }
+
+    .simpleText {
+      font-size: $f20;
+      line-height: 20px;
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      cursor: pointer;
+      max-width: 100%;
+    }
+  }
+}
+
+.blackColor {
+  font-weight: $Medium;
+}
+
+.greyColor {
+  color: $font-default-60;
+}
+</style>

+ 116 - 0
src/views/repair/operation/components/operates.vue

@@ -0,0 +1,116 @@
+<template>
+  <div class="containerBox">
+    <div v-for="(item, index) in stepComponents" :key="index"
+      :class="selectIndex == index ? 'operator active' : 'operator'" @click="setIndex(index)">
+      <div class="operatorText">{{ item.compentName }}</div>
+      <div class="operatorIcon">
+        <svg-icon :icon-class="item.compentType" size="45" />
+      </div>
+    </div>
+
+    <ReportBreak ref="reportBreakRef" />
+    <ReportWork ref="reportWorkRef" />
+  </div>
+</template>
+
+<script lang="ts" setup>
+import ReportBreak from "@/views/pro-operation/report-break/index.vue"; // ================ 报故
+import ReportWork from "@/views/pro-operation/report-work/index.vue"; // = 报工
+// ================ 报故
+const reportBreakRef = ref<InstanceType<typeof ReportBreak>>();
+
+// ================ 报工
+const reportWorkRef = ref<InstanceType<typeof ReportWork>>();
+
+const router = useRouter();
+
+const selectIndex = ref(0);
+const setIndex = (index: number) => {
+  selectIndex.value = index;
+  switch (stepComponents.value[index].compentType) {
+    case "baogu":
+      reportBreakRef.value?.openReportBreakDrawer();
+      break;
+    case "jiaoliao":
+      router.push({ name: "call-materiel" });
+      break;
+    case "gongweishangliao":
+      break;
+    case "liuzhuan":
+      break;
+    case "tuzhi":
+      router.push({ name: "drawing-list" });
+      break;
+    case "weiwai":
+      break;
+    case "baogong":
+      reportWorkRef.value?.openReportWorkDrawer();
+      break;
+    default:
+      break;
+  }
+};
+
+const stepComponents = ref([
+  {
+    compentName: "叫料",
+    compentType: "jiaoliao",
+  },
+  {
+    compentName: "工位上料",
+    compentType: "gongweishangliao",
+  },
+  {
+    compentName: "物料流转",
+    compentType: "liuzhuan",
+  },
+  {
+    compentName: "图纸",
+    compentType: "tuzhi",
+  },
+  {
+    compentName: "委外",
+    compentType: "weiwai",
+  },
+  {
+    compentName: "报故",
+    compentType: "baogu",
+  },
+  {
+    compentName: "报工",
+    compentType: "baogong",
+  },
+]);
+</script>
+
+<style lang="scss" scoped>
+.containerBox {
+  width: 100%;
+  font-weight: $Medium;
+
+  .operator {
+    width: 100%;
+    height: 88px;
+    border-radius: 16px;
+    background-color: white;
+    margin-top: 20px;
+    display: flex;
+    padding: 20px;
+    justify-content: space-between;
+    align-items: center;
+
+    .operatorText {
+      font-size: $f24;
+    }
+
+    .operatorIcon {
+      font-weight: 800;
+    }
+  }
+}
+
+.active {
+  background-color: #64bb5c !important;
+  color: white;
+}
+</style>

+ 69 - 0
src/views/repair/operation/components/replacement.vue

@@ -0,0 +1,69 @@
+<template>
+  <div class="commonTitle">物料替换</div>
+  <div class="scanBox">
+    <ScanCodeInput class="scanBoxInput" v-model="scanCode" />
+  </div>
+  <el-scrollbar class="scrollbarHeight">
+    <div class="item" v-for="item in 7" @click="openPop">
+      <div class="titleText">1</div>
+      <div class="describleText">2</div>
+      <div class="bottomText">
+        <div class="describleText" style="width: 100px">213</div>
+        <div class="bottomStyle">
+          <div class="describleText">123</div>
+          <div class="describleText">123</div>
+          <div class="describleText">123</div>
+        </div>
+      </div>
+    </div>
+  </el-scrollbar>
+  <ReplacePop v-model="showStatus" />
+</template>
+<script lang="ts" setup>
+import { getEscalationFaultById } from "@/api/repair";
+import ReplacePop from "@/views/repair/popUpView/replacePop.vue";
+const scanCode = ref("");
+const showStatus = ref(false);
+const openPop = () => {
+  showStatus.value = true;
+};
+</script>
+
+<style lang="scss" scoped>
+.scanBox {
+  height: 50px;
+  margin-bottom: $p10;
+
+  .scanBoxInput {
+    width: 60%;
+    min-width: 250px;
+  }
+}
+
+.scrollbarHeight {
+  height: calc(100vh - 244px);
+
+  .item {
+    background-color: white;
+    border-radius: 16px;
+    height: 140px;
+    padding: $p20;
+    display: flex;
+    flex-direction: column;
+    justify-content: space-between;
+    margin-bottom: $p20;
+
+    .bottomText {
+      display: flex;
+      width: 80%;
+
+      .bottomStyle {
+        flex: 1;
+        display: flex;
+        justify-content: space-between;
+        width: 60%;
+      }
+    }
+  }
+}
+</style>

+ 195 - 3
src/views/repair/operation/index.vue

@@ -1,7 +1,199 @@
 <template>
-  <div>src/views/repair/operation /index</div>
+  <div class="mainContentBox">
+    <el-row :gutter="20">
+      <el-col :span="4" class="boxStyle">
+        <!-- 侧边栏盒子 -->
+        <Jiluxiang />
+      </el-col>
+      <el-col :span="8">
+        <div class="grid-content ep-bg-purple">
+          <Info />
+        </div>
+      </el-col>
+      <el-col :span="12">
+        <div class="grid-content ep-bg-purple">
+          <Replacement />
+        </div>
+      </el-col>
+    </el-row>
+  </div>
 </template>
 
-<script lang="ts" setup></script>
+<script setup>
+import Jiluxiang from "@/views/repair/operation/components/Jiluxiang.vue";
+import Replacement from "@/views/repair/operation/components/replacement.vue";
+import { useRepairStore } from "@/store";
+import Info from "@/views/repair/components/info.vue";
+import { getOpCompent } from "@/api/prosteps";
 
-<style lang="scss" scoped></style>
+defineOptions({ name: "ProSteps" });
+const store = useRepairStore();
+const route = useRoute();
+const router = useRouter();
+const loading = ref(false);
+
+//配置标签信息Data
+const stepComponents = ref([]);
+const defaultComponents = [
+  {
+    compentName: "物料采集",
+    iconName: "wuliaocaiji",
+    path: "wuliaocaiji",
+    name: "Wuliaocaiji",
+  },
+  {
+    compentName: "记录项",
+    iconName: "jiluxiang",
+    path: "jiluxiang",
+    name: "Jiluxiang",
+  },
+  {
+    compentName: "多媒体采集",
+    iconName: "duomeiticaiji",
+    path: "duomeiticaiji",
+    name: "Duomeiticaiji",
+  },
+  {
+    compentName: "ESOP",
+    iconName: "ESOP",
+    path: "esop",
+    name: "Esop",
+  },
+  {
+    compentName: "点检",
+    iconName: "dianjian",
+    path: "dianjian",
+    name: "Dianjian",
+  },
+  {
+    compentName: "设备记录",
+    iconName: "shebeijilu",
+    path: "shebeijilu",
+    name: "Shebeijilu",
+  },
+  {
+    compentName: "紧固",
+    iconName: "jingu",
+    path: "jingu",
+    name: "Jingu",
+  },
+  {
+    compentName: "调试配对",
+    iconName: "tiaoshipipei",
+    path: "tiaoshipipei",
+    name: "Tiaoshipipei",
+  },
+  {
+    compentName: "铭牌绑定",
+    iconName: "mingpai",
+    path: "mingpaibangding",
+    name: "Mingpaibangding",
+  },
+];
+//当前路由在setpComponents中的index
+const selectIndex = ref(0);
+
+//配置data固定路由参数等
+const setStepComponents = (data) => {
+  let resData = [];
+  data.forEach((item) => {
+    defaultComponents.forEach((obj) => {
+      if (item.compentName === obj.compentName) {
+        resData.push({ ...item, ...obj });
+      }
+    });
+  });
+  return resData;
+};
+const getNameClass = (index) => {
+  return index === selectIndex.value ? "typeBoxSelected" : "typeBoxNormal";
+};
+//获取当前tags列表
+const getOpCompentArray = async () => {
+  const { data } = await getOpCompent("/129/12");
+  stepComponents.value = setStepComponents(data);
+  router.replace({ name: stepComponents.value[0].name });
+};
+//设置标签是否被选中
+const setSelectIndex = (index) => {
+  selectIndex.value = index;
+};
+const setSelectTag = () => {
+  const nowRouteName = route.name;
+  stepComponents.value.forEach((item, index) => {
+    if (item.name == nowRouteName) {
+      setSelectIndex(index);
+    }
+  });
+};
+onMounted(async () => {
+  await getOpCompentArray();
+  setSelectTag();
+});
+</script>
+
+<style lang="scss" scoped>
+.boxStyle {
+  height: calc(100vh - 80px);
+}
+
+.scrollbar-demo-item {
+  flex-shrink: 0;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  height: 80px;
+  width: 135px;
+  border-radius: 16px;
+  text-align: center;
+}
+
+.typeContainer {
+  width: 100%;
+  height: 80px;
+  overflow-x: auto;
+
+  .svgIcon {
+    @include flex;
+  }
+}
+
+.routerView {
+  display: flex;
+  flex: 1;
+  overflow-y: auto;
+  width: 100%;
+  height: calc(100vh - 184px);
+}
+
+.typeBox {
+  height: 80px;
+  width: 135px;
+  border-radius: 16px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+
+  .name {
+    height: 16px;
+    font-weight: 500;
+    font-size: $f20;
+    line-height: 20px;
+    text-align: center;
+    font-style: normal;
+    text-transform: none;
+    margin-top: $p10;
+  }
+}
+
+.typeBoxNormal {
+  background: transparent;
+  color: rgba(0, 0, 0, 0.9);
+}
+
+.typeBoxSelected {
+  background: $select-hover;
+  color: white;
+}
+</style>

+ 137 - 0
src/views/repair/popUpView/replacePop.vue

@@ -0,0 +1,137 @@
+<template>
+  <div class="midPopUp" v-if="modelValue" @click.stop="handleClose">
+    <div class="container" @click.stop>
+      <div class="headerTittle">物料详情</div>
+      <div class="info tmInfo">
+        <div class="titleText">123123213</div>
+        <div class="describeText">scsadsada</div>
+      </div>
+      <el-scrollbar>
+        <div class="body" v-for="item in 7">
+          <div class="info titleText" @click="clickInfo">adadwad</div>
+        </div>
+      </el-scrollbar>
+    </div>
+  </div>
+  <ConfirmMessage ref="confirmMessageRef" />
+</template>
+
+<script lang="ts" setup>
+import { ref } from "vue";
+const emits = defineEmits(["update:modelValue"]);
+const props = defineProps<{
+  modelValue: {
+    type: Boolean;
+    default: false;
+  };
+}>();
+const scanCode = ref("");
+const handleClose = () => {
+  emits("update:modelValue", false);
+};
+const confirmMessageRef = ref(null);
+const clickInfo = () => {
+  confirmMessageRef.value?.showDialog(
+    "替换确认",
+    "是否替换:ASD1241234234为新的物料?",
+    "确定",
+    () => {
+      console.log("替换");
+    }
+  );
+};
+</script>
+
+<style lang="scss" scoped>
+.el-divider {
+  margin-top: 0;
+}
+
+.header {
+  @include flex;
+  width: 100%;
+  margin: $p10 0;
+
+  .inputBox {
+    width: 75%;
+  }
+}
+
+.describeText {
+  line-height: 25px !important;
+}
+
+.infoBox {
+  width: 100%;
+  height: 200px;
+  border-radius: 16px;
+  display: flex;
+  justify-content: space-between;
+  padding: $p20;
+  border-radius: 16px;
+
+  .leftInfo {
+    display: flex;
+    flex-direction: column;
+    justify-content: space-between;
+
+    div {
+      text-align: left !important;
+    }
+  }
+
+  .rightBox {
+    display: flex;
+    flex-direction: column;
+    justify-content: space-between;
+
+    .sumBox {
+      width: 180px;
+      height: 80px;
+      padding-bottom: 40px;
+      text-align: left;
+
+      .describeText {
+        text-align: left;
+        line-height: 30px;
+      }
+
+      .sum {
+        font-size: $f38;
+        font-weight: bold;
+        line-height: 20px;
+      }
+    }
+  }
+}
+
+.body {
+  padding: 0 $p20;
+  margin-bottom: $p10;
+}
+
+.info {
+  width: 100%;
+  height: 70px;
+  padding: 0 $p20;
+  background-color: white;
+  border-radius: 16px;
+  line-height: 70px;
+}
+
+.tmInfo {
+  background-color: transparent;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  margin: 0 $p20;
+
+  .titleText {
+    line-height: 30px;
+  }
+
+  .describeText {
+    text-align: left;
+  }
+}
+</style>

+ 1 - 0
vite.config.ts

@@ -20,6 +20,7 @@ import {
   dependencies,
   devDependencies,
 } from "./package.json";
+import { directiveHooks } from "@vueuse/core";
 
 /** 平台的名称、版本、运行所需的`node`版本、依赖、构建时间的类型提示 */
 const __APP_INFO__ = {