Procházet zdrojové kódy

websocket链接传递时间戳唯一值 新建消息列表组件页面

pm před 11 měsíci
rodič
revize
a1a6af2f41

+ 211 - 0
src/components/TimeLine/card.vue

@@ -0,0 +1,211 @@
+<template>
+  <div class="item-content-card" @click="goDetail()">
+    <div class="time-title" :class="statusStyle(cardData.status)">
+      <i class="el-icon-time"></i>
+      <!-- {{ cardData.createTime.slice(-8) }} -->
+      <div class="item-status"><b>{{ formatStatus(cardData.status) }}</b></div>
+    </div>
+    <div class="time-content">
+      <div class="time-content-no">
+        <div class="time-content-no-circle" :class="{'time-content-delete' : cardData.type!=1}"></div>
+        {{ cardData.workNo }}
+      </div>
+      <div class="time-content-name">
+        <span>{{ cardData.name }}</span>
+        新增/导入/删除
+        <div v-if="showRevoke()" class="opera-icon-back" title="撤销" @click.stop="revokeWorkFlow"></div>
+        <div v-if="showRevoke() && cardData.status == 4" class="opera-icon-edit" title="编辑" @click.stop="editWorkFlow"></div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+
+export default {
+  name: 'TheWorkNoteCard',
+  props: {
+    cardData: {
+      type: Object,
+      default: () => ({})
+    }
+  },
+  methods: {
+    // 跳转详情页面
+    goDetail() {
+      this.$router.push({});
+    },
+    // 显示撤销
+    showRevoke() {
+      // 判断符合条件的逻辑
+    },
+    // 撤销
+    revokeWorkFlow() {
+    },
+    // 编辑被驳回
+    editWorkFlow() {
+    },
+    statusStyle(v) {
+      if (String(v) === '2') {
+        return 'time-status-unreview';
+      } else if (String(v) === '3') {
+        return 'time-status-success';
+      } else if (String(v) === '4' || String(v) === '5') {
+        return 'time-status-back';
+      } else {
+        return 'time-status-unreview';
+      }
+    },
+    formatStatus(v) {
+      if (String(v) === '2') { // 待审核
+        return '待审核';
+      } else if (String(v) === '3') { // 通过
+        return '通过';
+      } else if (String(v) === '4') { // 驳回
+        return '驳回';
+      } else if (String(v) === '5') { // 撤销
+        return '撤销';
+      } else {
+        return '--';
+      }
+    },
+  }
+};
+</script>
+
+<style scoped lang="scss">
+.item-content-card {
+  cursor: pointer;
+  border-radius: 4px;
+  background-color: #f7f9fa;
+  margin-bottom: 10px;
+
+  .time-title {
+    position: relative;
+    box-sizing: border-box;
+    height: 50px;
+    padding: 15px;
+    border-bottom: 1px solid #e4e4e4;
+
+    i {
+      font-size: 16px;
+    }
+
+    .item-status {
+      position: absolute;
+      font-size: 12px;
+      top: 13px;
+      right: 0;
+      width: 40px;
+      text-align: center;
+      z-index: 1;
+      transform: rotate(45deg)
+    }
+
+    &:after {
+      content: "";
+      position: absolute;
+      top: 0;
+      right: 0;
+      border-style: solid;
+      border-width: 25px 25px 25px 25px;
+      width: 0px;
+      height: 0px;
+    }
+  }
+
+  .time-status-unreview {
+    .item-status {
+      color: #409EFF;
+    }
+
+    &:after {
+      border-color: #d3e7fb #d3e7fb transparent transparent;
+    }
+  }
+
+  .time-status-success {
+    .item-status {
+      color: #67C23A;
+    }
+
+    &:after {
+      border-color: #dbeed4 #dbeed4 transparent transparent;
+    }
+  }
+
+  .time-status-back {
+    .item-status {
+      color: #E6A23C;
+    }
+
+    &:after {
+      border-color: #f4e7d4 #f4e7d4 transparent transparent;
+    }
+  }
+
+  .time-content {
+    padding: 15px;
+
+    .time-content-no {
+      margin-bottom: 10px;
+
+      .time-content-no-circle {
+        width: 10px;
+        height: 10px;
+        display: inline-block;
+        background-color: #8ec850;
+        border-radius: 50%;
+        margin-right: 6px;
+      }
+
+      .time-content-delete {
+        background-color: #666666;
+      }
+    }
+
+    .time-content-name {
+      line-height: 20px;
+      padding-left: 20px;
+
+      span {
+        margin-right: 20px;
+      }
+
+      .opera-icon-back {
+        margin-left: 30px;
+        display: inline-block;
+        width: 18px;
+        height: 18px;
+        cursor: pointer;
+        //background: url('../images/rollback.png') no-repeat;
+        background-size: 18px;
+
+        &:hover {
+          // background: url('../images/rollback_h.png') no-repeat;
+          background-size: 18px;
+        }
+      }
+
+      .opera-icon-edit {
+        margin-left: 5px;
+        display: inline-block;
+        width: 18px;
+        height: 18px;
+        cursor: pointer;
+        //background: url('../images/edit.png') no-repeat;
+        background-size: 18px;
+
+        &:hover {
+          //background: url('../images/edit_h.png') no-repeat;
+          background-size: 18px;
+        }
+      }
+    }
+  }
+
+  &:hover {
+    box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.176470588235294)
+  }
+}
+</style>

