haoxuan
2023-11-03 6b027c18660b828ec7b57ad0e3f4ffca9f4d14d1
Merge branch 'dev' of http://192.168.5.5:10010/r/web/bulletin-board-style1 into wn
1个文件已添加
17个文件已修改
411 ■■■■■ 已修改文件
package-lock.json 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/device.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/index.ts 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/problem.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/task.ts 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/common/constants/index.ts 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/icons/AlertLightIcon.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/stores/devices.ts 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/stores/plc.ts 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dashboard/components/DashboardTitle.vue 88 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dashboard/components/DeviceNumberInfo.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dashboard/components/InputMaterialsList.vue 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dashboard/components/InputOutMaterialInfo.vue 57 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dashboard/components/MaterialDetails.vue 31 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dashboard/components/OutputMaterialsList.vue 65 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dashboard/components/TroubleTrackerModal.vue 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dashboard/index.vue 36 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package-lock.json
@@ -22,6 +22,7 @@
        "xstate": "^4.38.3"
      },
      "devDependencies": {
        "@iconify-json/bx": "^1.1.7",
        "@iconify-json/material-symbols-light": "^1.1.0",
        "@iconify-json/mdi": "^1.1.55",
        "@rushstack/eslint-patch": "^1.3.3",
@@ -811,6 +812,15 @@
      "resolved": "https://registry.npmmirror.com/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz",
      "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==",
      "dev": true
    },
    "node_modules/@iconify-json/bx": {
      "version": "1.1.7",
      "resolved": "https://registry.npmmirror.com/@iconify-json/bx/-/bx-1.1.7.tgz",
      "integrity": "sha512-Ugh8uUU9VtK8fI9BBnhLA7VvhPh7erSmJz+eqjvl8HCRRjkz5mbMO5/KYpCOriUVdiiKB9Yv1ObMqS73WLMSwA==",
      "dev": true,
      "dependencies": {
        "@iconify/types": "*"
      }
    },
    "node_modules/@iconify-json/material-symbols-light": {
      "version": "1.1.0",
@@ -5463,6 +5473,15 @@
      "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==",
      "dev": true
    },
    "@iconify-json/bx": {
      "version": "1.1.7",
      "resolved": "https://registry.npmmirror.com/@iconify-json/bx/-/bx-1.1.7.tgz",
      "integrity": "sha512-Ugh8uUU9VtK8fI9BBnhLA7VvhPh7erSmJz+eqjvl8HCRRjkz5mbMO5/KYpCOriUVdiiKB9Yv1ObMqS73WLMSwA==",
      "dev": true,
      "requires": {
        "@iconify/types": "*"
      }
    },
    "@iconify-json/material-symbols-light": {
      "version": "1.1.0",
      "resolved": "https://registry.npmmirror.com/@iconify-json/material-symbols-light/-/material-symbols-light-1.1.0.tgz",
package.json
@@ -27,6 +27,7 @@
    "xstate": "^4.38.3"
  },
  "devDependencies": {
    "@iconify-json/bx": "^1.1.7",
    "@iconify-json/material-symbols-light": "^1.1.0",
    "@iconify-json/mdi": "^1.1.55",
    "@rushstack/eslint-patch": "^1.3.3",
src/api/device.ts
@@ -1,4 +1,5 @@
export interface Devices {
  /** 本机设备编码 */
  systemDeviceID: string
  currentDeviceID: string
  systemDeviceStatus: number
src/api/index.ts
@@ -3,6 +3,7 @@
import type { PLCResponse } from './plc'
import type { Devices } from './device'
import type { CraftModel } from './craftModel'
import type { Problem } from './problem'
export interface BaseResponse<T = any> {
  code: number
@@ -141,3 +142,13 @@
    data: params
  })
}
/**
 * 获取问题诊断问题列表
 */
