<template>
|
<uni-popup
|
ref="popupRef"
|
type="bottom"
|
:round="20"
|
:safeAreaInsetBottom="true"
|
@close="handleClose"
|
@open="handleOpen"
|
>
|
<view class="dispatch-modal">
|
<!-- 头部 -->
|
<view class="modal-header">
|
<text class="modal-title">生产派工</text>
|
<view class="close-btn" @click="handleClose">
|
<up-icon name="close" size="20" color="#999"></up-icon>
|
</view>
|
</view>
|
|
<!-- 表单内容 -->
|
<view class="modal-content">
|
<up-form
|
:model="form"
|
ref="formRef"
|
:rules="rules"
|
labelWidth="120"
|
>
|
<!-- 项目基本信息 -->
|
<view class="form-section">
|
<text class="section-title">产品信息</text>
|
<!-- <up-form-item label="项目名称" prop="projectName">
|
<up-input
|
v-model="form.projectName"
|
disabled
|
placeholder="项目名称"
|
/>
|
</up-form-item> -->
|
<up-form-item label="产品大类" prop="productCategory">
|
<up-input
|
v-model="form.productCategory"
|
disabled
|
placeholder="产品大类"
|
/>
|
</up-form-item>
|
<up-form-item label="规格型号" prop="specificationModel">
|
<up-input
|
v-model="form.specificationModel"
|
disabled
|
placeholder="规格型号"
|
/>
|
</up-form-item>
|
<up-form-item label="绑定机器" prop="speculativeTradingName">
|
<up-input
|
v-model="form.speculativeTradingName"
|
disabled
|
placeholder="绑定机器"
|
/>
|
</up-form-item>
|
</view>
|
|
<!-- 数量信息 -->
|
<view class="form-section">
|
<text class="section-title">数量信息</text>
|
<up-form-item label="总数量" prop="quantity">
|
<up-input
|
v-model="form.quantity"
|
disabled
|
placeholder="总数量"
|
/>
|
</up-form-item>
|
<up-form-item label="待排产数量" prop="pendingQuantity">
|
<up-input
|
v-model="form.pendingQuantity"
|
disabled
|
placeholder="待排产数量"
|
/>
|
</up-form-item>
|
<up-form-item label="本次排产数量" prop="schedulingNum" required>
|
<up-number-box
|
v-model="form.schedulingNum"
|
:min="0"
|
:max="form.pendingQuantity"
|
:step="0.1"
|
:precision="2"
|
@change="handleNumChange"
|
/>
|
</up-form-item>
|
</view>
|
|
<!-- 派工信息 -->
|
<view class="form-section">
|
<text class="section-title">派工信息</text>
|
<up-form-item label="派工人" prop="schedulingUserId" required>
|
<uni-data-select v-model="form.schedulingUserId" :localdata="userColumns" :clear="false"></uni-data-select>
|
</up-form-item>
|
<up-form-item label="派工日期" prop="schedulingDate" required>
|
<uni-datetime-picker type="date" :clear-icon="false" v-model="form.schedulingDate">
|
<view class="datetime-picker-value">
|
{{form.schedulingDate}}
|
</view>
|
</uni-datetime-picker>
|
</up-form-item>
|
</view>
|
</up-form>
|
</view>
|
|
<!-- 底部按钮 -->
|
<view class="modal-footer">
|
<up-button
|
@click="handleClose"
|
text="取消"
|
type="info"
|
plain
|
:customStyle="{ marginRight: '12px', flex: 1 }"
|
/>
|
<up-button
|
@click="handleConfirm"
|
text="确认派工"
|
type="primary"
|
:customStyle="{ flex: 1 }"
|
:loading="submitting"
|
/>
|
</view>
|
</view>
|
</uni-popup>
|
</template>
|
|
<script setup>
|
import { ref, reactive, computed, getCurrentInstance } from 'vue';
|
import { userListNoPageByTenantId } from "@/api/system/user.js";
|
import { productionDispatch } from "@/api/productionManagement/productionOrder.js";
|
import useUserStore from "@/store/modules/user";
|
import dayjs from "dayjs";
|
|
const { proxy } = getCurrentInstance();
|
const userStore = useUserStore();
|
const emit = defineEmits(['confirm']);
|
|
// 弹窗显示状态
|
const popupRef = ref();
|
const submitting = ref(false);
|
|
// 用户列表
|
const userList = ref([]);
|
const userColumns = computed(() => {
|
return userList.value.map(user => ({
|
text: user.nickName,
|
value: user.userId
|
}))
|
});
|
|
// 表单数据
|
const form = reactive({
|
projectName: "",
|
productCategory: "",
|
quantity: "",
|
schedulingNum: 0,
|
schedulingUserId: "",
|
schedulingDate: "",
|
pendingQuantity: 0,
|
id: "" // 原始记录ID
|
});
|
|
// 表单验证规则
|
const rules = reactive({
|
// schedulingNum: [
|
// { required: true, message: "请输入排产数量", trigger: "blur" }
|
// ],
|
// schedulingUserId: [
|
// { required: true, message: "请选择派工人", trigger: "change" }
|
// ],
|
// schedulingDate: [
|
// { required: true, message: "请选择派工日期", trigger: "change" }
|
// ]
|
});
|
|
// 表单引用
|
const formRef = ref();
|
|
// 打开弹窗
|
const open = async (rowData) => {
|
try {
|
// 加载用户列表
|
const res = await userListNoPageByTenantId();
|
userList.value = res.data || [];
|
|
// 填充表单数据
|
Object.assign(form, {
|
...rowData,
|
schedulingNum: 0,
|
schedulingUserId: userStore.id,
|
schedulingDate: dayjs().format("YYYY-MM-DD")
|
});
|
popupRef.value.open()
|
} catch (error) {
|
console.log(error)
|
uni.showToast({
|
title: '加载用户列表失败',
|
icon: 'error'
|
});
|
}
|
};
|
|
// 处理数量变化
|
const handleNumChange = (value) => {
|
if (value > form.pendingQuantity) {
|
form.schedulingNum = form.pendingQuantity;
|
uni.showToast({
|
title: '排产数量不可大于待排产数量',
|
icon: 'none'
|
});
|
}
|
};
|
|
// 确认派工
|
const handleConfirm = async () => {
|
if(!form.schedulingNum){
|
uni.showToast({
|
title: '请输入排产数量',
|
icon:'none'
|
})
|
return
|
}
|
if(!form.schedulingUserId){
|
uni.showToast({
|
title: '请选择派工人',
|
icon:'none'
|
})
|
return
|
}
|
if(!form.schedulingDate){
|
uni.showToast({
|
title: '请选择派工日期',
|
icon:'none'
|
})
|
return
|
}
|
try {
|
if (form.schedulingNum <= 0) {
|
uni.showToast({
|
title: '排产数量必须大于0',
|
icon: 'none'
|
});
|
return;
|
}
|
|
submitting.value = true;
|
|
// 提交派工数据
|
await productionDispatch(form);
|
|
uni.showToast({
|
title: '派工成功',
|
icon: 'success'
|
});
|
|
handleClose();
|
emit('confirm');
|
|
} catch (error) {
|
uni.showToast({
|
title: '派工失败',
|
icon: 'error'
|
});
|
} finally {
|
submitting.value = false;
|
}
|
};
|
|
// 弹窗打开事件
|
const handleOpen = () => {
|
// 弹窗打开时的处理
|
};
|
|
// 关闭弹窗
|
const handleClose = () => {
|
popupRef.value.close()
|
// 重置表单
|
Object.assign(form, {
|
projectName: "",
|
productCategory: "",
|
quantity: "",
|
schedulingNum: 0,
|
schedulingUserId: "",
|
schedulingDate: "",
|
pendingQuantity: 0,
|
id: ""
|
});
|
};
|
|
// 暴露方法
|
defineExpose({
|
open
|
});
|
</script>
|
|
<style scoped lang="scss">
|
.dispatch-modal {
|
background: #ffffff;
|
border-radius: 20px 20px 0 0;
|
max-height: 80vh;
|
overflow: hidden;
|
display: flex;
|
flex-direction: column;
|
}
|
|
.modal-header {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
padding: 20px 20px 0 20px;
|
border-bottom: 1px solid #f0f0f0;
|
padding-bottom: 16px;
|
margin-bottom: 20px;
|
}
|
|
.modal-title {
|
font-size: 18px;
|
font-weight: 600;
|
color: #333;
|
}
|
|
.close-btn {
|
padding: 4px;
|
|
&:active {
|
opacity: 0.7;
|
}
|
}
|
|
.modal-content {
|
flex: 1;
|
padding: 0 20px;
|
overflow-y: auto;
|
.datetime-picker-value{
|
font-size: 14px;
|
border: 1px solid #e5e5e5;
|
box-sizing: border-box;
|
border-radius: 4px;
|
padding: 0 5px;
|
padding-left: 10px;
|
position: relative;
|
display: flex;
|
-webkit-user-select: none;
|
-moz-user-select: none;
|
user-select: none;
|
flex-direction: row;
|
align-items: center;
|
width: 100%;
|
flex: 1;
|
height: 35px;
|
}
|
}
|
|
.form-section {
|
margin-bottom: 24px;
|
}
|
|
.section-title {
|
display: block;
|
font-size: 16px;
|
font-weight: 600;
|
color: #333;
|
margin-bottom: 16px;
|
padding-left: 8px;
|
border-left: 3px solid #2979ff;
|
}
|
|
.modal-footer {
|
display: flex;
|
gap: 12px;
|
padding: 20px;
|
border-top: 1px solid #f0f0f0;
|
background: #fafafa;
|
}
|
|
// uView 组件样式调整
|
:deep(.up-form-item) {
|
margin-bottom: 20px;
|
}
|
|
:deep(.up-input) {
|
background: #f8f9fa;
|
border-radius: 8px;
|
}
|
|
:deep(.up-input--disabled) {
|
background: #f0f0f0;
|
color: #999;
|
}
|
|
:deep(.up-number-box) {
|
background: #f8f9fa;
|
border-radius: 8px;
|
}
|
</style>
|