695593266@qq.com 9 luni în urmă
părinte
comite
54826631ac

+ 37 - 0
src/api/produce/turnover.js

@@ -0,0 +1,37 @@
+import request from '@/utils/request';
+
+// 保存or更新
+export async function saveOrEdit(data) {
+  const res = await request.post(`/main/asset/saveOrEdit`, data);
+  if (res.data.code == 0) {
+    return res.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 查询实例详情
+export async function getAssetInfo(id) {
+  const res = await request.get(`main/asset/getById/${id}`);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 生成批次
+export async function getCode(code) {
+  const res = await request.get(`/main/codemanage/getCode/${code}`);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 生成编码
+export async function getAssetNum(data) {
+  const res = await request.post(`/wms/outin/getAssetNum`, data);
+  if (res.data.code == 0) {
+    return res.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}

+ 7 - 4
src/views/produce/components/feeding/index.vue

@@ -522,12 +522,15 @@
           const index = this.teamList.findIndex(
             (item) => item.id == this.teamId
           );
+          console.log(this.teamAllList);
           this.teamUserList = this.teamAllList[index];
-          const res = this.teamUserList.find(
-            (it) => it.id == this.$store.state.user.info.userId
-          );
+          if (this.teamUserList) {
+            const res = this.teamUserList.find(
+              (it) => it.id == this.$store.state.user.info.userId
+            );
 
-          this.executorIdList.push(res.id);
+            this.executorIdList.push(res.id);
+          }
         }
       },
 

+ 10 - 7
src/views/produce/components/footBtn.vue

@@ -7,7 +7,11 @@
       :style="{ background: item.bjColor }"
       @click="footClick(item.type)"
     >
-      <img src="../../../assets/Frame.png" class="Frame" />
+      <img
+        src="../../../assets/Frame.png"
+        class="Frame"
+        v-if="item.type !== 'turnover'"
+      />
       {{ item.name }}
     </div>
   </div>
@@ -82,7 +86,7 @@
             name: '异常',
             type: 'error',
             bjColor: '#cc0000'
-          }
+          },
           // {
           //   name: 'BOM',
           //   type: 'bom',
@@ -93,11 +97,10 @@
           //   type: 'device',
           //   bjColor: '#008866'
           // },
-          // {
-          //   name: '周转车',
-          //   type: 'turnover',
-          //   bjColor: '#8C0044'
-          // }
+          {
+            type: 'turnover',
+            bjColor: '#E6F7E7'
+          }
         ],
         btnList2: [
           // {

+ 11 - 4
src/views/produce/components/jobBooking/index.vue

@@ -665,11 +665,18 @@
             (item) => item.id == this.teamId
           );
           this.teamUserList = this.teamAllList[index];
-          const res = this.teamUserList.find(
-            (it) => it.id == this.$store.state.user.info.userId
-          );
+          if (this.teamUserList) {
+            const res = this.teamUserList.find(
+              (it) => it.id == this.$store.state.user.info.userId
+            );
+
+            this.executorIdList.push(res.id);
+          }
+          // const res = this.teamUserList.find(
+          //   (it) => it.id == this.$store.state.user.info.userId
+          // );
 
-          this.executorIdList.push(res.id);
+          // this.executorIdList.push(res.id);
         }
       },
 

+ 18 - 10
src/views/produce/components/outsourcing/index.vue

@@ -109,6 +109,7 @@
             placeholder="请选择"
             style="width: 260px"
             @change="changeTaskId"
+            filterable
           >
             <el-option
               v-for="(item, index) in gysList"
@@ -440,10 +441,16 @@
           // this.newStepsList = this.attributeData.newStepsList.filter(
           //   (item) => item.type != 2 && item.type != 3 && item.type != 6
           // );
+
           if (this.clientEnvironmentId == 3) {
-            this.newStepsList = this.attributeData.newStepsList.filter(
-              (item) => item.type != 6
-            );
+            if (
+              this.attributeData.newStepsList &&
+              this.attributeData.newStepsList.length != 0
+            ) {
+              this.newStepsList = this.attributeData.newStepsList.filter(
+                (item) => item.type != 6
+              );
+            }
           } else {
             this.newStepsList = this.attributeData.newStepsList;
           }
