|
|
|
@ -1,42 +1,26 @@
|
|
|
|
<template>
|
|
|
|
<template>
|
|
|
|
<ContentWrap>
|
|
|
|
<ContentWrap>
|
|
|
|
<el-form
|
|
|
|
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
|
|
|
|
class="-mb-15px"
|
|
|
|
|
|
|
|
:model="queryParams"
|
|
|
|
|
|
|
|
ref="queryFormRef"
|
|
|
|
|
|
|
|
:inline="true"
|
|
|
|
|
|
|
|
label-width="68px"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<el-form-item label="配方编码" prop="recipeCode">
|
|
|
|
<el-form-item label="配方编码" prop="recipeCode">
|
|
|
|
<el-input
|
|
|
|
<el-input
|
|
|
|
v-model="queryParams.recipeCode"
|
|
|
|
v-model="queryParams.recipeCode" placeholder="请输入配方编码" clearable @keyup.enter="handleQuery"
|
|
|
|
placeholder="请输入配方编码"
|
|
|
|
class="!w-240px" />
|
|
|
|
clearable
|
|
|
|
|
|
|
|
@keyup.enter="handleQuery"
|
|
|
|
|
|
|
|
class="!w-240px"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
<el-form-item label="配方名称" prop="recipeName">
|
|
|
|
<el-form-item label="配方名称" prop="name">
|
|
|
|
<el-input
|
|
|
|
<el-input
|
|
|
|
v-model="queryParams.recipeName"
|
|
|
|
v-model="queryParams.name" placeholder="请输入配方名称" clearable @keyup.enter="handleQuery"
|
|
|
|
placeholder="请输入配方名称"
|
|
|
|
class="!w-240px" />
|
|
|
|
clearable
|
|
|
|
|
|
|
|
@keyup.enter="handleQuery"
|
|
|
|
|
|
|
|
class="!w-240px"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
<el-form-item label="产品名称" prop="productName">
|
|
|
|
<el-form-item label="产品名称" prop="productName">
|
|
|
|
<el-input
|
|
|
|
<el-input
|
|
|
|
v-model="queryParams.productName"
|
|
|
|
v-model="queryParams.productName" placeholder="请输入产品名称" clearable @keyup.enter="handleQuery"
|
|
|
|
placeholder="请输入产品名称"
|
|
|
|
class="!w-240px" />
|
|
|
|
clearable
|
|
|
|
|
|
|
|
@keyup.enter="handleQuery"
|
|
|
|
|
|
|
|
class="!w-240px"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
|
|
|
|
<el-form-item>
|
|
|
|
<el-form-item>
|
|
|
|
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 查询</el-button>
|
|
|
|
<el-button @click="handleQuery">
|
|
|
|
|
|
|
|
<Icon icon="ep:search" class="mr-5px" /> 查询
|
|
|
|
|
|
|
|
</el-button>
|
|
|
|
<el-button type="primary" plain @click="openDialog('create')">
|
|
|
|
<el-button type="primary" plain @click="openDialog('create')">
|
|
|
|
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
|
|
|
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
|
|
|
</el-button>
|
|
|
|
</el-button>
|
|
|
|
@ -49,123 +33,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
<ContentWrap>
|
|
|
|
<ContentWrap>
|
|
|
|
<el-table
|
|
|
|
<el-table
|
|
|
|
ref="tableRef"
|
|
|
|
ref="tableRef" v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true" row-key="id"
|
|
|
|
v-loading="loading"
|
|
|
|
highlight-current-row @selection-change="handleSelectionChange" @row-click="handleRowClick">
|
|
|
|
:data="list"
|
|
|
|
|
|
|
|
:stripe="true"
|
|
|
|
|
|
|
|
:show-overflow-tooltip="true"
|
|
|
|
|
|
|
|
row-key="id"
|
|
|
|
|
|
|
|
@selection-change="handleSelectionChange"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<el-table-column type="selection" width="55" reserve-selection />
|
|
|
|
<el-table-column type="selection" width="55" reserve-selection />
|
|
|
|
<el-table-column label="配方编码" align="center" prop="recipeCode" />
|
|
|
|
<el-table-column label="配方编码" align="center" prop="recipeCode" />
|
|
|
|
<el-table-column label="配方名称" align="center" prop="recipeName" />
|
|
|
|
<el-table-column label="配方名称" align="center" prop="name" />
|
|
|
|
<el-table-column label="配方类型" align="center" prop="recipeType" />
|
|
|
|
<el-table-column label="配方类型" align="center" prop="recipeType">
|
|
|
|
<el-table-column label="关联产品" align="center" prop="productName" />
|
|
|
|
|
|
|
|
<el-table-column label="关联设备" align="center" prop="deviceName" />
|
|
|
|
|
|
|
|
<el-table-column label="备注" align="center" prop="remark" />
|
|
|
|
|
|
|
|
<el-table-column label="操作" align="center" width="240px" fixed="right">
|
|
|
|
|
|
|
|
<template #default="scope">
|
|
|
|
<template #default="scope">
|
|
|
|
<el-button link type="primary" @click="openConfigDialog(scope.row)">配置</el-button>
|
|
|
|
{{ getRecipeTypeLabel(scope.row.recipeType) }}
|
|
|
|
<el-button link type="info" @click="openDetail(scope.row)">详情</el-button>
|
|
|
|
|
|
|
|
<el-button link type="warning" @click="openDialog('update', scope.row)">编辑</el-button>
|
|
|
|
|
|
|
|
<el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
|
</el-table-column>
|
|
|
|
</el-table-column>
|
|
|
|
</el-table>
|
|
|
|
<el-table-column label="关联产品" align="center" prop="productName" />
|
|
|
|
<Pagination
|
|
|
|
<el-table-column label="关联设备" align="center" prop="machineName" />
|
|
|
|
:total="total"
|
|
|
|
<el-table-column label="配方描述" align="center" prop="recipeDesc" />
|
|
|
|
v-model:page="queryParams.pageNo"
|
|
|
|
<el-table-column label="操作" align="center" width="240px" fixed="right">
|
|
|
|
v-model:limit="queryParams.pageSize"
|
|
|
|
|
|
|
|
@pagination="handlePagination"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</ContentWrap>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<ContentWrap v-if="detailVisible">
|
|
|
|
|
|
|
|
<div class="flex items-center justify-between mb-12px">
|
|
|
|
|
|
|
|
<div class="text-14px">
|
|
|
|
|
|
|
|
详情:{{ detailMeta.recipeCode }} - {{ detailMeta.recipeName }}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<el-button link type="info" @click="closeDetail">收起</el-button>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<el-table
|
|
|
|
|
|
|
|
v-loading="detailLoading"
|
|
|
|
|
|
|
|
:data="detailList"
|
|
|
|
|
|
|
|
:stripe="true"
|
|
|
|
|
|
|
|
:show-overflow-tooltip="true"
|
|
|
|
|
|
|
|
row-key="id"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<el-table-column label="序号" align="center" width="80">
|
|
|
|
|
|
|
|
<template #default="scope">
|
|
|
|
<template #default="scope">
|
|
|
|
{{ (detailQueryParams.pageNo - 1) * detailQueryParams.pageSize + scope.$index + 1 }}
|
|
|
|
<el-button link type="primary" @click.stop="openDetail(scope.row)">配置</el-button>
|
|
|
|
|
|
|
|
<el-button link type="warning" @click.stop="openDialog('update', scope.row)">编辑</el-button>
|
|
|
|
|
|
|
|
<el-button link type="danger" @click.stop="handleDelete(scope.row)">删除</el-button>
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
|
</el-table-column>
|
|
|
|
</el-table-column>
|
|
|
|
<el-table-column label="点位名称" align="center" prop="pointName" />
|
|
|
|
|
|
|
|
<el-table-column label="点位类型" align="center" prop="pointType" />
|
|
|
|
|
|
|
|
<el-table-column label="数据类型" align="center" prop="dataType" />
|
|
|
|
|
|
|
|
<el-table-column label="单位" align="center" prop="dataUnit" />
|
|
|
|
|
|
|
|
</el-table>
|
|
|
|
</el-table>
|
|
|
|
<Pagination
|
|
|
|
<Pagination
|
|
|
|
:total="detailTotal"
|
|
|
|
:total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize"
|
|
|
|
v-model:page="detailQueryParams.pageNo"
|
|
|
|
@pagination="handlePagination" />
|
|
|
|
v-model:limit="detailQueryParams.pageSize"
|
|
|
|
|
|
|
|
@pagination="handleDetailPagination"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</ContentWrap>
|
|
|
|
</ContentWrap>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<RecipeDetailList
|
|
|
|
|
|
|
|
ref="detailRef"
|
|
|
|
|
|
|
|
:visible="detailVisible"
|
|
|
|
|
|
|
|
:recipe-id="detailMeta.recipeCode"
|
|
|
|
|
|
|
|
:manual-recipe-id="detailMeta.id"
|
|
|
|
|
|
|
|
:recipe-code="detailMeta.recipeCode"
|
|
|
|
|
|
|
|
:name="detailMeta.name"
|
|
|
|
|
|
|
|
@config="handleDetailConfig"
|
|
|
|
|
|
|
|
@close="closeDetail"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
<Dialog :title="dialogTitle" v-model="dialogVisible" width="720px">
|
|
|
|
<Dialog :title="dialogTitle" v-model="dialogVisible" width="720px">
|
|
|
|
<el-form
|
|
|
|
<el-form ref="dialogFormRef" :model="dialogForm" :rules="dialogRules" label-width="100px" v-loading="dialogLoading">
|
|
|
|
ref="dialogFormRef"
|
|
|
|
|
|
|
|
:model="dialogForm"
|
|
|
|
|
|
|
|
:rules="dialogRules"
|
|
|
|
|
|
|
|
label-width="100px"
|
|
|
|
|
|
|
|
v-loading="dialogLoading"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<el-form-item label="配方编码" prop="recipeCode">
|
|
|
|
<el-form-item label="配方编码" prop="recipeCode">
|
|
|
|
<el-input v-model="dialogForm.recipeCode" placeholder="请输入配方编码" clearable />
|
|
|
|
<el-input v-model="dialogForm.recipeCode" placeholder="请输入配方编码" clearable />
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
<el-form-item label="配方名称" prop="recipeName">
|
|
|
|
<el-form-item label="配方名称" prop="name">
|
|
|
|
<el-input v-model="dialogForm.recipeName" placeholder="请输入配方名称" clearable />
|
|
|
|
<el-input v-model="dialogForm.name" placeholder="请输入配方名称" clearable />
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
<el-form-item label="配方类型" prop="recipeType">
|
|
|
|
<el-form-item label="配方类型" prop="recipeType">
|
|
|
|
<el-input v-model="dialogForm.recipeType" placeholder="请输入配方类型" clearable />
|
|
|
|
<el-select
|
|
|
|
|
|
|
|
v-model="dialogForm.recipeType" placeholder="请选择配方类型" clearable filterable class="!w-full"
|
|
|
|
|
|
|
|
:loading="recipeTypeLoading">
|
|
|
|
|
|
|
|
<el-option v-for="item in recipeTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
|
|
|
|
|
|
|
|
</el-select>
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
<el-form-item label="关联产品" prop="productId">
|
|
|
|
<el-form-item label="关联产品" prop="productName">
|
|
|
|
<el-select
|
|
|
|
<el-select
|
|
|
|
v-model="dialogForm.productId"
|
|
|
|
v-model="dialogForm.productName" placeholder="请选择关联产品" clearable filterable class="!w-full"
|
|
|
|
placeholder="请选择关联产品"
|
|
|
|
:loading="productLoading">
|
|
|
|
clearable
|
|
|
|
<el-option v-for="item in productOptions" :key="item.value" :label="item.label" :value="item.value" />
|
|
|
|
filterable
|
|
|
|
|
|
|
|
class="!w-full"
|
|
|
|
|
|
|
|
:loading="productLoading"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<el-option
|
|
|
|
|
|
|
|
v-for="item in productOptions"
|
|
|
|
|
|
|
|
:key="item.value"
|
|
|
|
|
|
|
|
:label="item.label"
|
|
|
|
|
|
|
|
:value="item.value"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</el-select>
|
|
|
|
</el-select>
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
<el-form-item label="关联设备" prop="deviceId">
|
|
|
|
<el-form-item label="关联设备" prop="machineName">
|
|
|
|
<el-select
|
|
|
|
<el-select
|
|
|
|
v-model="dialogForm.deviceId"
|
|
|
|
v-model="dialogForm.machineName" placeholder="请选择关联设备" clearable filterable class="!w-full"
|
|
|
|
placeholder="请选择关联设备"
|
|
|
|
:loading="deviceLoading">
|
|
|
|
clearable
|
|
|
|
<el-option v-for="item in deviceOptions" :key="item.value" :label="item.label" :value="item.value" />
|
|
|
|
filterable
|
|
|
|
|
|
|
|
class="!w-full"
|
|
|
|
|
|
|
|
:loading="deviceLoading"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<el-option
|
|
|
|
|
|
|
|
v-for="item in deviceOptions"
|
|
|
|
|
|
|
|
:key="item.value"
|
|
|
|
|
|
|
|
:label="item.label"
|
|
|
|
|
|
|
|
:value="item.value"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</el-select>
|
|
|
|
</el-select>
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
<el-form-item label="备注" prop="remark">
|
|
|
|
<el-form-item label="配方描述" prop="recipeDesc">
|
|
|
|
<el-input v-model="dialogForm.remark" placeholder="请输入备注" clearable type="textarea" />
|
|
|
|
<el-input v-model="dialogForm.recipeDesc" placeholder="请输入配方描述" clearable type="textarea" />
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
</el-form>
|
|
|
|
</el-form>
|
|
|
|
<template #footer>
|
|
|
|
<template #footer>
|
|
|
|
@ -177,11 +112,8 @@
|
|
|
|
<Dialog title="配置" v-model="configVisible" width="920px">
|
|
|
|
<Dialog title="配置" v-model="configVisible" width="920px">
|
|
|
|
<div v-loading="configLoading">
|
|
|
|
<div v-loading="configLoading">
|
|
|
|
<el-transfer
|
|
|
|
<el-transfer
|
|
|
|
v-model="configSelectedKeys"
|
|
|
|
class="formula-config-transfer" v-model="configSelectedKeys" :data="configCandidates" filterable
|
|
|
|
:data="configCandidates"
|
|
|
|
:titles="['来源', '目标']" />
|
|
|
|
filterable
|
|
|
|
|
|
|
|
:titles="['候选点位', '已选点位']"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<template #footer>
|
|
|
|
<template #footer>
|
|
|
|
<el-button @click="configVisible = false">取 消</el-button>
|
|
|
|
<el-button @click="configVisible = false">取 消</el-button>
|
|
|
|
@ -194,9 +126,11 @@
|
|
|
|
import download from '@/utils/download'
|
|
|
|
import download from '@/utils/download'
|
|
|
|
import { ProductApi } from '@/api/erp/product/product'
|
|
|
|
import { ProductApi } from '@/api/erp/product/product'
|
|
|
|
import { DeviceApi } from '@/api/iot/device'
|
|
|
|
import { DeviceApi } from '@/api/iot/device'
|
|
|
|
import { RecipeConfigApi, RecipeConfigVO, RecipePointDetailVO } from '@/api/iot/recipeConfig'
|
|
|
|
import { RecipeApi } from '@/api/iot/recipe'
|
|
|
|
|
|
|
|
import { RecipeConfigApi, RecipeConfigVO } from '@/api/iot/recipeConfig'
|
|
|
|
|
|
|
|
import RecipeDetailList from './components/RecipeDetailList.vue'
|
|
|
|
|
|
|
|
|
|
|
|
type SelectOption = { label: string; value: number }
|
|
|
|
type SelectOption<T = any> = { label: string; value: T }
|
|
|
|
|
|
|
|
|
|
|
|
defineOptions({ name: 'FormulaConfig' })
|
|
|
|
defineOptions({ name: 'FormulaConfig' })
|
|
|
|
|
|
|
|
|
|
|
|
@ -204,13 +138,11 @@ const message = useMessage()
|
|
|
|
const { t } = useI18n()
|
|
|
|
const { t } = useI18n()
|
|
|
|
|
|
|
|
|
|
|
|
const loading = ref(false)
|
|
|
|
const loading = ref(false)
|
|
|
|
const tableRef = ref()
|
|
|
|
|
|
|
|
const queryFormRef = ref()
|
|
|
|
|
|
|
|
const queryParams = reactive({
|
|
|
|
const queryParams = reactive({
|
|
|
|
pageNo: 1,
|
|
|
|
pageNo: 1,
|
|
|
|
pageSize: 10,
|
|
|
|
pageSize: 10,
|
|
|
|
recipeCode: '',
|
|
|
|
recipeCode: '',
|
|
|
|
recipeName: '',
|
|
|
|
name: '',
|
|
|
|
productName: ''
|
|
|
|
productName: ''
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
@ -225,13 +157,13 @@ const total = ref(0)
|
|
|
|
|
|
|
|
|
|
|
|
const buildQueryParams = () => {
|
|
|
|
const buildQueryParams = () => {
|
|
|
|
const recipeCode = queryParams.recipeCode?.trim()
|
|
|
|
const recipeCode = queryParams.recipeCode?.trim()
|
|
|
|
const recipeName = queryParams.recipeName?.trim()
|
|
|
|
const name = queryParams.name?.trim()
|
|
|
|
const productName = queryParams.productName?.trim()
|
|
|
|
const productName = queryParams.productName?.trim()
|
|
|
|
return {
|
|
|
|
return {
|
|
|
|
pageNo: queryParams.pageNo,
|
|
|
|
pageNo: queryParams.pageNo,
|
|
|
|
pageSize: queryParams.pageSize,
|
|
|
|
pageSize: queryParams.pageSize,
|
|
|
|
recipeCode: recipeCode ? recipeCode : undefined,
|
|
|
|
recipeCode: recipeCode ? recipeCode : undefined,
|
|
|
|
recipeName: recipeName ? recipeName : undefined,
|
|
|
|
name: name ? name : undefined,
|
|
|
|
productName: productName ? productName : undefined
|
|
|
|
productName: productName ? productName : undefined
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -278,33 +210,25 @@ const handleDelete = async (row: RecipeConfigVO) => {
|
|
|
|
await RecipeConfigApi.deleteRecipeConfig(row.id)
|
|
|
|
await RecipeConfigApi.deleteRecipeConfig(row.id)
|
|
|
|
message.success(t('common.delSuccess'))
|
|
|
|
message.success(t('common.delSuccess'))
|
|
|
|
await getList()
|
|
|
|
await getList()
|
|
|
|
} catch {}
|
|
|
|
} catch { }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const productLoading = ref(false)
|
|
|
|
const productLoading = ref(false)
|
|
|
|
const productOptions = ref<SelectOption[]>([])
|
|
|
|
const productOptions = ref<SelectOption<string>[]>([])
|
|
|
|
const deviceLoading = ref(false)
|
|
|
|
const deviceLoading = ref(false)
|
|
|
|
const deviceOptions = ref<SelectOption[]>([])
|
|
|
|
const deviceOptions = ref<SelectOption<string>[]>([])
|
|
|
|
|
|
|
|
const recipeTypeLoading = ref(false)
|
|
|
|
const productLabelMap = computed<Record<number, string>>(() => {
|
|
|
|
const recipeTypeOptions = ref<SelectOption<string>[]>([])
|
|
|
|
return productOptions.value.reduce((acc, cur) => {
|
|
|
|
|
|
|
|
acc[cur.value] = cur.label
|
|
|
|
|
|
|
|
return acc
|
|
|
|
|
|
|
|
}, {} as Record<number, string>)
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const deviceLabelMap = computed<Record<number, string>>(() => {
|
|
|
|
const getRecipeTypeLabel = (value: unknown) => {
|
|
|
|
return deviceOptions.value.reduce((acc, cur) => {
|
|
|
|
return value === undefined || value === null ? '' : String(value)
|
|
|
|
acc[cur.value] = cur.label
|
|
|
|
}
|
|
|
|
return acc
|
|
|
|
|
|
|
|
}, {} as Record<number, string>)
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const getProductOptions = async () => {
|
|
|
|
const getProductOptions = async () => {
|
|
|
|
productLoading.value = true
|
|
|
|
productLoading.value = true
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
const data = await ProductApi.getProductSimpleList()
|
|
|
|
const data = await ProductApi.getProductSimpleList()
|
|
|
|
productOptions.value = (data ?? []).map((item: any) => ({ label: item.name, value: item.id }))
|
|
|
|
productOptions.value = (data ?? []).map((item: any) => ({ label: item.name, value: item.name }))
|
|
|
|
} finally {
|
|
|
|
} finally {
|
|
|
|
productLoading.value = false
|
|
|
|
productLoading.value = false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -314,15 +238,26 @@ const getDeviceOptions = async () => {
|
|
|
|
deviceLoading.value = true
|
|
|
|
deviceLoading.value = true
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
const data = await DeviceApi.getDeviceList()
|
|
|
|
const data = await DeviceApi.getDeviceList()
|
|
|
|
deviceOptions.value = (data ?? []).map((item: any) => ({ label: item.deviceName, value: item.id }))
|
|
|
|
deviceOptions.value = (data ?? []).map((item: any) => ({ label: item.deviceName, value: item.deviceName }))
|
|
|
|
} finally {
|
|
|
|
} finally {
|
|
|
|
deviceLoading.value = false
|
|
|
|
deviceLoading.value = false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const getRecipeTypeOptions = async () => {
|
|
|
|
|
|
|
|
recipeTypeLoading.value = true
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
const data = await RecipeApi.getRecipePage({})
|
|
|
|
|
|
|
|
recipeTypeOptions.value = (data?.list ?? []).map((item: any) => ({ label: item.name, value: item.name }))
|
|
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
|
|
recipeTypeLoading.value = false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const ensureOptionsLoaded = async () => {
|
|
|
|
const ensureOptionsLoaded = async () => {
|
|
|
|
if (!productOptions.value.length) await getProductOptions()
|
|
|
|
if (!productOptions.value.length) await getProductOptions()
|
|
|
|
if (!deviceOptions.value.length) await getDeviceOptions()
|
|
|
|
if (!deviceOptions.value.length) await getDeviceOptions()
|
|
|
|
|
|
|
|
if (!recipeTypeOptions.value.length) await getRecipeTypeOptions()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type DialogMode = 'create' | 'update'
|
|
|
|
type DialogMode = 'create' | 'update'
|
|
|
|
@ -334,16 +269,16 @@ const dialogLoading = ref(false)
|
|
|
|
const dialogForm = reactive({
|
|
|
|
const dialogForm = reactive({
|
|
|
|
id: undefined as number | undefined,
|
|
|
|
id: undefined as number | undefined,
|
|
|
|
recipeCode: '',
|
|
|
|
recipeCode: '',
|
|
|
|
recipeName: '',
|
|
|
|
name: '',
|
|
|
|
recipeType: '',
|
|
|
|
recipeType: '' as string | undefined,
|
|
|
|
productId: undefined as number | undefined,
|
|
|
|
productName: '' as string | undefined,
|
|
|
|
deviceId: undefined as number | undefined,
|
|
|
|
machineName: '' as string | undefined,
|
|
|
|
remark: ''
|
|
|
|
recipeDesc: ''
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const dialogRules = reactive({
|
|
|
|
const dialogRules = reactive({
|
|
|
|
recipeCode: [{ required: true, message: '配方编码不能为空', trigger: 'blur' }],
|
|
|
|
recipeCode: [{ required: true, message: '配方编码不能为空', trigger: 'blur' }],
|
|
|
|
recipeName: [{ required: true, message: '配方名称不能为空', trigger: 'blur' }]
|
|
|
|
name: [{ required: true, message: '配方名称不能为空', trigger: 'blur' }]
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const openDialog = async (mode: DialogMode, row?: RecipeConfigVO) => {
|
|
|
|
const openDialog = async (mode: DialogMode, row?: RecipeConfigVO) => {
|
|
|
|
@ -357,21 +292,21 @@ const openDialog = async (mode: DialogMode, row?: RecipeConfigVO) => {
|
|
|
|
if (mode === 'create') {
|
|
|
|
if (mode === 'create') {
|
|
|
|
dialogForm.id = undefined
|
|
|
|
dialogForm.id = undefined
|
|
|
|
dialogForm.recipeCode = ''
|
|
|
|
dialogForm.recipeCode = ''
|
|
|
|
dialogForm.recipeName = ''
|
|
|
|
dialogForm.name = ''
|
|
|
|
dialogForm.recipeType = ''
|
|
|
|
dialogForm.recipeType = ''
|
|
|
|
dialogForm.productId = undefined
|
|
|
|
dialogForm.productName = ''
|
|
|
|
dialogForm.deviceId = undefined
|
|
|
|
dialogForm.machineName = ''
|
|
|
|
dialogForm.remark = ''
|
|
|
|
dialogForm.recipeDesc = ''
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
dialogForm.id = row?.id
|
|
|
|
dialogForm.id = row?.id
|
|
|
|
dialogForm.recipeCode = row?.recipeCode ?? ''
|
|
|
|
dialogForm.recipeCode = row?.recipeCode ?? ''
|
|
|
|
dialogForm.recipeName = row?.recipeName ?? ''
|
|
|
|
dialogForm.name = row?.name ?? row?.recipeName ?? ''
|
|
|
|
dialogForm.recipeType = row?.recipeType ?? ''
|
|
|
|
dialogForm.recipeType = row?.recipeType === undefined || row?.recipeType === null ? '' : String(row.recipeType)
|
|
|
|
dialogForm.productId = row?.productId
|
|
|
|
dialogForm.productName = row?.productName ?? ''
|
|
|
|
dialogForm.deviceId = row?.deviceId
|
|
|
|
dialogForm.machineName = row?.machineName ?? row?.deviceName ?? ''
|
|
|
|
dialogForm.remark = row?.remark ?? ''
|
|
|
|
dialogForm.recipeDesc = row?.recipeDesc ?? row?.remark ?? ''
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const submitDialog = async () => {
|
|
|
|
const submitDialog = async () => {
|
|
|
|
@ -382,13 +317,11 @@ const submitDialog = async () => {
|
|
|
|
const data = {
|
|
|
|
const data = {
|
|
|
|
id: dialogForm.id,
|
|
|
|
id: dialogForm.id,
|
|
|
|
recipeCode: dialogForm.recipeCode,
|
|
|
|
recipeCode: dialogForm.recipeCode,
|
|
|
|
recipeName: dialogForm.recipeName,
|
|
|
|
name: dialogForm.name,
|
|
|
|
recipeType: dialogForm.recipeType,
|
|
|
|
recipeType: dialogForm.recipeType,
|
|
|
|
productId: dialogForm.productId,
|
|
|
|
productName: dialogForm.productName,
|
|
|
|
productName: dialogForm.productId ? productLabelMap.value[dialogForm.productId] : undefined,
|
|
|
|
machineName: dialogForm.machineName,
|
|
|
|
deviceId: dialogForm.deviceId,
|
|
|
|
recipeDesc: dialogForm.recipeDesc
|
|
|
|
deviceName: dialogForm.deviceId ? deviceLabelMap.value[dialogForm.deviceId] : undefined,
|
|
|
|
|
|
|
|
remark: dialogForm.remark
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (dialogMode.value === 'create') {
|
|
|
|
if (dialogMode.value === 'create') {
|
|
|
|
await RecipeConfigApi.createRecipeConfig(data)
|
|
|
|
await RecipeConfigApi.createRecipeConfig(data)
|
|
|
|
@ -404,86 +337,66 @@ const submitDialog = async () => {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const detailRef = ref()
|
|
|
|
const detailVisible = ref(false)
|
|
|
|
const detailVisible = ref(false)
|
|
|
|
const detailLoading = ref(false)
|
|
|
|
|
|
|
|
const detailList = ref<RecipePointDetailVO[]>([])
|
|
|
|
|
|
|
|
const detailTotal = ref(0)
|
|
|
|
|
|
|
|
const detailMeta = reactive({
|
|
|
|
const detailMeta = reactive({
|
|
|
|
recipeId: undefined as number | undefined,
|
|
|
|
id: undefined as number | undefined,
|
|
|
|
recipeCode: '',
|
|
|
|
recipeCode: '',
|
|
|
|
recipeName: ''
|
|
|
|
name: ''
|
|
|
|
})
|
|
|
|
|
|
|
|
const detailQueryParams = reactive({
|
|
|
|
|
|
|
|
pageNo: 1,
|
|
|
|
|
|
|
|
pageSize: 10,
|
|
|
|
|
|
|
|
recipeId: undefined as number | undefined
|
|
|
|
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const getDetailList = async () => {
|
|
|
|
|
|
|
|
if (!detailQueryParams.recipeId) return
|
|
|
|
|
|
|
|
detailLoading.value = true
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
const data = await RecipeConfigApi.getRecipePointDetailPage({
|
|
|
|
|
|
|
|
pageNo: detailQueryParams.pageNo,
|
|
|
|
|
|
|
|
pageSize: detailQueryParams.pageSize,
|
|
|
|
|
|
|
|
recipeId: detailQueryParams.recipeId
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
detailList.value = data.list
|
|
|
|
|
|
|
|
detailTotal.value = data.total
|
|
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
|
|
detailLoading.value = false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const openDetail = async (row: RecipeConfigVO) => {
|
|
|
|
const openDetail = async (row: RecipeConfigVO) => {
|
|
|
|
detailMeta.recipeId = row.id
|
|
|
|
detailMeta.id = row.id
|
|
|
|
detailMeta.recipeCode = row.recipeCode
|
|
|
|
detailMeta.recipeCode = row.recipeCode
|
|
|
|
detailMeta.recipeName = row.recipeName
|
|
|
|
detailMeta.name = row.name ?? row.recipeName ?? ''
|
|
|
|
detailQueryParams.recipeId = row.id
|
|
|
|
|
|
|
|
detailQueryParams.pageNo = 1
|
|
|
|
|
|
|
|
detailVisible.value = true
|
|
|
|
detailVisible.value = true
|
|
|
|
await getDetailList()
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const handleDetailConfig = () => {
|
|
|
|
|
|
|
|
if (!detailMeta.recipeCode) return
|
|
|
|
|
|
|
|
openConfigDialog(detailMeta.recipeCode)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const handleRowClick = async (row: RecipeConfigVO, column: any) => {
|
|
|
|
|
|
|
|
if (column?.type === 'selection') return
|
|
|
|
|
|
|
|
if (column?.label === '操作') return
|
|
|
|
|
|
|
|
await openDetail(row)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const closeDetail = () => {
|
|
|
|
const closeDetail = () => {
|
|
|
|
detailVisible.value = false
|
|
|
|
detailVisible.value = false
|
|
|
|
detailMeta.recipeId = undefined
|
|
|
|
detailMeta.id = undefined
|
|
|
|
detailMeta.recipeCode = ''
|
|
|
|
detailMeta.recipeCode = ''
|
|
|
|
detailMeta.recipeName = ''
|
|
|
|
detailMeta.name = ''
|
|
|
|
detailQueryParams.recipeId = undefined
|
|
|
|
|
|
|
|
detailQueryParams.pageNo = 1
|
|
|
|
|
|
|
|
detailQueryParams.pageSize = 10
|
|
|
|
|
|
|
|
detailList.value = []
|
|
|
|
|
|
|
|
detailTotal.value = 0
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const handleDetailPagination = () => {
|
|
|
|
|
|
|
|
getDetailList()
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type TransferItem = { key: number; label: string; disabled?: boolean }
|
|
|
|
type TransferItem = { key: number; label: string; disabled?: boolean }
|
|
|
|
|
|
|
|
|
|
|
|
const configVisible = ref(false)
|
|
|
|
const configVisible = ref(false)
|
|
|
|
const configLoading = ref(false)
|
|
|
|
const configLoading = ref(false)
|
|
|
|
const configRecipeId = ref<number | undefined>(undefined)
|
|
|
|
const configRecipeId = ref<string | undefined>(undefined)
|
|
|
|
const configCandidates = ref<TransferItem[]>([])
|
|
|
|
const configCandidates = ref<TransferItem[]>([])
|
|
|
|
const configSelectedKeys = ref<number[]>([])
|
|
|
|
const configSelectedKeys = ref<number[]>([])
|
|
|
|
|
|
|
|
|
|
|
|
const openConfigDialog = async (row: RecipeConfigVO) => {
|
|
|
|
const openConfigDialog = async (recipeCode: string) => {
|
|
|
|
configVisible.value = true
|
|
|
|
configVisible.value = true
|
|
|
|
configRecipeId.value = row.id
|
|
|
|
configRecipeId.value = recipeCode
|
|
|
|
configSelectedKeys.value = []
|
|
|
|
configSelectedKeys.value = []
|
|
|
|
configCandidates.value = []
|
|
|
|
configCandidates.value = []
|
|
|
|
configLoading.value = true
|
|
|
|
configLoading.value = true
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
const [candidateRes, selectedRes] = await Promise.all([
|
|
|
|
const [candidateRes, selectedRes] = await Promise.all([
|
|
|
|
RecipeConfigApi.getPointCandidatePage({ pageNo: 1, pageSize: 1000 }),
|
|
|
|
DeviceApi.getDeviceContactModelPage(),
|
|
|
|
RecipeConfigApi.getRecipePointDetailPage({ pageNo: 1, pageSize: 1000, recipeId: row.id })
|
|
|
|
RecipeConfigApi.getRecipePointDetailPage({ pageNo: 1, pageSize: 100, recipeId: recipeCode })
|
|
|
|
])
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
configCandidates.value = (candidateRes.list ?? []).map((item: any) => ({
|
|
|
|
const candidateList = Array.isArray(candidateRes)
|
|
|
|
|
|
|
|
? candidateRes
|
|
|
|
|
|
|
|
: ((candidateRes as any)?.list ?? (candidateRes as any)?.data ?? [])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
configCandidates.value = (candidateList ?? []).map((item: any) => ({
|
|
|
|
key: item.id,
|
|
|
|
key: item.id,
|
|
|
|
label: `${item.pointName}${item.pointType ? '(' + item.pointType : ''}${item.dataType ? '/' + item.dataType : ''}${item.dataUnit ? ' ' + item.dataUnit : ''}${item.pointType ? ')' : ''}`
|
|
|
|
label: `${item.attributeName ?? item.pointName ?? ''}${item.attributeType || item.pointType ? '(' + (item.attributeType ?? item.pointType) : ''}${item.dataType ? '/' + item.dataType : ''}${item.dataUnit ? ' ' + item.dataUnit : ''}${item.attributeType || item.pointType ? ')' : ''}`
|
|
|
|
}))
|
|
|
|
}))
|
|
|
|
|
|
|
|
|
|
|
|
configSelectedKeys.value = (selectedRes.list ?? [])
|
|
|
|
configSelectedKeys.value = (selectedRes.list ?? [])
|
|
|
|
@ -504,8 +417,8 @@ const submitConfig = async () => {
|
|
|
|
})
|
|
|
|
})
|
|
|
|
message.success(t('common.updateSuccess'))
|
|
|
|
message.success(t('common.updateSuccess'))
|
|
|
|
configVisible.value = false
|
|
|
|
configVisible.value = false
|
|
|
|
if (detailVisible.value && detailQueryParams.recipeId === configRecipeId.value) {
|
|
|
|
if (detailVisible.value && detailMeta.recipeCode === configRecipeId.value) {
|
|
|
|
await getDetailList()
|
|
|
|
await detailRef.value?.refresh?.()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} finally {
|
|
|
|
} finally {
|
|
|
|
configLoading.value = false
|
|
|
|
configLoading.value = false
|
|
|
|
@ -518,4 +431,21 @@ onMounted(() => {
|
|
|
|
})
|
|
|
|
})
|
|
|
|
</script>
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped></style>
|
|
|
|
<style scoped>
|
|
|
|
|
|
|
|
:deep(.formula-config-transfer.el-transfer) {
|
|
|
|
|
|
|
|
--el-transfer-panel-body-height: 440px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
:deep(.formula-config-transfer .el-transfer-panel) {
|
|
|
|
|
|
|
|
width: calc((100% - 96px) / 2);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
:deep(.el-transfer__buttons) {
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
</style>
|
|
|
|
|