export function apiGetProblemList() {
  return request<BaseResponse<Problem[]>>({
    url: '/v1/system/problemList',
    method: 'get'
  })
}
src/api/problem.ts
New file
@@ -0,0 +1,6 @@
export interface Problem {
  /** true正常  false异常 */
  CheckResult: boolean
  ItemCode: string
  ItemName: string
}
src/api/task.ts
@@ -47,8 +47,8 @@
  startTime: number
  endTime: number
  workHours: string
  inputMaterials: inputMaterial[]
  outputMaterials: inputMaterial[]
  inputMaterials: Material[]
  outputMaterials: Material[]
  workers: Worker[]
  allProcedureNames: string[]
  channel: number
@@ -62,12 +62,11 @@
  CurrentProcedureIndex: number
  CanStarted: boolean
}
export interface inputMaterial {
export interface Material {
  materialId: string
  materialName: string
  amount: number
  unit: string
  background: string
  date: string
}
src/common/constants/index.ts
@@ -17,7 +17,9 @@
  7: 'G'
}
export const DEVICE_STATUS_NAME_MAP = {
  1: '正常',
  2: '异常'
}
// plc 轮询间隔
export const PLC_POLLING_DURATION = 6_000
// 设备信息 轮询间隔
export const DEVICE_INFO_POLLING_DURATION = 15_000
// 问题诊断
export const PROBLEMS_POLLING_DURATION = 30_000
src/components/icons/AlertLightIcon.vue
@@ -19,14 +19,12 @@
    <g>
      <path
        style="opacity: 0.988"
        fill="#d71d05"
        d="M 87.5,-0.5 C 95.1667,-0.5 102.833,-0.5 110.5,-0.5C 146.888,7.72465 167.388,30.3913 172,67.5C 172.5,101.165 172.667,134.832 172.5,168.5C 123.833,168.5 75.1667,168.5 26.5,168.5C 26.3333,132.498 26.5,96.4985 27,60.5C 33.9986,27.0017 54.1653,6.66837 87.5,-0.5 Z M 101.5,40.5 C 103.678,52.6006 105.011,64.9339 105.5,77.5C 116.858,77.4139 128.191,77.9139 139.5,79C 123.945,100.223 108.778,121.723 94,143.5C 93.167,128.176 92.667,112.842 92.5,97.5C 80.4954,97.6665 68.4954,97.4999 56.5,97C 71.8692,78.4097 86.8692,59.5764 101.5,40.5 Z"
      />
    </g>
    <g>
      <path
        style="opacity: 0.995"
        fill="#d81d05"
        d="M 199.5,183.5 C 199.5,186.833 199.5,190.167 199.5,193.5C 197.167,195.167 195.167,197.167 193.5,199.5C 130.833,199.5 68.1667,199.5 5.5,199.5C 3.83333,197.167 1.83333,195.167 -0.5,193.5C -0.5,190.167 -0.5,186.833 -0.5,183.5C 1.67098,181.5 4.00432,179.666 6.5,178C 68.5,177.333 130.5,177.333 192.5,178C 194.996,179.666 197.329,181.5 199.5,183.5 Z"
      />
    </g>
src/stores/devices.ts
@@ -3,6 +3,7 @@
import { getDeviceList } from '@/api'
import { useRequest } from 'vue-hooks-plus'
import type { Devices } from '@/api/device'
import { DEVICE_INFO_POLLING_DURATION } from '@/common/constants'
export const useDevicesStore = defineStore('device', () => {
  const deviceInfo = computed(() => {
@@ -18,7 +19,7 @@
    cancel: cancelDevicePolling
  } = useRequest(getDeviceList, {
    manual: true,
    pollingInterval: 6000,
    pollingInterval: DEVICE_INFO_POLLING_DURATION,
    pollingWhenHidden: false
  })
src/stores/plc.ts
@@ -5,6 +5,7 @@
import { useRequest } from 'vue-hooks-plus'
import { useTasksStore } from '@/stores/tasks'
import type { PLCResponse } from '@/api/plc'
import { PLC_POLLING_DURATION } from '@/common/constants'
// 全局 watcher ref 防止多次调用 usePLCStore 时重复注册侦听器
const unwatch = ref()
@@ -31,7 +32,7 @@
      } as ProductProgressParams),
    {
      manual: true,
      pollingInterval: 6000,
      pollingInterval: PLC_POLLING_DURATION,
      pollingWhenHidden: false
    }
  )
