<template>
|
<view class="report-manage-page">
|
<view class="pt-2">
|
<wd-card class="card_bg">
|
<template #title>
|
<view class="flex justify-between w-full">
|
<text class="font-medium text-[#252525]">报工管理</text>
|
<wd-button
|
icon="file-add"
|
:round="false"
|
size="small"
|
custom-class="add_btn"
|
@click="handleAdd"
|
>
|
新增
|
</wd-button>
|
</view>
|
</template>
|
<wd-row class="my-2">
|
<wd-col :span="24">
|
<view class="flex">
|
<view class="icon_box">
|
<wd-icon name="folder" color="#0D867F"></wd-icon>
|
</view>
|
<text class="text-[#646874] mx-2">
|
领用杆号:
|
<text class="text-[#252525]">{{ parentData?.poleNumber || "" }}</text>
|
</text>
|
</view>
|
</wd-col>
|
</wd-row>
|
<wd-row class="my-2">
|
<wd-col :span="24">
|
<view class="flex">
|
<view class="icon_box">
|
<wd-icon name="folder" color="#0D867F"></wd-icon>
|
</view>
|
<text class="text-[#646874] mx-2">
|
杆型号:
|
<text class="text-[#252525]">{{ parentData?.poleModel || "" }}</text>
|
</text>
|
</view>
|
</wd-col>
|
</wd-row>
|
<wd-row class="my-2">
|
<wd-col :span="24">
|
<view class="flex">
|
<view class="icon_box">
|
<wd-icon name="folder" color="#0D867F"></wd-icon>
|
</view>
|
<text class="text-[#646874] mx-2">
|
杆包号:
|
<text class="text-[#252525]">{{ parentData?.polePackageNumber || "" }}</text>
|
</text>
|
</view>
|
</wd-col>
|
</wd-row>
|
<wd-row class="my-2">
|
<wd-col :span="24">
|
<view class="flex">
|
<view class="icon_box">
|
<wd-icon name="folder" color="#0D867F"></wd-icon>
|
</view>
|
<text class="text-[#646874] mx-2">
|
杆重:
|
<text class="text-[#252525]">{{ parentData?.poleWeight || "" }}kg</text>
|
</text>
|
</view>
|
</wd-col>
|
</wd-row>
|
</wd-card>
|
</view>
|
|
<view class="page-content">
|
<wd-card
|
v-for="(child, childIndex) in childList"
|
:key="child.id || child.tempId || childIndex"
|
class="card_bg"
|
>
|
<template #title>
|
<text class="font-medium text-[#252525]">单丝盘号: {{ child.monofilamentNumber }}</text>
|
</template>
|
<wd-row class="my-2" v-if="child.model">
|
<wd-col :span="12">
|
<view class="flex">
|
<view class="icon_box">
|
<wd-icon name="folder" color="#0D867F"></wd-icon>
|
</view>
|
<text class="text-[#646874] mx-2">
|
规格型号:
|
<text class="text-[#252525]">{{ child.model }}</text>
|
</text>
|
</view>
|
</wd-col>
|
<wd-col :span="12">
|
<view class="flex">
|
<view class="icon_box">
|
<wd-icon name="folder" color="#0D867F"></wd-icon>
|
</view>
|
<text class="text-[#646874] mx-2">
|
盘型号:
|
<text class="text-[#252525]">{{ child.dishModel }}</text>
|
</text>
|
</view>
|
</wd-col>
|
</wd-row>
|
<wd-row class="my-2">
|
<wd-col :span="12" v-if="child.oneLength">
|
<view class="flex">
|
<view class="icon_box">
|
<wd-icon name="folder" color="#0D867F"></wd-icon>
|
</view>
|
<text class="text-[#646874] mx-2">
|
盘长(m):
|
<text class="text-[#252525]">{{ child.oneLength }}</text>
|
</text>
|
</view>
|
</wd-col>
|
<wd-col :span="12" v-if="child.isJoint !== undefined && child.isJoint !== null">
|
<view class="flex">
|
<view class="icon_box">
|
<wd-icon name="folder" color="#0D867F"></wd-icon>
|
</view>
|
<text class="text-[#646874] mx-2">
|
是否接头:
|
<text class="text-[#252525]">
|
{{ child.isJoint === 1 ? "是" : child.isJoint === 0 ? "否" : "" }}
|
</text>
|
</text>
|
</view>
|
</wd-col>
|
</wd-row>
|
<wd-row class="my-2">
|
<wd-col :span="14" v-if="child.actuallyLength">
|
<view class="flex">
|
<view class="icon_box">
|
<wd-icon name="folder" color="#0D867F"></wd-icon>
|
</view>
|
<text class="text-[#646874] mx-2">
|
实际长度(m):
|
<text class="text-[#252525]">{{ child.actuallyLength }}</text>
|
</text>
|
</view>
|
</wd-col>
|
<wd-col :span="10" v-if="child.productUser">
|
<view class="flex">
|
<view class="icon_box">
|
<wd-icon name="folder" color="#0D867F"></wd-icon>
|
</view>
|
<text class="text-[#646874] mx-2">
|
生产人:
|
<text class="text-[#252525]">{{ child.productUser }}</text>
|
</text>
|
</view>
|
</wd-col>
|
</wd-row>
|
<wd-row class="my-2">
|
<wd-col :span="24" v-if="child.actuallyWeight">
|
<view class="flex">
|
<view class="icon_box">
|
<wd-icon name="folder" color="#0D867F"></wd-icon>
|
</view>
|
<text class="text-[#646874] mx-2">
|
实际重量(kg):
|
<text class="text-[#252525]">{{ child.actuallyWeight }}</text>
|
</text>
|
</view>
|
</wd-col>
|
</wd-row>
|
<wd-row class="my-2">
|
<wd-col :span="24" v-if="child.productTime">
|
<view class="flex">
|
<view class="icon_box">
|
<wd-icon name="folder" color="#0D867F"></wd-icon>
|
</view>
|
<text class="text-[#646874] mx-2">
|
生产日期:
|
<text class="text-[#252525]">{{ child.productTime }}</text>
|
</text>
|
</view>
|
</wd-col>
|
</wd-row>
|
<wd-row class="my-2">
|
<wd-col :span="24" v-if="child.processHour">
|
<view class="flex">
|
<view class="icon_box">
|
<wd-icon name="folder" color="#0D867F"></wd-icon>
|
</view>
|
<text class="text-[#646874] mx-2">
|
加工时间(h):
|
<text class="text-[#252525]">{{ child.processHour }}</text>
|
</text>
|
</view>
|
</wd-col>
|
</wd-row>
|
<template #footer>
|
<view class="flex gap-2">
|
<wd-button plain size="small" @click="toAttachment(child)">附件</wd-button>
|
<wd-button plain type="error" size="small" @click="handleDeleteSingle(child)">
|
删除
|
</wd-button>
|
</view>
|
</template>
|
</wd-card>
|
</view>
|
|
<!-- 新增报工弹框 -->
|
<wd-popup v-model="addDialogVisible" position="bottom" custom-class="yl-popup">
|
<view class="add-dialog">
|
<view class="dialog-header">
|
<text class="dialog-title">新增报工</text>
|
<wd-icon name="close" class="close-icon" @click="closeAddDialog"></wd-icon>
|
</view>
|
<view class="dialog-content">
|
<wd-cell-group>
|
<wd-input
|
v-model="newChildData.dishModel"
|
label="盘型号"
|
label-width="100px"
|
placeholder="请输入盘型号"
|
/>
|
<wd-input
|
v-model="newChildData.actuallyLength"
|
label="实际长度(m)"
|
label-width="100px"
|
type="number"
|
placeholder="请输入实际长度"
|
/>
|
<wd-input
|
v-model="newChildData.actuallyWeight"
|
label="实际重量(kg)"
|
label-width="100px"
|
type="number"
|
placeholder="请输入实际重量"
|
/>
|
<wd-cell title="是否接头" label-width="100px">
|
<wd-radio-group v-model="newChildData.isJoint">
|
<wd-radio :value="1">是</wd-radio>
|
<wd-radio :value="0">否</wd-radio>
|
</wd-radio-group>
|
</wd-cell>
|
</wd-cell-group>
|
</view>
|
<view class="dialog-footer">
|
<wd-button plain @click="closeAddDialog">取消</wd-button>
|
<wd-button type="primary" class="ml-2" @click="handleSaveNewChild">保存</wd-button>
|
</view>
|
</view>
|
</wd-popup>
|
|
<wd-toast />
|
</view>
|
</template>
|
|
<script setup lang="ts">
|
import { ref, watch, nextTick } from "vue";
|
import { onLoad } from "@dcloudio/uni-app";
|
import { useToast, dayjs } from "wot-design-uni";
|
import WireApi from "@/api/product/wire";
|
import { getTeamId } from "@/utils/cache";
|
import { useUserStore } from "@/store/modules/user";
|
|
const toast = useToast();
|
const userStore = useUserStore();
|
|
const paramsId = ref();
|
const parentData = ref<any>(null);
|
const childList = ref<any[]>([]);
|
const model = ref();
|
const oneLength = ref();
|
const allChildDataList = ref<any[]>([]);
|
const wireDetail = ref<any>(null);
|
|
// 新增弹框相关
|
const addDialogVisible = ref(false);
|
const newChildData = ref({
|
dishModel: "",
|
actuallyLength: "",
|
actuallyWeight: "",
|
isJoint: 0,
|
meterWeight: 0, // 米重
|
});
|
|
// 获取详情数据
|
const getDetailData = async (id: string) => {
|
try {
|
const { data } = await WireApi.getWireDetailById({ id });
|
wireDetail.value = data;
|
model.value = data.model;
|
oneLength.value = data.oneLength;
|
} catch (error) {
|
console.error("获取详情失败:", error);
|
}
|
};
|
|
// 初始化数据
|
const getData = async () => {
|
try {
|
const { code, data } = await WireApi.getWireOutputTree({
|
wireId: paramsId.value,
|
});
|
|
if (code == 200) {
|
allChildDataList.value = [];
|
const parentMap = new Map();
|
|
data.forEach((item: any) => {
|
const parentKey = `${item.poleNumber}-${item.poleModel}-${item.polePackageNumber}`;
|
|
if (item.node && Array.isArray(item.node)) {
|
item.node.forEach((child: any) => {
|
const childData = {
|
...child,
|
parentKey: parentKey,
|
poleNumber: item.poleNumber,
|
poleModel: item.poleModel,
|
polePackageNumber: item.polePackageNumber,
|
supplier: item.supplier,
|
};
|
allChildDataList.value.push(childData);
|
});
|
}
|
});
|
|
// 刷新当前页面的子级列表
|
const parentKey = `${parentData.value.poleNumber}-${parentData.value.poleModel}-${parentData.value.polePackageNumber}`;
|
childList.value = allChildDataList.value
|
.filter((child) => child.parentKey === parentKey)
|
.map((child, index) => ({
|
...child,
|
customIndex: index + 1,
|
selected: false,
|
}));
|
}
|
} catch (error) {
|
console.error("获取数据失败:", error);
|
toast.error("获取数据失败");
|
}
|
};
|
|
// 打开新增弹框
|
const handleAdd = () => {
|
const lastChild = childList.value[childList.value.length - 1];
|
|
// 从详情数据中获取米重
|
const meterWeight =
|
Number(wireDetail.value?.meterWeight) ||
|
Number(wireDetail.value?.weight) ||
|
Number(wireDetail.value?.theoryWeight) ||
|
0;
|
|
// 初始化新数据,如果有最后一条数据,使用其值作为默认值
|
newChildData.value = {
|
dishModel: lastChild?.dishModel || "",
|
actuallyLength: lastChild?.actuallyLength || "",
|
actuallyWeight: lastChild?.actuallyWeight || "",
|
isJoint: lastChild?.isJoint || 0,
|
meterWeight: meterWeight,
|
};
|
|
addDialogVisible.value = true;
|
};
|
|
// 保存新增的子级数据
|
const handleSaveNewChild = async () => {
|
if (!newChildData.value.actuallyLength || !newChildData.value.actuallyWeight) {
|
toast.error("请输入完整信息(实际长度和重量为必填项)");
|
return;
|
}
|
|
const lastChild = childList.value[childList.value.length - 1];
|
|
// 生成新的单丝盘号
|
const newMonofilamentNumber = addMonofilamentNumber(lastChild?.monofilamentNumber, "拉丝");
|
|
const newChild = {
|
id: null,
|
tempId: `temp_${Date.now()}`,
|
parentKey: `${parentData.value.poleNumber}-${parentData.value.poleModel}-${parentData.value.polePackageNumber}`,
|
teamId: getTeamId(),
|
type: "拉丝",
|
wireId: paramsId.value,
|
poleNumber: parentData.value.poleNumber,
|
poleModel: parentData.value.poleModel,
|
supplier: parentData.value.supplier,
|
polePackageNumber: parentData.value.polePackageNumber,
|
dishModel: newChildData.value.dishModel || null,
|
poleWeight: parentData.value.poleWeight,
|
monofilamentNumber: newMonofilamentNumber,
|
model: model.value || "",
|
oneLength: oneLength.value || null,
|
theoryWeight: lastChild?.theoryWeight || null,
|
actuallyLength: newChildData.value.actuallyLength,
|
actuallyWeight: newChildData.value.actuallyWeight,
|
processHour: lastChild?.processHour || null,
|
productUser: userStore.userInfo?.nickname || userStore.userInfo?.nickName || "",
|
productTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
|
customIndex: childList.value.length + 1,
|
isJoint: newChildData.value.isJoint,
|
selected: false,
|
};
|
|
// 为每个子级数据添加杆重信息
|
const childrenWithPoleWeight = [
|
{
|
...newChild,
|
poleWeight: parentData.value.poleWeight,
|
},
|
];
|
|
try {
|
const { code, data } = await WireApi.addWireOutputList(childrenWithPoleWeight);
|
if (code == 200) {
|
if (data) {
|
toast.warning(data);
|
} else {
|
toast.success("保存成功");
|
}
|
closeAddDialog();
|
await getData();
|
}
|
} catch (error) {
|
console.error("保存失败:", error);
|
toast.error("保存失败");
|
}
|
};
|
|
// 关闭新增弹框
|
const closeAddDialog = () => {
|
addDialogVisible.value = false;
|
// 重置表单数据
|
newChildData.value = {
|
dishModel: "",
|
actuallyLength: "",
|
actuallyWeight: "",
|
isJoint: 0,
|
meterWeight: 0,
|
};
|
};
|
|
// 生成新的单丝盘号
|
const addMonofilamentNumber = (val: string, type: string) => {
|
if (val) {
|
if (type == "拉丝") {
|
const arr = val.split("-");
|
if (arr.length >= 3) {
|
const prefix = `${arr[0]}-${arr[1]}`;
|
|
let count = 0;
|
allChildDataList.value.forEach((child) => {
|
if (child.monofilamentNumber) {
|
const childArr = child.monofilamentNumber.split("-");
|
if (childArr.length >= 3) {
|
const childPrefix = `${childArr[0]}-${childArr[1]}`;
|
if (childPrefix === prefix) {
|
count++;
|
}
|
}
|
}
|
});
|
|
childList.value.forEach((child) => {
|
if (child.monofilamentNumber && !child.id) {
|
const childArr = child.monofilamentNumber.split("-");
|
if (childArr.length >= 3) {
|
const childPrefix = `${childArr[0]}-${childArr[1]}`;
|
if (childPrefix === prefix) {
|
count++;
|
}
|
}
|
}
|
});
|
|
const a = count + 1;
|
const paddedA = a < 10 ? `0${a}` : `${a}`;
|
return `${prefix}-${paddedA}`;
|
}
|
}
|
}
|
return "";
|
};
|
|
// 跳转到附件页面
|
const toAttachment = (item: any) => {
|
uni.navigateTo({
|
url: "/pages/production/wire/attachment/index",
|
success: () => {
|
// 页面跳转成功后发送事件传递数据
|
uni.$emit("detailData", item);
|
},
|
fail: (error) => {
|
console.error("跳转附件页面失败:", error);
|
toast.error("跳转失败");
|
},
|
});
|
};
|
|
// 删除单个子级数据
|
const handleDeleteSingle = async (child: any) => {
|
try {
|
const res = await uni.showModal({
|
title: "提示",
|
content: `确定删除这条数据吗?`,
|
});
|
|
if (res.confirm) {
|
// 如果是已保存的数据,调用删除接口
|
if (child.id) {
|
await WireApi.deleteWireOutput({ id: child.id });
|
await getData();
|
toast.success("删除成功");
|
} else {
|
// 如果是未保存的数据,直接从列表中移除
|
const index = childList.value.findIndex((row) => row.tempId === child.tempId);
|
if (index !== -1) {
|
childList.value.splice(index, 1);
|
// 重新计算序号
|
childList.value.forEach((item, idx) => {
|
item.customIndex = idx + 1;
|
});
|
toast.success("删除成功");
|
}
|
}
|
}
|
} catch (error) {
|
console.error("删除失败:", error);
|
toast.error("删除失败");
|
}
|
};
|
|
// 自动计算实际重量
|
const handleCalculateWeight = (row: any) => {
|
// 从 newChildData 对象中获取米重
|
const meterWeight = Number(row.meterWeight) || 0;
|
const actuallyLength = Number(row.actuallyLength);
|
|
if (meterWeight > 0 && actuallyLength > 0) {
|
const calculatedWeight = (meterWeight * actuallyLength) / 1000;
|
row.actuallyWeight = Number(calculatedWeight.toFixed(3));
|
}
|
console.log("row", meterWeight, actuallyLength);
|
};
|
|
// 监听实际长度变化,自动计算重量
|
watch(
|
() => newChildData.value.actuallyLength,
|
(newValue, oldValue) => {
|
console.log("实际长度变化:", { newValue, oldValue, newChildData: newChildData.value });
|
if (newValue && String(newValue).trim() !== "") {
|
// 使用 nextTick 确保 v-model 已经更新
|
nextTick(() => {
|
handleCalculateWeight(newChildData.value);
|
});
|
}
|
},
|
{ immediate: false, deep: true }
|
);
|
|
onLoad(async (options: any) => {
|
paramsId.value = options.wireId;
|
|
// 从页面参数中获取父级数据
|
parentData.value = {
|
id: options.parentId,
|
poleNumber: options.poleNumber,
|
poleModel: options.poleModel,
|
polePackageNumber: options.polePackageNumber,
|
poleWeight: options.poleWeight,
|
supplier: options.supplier,
|
};
|
|
await getDetailData(options.wireId);
|
await getData();
|
});
|
</script>
|
|
<style lang="scss" scoped>
|
.report-manage-page {
|
min-height: 100vh;
|
background: #f3f9f8;
|
padding-bottom: 20px;
|
}
|
|
.card_bg {
|
box-shadow: 0px 0px 12px 0px rgba(0, 0, 0, 0.05);
|
padding-bottom: 10px;
|
}
|
|
.icon_box {
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
width: 20px;
|
height: 20px;
|
background: #e7f4ec99;
|
border-radius: 50%;
|
}
|
|
:deep() {
|
.add_btn {
|
border-radius: 4px;
|
}
|
}
|
|
.add-dialog {
|
max-height: 80vh;
|
display: flex;
|
flex-direction: column;
|
background: #fff;
|
border-radius: 12px 12px 0 0;
|
}
|
|
.dialog-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
padding: 16px;
|
border-bottom: 1px solid #e6e6e6;
|
position: sticky;
|
top: 0;
|
background: #fff;
|
z-index: 10;
|
}
|
|
.dialog-title {
|
font-size: 16px;
|
color: #333;
|
font-weight: 500;
|
}
|
|
.close-icon {
|
font-size: 20px;
|
color: #999;
|
padding: 4px;
|
}
|
|
.dialog-content {
|
flex: 1;
|
overflow-y: auto;
|
padding: 16px;
|
}
|
|
.dialog-footer {
|
display: flex;
|
justify-content: flex-end;
|
padding: 16px;
|
border-top: 1px solid #e6e6e6;
|
gap: 8px;
|
}
|
|
.page-content {
|
padding: 12px;
|
margin-top: 12px;
|
}
|
</style>
|