1686 lines
53 KiB
Vue
1686 lines
53 KiB
Vue
<template>
|
||
<div>
|
||
<el-row :gutter="10">
|
||
<el-form ref="formRef" :model="localForm" label-width="140px" inline :rules="rules">
|
||
<el-row :gutter="10">
|
||
<el-form-item label="单据号" prop="busNo">
|
||
<el-input v-model="localForm.busNo" placeholder="" style="width: 220px" disabled />
|
||
</el-form-item>
|
||
<el-form-item label="开单日期" prop="applyTime">
|
||
<el-date-picker
|
||
v-model="localForm.applyTime"
|
||
placeholder="请选择开单日期"
|
||
type="datetime"
|
||
value-format="YYYY-MM-DD HH:mm:ss"
|
||
:disabled="!localIsAddOrEditOrder.isAddOrder && !localIsAddOrEditOrder.isEditOrder"
|
||
clearable
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="开单人" prop="applicantId">
|
||
<el-select
|
||
v-model="localForm.applicantId"
|
||
placeholder="请选择开单人"
|
||
style="width: 140px"
|
||
:disabled="!localIsAddOrEditOrder.isAddOrder && !localIsAddOrEditOrder.isEditOrder"
|
||
clearable
|
||
>
|
||
<el-option
|
||
v-for="item in props.practitionerOption || []"
|
||
:key="item.value"
|
||
:label="item.label"
|
||
:value="item.value"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="单据分类" prop="categoryEnum">
|
||
<el-select
|
||
v-model="localForm.categoryEnum"
|
||
placeholder="请选择单据分类"
|
||
style="width: 180px"
|
||
:disabled="!localIsAddOrEditOrder.isAddOrder && !localIsAddOrEditOrder.isEditOrder"
|
||
clearable
|
||
>
|
||
<el-option
|
||
v-for="item in props.supplyCategoryOptions || []"
|
||
:key="item.value"
|
||
:label="item.label"
|
||
:value="item.value"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="摘要(A)" prop="reason">
|
||
<el-input
|
||
type="textarea"
|
||
v-model="localForm.reason"
|
||
placeholder="请输入摘要"
|
||
style="width: 300px"
|
||
:rows="1"
|
||
:disabled="!localIsAddOrEditOrder.isAddOrder && !localIsAddOrEditOrder.isEditOrder"
|
||
clearable
|
||
/>
|
||
</el-form-item>
|
||
</el-row>
|
||
</el-form>
|
||
</el-row>
|
||
<!-- 审核信息 -->
|
||
<el-row :gutter="10">
|
||
<el-col :span="8">
|
||
<div class="form-item">
|
||
<label class="form-label">审核人</label>
|
||
<el-tag type="warning" plain>
|
||
{{
|
||
(props.practitionerOption || []).find(
|
||
(item) => item.value === localAuditForm.approverId
|
||
)?.label || '暂无'
|
||
}}
|
||
</el-tag>
|
||
</div>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<div class="form-item">
|
||
<label class="form-label">审核日期</label>
|
||
<el-tag type="primary" plain>
|
||
{{ parseTime(localAuditForm.approvalTime, '{y}-{m}-{d} {h}:{i}:{s}') || '暂无' }}
|
||
</el-tag>
|
||
</div>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<div class="form-item">
|
||
<label class="form-label">审核状态:</label>
|
||
<el-tag
|
||
:type="localAuditForm.statusEnum_enumText === '同意' ? 'success' : 'danger'"
|
||
plain
|
||
>
|
||
{{ localAuditForm.statusEnum_enumText || '暂无' }}
|
||
</el-tag>
|
||
</div>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row :gutter="10" class="mb8">
|
||
<el-col :span="1.5">
|
||
<el-button
|
||
type="primary"
|
||
plain
|
||
icon="Plus"
|
||
@click="handleAddRow"
|
||
v-if="buttonShow.isAddShow"
|
||
>
|
||
添加行
|
||
</el-button>
|
||
</el-col>
|
||
<el-col :span="1.5">
|
||
<el-button
|
||
type="danger"
|
||
plain
|
||
icon="Delete"
|
||
@click="handleDeleteRow"
|
||
v-if="buttonShow.isDeleteShow"
|
||
>
|
||
删除行
|
||
</el-button>
|
||
</el-col>
|
||
<el-col :span="1.5">
|
||
<el-button
|
||
type="warning"
|
||
plain
|
||
icon="Check"
|
||
@click="handleSave"
|
||
v-if="buttonShow.isSaveShow"
|
||
>
|
||
保存
|
||
</el-button>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<el-row :gutter="10">
|
||
<el-form ref="tableFormRef" :model="{ localTableData }" :rules="rules" style="width: 100%">
|
||
<el-table
|
||
:data="localTableData"
|
||
ref="tableRef"
|
||
class="table-container"
|
||
max-height="calc(100vh - 400px)"
|
||
min-height="100px"
|
||
@selection-change="handleSelectionChange"
|
||
@row-click="handleRowClick"
|
||
>
|
||
<el-table-column type="selection" width="55" align="center" />
|
||
<el-table-column prop="itemBusNo" label="编号" fixed width="180">
|
||
<template #default="scope">
|
||
<el-form-item
|
||
:prop="`localTableData.${scope.$index}.itemBusNo`"
|
||
:rules="rules.itemBusNo"
|
||
>
|
||
<span>
|
||
{{ localTableData[scope.$index].itemBusNo || '' }}
|
||
</span>
|
||
</el-form-item>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="itemName" label="品名" width="180">
|
||
<template #default="scope">
|
||
<el-form-item
|
||
:prop="`localTableData.${scope.$index}.itemName`"
|
||
:rules="rules.itemName"
|
||
>
|
||
<PopoverList
|
||
v-if="localTableData[scope.$index].isEditing"
|
||
@search="handleSearch"
|
||
:width="1300"
|
||
:modelValue="localTableData[scope.$index].itemName"
|
||
>
|
||
<template #popover-content="{}">
|
||
<medicineList
|
||
ref="medicineListRef"
|
||
@selectRow="(row) => selectRow(row, scope.$index)"
|
||
:searchKey="medicineSearchKey"
|
||
:locationId="localForm.locationId"
|
||
/>
|
||
</template>
|
||
</PopoverList>
|
||
<span v-else-if="localTableData[scope.$index].isViewing">
|
||
{{ localTableData[scope.$index].itemName || '' }}
|
||
</span>
|
||
</el-form-item>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="totalVolume" label="规格" width="140">
|
||
<template #default="scope">
|
||
<el-form-item
|
||
:prop="`localTableData.${scope.$index}.totalVolume`"
|
||
:rules="rules.totalVolume"
|
||
>
|
||
<span>
|
||
{{ localTableData[scope.$index].totalVolume || '' }}
|
||
</span>
|
||
</el-form-item>
|
||
</template>
|
||
</el-table-column>
|
||
<!-- 产品批号 -->
|
||
<el-table-column prop="lotNumber" label="产品批号" width="180">
|
||
<template #default="scope">
|
||
<el-form-item
|
||
:prop="`localTableData.${scope.$index}.lotNumber`"
|
||
:rules="rules.lotNumber"
|
||
>
|
||
<el-input
|
||
v-if="localTableData[scope.$index].isEditing"
|
||
v-model="localTableData[scope.$index].lotNumber"
|
||
clearable
|
||
placeholder="请输入产品批号"
|
||
style="width: 180px"
|
||
/>
|
||
<span v-else-if="localTableData[scope.$index].isViewing">
|
||
{{ localTableData[scope.$index].lotNumber || '' }}
|
||
</span>
|
||
</el-form-item>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="unitCode" label="单位" width="100">
|
||
<template #default="scope">
|
||
<el-form-item
|
||
:prop="`localTableData.${scope.$index}.unitCode`"
|
||
:rules="rules.unitCode"
|
||
>
|
||
<el-select
|
||
v-if="localTableData[scope.$index].isEditing"
|
||
v-model="localTableData[scope.$index].unitCode"
|
||
:disabled="!localTableData[scope.$index].unitCode"
|
||
@change="handleUnitCodeChange(localTableData[scope.$index])"
|
||
>
|
||
<el-option
|
||
v-for="item in localTableData[scope.$index].unitList || []"
|
||
:key="item.value"
|
||
:label="item.value_dictText"
|
||
:value="item.value"
|
||
/>
|
||
</el-select>
|
||
<span v-else-if="localTableData[scope.$index].isViewing">
|
||
{{ localTableData[scope.$index].unitCode_dictText || '' }}
|
||
</span>
|
||
</el-form-item>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
prop="itemQuantity"
|
||
label="现存数量"
|
||
width="120"
|
||
:rules="rules.itemQuantity"
|
||
>
|
||
<template #default="scope">
|
||
<el-form-item
|
||
:prop="`localTableData.${scope.$index}.itemQuantity`"
|
||
:rules="rules.itemQuantity"
|
||
>
|
||
<el-input-number
|
||
:min="0"
|
||
v-if="localTableData[scope.$index].isEditing"
|
||
v-model="localTableData[scope.$index].itemQuantity"
|
||
@change="handleItemQuantityChange(localTableData[scope.$index])"
|
||
controls-position="right"
|
||
/>
|
||
<span v-else-if="localTableData[scope.$index].isViewing">
|
||
{{ localTableData[scope.$index].itemQuantity || '' }}
|
||
</span>
|
||
</el-form-item>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="price" label="进货价" width="120">
|
||
<template #default="scope">
|
||
<el-form-item :prop="`localTableData.${scope.$index}.price`">
|
||
<span>
|
||
{{ getPriceDisplay(scope.$index, 'price') }}
|
||
</span>
|
||
</el-form-item>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="totalPrice" label="进价金额" width="100">
|
||
<template #default="scope">
|
||
<el-form-item :prop="`localTableData.${scope.$index}.totalPrice`">
|
||
<span>
|
||
{{ getPriceDisplay(scope.$index, 'totalPrice') }}
|
||
</span>
|
||
</el-form-item>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="retailPrice" label="当前销售价" width="120">
|
||
<template #default="scope">
|
||
<el-form-item
|
||
:prop="`localTableData.${scope.$index}.retailPrice`"
|
||
:rules="rules.retailPrice"
|
||
>
|
||
<span>
|
||
{{ getPriceDisplay(scope.$index, 'retailPrice') }}
|
||
</span>
|
||
</el-form-item>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="totalRetailPrice" label="当前销售金额" width="120">
|
||
<template #default="scope">
|
||
<el-form-item
|
||
:prop="`localTableData.${scope.$index}.totalRetailPrice`"
|
||
:rules="rules.totalRetailPrice"
|
||
>
|
||
<span>
|
||
{{ getPriceDisplay(scope.$index, 'totalRetailPrice') }}
|
||
</span>
|
||
</el-form-item>
|
||
</template>
|
||
</el-table-column>
|
||
<!-- 生产日期 -->
|
||
<el-table-column prop="startTime" label="生产日期" width="180">
|
||
<template #default="scope">
|
||
<el-form-item
|
||
:prop="`localTableData.${scope.$index}.startTime`"
|
||
:rules="rules.startTime"
|
||
>
|
||
<span>
|
||
{{ parseTime(localTableData[scope.$index].startTime, '{y}-{m}-{d}') || '' }}
|
||
</span>
|
||
</el-form-item>
|
||
</template>
|
||
</el-table-column>
|
||
<!-- 失效日期 -->
|
||
<el-table-column prop="endTime" label="失效日期" width="180">
|
||
<template #default="scope">
|
||
<el-form-item :prop="`localTableData.${scope.$index}.endTime`" :rules="rules.endTime">
|
||
<span>
|
||
{{ parseTime(localTableData[scope.$index].endTime, '{y}-{m}-{d}') || '' }}
|
||
</span>
|
||
</el-form-item>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="supplierId_dictText" label="供应商" width="220">
|
||
<template #default="scope">
|
||
<el-form-item
|
||
:prop="`localTableData.${scope.$index}.supplierId_dictText`"
|
||
:rules="rules.supplierId_dictText"
|
||
>
|
||
<span>
|
||
{{ localTableData[scope.$index].supplierId_dictText || '' }}
|
||
</span>
|
||
</el-form-item>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="manufacturerText" label="厂家/产地" width="220">
|
||
<template #default="scope">
|
||
<el-form-item
|
||
:prop="`localTableData.${scope.$index}.manufacturerText`"
|
||
:rules="rules.manufacturerText"
|
||
>
|
||
<span>
|
||
{{ localTableData[scope.$index].manufacturerText || '' }}
|
||
</span>
|
||
</el-form-item>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="specificationInventory" label="规格库存" width="100">
|
||
<template #default="scope">
|
||
<el-form-item
|
||
:prop="`localTableData.${scope.$index}.specificationInventory`"
|
||
:rules="rules.specificationInventory"
|
||
>
|
||
<span
|
||
v-if="
|
||
getInventoryDisplay(scope.$index, 'max') ||
|
||
getInventoryDisplay(scope.$index, 'maxUnit') ||
|
||
getInventoryDisplay(scope.$index, 'min') ||
|
||
getInventoryDisplay(scope.$index, 'minUnit')
|
||
"
|
||
>
|
||
<span>
|
||
{{ getInventoryDisplay(scope.$index, 'max') }}
|
||
</span>
|
||
<span>
|
||
{{ getInventoryDisplay(scope.$index, 'maxUnit') }}
|
||
</span>
|
||
<span>
|
||
{{ getInventoryDisplay(scope.$index, 'min') }}
|
||
</span>
|
||
<span>
|
||
{{ getInventoryDisplay(scope.$index, 'minUnit') }}
|
||
</span>
|
||
</span>
|
||
<span v-else>0</span>
|
||
</el-form-item>
|
||
</template>
|
||
</el-table-column>
|
||
<!-- 批次库存 -->
|
||
<el-table-column prop="batchInventory" label="批次库存" width="100">
|
||
<template #default="scope">
|
||
<el-form-item :prop="`localTableData.${scope.$index}.batchInventory`">
|
||
<span
|
||
v-if="
|
||
getInventoryDisplay(scope.$index, 'batchMax') ||
|
||
getInventoryDisplay(scope.$index, 'batchMaxUnit') ||
|
||
getInventoryDisplay(scope.$index, 'batchMin') ||
|
||
getInventoryDisplay(scope.$index, 'batchMinUnit')
|
||
"
|
||
>
|
||
<span>
|
||
{{ getInventoryDisplay(scope.$index, 'batchMax') }}
|
||
</span>
|
||
<span>
|
||
{{ getInventoryDisplay(scope.$index, 'batchMaxUnit') }}
|
||
</span>
|
||
<span>
|
||
{{ getInventoryDisplay(scope.$index, 'batchMin') }}
|
||
</span>
|
||
<span>
|
||
{{ getInventoryDisplay(scope.$index, 'batchMinUnit') }}
|
||
</span>
|
||
</span>
|
||
<span v-else> 0 </span>
|
||
</el-form-item>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="profitLoss" label="损益" width="100">
|
||
<template #default="scope">
|
||
<el-form-item>
|
||
<span
|
||
v-if="
|
||
getInventoryDisplay(scope.$index, 'batchMax') ||
|
||
getInventoryDisplay(scope.$index, 'batchMaxUnit') ||
|
||
getInventoryDisplay(scope.$index, 'batchMin') ||
|
||
getInventoryDisplay(scope.$index, 'batchMinUnit')
|
||
"
|
||
>
|
||
<span>
|
||
{{ localTableData[scope.$index].profitLoss }}
|
||
</span>
|
||
</span>
|
||
</el-form-item>
|
||
</template>
|
||
</el-table-column>
|
||
<!-- 药品追溯码 -->
|
||
<el-table-column prop="traceNo" label="药品追溯码" width="180">
|
||
<template #default="scope">
|
||
<el-form-item :prop="`localTableData.${scope.$index}.traceNo`" :rules="rules.traceNo">
|
||
<el-input
|
||
v-if="localTableData[scope.$index].isEditing"
|
||
v-model="localTableData[scope.$index].traceNo"
|
||
clearable
|
||
placeholder="请输入药品追溯码"
|
||
style="width: 180px"
|
||
/>
|
||
<span v-else-if="localTableData[scope.$index].isViewing">
|
||
{{ localTableData[scope.$index].traceNo || '' }}
|
||
</span>
|
||
</el-form-item>
|
||
</template>
|
||
</el-table-column>
|
||
<!-- 药品追溯码单位 -->
|
||
<el-table-column prop="traceNoUnitCode" label="药品追溯码单位" width="180">
|
||
<template #default="scope">
|
||
<el-form-item
|
||
:prop="`localTableData.${scope.$index}.traceNoUnitCode`"
|
||
:rules="rules.traceNoUnitCode"
|
||
>
|
||
<el-select
|
||
v-if="localTableData[scope.$index].isEditing"
|
||
v-model="localTableData[scope.$index].traceNoUnitCode"
|
||
placeholder="请选择药品追溯码单位"
|
||
style="width: 180px"
|
||
>
|
||
<el-option
|
||
v-for="item in localTableData[scope.$index].unitList || []"
|
||
:key="item.value"
|
||
:label="item.value_dictText"
|
||
:value="item.value"
|
||
/>
|
||
</el-select>
|
||
<span v-else-if="localTableData[scope.$index].isViewing">
|
||
{{ localTableData[scope.$index].traceNoUnitCode_dictText || '' }}
|
||
</span>
|
||
</el-form-item>
|
||
</template>
|
||
</el-table-column>
|
||
<!-- 备注 -->
|
||
<el-table-column prop="remake" label="备注" width="180">
|
||
<template #default="scope">
|
||
<el-form-item :prop="`localTableData.${scope.$index}.remake`">
|
||
<el-input
|
||
v-if="localTableData[scope.$index].isEditing"
|
||
v-model="localTableData[scope.$index].remake"
|
||
/>
|
||
<span v-else-if="localTableData[scope.$index].isViewing">
|
||
{{ localTableData[scope.$index].remake || '' }}
|
||
</span>
|
||
</el-form-item>
|
||
</template>
|
||
</el-table-column>
|
||
<!-- 操作 -->
|
||
<el-table-column label="操作" width="100" fixed="right">
|
||
<template #default="scope">
|
||
<el-button
|
||
type="primary"
|
||
@click="handleScan(scope.row, scope.$index)"
|
||
link
|
||
icon="Edit"
|
||
>
|
||
扫码
|
||
</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</el-form>
|
||
</el-row>
|
||
<el-row justify="end">
|
||
<el-pagination
|
||
:current-page="localForm.pageNo"
|
||
:page-size="localForm.pageSize"
|
||
:page-sizes="[10, 50, 100, 200]"
|
||
:small="small"
|
||
layout="total, sizes, prev, pager, next, jumper"
|
||
:total="localTableDataTotal"
|
||
@current-change="handleCurrentChange"
|
||
@size-change="handleSizeChange"
|
||
v-show="localTableDataTotal > 0"
|
||
/>
|
||
</el-row>
|
||
<!-- 扫码追溯码弹窗 -->
|
||
<TraceNoDialog
|
||
:ypName="ypName"
|
||
:rowData="rowData"
|
||
:openDialog="openTraceNoDialog"
|
||
@submit="submit"
|
||
@cancel="openTraceNoDialog = false"
|
||
/>
|
||
<!-- 订单对话框 -->
|
||
<orderDialog
|
||
ref="orderDialogRef"
|
||
:dialogVisible="dialogVisible"
|
||
@dialogSubmit="dialogSubmit"
|
||
@dialogCancel="dialogCancel"
|
||
@updateTableData="updateTableData"
|
||
></orderDialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { addOrEditOrder, getBusNo, getMedicineList } from './api';
|
||
import { nextTick, ref, watch } from 'vue';
|
||
import medicineList from './medicineList.vue';
|
||
import orderDialog from './orderDialog.vue';
|
||
import PopoverList from '@/components/OpenHis/popoverList/index.vue';
|
||
import { parseTime } from '@/utils/his';
|
||
import TraceNoDialog from '@/components/OpenHis/TraceNoDialog/index.vue';
|
||
|
||
// 获取当前实例
|
||
const { proxy } = getCurrentInstance();
|
||
// 调用父组件方法
|
||
const emit = defineEmits(['update:form', 'getList', 'updateButtonState', 'clearForm']);
|
||
|
||
// 属性
|
||
const props = defineProps({
|
||
// 父组件 表格数据
|
||
tableData: {
|
||
type: Array,
|
||
default: () => [],
|
||
},
|
||
// 父组件 表格总条数
|
||
total: {
|
||
type: Number,
|
||
default: 0,
|
||
},
|
||
// 父组件 表格每页条数
|
||
small: {
|
||
type: Boolean,
|
||
default: false,
|
||
},
|
||
// 父组件 表单数据
|
||
form: {
|
||
type: Object,
|
||
default: () => ({
|
||
busNo: undefined,
|
||
applyTime: undefined,
|
||
supplierId: undefined,
|
||
applicantId: undefined,
|
||
reason: undefined,
|
||
status: undefined,
|
||
approverId: undefined,
|
||
}),
|
||
},
|
||
// 父组件 订单编辑还是新增
|
||
isAddOrEditOrder: {
|
||
type: Object,
|
||
default: () => ({
|
||
isAddOrder: false,
|
||
isEditOrder: false,
|
||
}),
|
||
},
|
||
// 父组件 审核表单数据
|
||
auditForm: {
|
||
type: Object,
|
||
default: () => ({
|
||
approvalTime: undefined,
|
||
statusEnum_enumText: undefined,
|
||
approverId_dictText: undefined,
|
||
}),
|
||
},
|
||
// 查询供应商列表 supplierOption
|
||
supplierOption: {
|
||
type: Array,
|
||
default: () => [],
|
||
},
|
||
// 查询经手人列表 practitionerOption
|
||
practitionerOption: {
|
||
type: Array,
|
||
default: () => [],
|
||
},
|
||
// 单据分类 supplyCategoryOptions
|
||
supplyCategoryOptions: {
|
||
type: Array,
|
||
default: () => [],
|
||
},
|
||
// 包装情况 packagingConditionOptions
|
||
packagingConditionOptions: {
|
||
type: Array,
|
||
default: () => [],
|
||
},
|
||
// 验收结果 acceptanceResultoryOptions
|
||
acceptanceResultoryOptions: {
|
||
type: Array,
|
||
default: () => [],
|
||
},
|
||
// 请领部门
|
||
pharmacyListOptions: {
|
||
type: Array,
|
||
default: () => [],
|
||
},
|
||
// 按钮显示
|
||
buttonShow: {
|
||
type: Object,
|
||
default: () => ({
|
||
isAddShow: false,
|
||
isDeleteShow: false,
|
||
isSaveShow: false,
|
||
isEditShow: false,
|
||
isOrderImport: false,
|
||
}),
|
||
},
|
||
// 单据类型 supplyTypeOptions
|
||
supplyTypeOptions: {
|
||
type: Array,
|
||
default: () => [],
|
||
},
|
||
// 审批状态 supplyStatusOptions
|
||
supplyStatusOptions: {
|
||
type: Array,
|
||
default: () => [],
|
||
},
|
||
// 表格数据总条数
|
||
tableDataTotal: {
|
||
type: Number,
|
||
default: 0,
|
||
},
|
||
});
|
||
// 本地表单数据,用于接收 props.form
|
||
const localForm = ref({
|
||
pageNo: 1,
|
||
pageSize: 10,
|
||
});
|
||
// 本地表格数据 用于接收 props.tableData
|
||
const localTableData = ref([]);
|
||
// 本地表格数据总条数
|
||
const localTableDataTotal = ref(0);
|
||
|
||
// 加载
|
||
const loading = ref(false);
|
||
// 品名搜索
|
||
const medicineSearchKey = ref('');
|
||
// 选择相关变量
|
||
const ids = ref([]);
|
||
const selectedRows = ref([]);
|
||
const single = ref(true);
|
||
const multiple = ref(true);
|
||
|
||
// 审核表单数据
|
||
const localAuditForm = ref({
|
||
approvalTime: undefined,
|
||
statusEnum_enumText: undefined,
|
||
approverId_dictText: undefined,
|
||
});
|
||
// 订单编辑还是新增
|
||
const localIsAddOrEditOrder = ref({
|
||
isAddOrder: false,
|
||
isEditOrder: false,
|
||
});
|
||
// 验证规则
|
||
const rules = {
|
||
// busNo: [{ required: true, message: '请输入单据号', trigger: 'blur' }],
|
||
supplierId: [{ required: true, message: '请输入供应商', trigger: 'blur' }],
|
||
applicantId: [{ required: true, message: '请输入采购员', trigger: 'blur' }],
|
||
categoryEnum: [{ required: true, message: '请输入单据类型', trigger: 'blur' }],
|
||
applyTime: [{ required: true, message: '请输入开单日期', trigger: 'blur' }],
|
||
itemBusNo: [{ required: true, message: '请输入编号', trigger: ['blur', 'change'] }],
|
||
itemName: [{ required: true, message: '请输入品名', trigger: 'blur' }],
|
||
totalVolume: [{ required: true, message: '请输入规格', trigger: 'blur' }],
|
||
unitCode: [{ required: true, message: '请输入单位', trigger: 'blur' }],
|
||
itemQuantity: [{ required: true, message: '请输入现存数量', trigger: 'blur' }],
|
||
lotNumber: [{ required: true, message: '请输入产品批号', trigger: 'blur' }],
|
||
purposeLocationId: [{ required: true, message: '请选择', trigger: 'blur' }],
|
||
startTime: [
|
||
{ required: true, message: '请输入生产日期', trigger: 'blur' },
|
||
{
|
||
validator: (rule, value, callback) => {
|
||
if (value) {
|
||
const currentRow = rule.field.split('.')[1]; // 获取当前行索引
|
||
const rowIndex = parseInt(currentRow);
|
||
const endTime = localTableData.value[rowIndex]?.endTime;
|
||
|
||
if (endTime && value > endTime) {
|
||
callback(new Error('生产日期不能大于失效日期'));
|
||
} else {
|
||
callback();
|
||
}
|
||
} else {
|
||
callback();
|
||
}
|
||
},
|
||
trigger: ['blur', 'change'],
|
||
},
|
||
],
|
||
endTime: [
|
||
{ required: true, message: '请输入失效日期', trigger: 'blur' },
|
||
{
|
||
validator: (rule, value, callback) => {
|
||
if (value) {
|
||
const currentRow = rule.field.split('.')[1]; // 获取当前行索引
|
||
const rowIndex = parseInt(currentRow);
|
||
const startTime = localTableData.value[rowIndex]?.startTime;
|
||
|
||
if (startTime && value < startTime) {
|
||
callback(new Error('失效日期不能小于生产日期'));
|
||
} else {
|
||
callback();
|
||
}
|
||
} else {
|
||
callback();
|
||
}
|
||
},
|
||
trigger: ['blur', 'change'],
|
||
},
|
||
],
|
||
packagingConditionEnum: [{ required: true, message: '请输入包装情况', trigger: 'blur' }],
|
||
acceptanceResultEnum: [{ required: true, message: '请选择验收结果', trigger: 'blur' }],
|
||
batchInventory: [{ required: true, message: '请输入批次库存', trigger: 'blur' }],
|
||
traceNo: [{ required: true, message: '请输入药品追溯码', trigger: 'blur' }],
|
||
traceNoUnitCode: [{ required: true, message: '请输入药品追溯码单位', trigger: 'blur' }],
|
||
phone: [{ required: true, message: '请输入供应商联系人', trigger: 'blur' }],
|
||
practitionerId: [{ required: true, message: '请输入开单人', trigger: 'blur' }],
|
||
invoiceNo: [{ required: true, message: '请输入发票号', trigger: 'blur' }],
|
||
// price: [{ required: true, message: '请输入进货价', trigger: 'blur' }],
|
||
// totalPrice: [{ required: true, message: '请输入进价金额', trigger: 'blur' }],
|
||
// retailPrice: [{ required: true, message: '请输入销售价', trigger: 'blur' }],
|
||
// totalRetailPrice: [{ required: true, message: '请输入销售金额', trigger: 'blur' }],
|
||
manufacturerText: [{ required: true, message: '请输入厂家/产地', trigger: 'blur' }],
|
||
specificationInventory: [{ required: true, message: '请输入规格库存', trigger: 'blur' }],
|
||
approvalNumber: [{ required: true, message: '请输入批注文号', trigger: 'blur' }],
|
||
};
|
||
// 药品名称
|
||
const ypName = ref('');
|
||
// 药品追溯码
|
||
const rowData = ref({});
|
||
// 药品追溯码弹窗
|
||
const openTraceNoDialog = ref(false);
|
||
// 当前索引
|
||
const currentIndex = ref(-1);
|
||
|
||
// 订单组件对话框
|
||
const dialogVisible = ref(false);
|
||
// 计算属性:获取指定行的当前单位数据
|
||
const getCurrentUnitData = (rowIndex) => {
|
||
const row = localTableData.value[rowIndex];
|
||
if (!row || !row.unitList) return null;
|
||
|
||
return row.unitList.find((item) => item.value === row.unitCode) || null;
|
||
};
|
||
|
||
// 计算属性:获取指定行的价格显示值
|
||
const getPriceDisplay = (rowIndex, priceType) => {
|
||
const row = localTableData.value[rowIndex];
|
||
if (!row) return '';
|
||
|
||
const currentUnit = getCurrentUnitData(rowIndex);
|
||
|
||
// 根据价格类型返回对应的值
|
||
switch (priceType) {
|
||
case 'price':
|
||
return currentUnit?.priceMask ? parseFloat(currentUnit.priceMask).toFixed(2) : '';
|
||
case 'totalPrice':
|
||
return row.totalPriceMask || currentUnit?.totalPriceMask
|
||
? parseFloat(row.totalPriceMask || currentUnit?.totalPriceMask).toFixed(2)
|
||
: '';
|
||
case 'retailPrice':
|
||
return currentUnit?.retailPriceMask ? parseFloat(currentUnit.retailPriceMask).toFixed(2) : '';
|
||
case 'totalRetailPrice':
|
||
return row.totalRetailPriceMask || currentUnit?.totalRetailPriceMask
|
||
? parseFloat(row.totalRetailPriceMask || currentUnit?.totalRetailPriceMask).toFixed(2)
|
||
: '';
|
||
default:
|
||
return '';
|
||
}
|
||
};
|
||
// 计算属性:获取指定行的库存显示值
|
||
const getInventoryDisplay = (rowIndex, type) => {
|
||
const currentUnit = getCurrentUnitData(rowIndex);
|
||
if (!currentUnit) return '';
|
||
|
||
switch (type) {
|
||
case 'max':
|
||
return currentUnit.specificationInventoryMax || '';
|
||
case 'maxUnit':
|
||
return currentUnit.specificationInventoryMax > 0
|
||
? currentUnit.specificationInventoryMaxUnit
|
||
: '';
|
||
case 'min':
|
||
return currentUnit.specificationInventoryMin > 0 ? currentUnit.specificationInventoryMin : '';
|
||
case 'minUnit':
|
||
return currentUnit.specificationInventoryMin > 0
|
||
? currentUnit.specificationInventoryMinUnit
|
||
: '';
|
||
case 'batchMax':
|
||
return currentUnit.batchInventoryMax || '';
|
||
case 'batchMaxUnit':
|
||
return currentUnit.batchInventoryMax > 0 ? currentUnit.batchInventoryMaxUnit : '';
|
||
case 'batchMin':
|
||
return currentUnit.batchInventoryMin > 0 ? currentUnit.batchInventoryMin : '';
|
||
case 'batchMinUnit':
|
||
return currentUnit.batchInventoryMin > 0 ? currentUnit.batchInventoryMinUnit : '';
|
||
default:
|
||
return '';
|
||
}
|
||
};
|
||
// 监听 props.isAddOrEditOrder 的变化
|
||
watch(
|
||
() => props.isAddOrEditOrder,
|
||
(newVal) => {
|
||
localIsAddOrEditOrder.value = { ...newVal };
|
||
}
|
||
);
|
||
// 监听 props.form 的变化
|
||
watch(
|
||
() => props.form,
|
||
(newVal) => {
|
||
localForm.value = { ...newVal };
|
||
},
|
||
{ deep: true }
|
||
);
|
||
// 监听 props.tableData 的变化
|
||
watch(
|
||
() => props.tableData,
|
||
(newVal) => {
|
||
localTableData.value = [...newVal];
|
||
},
|
||
{ deep: true }
|
||
);
|
||
// 监听 props.tableDataTotal 的变化
|
||
watch(
|
||
() => props.tableDataTotal,
|
||
(newVal) => {
|
||
localTableDataTotal.value = newVal;
|
||
}
|
||
);
|
||
// 监听 props.auditForm 的变化
|
||
watch(
|
||
() => props.auditForm,
|
||
(newVal) => {
|
||
localAuditForm.value = { ...newVal };
|
||
},
|
||
{ deep: true }
|
||
);
|
||
|
||
// 品名搜索
|
||
const handleSearch = (value) => {
|
||
medicineSearchKey.value = value;
|
||
};
|
||
// 获取单据号
|
||
const getInitBusNo = async () => {
|
||
const res = await getBusNo();
|
||
return res.data.busNo;
|
||
};
|
||
// 扫码
|
||
const handleScan = (row, index) => {
|
||
// 判断是否存在产品批号
|
||
if (row.lotNumber) {
|
||
// 设置药品数据
|
||
rowData.value = row;
|
||
// 设置药品名称
|
||
ypName.value = row.name;
|
||
// 设置仓库
|
||
rowData.value.locationId = localForm.purposeLocationId;
|
||
// 设置药品类型
|
||
rowData.value.itemType = 1;
|
||
// 设置药品追溯码弹窗
|
||
openTraceNoDialog.value = true;
|
||
// 设置当前索引
|
||
currentIndex.value = index;
|
||
} else {
|
||
proxy.$message.warning('请先输入产品批号!');
|
||
}
|
||
};
|
||
// 药品追溯码提交
|
||
const submit = (value) => {
|
||
localTableData.value[currentIndex.value].traceNo = value;
|
||
openTraceNoDialog.value = false;
|
||
};
|
||
// 分页当前页
|
||
const handleCurrentChange = (page) => {
|
||
localForm.value.pageNo = page;
|
||
// 通知父组件更新查询参数并重新获取数据
|
||
emit('update:query-params', {
|
||
pageNo: page,
|
||
pageSize: localForm.value.pageSize,
|
||
});
|
||
};
|
||
|
||
// 分页每页条数
|
||
const handleSizeChange = (size) => {
|
||
localForm.value.pageSize = size;
|
||
localForm.value.pageNo = 1; // 切换每页条数时重置到第一页
|
||
// 通知父组件更新查询参数并重新获取数据
|
||
emit('update:query-params', {
|
||
pageNo: 1,
|
||
pageSize: size,
|
||
});
|
||
};
|
||
|
||
// 行点击
|
||
const handleRowClick = (row) => {
|
||
// 判断订单是否可以编辑
|
||
if (!isAllowEdit(row)) {
|
||
return;
|
||
}
|
||
// 设置表格编辑状态
|
||
row.isEditing = true;
|
||
// 设置表格查看状态
|
||
row.isViewing = false;
|
||
};
|
||
// 判断订单是否可以编辑
|
||
const isAllowEdit = (row) => {
|
||
// 已审批的订单不能编辑
|
||
if (
|
||
localAuditForm.value.statusEnum === 3 ||
|
||
localAuditForm.value.statusEnum_enumText === '同意'
|
||
) {
|
||
return false; // 已审批,不能编辑
|
||
}
|
||
return true; // 未审批,可以编辑
|
||
};
|
||
// 监听单位变化
|
||
const handleUnitCodeChange = (row) => {
|
||
const isMaxUnit = row.unitCode === row.unitList[0].value;
|
||
if (isMaxUnit) {
|
||
row.price = row.priceMaxUnit;
|
||
row.retailPrice = row.retailPriceMaxUnit;
|
||
} else {
|
||
row.price = row.priceMinUnit;
|
||
row.retailPrice = row.retailPriceMinUnit;
|
||
}
|
||
// 进价金额
|
||
row.totalPrice = row.price * row.itemQuantity;
|
||
row.totalPriceMask = row.price * row.itemQuantity;
|
||
// 销售金额
|
||
row.totalRetailPrice = row.retailPrice * row.itemQuantity;
|
||
row.totalRetailPriceMask = row.retailPrice * row.itemQuantity;
|
||
// 构建损益变化
|
||
buildProfitLoss(row);
|
||
};
|
||
// 监听数量变化
|
||
const handleItemQuantityChange = (row) => {
|
||
// 转换为数值并保留2位小数
|
||
const quantity = parseFloat(row.itemQuantity) || 0;
|
||
const price = parseFloat(row.price) || 0;
|
||
const retailPrice = parseFloat(row.retailPrice) || 0;
|
||
|
||
// 进价金额
|
||
row.totalPrice = parseFloat((quantity * price).toFixed(2));
|
||
row.totalPriceMask = parseFloat((quantity * price).toFixed(2));
|
||
// 销售金额
|
||
row.totalRetailPrice = parseFloat((quantity * retailPrice).toFixed(2));
|
||
row.totalRetailPriceMask = parseFloat((quantity * retailPrice).toFixed(2));
|
||
|
||
//构建损益变化
|
||
buildProfitLoss(row);
|
||
// console.log('handleItemQuantityChange', row);
|
||
};
|
||
// 构建损益变化
|
||
const buildProfitLoss = (item) => {
|
||
// 当前选中最大单位
|
||
if (item.unitCode != item.minUnitCode) {
|
||
if (item.itemQuantity * item.partPercent > item.batchInventory) {
|
||
item.profitLoss = '↑';
|
||
} else if (item.itemQuantity * item.partPercent == item.batchInventory) {
|
||
item.profitLoss = '-';
|
||
} else {
|
||
item.profitLoss = '↓';
|
||
}
|
||
} else {
|
||
if (item.itemQuantity > item.batchInventory) {
|
||
item.profitLoss = '↑';
|
||
} else if (item.itemQuantity == item.batchInventory) {
|
||
item.profitLoss = '-';
|
||
} else {
|
||
item.profitLoss = '↓';
|
||
}
|
||
}
|
||
};
|
||
// 监听进货价数量变化
|
||
const handleItemPriceChange = (row) => {
|
||
// 进价金额
|
||
row.totalPrice = parseFloat((row.itemQuantity * row.price).toFixed(2));
|
||
// 进价金额(假)
|
||
row.totalPriceMask = parseFloat((row.itemQuantity * row.price).toFixed(2));
|
||
};
|
||
// 监听销售价数量变化
|
||
const handleItemRetailPriceChange = (row) => {
|
||
// 销售金额
|
||
row.totalRetailPrice = parseFloat((row.itemQuantity * row.retailPrice).toFixed(2));
|
||
// 销售金额(假)
|
||
row.totalRetailPriceMask = parseFloat((row.itemQuantity * row.retailPrice).toFixed(2));
|
||
};
|
||
// 选择药品
|
||
const selectRow = (rowValue, index) => {
|
||
localTableData.value[index] = {
|
||
// 选中行药品数据
|
||
...rowValue,
|
||
// 药品 id
|
||
itemId: rowValue.id,
|
||
// 药品编号
|
||
itemBusNo: rowValue.busNo,
|
||
// 药品名称
|
||
itemName: rowValue.name,
|
||
// 单位
|
||
unitCode: rowValue.unitCode,
|
||
// 单位名称
|
||
unitCodeDictText: rowValue.unitCode_dictText,
|
||
// 备注
|
||
remake: rowValue.remake,
|
||
// 规格库存最大值
|
||
specificationInventoryMax: rowValue.specificationInventory,
|
||
// 批次库存最大值
|
||
batchInventoryMax: rowValue.batchInventory,
|
||
// 只用于显示
|
||
// 编辑状态
|
||
isEditing: true,
|
||
// 查看状态
|
||
isViewing: false,
|
||
// 包装情况
|
||
packagingConditionEnum: 1,
|
||
// 验收结果
|
||
acceptanceResultEnum: 1,
|
||
// 生产日期
|
||
startTime: parseTime(rowValue.productionDate, '{y}-{m}-{d}'),
|
||
// 失效日期
|
||
endTime: parseTime(rowValue.expirationDate, '{y}-{m}-{d}'),
|
||
};
|
||
// 重新构建价格单位 规格库存 进价 售价表格数据
|
||
rebuildTableData(localTableData.value[index]);
|
||
// 手动触发验证
|
||
nextTick(() => {
|
||
proxy.$refs.tableFormRef.validateField(`localTableData.${index}.itemBusNo`);
|
||
proxy.$refs.tableFormRef.validateField(`localTableData.${index}.itemName`);
|
||
proxy.$refs.tableFormRef.validateField(`localTableData.${index}.totalVolume`);
|
||
proxy.$refs.tableFormRef.validateField(`localTableData.${index}.unitCode`);
|
||
// proxy.$refs.tableFormRef.validateField(`localTableData.${index}.price`);
|
||
// proxy.$refs.tableFormRef.validateField(`localTableData.${index}.retailPrice`);
|
||
proxy.$refs.tableFormRef.validateField(`localTableData.${index}.manufacturerText`);
|
||
proxy.$refs.tableFormRef.validateField(`localTableData.${index}.specificationInventory`);
|
||
proxy.$refs.tableFormRef.validateField(`localTableData.${index}.approvalNumber`);
|
||
});
|
||
};
|
||
// 重新构建价格单位 规格库存 进价 售价表格数据
|
||
const rebuildTableData = (row) => {
|
||
// 构建单位列表
|
||
buildUnitList(row);
|
||
// 构建进货价和销售价
|
||
buildPrice(row);
|
||
};
|
||
// 构建进货价和销售价
|
||
const buildPrice = (item) => {
|
||
// 判断当前单位是最大单位还是最小单位
|
||
const isMaxUnit = item.unitCode === item.unitList[0].value;
|
||
if (isMaxUnit) {
|
||
// 进货价
|
||
item.price = item.price;
|
||
item.priceMaxUnit = item.price;
|
||
item.priceMinUnit = item.price / parseInt(item.partPercent);
|
||
|
||
// 销售价
|
||
item.retailPrice = item.retailPrice;
|
||
item.retailPriceMaxUnit = item.retailPrice;
|
||
item.retailPriceMinUnit = (parseFloat(item.retailPrice) / parseInt(item.partPercent)).toFixed(
|
||
2
|
||
);
|
||
} else {
|
||
// 进货价
|
||
item.price = item.price;
|
||
item.priceMaxUnit = parseFloat((item.price * parseInt(item.partPercent)).toFixed(2));
|
||
item.priceMinUnit = item.price;
|
||
|
||
// 销售价
|
||
item.retailPrice = item.retailPrice;
|
||
item.retailPriceMaxUnit = parseFloat(
|
||
(item.retailPrice * parseInt(item.partPercent)).toFixed(2)
|
||
);
|
||
item.retailPriceMinUnit = item.retailPrice;
|
||
}
|
||
};
|
||
// 构建单位列表
|
||
const buildUnitList = (row) => {
|
||
// 单位列表
|
||
(row.unitList || []).forEach((item) => {
|
||
// 最大单位
|
||
if (item.value === row.unitCode) {
|
||
// 假数据 只做显示用 不参与计算 用于显示
|
||
// 进货价(假)
|
||
item.priceMask = row.price;
|
||
// 销售价(假)
|
||
item.retailPriceMask = row.retailPrice;
|
||
|
||
// 进价金额(假)
|
||
item.totalPriceMask = row.totalPrice;
|
||
// 销售金额(假)
|
||
item.totalRetailPriceMask = row.totalRetailPrice;
|
||
|
||
// 规格库存
|
||
item.specificationInventoryOriginal = row.specificationInventory;
|
||
// 规格库存最大值
|
||
item.specificationInventoryMax = Math.floor(row.specificationInventory / row.partPercent);
|
||
// 规格库存最小智
|
||
item.specificationInventoryMin = row.specificationInventory % row.partPercent;
|
||
// 规格库在最大单位
|
||
item.specificationInventoryMaxUnit = row.unitCode_dictText;
|
||
// 规格库存最小单位
|
||
item.specificationInventoryMinUnit = row.minUnitCode_dictText;
|
||
|
||
// 批次库存
|
||
item.batchInventoryOriginal = row.batchInventory;
|
||
// 批次库存最大值
|
||
item.batchInventoryMax = Math.floor(row.batchInventory / row.partPercent);
|
||
// 批次库存最小值
|
||
item.batchInventoryMin = row.batchInventory % row.partPercent;
|
||
// 批次库存最大单位
|
||
item.batchInventoryMaxUnit = row.unitCode_dictText;
|
||
// 批次库存最小单位
|
||
item.batchInventoryMinUnit = row.minUnitCode_dictText;
|
||
} else {
|
||
// 最小单位
|
||
// 假数据 只做显示用 不参与计算 用于显示
|
||
// 进货价(假)
|
||
item.priceMask = row.price / row.partPercent;
|
||
// 销售价(假)
|
||
item.retailPriceMask = (parseFloat(row.retailPrice) / parseFloat(row.partPercent)).toFixed(2);
|
||
|
||
// 进价金额(假)
|
||
item.totalPriceMask = row.totalPrice;
|
||
// 销售金额(假)
|
||
item.totalRetailPriceMask = row.totalRetailPrice;
|
||
|
||
// 规格库存
|
||
item.specificationInventoryOriginal = row.specificationInventory;
|
||
// 规格库存最大
|
||
item.specificationInventoryMin = row.specificationInventory;
|
||
// 规格库存最大单位
|
||
item.specificationInventoryMinUnit = row.minUnitCode_dictText;
|
||
|
||
// 批次库存
|
||
item.batchInventoryOriginal = row.batchInventory;
|
||
// 批次库存最大
|
||
item.batchInventoryMin = row.batchInventory;
|
||
// 批次库存最大单位
|
||
item.batchInventoryMinUnit = row.minUnitCode_dictText;
|
||
}
|
||
});
|
||
};
|
||
// 校验是否有空行
|
||
const isEmptyRow = () => {
|
||
// 如果 localTableData的长度大于 1 时在判断否有空行
|
||
if (!localTableData.value) {
|
||
return true;
|
||
}
|
||
return localTableData.value.some((row) => !row.itemId || !row.itemQuantity || !row.itemName);
|
||
};
|
||
// 新增一个空行
|
||
const addEmptyRow = () => {
|
||
localTableData.value.push({
|
||
// 单据号
|
||
busNo: localForm.value.busNo,
|
||
// 开单日期
|
||
applyTime: localForm.value.applyTime,
|
||
// 采购员
|
||
applicantId: localForm.value.applicantId,
|
||
// 摘要
|
||
reason: localForm.value.reason,
|
||
// 单据分类
|
||
categoryEnum: localForm.value.categoryEnum,
|
||
// 供应商
|
||
supplierId: localForm.value.supplierId,
|
||
// 仓库
|
||
purposeLocationId: localForm.value.locationId,
|
||
// 表格需要的字段
|
||
itemBusNo: '',
|
||
// 药品 id
|
||
itemId: '',
|
||
// 品名
|
||
itemName: '',
|
||
// 规格
|
||
totalVolume: '',
|
||
// 单位
|
||
unitCode: '',
|
||
// 数量
|
||
itemQuantity: 0,
|
||
// 进货价
|
||
price: '',
|
||
// 进价金额
|
||
totalPrice: '',
|
||
// 销售价
|
||
retailPrice: '',
|
||
// 销售金额
|
||
totalRetailPrice: '',
|
||
// 生产厂家
|
||
manufacturerText: '',
|
||
// 规格库存
|
||
specificationInventory: '',
|
||
// 批注文号
|
||
approvalNumber: '',
|
||
// 验收结果
|
||
acceptanceResultEnum: 1,
|
||
// 包装情况
|
||
packagingConditionEnum: 1,
|
||
// 备注
|
||
remake: '',
|
||
// 编辑状态
|
||
isEditing: true,
|
||
// 查看状态
|
||
isViewing: false,
|
||
});
|
||
nextTick(() => {
|
||
// 处理本地按钮状态
|
||
emit('updateButtonState', {
|
||
// 审核 按钮禁用
|
||
isAuditDisabled: true,
|
||
// 取消 按钮禁用
|
||
isCancelDisabled: false,
|
||
// 删除 按钮禁用
|
||
isDeleteDisabled: true,
|
||
// 添加 按钮禁用
|
||
isAddDisabled: true,
|
||
// 编辑 按钮禁用
|
||
isEditDisabled: true,
|
||
// 添加行 按钮显示
|
||
isAddShow: true,
|
||
// 删除行 按钮显示
|
||
isDeleteShow: true,
|
||
// 保存行 按钮显示
|
||
isSaveShow: true,
|
||
// 编辑行 按钮显示
|
||
isEditShow: true,
|
||
// 警戒订货 按钮显示
|
||
isOrderImport: true,
|
||
});
|
||
});
|
||
};
|
||
// 添加行
|
||
const handleAddRow = async () => {
|
||
// 验证表单
|
||
const formValid = await validateFormRef();
|
||
if (!formValid) {
|
||
return;
|
||
}
|
||
// 如果当前没有数据,直接添加空行
|
||
if (!localTableData.value || localTableData.value.length === 0) {
|
||
// 确保 localTableData 存在
|
||
if (!localTableData.value) {
|
||
localTableData.value = [];
|
||
}
|
||
// 添加一个包含所有字段的空对象
|
||
addEmptyRow();
|
||
|
||
return;
|
||
}
|
||
|
||
// 如果有数据,检查是否有空行
|
||
if (isEmptyRow()) {
|
||
proxy.$message.error('请填写完整信息');
|
||
return;
|
||
}
|
||
|
||
// 添加一个包含所有字段的空对象
|
||
addEmptyRow();
|
||
};
|
||
|
||
// 验证表单
|
||
const validateFormRef = () => {
|
||
return new Promise((resolve) => {
|
||
proxy.$refs.formRef.validate((valid) => {
|
||
resolve(valid);
|
||
});
|
||
});
|
||
};
|
||
|
||
// 验证表格
|
||
const validateTableFormRef = () => {
|
||
if (!localTableData.value || localTableData.value.length === 0) {
|
||
return false;
|
||
}
|
||
return new Promise((resolve) => {
|
||
proxy.$refs.tableFormRef.validate((valid) => {
|
||
resolve(valid);
|
||
});
|
||
});
|
||
};
|
||
|
||
// 保存行
|
||
const handleSave = async () => {
|
||
// 验证表单头部
|
||
const formValid = await validateFormRef();
|
||
if (!formValid) {
|
||
return;
|
||
}
|
||
if (!formValid) {
|
||
return;
|
||
}
|
||
|
||
// 验证表格数据
|
||
const tableValid = await validateTableFormRef();
|
||
|
||
if (!tableValid) {
|
||
return;
|
||
}
|
||
|
||
// 保存当前数据状态,防止在确认过程中被修改
|
||
const currentTableData = JSON.parse(JSON.stringify(localTableData.value));
|
||
const currentFormData = JSON.parse(JSON.stringify(localForm.value));
|
||
|
||
// 是否确认保存数据
|
||
const isConfirm = await proxy.$modal.confirm('确认保存数据吗?', '提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning',
|
||
});
|
||
if (!isConfirm) {
|
||
return;
|
||
}
|
||
|
||
// 加载中
|
||
loading.value = true;
|
||
// 使用保存的数据状态重构数据
|
||
const editData = await buildEditForm(currentTableData, currentFormData);
|
||
|
||
// 判断是新增还是编辑
|
||
if (localIsAddOrEditOrder.value.isAddOrder) {
|
||
addOrEditOrder(editData).then((res) => {
|
||
if (res.code === 200) {
|
||
proxy.$message.success('新增成功');
|
||
// 调用父组件的 getList 方法
|
||
emit('getList');
|
||
// 清空表单
|
||
resetAllData();
|
||
// 关闭加载
|
||
loading.value = false;
|
||
}
|
||
});
|
||
} else if (localIsAddOrEditOrder.value.isEditOrder) {
|
||
addOrEditOrder(editData).then((res) => {
|
||
if (res.code === 200) {
|
||
proxy.$message.success('保存成功');
|
||
// 调用父组件的 getList 方法
|
||
emit('getList');
|
||
// 清空表单
|
||
resetAllData();
|
||
} else {
|
||
proxy.$message.error('保存失败');
|
||
}
|
||
// 关闭加载
|
||
loading.value = false;
|
||
});
|
||
}
|
||
};
|
||
// 重构数据
|
||
const buildEditForm = async (data, formData = null) => {
|
||
const formDataCopy = [...data];
|
||
// 获取单据号
|
||
let busNo = '';
|
||
if (localIsAddOrEditOrder.value.isAddOrder) {
|
||
busNo = await getInitBusNo();
|
||
} else {
|
||
busNo = data[0].busNo;
|
||
}
|
||
// 订单数据
|
||
const orderData = data[0];
|
||
// 使用传入的表单数据,如果没有则使用当前的localForm
|
||
const currentForm = formData || localForm.value;
|
||
// 表格数据
|
||
formDataCopy.forEach((item) => {
|
||
// 单据号
|
||
item.busNo = busNo;
|
||
// 开单日期
|
||
item.applyTime = currentForm.applyTime;
|
||
// 采购员
|
||
item.applicantId = currentForm.applicantId;
|
||
// 单据分类
|
||
item.categoryEnum = currentForm.categoryEnum;
|
||
// 摘要
|
||
item.reason = currentForm.reason;
|
||
// 仓库
|
||
item.purposeLocationId = orderData.purposeLocationId
|
||
? orderData.purposeLocationId
|
||
: currentForm.locationId;
|
||
// 开单人
|
||
item.practitionerId = currentForm.practitionerId;
|
||
// 请领部门
|
||
item.purposeLocationId = currentForm.purposeLocationId;
|
||
});
|
||
// 重构数据
|
||
return formDataCopy;
|
||
};
|
||
// 清空表单
|
||
const resetAllData = () => {
|
||
// 清空表单数据
|
||
localForm.value = {};
|
||
|
||
// 清空审核表单数据
|
||
localAuditForm.value = {};
|
||
|
||
// 清空表格数据
|
||
localTableData.value = [];
|
||
|
||
// 重置订单状态
|
||
localIsAddOrEditOrder.value = {
|
||
isAddOrder: false,
|
||
isEditOrder: false,
|
||
};
|
||
|
||
// 重置按钮状态为初始状态
|
||
emit('updateButtonState', {
|
||
// 审核 按钮禁用
|
||
isAuditDisabled: true,
|
||
// 取消 按钮禁用
|
||
isCancelDisabled: true,
|
||
// 删除 按钮禁用
|
||
isDeleteDisabled: true,
|
||
// 添加 按钮禁用
|
||
isAddDisabled: false,
|
||
// 编辑 按钮禁用
|
||
isEditDisabled: true,
|
||
// 添加行 按钮显示
|
||
isAddShow: false,
|
||
// 删除行 按钮显示
|
||
isDeleteShow: false,
|
||
// 保存行 按钮显示
|
||
isSaveShow: false,
|
||
// 编辑行 按钮显示
|
||
isEditShow: false,
|
||
});
|
||
};
|
||
// 删除行
|
||
const handleDeleteRow = () => {
|
||
if (selectedRows.value.length === 0) {
|
||
proxy.$message.warning('请选择要删除的行');
|
||
return;
|
||
}
|
||
|
||
proxy
|
||
.$confirm('确认删除选中的行吗?', '提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning',
|
||
})
|
||
.then(() => {
|
||
// 从 tableData 中删除选中的行
|
||
const selectedIndexes = [];
|
||
|
||
// 获取选中行在 localTableData 中的索引
|
||
selectedRows.value.forEach((selectedRow) => {
|
||
const index = localTableData.value.findIndex(
|
||
(row) => row.itemBusNo === selectedRow.itemBusNo && row.itemName === selectedRow.itemName
|
||
);
|
||
if (index !== -1) {
|
||
selectedIndexes.push(index);
|
||
}
|
||
});
|
||
|
||
// 按索引从大到小排序,避免删除时索引变化的问题
|
||
selectedIndexes.sort((a, b) => b - a);
|
||
|
||
// 删除选中的行
|
||
selectedIndexes.forEach((index) => {
|
||
localTableData.value.splice(index, 1);
|
||
});
|
||
|
||
// 清空选择
|
||
selectedRows.value = [];
|
||
ids.value = [];
|
||
|
||
// 如果删除后没有数据了,更新按钮状态
|
||
if (localTableData.value.length === 0) {
|
||
emit('updateButtonState', {
|
||
// 审核 按钮禁用
|
||
isAuditDisabled: true,
|
||
// 取消 按钮禁用
|
||
isCancelDisabled: true,
|
||
// 删除 按钮禁用
|
||
isDeleteDisabled: true,
|
||
// 添加 按钮禁用
|
||
isAddDisabled: false,
|
||
// 编辑 按钮禁用
|
||
isEditDisabled: true,
|
||
// 添加行 按钮显示
|
||
isAddShow: true,
|
||
// 删除行 按钮显示
|
||
isDeleteShow: true,
|
||
// 保存行 按钮显示
|
||
isSaveShow: true,
|
||
// 编辑行 按钮显示
|
||
isEditShow: false,
|
||
// 警戒订货 按钮显示
|
||
isOrderImport: true,
|
||
});
|
||
}
|
||
|
||
proxy.$message.success('删除成功');
|
||
})
|
||
.catch(() => {
|
||
// 用户取消删除
|
||
});
|
||
};
|
||
|
||
// 日期范围验证函数
|
||
const validateDateRange = (rowIndex) => {
|
||
const row = localTableData.value[rowIndex];
|
||
if (row && row.startTime && row.endTime) {
|
||
if (row.endTime < row.startTime) {
|
||
proxy.$message.error('失效日期不能小于生产日期');
|
||
// 清空失效日期
|
||
row.endTime = '';
|
||
}
|
||
}
|
||
};
|
||
|
||
// 选择变化处理
|
||
const handleSelectionChange = (selection) => {
|
||
ids.value = selection.map((item) => item.id);
|
||
selectedRows.value = selection;
|
||
single.value = selection.length != 1;
|
||
multiple.value = !selection.length;
|
||
};
|
||
|
||
// 更新表格数据
|
||
const updateTableData = (updateValue) => {
|
||
// 更新表格数据
|
||
localTableData.value = localTableData.value.concat(updateValue.currentOrderList);
|
||
// 更新表单数据 - 合并数据而不是替换
|
||
localForm.value = { ...localForm.value, ...updateValue.currentOrderForm };
|
||
|
||
// 更新按钮状态
|
||
emit('updateButtonState', {
|
||
// 审核 按钮禁用
|
||
isAuditDisabled: true,
|
||
// 取消 按钮禁用
|
||
isCancelDisabled: true,
|
||
// 删除 按钮禁用
|
||
isDeleteDisabled: true,
|
||
// 添加 按钮禁用
|
||
isAddDisabled: false,
|
||
// 编辑 按钮禁用
|
||
isEditDisabled: true,
|
||
// 添加行 按钮显示
|
||
isAddShow: true,
|
||
// 删除行 按钮显示
|
||
isDeleteShow: true,
|
||
// 保存行 按钮显示
|
||
isSaveShow: true,
|
||
// 编辑行 按钮显示
|
||
isEditShow: false,
|
||
// 警戒订货 按钮显示
|
||
isOrderImport: true,
|
||
});
|
||
};
|
||
|
||
// 对话框提交
|
||
const dialogSubmit = (value) => {
|
||
//对话框关闭
|
||
dialogVisible.value = value.dialogVisible;
|
||
};
|
||
// 对话框取消
|
||
const dialogCancel = (value) => {
|
||
//对话框关闭
|
||
dialogVisible.value = value.dialogVisible;
|
||
};
|
||
// 订货单导入
|
||
const handleOrderImport = async () => {
|
||
// 对话框显示
|
||
dialogVisible.value = true;
|
||
// 获取订单列表
|
||
await proxy.$refs.orderDialogRef.getOrderList(localForm.value.locationId);
|
||
};
|
||
|
||
// 组件名称
|
||
defineOptions({ name: 'orderTable' });
|
||
// 暴露方法给父组件
|
||
defineExpose({
|
||
resetAllData,
|
||
});
|
||
</script>
|
||
|
||
<style scoped>
|
||
/* 表格中的表单项样式 */
|
||
.table-form-item {
|
||
margin-bottom: 0 !important;
|
||
display: block !important;
|
||
}
|
||
|
||
/* 确保表格行有足够的高度显示错误信息 */
|
||
.el-table .el-table__row {
|
||
min-height: 100px;
|
||
}
|
||
|
||
/* 表格单元格样式 */
|
||
.el-table .el-table__cell {
|
||
padding-bottom: 25px;
|
||
}
|
||
|
||
/* 输入框样式 */
|
||
.el-table .el-input {
|
||
width: 100%;
|
||
}
|
||
|
||
/* 确保表格占满容器宽度 */
|
||
.el-table {
|
||
width: 100% !important;
|
||
}
|
||
|
||
/* 确保表格容器占满宽度 */
|
||
.el-form {
|
||
width: 100%;
|
||
}
|
||
|
||
/* 确保行容器占满宽度 */
|
||
.el-row {
|
||
width: 100%;
|
||
}
|
||
|
||
/* 自定义表单项样式 */
|
||
.form-item {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 18px;
|
||
}
|
||
|
||
.form-label {
|
||
width: 100px;
|
||
text-align: right;
|
||
padding-right: 12px;
|
||
font-size: 14px;
|
||
color: #606266;
|
||
line-height: 40px;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
/* 强制显示错误信息 */
|
||
.el-form-item__error {
|
||
position: static !important;
|
||
visibility: visible !important;
|
||
opacity: 1 !important;
|
||
display: block !important;
|
||
margin-top: 2px !important;
|
||
font-size: 12px !important;
|
||
color: #f56c6c !important;
|
||
}
|
||
|
||
/* 确保表单项内容正确显示 */
|
||
.el-form-item__content {
|
||
display: block !important;
|
||
width: 100% !important;
|
||
}
|
||
|
||
/* 表格单元格内容样式 */
|
||
.el-table .cell {
|
||
padding: 8px 0;
|
||
}
|
||
.table-container {
|
||
width: 100%;
|
||
}
|
||
</style> |