| | |
| | | <template> |
| | | <wd-form ref="form" :model="model" class="relative form_box"> |
| | | <wd-cell-group :border="true"> |
| | | <wd-input |
| | | v-model="model.selfInspectName" |
| | | label="自检名称" |
| | | label-width="100px" |
| | | prop="selfInspectName" |
| | | clearable |
| | | placeholder="请输入自检名称" |
| | | /> |
| | | <wd-input |
| | | v-model="model.unit" |
| | | label="单位" |
| | | label-width="100px" |
| | | prop="unit" |
| | | clearable |
| | | placeholder="请输入单位" |
| | | /> |
| | | <wd-input |
| | | v-model="model.standard" |
| | | label="标准值" |
| | | label-width="100px" |
| | | prop="standard" |
| | | clearable |
| | | placeholder="请输入标准值" |
| | | /> |
| | | <wd-input |
| | | v-model="model.selfInspectValue" |
| | | label="自检值" |
| | | label-width="100px" |
| | | prop="selfInspectValue" |
| | | clearable |
| | | placeholder="请输入自检值" |
| | | /> |
| | | <wd-input |
| | | v-model="model.selfInspectResult" |
| | | label="自检结果" |
| | | label-width="100px" |
| | | prop="selfInspectResult" |
| | | clearable |
| | | placeholder="请输入自检结果" |
| | | /> |
| | | </wd-cell-group> |
| | | </wd-form> |
| | | <view class="form-container"> |
| | | <view class="dialog-header"> |
| | | <text class="dialog-title">{{ isEdit ? "编辑自检" : "新增自检" }}</text> |
| | | <wd-icon name="close" class="close-icon" @click="handleClose"></wd-icon> |
| | | </view> |
| | | <view class="dialog-content"> |
| | | <wd-form ref="formRef" :model="formData"> |
| | | <!-- 基本信息 --> |
| | | <view class="section-title">基本信息</view> |
| | | <wd-cell-group border> |
| | | <wd-input |
| | | v-model="formData.fixedInfo.firstNo" |
| | | label="首检单号" |
| | | label-width="120px" |
| | | placeholder="请输入首检单号" |
| | | /> |
| | | <wd-input |
| | | v-model="formData.fixedInfo.lastSlot" |
| | | label="定径模具" |
| | | label-width="120px" |
| | | placeholder="请输入定径模具" |
| | | /> |
| | | </wd-cell-group> |
| | | |
| | | <!-- 单丝直径 --> |
| | | <view class="section-title">单丝直径(mm)</view> |
| | | <wd-cell-group border> |
| | | <wd-cell title="最大值" label-width="120px"> |
| | | <wd-input-number |
| | | v-model="formData.inspectionResult.maxDia" |
| | | :min="0" |
| | | :precision="3" |
| | | :step="0.01" |
| | | placeholder="请输入最大值" |
| | | :max=" |
| | | formData.inspectionResult.minDia !== null && |
| | | formData.inspectionResult.minDia !== undefined |
| | | ? undefined |
| | | : 999999 |
| | | " |
| | | /> |
| | | </wd-cell> |
| | | <wd-cell title="最小值" label-width="120px"> |
| | | <wd-input-number |
| | | v-model="formData.inspectionResult.minDia" |
| | | :min="0" |
| | | :precision="3" |
| | | :step="0.01" |
| | | placeholder="请输入最小值" |
| | | :max=" |
| | | formData.inspectionResult.maxDia !== null && |
| | | formData.inspectionResult.maxDia !== undefined |
| | | ? formData.inspectionResult.maxDia |
| | | : 999999 |
| | | " |
| | | /> |
| | | </wd-cell> |
| | | </wd-cell-group> |
| | | |
| | | <!-- 外观 --> |
| | | <view class="section-title">外观</view> |
| | | <wd-cell-group border> |
| | | <wd-cell title="外观质量" label-width="120px"> |
| | | <view class="checkbox-group"> |
| | | <wd-checkbox |
| | | v-for="option in appearanceOptions" |
| | | :key="option.value" |
| | | :modelValue=" |
| | | Array.isArray(formData.inspectionResult.appearance) |
| | | ? formData.inspectionResult.appearance.includes(String(option.value)) |
| | | : false |
| | | " |
| | | shape="square" |
| | | @change="(val) => handleAppearanceChange(String(option.value), val)" |
| | | > |
| | | {{ option.label }} |
| | | </wd-checkbox> |
| | | </view> |
| | | </wd-cell> |
| | | </wd-cell-group> |
| | | |
| | | <!-- 成盘质量 --> |
| | | <view class="section-title">成盘质量</view> |
| | | <wd-cell-group border> |
| | | <wd-cell title="卷绕紧密" label-width="120px"> |
| | | <wd-radio-group v-model="formData.inspectionResult.windingTightness" size="small"> |
| | | <wd-radio value="是">是</wd-radio> |
| | | <wd-radio value="否">否</wd-radio> |
| | | </wd-radio-group> |
| | | </wd-cell> |
| | | <wd-cell title="排列整齐" label-width="120px"> |
| | | <wd-radio-group v-model="formData.inspectionResult.arrangementNeatness" size="small"> |
| | | <wd-radio value="是">是</wd-radio> |
| | | <wd-radio value="否">否</wd-radio> |
| | | </wd-radio-group> |
| | | </wd-cell> |
| | | <wd-cell title="外层铝线离侧板边缘距离(mm)" label-width="200px"> |
| | | <wd-input-number |
| | | v-model="formData.inspectionResult.aluminumWireDistance" |
| | | :min="0" |
| | | :precision="0" |
| | | placeholder="请输入距离" |
| | | :class="{ 'text-danger': formData.inspectionResult.aluminumWireDistance < 25 }" |
| | | /> |
| | | </wd-cell> |
| | | </wd-cell-group> |
| | | |
| | | <!-- 其他信息 --> |
| | | <view class="section-title">其他信息</view> |
| | | <wd-cell-group border> |
| | | <wd-cell title="成品模后接头情况" label-width="120px"> |
| | | <wd-radio-group v-model="formData.inspectionResult.jointCondition" size="small"> |
| | | <wd-radio value="有">有</wd-radio> |
| | | <wd-radio value="无">无</wd-radio> |
| | | </wd-radio-group> |
| | | </wd-cell> |
| | | <wd-cell title="结论" label-width="120px"> |
| | | <wd-radio-group v-model="formData.inspectionResult.conclusion" size="small"> |
| | | <wd-radio value="合格">合格</wd-radio> |
| | | <wd-radio value="不合格">不合格</wd-radio> |
| | | </wd-radio-group> |
| | | </wd-cell> |
| | | </wd-cell-group> |
| | | </wd-form> |
| | | </view> |
| | | <view class="dialog-footer"> |
| | | <wd-button plain @click="handleClose" style="margin-right: 10px">取消</wd-button> |
| | | <wd-button type="primary" class="ml-2" @click="handleSubmit">保存</wd-button> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import useFormData from "@/hooks/useFormData"; |
| | | const { form: model } = useFormData({ |
| | | selfInspectName: undefined, // 自检名称 |
| | | unit: undefined, // 单位 |
| | | standard: undefined, // 标准值 |
| | | selfInspectValue: undefined, // 自检值 |
| | | selfInspectResult: undefined, // 自检值 |
| | | }); |
| | | import { ref, watch, computed } from "vue"; |
| | | import { dayjs } from "wot-design-uni"; |
| | | |
| | | const props = defineProps<{ |
| | | visible: boolean; |
| | | formData: any; |
| | | appearanceOptions: Array<{ label: string; value: string | number }>; |
| | | previousAppearanceValue?: string[]; |
| | | }>(); |
| | | |
| | | const emit = defineEmits<{ |
| | | (e: "update:visible", value: boolean): void; |
| | | (e: "submit", data: any): void; |
| | | (e: "close"): void; |
| | | }>(); |
| | | |
| | | const formRef = ref(); |
| | | const isEdit = computed(() => !!props.formData?.id && !props.formData?.isNew); |
| | | |
| | | // 存储前一个外观质量值 |
| | | const previousAppearanceValue = ref<string[]>(props.previousAppearanceValue || []); |
| | | |
| | | // 处理外观质量互斥逻辑 |
| | | const handleAppearanceQualityChange = ( |
| | | selectedValues: string[], |
| | | previousValues: string[], |
| | | allOptions: Array<{ label: string; value: string | number }> |
| | | ): string[] => { |
| | | if (!allOptions || allOptions.length === 0) { |
| | | return selectedValues; |
| | | } |
| | | |
| | | const noIssueOption = allOptions.find( |
| | | (item) => item.label === "无外观问题" || item.value === "无外观问题" |
| | | ); |
| | | |
| | | if (!noIssueOption) { |
| | | return selectedValues; |
| | | } |
| | | |
| | | const noIssueValue = String(noIssueOption.value); |
| | | const hasNoIssue = selectedValues.includes(noIssueValue); |
| | | const hadNoIssue = previousValues.includes(noIssueValue); |
| | | const isNewlySelectedNoIssue = !hadNoIssue && hasNoIssue; |
| | | const isSelectingOtherWithNoIssue = |
| | | hadNoIssue && hasNoIssue && selectedValues.length > previousValues.length; |
| | | |
| | | let result: string[]; |
| | | if (isNewlySelectedNoIssue) { |
| | | result = [noIssueValue]; |
| | | } else if (isSelectingOtherWithNoIssue) { |
| | | result = selectedValues.filter((val) => val !== noIssueValue); |
| | | } else { |
| | | result = selectedValues; |
| | | } |
| | | |
| | | return result; |
| | | }; |
| | | |
| | | // 处理外观选择变化 |
| | | const handleAppearanceChange = (optionValue: string, checked: boolean) => { |
| | | const currentValues = Array.isArray(props.formData.inspectionResult.appearance) |
| | | ? props.formData.inspectionResult.appearance |
| | | : []; |
| | | |
| | | let newValues: string[]; |
| | | if (checked) { |
| | | newValues = [...currentValues, optionValue]; |
| | | } else { |
| | | newValues = currentValues.filter((v: string) => v !== optionValue); |
| | | } |
| | | |
| | | const processedValues = handleAppearanceQualityChange( |
| | | newValues, |
| | | previousAppearanceValue.value, |
| | | props.appearanceOptions |
| | | ); |
| | | |
| | | props.formData.inspectionResult.appearance = JSON.parse(JSON.stringify(processedValues)); |
| | | previousAppearanceValue.value = JSON.parse(JSON.stringify(processedValues)); |
| | | }; |
| | | |
| | | const handleClose = () => { |
| | | emit("update:visible", false); |
| | | emit("close"); |
| | | }; |
| | | |
| | | const handleSubmit = () => { |
| | | // 验证单丝直径:最大值应该大于或等于最小值 |
| | | const maxDia = props.formData.inspectionResult.maxDia; |
| | | const minDia = props.formData.inspectionResult.minDia; |
| | | |
| | | if (maxDia !== null && minDia !== null && maxDia < minDia) { |
| | | uni.showToast({ |
| | | title: "单丝直径最大值不能小于最小值", |
| | | icon: "none", |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | // 验证外层铝线离侧板边缘距离 |
| | | const aluminumWireDistance = props.formData.inspectionResult.aluminumWireDistance; |
| | | if (aluminumWireDistance < 25) { |
| | | uni.showToast({ |
| | | title: "外层铝线离侧板边缘距离不能低于25mm", |
| | | icon: "none", |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | emit("submit", props.formData); |
| | | }; |
| | | |
| | | // 监听 visible 变化,初始化 previousAppearanceValue |
| | | watch( |
| | | () => props.visible, |
| | | (newVal) => { |
| | | if (newVal && props.formData?.inspectionResult?.appearance) { |
| | | previousAppearanceValue.value = JSON.parse( |
| | | JSON.stringify(props.formData.inspectionResult.appearance || []) |
| | | ); |
| | | } |
| | | } |
| | | ); |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .form_box { |
| | | .form-container { |
| | | max-height: 80vh; |
| | | display: flex; |
| | | flex-direction: column; |
| | | background: #fff; |
| | | border-radius: 12px 12px 0 0; |
| | | } |
| | | .submit_btn { |
| | | position: absolute; |
| | | bottom: 0; |
| | | width: 100%; |
| | | |
| | | .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; |
| | | } |
| | | |
| | | .section-title { |
| | | font-size: 14px; |
| | | font-weight: 700; |
| | | color: #252525; |
| | | margin: 16px 0 8px 0; |
| | | padding-bottom: 8px; |
| | | border-bottom: 1px solid #e6e6e6; |
| | | } |
| | | |
| | | .checkbox-group { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | gap: 12px; |
| | | } |
| | | |
| | | :deep(.wd-checkbox) { |
| | | margin-right: 0; |
| | | } |
| | | |
| | | .dialog-footer { |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | padding: 16px; |
| | | border-top: 1px solid #e6e6e6; |
| | | gap: 8px; |
| | | } |
| | | |
| | | .text-danger { |
| | | :deep(.wd-input-number__input) { |
| | | color: #f56c6c; |
| | | border-color: #f56c6c; |
| | | } |
| | | } |
| | | </style> |