src/views/dashboard/components/DashboardTitle.vue
@@ -1,41 +1,103 @@
<template>
  <div class="dashboard-title">
    <div class="title-text">智能工作台 — {{ deviceStore?.deviceInfo?.currentDeviceID ?? '' }}</div>
    <div class="title-text">
      智能工作台 — {{ deviceStore?.deviceInfo?.currentDeviceID ?? '' }}
      <el-icon size="32" color="#0db7f5" style="margin-left: 20px; cursor: pointer" @click="openDevicesModal">
        <IconSlider></IconSlider>
      </el-icon>
    </div>
    <div class="title-status">
      <div class="connection-info" @click="openSelectDeviceModal">
        <el-icon size="30" color="red">
      <div class="connection-info" @click="openProblemsModal">
        <el-icon size="30" :color="problemsIconStatus ? '#00ff00' : '#ff0000'">
          <AlertLightIcon></AlertLightIcon>
        </el-icon>
      </div>
      <div class="cloud-connection-status">
        <el-icon size="45" color="#ff0000">
          <IconCloudOff></IconCloudOff>
        <el-icon v-if="cloudConnectionIconStatus" size="45" color="#00ff00">
          <IconCloudDone></IconCloudDone>
        </el-icon>
        <el-icon size="45" color="#00ff00">
          <IconCloudDone></IconCloudDone>
        <el-icon v-else size="45" color="#ff0000">
          <IconCloudOff></IconCloudOff>
        </el-icon>
      </div>
    </div>
  </div>
  <TroubleTrackerModal v-model="showModal"></TroubleTrackerModal>
  <TroubleTrackerModal v-model="showProblemsModal" :problems="problemList"></TroubleTrackerModal>
