生产领料、BOM管理、生产工单适配手机端
This commit is contained in:
@@ -1,26 +1,31 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="dialogTitle"
|
||||
<el-drawer
|
||||
v-model="dialogVisible"
|
||||
width="1000px"
|
||||
@close="handleClose"
|
||||
:close-on-click-modal="false"
|
||||
:title="dialogTitle"
|
||||
direction="rtl"
|
||||
size="100%"
|
||||
:close-on-press-escape="true"
|
||||
:destroy-on-close="true"
|
||||
:append-to-body="true"
|
||||
class="mobile-form-drawer"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
label-width="100px"
|
||||
v-loading="formLoading"
|
||||
>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<div class="mobile-form" v-loading="formLoading">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
label-position="top"
|
||||
:disabled="isViewMode"
|
||||
>
|
||||
<!-- 基本信息 -->
|
||||
<div class="mobile-form__section">
|
||||
<div class="mobile-form__section-title">基本信息</div>
|
||||
<el-form-item label="产品" prop="productId">
|
||||
<el-select
|
||||
v-model="formData.productId"
|
||||
placeholder="请选择产品"
|
||||
filterable
|
||||
class="!w-100%"
|
||||
style="width: 100%"
|
||||
:disabled="isViewMode"
|
||||
@change="handleProductChange"
|
||||
>
|
||||
@@ -32,154 +37,147 @@
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="BOM名称" prop="bomName">
|
||||
<el-input v-model="formData.bomName" placeholder="请输入BOM名称" :disabled="isViewMode" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="BOM编码" prop="bomCode">
|
||||
<el-input v-model="formData.bomCode" placeholder="自动生成" :disabled="true" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="版本号" prop="version">
|
||||
<el-input v-model="formData.version" placeholder="如:V1.0" :disabled="isViewMode" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="默认版本" prop="isDefault">
|
||||
<el-radio-group v-model="formData.isDefault" :disabled="isViewMode">
|
||||
<el-radio :label="1">是</el-radio>
|
||||
<el-radio :label="0">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-radio-group v-model="formData.status" :disabled="isViewMode">
|
||||
<el-radio :label="1">启用</el-radio>
|
||||
<el-radio :label="0">禁用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="formData.remark" type="textarea" :rows="3" placeholder="请输入备注" :disabled="isViewMode" />
|
||||
<el-input v-model="formData.remark" type="textarea" :rows="2" placeholder="请输入备注" :disabled="isViewMode" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
<!-- BOM明细 -->
|
||||
<el-divider content-position="left">BOM明细</el-divider>
|
||||
<el-form-item v-if="!isViewMode">
|
||||
<el-button type="primary" @click="addItem">
|
||||
<Icon icon="ep:plus" class="mr-5px" /> 添加物料
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
<!-- BOM明细 -->
|
||||
<div class="mobile-form__section">
|
||||
<div class="mobile-form__section-title">BOM明细</div>
|
||||
<el-button v-if="!isViewMode" type="primary" plain style="width: 100%; margin-bottom: 12px" @click="addItem">
|
||||
<Icon icon="ep:plus" class="mr-5px" /> 添加物料
|
||||
</el-button>
|
||||
|
||||
<el-table :data="formData.items" border style="width: 100%">
|
||||
<el-table-column label="物料" min-width="200">
|
||||
<template #default="{ row, $index }">
|
||||
<el-select
|
||||
v-if="!isViewMode"
|
||||
v-model="row.materialId"
|
||||
placeholder="请选择物料"
|
||||
filterable
|
||||
class="!w-100%"
|
||||
@change="(val: number) => handleMaterialChange(val, $index)"
|
||||
<div class="mobile-item-list">
|
||||
<div
|
||||
v-for="(row, $index) in formData.items"
|
||||
:key="$index"
|
||||
class="mobile-item-card"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in materialList"
|
||||
:key="item.id"
|
||||
:label="`${item.name} (${item.barCode || '-'})`"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
<span v-else>{{ row.materialName }} ({{ row.materialCode || '-' }})</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="物料类型" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-input v-if="!isViewMode" v-model="row.materialType" placeholder="类型" :disabled="true" />
|
||||
<span v-else>{{ row.materialType || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="单位" width="80">
|
||||
<template #default="{ row }">
|
||||
<el-input v-if="!isViewMode" v-model="row.unit" placeholder="单位" />
|
||||
<span v-else>{{ row.unit || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="单位用量" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-input-number
|
||||
v-if="!isViewMode"
|
||||
v-model="row.unitQuantity"
|
||||
:min="0"
|
||||
:precision="4"
|
||||
:step="0.1"
|
||||
:controls="false"
|
||||
class="!w-100%"
|
||||
/>
|
||||
<span v-else>{{ row.unitQuantity }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="损耗率(%)" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-input-number
|
||||
v-if="!isViewMode"
|
||||
v-model="row.lossRate"
|
||||
:min="0"
|
||||
:max="100"
|
||||
:precision="2"
|
||||
:controls="false"
|
||||
class="!w-100%"
|
||||
/>
|
||||
<span v-else>{{ row.lossRate || 0 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="单价" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-input-number
|
||||
v-if="!isViewMode"
|
||||
v-model="row.unitPrice"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
:controls="false"
|
||||
class="!w-100%"
|
||||
/>
|
||||
<span v-else>{{ row.unitPrice ? '¥' + row.unitPrice : '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="必需" width="80">
|
||||
<template #default="{ row }">
|
||||
<el-checkbox v-if="!isViewMode" v-model="row.required" :true-label="1" :false-label="0" />
|
||||
<el-tag v-else :type="row.required === 1 ? 'success' : 'info'" size="small">
|
||||
{{ row.required === 1 ? '是' : '否' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="!isViewMode" label="操作" width="80" fixed="right">
|
||||
<template #default="{ $index }">
|
||||
<el-button link type="danger" @click="removeItem($index)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="dialogVisible = false">{{ isViewMode ? '关闭' : '取消' }}</el-button>
|
||||
<el-button v-if="!isViewMode" type="primary" @click="submitForm" :loading="formLoading">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<div class="mobile-item-card__header">
|
||||
<span class="mobile-item-card__index">#{{ $index + 1 }}</span>
|
||||
<span class="mobile-item-card__name">{{ row.materialName || '未选择物料' }}</span>
|
||||
<el-button
|
||||
v-if="!isViewMode"
|
||||
link
|
||||
type="danger"
|
||||
size="small"
|
||||
@click="removeItem($index)"
|
||||
>删除</el-button>
|
||||
</div>
|
||||
<div class="mobile-item-card__body">
|
||||
<el-form-item v-if="!isViewMode" label="物料" :prop="`items.${$index}.materialId`">
|
||||
<el-select
|
||||
v-model="row.materialId"
|
||||
placeholder="请选择物料"
|
||||
filterable
|
||||
style="width: 100%"
|
||||
@change="(val: number) => handleMaterialChange(val, $index)"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in materialList"
|
||||
:key="item.id"
|
||||
:label="`${item.name} (${item.barCode || '-'})`"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<div class="mobile-item-card__info-row">
|
||||
<span class="mobile-item-card__info-label">物料编码</span>
|
||||
<span class="mobile-item-card__info-value">{{ row.materialCode || '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-item-card__info-row">
|
||||
<span class="mobile-item-card__info-label">物料类型</span>
|
||||
<span class="mobile-item-card__info-value">{{ row.materialType || '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-item-card__info-row">
|
||||
<span class="mobile-item-card__info-label">单位</span>
|
||||
<span class="mobile-item-card__info-value" v-if="isViewMode">{{ row.unit || '-' }}</span>
|
||||
<el-input v-else v-model="row.unit" placeholder="单位" style="width: 120px" />
|
||||
</div>
|
||||
<div class="mobile-item-card__input-group">
|
||||
<el-form-item label="单位用量" :prop="`items.${$index}.unitQuantity`">
|
||||
<el-input-number
|
||||
v-if="!isViewMode"
|
||||
v-model="row.unitQuantity"
|
||||
:min="0"
|
||||
:precision="4"
|
||||
:step="0.1"
|
||||
controls-position="right"
|
||||
style="width: 100%"
|
||||
/>
|
||||
<span v-else>{{ row.unitQuantity }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="损耗率(%)" :prop="`items.${$index}.lossRate`">
|
||||
<el-input-number
|
||||
v-if="!isViewMode"
|
||||
v-model="row.lossRate"
|
||||
:min="0"
|
||||
:max="100"
|
||||
:precision="2"
|
||||
controls-position="right"
|
||||
style="width: 100%"
|
||||
/>
|
||||
<span v-else>{{ row.lossRate || 0 }}</span>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="mobile-item-card__input-group">
|
||||
<el-form-item label="单价" :prop="`items.${$index}.unitPrice`">
|
||||
<el-input-number
|
||||
v-if="!isViewMode"
|
||||
v-model="row.unitPrice"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
controls-position="right"
|
||||
style="width: 100%"
|
||||
/>
|
||||
<span v-else>{{ row.unitPrice ? '¥' + row.unitPrice : '-' }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="必需">
|
||||
<el-checkbox v-if="!isViewMode" v-model="row.required" :true-label="1" :false-label="0" />
|
||||
<el-tag v-else :type="row.required === 1 ? 'success' : 'info'" size="small">
|
||||
{{ row.required === 1 ? '是' : '否' }}
|
||||
</el-tag>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="formData.items.length === 0" class="mobile-empty-tip">
|
||||
暂无物料明细,请点击上方按钮添加
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-form>
|
||||
|
||||
<!-- 底部操作按钮 -->
|
||||
<div class="mobile-form__footer">
|
||||
<el-button @click="dialogVisible = false">{{ isViewMode ? '关闭' : '取消' }}</el-button>
|
||||
<el-button v-if="!isViewMode" type="primary" @click="submitForm" :loading="formLoading">确 定</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -374,3 +372,109 @@ const handleClose = () => {
|
||||
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.mobile-form {
|
||||
padding: 0 4px;
|
||||
}
|
||||
.mobile-form__section {
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
padding: 14px;
|
||||
margin-bottom: 12px;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
.mobile-form__section-title {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
margin-bottom: 12px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
.mobile-form__footer {
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
background: #fff;
|
||||
padding: 12px 16px;
|
||||
padding-bottom: calc(12px + constant(safe-area-inset-bottom));
|
||||
padding-bottom: calc(12px + env(safe-area-inset-bottom));
|
||||
border-top: 1px solid #eee;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
z-index: 10;
|
||||
margin: 0 -4px;
|
||||
|
||||
.el-button {
|
||||
flex: 1;
|
||||
height: 40px;
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
.mobile-item-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
.mobile-item-card {
|
||||
background: #f9f9fb;
|
||||
border-radius: 8px;
|
||||
padding: 12px;
|
||||
border: 1px solid #ebeef5;
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 10px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
&__index {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
font-weight: 600;
|
||||
}
|
||||
&__name {
|
||||
flex: 1;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
&__body {
|
||||
font-size: 13px;
|
||||
}
|
||||
&__info-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 4px 0;
|
||||
}
|
||||
&__info-label {
|
||||
color: #909399;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
&__info-value {
|
||||
color: #606266;
|
||||
text-align: right;
|
||||
}
|
||||
&__input-group {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-top: 6px;
|
||||
:deep(.el-form-item) {
|
||||
flex: 1;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.mobile-empty-tip {
|
||||
text-align: center;
|
||||
color: #909399;
|
||||
padding: 20px 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,138 +1,134 @@
|
||||
<template>
|
||||
<ContentWrap>
|
||||
<!-- 搜索工作栏 -->
|
||||
<el-form
|
||||
ref="queryFormRef"
|
||||
:model="queryParams"
|
||||
:inline="true"
|
||||
label-width="80px"
|
||||
class="-mb-15px"
|
||||
>
|
||||
<el-form-item label="产品名称" prop="productName">
|
||||
<el-input
|
||||
v-model="queryParams.productName"
|
||||
placeholder="请输入产品名称"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-200px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="BOM编码" prop="bomCode">
|
||||
<el-input
|
||||
v-model="queryParams.bomCode"
|
||||
placeholder="请输入BOM编码"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-200px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="BOM名称" prop="bomName">
|
||||
<div class="mobile-bom-list">
|
||||
<!-- 顶部操作栏 -->
|
||||
<div class="mobile-header">
|
||||
<div class="mobile-header__search">
|
||||
<el-input
|
||||
v-model="queryParams.bomName"
|
||||
placeholder="请输入BOM名称"
|
||||
placeholder="搜索BOM名称"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-200px"
|
||||
:prefix-icon="Search"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select
|
||||
v-model="queryParams.status"
|
||||
placeholder="请选择状态"
|
||||
clearable
|
||||
class="!w-200px"
|
||||
>
|
||||
<el-option label="启用" :value="1" />
|
||||
<el-option label="禁用" :value="0" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleQuery">
|
||||
<Icon icon="ep:search" class="mr-5px" /> 搜索
|
||||
</el-button>
|
||||
<el-button @click="resetQuery">
|
||||
<Icon icon="ep:refresh" class="mr-5px" /> 重置
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="mobile-header__actions">
|
||||
<el-button :icon="Filter" circle @click="filterVisible = true" />
|
||||
<el-button type="primary" :icon="Plus" circle @click="openForm('create')" v-hasPermi="['mes:product-bom:create']" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-button type="primary"
|
||||
@click="openForm('create')"
|
||||
v-hasPermi="['mes:product-bom:create']"
|
||||
>
|
||||
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ContentWrap>
|
||||
<div class="mobile-header__quick-filter">
|
||||
<div
|
||||
class="quick-filter-item"
|
||||
:class="{ active: queryParams.status === undefined }"
|
||||
@click="handleQuickFilter(undefined)"
|
||||
>
|
||||
全部
|
||||
</div>
|
||||
<div
|
||||
class="quick-filter-item"
|
||||
:class="{ active: queryParams.status === 1 }"
|
||||
@click="handleQuickFilter(1)"
|
||||
>
|
||||
启用
|
||||
</div>
|
||||
<div
|
||||
class="quick-filter-item"
|
||||
:class="{ active: queryParams.status === 0 }"
|
||||
@click="handleQuickFilter(0)"
|
||||
>
|
||||
禁用
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ContentWrap>
|
||||
|
||||
<!-- 列表 -->
|
||||
<el-table v-loading="loading" :data="list">
|
||||
<el-table-column label="BOM编码" align="center" prop="bomCode" width="180" />
|
||||
<el-table-column label="BOM名称" align="center" prop="bomName" min-width="150" />
|
||||
<el-table-column label="产品编码" align="center" prop="productCode" width="120" />
|
||||
<el-table-column label="产品名称" align="center" prop="productName" min-width="150" />
|
||||
<el-table-column label="版本" align="center" prop="version" width="80" />
|
||||
<el-table-column label="默认版本" align="center" prop="isDefault" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.isDefault === 1 ? 'success' : 'info'">
|
||||
{{ row.isDefault === 1 ? '是' : '否' }}
|
||||
<!-- 卡片列表 -->
|
||||
<div class="mobile-list" v-loading="loading">
|
||||
<div v-if="list.length === 0 && !loading" class="mobile-empty">
|
||||
<el-empty description="暂无BOM记录" />
|
||||
</div>
|
||||
<div
|
||||
v-for="item in list"
|
||||
:key="item.id"
|
||||
class="mobile-card"
|
||||
@click="openForm('view', item.id)"
|
||||
>
|
||||
<div class="mobile-card__header">
|
||||
<span class="mobile-card__no">{{ item.bomName }}</span>
|
||||
<el-tag :type="item.status === 1 ? 'success' : 'danger'" size="small">
|
||||
{{ item.status === 1 ? '启用' : '禁用' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" align="center" prop="status" width="80">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.status === 1 ? 'success' : 'danger'">
|
||||
{{ row.status === 1 ? '启用' : '禁用' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180" />
|
||||
<el-table-column label="操作" align="center" fixed="right" width="200">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="openForm('view', scope.row.id)"
|
||||
v-hasPermi="['mes:product-bom:query']"
|
||||
>
|
||||
查看
|
||||
</el-button>
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="openForm('update', scope.row.id)"
|
||||
v-hasPermi="['mes:product-bom:update']"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row.id)"
|
||||
v-hasPermi="['mes:product-bom:delete']"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="mobile-card__body">
|
||||
<div class="mobile-card__row">
|
||||
<span class="mobile-card__label">BOM编码</span>
|
||||
<span class="mobile-card__value">{{ item.bomCode || '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-card__row">
|
||||
<span class="mobile-card__label">产品名称</span>
|
||||
<span class="mobile-card__value">{{ item.productName || '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-card__row">
|
||||
<span class="mobile-card__label">产品编码</span>
|
||||
<span class="mobile-card__value">{{ item.productCode || '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-card__row">
|
||||
<span class="mobile-card__label">版本</span>
|
||||
<span class="mobile-card__value">
|
||||
{{ item.version || '-' }}
|
||||
<el-tag v-if="item.isDefault === 1" type="success" size="small" style="margin-left: 4px">默认</el-tag>
|
||||
</span>
|
||||
</div>
|
||||
<div class="mobile-card__row">
|
||||
<span class="mobile-card__label">创建时间</span>
|
||||
<span class="mobile-card__value">{{ item.createTime || '-' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mobile-card__footer">
|
||||
<el-button size="small" @click.stop="openForm('view', item.id)" v-hasPermi="['mes:product-bom:query']">查看</el-button>
|
||||
<el-button size="small" type="primary" @click.stop="openForm('update', item.id)" v-hasPermi="['mes:product-bom:update']">编辑</el-button>
|
||||
<el-button size="small" type="danger" @click.stop="handleDelete(item.id)" v-hasPermi="['mes:product-bom:delete']">删除</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<Pagination
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNo"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</ContentWrap>
|
||||
<div class="mobile-pagination" v-if="total > 0">
|
||||
<Pagination :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize" :page-sizes="[10, 20]" layout="total, prev, pager, next" :pager-count="5" @pagination="getList" />
|
||||
</div>
|
||||
|
||||
<!-- 表单弹窗:添加/修改 -->
|
||||
<ProductBomForm ref="formRef" @success="getList" />
|
||||
<!-- 筛选抽屉 -->
|
||||
<el-drawer v-model="filterVisible" title="筛选条件" direction="btt" size="50%">
|
||||
<el-form :model="queryParams" ref="queryFormRef" label-position="top">
|
||||
<el-form-item label="产品名称" prop="productName">
|
||||
<el-input v-model="queryParams.productName" placeholder="请输入产品名称" clearable style="width:100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="BOM编码" prop="bomCode">
|
||||
<el-input v-model="queryParams.bomCode" placeholder="请输入BOM编码" clearable style="width:100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="BOM名称" prop="bomName">
|
||||
<el-input v-model="queryParams.bomName" placeholder="请输入BOM名称" clearable style="width:100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable style="width:100%">
|
||||
<el-option label="启用" :value="1" />
|
||||
<el-option label="禁用" :value="0" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="resetQuery">重置</el-button>
|
||||
<el-button type="primary" @click="handleFilterConfirm">确认筛选</el-button>
|
||||
</template>
|
||||
</el-drawer>
|
||||
|
||||
<!-- 表单弹窗:添加/修改 -->
|
||||
<ProductBomForm ref="formRef" @success="getList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { Search, Filter, Plus } from '@element-plus/icons-vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { Icon } from '@/components/Icon'
|
||||
import ProductBomForm from './ProductBomForm.vue'
|
||||
@@ -140,6 +136,8 @@ import { getProductBomPage, deleteProductBom } from '@/api/mes/product/bom'
|
||||
|
||||
defineOptions({ name: 'MesProductBom' })
|
||||
|
||||
const filterVisible = ref(false)
|
||||
|
||||
const loading = ref(true)
|
||||
const total = ref(0)
|
||||
const list = ref<any[]>([])
|
||||
@@ -194,4 +192,90 @@ const handleDelete = async (id: number) => {
|
||||
onMounted(() => {
|
||||
getList()
|
||||
})
|
||||
|
||||
/** 快捷分类筛选 */
|
||||
const handleQuickFilter = (status: number | undefined) => {
|
||||
queryParams.status = status
|
||||
queryParams.pageNo = 1
|
||||
getList()
|
||||
}
|
||||
|
||||
/** 筛选确认 */
|
||||
const handleFilterConfirm = () => {
|
||||
filterVisible.value = false
|
||||
handleQuery()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.mobile-bom-list {
|
||||
padding: 12px;
|
||||
background: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
.mobile-header {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
&__search { flex: 1; }
|
||||
&__actions { display: flex; gap: 4px; flex-shrink: 0; }
|
||||
}
|
||||
.mobile-header__quick-filter {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
margin: 8px 0;
|
||||
justify-content: flex-start;
|
||||
|
||||
.quick-filter-item {
|
||||
padding: 4px 12px;
|
||||
font-size: 14px;
|
||||
border-radius: 20px;
|
||||
cursor: pointer;
|
||||
color: #909399;
|
||||
background: transparent;
|
||||
transition: all 0.2s;
|
||||
|
||||
&.active {
|
||||
color: #fff;
|
||||
background: #409eff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.mobile-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
.mobile-empty { padding: 40px 0; }
|
||||
.mobile-card {
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
padding: 14px;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
|
||||
&__header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
&__no { font-weight: 600; font-size: 15px; color: #303133; }
|
||||
&__body { font-size: 13px; }
|
||||
&__row { display: flex; justify-content: space-between; padding: 3px 0; }
|
||||
&__label { color: #909399; flex-shrink: 0; margin-right: 12px; }
|
||||
&__value {
|
||||
color: #606266;
|
||||
text-align: right;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
&__footer { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; padding-top: 10px; border-top: 1px solid #f0f0f0; }
|
||||
}
|
||||
.mobile-pagination {
|
||||
margin-top: 12px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
:deep(.el-pagination) { flex-wrap: wrap; justify-content: center; }
|
||||
}
|
||||
</style>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,146 +1,243 @@
|
||||
<template>
|
||||
<Dialog title="查看领料单" v-model="dialogVisible" width="80%">
|
||||
<Descriptions :schema="schema" :data="detailData" />
|
||||
<el-drawer
|
||||
v-model="dialogVisible"
|
||||
title="查看领料单"
|
||||
direction="rtl"
|
||||
size="100%"
|
||||
:close-on-press-escape="true"
|
||||
:destroy-on-close="true"
|
||||
:append-to-body="true"
|
||||
class="mobile-form-drawer"
|
||||
>
|
||||
<div class="mobile-form">
|
||||
<!-- 基本信息 -->
|
||||
<div class="mobile-form__section">
|
||||
<div class="mobile-form__section-title">基本信息</div>
|
||||
<div class="mobile-info-list">
|
||||
<div class="mobile-info-row" v-for="item in schema" :key="item.field">
|
||||
<span class="mobile-info-row__label">{{ item.label }}</span>
|
||||
<span class="mobile-info-row__value">
|
||||
{{ item.formatter ? item.formatter(detailData[item.field]) : (detailData[item.field] || '-') }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-divider content-position="left">领料明细</el-divider>
|
||||
<el-table :data="detailData.items" border style="width: 100%" max-height="480">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column label="物料信息" min-width="240">
|
||||
<template #default="{ row }">
|
||||
<div class="text-13px text-gray-600">编码:{{ row.materialCode }}</div>
|
||||
<div class="text-13px">名称:{{ row.materialName }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="单位" prop="unit" width="80" />
|
||||
<el-table-column label="计划数量" prop="planQuantity" width="120" />
|
||||
<el-table-column label="实际数量" prop="actualQuantity" width="120" />
|
||||
<el-table-column label="仓库" prop="warehouseName" width="140" />
|
||||
<el-table-column label="过磅单号" prop="no" width="160" />
|
||||
<el-table-column label="备注" prop="remark" min-width="160" />
|
||||
<el-table-column label="操作" width="100" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-tooltip content="过磅详情" placement="top" v-if="row.purchaseId">
|
||||
<el-button link type="primary" @click="openWeighDetail(row.purchaseId)">
|
||||
<Icon icon="ep:document" />
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 领料明细 -->
|
||||
<div class="mobile-form__section">
|
||||
<div class="mobile-form__section-title">领料明细</div>
|
||||
<div class="mobile-item-list">
|
||||
<div
|
||||
v-for="(row, index) in detailData.items"
|
||||
:key="index"
|
||||
class="mobile-item-card"
|
||||
>
|
||||
<div class="mobile-item-card__header">
|
||||
<span class="mobile-item-card__index">#{{ index + 1 }}</span>
|
||||
<span class="mobile-item-card__name">{{ row.materialName || '未知物料' }}</span>
|
||||
</div>
|
||||
<div class="mobile-item-card__body">
|
||||
<div class="mobile-item-card__info-row">
|
||||
<span class="mobile-item-card__info-label">物料编码</span>
|
||||
<span class="mobile-item-card__info-value">{{ row.materialCode || '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-item-card__info-row">
|
||||
<span class="mobile-item-card__info-label">单位</span>
|
||||
<span class="mobile-item-card__info-value">{{ row.unit || '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-item-card__info-row">
|
||||
<span class="mobile-item-card__info-label">计划数量</span>
|
||||
<span class="mobile-item-card__info-value">{{ row.planQuantity }}</span>
|
||||
</div>
|
||||
<div class="mobile-item-card__info-row">
|
||||
<span class="mobile-item-card__info-label">实际数量</span>
|
||||
<span class="mobile-item-card__info-value">{{ row.actualQuantity || '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-item-card__info-row">
|
||||
<span class="mobile-item-card__info-label">仓库</span>
|
||||
<span class="mobile-item-card__info-value">{{ row.warehouseName || '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-item-card__info-row">
|
||||
<span class="mobile-item-card__info-label">过磅单号</span>
|
||||
<span class="mobile-item-card__info-value">{{ row.no || '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-item-card__info-row" v-if="row.remark">
|
||||
<span class="mobile-item-card__info-label">备注</span>
|
||||
<span class="mobile-item-card__info-value">{{ row.remark }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mobile-item-card__footer" v-if="row.purchaseId">
|
||||
<el-button size="small" @click="openWeighDetail(row.purchaseId)">查看过磅详情</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="detailData.items.length === 0" class="mobile-empty-tip">
|
||||
暂无领料明细
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<el-button @click="dialogVisible = false">关闭</el-button>
|
||||
</template>
|
||||
</Dialog>
|
||||
<!-- 底部操作按钮 -->
|
||||
<div class="mobile-form__footer">
|
||||
<el-button @click="dialogVisible = false">关 闭</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
|
||||
<!-- 过磅单详情弹窗 -->
|
||||
<Dialog title="过磅单详情" v-model="weighDialogVisible" width="50%">
|
||||
<el-descriptions :column="2" border>
|
||||
<el-descriptions-item label="过磅单号">{{ weighDetail?.no || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="入库状态">{{
|
||||
weighDetail?.inStatus === 1 ? '已入库' : '未入库'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="产品">{{
|
||||
weighDetail?.productName || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="车牌">{{
|
||||
weighDetail?.vehicleNumber || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="毛重">{{
|
||||
weighDetail?.grossWeight != null ? weighDetail.grossWeight + ' kg' : '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="皮重">{{
|
||||
weighDetail?.tareWeight != null ? weighDetail.tareWeight + ' kg' : '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="净重">{{
|
||||
weighDetail?.netWeight != null ? weighDetail.netWeight + ' kg' : '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="计划重量">{{
|
||||
weighDetail?.plannedWeight != null ? weighDetail.plannedWeight + ' kg' : '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="杂质率">{{
|
||||
weighDetail?.impurityRate != null ? (weighDetail.impurityRate * 100).toFixed(2) + '%' : '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="供应商">{{
|
||||
weighDetail?.supplierName || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="供应商类型">{{
|
||||
weighDetail?.supplierName2 || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="身份证号">{{
|
||||
weighDetail?.idCardNumber || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="司机">{{ weighDetail?.driver || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="管理员">{{
|
||||
weighDetail?.administrator || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="过磅员">{{ weighDetail?.weigher || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="产地证编号">{{
|
||||
weighDetail?.originCertificateNumber || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="附件">
|
||||
<template v-if="weighDetail?.fileUrl">
|
||||
<a :href="weighDetail.fileUrl" target="_blank">查看附件</a>
|
||||
</template>
|
||||
<template v-else>-</template>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="备注" :span="2">{{
|
||||
weighDetail?.remark || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="创建时间" :span="2">{{
|
||||
weighDetail?.createTime ? formatDate(weighDetail.createTime) : '-'
|
||||
}}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-drawer
|
||||
v-model="weighDialogVisible"
|
||||
title="过磅单详情"
|
||||
direction="rtl"
|
||||
size="100%"
|
||||
:close-on-press-escape="true"
|
||||
:destroy-on-close="true"
|
||||
:append-to-body="true"
|
||||
class="mobile-form-drawer"
|
||||
>
|
||||
<div class="mobile-form">
|
||||
<!-- 基本信息 -->
|
||||
<div class="mobile-form__section">
|
||||
<div class="mobile-form__section-title">基本信息</div>
|
||||
<div class="mobile-info-list">
|
||||
<div class="mobile-info-row">
|
||||
<span class="mobile-info-row__label">过磅单号</span>
|
||||
<span class="mobile-info-row__value">{{ weighDetail?.no || '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-info-row">
|
||||
<span class="mobile-info-row__label">入库状态</span>
|
||||
<span class="mobile-info-row__value">
|
||||
<el-tag :type="weighDetail?.inStatus === 1 ? 'success' : 'warning'" size="small">
|
||||
{{ weighDetail?.inStatus === 1 ? '已入库' : '未入库' }}
|
||||
</el-tag>
|
||||
</span>
|
||||
</div>
|
||||
<div class="mobile-info-row">
|
||||
<span class="mobile-info-row__label">产品</span>
|
||||
<span class="mobile-info-row__value">{{ weighDetail?.productName || '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-info-row">
|
||||
<span class="mobile-info-row__label">车牌</span>
|
||||
<span class="mobile-info-row__value">{{ weighDetail?.vehicleNumber || '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-info-row">
|
||||
<span class="mobile-info-row__label">毛重</span>
|
||||
<span class="mobile-info-row__value">{{ weighDetail?.grossWeight != null ? weighDetail.grossWeight + ' kg' : '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-info-row">
|
||||
<span class="mobile-info-row__label">皮重</span>
|
||||
<span class="mobile-info-row__value">{{ weighDetail?.tareWeight != null ? weighDetail.tareWeight + ' kg' : '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-info-row">
|
||||
<span class="mobile-info-row__label">净重</span>
|
||||
<span class="mobile-info-row__value">{{ weighDetail?.netWeight != null ? weighDetail.netWeight + ' kg' : '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-info-row">
|
||||
<span class="mobile-info-row__label">计划重量</span>
|
||||
<span class="mobile-info-row__value">{{ weighDetail?.plannedWeight != null ? weighDetail.plannedWeight + ' kg' : '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-info-row">
|
||||
<span class="mobile-info-row__label">杂质率</span>
|
||||
<span class="mobile-info-row__value">{{ weighDetail?.impurityRate != null ? (weighDetail.impurityRate * 100).toFixed(2) + '%' : '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-info-row">
|
||||
<span class="mobile-info-row__label">供应商</span>
|
||||
<span class="mobile-info-row__value">{{ weighDetail?.supplierName || '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-info-row">
|
||||
<span class="mobile-info-row__label">司机</span>
|
||||
<span class="mobile-info-row__value">{{ weighDetail?.driver || '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-info-row">
|
||||
<span class="mobile-info-row__label">管理员</span>
|
||||
<span class="mobile-info-row__value">{{ weighDetail?.administrator || '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-info-row">
|
||||
<span class="mobile-info-row__label">过磅员</span>
|
||||
<span class="mobile-info-row__value">{{ weighDetail?.weigher || '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-info-row" v-if="weighDetail?.fileUrl">
|
||||
<span class="mobile-info-row__label">附件</span>
|
||||
<span class="mobile-info-row__value"><a :href="weighDetail.fileUrl" target="_blank">查看附件</a></span>
|
||||
</div>
|
||||
<div class="mobile-info-row" v-if="weighDetail?.remark">
|
||||
<span class="mobile-info-row__label">备注</span>
|
||||
<span class="mobile-info-row__value">{{ weighDetail.remark }}</span>
|
||||
</div>
|
||||
<div class="mobile-info-row">
|
||||
<span class="mobile-info-row__label">创建时间</span>
|
||||
<span class="mobile-info-row__value">{{ weighDetail?.createTime ? formatDate(weighDetail.createTime) : '-' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 检验信息部分 - 仅当有检验数据时显示 -->
|
||||
<template v-if="hasInspectionData">
|
||||
<el-divider content-position="left">检验信息</el-divider>
|
||||
<el-descriptions :column="2" border>
|
||||
<el-descriptions-item label="取样日期">{{
|
||||
weighDetail?.sampleDate ? formatDate(weighDetail.sampleDate) : '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="取样地点">{{
|
||||
weighDetail?.sampleLocation || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="代表重量">{{
|
||||
weighDetail?.representativeWeight != null ? weighDetail.representativeWeight + ' kg' : '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="样品重量">{{
|
||||
weighDetail?.sampleWeight != null ? weighDetail.sampleWeight + ' kg' : '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="杂质重量">{{
|
||||
weighDetail?.impurityWeight != null ? weighDetail.impurityWeight + ' kg' : '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="沙土重量">{{
|
||||
weighDetail?.sandWeight != null ? weighDetail.sandWeight + ' kg' : '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="感官">{{
|
||||
weighDetail?.sensoryEvaluation || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="合格率">{{
|
||||
weighDetail?.qualificationRate ? weighDetail.qualificationRate + '%' : '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="水分">{{
|
||||
weighDetail?.moistureContent ? weighDetail.moistureContent + '%' : '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="含糖">{{
|
||||
weighDetail?.sugarContent ? weighDetail.sugarContent + '%' : '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="RA值">{{
|
||||
weighDetail?.raValue || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="STV值">{{
|
||||
weighDetail?.stvValue || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="化验员">{{
|
||||
weighDetail?.labTechnician || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="检验备注" :span="2">{{
|
||||
weighDetail?.inspectionRemark || '-'
|
||||
}}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</template>
|
||||
</Dialog>
|
||||
<!-- 检验信息部分 - 仅当有检验数据时显示 -->
|
||||
<div class="mobile-form__section" v-if="hasInspectionData">
|
||||
<div class="mobile-form__section-title">检验信息</div>
|
||||
<div class="mobile-info-list">
|
||||
<div class="mobile-info-row">
|
||||
<span class="mobile-info-row__label">取样日期</span>
|
||||
<span class="mobile-info-row__value">{{ weighDetail?.sampleDate ? formatDate(weighDetail.sampleDate) : '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-info-row">
|
||||
<span class="mobile-info-row__label">取样地点</span>
|
||||
<span class="mobile-info-row__value">{{ weighDetail?.sampleLocation || '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-info-row">
|
||||
<span class="mobile-info-row__label">代表重量</span>
|
||||
<span class="mobile-info-row__value">{{ weighDetail?.representativeWeight != null ? weighDetail.representativeWeight + ' kg' : '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-info-row">
|
||||
<span class="mobile-info-row__label">样品重量</span>
|
||||
<span class="mobile-info-row__value">{{ weighDetail?.sampleWeight != null ? weighDetail.sampleWeight + ' kg' : '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-info-row">
|
||||
<span class="mobile-info-row__label">杂质重量</span>
|
||||
<span class="mobile-info-row__value">{{ weighDetail?.impurityWeight != null ? weighDetail.impurityWeight + ' kg' : '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-info-row">
|
||||
<span class="mobile-info-row__label">沙土重量</span>
|
||||
<span class="mobile-info-row__value">{{ weighDetail?.sandWeight != null ? weighDetail.sandWeight + ' kg' : '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-info-row">
|
||||
<span class="mobile-info-row__label">感官</span>
|
||||
<span class="mobile-info-row__value">{{ weighDetail?.sensoryEvaluation || '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-info-row">
|
||||
<span class="mobile-info-row__label">合格率</span>
|
||||
<span class="mobile-info-row__value">{{ weighDetail?.qualificationRate ? weighDetail.qualificationRate + '%' : '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-info-row">
|
||||
<span class="mobile-info-row__label">水分</span>
|
||||
<span class="mobile-info-row__value">{{ weighDetail?.moistureContent ? weighDetail.moistureContent + '%' : '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-info-row">
|
||||
<span class="mobile-info-row__label">含糖</span>
|
||||
<span class="mobile-info-row__value">{{ weighDetail?.sugarContent ? weighDetail.sugarContent + '%' : '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-info-row">
|
||||
<span class="mobile-info-row__label">RA值</span>
|
||||
<span class="mobile-info-row__value">{{ weighDetail?.raValue || '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-info-row">
|
||||
<span class="mobile-info-row__label">STV值</span>
|
||||
<span class="mobile-info-row__value">{{ weighDetail?.stvValue || '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-info-row">
|
||||
<span class="mobile-info-row__label">化验员</span>
|
||||
<span class="mobile-info-row__value">{{ weighDetail?.labTechnician || '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-info-row" v-if="weighDetail?.inspectionRemark">
|
||||
<span class="mobile-info-row__label">检验备注</span>
|
||||
<span class="mobile-info-row__value">{{ weighDetail.inspectionRemark }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mobile-form__footer">
|
||||
<el-button @click="weighDialogVisible = false" style="width: 100%">关 闭</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -246,3 +343,115 @@ defineExpose({
|
||||
open
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.mobile-form {
|
||||
padding: 0 4px;
|
||||
}
|
||||
.mobile-form__section {
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
padding: 14px;
|
||||
margin-bottom: 12px;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
.mobile-form__section-title {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
margin-bottom: 12px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
.mobile-form__footer {
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
background: #fff;
|
||||
padding: 12px 16px;
|
||||
padding-bottom: calc(12px + constant(safe-area-inset-bottom));
|
||||
padding-bottom: calc(12px + env(safe-area-inset-bottom));
|
||||
border-top: 1px solid #eee;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
z-index: 10;
|
||||
margin: 0 -4px;
|
||||
|
||||
.el-button {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
.mobile-info-list {
|
||||
font-size: 13px;
|
||||
}
|
||||
.mobile-info-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 6px 0;
|
||||
border-bottom: 1px solid #f5f5f5;
|
||||
&:last-child { border-bottom: none; }
|
||||
&__label { color: #909399; flex-shrink: 0; margin-right: 12px; }
|
||||
&__value { color: #303133; text-align: right; }
|
||||
}
|
||||
.mobile-item-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
.mobile-item-card {
|
||||
background: #f9f9fb;
|
||||
border-radius: 8px;
|
||||
padding: 12px;
|
||||
border: 1px solid #ebeef5;
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 10px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
&__index {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
font-weight: 600;
|
||||
}
|
||||
&__name {
|
||||
flex: 1;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
&__body {
|
||||
font-size: 13px;
|
||||
}
|
||||
&__info-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 4px 0;
|
||||
}
|
||||
&__info-label {
|
||||
color: #909399;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
&__info-value {
|
||||
color: #606266;
|
||||
text-align: right;
|
||||
}
|
||||
&__footer {
|
||||
margin-top: 10px;
|
||||
padding-top: 10px;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
}
|
||||
}
|
||||
.mobile-empty-tip {
|
||||
text-align: center;
|
||||
color: #909399;
|
||||
padding: 20px 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,21 +1,29 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="formType === 'create' ? '新增工单' : '编辑工单'"
|
||||
<el-drawer
|
||||
v-model="visible"
|
||||
:width="isMobile ? '100%' : '900px'"
|
||||
:fullscreen="isMobile"
|
||||
@close="handleClose"
|
||||
:close-on-click-modal="false"
|
||||
:title="formType === 'create' ? '新增工单' : '编辑工单'"
|
||||
direction="rtl"
|
||||
size="100%"
|
||||
:close-on-press-escape="true"
|
||||
:destroy-on-close="true"
|
||||
:append-to-body="true"
|
||||
class="mobile-form-drawer"
|
||||
>
|
||||
<el-form :model="form" :rules="rules" ref="formRef" :label-width="isMobile ? '80px' : '120px'" v-loading="formLoading">
|
||||
<el-tabs v-model="activeTab">
|
||||
<div class="mobile-form" v-loading="formLoading">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-position="top"
|
||||
>
|
||||
<!-- 基本信息 -->
|
||||
<el-tab-pane label="基本信息" name="basic">
|
||||
<div class="mobile-form__section">
|
||||
<div class="mobile-form__section-title">基本信息</div>
|
||||
<el-form-item label="产品" prop="productId">
|
||||
<el-select
|
||||
v-model="form.productId"
|
||||
placeholder="请选择产品"
|
||||
:class="isMobile ? '!w-full' : '!w-240px'"
|
||||
style="width: 100%"
|
||||
@change="handleProductChange"
|
||||
>
|
||||
<el-option
|
||||
@@ -42,7 +50,7 @@
|
||||
<el-select
|
||||
v-model="form.routeId"
|
||||
placeholder="请选择工序路线"
|
||||
:class="isMobile ? '!w-full' : '!w-240px'"
|
||||
style="width: 100%"
|
||||
@change="handleRouteChange"
|
||||
>
|
||||
<el-option
|
||||
@@ -63,7 +71,8 @@
|
||||
:precision="2"
|
||||
:step="0.1"
|
||||
placeholder="请输入计划数量"
|
||||
:class="isMobile ? '!w-full' : ''"
|
||||
controls-position="right"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="优先级" prop="priority">-->
|
||||
@@ -78,7 +87,7 @@
|
||||
<el-form-item label="计划时间" prop="planTime">
|
||||
<el-date-picker
|
||||
v-model="form.planTime"
|
||||
:type="isMobile ? 'datetimerange' : 'datetimerange'"
|
||||
type="datetimerange"
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
:default-time="[
|
||||
@@ -97,35 +106,52 @@
|
||||
)
|
||||
)
|
||||
]"
|
||||
:class="isMobile ? '!w-full' : '!w-380px'"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入备注" />
|
||||
<el-input v-model="form.remark" type="textarea" :rows="2" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
</el-tab-pane>
|
||||
</div>
|
||||
|
||||
<!-- 工序信息 -->
|
||||
<el-tab-pane label="工序信息" name="process">
|
||||
<el-table :data="form.operations" border>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column label="工序编码" prop="operationCode" min-width="120" align="center" />
|
||||
<el-table-column label="工序名称" prop="operationName" min-width="120" align="center" />
|
||||
<el-table-column
|
||||
label="工时(分钟)"
|
||||
prop="requiredTime"
|
||||
min-width="120"
|
||||
align="center"
|
||||
/>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="visible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="loading" @click="submitForm">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<div class="mobile-form__section">
|
||||
<div class="mobile-form__section-title">工序信息</div>
|
||||
<div class="mobile-item-list">
|
||||
<div
|
||||
v-for="(op, index) in form.operations"
|
||||
:key="index"
|
||||
class="mobile-item-card"
|
||||
>
|
||||
<div class="mobile-item-card__header">
|
||||
<span class="mobile-item-card__index">#{{ index + 1 }}</span>
|
||||
<span class="mobile-item-card__name">{{ op.operationName || '未知工序' }}</span>
|
||||
</div>
|
||||
<div class="mobile-item-card__body">
|
||||
<div class="mobile-item-card__info-row">
|
||||
<span class="mobile-item-card__info-label">工序编码</span>
|
||||
<span class="mobile-item-card__info-value">{{ op.operationCode || '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-item-card__info-row">
|
||||
<span class="mobile-item-card__info-label">工时(分钟)</span>
|
||||
<span class="mobile-item-card__info-value">{{ op.requiredTime || '-' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="form.operations.length === 0" class="mobile-empty-tip">
|
||||
请先选择工序路线
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-form>
|
||||
|
||||
<!-- 底部操作按钮 -->
|
||||
<div class="mobile-form__footer">
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
<el-button type="primary" :loading="loading" @click="submitForm">确 定</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -408,8 +434,98 @@ const handleClose = () => {
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.el-tabs :deep(.el-tabs__content) {
|
||||
<style lang="scss" scoped>
|
||||
.mobile-form {
|
||||
padding: 0 4px;
|
||||
}
|
||||
.mobile-form__section {
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
padding: 14px;
|
||||
margin-bottom: 12px;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
.mobile-form__section-title {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
margin-bottom: 12px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
.mobile-form__footer {
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
background: #fff;
|
||||
padding: 12px 16px;
|
||||
padding-bottom: calc(12px + constant(safe-area-inset-bottom));
|
||||
padding-bottom: calc(12px + env(safe-area-inset-bottom));
|
||||
border-top: 1px solid #eee;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
z-index: 10;
|
||||
margin: 0 -4px;
|
||||
|
||||
.el-button {
|
||||
flex: 1;
|
||||
height: 40px;
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
.mobile-item-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
.mobile-item-card {
|
||||
background: #f9f9fb;
|
||||
border-radius: 8px;
|
||||
padding: 12px;
|
||||
border: 1px solid #ebeef5;
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 10px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
&__index {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
font-weight: 600;
|
||||
}
|
||||
&__name {
|
||||
flex: 1;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
&__body {
|
||||
font-size: 13px;
|
||||
}
|
||||
&__info-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 4px 0;
|
||||
}
|
||||
&__info-label {
|
||||
color: #909399;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
&__info-value {
|
||||
color: #606266;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
.mobile-empty-tip {
|
||||
text-align: center;
|
||||
color: #909399;
|
||||
padding: 20px 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,128 +1,126 @@
|
||||
<template>
|
||||
<el-dialog title="工序执行情况" v-model="visible" width="1200px" v-loading="loading">
|
||||
<!-- 工序进度统计 -->
|
||||
<OperationProgressCard :progressData="progressData" />
|
||||
<el-drawer
|
||||
v-model="visible"
|
||||
title="工序执行情况"
|
||||
direction="rtl"
|
||||
size="100%"
|
||||
:close-on-press-escape="true"
|
||||
:destroy-on-close="true"
|
||||
:append-to-body="true"
|
||||
class="mobile-form-drawer"
|
||||
>
|
||||
<div class="mobile-form" v-loading="loading">
|
||||
<!-- 工序进度统计 -->
|
||||
<div class="mobile-form__section">
|
||||
<div class="mobile-form__section-title">工序进度</div>
|
||||
<OperationProgressCard :progressData="progressData" />
|
||||
</div>
|
||||
|
||||
<!-- 工序列表 -->
|
||||
<el-table :data="operationList" border stripe v-loading="tableLoading">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column label="工序信息" min-width="180">
|
||||
<template #default="{ row }">
|
||||
<div>{{ row.operationName }}</div>
|
||||
<div class="text-gray-400 text-sm">{{ row.operationCode }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="生产数量" min-width="180">
|
||||
<template #default="{ row }">
|
||||
<div>计划:{{ row.planQuantity }}</div>
|
||||
<div class="mt-1">完成:{{ row.completedQuantity }}</div>
|
||||
<div class="mt-1">
|
||||
<span class="text-success">合格:{{ row.qualifiedQuantity }}</span>
|
||||
<span class="text-danger ml-2">不合格:{{ row.unqualifiedQuantity }}</span>
|
||||
<!-- 工序列表 -->
|
||||
<div class="mobile-form__section">
|
||||
<div class="mobile-form__section-title">工序列表</div>
|
||||
<div class="mobile-item-list" v-loading="tableLoading">
|
||||
<div
|
||||
v-for="(row, index) in operationList"
|
||||
:key="row.id"
|
||||
class="mobile-item-card"
|
||||
>
|
||||
<div class="mobile-item-card__header">
|
||||
<span class="mobile-item-card__index">#{{ index + 1 }}</span>
|
||||
<span class="mobile-item-card__name">{{ row.operationName || '未知工序' }}</span>
|
||||
<el-tag :type="getStatusType(row.status)" size="small">{{ getStatusText(row.status) }}</el-tag>
|
||||
</div>
|
||||
<div class="mobile-item-card__body">
|
||||
<div class="mobile-item-card__info-row">
|
||||
<span class="mobile-item-card__info-label">工序编码</span>
|
||||
<span class="mobile-item-card__info-value">{{ row.operationCode || '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-item-card__info-row">
|
||||
<span class="mobile-item-card__info-label">计划数量</span>
|
||||
<span class="mobile-item-card__info-value">{{ row.planQuantity }}</span>
|
||||
</div>
|
||||
<div class="mobile-item-card__info-row">
|
||||
<span class="mobile-item-card__info-label">完成数量</span>
|
||||
<span class="mobile-item-card__info-value">{{ row.completedQuantity }}</span>
|
||||
</div>
|
||||
<div class="mobile-item-card__info-row">
|
||||
<span class="mobile-item-card__info-label">合格/不合格</span>
|
||||
<span class="mobile-item-card__info-value">
|
||||
<span style="color: #67c23a">{{ row.qualifiedQuantity }}</span>
|
||||
<span style="color: #909399"> / </span>
|
||||
<span style="color: #f56c6c">{{ row.unqualifiedQuantity }}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="mobile-item-card__info-row">
|
||||
<span class="mobile-item-card__info-label">操作人</span>
|
||||
<span class="mobile-item-card__info-value">{{ getOperationExecution(row.id)?.workerName || '-' }}</span>
|
||||
</div>
|
||||
<div class="mobile-item-card__info-row">
|
||||
<span class="mobile-item-card__info-label">开始时间</span>
|
||||
<span class="mobile-item-card__info-value">{{ getOperationExecution(row.id)?.startTime || '未开始' }}</span>
|
||||
</div>
|
||||
<div class="mobile-item-card__info-row">
|
||||
<span class="mobile-item-card__info-label">结束时间</span>
|
||||
<span class="mobile-item-card__info-value">{{ getOperationExecution(row.id)?.endTime || '未结束' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mobile-item-card__footer">
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
@click="handleStart(row)"
|
||||
v-if="row.status === 0 && [2, 3].includes(workOrderStatus)"
|
||||
v-hasPermi="['mes:production-order:operations']"
|
||||
>开始</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
type="success"
|
||||
@click="handleComplete(row)"
|
||||
v-if="row.status === 1"
|
||||
v-hasPermi="['mes:production-order:operations']"
|
||||
>完成</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
type="warning"
|
||||
@click="handlePause(row)"
|
||||
v-if="row.status === 1"
|
||||
v-hasPermi="['mes:production-order:operations']"
|
||||
>暂停</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
@click="handleResume(row)"
|
||||
v-if="row.status === 3"
|
||||
v-hasPermi="['mes:production-order:operations']"
|
||||
>恢复</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
@click="handleViewDetail(row)"
|
||||
v-if="row.status === 2"
|
||||
v-hasPermi="['mes:production-order:operations']"
|
||||
>详情</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
@click="handleRecordProgress(row)"
|
||||
v-if="row.status === 1"
|
||||
v-hasPermi="['mes:production-order:operations']"
|
||||
>记录进度</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
@click="handleViewProgressHistory(row)"
|
||||
v-if="row.status === 1 || row.status === 2"
|
||||
v-hasPermi="['mes:production-order:operations']"
|
||||
>查看记录</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作人" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<div>{{ getOperationExecution(row.id)?.workerName || '-' }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="实际时间" min-width="180">
|
||||
<template #default="{ row }">
|
||||
<div>开始:{{ getOperationExecution(row.id)?.startTime || '未开始' }}</div>
|
||||
<div class="mt-1">结束:{{ getOperationExecution(row.id)?.endTime || '未结束' }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="getStatusType(row.status)">{{ getStatusText(row.status) }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="200" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tooltip
|
||||
content="开始"
|
||||
placement="top"
|
||||
v-if="row.status === 0 && [2, 3].includes(workOrderStatus)"
|
||||
>
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="handleStart(row)"
|
||||
v-hasPermi="['mes:production-order:operations']"
|
||||
>
|
||||
<Icon icon="ep:video-play" />
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="完成" placement="top" v-if="row.status === 1">
|
||||
<el-button
|
||||
link
|
||||
type="success"
|
||||
@click="handleComplete(row)"
|
||||
v-hasPermi="['mes:production-order:operations']"
|
||||
>
|
||||
<Icon icon="ep:check" />
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="暂停" placement="top" v-if="row.status === 1">
|
||||
<el-button
|
||||
link
|
||||
type="warning"
|
||||
@click="handlePause(row)"
|
||||
v-hasPermi="['mes:production-order:operations']"
|
||||
>
|
||||
<Icon icon="ep:video-pause" />
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="恢复" placement="top" v-if="row.status === 3">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="handleResume(row)"
|
||||
v-hasPermi="['mes:production-order:operations']"
|
||||
>
|
||||
<Icon icon="ep:video-play" />
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<!-- 查看详情按钮 - 修改显示条件 -->
|
||||
<el-tooltip content="查看详情" placement="top" v-if="row.status === 2">
|
||||
<el-button
|
||||
link
|
||||
type="info"
|
||||
@click="handleViewDetail(row)"
|
||||
v-hasPermi="['mes:production-order:operations']"
|
||||
>
|
||||
<Icon icon="ep:document-copy" />
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="记录进度" placement="top" v-if="row.status === 1">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="handleRecordProgress(row)"
|
||||
v-hasPermi="['mes:production-order:operations']"
|
||||
>
|
||||
<Icon icon="ep:edit" />
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip
|
||||
content="查看记录"
|
||||
placement="top"
|
||||
v-if="row.status === 1 || row.status === 2"
|
||||
>
|
||||
<el-button
|
||||
link
|
||||
type="info"
|
||||
@click="handleViewProgressHistory(row)"
|
||||
v-hasPermi="['mes:production-order:operations']"
|
||||
>
|
||||
<Icon icon="ep:list" />
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
<div v-if="operationList.length === 0 && !tableLoading" class="mobile-empty-tip">
|
||||
暂无工序数据
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
|
||||
<!-- 开始工序弹窗 -->
|
||||
<OperationStartDialog
|
||||
@@ -135,7 +133,7 @@
|
||||
/>
|
||||
|
||||
<!-- 完成工序弹窗 -->
|
||||
<el-dialog v-model="completeDialogVisible" title="完成工序" width="600px" append-to-body>
|
||||
<el-dialog v-model="completeDialogVisible" title="完成工序" width="400px" append-to-body>
|
||||
<el-form ref="completeFormRef" :model="completeForm" :rules="completeRules" label-width="120px">
|
||||
<!-- 动态工序字段 -->
|
||||
<template v-if="Object.keys(processFields).length > 0">
|
||||
@@ -1097,7 +1095,88 @@ onMounted(() => {
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style lang="scss" scoped>
|
||||
.mobile-form {
|
||||
padding: 0 4px;
|
||||
}
|
||||
.mobile-form__section {
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
padding: 14px;
|
||||
margin-bottom: 12px;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
.mobile-form__section-title {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
margin-bottom: 12px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
.mobile-item-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
.mobile-item-card {
|
||||
background: #f9f9fb;
|
||||
border-radius: 8px;
|
||||
padding: 12px;
|
||||
border: 1px solid #ebeef5;
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 10px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
&__index {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
font-weight: 600;
|
||||
}
|
||||
&__name {
|
||||
flex: 1;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
&__body {
|
||||
font-size: 13px;
|
||||
}
|
||||
&__info-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 4px 0;
|
||||
}
|
||||
&__info-label {
|
||||
color: #909399;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
&__info-value {
|
||||
color: #606266;
|
||||
text-align: right;
|
||||
}
|
||||
&__footer {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
margin-top: 10px;
|
||||
padding-top: 10px;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
}
|
||||
}
|
||||
.mobile-empty-tip {
|
||||
text-align: center;
|
||||
color: #909399;
|
||||
padding: 20px 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
.text-lg {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user