获取设备列表、切换设备列表、开始生产接口和逻辑修改、结束任务联调、工艺信息联调、切换任务联调
| | |
| | | import { request } from '@/common/utils' |
| | | import type { CraftParamsResponse, TasksGroupByChannel } from './task' |
| | | import type { CraftParamsResponse, TasksGroupByChannel, Task } from './task' |
| | | import type { PLCResponse } from './plc' |
| | | import type { Devices } from './device' |
| | | import type { CraftModel } from './craftModel' |
| | |
| | | offset: number |
| | | /** 查多少条 */ |
| | | limit: number |
| | | /** 设备id */ |
| | | deviceID: string |
| | | } |
| | | |
| | | /** |
| | |
| | | export function getTaskList(params: TaskListParams) { |
| | | return request<BaseResponse<TasksGroupByChannel>>({ |
| | | url: '/api-s/v1/reportWork/taskList', |
| | | method: 'get', |
| | | params |
| | | }) |
| | | } |
| | | |
| | | export interface TaskInfoParams { |
| | | /** 设备id */ |
| | | deviceID: string |
| | | /** 工序id */ |
| | | procedureID: number |
| | | } |
| | | |
| | | /** |
| | | * 获取任务详情 |
| | | * @param params |
| | | */ |
| | | export function getTaskInfo(params: TaskInfoParams) { |
| | | return request<BaseResponse<Task>>({ |
| | | url: '/api-s/v1/reportWork/taskInfo', |
| | | method: 'get', |
| | | params |
| | | }) |
| | |
| | | }) |
| | | } |
| | | |
| | | export interface ProcedureUpdateParams { |
| | | isFinish: boolean |
| | | isProcessing: boolean |
| | | workOrderProcedureID: number |
| | | } |
| | | |
| | | /** |
| | | * 开始任务/完成任务 (原 获取工艺参数/结束任务) |
| | | * @param params |
| | | */ |
| | | export function procedureUpdate(params: ProcedureUpdateParams) { |
| | | return request<BaseResponse>({ |
| | | url: `/api-s/v1/reportWork/procedureUpdate`, |
| | | method: 'post', |
| | | data: params |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * 获取当前面板绑定的设备列表 |
| | | */ |
| | |
| | | */ |
| | | export function apiSetCurrentDevice(data: SetCurrentDeviceParams) { |
| | | return request<BaseResponse>({ |
| | | url: `/v1/device/setCurrentDeviceId`, |
| | | url: `/api-s/v1/reportWork/setCurrentDeviceId`, |
| | | method: 'post', |
| | | data |
| | | }) |
| | |
| | | export interface ReportingRecordListParams { |
| | | page?: number |
| | | pageSize?: number |
| | | procedureId: number |
| | | workOrderProcedureID: number |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | export function apiGetReportingRecordList(params: ReportingRecordListParams) { |
| | | return request<ListResponse<ReportingRecord[]>>({ |
| | | url: '/v1/reportWork/list', |
| | | url: '/api-s/v1/reportWork/list', |
| | | method: 'get', |
| | | params |
| | | }) |
| | | } |
| | | |
| | | export interface ReportWorkParams { |
| | | procedureId: number |
| | | workOrderProcedureID: number |
| | | reportAmount: number |
| | | workerID: string |
| | | workerName: string |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | export function apiReportWork(params: ReportWorkParams) { |
| | | return request<BaseResponse>({ |
| | | url: '/v1/reportWork/report', |
| | | url: '/api-s/v1/reportWork/report', |
| | | method: 'post', |
| | | data: params |
| | | }) |
| | |
| | | /** 1 未生产 2生产中 3生产完成*/ |
| | | Status: 1 | 2 | 3 |
| | | procedure: ProcedureProcedure |
| | | productProcedureID: string |
| | | } |
| | | |
| | | export interface ProcedureProcedure { |
| | |
| | | channel: number |
| | | } |
| | | |
| | | export interface ParamsMap { |
| | | [keyProp: string]: string |
| | | } |
| | | export interface ProcedureModel { |
| | | number: string |
| | | product: string |
| | | procedure: string |
| | | paramsMap: ParamsMap |
| | | } |
| | | |
| | | export interface Task { |
| | | Order: Order |
| | | Procedure: Procedure |
| | |
| | | AllProcedures: string[] |
| | | CurrentProcedureIndex: number |
| | | CanStarted: boolean |
| | | ProcedureModel: ProcedureModel |
| | | } |
| | | export interface Material { |
| | | materialId: string |
| | |
| | | function getCraftModelList() { |
| | | if (taskStore.activeTask?.Procedure.ID) { |
| | | craftModelList.value = [] |
| | | apiGetCraftModelList({ |
| | | procedureId: taskStore.activeTask?.Procedure.ID, |
| | | page: page.value, |
| | | pageSize: 6 |
| | | }).then((res) => { |
| | | craftModelList.value = res.data ?? [] |
| | | total.value = res.total |
| | | }) |
| | | console.log(taskStore, '8877994455') |
| | | const procedureModel = taskStore.activeTask?.ProcedureModel |
| | | const craftObj = [ |
| | | { |
| | | ID: Number(taskStore.activeTask?.Procedure?.productProcedureID), |
| | | CreatedAt: taskStore.activeTask?.Procedure?.CreatedAt, |
| | | UpdatedAt: taskStore.activeTask?.Procedure?.UpdatedAt, |
| | | DeletedAt: taskStore.activeTask?.Procedure?.DeletedAt, |
| | | number: procedureModel?.number, |
| | | product: procedureModel?.product, |
| | | procedure: procedureModel?.procedure, |
| | | Params: '', |
| | | paramsMap: procedureModel?.paramsMap, |
| | | deviceId: '', |
| | | isUpdate: false, |
| | | newParamsMap: '', |
| | | newNumber: '' |
| | | } |
| | | ] |
| | | craftModelList.value = craftObj ?? [] |
| | | |
| | | // apiGetCraftModelList({ |
| | | // procedureId: taskStore.activeTask?.Procedure.ID, |
| | | // page: page.value, |
| | | // pageSize: 6 |
| | | // }).then((res) => { |
| | | // craftModelList.value = res.data ?? [] |
| | | // total.value = res.total |
| | | // }) |
| | | } |
| | | } |
| | | |
| | |
| | | if (taskStore.activeTask?.Procedure.ID && !loading.value && hasMore.value) { |
| | | page.value++ |
| | | loading.value = true |
| | | apiGetCraftModelList({ |
| | | procedureId: taskStore.activeTask?.Procedure.ID, |
| | | page: page.value, |
| | | pageSize: 6 |
| | | }) |
| | | .then((res) => { |
| | | craftModelList.value = [...craftModelList.value, ...(res.data ?? [])] |
| | | total.value = res.total |
| | | }) |
| | | .finally(() => { |
| | | loading.value = false |
| | | }) |
| | | console.log(taskStore, '998877994455') |
| | | // apiGetCraftModelList({ |
| | | // procedureId: taskStore.activeTask?.Procedure.ID, |
| | | // page: page.value, |
| | | // pageSize: 6 |
| | | // }) |
| | | // .then((res) => { |
| | | // craftModelList.value = [...craftModelList.value, ...(res.data ?? [])] |
| | | // total.value = res.total |
| | | // }) |
| | | // .finally(() => { |
| | | // loading.value = false |
| | | // }) |
| | | } |
| | | } |
| | | |
| | |
| | | data: deviceRes, |
| | | run: startDevicePolling, |
| | | cancel: cancelDevicePolling |
| | | } = useRequest(getDeviceList, { |
| | | manual: true, |
| | | pollingInterval: DEVICE_INFO_POLLING_DURATION, |
| | | pollingWhenHidden: false |
| | | }) |
| | | } = useRequest( |
| | | getDeviceList |
| | | // { |
| | | // manual: true, |
| | | // pollingInterval: DEVICE_INFO_POLLING_DURATION, |
| | | // pollingWhenHidden: false |
| | | // } |
| | | ) |
| | | |
| | | function startPollingDevice() { |
| | | cancelDevicePolling() |
| | |
| | | import { computed, ref } from 'vue' |
| | | import { defineStore } from 'pinia' |
| | | import type { Task, TasksGroupByChannel, TasksResponse } from '@/api/task' |
| | | import type { TaskListParams } from '@/api' |
| | | import { getTaskList } from '@/api' |
| | | import type { TaskListParams, TaskInfoParams } from '@/api' |
| | | import { getTaskList, getTaskInfo } from '@/api' |
| | | import { isNumber } from 'lodash-es' |
| | | |
| | | export interface ChannelMoreBtnStatus { |
| | |
| | | const params: TaskListParams = { |
| | | type, |
| | | offset: 0, |
| | | limit: 3 |
| | | limit: 3, |
| | | deviceID: localStorage.getItem('currentDeviceID') || '' |
| | | } |
| | | return getTaskList(params) |
| | | .then((res) => { |
| | |
| | | |
| | | if (firstNotEmptyChannel) { |
| | | const channelNumber = +firstNotEmptyChannel[0] |
| | | activeTask.value = channels[channelNumber].Tasks[0] |
| | | setActiveChannel(channelNumber) |
| | | // activeTask.value = channels[channelNumber].Tasks[0] |
| | | console.log(channels[channelNumber].Tasks[0].Procedure.ID, '1111') |
| | | const params: TaskInfoParams = { |
| | | deviceID: localStorage.getItem('currentDeviceID') || '', |
| | | procedureID: channels[channelNumber].Tasks[0].Procedure.ID |
| | | } |
| | | return getTaskInfo(params) |
| | | .then((res) => { |
| | | activeTask.value = res.data |
| | | }) |
| | | .catch((err) => { |
| | | console.error(err) |
| | | }) |
| | | .finally(() => {}) |
| | | } else { |
| | | // 如果没有任务就清空当前选中的任务 |
| | | activeTask.value = undefined |
| | |
| | | function autoSelectTask(channel: number) { |
| | | const currentChannelTaskList = channels.value[channel].Tasks |
| | | if (currentChannelTaskList?.length) { |
| | | activeTask.value = currentChannelTaskList[0] |
| | | setActiveChannel(channel) |
| | | // activeTask.value = currentChannelTaskList[0].Procedure.ID |
| | | const params: TaskInfoParams = { |
| | | deviceID: localStorage.getItem('currentDeviceID') || '', |
| | | procedureID: currentChannelTaskList[0].Procedure.ID |
| | | } |
| | | return getTaskInfo(params) |
| | | .then((res) => { |
| | | activeTask.value = res.data |
| | | }) |
| | | .catch((err) => { |
| | | console.error(err) |
| | | }) |
| | | .finally(() => {}) |
| | | } else { |
| | | const firstNotEmptyChannel = Object.entries(channels.value).find((ele) => { |
| | | const taskList = (ele[1] as TasksResponse)?.Tasks |
| | |
| | | type: currentType.value, |
| | | channel: channelNumber, |
| | | offset: taskLength, |
| | | limit: 10 |
| | | limit: 10, |
| | | deviceID: localStorage.getItem('currentDeviceID') || '' |
| | | } |
| | | getTaskList(params) |
| | | .then((res) => { |
| | |
| | | import { useTasksStore } from '@/stores/tasks' |
| | | import { ArrowDownBold, ArrowUpBold } from '@element-plus/icons-vue' |
| | | import { isNumber } from 'lodash-es' |
| | | import { getTaskInfo } from '@/api' |
| | | import type { TaskInfoParams } from '@/api' |
| | | import { storeToRefs } from 'pinia' |
| | | |
| | | export interface ChannelCollapseProps { |
| | | channels: TasksGroupByChannel |
| | |
| | | const activeChannel = ref<string[]>([]) |
| | | |
| | | const tasksStore = useTasksStore() |
| | | const { activeTask } = storeToRefs(tasksStore) |
| | | |
| | | watchEffect(() => { |
| | | // 通道数据变化后 |
| | |
| | | } |
| | | |
| | | function selectTask(task: Task | undefined) { |
| | | tasksStore.setActiveTask(task) |
| | | let channel = tasksStore?.activeTask?.Channel |
| | | if (isNumber(channel)) { |
| | | tasksStore.setActiveChannel(channel) |
| | | console.log(task, 'iiiiiii') |
| | | |
| | | const params: TaskInfoParams = { |
| | | deviceID: localStorage.getItem('currentDeviceID') || '', |
| | | procedureID: Number(task?.Procedure.ID) |
| | | } |
| | | return getTaskInfo(params) |
| | | .then((res) => { |
| | | tasksStore.setActiveTask(res.data) |
| | | let channel = tasksStore?.activeTask?.Channel |
| | | if (isNumber(channel)) { |
| | | tasksStore.setActiveChannel(channel) |
| | | } |
| | | // taskStore.activeTask?.value = res.data |
| | | }) |
| | | .catch((err) => { |
| | | console.error(err) |
| | | }) |
| | | .finally(() => {}) |
| | | // tasksStore.setActiveTask(task) |
| | | } |
| | | </script> |
| | | |
| | |
| | | }) |
| | | return |
| | | } |
| | | localStorage.setItem('currentDeviceID', selectedDevice.value || '') |
| | | apiSetCurrentDevice({ currentDeviceID: selectedDevice.value }) |
| | | .then(() => { |
| | | ElMessage({ |
| | |
| | | </div> |
| | | <div v-if="craftModel.number == task?.Procedure?.processModelNumber" class="tip-current">当前使用</div> |
| | | <div class="btn"> |
| | | <el-button |
| | | <!-- <el-button |
| | | type="primary" |
| | | :loading="loading" |
| | | :disabled="craftModel.isUpdate ? false : true" |
| | | @click="onUpdateClick" |
| | | > |
| | | <!-- <el-icon v-if="loading" color="#fff" :size="16" class="refresh-top-icon"> |
| | | <Loading /> |
| | | </el-icon> --> |
| | | 更新工艺 |
| | | </el-button> |
| | | </el-button> --> |
| | | </div> |
| | | </div> |
| | | </template> |
| | |
| | | return |
| | | } |
| | | apiGetReportingRecordList({ |
| | | procedureId: procedureId |
| | | workOrderProcedureID: procedureId |
| | | }) |
| | | .then((res) => { |
| | | if (res.code === 200) { |
| | |
| | | import { useDateFormat } from '@vueuse/core' |
| | | import TaskControlModal from '@/views/dashboard/components/TaskControlModal.vue' |
| | | import { CircleCloseFilled } from '@element-plus/icons-vue' |
| | | import { apiReportWork, finishTask } from '@/api' |
| | | import { apiReportWork, procedureUpdate } from '@/api' |
| | | import { ElMessage } from 'element-plus' |
| | | import ReportProductionModal from '@/views/dashboard/components/ReportProductionModal.vue' |
| | | import { usePLCStore } from '@/stores/plc' |
| | |
| | | return true |
| | | } |
| | | } |
| | | finishTask({ id: task!.value.Procedure.ID }).then( |
| | | procedureUpdate({ |
| | | isFinish: true, |
| | | isProcessing: false, |
| | | workOrderProcedureID: Number(task!.value.Procedure.ID) |
| | | }).then( |
| | | (res) => { |
| | | ElMessage({ |
| | | message: '操作成功!', |
| | |
| | | // 有人员才可以报工 |
| | | if (workers.value[0].workerId) { |
| | | apiReportWork({ |
| | | procedureId: task.value?.Procedure.ID, |
| | | workOrderProcedureID: Number(task.value?.Procedure.ID), |
| | | reportAmount: amount, |
| | | workerID: workers.value[0].workerId |
| | | workerID: workers.value[0].workerId, |
| | | workerName: workers.value[0].workerName |
| | | }) |
| | | .then((res) => { |
| | | if (res.code === 200) { |
| | |
| | | <div class="modal-content"> |
| | | <template v-if="['初始化', '计时中', '准备生产', '下发参数中'].includes(state.value as string)"> |
| | | <div class="content-title"> |
| | | <div class="content-title-item">当前任务:{{ task?.Procedure.procedure.procedureName || '' }}</div> |
| | | <div class="content-title-item">当前任务:{{ task?.Procedure?.procedure?.procedureName || '' }}</div> |
| | | <div class="content-title-item"> |
| | | 生产数量: |
| | | <div class="leaf-shape"> |
| | |
| | | <div class="info-item">产品名称:{{ task.Order.productName || '' }}</div> |
| | | <div class="info-item">数量:{{ task.Order.amount || 0 }}{{ task.Order.unit }}</div> |
| | | <div class="info-item">交货日期:{{ task.Order.deliverDate || '' }}</div> |
| | | <div class="info-item">工时: {{ task.Procedure.procedure.workHours || '' }}</div> |
| | | <div class="info-item">工时: {{ task?.Procedure?.procedure?.workHours || '' }}</div> |
| | | <div class="info-item"> |
| | | 计划时间: {{ formatDate(task.Procedure.startTime) || '' }} |
| | | 计划时间: {{ formatDate(task?.Procedure?.startTime) || '' }} |
| | | - |
| | | {{ formatDate(task.Procedure.endTime) }} |
| | | {{ formatDate(task?.Procedure?.endTime) }} |
| | | </div> |
| | | |
| | | <div class="info-item">客户名称:{{ task.Order.customer || '' }}</div> |
| | |
| | | import { ref, toRefs, watch } from 'vue' |
| | | import BigButton from '@/views/dashboard/components/BigButton.vue' |
| | | import { CHANNEL_NAME_MAP } from '@/common/constants' |
| | | import { getCraftParams, sendProcessParams } from '@/api' |
| | | import { procedureUpdate, sendProcessParams } from '@/api' |
| | | import { useCountDown } from '@/common/composable' |
| | | import { storeToRefs } from 'pinia' |
| | | import { useTasksStore } from '@/stores/tasks' |
| | |
| | | if (taskId) { |
| | | craftParams.value = [] |
| | | getCraftParamsTip.value = '' |
| | | |
| | | getCraftParams({ id: taskId }).then( |
| | | (res) => { |
| | | craftParams.value = res.data.Params ?? [] |
| | | getCraftParamsTip.value = '' |
| | | }, |
| | | (err) => { |
| | | console.error(err) |
| | | craftParams.value = [] |
| | | getCraftParamsTip.value = '获取工艺参数失败!' |
| | | } |
| | | ) |
| | | } |
| | | } |
| | | |
| | |
| | | function startProduce() { |
| | | send('开始生产') |
| | | |
| | | sendProcessParams({ |
| | | procedureId: task!.value!.Procedure.ID |
| | | }) |
| | | .then( |
| | | (res) => { |
| | | deliveryTip.value = '下发成功' |
| | | send('成功') |
| | | countdown3s.startCountdown() |
| | | }, |
| | | (err) => { |
| | | console.error(err) |
| | | deliveryTip.value = err.msg ? err.msg : '抱歉,工序下发失败!' |
| | | send('失败') |
| | | } |
| | | ) |
| | | .finally(() => {}) |
| | | procedureUpdate({ |
| | | isFinish: false, |
| | | isProcessing: true, |
| | | workOrderProcedureID: Number(task!.value!.Procedure.ID) |
| | | }).then( |
| | | (res) => { |
| | | deliveryTip.value = '下发成功' |
| | | send('成功') |
| | | countdown3s.startCountdown() |
| | | }, |
| | | (err) => { |
| | | console.error(err) |
| | | deliveryTip.value = err.msg ? err.msg : '抱歉,工序下发失败!' |
| | | send('失败') |
| | | } |
| | | ) |
| | | // sendProcessParams({ |
| | | // procedureId: task!.value!.Procedure.ID |
| | | // }) |
| | | // .then( |
| | | // (res) => { |
| | | // deliveryTip.value = '下发成功' |
| | | // send('成功') |
| | | // countdown3s.startCountdown() |
| | | // }, |
| | | // (err) => { |
| | | // console.error(err) |
| | | // deliveryTip.value = err.msg ? err.msg : '抱歉,工序下发失败!' |
| | | // send('失败') |
| | | // } |
| | | // ) |
| | | // .finally(() => {}) |
| | | } |
| | | |
| | | /** |
| | |
| | | <div class="row"> |
| | | <div class="col"> |
| | | 当前任务: |
| | | <span>{{ task.Procedure.procedure.procedureName || '' }}</span> |
| | | <span>{{ task.Procedure?.procedure?.procedureName || '' }}</span> |
| | | </div> |
| | | <div class="col"> |
| | | 产品名称: |
| | |
| | | </el-tab-pane> |
| | | <el-tab-pane label="物料清单" name="物料清单"> |
| | | <InputMaterialsList |
| | | :material-list="activeTask?.Procedure.procedure.inputMaterials" |
| | | :material-list="activeTask?.Procedure?.procedure?.inputMaterials" |
| | | @detail-click="showMaterialDetailModal" |
| | | ></InputMaterialsList> |
| | | <OutputMaterialsList |
| | | :material-list="activeTask?.Procedure.procedure.outputMaterials" |
| | | :material-list="activeTask?.Procedure?.procedure?.outputMaterials" |
| | | @detail-click="showMaterialDetailModal" |
| | | ></OutputMaterialsList> |
| | | </el-tab-pane> |
| | |
| | | <template #rightBlock2> |
| | | <DeviceStatusInfo :type="1"></DeviceStatusInfo> |
| | | <DeviceStatusInfo :device="deviceStore.deviceInfo" :type="2"></DeviceStatusInfo> |
| | | <DeviceNumberInfo></DeviceNumberInfo> |
| | | </template> |
| | | <DeviceNumberInfo></DeviceNumberInfo> </template |
| | | >当前任务: |
| | | <template #rightBlock3> |
| | | <SubTitle>知识库</SubTitle> |
| | | <div class="task-detail-right-3"> |
| | |
| | | // 启动 设备 轮询 |
| | | const deviceStore = useDevicesStore() |
| | | deviceStore.startPollingDevice() |
| | | // console.log(deviceStore, '1111') |
| | | // localStorage.setItem('currentDeviceID', deviceStore.deviceInfo.currentDeviceID) |
| | | |
| | | // 切换任务时获取对应任务的工艺模型信息 |
| | | const craftModelStore = useCraftModelStore() |
| | |
| | | const currentWorkers = computed(() => { |
| | | const channel = activeTask.value?.Channel |
| | | if (isNumber(channel)) { |
| | | return channels.value[channel].workers ?? [] |
| | | console.log(activeTask.value?.Procedure?.procedure?.workers, '99999') |
| | | // return [] |
| | | return activeTask.value?.Procedure?.procedure?.workers ?? [] |
| | | } else { |
| | | return [] |
| | | } |