</template>
<script setup lang="ts">
import AlertLightIcon from '@/components/icons/AlertLightIcon.vue'
import { ref } from 'vue'
import { computed, onUnmounted, ref } from 'vue'
import { useDevicesStore } from '@/stores/devices'
import TroubleTrackerModal from '@/views/dashboard/components/TroubleTrackerModal.vue'
import IconCloudDone from '~icons/material-symbols-light/cloud-done-outline'
import IconCloudOff from '~icons/material-symbols-light/cloud-off-outline'
import IconSlider from '~icons/bx/slider'
import { useRequest } from 'vue-hooks-plus'
import { apiGetProblemList } from '@/api'
import { PROBLEMS_POLLING_DURATION } from '@/common/constants'
const showModal = ref(false)
function openSelectDeviceModal() {
  showModal.value = true
// 是否显示问题诊断modal
const showProblemsModal = ref(false)
/**
 * 打开问题诊断modal
 */
function openProblemsModal() {
  showProblemsModal.value = true
}
// 是否显示设备切换modal
const showDevicesModal = ref(false)
/**
 * 打开设备切换modal
 */
function openDevicesModal() {
  showDevicesModal.value = true
}
// 获取当前设备名
const deviceStore = useDevicesStore()
// 问题诊断列表
const problemList = computed(() => {
  return problemsRes?.value?.data ?? []
})
// 问题诊断icon状态, 问题列表中有一条异常即为红灯 否则是绿灯  true绿灯
const problemsIconStatus = computed(() => {
  if (!problemList.value || !problemList.value?.length) {
    // 默认绿灯, 拿到一次数据后才以接口为准
    return true
  }
  return !problemList.value.some((ele) => !ele.CheckResult)
})
// 云端连接icon状态, 问题列表中有一条代表云端链接的, 异常即为红色云icon 否则是绿色  true绿云
const cloudConnectionIconStatus = computed(() => {
  if (!problemList.value || !problemList.value?.length) {
    // 默认绿灯, 拿到一次数据后才以接口为准
    return true
  }
  // 没数据就当是链接正常
  const cloudConnection = problemList.value.find((ele) => ele.ItemCode === 'cloud')
  return cloudConnection ? cloudConnection?.CheckResult : true
})
/**
 * 轮询问题诊断
 */
const {
  data: problemsRes,
  run: startProblemsPolling,
  cancel: cancelProblemsPolling
} = useRequest(apiGetProblemList, {
  manual: true,
  pollingInterval: PROBLEMS_POLLING_DURATION,
  pollingWhenHidden: false
})
startProblemsPolling()
onUnmounted(() => {
  cancelProblemsPolling()
})
</script>
<style scoped lang="scss">
src/views/dashboard/components/DeviceNumberInfo.vue
@@ -4,7 +4,7 @@
      <div class="device-t">本机设备编码</div>
      <div class="device-b">
        <div class="device-info">
          {{ deviceInfo?.currentDeviceID }}
          {{ deviceInfo?.systemDeviceID }}
        </div>
      </div>
    </div>
src/views/dashboard/components/InputMaterialsList.vue
@@ -6,8 +6,8 @@
    </div>
    <el-scrollbar always class="scroller">
      <div class="materials-b">
        <div v-for="item in inputMaterials" :key="item.materialId">
          <InputOutMaterialInfo :item="item" :background="item.background"></InputOutMaterialInfo>
        <div v-for="item in props.materialList" :key="item.materialId">
          <InputOutMaterialInfo :material="item" @detail-click="onDetailClick"></InputOutMaterialInfo>
        </div>
      </div>
    </el-scrollbar>
@@ -16,23 +16,18 @@
<script setup lang="ts">
import InputOutMaterialInfo from '@/views/dashboard/components/InputOutMaterialInfo.vue'
import BigButton from '@/views/dashboard/components/BigButton.vue'
import { toRefs } from 'vue'
const inputMaterials = [
  {
    materialId: '1111',
    materialName: '输入名称',
    amount: 10,
    unit: '个',
    date: 10
  },
  {
    materialId: '2222222222222222',
    materialName: '输入名称2',
    amount: 20,
    unit: '个',
    background: '#33ccff'
  }
]
import type { Material } from '@/api/task'
const props = defineProps<{
  materialList?: Material[]
}>()
const emits = defineEmits<{
  detailClick: [material: Material]
}>()
function onDetailClick(material: Material) {
  emits('detailClick', material)
}
</script>
<style scoped lang="scss">
src/views/dashboard/components/InputOutMaterialInfo.vue
@@ -4,57 +4,55 @@
      <div class="card-t-t card_drop">
        <el-popover :width="200" placement="top-start" trigger="click">
          <template #reference>
            {{ item.materialId }}
            {{ material.materialId }}
          </template>
          {{ item.materialId }}
          {{ material.materialId }}
        </el-popover>
      </div>
      <div class="card-t-b">
        设备12
        <el-icon class="right-arrow">
          <Right />
        </el-icon>
        设备13
        <!--        TODO: 接口缺失数据, 待添加-->
        <!--        设备12-->
        <!--        <el-icon class="right-arrow">-->
        <!--          <Right />-->
        <!--        </el-icon>-->
        <!--        设备13-->
      </div>
    </div>
    <div class="card-b">
      <div class="card_drop card-b-l">
        <el-popover :width="200" placement="top-start" trigger="click">
          <template #reference>
            {{ item.materialName }}
            {{ material.materialName }}
          </template>
          {{ item.materialName }}
          {{ material.materialName }}
        </el-popover>
      </div>
      <div class="card-b-r">
        <el-popover v-if="item.date" popper-class="card-info" :width="110" placement="top" trigger="click">
          <template #reference> {{ item.amount }} {{ item.unit }} </template>
          预计{{ item.date }}分钟送达
        <el-popover v-if="material.date" popper-class="card-info" :width="110" placement="top" trigger="click">
          <template #reference> {{ material.amount }} {{ material.unit }} </template>
          预计{{ material.date }}分钟送达
        </el-popover>
        <div v-else>{{ item.amount }} {{ item.unit }}</div>
        <div v-else>{{ material.amount }} {{ material.unit }}</div>
      </div>
    </div>
  </div>
  <MaterialDetails v-model="showModal"></MaterialDetails>
</template>
<script setup lang="ts">
import type { inputMaterial } from '@/api/task'
import MaterialDetails from '@/views/dashboard/components/MaterialDetails.vue'
import { Right } from '@element-plus/icons-vue'
import { ref, toRefs } from 'vue'
import type { Material } from '@/api/task'
import { toRefs } from 'vue'
export interface InputOutMaterialInfoProps {
  item: inputMaterial
  background?: string
  material: Material
  // TODO: 接口还不支持, 预留
  type?: '已送达' | '运输中'
}
const props = withDefaults(defineProps<InputOutMaterialInfoProps>(), {
  background: '#ffcc00'
})
const { item, background } = toRefs(props)
const showModal = ref(false)
const props = defineProps<InputOutMaterialInfoProps>()
const { material } = toRefs(props)
const emits = defineEmits<{
  detailClick: [material: Material]
}>()
function materialInfoClick() {
  showModal.value = true
  emits('detailClick', material.value)
}
</script>
@@ -93,8 +91,7 @@
    font-size: 12px;
    color: #333;
    padding: 3px 5px;
    // background: $status-done;
    background-color: v-bind(background);
    background: $status-done;
    text-align: left;
    .card-t-t {
      width: 100%;
@@ -126,7 +123,7 @@
  background: red !important;
  font-size: 12px;
  color: #fff;
  border: 0px;
  border: 0;
  border-radius: 10px;
  // height:20px!important;
  line-height: 8px !important;
src/views/dashboard/components/MaterialDetails.vue
@@ -3,19 +3,22 @@
    <BaseModal v-model="modelData" :wider="true" @close="closeModal">
      <template #title>物料详情 </template>
      <div class="details-box">
        <div class="details-t">
          <div class="details-t-t">{{ materialObj.form.materialId }}</div>
        <div v-if="material" class="details-t">
          <div class="details-t-t">{{ material.materialId }}</div>
          <div class="details-t-b">
            <div class="details-t-b-l">
              <div class="item">物料名称:{{ materialObj.form.materialName }}</div>
              <div class="item">数量:{{ materialObj.form.amount }}</div>
              <div class="item">物料规格:{{ materialObj.form.amount }}</div>
              <div class="item">物料类型:{{ materialObj.form.amount }}</div>
              <div class="item">物料名称:{{ material.materialName }}</div>
              <div class="item">数量:{{ material.amount }}</div>
              <div class="item">物料规格:{{ material.amount }}</div>
              <div class="item">物料类型:{{ material.amount }}</div>
            </div>
            <BigButton class="btn" bg-color="#03d203f0">已送达</BigButton>
            <!--   TODO:  物料送达缺接口-->
            <BigButton v-if="false" class="btn" bg-color="#03d203f0">已送达</BigButton>
          </div>
        </div>
        <div class="details-b">
        <!--   TODO:  物料送达缺接口-->
        <div v-if="false" class="details-b">
          <div class="details-b-t">运输详情</div>
          <div class="details-b-b">
@@ -44,11 +47,13 @@
<script setup lang="ts">
import { useVModel } from '@vueuse/core'
import BigButton from '@/views/dashboard/components/BigButton.vue'
import { ref } from 'vue'
import type { Material } from '@/api/task'
export interface MaterialDetailsProps {
  material?: Material
  modelValue: boolean
}
const props = withDefaults(defineProps<MaterialDetailsProps>(), {
  material: undefined,
  modelValue: false
})
const emit = defineEmits<{
@@ -59,14 +64,8 @@
function closeModal() {
  modelData.value = false
}
// 假数据
const materialObj = {
  form: {
    materialId: '1111',
    materialName: '输入名称',
    amount: 10,
    unit: '个',
    date: 10
  },
  materialFlow: [
    {
      label: '已送达',
src/views/dashboard/components/OutputMaterialsList.vue
@@ -6,8 +6,8 @@
    </div>
    <el-scrollbar always class="scroller">
      <div class="materials-b">
        <div v-for="item in outputMaterials" :key="item.materialId">
          <InputOutMaterialInfo :item="item" :background="item.background"></InputOutMaterialInfo>
        <div v-for="item in props.materialList" :key="item.materialId">
          <InputOutMaterialInfo :material="item" @detail-click="onDetailClick"></InputOutMaterialInfo>
        </div>
      </div>
    </el-scrollbar>
@@ -16,55 +16,18 @@
<script setup lang="ts">
import InputOutMaterialInfo from '@/views/dashboard/components/InputOutMaterialInfo.vue'
import BigButton from '@/views/dashboard/components/BigButton.vue'
import { toRefs } from 'vue'
const outputMaterials = [
  {
    materialId: '1111',
    materialName: '输入名称',
    amount: 10,
    unit: '个'
  },
  {
    materialId: '2222222222222222',
    materialName: '输入名称2',
    amount: 20,
    unit: '个',
    background: '#33ccff'
  },
  {
    materialId: '1111',
    materialName: '输入名称',
    amount: 10,
    unit: '个'
  },
  {
    materialId: '2222222222222222',
    materialName: '输入名称2',
    amount: 20,
    unit: '个',
    background: '#33ccff'
  },
  {
    materialId: '1111',
    materialName: '输入名称',
    amount: 10,
    unit: '个'
  },
  {
    materialId: '2222222222222222',
    materialName: '输入名称2',
    amount: 20,
    unit: '个',
    background: '#33ccff'
  },
  {
    materialId: '2222222222222222',
    materialName: '输入名称2',
    amount: 20,
    unit: '个',
    background: '#33ccff'
  }
]
import type { Material } from '@/api/task'
const props = defineProps<{
  materialList?: Material[]
}>()
const emits = defineEmits<{
  detailClick: [material: Material]
}>()
function onDetailClick(material: Material) {
  emits('detailClick', material)
}
</script>
<style scoped lang="scss">
src/views/dashboard/components/TroubleTrackerModal.vue
@@ -4,17 +4,17 @@
      <template #title>问题诊断 </template>
      <div class="modal-content">
        <el-scrollbar always class="scroller">
          <div v-if="fakeTroubles?.length" class="trouble">
            <div v-for="(item, index) in fakeTroubles" :key="index" class="trouble-item">
          <div v-if="problems?.length" class="trouble">
            <div v-for="(item, index) in problems" :key="index" class="trouble-item">
              <div class="trouble-content">
                <div class="trouble-icon">
                  <el-icon v-if="item.status === 2" size="30" color="#ff0000"><WarnTriangleFilled /></el-icon>
                  <el-icon v-if="item.status === 1" size="30" color="#00ff00"><CircleCheckFilled /></el-icon>
                  <el-icon v-if="item.CheckResult" size="30" color="#00ff00"><CircleCheckFilled /></el-icon>
                  <el-icon v-if="!item.CheckResult" size="30" color="#ff0000"><WarnTriangleFilled /></el-icon>
                </div>
                <div class="trouble-text">{{ item.content }}</div>
                <div class="trouble-text">{{ item.ItemName }}</div>
              </div>
              <div class="trouble-status" :class="{ green: item.status === 1, red: item.status === 2 }">
                {{ DEVICE_STATUS_NAME_MAP[item.status] }}
              <div class="trouble-status" :class="{ green: item.CheckResult, red: !item.CheckResult }">
                {{ item.CheckResult ? '正常' : '异常' }}
              </div>
            </div>
          </div>
@@ -25,15 +25,18 @@
</template>
<script setup lang="ts">
import { useVModel } from '@vueuse/core'
import { ref } from 'vue'
import { CircleCheckFilled, WarnTriangleFilled } from '@element-plus/icons-vue'
import { DEVICE_STATUS_NAME_MAP } from '@/common/constants'
import type { Problem } from '@/api/problem'
import { toRefs } from 'vue'
export interface TroubleTrackerModalProps {
  modelValue: boolean
  problems?: Problem[]
}
const props = withDefaults(defineProps<TroubleTrackerModalProps>(), {
  modelValue: false
  modelValue: false,
  problems: undefined
})
const { problems } = toRefs(props)
const emit = defineEmits<{
  'update:modelValue': [show: boolean]
}>()
@@ -42,19 +45,6 @@
function closeModal() {
  modelData.value = false
}
const fakeTroubles = ref<{ content: string; status: 1 | 2 }[]>([{ content: '云端网络连接', status: 1 }])
// TODO: 等接口
fakeTroubles.value.push(
  ...Array(100)
    .fill(0)
    .map(() => {
      return {
        content: '云端网络连接',
        status: Math.ceil(Math.random() + 1)
      } as { content: string; status: 1 | 2 }
    })
)
</script>
<style scoped lang="scss">
.modal-content {
src/views/dashboard/index.vue
@@ -23,8 +23,14 @@
          ></ProcessInfo>
        </el-tab-pane>
        <el-tab-pane label="物料清单" name="物料清单">
          <InputMaterialsList></InputMaterialsList>
          <OutputMaterialsList></OutputMaterialsList>
          <InputMaterialsList
            :material-list="activeTask?.Procedure.procedure.inputMaterials"
            @detail-click="showMaterialDetailModal"
          ></InputMaterialsList>
          <OutputMaterialsList
            :material-list="activeTask?.Procedure.procedure.outputMaterials"
            @detail-click="showMaterialDetailModal"
          ></OutputMaterialsList>
        </el-tab-pane>
      </el-tabs>
    </template>
@@ -33,8 +39,8 @@
      <div class="task-detail">
        <TaskControl :task="activeTask" @should-reload="reloadAllData"></TaskControl>
      </div>
      <ColorInfo :order="order" :type="1"></ColorInfo>
      <ColorInfo :order="order" :type="2"></ColorInfo>
      <ColorInfo :type="1"></ColorInfo>
      <ColorInfo :type="2"></ColorInfo>
    </template>
    <template #middleBlock4>
      <SubTitle>人员信息</SubTitle>
@@ -57,11 +63,12 @@
    </template>
  </DashboardLayout>
  <CraftDetailModal v-model="showCraftModelDetail" @close="showCraftModelDetail = false"></CraftDetailModal>
  <MaterialDetails v-model="showMaterialDetail" :material="currentMaterialInfo"></MaterialDetails>
</template>
<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import ChannelCollapse from '@/views/dashboard/components/ChannelCollapse.vue'
import type { Worker, Order, Task } from '@/api/task'
import type { Worker, Order, Task, Material } from '@/api/task'
import PersonInfo from '@/views/dashboard/components/PersonInfo.vue'
import ProcessInfo from '@/views/dashboard/components/ProcessInfo.vue'
import ColorInfo from '@/views/dashboard/components/ColorInfo.vue'
@@ -84,6 +91,7 @@
import { useDevicesStore } from '@/stores/devices'
import { useCraftModelStore } from '@/stores/craftModel'
import CraftDetailModal from '@/views/dashboard/components/CraftDetailModal.vue'
import MaterialDetails from '@/views/dashboard/components/MaterialDetails.vue'
defineOptions({
  name: 'DashboardView'
@@ -93,10 +101,6 @@
const taskStore = useTasksStore()
const workers = computed(() => {
  return taskStore.activeTask?.Procedure?.procedure?.workers ?? []
})
const process = computed(() => {
  return { product: '产品名称', number: '111', procedure: '工艺名称', isUpdate: true } as any
})
const order = computed(() => {
@@ -157,6 +161,20 @@
  console.log(1)
  showCraftModelDetail.value = true
}
// 是否展示物料详情弹窗
const showMaterialDetail = ref(false)
// 当前要展示的物料详情
const currentMaterialInfo = ref<Material>()
/**
 * 显示物料详情弹窗
 * @param material
 */
function showMaterialDetailModal(material: Material) {
  currentMaterialInfo.value = material
  showMaterialDetail.value = true
}
</script>
<style scoped lang="scss">