|
@@ -1,28 +1,34 @@
|
|
|
<template>
|
|
<template>
|
|
|
-<!--基本信息-->
|
|
|
|
|
|
|
+ <!--基本信息-->
|
|
|
<ContentWrap>
|
|
<ContentWrap>
|
|
|
<div class="basicInformation">
|
|
<div class="basicInformation">
|
|
|
<div class="tab-header">
|
|
<div class="tab-header">
|
|
|
- <img src="@/assets/images/information.png" alt="" class="titleimg"/><span class="tab-title"> 基本信息</span>
|
|
|
|
|
|
|
+ <img src="@/assets/images/information.png" alt="" class="titleimg" /><span
|
|
|
|
|
+ class="tab-title"
|
|
|
|
|
+ >
|
|
|
|
|
+ 基本信息</span
|
|
|
|
|
+ >
|
|
|
</div>
|
|
</div>
|
|
|
<div class="basicContent">
|
|
<div class="basicContent">
|
|
|
- <p>SOP: <span>CCO-老液体 2cco#粉料系统-维修</span> </p>
|
|
|
|
|
- <p>作业区域: <span>CCO-BD</span> </p>
|
|
|
|
|
- <p>工艺设备: <span>搅拌机-03</span> </p>
|
|
|
|
|
- <p>作业类型: <span>维修</span> </p>
|
|
|
|
|
- <p>作业状态: <span>进行中</span> </p>
|
|
|
|
|
- <p>开始时间: <span>2025-07-04 14:10:01</span> </p>
|
|
|
|
|
- <p>结束时间: <span>-</span> </p>
|
|
|
|
|
- <p>当前步骤: <span class="specialText">确认隔离方式</span> </p>
|
|
|
|
|
- <p>最新日志: <span>2025-07-04 14:10:01 张天乐 已确认执行识别工作内容</span> </p>
|
|
|
|
|
|
|
+ <p>作业名称: <span>{{JobForm.ticketName}}</span> </p>
|
|
|
|
|
+ <p>作业区域: <span>{{JobForm.workstationName}}</span> </p>
|
|
|
|
|
+ <p>工艺设备: <span>{{JobForm.machineryName}}</span> </p>
|
|
|
|
|
+ <p>作业类型: <span>{{ ticketTypeLabel }}</span></p>
|
|
|
|
|
+ <p>作业状态: <span>{{ ticketStatusLabel }}</span></p>
|
|
|
|
|
+ <p>开始时间: <span>{{JobForm.ticketStartTime}}</span> </p>
|
|
|
|
|
+ <p>结束时间: <span>{{JobForm.ticketEndTime}}</span> </p>
|
|
|
|
|
+ <p>当前步骤: <span class="specialText">待更新</span> </p>
|
|
|
|
|
+ <p>最新日志: <span>待更新</span> </p>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</ContentWrap>
|
|
</ContentWrap>
|
|
|
-<!--作业流程-->
|
|
|
|
|
|
|
+ <!--作业流程-->
|
|
|
<ContentWrap>
|
|
<ContentWrap>
|
|
|
<div class="jobProcess">
|
|
<div class="jobProcess">
|
|
|
<div class="tab-header">
|
|
<div class="tab-header">
|
|
|
- <img src="@/assets/images/jobProcess.png" alt="" class="titleimg"/><span class="tab-title">作业流程</span>
|
|
|
|
|
|
|
+ <img src="@/assets/images/jobProcess.png" alt="" class="titleimg" /><span class="tab-title"
|
|
|
|
|
+ >作业流程</span
|
|
|
|
|
+ >
|
|
|
</div>
|
|
</div>
|
|
|
<div class="processDetail">
|
|
<div class="processDetail">
|
|
|
<!-- VueFlow 主画布 -->
|
|
<!-- VueFlow 主画布 -->
|
|
@@ -55,12 +61,7 @@
|
|
|
:id="`${id}-bottom`"
|
|
:id="`${id}-bottom`"
|
|
|
class="handle handle-bottom"
|
|
class="handle handle-bottom"
|
|
|
/>
|
|
/>
|
|
|
- <Handle
|
|
|
|
|
- type="target"
|
|
|
|
|
- position="left"
|
|
|
|
|
- :id="`${id}-left`"
|
|
|
|
|
- class="handle handle-left"
|
|
|
|
|
- />
|
|
|
|
|
|
|
+ <Handle type="target" position="left" :id="`${id}-left`" class="handle handle-left" />
|
|
|
<Handle
|
|
<Handle
|
|
|
type="source"
|
|
type="source"
|
|
|
position="right"
|
|
position="right"
|
|
@@ -73,84 +74,487 @@
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</ContentWrap>
|
|
</ContentWrap>
|
|
|
-
|
|
|
|
|
<!--作业执行-->
|
|
<!--作业执行-->
|
|
|
<ContentWrap>
|
|
<ContentWrap>
|
|
|
<div class="jobExecution">
|
|
<div class="jobExecution">
|
|
|
- <el-tabs
|
|
|
|
|
- v-model="activeName"
|
|
|
|
|
- type="card"
|
|
|
|
|
- class="demo-tabs"
|
|
|
|
|
- @tab-click="handleClick"
|
|
|
|
|
- >
|
|
|
|
|
- <el-tab-pane name="first">
|
|
|
|
|
- <template #label>
|
|
|
|
|
- <div class="tab-label">
|
|
|
|
|
- <img src="@/assets/images/icon_job_members.png" alt="" class="titleimg" />
|
|
|
|
|
- <span class="tab-text ">作业人员</span>
|
|
|
|
|
|
|
+ <el-tabs v-model="activeName" type="card" class="demo-tabs" @tab-click="handleClick">
|
|
|
|
|
+ <!-- 作业人员-->
|
|
|
|
|
+ <el-tab-pane name="first">
|
|
|
|
|
+ <template #label>
|
|
|
|
|
+ <div class="tab-label">
|
|
|
|
|
+ <img src="@/assets/images/icon_job_members.png" alt="" class="titleimg" />
|
|
|
|
|
+ <span class="tab-text">作业人员</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <div class="jobMemberBox">
|
|
|
|
|
+ <!-- 锁定人区域 -->
|
|
|
|
|
+ <div class="left_box">
|
|
|
|
|
+ <div class="tab-header">
|
|
|
|
|
+ <span class="tab-title">锁定人</span>
|
|
|
</div>
|
|
</div>
|
|
|
- </template>
|
|
|
|
|
- <div class="jobMemberBox">
|
|
|
|
|
-<!-- 锁定人-->
|
|
|
|
|
- <div class="lockmember"></div>
|
|
|
|
|
-<!-- 共锁人-->
|
|
|
|
|
- <div class="co-lockmember"></div>
|
|
|
|
|
|
|
|
|
|
|
|
+ <!-- 有锁定人数据时显示 -->
|
|
|
|
|
+ <div v-if="groupedLockers.length" class="group-container-user">
|
|
|
|
|
+ <div v-for="group in groupedLockers" :key="group.groupId" class="group-card-user">
|
|
|
|
|
+ <div class="group-title">{{ group.groupName }}</div>
|
|
|
|
|
+ <div class="user-list">
|
|
|
|
|
+ <div v-for="user in group.users" :key="user.userId" class="user-card">
|
|
|
|
|
+ <img src="@/assets/images/UserBlack.png" />
|
|
|
|
|
+ <div class="user-name">{{ user.userName }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
- </el-tab-pane>
|
|
|
|
|
|
|
+ <!-- 共锁人区域 -->
|
|
|
|
|
+ <div class="right_box">
|
|
|
|
|
+ <div class="tab-header">
|
|
|
|
|
+ <span class="tab-title">共锁人</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div v-if="coLockUsers.length" class="user-list-colocker">
|
|
|
|
|
+ <div v-for="user in coLockUsers" :key="user.userId" class="user-card">
|
|
|
|
|
+ <img src="@/assets/images/UserBlack.png" />
|
|
|
|
|
+ <div class="user-name">{{ user.userName }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-tab-pane>
|
|
|
|
|
+ <!--点位锁定-->
|
|
|
|
|
+ <el-tab-pane name="second">
|
|
|
|
|
+ <template #label>
|
|
|
|
|
+ <div class="tab-label">
|
|
|
|
|
+ <img src="@/assets/images/icon_red_lock.png" alt="" class="titleimg" />
|
|
|
|
|
+ <span class="tab-text">点位锁定</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <div class="jobMemberBox">
|
|
|
|
|
+ <div
|
|
|
|
|
+ class="group-box"
|
|
|
|
|
+ v-for="(group, index) in jobGroupList"
|
|
|
|
|
+ :key="group.id"
|
|
|
|
|
+ >
|
|
|
|
|
+ <div class="tab-header">
|
|
|
|
|
+ <p class="tab-title">{{ group.groupName }}</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <!-- 表格数据 -->
|
|
|
|
|
+ <div class="tableCon">
|
|
|
|
|
+ <el-radio-group v-model="tableLayouts[index]">
|
|
|
|
|
+ <el-radio-button value="fixed">fixed</el-radio-button>
|
|
|
|
|
+ <el-radio-button value="auto">auto</el-radio-button>
|
|
|
|
|
+ </el-radio-group>
|
|
|
|
|
+ <el-table
|
|
|
|
|
+ :data="getPointsByGroupId(group.id)"
|
|
|
|
|
+ :table-layout="tableLayouts[index]"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-table-column prop="pointId" label="隔离点" />
|
|
|
|
|
+ <el-table-column prop="ticketId" label="作用" />
|
|
|
|
|
+ <el-table-column prop="ticketId" label="锁定人" />
|
|
|
|
|
+ <el-table-column prop="pointStatus" label="锁定状态" >
|
|
|
|
|
+ <template #default="scope">
|
|
|
|
|
+ <dict-tag
|
|
|
|
|
+ :type="DICT_TYPE.POINT_STATUS"
|
|
|
|
|
+ :value="scope.row.pointStatus"
|
|
|
|
|
+ />
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
|
|
|
- <el-tab-pane name="second">
|
|
|
|
|
- <template #label>
|
|
|
|
|
- <div class="tab-label">
|
|
|
|
|
- <img src="@/assets/images/icon_red_lock.png" alt="" class="titleimg" />
|
|
|
|
|
- <span class="tab-text ">点位锁定</span>
|
|
|
|
|
|
|
+ </el-table>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-tab-pane>
|
|
|
|
|
+ <!-- 人员共锁 -->
|
|
|
|
|
+ <el-tab-pane name="third">
|
|
|
|
|
+ <template #label>
|
|
|
|
|
+ <div class="tab-label">
|
|
|
|
|
+ <img src="@/assets/images/icon_co-lock.png" alt="" class="titleimg" />
|
|
|
|
|
+ <span class="tab-text">人员共锁</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <div class="biglockBox">
|
|
|
|
|
+ <!-- 待共锁-->
|
|
|
|
|
+ <div class="mumberbox">
|
|
|
|
|
+ <div class="tab-header">
|
|
|
|
|
+ <span class="tab-title">待共锁(5)</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="user">
|
|
|
|
|
+ <div class="userItem" >
|
|
|
|
|
+ <img src="@/assets/images/icon_co-lock.png" alt=""/>
|
|
|
|
|
+ <p>哇哈哈</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <el-icon :size="50" :color="color" class="arrow">
|
|
|
|
|
+ <CaretRight />
|
|
|
|
|
+ </el-icon>
|
|
|
|
|
+ <!-- 已共锁-->
|
|
|
|
|
+ <div class="mumberbox">
|
|
|
|
|
+ <div class="tab-header">
|
|
|
|
|
+ <span class="tab-title">已共锁(5)</span>
|
|
|
</div>
|
|
</div>
|
|
|
- </template>
|
|
|
|
|
- Config
|
|
|
|
|
- </el-tab-pane>
|
|
|
|
|
-
|
|
|
|
|
- <el-tab-pane name="third">
|
|
|
|
|
- <template #label>
|
|
|
|
|
- <div class="tab-label">
|
|
|
|
|
- <img src="@/assets/images/icon_co-lock.png" alt="" class="titleimg" />
|
|
|
|
|
- <span class="tab-text ">人员共锁</span>
|
|
|
|
|
|
|
+ <div class="user">
|
|
|
|
|
+ <div class="userItem" >
|
|
|
|
|
+ <img src="@/assets/images/icon_co-lock.png" alt=""/>
|
|
|
|
|
+ <p>哇哈哈</p>
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
- </template>
|
|
|
|
|
- Role
|
|
|
|
|
- </el-tab-pane>
|
|
|
|
|
-
|
|
|
|
|
- <el-tab-pane name="fourth">
|
|
|
|
|
- <template #label>
|
|
|
|
|
- <div class="tab-label">
|
|
|
|
|
- <img src="@/assets/images/icon_job_log.png" alt="" class="titleimg" />
|
|
|
|
|
- <span class="tab-text ">作业日志</span>
|
|
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <el-icon :size="50" :color="color" class="arrow">
|
|
|
|
|
+ <CaretRight />
|
|
|
|
|
+ </el-icon>
|
|
|
|
|
+ <!-- 未共锁-->
|
|
|
|
|
+ <div class="mumberbox">
|
|
|
|
|
+ <div class="tab-header">
|
|
|
|
|
+ <span class="tab-title">未共锁(0)</span>
|
|
|
</div>
|
|
</div>
|
|
|
- </template>
|
|
|
|
|
- Task
|
|
|
|
|
- </el-tab-pane>
|
|
|
|
|
- </el-tabs>
|
|
|
|
|
|
|
+ <div class="user">
|
|
|
|
|
+ <div class="userItem" >
|
|
|
|
|
+ <img src="@/assets/images/icon_co-lock.png" alt=""/>
|
|
|
|
|
+ <p>哇哈哈</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="userItem" >
|
|
|
|
|
+ <img src="@/assets/images/icon_co-lock.png" alt=""/>
|
|
|
|
|
+ <p>哇哈哈</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-tab-pane>
|
|
|
|
|
+ <!--作业日志-->
|
|
|
|
|
+ <el-tab-pane name="fourth">
|
|
|
|
|
+ <template #label>
|
|
|
|
|
+ <div class="tab-label">
|
|
|
|
|
+ <img src="@/assets/images/icon_job_log.png" alt="" class="titleimg" />
|
|
|
|
|
+ <span class="tab-text">作业日志</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ Task
|
|
|
|
|
+ </el-tab-pane>
|
|
|
|
|
+ </el-tabs>
|
|
|
</div>
|
|
</div>
|
|
|
-
|
|
|
|
|
</ContentWrap>
|
|
</ContentWrap>
|
|
|
-
|
|
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
-
|
|
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
|
-import {Handle, VueFlow} from "@vue-flow/core";
|
|
|
|
|
|
|
+import { Handle, useVueFlow, VueFlow } from '@vue-flow/core'
|
|
|
import { ref } from 'vue'
|
|
import { ref } from 'vue'
|
|
|
|
|
+import * as JobPointGroup from '@/api/job/jobPointGroup'
|
|
|
|
|
+import * as PointApi from '@/api/dv/spm/index'
|
|
|
|
|
+import * as JobApi from '@/api/job/index'
|
|
|
|
|
+import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
|
|
|
|
+import type { TableInstance } from 'element-plus'
|
|
|
|
|
+import { CaretRight } from '@element-plus/icons-vue'
|
|
|
|
|
|
|
|
-const route = useRoute()
|
|
|
|
|
-console.log(route.query.id,'是否传递成功')
|
|
|
|
|
|
|
+const tableLayout = ref<TableInstance['tableLayout']>('fixed')
|
|
|
|
|
+const tableLayout1 = ref<TableInstance['tableLayout1']>('fixed')
|
|
|
|
|
+
|
|
|
|
|
+const JobForm = reactive({
|
|
|
|
|
+ createTime: null,
|
|
|
|
|
+ id: null,
|
|
|
|
|
+ machineryId: null,
|
|
|
|
|
+ machineryName: null,
|
|
|
|
|
+ modeId: null,
|
|
|
|
|
+ sopGroupList: null,
|
|
|
|
|
+ sopIndex: null,
|
|
|
|
|
+ sopName: null,
|
|
|
|
|
+ workstationId: null,
|
|
|
|
|
+ workstationName: null,
|
|
|
|
|
+ ticketCode: null,
|
|
|
|
|
+ ticketName: null,
|
|
|
|
|
+ sopId: null,
|
|
|
|
|
+ ticketType: null,
|
|
|
|
|
+ ticketContent: null,
|
|
|
|
|
+ ticketStatus: null,
|
|
|
|
|
+ ticketStartTime: null,
|
|
|
|
|
+ ticketEndTime: null,
|
|
|
|
|
+ ticketGroupList: null,
|
|
|
|
|
+ ticketPointsList: null,
|
|
|
|
|
+ ticketStepList: null,
|
|
|
|
|
+ ticketUserList: null
|
|
|
|
|
+})
|
|
|
|
|
+const allGroups = ref<any[]>([]) //获取所有分组
|
|
|
|
|
+const groupList = ref([]) //获取当前sopId的分组
|
|
|
|
|
+const allPoints = ref<any[]>([]) //获取所有点位
|
|
|
const activeName = ref('first')
|
|
const activeName = ref('first')
|
|
|
|
|
+const route = useRoute()
|
|
|
|
|
+const jobTypeOptions = ref([])
|
|
|
|
|
+const jobStatusOptions = ref([])
|
|
|
|
|
+// 表格数据
|
|
|
|
|
+const jobGroupList=ref([]) //获取作业分组信息
|
|
|
|
|
+const ticketPointsList = ref([]) // 隔离点数据
|
|
|
|
|
+const tableLayouts = ref([]) // 每组表格的布局
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+// 初始化
|
|
|
|
|
+onMounted(async () => {
|
|
|
|
|
+ await getDetail()
|
|
|
|
|
+ jobTypeOptions.value = await getIntDictOptions(DICT_TYPE.TICKET_TYPE)
|
|
|
|
|
+ jobStatusOptions.value = await getIntDictOptions(DICT_TYPE.TICKET_STATUS)
|
|
|
|
|
+ await fetchAllGroupsAndPoints() //获取所有分组和点位 来渲染SOP的首页
|
|
|
|
|
+ await onModeContent()
|
|
|
|
|
+})
|
|
|
|
|
+console.log(route.query.id, '是否传递成功')
|
|
|
|
|
+
|
|
|
|
|
+const ticketTypeLabel = computed(() => {
|
|
|
|
|
+ const match = jobTypeOptions.value.find(item => item.value == JobForm.ticketType)
|
|
|
|
|
+ return match ? match.label : JobForm.ticketType
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+const ticketStatusLabel = computed(() => {
|
|
|
|
|
+ const match = jobStatusOptions.value.find(item => item.value == JobForm.ticketStatus)
|
|
|
|
|
+ return match ? match.label : JobForm.ticketStatus
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+// 获取详情
|
|
|
|
|
+// const getDetail = async () => {
|
|
|
|
|
+// // 获取sop信息
|
|
|
|
|
+// const JobData = await JobApi.selectJobTicketById(route.query.id)
|
|
|
|
|
+// // 将JobData的数据复制给JobForm
|
|
|
|
|
+// Object.assign(JobForm, JobData)
|
|
|
|
|
+// jobGroupList.value=JobForm.ticketGroupList
|
|
|
|
|
+// tableData.value = JobForm.ticketPointsList
|
|
|
|
|
+// console.log(JobData,'数据有哪些',tableData.value,'隔离点数据',jobGroupList.value,'分组信息')
|
|
|
|
|
+// }
|
|
|
|
|
+
|
|
|
|
|
+// 初始化详情数据
|
|
|
|
|
+const getDetail = async () => {
|
|
|
|
|
+ const JobData = await JobApi.selectJobTicketById(route.query.id)
|
|
|
|
|
+ // 将JobData的数据复制给JobForm
|
|
|
|
|
+ Object.assign(JobForm, JobData)
|
|
|
|
|
+
|
|
|
|
|
+ jobGroupList.value = JobForm.ticketGroupList
|
|
|
|
|
+ ticketPointsList.value = JobForm.ticketPointsList
|
|
|
|
|
+ console.log(JobData,'数据有哪些',ticketPointsList.value,'隔离点数据',jobGroupList.value,'分组信息')
|
|
|
|
|
+ // 初始化每个表格的布局设置为 'fixed'
|
|
|
|
|
+ tableLayouts.value = jobGroupList.value.map(() => 'fixed')
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 获取某个分组下的隔离点
|
|
|
|
|
+const getPointsByGroupId = (groupId) => {
|
|
|
|
|
+ return ticketPointsList.value.filter((point) => point.groupId === groupId)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+// 作业流程绘制
|
|
|
|
|
+const nodes = ref([]) //储存节点
|
|
|
|
|
+const edges = ref([]) // 存储连接线
|
|
|
|
|
+const { addNodes, addEdges, setEdges, setNodes } = useVueFlow()
|
|
|
|
|
+// 模式初始化
|
|
|
|
|
+const onModeContent = async (value) => {
|
|
|
|
|
+ JobForm.modeId = value
|
|
|
|
|
+ await clearCanvasProperly()
|
|
|
|
|
+ const Data = await JobApi.selectJobTicketById(route.query.id)
|
|
|
|
|
+ const sortedData = Data.ticketStepList.sort((a, b) => (a.stepIndex || 0) - (b.stepIndex || 0))
|
|
|
|
|
+ renderNodesFromData(sortedData)
|
|
|
|
|
+ renderEdgesFromData(sortedData)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 独立的清空画布函数
|
|
|
|
|
+const clearCanvasProperly = async () => {
|
|
|
|
|
+ setNodes([])
|
|
|
|
|
+ setEdges([])
|
|
|
|
|
+ nodes.value = [] // 同步响应式数据(如果有自定义 nodes)
|
|
|
|
|
+ edges.value = []
|
|
|
|
|
+}
|
|
|
|
|
+// 初始化数据渲染节点 - 修正版本
|
|
|
|
|
+const renderNodesFromData = (data) => {
|
|
|
|
|
+ // 清空现有节点
|
|
|
|
|
+ nodes.value = []
|
|
|
|
|
+
|
|
|
|
|
+ data.forEach((item, index) => {
|
|
|
|
|
+ const nodeId = `node-${item.id || Date.now() + index}`
|
|
|
|
|
+
|
|
|
|
|
+ const newNode = {
|
|
|
|
|
+ id: nodeId,
|
|
|
|
|
+ position: {
|
|
|
|
|
+ x: 100 + index * 200,
|
|
|
|
|
+ y: 100
|
|
|
|
|
+ },
|
|
|
|
|
+ width: 100,
|
|
|
|
|
+ height: 150,
|
|
|
|
|
+ data: {
|
|
|
|
|
+ stepIcon: item.stepIcon,
|
|
|
|
|
+ stepTitleShort: item.stepTitleShort,
|
|
|
|
|
+ stepIndex: item.stepIndex || index + 1, // 使用 stepIndex
|
|
|
|
|
+ index: item.stepIndex || index + 1, // 保持兼容性
|
|
|
|
|
+ // 保存完整的数据用于表单编辑
|
|
|
|
|
+ stepData: item
|
|
|
|
|
+ },
|
|
|
|
|
+ style: {
|
|
|
|
|
+ width: '130px',
|
|
|
|
|
+ height: '180px',
|
|
|
|
|
+ borderRadius: '12px',
|
|
|
|
|
+ border: '1px solid #999',
|
|
|
|
|
+ textAlign: 'center',
|
|
|
|
|
+ display: 'flex',
|
|
|
|
|
+ flexDirection: 'column',
|
|
|
|
|
+ alignItems: 'center',
|
|
|
|
|
+ justifyContent: 'space-between',
|
|
|
|
|
+ padding: '10px',
|
|
|
|
|
+ backgroundColor: '#fff'
|
|
|
|
|
+ },
|
|
|
|
|
+ draggable: true
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ addNodes(newNode)
|
|
|
|
|
+ nodes.value.push(newNode)
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 渲染连接线 - 新增函数
|
|
|
|
|
+const renderEdgesFromData = (data) => {
|
|
|
|
|
+ // 清空现有连接线
|
|
|
|
|
+ edges.value = []
|
|
|
|
|
+
|
|
|
|
|
+ // 根据 stepIndex 顺序创建连接线
|
|
|
|
|
+ for (let i = 0; i < data.length - 1; i++) {
|
|
|
|
|
+ const currentStep = data[i]
|
|
|
|
|
+ const nextStep = data[i + 1]
|
|
|
|
|
+
|
|
|
|
|
+ const sourceNodeId = `node-${currentStep.id}`
|
|
|
|
|
+ const targetNodeId = `node-${nextStep.id}`
|
|
|
|
|
+
|
|
|
|
|
+ // 创建连接线,从右侧连接到左侧
|
|
|
|
|
+ const edge = {
|
|
|
|
|
+ id: `edge-${currentStep.id}-${nextStep.id}`,
|
|
|
|
|
+ source: sourceNodeId,
|
|
|
|
|
+ target: targetNodeId,
|
|
|
|
|
+ sourceHandle: `${sourceNodeId}-right`, // 从右侧连接点出发
|
|
|
|
|
+ targetHandle: `${targetNodeId}-left`, // 连接到左侧连接点
|
|
|
|
|
+ type: 'smoothstep',
|
|
|
|
|
+ style: { stroke: '#333', strokeWidth: 2 },
|
|
|
|
|
+ markerEnd: {
|
|
|
|
|
+ type: 'arrowclosed',
|
|
|
|
|
+ width: 20,
|
|
|
|
|
+ height: 20,
|
|
|
|
|
+ color: '#333'
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ addEdges(edge)
|
|
|
|
|
+ edges.value.push(edge)
|
|
|
|
|
+
|
|
|
|
|
+ console.log('创建连接线:', edge)
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
const handleClick = (tab: TabsPaneContext, event: Event) => {
|
|
const handleClick = (tab: TabsPaneContext, event: Event) => {
|
|
|
console.log(tab, event)
|
|
console.log(tab, event)
|
|
|
}
|
|
}
|
|
|
-</script>
|
|
|
|
|
|
|
|
|
|
|
|
+//ticketType改变函数
|
|
|
|
|
+const handleTicketpTypeChange = (value) => {
|
|
|
|
|
+ JobForm.ticketType = value
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 获取所有点位和分组的数据
|
|
|
|
|
+const fetchAllGroupsAndPoints = async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 分组信息
|
|
|
|
|
+ const groupRes = await JobPointGroup.getJobTicketGroupPage({ pageSize: -1, pageNo: 1 })
|
|
|
|
|
+ allGroups.value = groupRes.list
|
|
|
|
|
+ console.log('获取分组', groupRes.list)
|
|
|
|
|
+ // 获取当前ticketId的分组
|
|
|
|
|
+ if (route.query.id) {
|
|
|
|
|
+ const groupData = await JobPointGroup.getJobTicketGroupPage({
|
|
|
|
|
+ pageSize: -1,
|
|
|
|
|
+ pageNo: 1,
|
|
|
|
|
+ ticketId: route.query.id
|
|
|
|
|
+ })
|
|
|
|
|
+ groupList.value = groupData.list
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 点位信息
|
|
|
|
|
+ const pointRes = await PointApi.getIsIsolationPointPage({ pageSize: -1, pageNo: 1 })
|
|
|
|
|
+ allPoints.value = pointRes?.list
|
|
|
|
|
+ console.log('获取点位', pointRes)
|
|
|
|
|
+ } catch (e) {}
|
|
|
|
|
+}
|
|
|
|
|
+// 回显分组和点位数据的计算属性
|
|
|
|
|
+const resolvedGroupedPoints = computed(() => {
|
|
|
|
|
+ const groupsMap = new Map<string, { groupId: string; groupName: string; points: any[] }>()
|
|
|
|
|
+
|
|
|
|
|
+ console.log('JobForm.sopPointsList:', JobForm.ticketPointsList)
|
|
|
|
|
+ console.log('allGroups.value:', allGroups.value)
|
|
|
|
|
+ console.log('allPoints.value:', allPoints.value)
|
|
|
|
|
+
|
|
|
|
|
+ JobForm.ticketPointsList.forEach((item) => {
|
|
|
|
|
+ const groupId = String(item.groupId)
|
|
|
|
|
+ const pointId = item.pointId
|
|
|
|
|
+
|
|
|
|
|
+ console.log('处理项目:', { groupId, pointId, item })
|
|
|
|
|
+
|
|
|
|
|
+ // 查分组名
|
|
|
|
|
+ const groupInfo = allGroups.value.find((g) => String(g.id) === groupId)
|
|
|
|
|
+ const groupName = groupInfo?.groupName
|
|
|
|
|
+
|
|
|
|
|
+ console.log('找到的分组信息:', groupInfo, '分组名:', groupName)
|
|
|
|
|
+
|
|
|
|
|
+ // 查点位详情
|
|
|
|
|
+ const pointInfo = allPoints.value.find((p) => p.id == pointId)
|
|
|
|
|
+ const pointName = pointInfo?.pointName
|
|
|
|
|
+ const pointIcon = pointInfo?.pointIcon
|
|
|
|
|
+
|
|
|
|
|
+ console.log('找到的点位信息:', pointInfo, '点位名:', pointName)
|
|
|
|
|
+
|
|
|
|
|
+ if (!groupsMap.has(groupId)) {
|
|
|
|
|
+ groupsMap.set(groupId, {
|
|
|
|
|
+ groupId,
|
|
|
|
|
+ groupName,
|
|
|
|
|
+ points: []
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const group = groupsMap.get(groupId)!
|
|
|
|
|
+
|
|
|
|
|
+ // 检查是否重复
|
|
|
|
|
+ const isDuplicate = group.points.some((p) => p.pointId === pointId)
|
|
|
|
|
+ console.log('是否重复:', isDuplicate, '当前组内点位:', group.points)
|
|
|
|
|
+
|
|
|
|
|
+ // 防止重复添加
|
|
|
|
|
+ if (!isDuplicate) {
|
|
|
|
|
+ group.points.push({
|
|
|
|
|
+ pointId,
|
|
|
|
|
+ pointName,
|
|
|
|
|
+ pointIcon
|
|
|
|
|
+ })
|
|
|
|
|
+ console.log('添加点位后:', group.points)
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ const result = Array.from(groupsMap.values())
|
|
|
|
|
+ console.log('最终结果:', result)
|
|
|
|
|
+ return result
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+// 从 JobForm.sopUserList 中提取锁定人并按 groupId 分组
|
|
|
|
|
+const groupedLockers = computed(() => {
|
|
|
|
|
+ const lockerUsers =
|
|
|
|
|
+ JobForm.ticketUserList?.filter((u) => u.userRole === 'jtlocker' && u.groupId != null) || []
|
|
|
|
|
+ const groupMap = new Map()
|
|
|
|
|
+
|
|
|
|
|
+ lockerUsers.forEach((user) => {
|
|
|
|
|
+ if (!groupMap.has(user.groupId)) {
|
|
|
|
|
+ const groupName =
|
|
|
|
|
+ groupList.value.find((g) => g.id === user.groupId)?.groupName || '未命名分组'
|
|
|
|
|
+ groupMap.set(user.groupId, { groupId: user.groupId, groupName, users: [] })
|
|
|
|
|
+ }
|
|
|
|
|
+ groupMap.get(user.groupId).users.push(user)
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ return Array.from(groupMap.values())
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+// 提取共锁人
|
|
|
|
|
+const coLockUsers = computed(() => {
|
|
|
|
|
+ return JobForm.ticketUserList?.filter((u) => u.userRole === 'jtcolocker') || []
|
|
|
|
|
+})
|
|
|
|
|
+</script>
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
<style scoped lang="scss">
|
|
|
.basicInformation {
|
|
.basicInformation {
|
|
@@ -158,7 +562,7 @@ const handleClick = (tab: TabsPaneContext, event: Event) => {
|
|
|
border-radius: 4px;
|
|
border-radius: 4px;
|
|
|
margin-top: 20px;
|
|
margin-top: 20px;
|
|
|
|
|
|
|
|
- .basicContent{
|
|
|
|
|
|
|
+ .basicContent {
|
|
|
width: 100%;
|
|
width: 100%;
|
|
|
height: 100%;
|
|
height: 100%;
|
|
|
overflow-y: auto;
|
|
overflow-y: auto;
|
|
@@ -167,13 +571,13 @@ const handleClick = (tab: TabsPaneContext, event: Event) => {
|
|
|
padding: 10px 20px;
|
|
padding: 10px 20px;
|
|
|
box-sizing: border-box;
|
|
box-sizing: border-box;
|
|
|
//background: pink;
|
|
//background: pink;
|
|
|
- p{
|
|
|
|
|
|
|
+ p {
|
|
|
display: block;
|
|
display: block;
|
|
|
min-width: 32%;
|
|
min-width: 32%;
|
|
|
min-height: 25px;
|
|
min-height: 25px;
|
|
|
margin: 8px 5px;
|
|
margin: 8px 5px;
|
|
|
//background: green;
|
|
//background: green;
|
|
|
- .specialText{
|
|
|
|
|
|
|
+ .specialText {
|
|
|
color: #42bafa;
|
|
color: #42bafa;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -187,7 +591,7 @@ const handleClick = (tab: TabsPaneContext, event: Event) => {
|
|
|
border-radius: 4px 4px 0 0;
|
|
border-radius: 4px 4px 0 0;
|
|
|
display: flex;
|
|
display: flex;
|
|
|
align-items: center; /* 垂直居中 */
|
|
align-items: center; /* 垂直居中 */
|
|
|
- .titleimg{
|
|
|
|
|
|
|
+ .titleimg {
|
|
|
width: 25px;
|
|
width: 25px;
|
|
|
height: 25px;
|
|
height: 25px;
|
|
|
margin-right: 8px;
|
|
margin-right: 8px;
|
|
@@ -198,7 +602,7 @@ const handleClick = (tab: TabsPaneContext, event: Event) => {
|
|
|
color: #303133;
|
|
color: #303133;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-.processDetail{
|
|
|
|
|
|
|
+.processDetail {
|
|
|
width: 100%;
|
|
width: 100%;
|
|
|
height: 300px;
|
|
height: 300px;
|
|
|
overflow-y: auto;
|
|
overflow-y: auto;
|
|
@@ -226,26 +630,315 @@ const handleClick = (tab: TabsPaneContext, event: Event) => {
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
justify-content: space-between;
|
|
justify-content: space-between;
|
|
|
}
|
|
}
|
|
|
-.jobExecution{
|
|
|
|
|
|
|
+.jobExecution {
|
|
|
width: 100%;
|
|
width: 100%;
|
|
|
height: 600px;
|
|
height: 600px;
|
|
|
//background: blue;
|
|
//background: blue;
|
|
|
- .tab-label{
|
|
|
|
|
|
|
+ .tab-label {
|
|
|
padding: 12px 20px;
|
|
padding: 12px 20px;
|
|
|
border-radius: 4px 4px 0 0;
|
|
border-radius: 4px 4px 0 0;
|
|
|
display: flex;
|
|
display: flex;
|
|
|
align-items: center; /* 垂直居中 */
|
|
align-items: center; /* 垂直居中 */
|
|
|
- .titleimg{
|
|
|
|
|
|
|
+ .titleimg {
|
|
|
width: 25px;
|
|
width: 25px;
|
|
|
height: 25px;
|
|
height: 25px;
|
|
|
margin-right: 8px;
|
|
margin-right: 8px;
|
|
|
}
|
|
}
|
|
|
- .tab-text {
|
|
|
|
|
|
|
+ .tab-text {
|
|
|
font-size: 14px;
|
|
font-size: 14px;
|
|
|
font-weight: 500;
|
|
font-weight: 500;
|
|
|
color: #303133;
|
|
color: #303133;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ .jobMemberBox {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ min-height: 300px;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
|
+ }
|
|
|
|
|
+ .left_box {
|
|
|
|
|
+ width: 500px;
|
|
|
|
|
+ margin-right: 10px;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+
|
|
|
|
|
+ img {
|
|
|
|
|
+ width: 80px;
|
|
|
|
|
+ height: 80px;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .right_box {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+
|
|
|
|
|
+ img {
|
|
|
|
|
+ width: 80px;
|
|
|
|
|
+ height: 80px;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ //作业流程
|
|
|
|
|
+ .custom-node {
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ width: 125px;
|
|
|
|
|
+ height: 180px;
|
|
|
|
|
+ background-color: #fff;
|
|
|
|
|
+ border-radius: 12px;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ padding: 10px;
|
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .node-content {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //连接点样式
|
|
|
|
|
+
|
|
|
|
|
+ .handle {
|
|
|
|
|
+ width: 12px;
|
|
|
|
|
+ height: 12px;
|
|
|
|
|
+ background-color: #1a192b;
|
|
|
|
|
+ border: 2px solid #fff;
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+ cursor: crosshair;
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ z-index: 10;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .handle:hover {
|
|
|
|
|
+ background-color: #555;
|
|
|
|
|
+ transform: scale(1.2);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .handle-top {
|
|
|
|
|
+ top: -8px;
|
|
|
|
|
+ left: 50%;
|
|
|
|
|
+ transform: translateX(-50%);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .handle-bottom {
|
|
|
|
|
+ bottom: -8px;
|
|
|
|
|
+ left: 50%;
|
|
|
|
|
+ transform: translateX(-50%);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .handle-left {
|
|
|
|
|
+ left: -8px;
|
|
|
|
|
+ top: 50%;
|
|
|
|
|
+ transform: translateY(-50%);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .handle-right {
|
|
|
|
|
+ right: -8px;
|
|
|
|
|
+ top: 50%;
|
|
|
|
|
+ transform: translateY(-50%);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //连接点全局样式
|
|
|
|
|
+ :deep(.vue-flow__handle) {
|
|
|
|
|
+ width: 12px;
|
|
|
|
|
+ height: 12px;
|
|
|
|
|
+ background-color: #1a192b;
|
|
|
|
|
+ border: 2px solid #fff;
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+ cursor: crosshair;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ :deep(.vue-flow__handle:hover) {
|
|
|
|
|
+ background-color: #555;
|
|
|
|
|
+ transform: scale(1.2);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //连接线样式
|
|
|
|
|
+ :deep(.vue-flow__edge-path) {
|
|
|
|
|
+ stroke: #333;
|
|
|
|
|
+ stroke-width: 2;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ :deep(.vue-flow__edge) {
|
|
|
|
|
+ z-index: 1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 箭头样式
|
|
|
|
|
+ :deep(.vue-flow__edge-marker) {
|
|
|
|
|
+ fill: #333;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .group-container {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
|
+ gap: 20px; /* 卡片之间的间距 */
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .point-group {
|
|
|
|
|
+ border: 1px solid #ccc;
|
|
|
|
|
+ border-radius: 8px;
|
|
|
|
|
+ padding: 12px;
|
|
|
|
|
+ min-width: 250px;
|
|
|
|
|
+ background-color: #fafafa;
|
|
|
|
|
+ height: 250px;
|
|
|
|
|
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .group-title {
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ font-size: 16px;
|
|
|
|
|
+ margin-bottom: 12px;
|
|
|
|
|
+ padding-bottom: 6px;
|
|
|
|
|
+ border-bottom: 1px solid #e0e0e0;
|
|
|
|
|
+ color: #333;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .points-list {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
|
+ gap: 12px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .point-item {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ width: 60px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .point-icon {
|
|
|
|
|
+ width: 40px;
|
|
|
|
|
+ height: 40px;
|
|
|
|
|
+ object-fit: contain;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .point-name {
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ margin-top: 4px;
|
|
|
|
|
+ color: #555;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //用户的卡片
|
|
|
|
|
+ .group-container-user {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: row;
|
|
|
|
|
+ gap: 16px;
|
|
|
|
|
+ overflow-x: auto;
|
|
|
|
|
+ padding-bottom: 10px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .group-card-user {
|
|
|
|
|
+ width: 180px;
|
|
|
|
|
+ min-height: 150px;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ border-radius: 8px;
|
|
|
|
|
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
|
|
|
|
|
+ padding: 12px;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+ border: 1px solid #eee;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ margin-top: 10px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .group-title {
|
|
|
|
|
+ font-weight: bold;
|
|
|
|
|
+ font-size: 16px;
|
|
|
|
|
+ margin-bottom: 10px;
|
|
|
|
|
+ color: #333;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ border-bottom: 1px solid #f0f0f0;
|
|
|
|
|
+ padding-bottom: 6px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .user-list {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
|
+ gap: 10px;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .user-list-colocker {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
|
+ gap: 10px;
|
|
|
|
|
+ justify-content: flex-start;
|
|
|
|
|
+ margin-top: 10px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .user-card {
|
|
|
|
|
+ width: 60px;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+
|
|
|
|
|
+ img {
|
|
|
|
|
+ width: 40px;
|
|
|
|
|
+ height: 40px;
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+ border: 1px solid #ccc;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .user-name {
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ margin-top: 4px;
|
|
|
|
|
+ color: #555;
|
|
|
|
|
+ word-break: break-all;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ //点位数据
|
|
|
|
|
+ .group-box{
|
|
|
|
|
+ margin: 0 20px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //人员共锁
|
|
|
|
|
+ .biglockBox{
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
|
+ //background: green;
|
|
|
|
|
+ .mumberbox{
|
|
|
|
|
+ width: 28%;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ margin: 0 15px;
|
|
|
|
|
+ .user{
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 500px;
|
|
|
|
|
+ overflow-y: auto;
|
|
|
|
|
+ overflow-x: hidden;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
|
+ padding:2px 5px;
|
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
|
+ //background: pink;
|
|
|
|
|
+ .userItem{
|
|
|
|
|
+ width: 20%;
|
|
|
|
|
+ height: 80px;
|
|
|
|
|
+ padding: 2px 13px;
|
|
|
|
|
+ //background: #000;
|
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
|
+ img{
|
|
|
|
|
+ width: 50px;
|
|
|
|
|
+ height:50px;
|
|
|
|
|
+ }
|
|
|
|
|
+ p{
|
|
|
|
|
+ font-size: 16px;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ .arrow{
|
|
|
|
|
+ margin-top: 15%;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/* 小屏幕下隐藏文字,只显示图标 */
|
|
/* 小屏幕下隐藏文字,只显示图标 */
|
|
|
@media (max-width: 768px) {
|
|
@media (max-width: 768px) {
|
|
|
.tab-label {
|
|
.tab-label {
|
|
@@ -267,8 +960,9 @@ const handleClick = (tab: TabsPaneContext, event: Event) => {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+ .group-card-user {
|
|
|
|
|
+ width: 160px;
|
|
|
|
|
+ min-height: 130px;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
</style>
|
|
</style>
|