+ 181 - 0
src/components/TimeLine/timeline.vue

@@ -0,0 +1,181 @@
+<template>
+  <div class="timeline-main">
+    <!--年月标题-->
+    <div class="timeline-title">
+      {{ timeData.yearData }}
+      <i
+        :class="showCards ? 'el-icon-arrow-down' : 'el-icon-arrow-right'"
+        @click="showCards = !showCards"
+      ></i>
+    </div>
+    <ul class="timeline-body">
+      <!--时间线顶部圆点-->
+      <li class="timeline-item-head">
+        <div class="item-node"></div>
+        <div class="item-tail"></div>
+      </li>
+      <!--时间线内容-->
+      <template v-if="showCards">
+        <li
+          v-for="(mouthItem, i) in timeData.mouthData"
+          :key="'mm' + i"
+          class="timeline-item"
+        >
+          <div class="item-left">
+            <div class="item-left-data">{{ mouthItem.dateData }}</div>
+            <div class="item-left-total">
+              <div class="item-left-total-text">
+                共{{ mouthItem.dateArr.length }}条
+              </div>
+              <div class="item-left-total-end"></div>
+            </div>
+          </div>
+          <div class="item-tail"></div>
+          <div class="item-node"></div>
+          <div class="item-content">
+            <slot name="cardSlot" v-for="v in mouthItem.dateArr" :card="v"></slot>
+          </div>
+        </li>
+      </template>
+      <!--时间线尾部圆点-->
+      <li class="timeline-item-foot">
+        <div class="item-node"></div>
+        <div class="item-tail"></div>
+      </li>
+    </ul>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "Timeline",
+  props: {
+    timeData: {
+      type: Object,
+      default: () => ({}),
+    },
+  },
+  data() {
+    return {
+      showCards: true,
+    };
+  },
+};
+</script>
+
+<style scoped lang="scss">
+.timeline-main {
+  padding: 0 0 0 20px;
+
+  .timeline-title {
+    margin-bottom: 10px;
+    font-weight: bold;
+
+    i {
+      cursor: pointer;
+    }
+  }
+
+  .timeline-body {
+    margin: 0;
+    font-size: 14px;
+    list-style: none;
+    // 顶尾圆圈
+    .timeline-item-head,
+    .timeline-item-foot {
+      position: relative;
+      height: 15px;
+
+      .item-tail {
+        position: absolute;
+        left: 45px;
+        height: 100%;
+        border-left: 2px solid #e4e7ed;
+      }
+
+      .item-node {
+        position: absolute;
+        left: 42px;
+        width: 8px;
+        height: 8px;
+        background-color: #e4e7ed;
+        border-radius: 50%;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+      }
+    }
+
+    .timeline-item-foot {
+      .item-node {
+        top: 14px;
+      }
+    }
+
+    // 时间线主体内容
+    .timeline-item {
+      position: relative;
+      padding-bottom: 10px;
+
+      .item-left {
+        position: absolute;
+        top: 13px;
+        left: -9px;
+
+        .item-left-data {
+          font-weight: bold;
+          line-height: 20px;
+        }
+
+        .item-left-total {
+          display: flex;
+          font-size: 12px;
+
+          .item-left-total-text {
+            padding: 0 3px;
+            line-height: 20px;
+            color: #ffffff;
+            background: #409eff;
+          }
+
+          .item-left-total-end {
+            width: 0;
+            height: 0;
+            border-top: 10px solid transparent;
+            border-left: 6px solid #409eff;
+            border-bottom: 10px solid transparent;
+          }
+        }
+      }
+
+      .item-tail {
+        position: absolute;
+        left: 45px;
+        height: 100%;
+        border-left: 2px solid #e4e7ed;
+      }
+
+      .item-node {
+        position: absolute;
+        top: 38px;
+        left: 41px;
+        width: 6px;
+        height: 6px;
+        background-color: #ffffff;
+        border: 2px solid #409eff;
+        border-radius: 50%;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+      }
+
+      .item-content {
+        position: relative;
+        padding-top: 15px;
+        padding-left: 60px;
+        // top: -3px;
+      }
+    }
+  }
+}
+</style>