@@ -464,12 +471,11 @@
     mounted() {
       this.getContactList();
       this.getFactoryList();
-      console.log(this.outsourceFormVal, 'outsourceFormVal');
-      if (this.activeName == '1') {
-        this.attributeData.name = this.outsourceFormVal.name + '委托';
-      } else if (this.activeName == '2') {
-        this.attributeData.name = this.outsourceFormVal.name + '请托';
-      }
+      // if (this.activeName == '1') {
+      //   this.attributeData.name = this.outsourceFormVal.name + '委托';
+      // } else if (this.activeName == '2') {
+      //   this.attributeData.name = this.outsourceFormVal.name + '请托';
+      // }
     },
 
     methods: {
@@ -549,7 +555,7 @@
         console.log(e);
         const arr = this.newStepsList.find((item) => item.taskId === e);
 
-        if (this.attributeData.taskIdes.length) {
+        if (this.attributeData.taskIdes.length != 0) {
           if (this.attributeData.taskIdes.length == 1) {
             this.attributeData.sceneText = '单工序';
             this.attributeData.outsourceScene = 2;
@@ -577,6 +583,8 @@
           //   }
           // }
         } else {
+          this.attributeData.sceneText = '';
+          this.attributeData.outsourceScene = '';
           // uni.showToast({
           //   title: '委外到工序为空',
           //   icon: 'none'

+ 16 - 13
src/views/produce/components/outsourcing/outsourceList.vue

@@ -286,19 +286,6 @@
                     <span>编码</span>{{ item.code }}
                   </div>
 
-                  <div v-if="clientEnvironmentId == 3">
-                    <el-button type="text" @click="convertList(item, index)"
-                      >转物品清单</el-button
-                    >
-
-                    <el-button
-                      type="text"
-                      style="color: red"
-                      @click="deleteBomMaterial(item, index)"
-                      >删除</el-button
-                    >
-                  </div>
-
                   <div
                     v-for="(itm, index) in tableH(item.rootCategoryLevelId)"
                     :key="index"
@@ -320,6 +307,7 @@
                         ? item.demandQuantity
                         : item.count * (checkListLen || 1)
                     }}
+                    {{ item.unit }}
                   </div>
                   <div
                     class="items content_num"
@@ -331,6 +319,7 @@
                       style="width: 90% !important"
                       v-model="item.demandQuantity"
                     />
+                    {{ item.measuringUnit }}
                   </div>
 
                   <div
@@ -351,6 +340,20 @@
                       style="width: 90% !important"
                       v-model="item.demandQuantity"
                     />
+                    {{ item.measuringUnit }}
+                  </div>
+
+                  <div v-if="clientEnvironmentId == 3">
+                    <el-button type="text" @click="convertList(item, index)"
+                      >转物品清单</el-button
+                    >
+
+                    <el-button
+                      type="text"
+                      style="color: red"
+                      @click="deleteBomMaterial(item, index)"
+                      >删除</el-button
+                    >
                   </div>
                 </div>
               </div>

+ 176 - 179
src/views/produce/components/outsourcing/outsourcingList.vue

@@ -1,189 +1,186 @@
 <template>
-    <div class="ele-body">
-      <el-card shadow="never" v-loading="loading">
-        <return-search @search="reload" ref="searchRef"> </return-search>
-  
-        <!-- 数据表格 -->
-        <ele-pro-table
-          ref="table"
-          :columns="columns"
-          :datasource="datasource"
-          row-key="id"
-          cache-key="returnKey"
-          autoAmendPage
-          :parse-data="parseData"
-          :selection.sync="selection"
-        >
-          <template v-slot:toolbar>
-            <el-button type="primary" size="mini" @click="handleReturn"
-              >新建</el-button
-            >
-          </template>
-  
-          <template v-slot:scene="{ row }">
-            {{ sceneListFn(row.scene) }}
-          </template>
-  
-          <template v-slot:action="{ row }">
-            <el-button type="text" size="mini" @click="handDetailed(row)"
-              >详情</el-button
-            >
-          </template>
-        </ele-pro-table>
-      </el-card>
-  
-      <returnPop
-        v-if="returnShow"
-        :returnDetailsId="returnDetailsId"
-        @close="close"
-        :sceneList="sceneList"
-      ></returnPop>
-    </div>
-  </template>
-  
-  <script>
-
-    export default {
-      components: {
-        returnSearch,
-        returnPop
+  <div class="ele-body">
+    <el-card shadow="never" v-loading="loading">
+      <return-search @search="reload" ref="searchRef"> </return-search>
+
+      <!-- 数据表格 -->
+      <ele-pro-table
+        ref="table"
+        :columns="columns"
+        :datasource="datasource"
+        row-key="id"
+        cache-key="returnKey"
+        autoAmendPage
+        :parse-data="parseData"
+        :selection.sync="selection"
+      >
+        <template v-slot:toolbar>
+          <el-button type="primary" size="mini" @click="handleReturn"
+            >新建</el-button
+          >
+        </template>
+
+        <template v-slot:scene="{ row }">
+          {{ sceneListFn(row.scene) }}
+        </template>
+
+        <template v-slot:action="{ row }">
+          <el-button type="text" size="mini" @click="handDetailed(row)"
+            >详情</el-button
+          >
+        </template>
+      </ele-pro-table>
+    </el-card>
+
+    <returnPop
+      v-if="returnShow"
+      :returnDetailsId="returnDetailsId"
+      @close="close"
+      :sceneList="sceneList"
+    ></returnPop>
+  </div>
+</template>
+
+<script>
+  export default {
+    components: {
+      returnSearch,
+      returnPop
+    },
+    data() {
+      return {
+        // 加载状态
+        loading: false,
+        selection: [],
+
+        returnShow: false,
+        returnDetailsId: null,
+
+        sceneList: []
+      };
+    },
+    computed: {
+      columns() {
+        return [
+          {
+            prop: 'remark',
+            label: '材料名称',
+            align: 'center'
+          },
+          {
+            prop: 'remark',
+            label: '材料名称',
+            align: 'center'
+          },
+          {
+            prop: 'code',
+            label: '牌号',
+            align: 'center'
+          },
+
+          {
+            prop: 'name',
+            label: '型号',
+            align: 'center'
+          },
+
+          {
+            slot: 'scene',
+            prop: 'scene',
+            label: '模孔数量',
+            align: 'center'
+          },
+
+          {
+            prop: 'executorName',
+            label: '芯棒直径',
+            align: 'center'
+          },
+
+          {
+            prop: 'executorTime',
+            label: '收缩系数',
+            align: 'center'
+          }
+        ];
+      }
+    },
+    created() {
+      this.getByCodeFn();
+    },
+    methods: {
+      /* 表格数据源 */
+      async datasource({ page, limit, where }) {
+        let res = await returnPage({
+          ...where,
+
+          pageNum: page,
+          size: limit
+        });
+
+        return res;
       },
-      data() {
-        return {
-          // 加载状态
-          loading: false,
-          selection: [],
-  
-          returnShow: false,
-          returnDetailsId: null,
-  
-          sceneList: []
-        };
+
+      // 新增退料
+      handleReturn() {
+        this.returnDetailsId = null;
+        this.returnShow = true;
       },
-      computed: {
-        columns() {
-          return [
-            {
-              prop: 'remark',
-              label: '材料名称',
-              align: 'center'
-            },
-            {
-              prop: 'remark',
-              label: '材料名称',
-              align: 'center'
-            },
-            {
-              prop: 'code',
-              label: '牌号',
-              align: 'center'
-            },
-  
-            {
-              prop: 'name',
-              label: '型号',
-              align: 'center'
-            },
-  
-            {
-              slot: 'scene',
-              prop: 'scene',
-              label: '模孔数量',
-              align: 'center'
-            },
-  
-            {
-              prop: 'executorName',
-              label: '芯棒直径',
-              align: 'center'
-            },
-  
-            {
-              prop: 'executorTime',
-              label: '收缩系数',
-              align: 'center'
-            },
-        
-          ];
+
+      close(val) {
+        if (val) {
+          this.reload();
         }
+        this.returnDetailsId = null;
+        this.returnShow = false;
       },
-      created() {
-        this.getByCodeFn();
+
+      //查看详情
+      handDetailed(row) {
+        this.returnDetailsId = row.id;
+        this.returnShow = true;
       },
-      methods: {
-        /* 表格数据源 */
-        async datasource({ page, limit, where }) {
-          let res = await returnPage({
-            ...where,
-  
-            pageNum: page,
-            size: limit
-          });
-  
-          return res;
-        },
-  
-        // 新增退料
-        handleReturn() {
-          this.returnDetailsId = null;
-          this.returnShow = true;
-        },
-  
-        close(val) {
-          if (val) {
-            this.reload();
-          }
-          this.returnDetailsId = null;
-          this.returnShow = false;
-        },
-  
-        //查看详情
-        handDetailed(row) {
-          this.returnDetailsId = row.id;
-          this.returnShow = true;
-        },
-  
-        getByCodeFn() {
-          getByCode('returnScenario').then((res) => {
-            let _arr = [];
-            res.data.map((item) => {
-              const key = Object.keys(item)[0];
-              const value = item[key];
-              _arr.push({ label: value, value: key });
-            });
-  
-            this.sceneList = _arr;
+
+      getByCodeFn() {
+        getByCode('returnScenario').then((res) => {
+          let _arr = [];
+          res.data.map((item) => {
+            const key = Object.keys(item)[0];
+            const value = item[key];
+            _arr.push({ label: value, value: key });
           });
-        },
-  
-        sceneListFn(val) {
-          let _arr = this.sceneList;
-          for (const item of _arr) {
-            if (item.value == val) {
-              return item.label;
-            }
+
+          this.sceneList = _arr;
+        });
+      },
+
+      sceneListFn(val) {
+        let _arr = this.sceneList;
+        for (const item of _arr) {
+          if (item.value == val) {
+            return item.label;
           }
-        },
-  
-        /* 刷新表格 */
-        reload(where = {}) {
-          this.$refs.table.reload({ page: 1, where });
-        },
-  
-        /* 数据转为树形结构 */
-        parseData(data) {
-          return {
-            ...data,
-            list: this.$util.toTreeData({
-              data: data.list,
-              count: data.total,
-  
-              idField: 'id',
-              parentIdField: 'parentId'
-            })
-          };
         }
+      },
+
+      /* 刷新表格 */
+      reload(where = {}) {
+        this.$refs.table.reload({ page: 1, where });
+      },
+
+      /* 数据转为树形结构 */
+      parseData(data) {
+        return {
+          ...data,
+          list: this.$util.toTreeData({
+            data: data.list,
+            count: data.total,
+
+            idField: 'id',
+            parentIdField: 'parentId'
+          })
+        };
       }
-    };
-  </script>
-  
+    }
+  };
+</script>

+ 24 - 9
src/views/produce/components/picking/detailed.vue

@@ -91,16 +91,25 @@
             showOverflowTooltip: true,
             slot: 'index'
           },
-
+          {
+            width: 120,
+            prop: 'batchNo',
+            slot: 'batchNo',
+            label: '批次号',
+            align: 'center',
+            showOverflowTooltip: true
+          },
           {
             prop: 'rootCategoryLevelName',
             label: '领料类型',
-            align: 'center'
+            align: 'center',
+            showOverflowTooltip: true
           },
           {
             prop: 'categoryCode',
             label: '编码',
-            align: 'center'
+            align: 'center',
+            showOverflowTooltip: true
           },
 
           {
@@ -123,36 +132,42 @@
             prop: 'demandQuantity',
             label: '数量',
             align: 'center',
-            slot: 'demandQuantity'
+            slot: 'demandQuantity',
+            showOverflowTooltip: true
           },
 
           {
             prop: 'warehouseName',
             label: '领料仓库',
-            align: 'center'
+            align: 'center',
+            showOverflowTooltip: true
           },
 
           {
             prop: 'warehouseLeaderName',
             slot: 'warehouseLeaderName',
             label: '审核人',
-            align: 'center'
+            align: 'center',
+            showOverflowTooltip: true
           },
 
           {
             prop: 'brandNo',
             label: '牌号',
-            align: 'center'
+            align: 'center',
+            showOverflowTooltip: true
           },
           {
             prop: 'model',
             label: '型号',
-            align: 'center'
+            align: 'center',
+            showOverflowTooltip: true
           },
           {
             prop: 'specification',
             label: '规格',
-            align: 'center'
+            align: 'center',
+            showOverflowTooltip: true
           }
         ];
       },

+ 96 - 0
src/views/produce/components/turnover/components/details.vue

@@ -0,0 +1,96 @@
+<template>
+  <div class="ele-body">
+    <!-- tab切换 -->
+    <el-card :body-style="{ padding: 0 }">
+      <div class="switch">
+        <div class="switch_left">
+          <ul>
+            <li
+              v-for="item in tabOptions"
+              :key="item.key"
+              :class="{ active: activeComp == item.key }"
+              @click="activeComp = item.key"
+            >
+              {{ item.name }}
+            </li>
+          </ul>
+        </div>
+        <!-- <div class="right" style="padding: 10px">
+          <el-button @click="$router.go(-1)">返回</el-button>
+        </div> -->
+      </div>
+      <div class="page-title">
+        <el-page-header @back="$router.go(-1)">
+          <div slot="content" class="pageContent">
+            <span v-for="item in tabOptions" :key="item.key">
+              {{ item.key == activeComp ? item.name + '详情' : '' }}
+            </span>
+          </div>
+        </el-page-header>
+      </div>
+      <div class="content-wrapper">
+        <component
+          :is="activeComp"
+          :rowId="rowId"
+          :code="code"
+          :showTitle="false"
+        ></component>
+      </div>
+    </el-card>
+  </div>
+</template>
+
+<script>
+  import baseInfo from './edit.vue';
+  import maintain from '../../device/components/maintain.vue';
+  import repair from '../../device/components/repair.vue';
+  import malfunction from '../../device/components/malfunction.vue';
+  import inventory from '../../device/components/inventory.vue';
+  import pointInspection from '../../device/components/point-inspection.vue';
+  import internet from '../../device/components/internet.vue';
+  import produceOrder from '../../device/components/produce-order.vue';
+  export default {
+    components: {
+      baseInfo,
+      pointInspection,
+      maintain,
+      repair,
+      inventory,
+      malfunction,
+      internet,
+      produceOrder
+    },
+    data() {
+      return {
+        activeComp: 'baseInfo',
+        tabOptions: [
+          { key: 'baseInfo', name: '周转车信息' },
+          { key: 'pointInspection', name: '巡点检记录' },
+          { key: 'maintain', name: '保养记录' },
+          // { key: 'mould', name: '关联模具' },
+          { key: 'repair', name: '维修记录' },
+          { key: 'malfunction', name: '故障记录' },
+          { key: 'inventory', name: '盘点记录' },
+          { key: 'internet', name: '物联数据' },
+          { key: 'produceOrder', name: '生产记录' }
+          // // { key: "InternetRecord", name: "物联记录" },
+        ],
+        rowId: null,
+        code: null
+      };
+    },
+
+    created() {
+      this.rowId = this.$route.query.id;
+      this.code = this.$route.query.code;
+    }
+  };
+</script>
+
+<style lang="scss" scoped>
+  .page-title {
+    background: #fff;
+    padding: 26px 10px 15px;
+    border-bottom: 1px solid #eaeefb;
+  }
+</style>

+ 589 - 0
src/views/produce/components/turnover/components/edit.vue

@@ -0,0 +1,589 @@
+<template>
+  <div id="equipment_edit" class="ele-body baseinfo-container">
+    <el-card shadow="never">
+      <div class="page-title" v-if="showTitle">
+        <el-page-header @back="$router.go(-1)">
+          <div slot="content" class="pageContent">
+            <div>{{ title }}</div>
+          </div>
+        </el-page-header>
+        <div>
+          <el-button type="primary" @click="submit" :loading="btnLoading"
+            >确定</el-button
+          >
+        </div>
+      </div>
+      <div v-if="pageType == 'add'">
+        <el-button type="primary" plain @click="handlwpbm">选择物品</el-button>
+      </div>
+      <el-form
+        label-width="120px"
+        :model="{ ...form, ...positionInfo }"
+        ref="form"
+        :rules="rules"
+      >
+        <div class="content">
+          <basicInfoVue ref="basicInfoVueRef" />
+          <businessInformation ref="businessInformationRef" :form="form" />
+          <assetInformation ref="assetInformationRef" :form="form" />
+          <turnoverCarInformation ref="turnoverCarInformationRef" />
+          <warehouseConfigVue ref="warehouseConfigRef" class="ims" />
+          <productInfoVue ref="productInfoRef" />
+          <planVue ref="planRef" />
+          <qualityConfig ref="qualityConfigRef" />
+          <footerVue ref="footerVueRef" />
+          <documentInformation ref="documentInformationRef" type="周转车" />
+          <div class="basic-details-title border-none">
+            <span class="border-span">物联参数</span>
+          </div>
+          <el-row>
+            <el-col>
+              <el-form-item label="是否启用物联">
+                <el-switch
+                  v-model="isIotEnable"
+                  active-text="开"
+                  inactive-text="关"
+                  :active-value="1"
+                  :inactive-value="0"
+                >
+                </el-switch>
+              </el-form-item>
+            </el-col>
+            <el-col>
+              <el-form-item label="物联ID">{{ iotId }}</el-form-item>
+            </el-col>
+          </el-row>
+          <div class="basic-details-title border-none">
+            <span class="border-span">扩展信息</span>
+          </div>
+          <div class="kzzd">
+            <el-row>
+              <el-col
+                :span="24"
+                v-for="(item, index) in form.extInfoSelf"
+                :key="index"
+                style="margin-bottom: 20px"
+              >
+                <el-form-item
+                  label-width="0"
+                  :prop="'extInfoSelf.' + index + '.key'"
+                  :rules="{
+                    required: true,
+                    message: '自定义参数名称不能为空',
+                    trigger: 'blur'
+                  }"
+                >
+                  <div class="add-col">
+                    <el-input
+                      class="col-input"
+                      v-model="item.key"
+                      placeholder="参数名称"
+                    ></el-input>
+                    <el-input
+                      class="col-input"
+                      v-model="item.value"
+                      placeholder="参数值"
+                    ></el-input>
+                    <el-button
+                      class="del"
+                      type="text"
+                      @click="delt(item, index)"
+                    >
+                      删除
+                    </el-button>
+                  </div>
+                </el-form-item>
+              </el-col>
+              <el-col :span="24" v-if="form.extInfoSelf.length < 10">
+                <el-form-item label-width="0">
+                  <el-button
+                    class="primarybutton"
+                    type="primary"
+                    @click="addItem"
+                    >增加自定义参数</el-button
+                  >
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </div>
+        </div>
+      </el-form>
+      <DialogGoods
+        ref="DialogGoods"
+        @succeed="cbDialogGoods"
+        width="1200px"
+      ></DialogGoods>
+    </el-card>
+  </div>
+</template>
+
+<script>
+  import turnoverCarInformation from './turnoverCarInformation.vue';
+  // import warehouseConfigVue from '../components/warehouseConfig.vue';
+  import warehouseConfigVue from '../../device/components/warehouseConfig.vue';
+  // import productInfoVue from '../components/productInfo.vue';
+  import productInfoVue from '../../device/components/productInfo.vue';
+  // import planVue from '../components/plan.vue';
+  import planVue from '../../device/components/plan.vue';
+  // import qualityConfig from '../components/qualityConfig.vue';
+  import qualityConfig from '../../device/components/qualityConfig.vue';
+  // import footerVue from '../components/footer.vue';
+  import footerVue from '../../device/components/footer.vue';
+  // import documentInformation from '../components/documentInformation.vue';
+  import documentInformation from '../../device/components/documentInformation.vue';
+  // import basicInfoVue from '../components/basicInfo.vue';
+  import basicInfoVue from '../../device/components/basicInfo.vue';
+  // import DialogGoods from '../components/DialogGoods';
+  import DialogGoods from '../../device/components/DialogGoods.vue';
+  // import assetInformation from '../components/assetInformation.vue';
+  import assetInformation from '../../device/components/assetInformation.vue';
+  // import businessInformation from '../components/businessInformation.vue';
+  import businessInformation from '../../device/components/businessInformation.vue';
+  import { getDetails } from '@/api/classifyManage/itemInformation';
+  import {
+    saveOrEdit,
+    getAssetInfo,
+    getCode,
+    getAssetNum
+  } from '@/api/produce/turnover.js';
+  export default {
+    components: {
+      warehouseConfigVue,
+      productInfoVue,
+      planVue,
+      qualityConfig,
+      footerVue,
+      documentInformation,
+      DialogGoods,
+      assetInformation,
+      businessInformation,
+      basicInfoVue,
+      turnoverCarInformation
+    },
+    data() {
+      return {
+        labelStyle: {
+          width: '200px'
+        },
+        contentStyle: {
+          width: '400px'
+        },
+        isLink: true,
+        title: '新建周转车信息',
+        pageType: 'add',
+        btnLoading: false,
+        // 周转车主键id
+        id: '',
+        form: {
+          extInfoSelf: [],
+          // 基本信息
+          code: '',
+          name: '',
+          productTime: '',
+          workstation: ''
+        },
+        rules: {
+          name: [
+            { required: true, message: '请输入周转车名称', trigger: 'blur' }
+          ],
+          // location: [{ validator: addressValidation, trigger: 'change' }],
+          code: [
+            { required: true, message: '请输入周转车编码', trigger: 'blur' }
+          ]
+        },
+        // 基本信息
+        basicInfo: {},
+        positionInfo: {
+          // 详细地址
+          deviceDetailAddress: '',
+          // 请选择产线
+          lineCode: '',
+          lineName: '',
+          // 请选择车间
+          workshopCode: '',
+          workshopName: '',
+          // 请选择工厂
+          factoryCode: '',
+          factoryName: ''
+        },
+        // 图片
+        imageUrl: null,
+        // 文档信息
+        attUrl: {
+          operatingManual: {
+            value: [],
+            sort: 1
+          },
+          productionLicence: {
+            value: [],
+            sort: 2
+          },
+          explosionProofCertificate: {
+            value: [],
+            sort: 3
+          },
+          surveyReport: {
+            value: [],
+            sort: 4
+          },
+          inspectionCycleManual: {
+            value: [],
+            sort: 5
+          },
+          informationDrawing: {
+            value: [],
+            sort: 6
+          },
+          productCertificate: {
+            value: [],
+            sort: 7
+          }
+        },
+        // 是否开始物联
+        isIotEnable: true,
+        // 物联ID
+        iotId: '',
+        // 回显过保时间
+        cbexpirationTime: '',
+        // 生命周期
+        sourceDICT: '',
+        // 网络状态
+        networkStatus: '',
+        id: ''
+      };
+    },
+    props: {
+      showTitle: {
+        type: Boolean,
+        default: true
+      }
+    },
+    watch: {},
+    computed: {
+      // 过保时间
+      expirationTime() {
+        if (this.form.productTime && this.basicInfo.expirationDate) {
+          return this.setGbTime(
+            this.form.productTime,
+            this.basicInfo.expirationDate,
+            this.basicInfo.expirationDateUnit
+          );
+        } else {
+          return '';
+        }
+      }
+    },
+    async created() {
+      if (this.$route.query.id) {
+        this.pageType = 'edit';
+        this.id = this.$route.query.id;
+        await this.getInfo();
+        this.title = '编辑周转车信息';
+        // this.getgys();
+        // await this._getWarehouseChildren();
+      } else {
+        this.pageType = 'add';
+        this.title = '新增周转车信息';
+      }
+    },
+    methods: {
+      handlwpbm() {
+        this.$refs.DialogGoods.open('7');
+      },
+      async cbDialogGoods(data) {
+        let res = await getDetails(data.id);
+        if (!data.extInfoSelf) {
+          data.extInfoSelf = [];
+        }
+        // if (!data.workstation) {
+        //   data.workstation = {};
+        // }
+        if (!data.isPublic) {
+          data.isPublic = 0;
+        }
+        this.form = data;
+        this.form.category = res;
+        this.basicInfo = data;
+        this.form.rootCategoryLevelId = this.basicInfo.categoryLevelPathId
+          .split(',')[0]
+          .replace('[', '');
+        this.form.categoryId = this.basicInfo.id;
+        this.form.name = this.basicInfo.name;
+        this.form.code = data.code; //Date.now(); //res.data[0].onlyCode;
+        this.initOtherMsg();
+      },
+      // 计算过保时间
+      setGbTime(basic, value, type) {
+        basic = Date.parse(basic);
+        let time;
+        switch (type) {
+          case 'minute':
+            time = value * 1000 * 60;
+            break;
+          case 'hour':
+            time = value * 1000 * 60 * 60;
+            break;
+          case 'day':
+            time = value * 1000 * 60 * 60 * 24;
+            break;
+          case 'month':
+            time = value * 1000 * 60 * 60 * 24 * 30;
+            break;
+          case 'year':
+            time = value * 1000 * 60 * 60 * 24 * 365;
+            break;
+          default:
+            break;
+        }
+
+        let num = basic + time;
+        return parseTime(num);
+      },
+      // 添加自定义参数
+      addItem() {
+        if (this.form.extInfoSelf.length < 10) {
+          let item = { key: '', value: '' };
+          this.form.extInfoSelf.push(item);
+        } else {
+          this.$message.warning('自定义参数最多添加10条');
+        }
+      },
+      // 删除自定义参数
+      delt(item, index) {
+        this.form.extInfoSelf.splice(index, 1);
+      },
+      // 提交
+      submit() {
+        if (JSON.stringify(this.basicInfo) === '{}' && this.pageType == 'add') {
+          return this.$message.error('请选择物品');
+        }
+        this.$refs.form.validate(async (valid) => {
+          if (valid) {
+            if (!this.form.areaPersonInChargeGroupId) {
+              this.$message.error('请选片区负责人部门');
+              return;
+            }
+            if (!this.form.areaPersonInChargeUserId) {
+              this.$message.error('请选片区负责人');
+              return;
+            }
+            let par = {
+              //基本信息
+              ...this.form,
+              assetType: 1,
+              // 资产信息
+              positionIds: '1,1,1,1',
+              position: {
+                detailPosition: this.positionInfo.deviceDetailAddress,
+                pathIds: `${
+                  this.positionInfo.factoryCode
+                    ? this.positionInfo.factoryCode + ','
+                    : ''
+                }${
+                  this.positionInfo.workshopCode
+                    ? this.positionInfo.workshopCode + ','
+                    : ''
+                }${this.positionInfo.lineCode}`,
+                pathName: `${
+                  this.positionInfo.factoryName
+                    ? this.positionInfo.factoryName + ','
+                    : ''
+                }${
+                  this.positionInfo.workshopName
+                    ? this.positionInfo.workshopName + ','
+                    : ''
+                }${this.positionInfo.lineName}`,
+                type: '1',
+                num: 1
+              },
+              // 文档信息
+              attUrl: this.setWd() || [],
+              // 周转车图片
+              imageUrl: this.imageUrl || {},
+              // 是否启用物联
+              isIotEnable: this.isIotEnable
+              // 扩展字段
+              // extInfoSelf: this.setKz()
+            };
+            par.deviceLocationName = par.location
+              ? par.location.toString()
+              : '';
+            par.extInfo = null;
+            let obj = {};
+            par.extInfoSelf.forEach((item) => {
+              obj[item.key] = item.value;
+            });
+            par.extInfoSelf = obj;
+            if (this.pageType == 'edit') {
+              par.id = this.id;
+            } else {
+              const batchNo = await getCode('lot_number_code');
+              const res = await getAssetNum({
+                assetCode: par.code,
+                batchNum: batchNo,
+                num: 1
+              });
+              console.log(res);
+              par.code = res.data.shift().onlyCode;
+              par.id = '';
+            }
+            this.btnLoading = true;
+            console.log('sasasasa', par);
+            // return;
+            saveOrEdit(par)
+              .then((res) => {
+                this.$message.success('操作成功');
+                this.$router.go(-1);
+              })
+              .finally(() => {
+                this.btnLoading = false;
+              });
+          } else {
+            console.log('error submit!!');
+            return false;
+          }
+        });
+      },
+      // 处理扩展字段
+      setKz() {
+        return this.form.extInfoSelf || [];
+      },
+      // 处理文档信息
+      setWd() {
+        return Object.values(this.attUrl).map((item) => {
+          console.log(item, 'item');
+          return {
+            value: item.value || [],
+            sort: item.sort
+          };
+        });
+      },
+      // 获取周转车详情
+      async getInfo() {
+        const data = await getAssetInfo(this.id);
+        // 扩展字段
+        data.extInfoSelf = data.extInfoSelf || [];
+        // 权属人相关信息
+        // if (!data.workstation) {
+        //   data.workstation = {};
+        // }
+        // 资产信息类型默认专用
+        if (!data.isPublic) {
+          data.isPublic = 0;
+        }
+        this.form = data;
+        this.form.location = data.deviceLocationName.split(',');
+        this.basicInfo = data;
+        this.cbexpirationTime = data.expirationTime;
+        this.sourceDICT = data.sourceDICT;
+        this.networkStatus = data.networkStatus;
+        this.positionInfo.deviceDetailAddress = data.deviceDetailAddress;
+        this.initOtherMsg();
+        // 周转车图片
+        this.imageUrl = data.imageUrl;
+        // 物联参数
+        this.isIotEnable = data.isIotEnable;
+        this.iotId = data.iotId;
+      },
+      async initOtherMsg() {
+        // 基本信息
+        this.$refs.basicInfoVueRef.getDetailInfoAugr(
+          this.form.category.category
+        );
+        // 仓储配置
+        this.$refs.warehouseConfigRef.getDetailInfoAugr(
+          this.form.category.categoryWms
+        );
+        // 生产信息
+        this.$refs.productInfoRef.getDetailInfoAugr(
+          this.form.category.categoryMes
+        );
+        // 计划配置
+        this.$refs.planRef.getDetailInfoAugr(this.form.category.categoryAps);
+        // 质量配置
+        this.$refs.qualityConfigRef.getDetailInfoAugr(
+          this.form.category.categoryQms
+        );
+        // 周转车信息
+        this.$refs.turnoverCarInformationRef.getDetailInfoAugr(
+          this.form.category.categoryVehicle
+        );
+        // 其他和关联信息
+        this.$refs.footerVueRef.getDetailInfoAugr(this.form.category.category);
+        // 文档信息
+        if (this.form.attUrl && this.form.attUrl.length > 0) {
+          Object.keys(this.attUrl).forEach((n, index) => {
+            this.attUrl[n].value = this.form.attUrl[index].value || [];
+          });
+          this.$refs.documentInformationRef.getDetailInfoAugr(this.attUrl);
+        }
+      },
+      // 设置标准产能
+      setbzcn(val) {
+        if (!val) {
+          return '';
+        }
+        let item = JSON.parse(val);
+        return item.standardCapacity || '';
+      }
+    }
+  };
+</script>
+
+<style lang="scss" scoped>
+  ::v-deep .descriptions {
+    margin-bottom: 10px;
+  }
+  .baseinfo-container .basic-details-title {
+    font-size: 16px;
+    margin: 15px 0;
+  }
+  .upload-container {
+    display: flex;
+    justify-content: flex-start;
+    .file-list {
+      margin-left: 50px;
+      flex: 1;
+    }
+  }
+  .equipment-container {
+    .label-none {
+      .el-form-item__content {
+        margin-left: 0 !important;
+      }
+    }
+  }
+  .sbwz {
+    .item {
+      width: 120px !important;
+    }
+    .item + .item {
+      margin-left: 10px;
+    }
+    .item-input {
+      width: 350px !important;
+    }
+  }
+  .input {
+    width: 100%;
+  }
+  .kzzd {
+    width: 500px;
+    .add-col {
+      display: flex;
+      .col-input {
+        & + .col-input {
+          margin-left: 10px;
+        }
+      }
+      .del {
+        margin-left: 10px;
+      }
+    }
+  }
+  ::v-deep .el-descriptions {
+    .el-form-item {
+      margin-bottom: 0px;
+    }
+  }
+</style>

+ 73 - 0
src/views/produce/components/turnover/components/turnoverCarInformation.vue

@@ -0,0 +1,73 @@
+<template>
+  <div>
+    <div class="basic-details-title border-none">
+      <span class="border-span">周转车信息</span>
+    </div>
+    <el-descriptions
+      :label-style="labelStyle"
+      :contentStyle="contentStyle"
+      title=""
+      :column="3"
+      size="medium"
+      border
+    >
+      <el-descriptions-item>
+        <template slot="label">长</template>
+        {{
+          categoryVehicle.vehicleLen ? categoryVehicle.vehicleLen + 'mm' : null
+        }}
+      </el-descriptions-item>
+      <el-descriptions-item>
+        <template slot="label">宽</template>
+        {{ categoryVehicle.wilde ? categoryVehicle.wilde + 'mm' : null }}
+      </el-descriptions-item>
+      <el-descriptions-item>
+        <template slot="label">高</template>
+        {{ categoryVehicle.hight ? categoryVehicle.hight + 'mm' : null }}
+      </el-descriptions-item>
+      <el-descriptions-item>
+        <template slot="label">层数</template>
+        {{ categoryVehicle.levelNum }}
+      </el-descriptions-item>
+      <el-descriptions-item>
+        <template slot="label">材质</template>
+        {{ categoryVehicle.materialQuality }}
+      </el-descriptions-item>
+    </el-descriptions>
+  </div>
+</template>
+<script>
+  export default {
+    data() {
+      return {
+        labelStyle: {
+          width: '200px'
+        },
+        contentStyle: {
+          width: '400px'
+        },
+        categoryVehicle: {}
+      };
+    },
+    methods: {
+      async getDetailInfoAugr(data) {
+        this.categoryVehicle = { ...data };
+      }
+    }
+  };
+</script>
+
+<style lang="scss" scoped>
+  .upload-container {
+    display: flex;
+    justify-content: flex-start;
+    .file-list {
+      margin-left: 50px;
+      flex: 1;
+    }
+  }
+  .basic-details-title {
+    font-size: 16px;
+    margin: 15px 0;
+  }
+</style>

+ 12 - 4
src/views/produce/components/warehousing/index.vue

@@ -750,11 +750,19 @@
             (item) => item.id == this.teamId
           );
           this.teamUserList = this.teamAllList[index];
-          const res = this.teamUserList.find(
-            (it) => it.id == this.$store.state.user.info.userId
-          );
 
-          this.executorIdList.push(res.id);
+          if (this.teamUserList) {
+            const res = this.teamUserList.find(
+              (it) => it.id == this.$store.state.user.info.userId
+            );
+
+            this.executorIdList.push(res.id);
+          }
+          // const res = this.teamUserList.find(
+          //   (it) => it.id == this.$store.state.user.info.userId
+          // );
+
+          // this.executorIdList.push(res.id);
         }
       },
 

+ 6 - 0
src/views/produce/components/workPlan/components/sampleListDialog.vue

@@ -19,6 +19,7 @@
                 label="质检方案编码"
                 prop="qualitySchemeTemplateCode"
                 align="center"
+                show-overflow-tooltip
               >
                 <template slot-scope="scope">
                   <span :class="scope.row.qualityResults === 2 ? 'warn' : ''">
@@ -30,6 +31,7 @@
                 label="质检方案名称"
                 prop="qualitySchemeTemplateName"
                 align="center"
+                show-overflow-tooltip
               >
                 <template slot-scope="scope">
                   <span :class="scope.row.qualityResults === 2 ? 'warn' : ''">
@@ -41,6 +43,7 @@
                 label="质检类型"
                 prop="categoryLevelClassName"
                 align="center"
+                show-overflow-tooltip
               >
                 <template slot-scope="scope">
                   <span :class="scope.row.qualityResults === 2 ? 'warn' : ''">
@@ -52,6 +55,7 @@
                 label="质检项编码"
                 prop="inspectionCode"
                 align="center"
+                show-overflow-tooltip
               >
                 <template slot-scope="scope">
                   <span :class="scope.row.qualityResults === 2 ? 'warn' : ''">
@@ -63,6 +67,7 @@
                 label="质检项名称"
                 prop="inspectionName"
                 align="center"
+                show-overflow-tooltip
               >
                 <template slot-scope="scope">
                   <span :class="scope.row.qualityResults === 2 ? 'warn' : ''">
@@ -233,6 +238,7 @@
           { label: '批次号', prop: 'batchNo', align: 'center' },
           // { label: '发货条码', prop: 'barcodes', align: 'center' },
           { label: '包装编码', prop: 'packageNo', align: 'center' },
+          { label: '样品编码', prop: 'sampleCode', align: 'center' },
           { label: '包装数量', prop: 'packingQuantity', align: 'center' },
           // { label: '包装单位', prop: 'packingUnit', align: 'center' },
           { label: '计量数量', prop: 'measureQuantity', align: 'center' },

+ 194 - 50
src/views/produce/index.vue

@@ -1,5 +1,20 @@
 <template>
   <div class="index_box">
+    <!-- <div class="menu-container">
+      <div
+        v-for="(item, index) in menuItems"
+        :key="item.label"
+        class="menu-item"
+        :class="{ active: isOpen }"
+        :style="getItemStyle(index)"
+        @click="handleItemClick(item)"
+      >
+        {{ item.label }}
+      </div>
+      <button class="toggle-btn" @click="toggleMenu">
+        {{ isOpen ? 'X' : '≡' }}
+      </button>
+    </div> -->
     <div class="content_box">
       <!-- @tab-click="handleClick" -->
       <!-- 工序名称 -->
@@ -264,6 +279,9 @@
           :singleReportInspection="singleReportInspection"
           style="background: rgba(223, 250, 222, 0.6); padding: 10px"
         ></footBtn>
+
+        <!-- <div class="box"> -->
+        <!-- </div> -->
       </div>
       <!-- <footBtn @footBtn="footBtn"></footBtn> -->
     </div>
@@ -416,7 +434,17 @@
           { label: '按钮3' },
           { label: '按钮4' }
         ],
-        radius: 120 // 按钮展开的半径
+        radius: 120, // 按钮展开的半径
+        isOpen: false,
+        lastClicked: '无',
+        menuItems: [
+          { label: 'BOM', action: 'Add' },
+          { label: '周转车', action: 'Bold' },
+          { label: '设备', action: 'Copy' },
+          { label: '产前准备', action: 'Delete' },
+          { label: '过程检测', action: 'Edit' },
+          { label: '产后检查', action: 'Favorite' }
+        ]
       };
     },
 
@@ -450,16 +478,38 @@
       toggleMenu() {
         this.isOpen = !this.isOpen;
       },
-      getBtnStyle(index) {
-        // 计算扇形角度分布
-        const angle = Math.PI / 2 / (this.buttons.length - 1); // 90° 扇形
-        const x = Math.cos(angle * index) * this.radius;
-        const y = Math.sin(angle * index) * this.radius;
+      handleItemClick(item) {
+        this.lastClicked = item.action;
+        // console.log(`Clicked: ${item.label} - ${item.action}`);
+      },
+      getItemStyle(index) {
+        if (!this.isOpen) {
+          return {};
+        }
+
+        const radius = 120;
+
+        let angle = -180 + (120 / (this.menuItems.length - 1)) * index;
+        let rad = (angle * Math.PI) / 180;
+        let tx = Math.cos(rad) * radius;
+        let ty = Math.sin(rad) * radius;
+
+        // const angle =
+        //   -180 +
+        //   ((index / (this.menuItems.length - 1)) * Math.PI) / 2 -
+        //   Math.PI / 4;
+        // const radius = 120;
+
+        // const tx = radius * Math.cos(angle);
+        // const ty = -radius * Math.sin(angle);
+
         return {
-          transform: `translate(${x}px, ${y}px)`,
-          transitionDelay: `${index * 0.05}s`
+          '--tx': `${tx}px`,
+          '--ty': `${ty}px`,
+          'transition-delay': `${index * 0.05}s`
         };
       },
+
       // 前端筛选
       seekInput() {
         // console.log(activeName);
@@ -1022,6 +1072,7 @@
   }
 
   .index_box {
+    position: relative;
     padding: 10px;
     padding-bottom: 0;
     width: 100%;
@@ -1085,61 +1136,154 @@
     background: #f0f3f3;
   }
 
+  // .menu-container {
+  //   position: relative;
+  //   width: 200px;
+  //   height: 200px;
+  //   margin: 100px;
+  // }
+
+  /* 主按钮 */
+  // .main-btn {
+  //   width: 60px;
+  //   height: 60px;
+  //   background: #3498db;
+  //   border-radius: 50%;
+  //   color: #fff;
+  //   font-size: 30px;
+  //   text-align: center;
+  //   line-height: 60px;
+  //   cursor: pointer;
+  //   position: absolute;
+  //   left: 0;
+  //   bottom: 0;
+  //   box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
+  //   transition: transform 0.3s;
+  // }
+  // .main-btn:hover {
+  //   transform: rotate(90deg);
+  // }
+
+  /* 子按钮 */
+  // .sub-btn {
+  //   width: 40px;
+  //   height: 40px;
+  //   background: #e74c3c;
+  //   border-radius: 50%;
+  //   color: #fff;
+  //   font-size: 14px;
+  //   text-align: center;
+  //   line-height: 50px;
+  //   position: absolute;
+  //   left: 5px;
+  //   bottom: 5px;
+  //   box-shadow: 0 3px 8px rgba(0, 0, 0, 0.25);
+  //   transform: translate(0, 0);
+  //   transition: all 0.4s ease;
+  //   opacity: 1;
+  // }
+
+  /* 动画进入/离开 */
+  // .fan-enter-active,
+  // .fan-leave-active {
+  //   transition: all 0.4s ease;
+  // }
+  // .fan-enter,
+  // .fan-leave-to {
+  //   opacity: 0;
+  //   transform: translate(0, 0);
+  // }
+
+  // .box {
+  //   position: relative;
+  // }
+
   .menu-container {
-    position: relative;
-    width: 200px;
-    height: 200px;
-    margin: 100px;
+    position: fixed;
+    right: 0;
+    margin-top: 42.5%;
+    width: 235px;
+    height: 100px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    z-index: 999;
   }
 
-  /* 主按钮 */
-  .main-btn {
-    width: 60px;
-    height: 60px;
-    background: #3498db;
+  .toggle-btn {
+    position: absolute;
+    width: 55px;
+    height: 55px;
+    background: #2196f3;
     border-radius: 50%;
-    color: #fff;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    color: white;
     font-size: 30px;
-    text-align: center;
-    line-height: 60px;
+    font-weight: bold;
     cursor: pointer;
-    position: absolute;
-    left: 0;
-    bottom: 0;
-    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
-    transition: transform 0.3s;
+    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2);
+    z-index: 100;
+    transition: all 0.3s ease;
+    border: none;
+    left: 60%;
+    top: 60%;
+    transform: translate(-50%, -50%);
   }
-  .main-btn:hover {
-    transform: rotate(90deg);
+
+  .toggle-btn:hover {
+    transform: translate(-50%, -50%) scale(1.05);
+    box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3);
   }
 
-  /* 子按钮 */
-  .sub-btn {
-    width: 40px;
-    height: 40px;
-    background: #e74c3c;
-    border-radius: 50%;
-    color: #fff;
-    font-size: 14px;
-    text-align: center;
-    line-height: 50px;
+  .toggle-btn:active {
+    transform: translate(-50%, -50%) scale(0.95);
+  }
+
+  .menu-item {
     position: absolute;
-    left: 5px;
-    bottom: 5px;
-    box-shadow: 0 3px 8px rgba(0, 0, 0, 0.25);
-    transform: translate(0, 0);
-    transition: all 0.4s ease;
+    width: 50px;
+    height: 50px;
+    background: #4caf50;
+    border-radius: 50%;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    color: white;
+    font-size: 12px;
+    font-weight: bold;
+    box-shadow: 0 6px 15px rgba(0, 0, 0, 0.2);
+    transition: all 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
+    transform: translate(-50%, -50%) scale(0);
+    opacity: 0;
+    pointer-events: none;
+    z-index: 90;
+    left: 55%;
+    top: 60%;
+  }
+
+  .menu-item.active {
     opacity: 1;
+    pointer-events: auto;
+    transform: translate(var(--tx), var(--ty)) scale(1);
   }
 
-  /* 动画进入/离开 */
-  .fan-enter-active,
-  .fan-leave-active {
-    transition: all 0.4s ease;
+  .menu-item:hover {
+    transform: translate(var(--tx), var(--ty)) scale(1.15) !important;
+    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
+    background: #66bb6a;
+    cursor: pointer;
   }
-  .fan-enter,
-  .fan-leave-to {
-    opacity: 0;
-    transform: translate(0, 0);
+
+  .instructions {
+    margin-top: 2rem;
+    color: white;
+    text-align: center;
+    background: rgba(255, 255, 255, 0.1);
+    padding: 1rem;
+    border-radius: 10px;
+    max-width: 500px;
+    backdrop-filter: blur(5px);
   }
 </style>