|
@@ -85,6 +85,10 @@
|
|
width="60"
|
|
width="60"
|
|
align="center"
|
|
align="center"
|
|
/>
|
|
/>
|
|
|
|
+ <el-table-column label="工厂id" align="center" prop="factoryId" v-if="false"/>
|
|
|
|
+ <el-table-column label="成本中心id" align="center" prop="costCenterId" v-if="false"/>
|
|
|
|
+ <el-table-column label="工厂" align="center" prop="factory" v-if="true"/>
|
|
|
|
+ <el-table-column label="成本中心" align="center" prop="costCenter" v-if="true"/>
|
|
<el-table-column label="物料编码" align="center" prop="materialCode" />
|
|
<el-table-column label="物料编码" align="center" prop="materialCode" />
|
|
<el-table-column label="物料名称" align="center" prop="materialName" />
|
|
<el-table-column label="物料名称" align="center" prop="materialName" />
|
|
<el-table-column label="单价" align="center" prop="unitPrice" :formatter="erpPriceTableColumnFormatter"/>
|
|
<el-table-column label="单价" align="center" prop="unitPrice" :formatter="erpPriceTableColumnFormatter"/>
|
|
@@ -100,7 +104,7 @@
|
|
style="vertical-align: middle"
|
|
style="vertical-align: middle"
|
|
link
|
|
link
|
|
type="danger"
|
|
type="danger"
|
|
- @click="handleDelete(scope.row.deviceId+'-'+scope.row.bomNodeId)"
|
|
|
|
|
|
+ @click="handleDelete(scope.row.materialCode)"
|
|
>
|
|
>
|
|
移除
|
|
移除
|
|
</el-button>
|
|
</el-button>
|
|
@@ -120,39 +124,19 @@
|
|
</el-form-item>
|
|
</el-form-item>
|
|
</el-form>
|
|
</el-form>
|
|
</ContentWrap>
|
|
</ContentWrap>
|
|
- <MainPlanDeviceList ref="deviceFormRef" @choose="deviceChoose" />
|
|
|
|
<SelectLocalStock ref="localStockFormRef" @choose="stockChoose" />
|
|
<SelectLocalStock ref="localStockFormRef" @choose="stockChoose" />
|
|
- <!-- 表单弹窗:添加/修改 -->
|
|
|
|
- <WorkOrderMaterial ref="materialFormRef" @choose="selectChoose" />
|
|
|
|
- <!-- 抽屉组件 展示已经选择的物料 并编辑物料消耗 -->
|
|
|
|
- <MaterialListDrawer
|
|
|
|
- :model-value="drawerVisible"
|
|
|
|
- @update:model-value="val => drawerVisible = val"
|
|
|
|
- :node-id="currentBomNodeId"
|
|
|
|
- :materials="materialList.filter(item => item.bomNodeId === currentBomNodeId)"
|
|
|
|
- />
|
|
|
|
</template>
|
|
</template>
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
-import { IotDeviceApi, IotDeviceVO } from '@/api/pms/device'
|
|
|
|
import * as UserApi from '@/api/system/user'
|
|
import * as UserApi from '@/api/system/user'
|
|
import { useUserStore } from '@/store/modules/user'
|
|
import { useUserStore } from '@/store/modules/user'
|
|
import { ref } from 'vue'
|
|
import { ref } from 'vue'
|
|
-import type { ComponentPublicInstance } from 'vue'
|
|
|
|
-import { IotMaintenanceBomApi, IotMaintenanceBomVO } from '@/api/pms/iotmaintenancebom'
|
|
|
|
-import { IotMainWorkOrderBomApi, IotMainWorkOrderBomVO } from '@/api/pms/iotmainworkorderbom'
|
|
|
|
-import { IotMainWorkOrderBomMaterialApi, IotMainWorkOrderBomMaterialVO } from '@/api/pms/iotmainworkorderbommaterial'
|
|
|
|
-import { IotMainWorkOrderApi, IotMainWorkOrderVO } from '@/api/pms/iotmainworkorder'
|
|
|
|
|
|
+import { IotMaterialRequisitionApi, IotMaterialRequisitionVO } from '@/api/pms/iotmaterialrequisition'
|
|
import { IotMaterialRequisitionDetailApi, IotMaterialRequisitionDetailVO } from '@/api/pms/iotmaterialrequisitiondetail'
|
|
import { IotMaterialRequisitionDetailApi, IotMaterialRequisitionDetailVO } from '@/api/pms/iotmaterialrequisitiondetail'
|
|
import { useTagsViewStore } from '@/store/modules/tagsView'
|
|
import { useTagsViewStore } from '@/store/modules/tagsView'
|
|
import {CACHE_KEY, useCache} from "@/hooks/web/useCache";
|
|
import {CACHE_KEY, useCache} from "@/hooks/web/useCache";
|
|
-import MainPlanDeviceList from "@/views/pms/maintenance/MainPlanDeviceList.vue";
|
|
|
|
|
|
+import SelectLocalStock from "@/views/pms/iotmaterialrequisition/SelectLocalStock.vue";
|
|
import * as DeptApi from "@/api/system/dept";
|
|
import * as DeptApi from "@/api/system/dept";
|
|
import {erpPriceTableColumnFormatter} from "@/utils";
|
|
import {erpPriceTableColumnFormatter} from "@/utils";
|
|
-import dayjs from 'dayjs'
|
|
|
|
-import MaterialListDrawer from "@/views/pms/iotmainworkorder/SelectedMaterialDrawer.vue";
|
|
|
|
-import WorkOrderMaterial from "@/views/pms/iotmainworkorder/WorkOrderMaterial.vue";
|
|
|
|
-import { IotDevicePersonApi, IotDevicePersonVO } from '@/api/pms/iotdeviceperson'
|
|
|
|
-import {DICT_TYPE, getIntDictOptions, getStrDictOptions} from "@/utils/dict";
|
|
|
|
|
|
|
|
/** 物料领用 表单 */
|
|
/** 物料领用 表单 */
|
|
defineOptions({ name: 'IotMaterialRequisitionAdd' })
|
|
defineOptions({ name: 'IotMaterialRequisitionAdd' })
|
|
@@ -163,21 +147,12 @@ const { delView } = useTagsViewStore() // 视图操作
|
|
const { currentRoute, push } = useRouter()
|
|
const { currentRoute, push } = useRouter()
|
|
const deptUsers = ref<UserApi.UserVO[]>([]) // 用户列表
|
|
const deptUsers = ref<UserApi.UserVO[]>([]) // 用户列表
|
|
const dept = ref() // 当前登录人所属部门对象
|
|
const dept = ref() // 当前登录人所属部门对象
|
|
-const configFormRef = ref() // 配置弹出框对象
|
|
|
|
-const bomNodeId = ref() // 最新的bomNodeId
|
|
|
|
const dialogTitle = ref('') // 弹窗的标题
|
|
const dialogTitle = ref('') // 弹窗的标题
|
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
|
-const deviceLabel = ref('') // 表单的类型:create - 新增;update - 修改
|
|
|
|
-const drawerVisible = ref<boolean>(false)
|
|
|
|
-const currentBomNodeId = ref() // 当前选中的bom节点
|
|
|
|
-const showDrawer = ref()
|
|
|
|
-const list = ref<IotMainWorkOrderBomVO[]>([]) // 保养工单bom关联列表的数据
|
|
|
|
const materialList = ref<IotMaterialRequisitionDetailVO[]>([]) // 领用单明细
|
|
const materialList = ref<IotMaterialRequisitionDetailVO[]>([]) // 领用单明细
|
|
-const deviceIds = ref<number[]>([]) // 已经选择的设备id数组
|
|
|
|
const { params, name } = useRoute() // 查询参数
|
|
const { params, name } = useRoute() // 查询参数
|
|
const id = params.id
|
|
const id = params.id
|
|
-const devicePersonsMap = ref<Map<number, Set<string>>>(new Map()) // 存储设备-责任人映射
|
|
|
|
|
|
|
|
const formData = ref({
|
|
const formData = ref({
|
|
id: undefined,
|
|
id: undefined,
|
|
@@ -198,12 +173,6 @@ const formRules = reactive({
|
|
})
|
|
})
|
|
const formRef = ref() // 表单 Ref
|
|
const formRef = ref() // 表单 Ref
|
|
|
|
|
|
-interface MaterialFormExpose {
|
|
|
|
- open: (deptId: number, bomNodeId: number) => void
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-const materialFormRef = ref<MaterialFormExpose>();
|
|
|
|
-
|
|
|
|
// 监听物料列表变化
|
|
// 监听物料列表变化
|
|
watch(
|
|
watch(
|
|
() => materialList.value,
|
|
() => materialList.value,
|
|
@@ -231,19 +200,15 @@ const calculateTotalCost = () => {
|
|
formData.value.cost = (materialTotal).toFixed(2)
|
|
formData.value.cost = (materialTotal).toFixed(2)
|
|
}
|
|
}
|
|
|
|
|
|
-/** 查看已经选择的物料 并编辑 */
|
|
|
|
-const handleView = (nodeId) => {
|
|
|
|
- currentBomNodeId.value = nodeId
|
|
|
|
- drawerVisible.value = true
|
|
|
|
- // showDrawer.value.openDrawer()
|
|
|
|
- console.log('当前bom节点:', currentBomNodeId.value)
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
// 多选 物料
|
|
// 多选 物料
|
|
const stockChoose = (selectedStocks) => {
|
|
const stockChoose = (selectedStocks) => {
|
|
// 转换数据结构(根据你的接口定义调整)
|
|
// 转换数据结构(根据你的接口定义调整)
|
|
const newItems = selectedStocks.map(stock => ({
|
|
const newItems = selectedStocks.map(stock => ({
|
|
id: stock.id,
|
|
id: stock.id,
|
|
|
|
+ factoryId: stock.factoryId,
|
|
|
|
+ factory: stock.factory,
|
|
|
|
+ costCenterId: stock.costCenterId,
|
|
|
|
+ costCenter: stock.costCenter,
|
|
materialCode: stock.materialCode,
|
|
materialCode: stock.materialCode,
|
|
materialName: stock.materialName,
|
|
materialName: stock.materialName,
|
|
unit: stock.unit,
|
|
unit: stock.unit,
|
|
@@ -311,14 +276,12 @@ const submitForm = async () => {
|
|
formLoading.value = true
|
|
formLoading.value = true
|
|
try {
|
|
try {
|
|
const data = {
|
|
const data = {
|
|
- mainWorkOrder: formData.value,
|
|
|
|
- mainWorkOrderBom: list.value,
|
|
|
|
- mainWorkOrderMaterials: materialList.value
|
|
|
|
|
|
+ materialRequisition: formData.value,
|
|
|
|
+ materialReqDetails: materialList.value
|
|
}
|
|
}
|
|
- await IotMainWorkOrderApi.addWorkOrder(data)
|
|
|
|
|
|
+ await IotMaterialRequisitionApi.addMaterialRequisition(data)
|
|
message.success(t('common.createSuccess'))
|
|
message.success(t('common.createSuccess'))
|
|
close()
|
|
close()
|
|
-
|
|
|
|
// 发送操作成功的事件
|
|
// 发送操作成功的事件
|
|
emit('success')
|
|
emit('success')
|
|
} finally {
|
|
} finally {
|
|
@@ -331,11 +294,11 @@ const validateTableData = (): boolean => {
|
|
let isValid = true
|
|
let isValid = true
|
|
const errorMessages: string[] = []
|
|
const errorMessages: string[] = []
|
|
|
|
|
|
- if (list.value.length === 0) {
|
|
|
|
- errorMessages.push('请至少添加一条设备保养明细')
|
|
|
|
|
|
+ if (materialList.value.length === 0) {
|
|
|
|
+ errorMessages.push('请至少添加一条物料明细')
|
|
isValid = false
|
|
isValid = false
|
|
// 直接返回无需后续校验
|
|
// 直接返回无需后续校验
|
|
- message.error('请至少添加一条设备保养明细')
|
|
|
|
|
|
+ message.error('请至少添加一条物料明细')
|
|
return isValid
|
|
return isValid
|
|
}
|
|
}
|
|
return isValid
|
|
return isValid
|
|
@@ -362,38 +325,26 @@ onMounted(async () => {
|
|
// 查询当前登录人所属部门名称
|
|
// 查询当前登录人所属部门名称
|
|
dept.value = await DeptApi.getDept(deptId)
|
|
dept.value = await DeptApi.getDept(deptId)
|
|
formData.value.name = dept.value.name + ' - 领料单'
|
|
formData.value.name = dept.value.name + ' - 领料单'
|
|
- deptUsers.value = await UserApi.getDeptUsersByDeptId(deptId)
|
|
|
|
formData.value.deptId = deptId
|
|
formData.value.deptId = deptId
|
|
try {
|
|
try {
|
|
formType.value = 'create'
|
|
formType.value = 'create'
|
|
- const { wsCache } = useCache()
|
|
|
|
- const userInfo = wsCache.get(CACHE_KEY.USER)
|
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
console.error('数据加载失败:', error)
|
|
console.error('数据加载失败:', error)
|
|
message.error('数据加载失败,请重试')
|
|
message.error('数据加载失败,请重试')
|
|
}
|
|
}
|
|
})
|
|
})
|
|
|
|
|
|
-const handleDelete = async (str: string) => {
|
|
|
|
|
|
+const handleDelete = async (materialCode: string) => {
|
|
try {
|
|
try {
|
|
- const [deviceIdStr, bomNodeId] = str.split('-')
|
|
|
|
- const deviceId = parseInt(deviceIdStr)
|
|
|
|
- // 删除列表项
|
|
|
|
- const index = list.value.findIndex((item) => (item.deviceId+'-'+item.bomNodeId) === str)
|
|
|
|
|
|
+ // 从 materialList 中移除对应物料
|
|
|
|
+ const index = materialList.value.findIndex(item => item.materialCode === materialCode);
|
|
if (index !== -1) {
|
|
if (index !== -1) {
|
|
- list.value.splice(index, 1)
|
|
|
|
- deviceIds.value = []
|
|
|
|
- }
|
|
|
|
- // 更新设备ID列表(需要检查是否还有该设备的其他项)
|
|
|
|
- const hasOtherItems = list.value.some(item => item.deviceId === deviceId)
|
|
|
|
- if (!hasOtherItems) {
|
|
|
|
- deviceIds.value = deviceIds.value.filter(id => id !== deviceId)
|
|
|
|
- devicePersonsMap.value.delete(deviceId) // 移除对应设备的责任人
|
|
|
|
|
|
+ materialList.value.splice(index, 1);
|
|
|
|
+ calculateTotalCost(); // 重新计算总费用
|
|
}
|
|
}
|
|
- // message.success('移除成功')
|
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
- console.error('移除失败:', error)
|
|
|
|
- message.error('移除失败')
|
|
|
|
|
|
+ console.error('移除失败:', error);
|
|
|
|
+ message.error('移除失败');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|