+ 1 - 1
src/utils/websocket.js

@@ -155,7 +155,7 @@ const reconnect = () => {
   if (lockReconnect) {
     return;
   }
-  writeToScreen("1分钟后重连");
+  writeToScreen("1分钟后重连");
   lockReconnect = true;
   // 没连接上会一直重连,设置延迟避免请求过多
   wsCreateHandler && clearTimeout(wsCreateHandler);

+ 3 - 2
src/views/mes/job/jobplay/index.vue

@@ -300,8 +300,9 @@ export default {
   },
   methods: {
     initWebSocket(){
-      const userId=localStorage.getItem('userId')
-      connectWebsocket(`ws://192.168.1.127:9090/websocket/jobTicket/${userId}`,{w:'S',},(res)=>{
+      const timestep= Date.now();
+      connectWebsocket(`ws://192.168.1.127:9090/websocket/jobTicket/${timestep}`,{w:'S',},(res)=>{
+
           console.log(res,'websocket接收服务器的数据-index');
           const resMsg=res
           if(resMsg=='refresh'){

+ 10 - 3
src/views/mes/job/jobplay/jobPlayDetail.vue

@@ -165,9 +165,15 @@
 <script>
 import { getJobPlayTicketInfo } from '@/api/mes/jobplay/jobplay'
 import { connectWebsocket, closeWebsocket, sendMsg } from "@/utils/websocket";
+import timeline from '@/components/TimeLine/timeline.vue'
+import card from "@/components/TimeLine/card.vue"
 export default {
   name: 'jobPlayDetail',
   dicts: ['ticket_type', 'ticket_status'],
+  components: {
+    timeline,
+    card
+  },
   data() {
     return {
       jobTicket: [],
@@ -175,7 +181,8 @@ export default {
       colockUserList: [],
       ticketPointsList: [],
       ticketId: null,
-      intervalId: null
+      intervalId: null,
+      uni_data:[]
     }
   },
   mounted() {
@@ -207,8 +214,8 @@ export default {
       })
     },
     initWebSocket(){
-      const userId=localStorage.getItem('userId')
-      connectWebsocket(`ws://192.168.1.127:9090/websocket/jobTicket/${userId}`,{w:'S',},(res)=>{
+      const timestep= Date.now();
+      connectWebsocket(`ws://192.168.1.127:9090/websocket/jobTicket/${timestep}`,{w:'S',},(res)=>{
         console.log(res,'websocket接收服务器的数据');
         const resMsg=res
         if(resMsg=='refresh'){