版本更新
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
// 药库订货单初始化
|
||||
export function getInit () {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/documentManagement/init',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
// 订货单单据列表:显示所有单据 左边框
|
||||
export function getOrderList (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/documentManagement/documentManagement-page',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,337 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-row :gutter="10">
|
||||
<el-form ref="queryRef" :model="queryParams" label-width="100px" :inline="true">
|
||||
<!-- 库房类型 -->
|
||||
<el-form-item label="库房类型" prop="locationTypeEnum">
|
||||
<el-select
|
||||
v-model="queryParams.locationTypeEnum"
|
||||
placeholder="请选择库房类型"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
filterable
|
||||
@change="getList"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in warehouseTypeOption || []"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 库房 -->
|
||||
<el-form-item label="库房" prop="locationId">
|
||||
<el-select
|
||||
v-model="queryParams.locationId"
|
||||
placeholder="请选择库房"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
:disabled="!queryParams.locationTypeEnum"
|
||||
@change="getList"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in currentLocationOptions"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- 单据类型 -->
|
||||
<el-form-item label="单据类型" prop="typeEnum">
|
||||
<el-select
|
||||
v-model="queryParams.typeEnum"
|
||||
placeholder="请选择单据类型"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
:disabled="!queryParams.locationTypeEnum"
|
||||
@change="getList"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in currentOrderOptions"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
:key="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="单据状态" prop="statusEnum">
|
||||
<el-select
|
||||
v-model="queryParams.statusEnum"
|
||||
placeholder="请选择单据类型"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
@change="getList"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in supplyStatusOptions"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
:key="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- 制单日期 -->
|
||||
<el-form-item label="制单日期" prop="orderDate">
|
||||
<el-date-picker
|
||||
v-model="orderDateRange"
|
||||
type="daterange"
|
||||
clearable
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 审核日期 -->
|
||||
<el-form-item label="审核日期" prop="approvalDate">
|
||||
<el-date-picker
|
||||
v-model="auditDateRange"
|
||||
type="daterange"
|
||||
clearable
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
<el-table :data="orderList" v-loading="loading" style="width: 100%">
|
||||
<el-table-column label="订单编号" prop="supplyBusNo" align="center" />
|
||||
<el-table-column label="申请人" prop="applicantId_dictText" align="center" />
|
||||
<el-table-column label="申请时间" prop="applyTime" align="center" />
|
||||
<el-table-column label="批准时间" prop="approvalTime" align="center" />
|
||||
<el-table-column label="批准人" prop="approverId_dictText" align="center" />
|
||||
<el-table-column label="仓库" prop="locationId_dictText" align="center" />
|
||||
<el-table-column label="状态" prop="statusEnum_enumText" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag :type="statusEnumTagOptions[scope.row.statusEnum]?.type || 'info'">
|
||||
{{ scope.row.statusEnum_enumText }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="供应商" prop="supplierId_dictText" align="center" />
|
||||
<el-table-column label="单据类型" prop="typeEnum_enumText" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag :type="typeEnumTagOptions[scope.row.typeEnum]?.type || 'info'">
|
||||
{{ scope.row.typeEnum_enumText }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="180">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
icon="View"
|
||||
@click="handleView(scope.row)"
|
||||
v-if="isTypeEnumTagOptions(scope.row.typeEnum)"
|
||||
>查看</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNo"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, computed, watch } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { getInit, getOrderList } from './components/api';
|
||||
import useUserStore from '@/store/modules/user';
|
||||
import { parseTime } from '@/utils/openhis';
|
||||
const router = useRouter();
|
||||
// 制单日期
|
||||
const orderDateRange = ref([]);
|
||||
// 审核日期
|
||||
const auditDateRange = ref([]);
|
||||
// 查询参数
|
||||
const queryParams = ref({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
locationTypeEnum: null,
|
||||
typeEnum: null,
|
||||
locationId: null,
|
||||
});
|
||||
// tag列表
|
||||
const typeEnumTagOptions = ref({
|
||||
13: { value: 13, label: '采购订货', type: 'primary' },
|
||||
1: { value: 1, label: '采购入库', type: 'success' },
|
||||
5: { value: 5, label: '采购退货', type: 'danger' },
|
||||
7: { value: 7, label: '领用出库', type: 'warning' },
|
||||
9: { value: 9, label: '领用退货', type: 'success' },
|
||||
6: { value: 6, label: '报损单', type: 'info' },
|
||||
4: { value: 4, label: '商品盘点', type: 'warning' },
|
||||
// 2: { value: 2, label: '商品调拨', type: 'info' },
|
||||
});
|
||||
// tag列表
|
||||
const statusEnumTagOptions = ref({
|
||||
1: { value: 1, label: '待审核', type: 'warning' },
|
||||
2: { value: 2, label: '审核中', type: 'primary' },
|
||||
3: { value: 3, label: '同意', type: 'success' },
|
||||
4: { value: 4, label: '驳回', type: 'danger' },
|
||||
9: { value: 9, label: '已撤回', type: 'info' },
|
||||
10: { value: 10, label: '待审请', type: 'warning' },
|
||||
});
|
||||
// 判断单据类型是否在 typeEnumTagOptions 中
|
||||
const isTypeEnumTagOptions = (type) => {
|
||||
return Number(type) in typeEnumTagOptions.value;
|
||||
};
|
||||
// 当前选中的库房类型对应的单据类型选项
|
||||
const currentOrderOptions = computed(() => {
|
||||
if (!queryParams.value.locationTypeEnum || !warehouseTypeOption.value.length) {
|
||||
return [];
|
||||
}
|
||||
const currentType = warehouseTypeOption.value.find(
|
||||
(item) => item.value === queryParams.value.locationTypeEnum
|
||||
);
|
||||
return currentType ? currentType.orderOption || [] : [];
|
||||
});
|
||||
|
||||
// 当前选中的库房类型对应的库房选项
|
||||
const currentLocationOptions = computed(() => {
|
||||
if (!queryParams.value.locationTypeEnum || !warehouseTypeOption.value.length) {
|
||||
return [];
|
||||
}
|
||||
const currentType = warehouseTypeOption.value.find(
|
||||
(item) => item.value === queryParams.value.locationTypeEnum
|
||||
);
|
||||
return currentType ? currentType.locationOption || [] : [];
|
||||
});
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNo = 1;
|
||||
getList();
|
||||
};
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
orderDateRange.value = [];
|
||||
auditDateRange.value = [];
|
||||
queryParams.value.locationTypeEnum = null;
|
||||
queryParams.value.typeEnum = null;
|
||||
queryParams.value.locationId = null;
|
||||
handleQuery();
|
||||
};
|
||||
// 下拉框数据
|
||||
const warehouseTypeOption = ref([]);
|
||||
// 单据状态
|
||||
const supplyStatusOptions = ref([]);
|
||||
// 初始化
|
||||
const init = async () => {
|
||||
try {
|
||||
const res = await getInit();
|
||||
warehouseTypeOption.value = res.data.warehouseTypeOption;
|
||||
supplyStatusOptions.value = res.data.supplyStatusOptions;
|
||||
} catch (error) {
|
||||
console.error('初始化失败:', error);
|
||||
}
|
||||
};
|
||||
// 订单列表
|
||||
const orderList = ref([]);
|
||||
const total = ref(0);
|
||||
// 加载状态
|
||||
const loading = ref(false);
|
||||
// 获取列表
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
const params = {
|
||||
...queryParams.value,
|
||||
applyTimeSTime:
|
||||
orderDateRange.value && parseTime(orderDateRange.value[0], '{y}-{m}-{d}')
|
||||
? parseTime(orderDateRange.value[0], '{y}-{m}-{d}')
|
||||
: null,
|
||||
applyTimeETime:
|
||||
orderDateRange.value && parseTime(orderDateRange.value[1], '{y}-{m}-{d}')
|
||||
? parseTime(orderDateRange.value[1], '{y}-{m}-{d}')
|
||||
: null,
|
||||
approvalTimeSTime:
|
||||
auditDateRange.value && parseTime(auditDateRange.value[0], '{y}-{m}-{d}')
|
||||
? parseTime(auditDateRange.value[0], '{y}-{m}-{d}')
|
||||
: null,
|
||||
approvalTimeETime:
|
||||
auditDateRange.value && parseTime(auditDateRange.value[1], '{y}-{m}-{d}')
|
||||
? parseTime(auditDateRange.value[1], '{y}-{m}-{d}')
|
||||
: null,
|
||||
};
|
||||
const res = await getOrderList(params);
|
||||
// 赋值
|
||||
orderList.value = res.data.records;
|
||||
// 总数
|
||||
total.value = res.data.total;
|
||||
} catch (error) {
|
||||
console.error('获取列表失败:', error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
// 查看
|
||||
const handleView = (row) => {
|
||||
switch (Number(row.typeEnum)) {
|
||||
case 13:
|
||||
// 采购订货
|
||||
router.push({ path: '/medicineStorage/purchaseOrder/', query: { busNo: row.supplyBusNo } });
|
||||
break;
|
||||
case 1:
|
||||
// 采购入库
|
||||
router.push({ path: '/medicineStorage/stockInOrder/', query: { busNo: row.supplyBusNo } });
|
||||
break;
|
||||
case 5:
|
||||
// 采购退货
|
||||
router.push({ path: '/medicineStorage/returnOrder/', query: { busNo: row.supplyBusNo } });
|
||||
break;
|
||||
case 7:
|
||||
// 领用出库
|
||||
router.push({ path: '/medicineStorage/stockOutOrder/', query: { busNo: row.supplyBusNo } });
|
||||
break;
|
||||
case 9:
|
||||
// 领用退货
|
||||
router.push({
|
||||
path: '/medicineStorage/returnToWarehouseOrder/',
|
||||
query: { busNo: row.supplyBusNo },
|
||||
});
|
||||
break;
|
||||
case 6:
|
||||
// 报损单
|
||||
router.push({ path: '/medicineStorage/profitLossOrder/', query: { busNo: row.supplyBusNo } });
|
||||
break;
|
||||
case 4:
|
||||
// 商品盘点
|
||||
router.push({
|
||||
path: '/medicineStorage/stocktakingOrder/',
|
||||
query: { busNo: row.supplyBusNo },
|
||||
});
|
||||
break;
|
||||
default:
|
||||
console.log('未知的单据类型:', row.typeEnum);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
// 监听库房类型变化,清空相关选项
|
||||
watch(
|
||||
() => queryParams.value.locationTypeEnum,
|
||||
(newVal, oldVal) => {
|
||||
if (newVal !== oldVal) {
|
||||
queryParams.value.typeEnum = null;
|
||||
queryParams.value.locationId = null;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
init();
|
||||
getList();
|
||||
</script>
|
||||
@@ -0,0 +1,83 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
// 药库订货单初始化
|
||||
export function getInit () {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/profitLoss-order/init',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
// 订货单单据列表:显示所有单据 左边框
|
||||
export function getOrderList (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/profitLoss-order/profitLoss-order-page',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
// 根据供应商获取药品:对应添加/编辑时加下一行数据后,点击项目时调用的接口
|
||||
export function getMedicineList (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/profitLoss-order/medication-info',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
// 获取单据号:添加时,获取新单据号。编辑的逻辑是先删除后新增。
|
||||
export function getBusNo () {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/profitLoss-order/busNo-init',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
// 添加/编辑采购单:添加/编辑采购单
|
||||
export function addOrEditOrder (data) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/profitLoss-order/addOrEdit-profitLossOrder',
|
||||
method: 'PUT',
|
||||
data,
|
||||
});
|
||||
}
|
||||
// 删除单据
|
||||
export function deleteOrder (data) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/profitLoss-order/delete-profitLossOrder?busNo=' +
|
||||
data,
|
||||
method: 'DELETE',
|
||||
});
|
||||
}
|
||||
// 同意审批
|
||||
export function agreeApproval (data) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/profitLoss-order/agree-approval?busNo=' + data,
|
||||
method: 'PUT',
|
||||
});
|
||||
}
|
||||
// 获取单据详情
|
||||
export function getOrderDetail (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/profitLoss-order/profitLoss-order-detail-page',
|
||||
method: 'GET',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
// 订货单单据列表
|
||||
export function getPurchaseOrderList (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/purchase-order/purchase-order-page',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
// 获取单据详情
|
||||
export function getPurchaseOrderDetail (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/purchase-order/purchase-order-detail-page',
|
||||
method: 'GET',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-table ref="medicineRef" height="400" :data="medicineList" @cell-click="clickRow">
|
||||
<el-table-column label="项目编码" align="center" prop="busNo" width="150" />
|
||||
<el-table-column label="项目名称" align="center" prop="name" width="180" />
|
||||
<el-table-column label="进货价" align="center" prop="price" />
|
||||
<el-table-column label="零售价" align="center" prop="retailPrice" />
|
||||
<el-table-column label="包装单位" align="center" prop="unitCode_dictText" />
|
||||
<el-table-column label="最小单位" align="center" prop="minUnitCode_dictText" />
|
||||
<el-table-column label="规格" align="center" prop="totalVolume" />
|
||||
<el-table-column label="规格库存" align="center" prop="specificationInventory" />
|
||||
<el-table-column label="批次库存" align="center" prop="batchInventory" />
|
||||
<el-table-column label="供应商" align="center" prop="supplierId_dictText" />
|
||||
<el-table-column label="生产厂家" align="center" prop="manufacturerText" />
|
||||
<el-table-column label="批准文号" align="center" prop="approvalNumber" />
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getMedicineList } from './api';
|
||||
import { watch } from 'vue';
|
||||
import { throttle } from 'lodash-es';
|
||||
|
||||
const props = defineProps({
|
||||
searchKey: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
locationId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
// 选择药品
|
||||
const emit = defineEmits(['selectRow']);
|
||||
//
|
||||
const queryParams = ref({
|
||||
pageNum: 1,
|
||||
pageSize: 50,
|
||||
searchKey: props.searchKey,
|
||||
});
|
||||
// 药品列表
|
||||
const medicineList = ref([]);
|
||||
|
||||
// 节流函数
|
||||
const throttledGetList = throttle(
|
||||
() => {
|
||||
getList();
|
||||
},
|
||||
300,
|
||||
{ leading: true, trailing: true }
|
||||
);
|
||||
|
||||
// 获取药品列表
|
||||
const getList = (query) => {
|
||||
queryParams.value = {
|
||||
...queryParams.value,
|
||||
...query,
|
||||
locationId: props.locationId,
|
||||
}
|
||||
getMedicineList(query || queryParams.value).then((res) => {
|
||||
medicineList.value = res.data.records;
|
||||
});
|
||||
};
|
||||
|
||||
// 点击行
|
||||
const clickRow = (row) => {
|
||||
// console.log(row, 'row');
|
||||
emit('selectRow', row);
|
||||
};
|
||||
|
||||
// 监听搜索关键字
|
||||
watch(
|
||||
() => props,
|
||||
(newValue) => {
|
||||
queryParams.value.searchKey = newValue.searchKey;
|
||||
throttledGetList();
|
||||
},
|
||||
{ immdiate: true, deep: true }
|
||||
);
|
||||
|
||||
// 获取药品列表
|
||||
getList();
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,343 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog
|
||||
title="订单列表"
|
||||
v-model="localDialogVisible"
|
||||
width="960px"
|
||||
append-to-body
|
||||
@close="resetAllData"
|
||||
>
|
||||
<el-table
|
||||
:data="orderList"
|
||||
ref="tableRef"
|
||||
width="100%"
|
||||
highlight-current-row
|
||||
height="470px"
|
||||
@row-dblclick="handleRowDBClick"
|
||||
@row-click="handleRowClick"
|
||||
>
|
||||
<el-table-column
|
||||
label="订单编号"
|
||||
prop="supplyBusNo"
|
||||
width="200"
|
||||
align="center"
|
||||
></el-table-column>
|
||||
<el-table-column label="采购员" prop="applicantId_dictText" width="100" align="center" />
|
||||
<el-table-column label="供应商" prop="supplierId_dictText" width="220" align="center" />
|
||||
<el-table-column label="审核状态" prop="statusEnum_enumText" width="100" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.statusEnum_enumText === '同意'" type="success">
|
||||
{{ scope.row.statusEnum_enumText }}
|
||||
</el-tag>
|
||||
<el-tag v-else type="danger">{{ scope.row.statusEnum_enumText }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="单据类型" prop="typeEnum_enumText" width="100" align="center" />
|
||||
<el-table-column label="单据日期" prop="applyTime" width="200" align="center">
|
||||
<template #default="scope">
|
||||
{{ parseTime(scope.row.applyTime, '{yy}-{mm}-{dd} {hh}:{ii}:{ss}') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-row justify="end" style="margin-top: 10px">
|
||||
<el-pagination
|
||||
:current-page="queryParams.pageNo"
|
||||
:page-size="queryParams.pageSize"
|
||||
:page-sizes="[10, 50, 100, 200]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="localTableDataTotal"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
v-show="localTableDataTotal > 0"
|
||||
/>
|
||||
</el-row>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="handleCancel">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit"> 确认 </el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getPurchaseOrderList, getPurchaseOrderDetail } from './api';
|
||||
import { ref, watch, getCurrentInstance } from 'vue';
|
||||
import { parseTime } from '@/utils/his';
|
||||
// 调用父组件方法
|
||||
const emit = defineEmits(['dialogSubmit', 'dialogCancel', 'updateTableData']);
|
||||
// 获取当前实例
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
// 属性
|
||||
const props = defineProps({
|
||||
// 对话框x显示
|
||||
dialogVisible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
// 本地对话框显示
|
||||
const localDialogVisible = ref(false);
|
||||
// 监听属性
|
||||
watch(
|
||||
() => props.dialogVisible,
|
||||
(newValue) => {
|
||||
localDialogVisible.value = newValue;
|
||||
}
|
||||
);
|
||||
// 获取当前行
|
||||
const currentRow = ref({});
|
||||
// 行点击 双击
|
||||
const handleRowClick = (row) => {
|
||||
// 设置当前行
|
||||
currentRow.value = row;
|
||||
};
|
||||
// 行点击 双击
|
||||
const handleRowDBClick = (row) => {
|
||||
// 设置当前行
|
||||
currentRow.value = row;
|
||||
// 提交
|
||||
handleSubmit();
|
||||
};
|
||||
// 订单列表
|
||||
const orderList = ref([]);
|
||||
// 订单列表总条数
|
||||
const localTableDataTotal = ref(0);
|
||||
// 当前locationId
|
||||
const currentLocationId = ref(undefined);
|
||||
// 查询参数
|
||||
const queryParams = ref({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
locationId: undefined,
|
||||
});
|
||||
// 分页每页条数
|
||||
const handleSizeChange = (size) => {
|
||||
queryParams.value.pageSize = size;
|
||||
queryParams.value.pageNo = 1; // 切换每页条数时重置到第一页
|
||||
// 重新获取数据
|
||||
if (currentLocationId.value) {
|
||||
getOrderList(currentLocationId.value);
|
||||
}
|
||||
};
|
||||
// 分页当前页
|
||||
const handleCurrentChange = (page) => {
|
||||
queryParams.value.pageNo = page;
|
||||
// 重新获取数据
|
||||
if (currentLocationId.value) {
|
||||
getOrderList(currentLocationId.value);
|
||||
}
|
||||
};
|
||||
|
||||
// 获取订货单列表
|
||||
const getOrderList = async (locationId) => {
|
||||
try {
|
||||
// 保存当前locationId
|
||||
currentLocationId.value = locationId;
|
||||
|
||||
// 构建请求参数
|
||||
const requestParams = {
|
||||
// 仓库ID
|
||||
locationId: locationId,
|
||||
// 页码
|
||||
pageNo: queryParams.value.pageNo,
|
||||
// 每页条数
|
||||
pageSize: queryParams.value.pageSize,
|
||||
// 订单状态 3 :审核通过
|
||||
statusEnum: 3,
|
||||
};
|
||||
const res = await getPurchaseOrderList(requestParams);
|
||||
if (res.data.records && res.data.records.length > 0) {
|
||||
// 订货单列表
|
||||
orderList.value = res.data.records || [];
|
||||
// 订货单列表总条数
|
||||
localTableDataTotal.value = res.data.total;
|
||||
} else {
|
||||
proxy.$message.error('获取订货单列表失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取订货单列表失败:', error);
|
||||
}
|
||||
};
|
||||
// 重置所有数据
|
||||
const resetAllData = () => {
|
||||
// 重置分页参数
|
||||
queryParams.value.pageNo = 1;
|
||||
queryParams.value.pageSize = 10;
|
||||
currentLocationId.value = undefined;
|
||||
orderList.value = [];
|
||||
localTableDataTotal.value = 0;
|
||||
};
|
||||
// 提交数据
|
||||
const handleSubmit = async () => {
|
||||
// 取消按钮
|
||||
handleCancel();
|
||||
// 获取当前进货单的订单列表
|
||||
await getCurrentOrderDetail();
|
||||
// 传递数据给父组件
|
||||
emit('updateTableData', {
|
||||
currentOrderList: setCurrentOrderList.value,
|
||||
currentOrderForm: setCurrentOrderForm.value,
|
||||
});
|
||||
};
|
||||
// 设置当前进货单的订单列表
|
||||
const setCurrentOrderList = ref([]);
|
||||
// 设置当前进货单的订单表单
|
||||
const setCurrentOrderForm = ref({});
|
||||
|
||||
// 获取当前进货单的订单列表
|
||||
const getCurrentOrderDetail = async () => {
|
||||
const res = await getPurchaseOrderDetail({ busNo: currentRow.value.supplyBusNo });
|
||||
// 构建编辑后的表单数据
|
||||
buildEditForm(res.data.records);
|
||||
};
|
||||
// 构建编辑后的表单数据
|
||||
const buildEditForm = (data) => {
|
||||
// 构建表格数据
|
||||
if (data.length > 0) {
|
||||
// 表单数据
|
||||
setCurrentOrderForm.value = {
|
||||
// 供应商
|
||||
supplierId: data[0].supplierId,
|
||||
// 供应商联系人
|
||||
phone: data[0].phone,
|
||||
// 采购员
|
||||
practitionerId: data[0].applicantId,
|
||||
};
|
||||
// 表格数据
|
||||
data.forEach((item) => {
|
||||
// 表格编辑状态
|
||||
item.isEditing = true;
|
||||
// 表格查看状态
|
||||
item.isViewing = false;
|
||||
// 判断当前单位是否是最大单位
|
||||
buildPrice(item);
|
||||
// 构建单位列表
|
||||
buildUnitList(item);
|
||||
});
|
||||
// 更新表格数据
|
||||
setCurrentOrderList.value = data;
|
||||
}
|
||||
};
|
||||
// 构建进货价和销售价
|
||||
const buildPrice = (item) => {
|
||||
// 判断当前单位是最大单位还是最小单位
|
||||
const isMaxUnit = item.unitCode === item.maxUnitCode;
|
||||
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 = (item) => {
|
||||
// 表格单位列表
|
||||
(item.unitList || []).forEach((unit) => {
|
||||
// 判断当前单位是最大单位还是最小单位
|
||||
const isMaxUnit = unit.value === item.maxUnitCode;
|
||||
const isMinUnit = unit.value === item.minUnitCode;
|
||||
|
||||
// // 进货价(假)
|
||||
unit.priceMask = item.price;
|
||||
|
||||
// 销售价(假)
|
||||
unit.retailPriceMask = item.retailPrice;
|
||||
|
||||
// 进价金额(假)
|
||||
unit.totalPriceMask = (parseFloat(item.price) * parseFloat(item.itemQuantity)).toFixed(2);
|
||||
|
||||
// 销售金额(假)
|
||||
unit.totalRetailPriceMask = (
|
||||
parseFloat(item.retailPrice) * parseFloat(item.itemQuantity)
|
||||
).toFixed(2);
|
||||
|
||||
// 规格库存
|
||||
unit.specificationInventoryOriginal = item.specificationInventory;
|
||||
|
||||
// 规格库存显示逻辑
|
||||
if (isMaxUnit) {
|
||||
// 最大单位:显示为 "X盒"
|
||||
unit.specificationInventoryMax = Math.floor(
|
||||
item.specificationInventory / parseInt(item.partPercent)
|
||||
);
|
||||
unit.specificationInventoryMaxUnit =
|
||||
unit.specificationInventoryMax > 0 ? item.maxUnitCode_dictText : '';
|
||||
unit.specificationInventoryMin = item.specificationInventory % parseInt(item.partPercent);
|
||||
unit.specificationInventoryMinUnit =
|
||||
unit.specificationInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
|
||||
// 批次库存
|
||||
unit.batchInventoryMax = Math.floor(item.batchInventory / parseInt(item.partPercent));
|
||||
unit.batchInventoryMaxUnit = unit.batchInventoryMax > 0 ? item.maxUnitCode_dictText : '';
|
||||
unit.batchInventoryMin = item.batchInventory % parseInt(item.partPercent);
|
||||
unit.batchInventoryMinUnit = unit.batchInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
} else if (isMinUnit) {
|
||||
// 最小单位:显示为 "X瓶"
|
||||
unit.specificationInventoryMax = item.specificationInventory;
|
||||
unit.specificationInventoryMaxUnit =
|
||||
unit.specificationInventoryMax > 0 ? item.minUnitCode_dictText : '';
|
||||
unit.specificationInventoryMin = 0;
|
||||
unit.specificationInventoryMinUnit =
|
||||
unit.specificationInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
|
||||
// 批次库存
|
||||
unit.batchInventoryMax = item.batchInventory;
|
||||
unit.batchInventoryMaxUnit = unit.batchInventoryMax > 0 ? item.minUnitCode_dictText : '';
|
||||
unit.batchInventoryMin = 0;
|
||||
unit.batchInventoryMinUnit = unit.batchInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
} else {
|
||||
// 其他单位:显示为 "X瓶"
|
||||
unit.specificationInventoryMax = item.specificationInventory;
|
||||
unit.specificationInventoryMaxUnit =
|
||||
unit.specificationInventoryMax > 0 ? item.minUnitCode_dictText : '';
|
||||
unit.specificationInventoryMin = 0;
|
||||
unit.specificationInventoryMinUnit =
|
||||
unit.specificationInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
|
||||
// 批次库存
|
||||
unit.batchInventoryMax = item.batchInventory;
|
||||
unit.batchInventoryMaxUnit = unit.batchInventoryMax > 0 ? item.minUnitCode_dictText : '';
|
||||
unit.batchInventoryMin = 0;
|
||||
unit.batchInventoryMinUnit = unit.batchInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
}
|
||||
});
|
||||
};
|
||||
// 取消按钮
|
||||
const handleCancel = () => {
|
||||
emit('dialogCancel', {
|
||||
dialogVisible: false,
|
||||
});
|
||||
};
|
||||
defineOptions({
|
||||
name: 'orderDialog',
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
getOrderList,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
1081
openhis-ui-vue3/src/views/medicineStorage/profitLossOrder/index.vue
Normal file
1081
openhis-ui-vue3/src/views/medicineStorage/profitLossOrder/index.vue
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,66 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
// 药库订货单初始化
|
||||
export function getInit () {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/purchase-order/init',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
// 订货单单据列表:显示所有单据 左边框
|
||||
export function getOrderList (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/purchase-order/purchase-order-page',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
// 根据供应商获取药品:对应添加/编辑时加下一行数据后,点击项目时调用的接口
|
||||
export function getMedicineList (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/purchase-order/medication-info',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
// 获取单据号:添加时,获取新单据号。编辑的逻辑是先删除后新增。
|
||||
export function getBusNo () {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/purchase-order/busNo-init',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
// 添加/编辑采购单:添加/编辑采购单
|
||||
export function addOrEditOrder (data) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/purchase-order/addOrEdit-purchaseOrder',
|
||||
method: 'PUT',
|
||||
data,
|
||||
});
|
||||
}
|
||||
// 删除单据
|
||||
export function deleteOrder (data) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/purchase-order/delete-purchaseOrder?busNo=' +
|
||||
data,
|
||||
method: 'DELETE',
|
||||
});
|
||||
}
|
||||
// 同意审批
|
||||
export function agreeApproval (data) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/purchase-order/agree-approval?busNo=' + data,
|
||||
method: 'PUT',
|
||||
});
|
||||
}
|
||||
// 获取单据详情
|
||||
export function getOrderDetail (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/purchase-order/purchase-order-detail-page',
|
||||
method: 'GET',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-table ref="medicineRef" height="400" :data="medicineList" @cell-click="clickRow">
|
||||
<el-table-column label="项目编码" align="center" prop="busNo" width="150" />
|
||||
<el-table-column label="项目名称" align="center" prop="name" width="180" />
|
||||
<el-table-column label="进货价" align="center" prop="price" />
|
||||
<el-table-column label="零售价" align="center" prop="retailPrice" />
|
||||
<el-table-column label="包装单位" align="center" prop="unitCode_dictText" />
|
||||
<el-table-column label="最小单位" align="center" prop="minUnitCode_dictText" />
|
||||
<el-table-column label="规格" align="center" prop="totalVolume" />
|
||||
<el-table-column label="规格库存" align="center" prop="specificationInventory" />
|
||||
<el-table-column label="生产厂家" align="center" prop="manufacturerText" />
|
||||
<el-table-column label="批准文号" align="center" prop="approvalNumber" />
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getMedicineList } from './api';
|
||||
import { watch } from 'vue';
|
||||
import { throttle } from 'lodash-es';
|
||||
|
||||
const props = defineProps({
|
||||
searchKey: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
// 选择药品
|
||||
const emit = defineEmits(['selectRow']);
|
||||
//
|
||||
const queryParams = ref({
|
||||
pageNum: 1,
|
||||
pageSize: 50,
|
||||
searchKey: props.searchKey,
|
||||
// 13 药品
|
||||
typeEnum: 13,
|
||||
});
|
||||
// 药品列表
|
||||
const medicineList = ref([]);
|
||||
|
||||
// 节流函数
|
||||
const throttledGetList = throttle(
|
||||
() => {
|
||||
getList();
|
||||
},
|
||||
300,
|
||||
{ leading: true, trailing: true }
|
||||
);
|
||||
|
||||
// 获取药品列表
|
||||
const getList = (query) => {
|
||||
getMedicineList(query || queryParams.value).then((res) => {
|
||||
medicineList.value = res.data.records;
|
||||
});
|
||||
};
|
||||
|
||||
// 点击行
|
||||
const clickRow = (row) => {
|
||||
// console.log(row, 'row');
|
||||
emit('selectRow', row);
|
||||
};
|
||||
|
||||
// 监听搜索关键字
|
||||
watch(
|
||||
() => props,
|
||||
(newValue) => {
|
||||
queryParams.value.searchKey = newValue.searchKey;
|
||||
throttledGetList();
|
||||
},
|
||||
{ immdiate: true, deep: true }
|
||||
);
|
||||
|
||||
// 获取药品列表
|
||||
getList();
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
1008
openhis-ui-vue3/src/views/medicineStorage/purchaseOrder/index.vue
Normal file
1008
openhis-ui-vue3/src/views/medicineStorage/purchaseOrder/index.vue
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,83 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
// 药库订货单初始化
|
||||
export function getInit () {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/return-order/init',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
// 订货单单据列表:显示所有单据 左边框
|
||||
export function getOrderList (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/return-order/return-order-page',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
// 根据供应商获取药品:对应添加/编辑时加下一行数据后,点击项目时调用的接口
|
||||
export function getMedicineList (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/return-order/medication-info',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
// 获取单据号:添加时,获取新单据号。编辑的逻辑是先删除后新增。
|
||||
export function getBusNo () {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/return-order/busNo-init',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
// 添加/编辑采购单:添加/编辑采购单
|
||||
export function addOrEditOrder (data) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/return-order/addOrEdit-returnOrder',
|
||||
method: 'PUT',
|
||||
data,
|
||||
});
|
||||
}
|
||||
// 删除单据
|
||||
export function deleteOrder (data) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/return-order/delete-returnOrder?busNo=' + data,
|
||||
method: 'DELETE',
|
||||
});
|
||||
}
|
||||
// 同意审批
|
||||
export function agreeApproval (data) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/return-order/agree-approval?busNo=' + data,
|
||||
method: 'PUT',
|
||||
});
|
||||
}
|
||||
// 获取单据详情
|
||||
export function getOrderDetail (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/return-order/return-order-detail-page',
|
||||
method: 'GET',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
// 订货单单据列表
|
||||
export function getStockInOrderList (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/stockIn-order/stockIn-order-page',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
// 获取单据详情
|
||||
export function getStockInOrderDetail (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/stockIn-order/stockIn-order-detail-page',
|
||||
method: 'GET',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-table ref="medicineRef" height="400" :data="medicineList" @cell-click="clickRow">
|
||||
<el-table-column label="项目编码" align="center" prop="busNo" width="150" />
|
||||
<el-table-column label="项目名称" align="center" prop="name" width="180" />
|
||||
<el-table-column label="进货价" align="center" prop="price" />
|
||||
<el-table-column label="零售价" align="center" prop="retailPrice" />
|
||||
<el-table-column label="包装单位" align="center" prop="unitCode_dictText" />
|
||||
<el-table-column label="最小单位" align="center" prop="minUnitCode_dictText" />
|
||||
<el-table-column label="规格" align="center" prop="totalVolume" />
|
||||
<el-table-column label="规格库存" align="center" prop="specificationInventory" />
|
||||
<el-table-column label="供应商" align="center" prop="supplierId_dictText" />
|
||||
<el-table-column label="生产厂家" align="center" prop="manufacturerText" />
|
||||
<el-table-column label="批准文号" align="center" prop="approvalNumber" />
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getMedicineList } from './api';
|
||||
import { watch } from 'vue';
|
||||
import { throttle } from 'lodash-es';
|
||||
|
||||
const props = defineProps({
|
||||
searchKey: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
locationId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
supplierId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
// 选择药品
|
||||
const emit = defineEmits(['selectRow']);
|
||||
//
|
||||
const queryParams = ref({
|
||||
pageNum: 1,
|
||||
pageSize: 50,
|
||||
searchKey: props.searchKey,
|
||||
});
|
||||
// 药品列表
|
||||
const medicineList = ref([]);
|
||||
|
||||
// 节流函数
|
||||
const throttledGetList = throttle(
|
||||
() => {
|
||||
getList();
|
||||
},
|
||||
300,
|
||||
{ leading: true, trailing: true }
|
||||
);
|
||||
|
||||
// 获取药品列表
|
||||
const getList = (query) => {
|
||||
queryParams.value = {
|
||||
...queryParams.value,
|
||||
...query,
|
||||
locationId: props.locationId,
|
||||
supplierId: props.supplierId,
|
||||
}
|
||||
getMedicineList(query || queryParams.value).then((res) => {
|
||||
medicineList.value = res.data.records;
|
||||
});
|
||||
};
|
||||
|
||||
// 点击行
|
||||
const clickRow = (row) => {
|
||||
// console.log(row, 'row');
|
||||
emit('selectRow', row);
|
||||
};
|
||||
|
||||
// 监听搜索关键字
|
||||
watch(
|
||||
() => props,
|
||||
(newValue) => {
|
||||
queryParams.value.searchKey = newValue.searchKey;
|
||||
throttledGetList();
|
||||
},
|
||||
{ immdiate: true, deep: true }
|
||||
);
|
||||
|
||||
// 获取药品列表
|
||||
getList();
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,350 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog
|
||||
title="订单列表"
|
||||
v-model="localDialogVisible"
|
||||
width="960px"
|
||||
append-to-body
|
||||
@close="resetAllData"
|
||||
>
|
||||
<el-table
|
||||
:data="orderList"
|
||||
ref="tableRef"
|
||||
width="100%"
|
||||
highlight-current-row
|
||||
height="470px"
|
||||
@row-dblclick="handleRowDBClick"
|
||||
@row-click="handleRowClick"
|
||||
>
|
||||
<el-table-column
|
||||
label="订单编号"
|
||||
prop="supplyBusNo"
|
||||
width="200"
|
||||
align="center"
|
||||
></el-table-column>
|
||||
<el-table-column label="采购员" prop="applicantId_dictText" width="100" align="center" />
|
||||
<el-table-column label="供应商" prop="supplierId_dictText" width="220" align="center" />
|
||||
<el-table-column label="审核状态" prop="statusEnum_enumText" width="100" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.statusEnum_enumText === '同意'" type="success">
|
||||
{{ scope.row.statusEnum_enumText }}
|
||||
</el-tag>
|
||||
<el-tag v-else type="danger">{{ scope.row.statusEnum_enumText }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="单据类型" prop="typeEnum_enumText" width="100" align="center" />
|
||||
<el-table-column label="单据日期" prop="applyTime" width="200" align="center">
|
||||
<template #default="scope">
|
||||
{{ parseTime(scope.row.applyTime, '{yy}-{mm}-{dd} {hh}:{ii}:{ss}') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-row justify="end" style="margin-top: 10px">
|
||||
<el-pagination
|
||||
:current-page="queryParams.pageNo"
|
||||
:page-size="queryParams.pageSize"
|
||||
:page-sizes="[10, 50, 100, 200]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="localTableDataTotal"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
v-show="localTableDataTotal > 0"
|
||||
/>
|
||||
</el-row>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="handleCancel">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit"> 确认 </el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getStockInOrderList, getStockInOrderDetail } from './api';
|
||||
import { ref, watch, getCurrentInstance } from 'vue';
|
||||
import { parseTime } from '@/utils/his';
|
||||
// 调用父组件方法
|
||||
const emit = defineEmits(['dialogSubmit', 'dialogCancel', 'updateTableData']);
|
||||
// 获取当前实例
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
// 属性
|
||||
const props = defineProps({
|
||||
// 对话框x显示
|
||||
dialogVisible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
// 本地对话框显示
|
||||
const localDialogVisible = ref(false);
|
||||
// 监听属性
|
||||
watch(
|
||||
() => props.dialogVisible,
|
||||
(newValue) => {
|
||||
localDialogVisible.value = newValue;
|
||||
}
|
||||
);
|
||||
// 获取当前行
|
||||
const currentRow = ref({});
|
||||
// 行点击 双击
|
||||
const handleRowClick = (row) => {
|
||||
// 设置当前行
|
||||
currentRow.value = row;
|
||||
};
|
||||
// 行点击 双击
|
||||
const handleRowDBClick = (row) => {
|
||||
// 设置当前行
|
||||
currentRow.value = row;
|
||||
// 提交
|
||||
handleSubmit();
|
||||
};
|
||||
// 订单列表
|
||||
const orderList = ref([]);
|
||||
// 订单列表总条数
|
||||
const localTableDataTotal = ref(0);
|
||||
// 当前locationId
|
||||
const currentLocationId = ref(undefined);
|
||||
// 查询参数
|
||||
const queryParams = ref({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
locationId: undefined,
|
||||
});
|
||||
// 分页每页条数
|
||||
const handleSizeChange = (size) => {
|
||||
queryParams.value.pageSize = size;
|
||||
queryParams.value.pageNo = 1; // 切换每页条数时重置到第一页
|
||||
// 重新获取数据
|
||||
if (currentLocationId.value) {
|
||||
getOrderList(currentLocationId.value);
|
||||
}
|
||||
};
|
||||
// 分页当前页
|
||||
const handleCurrentChange = (page) => {
|
||||
queryParams.value.pageNo = page;
|
||||
// 重新获取数据
|
||||
if (currentLocationId.value) {
|
||||
getOrderList(currentLocationId.value);
|
||||
}
|
||||
};
|
||||
|
||||
// 获取订货单列表
|
||||
const getOrderList = async (locationId) => {
|
||||
try {
|
||||
// 保存当前locationId
|
||||
currentLocationId.value = locationId;
|
||||
|
||||
// 构建请求参数
|
||||
const requestParams = {
|
||||
// 仓库ID
|
||||
locationId: locationId,
|
||||
// 页码
|
||||
pageNo: queryParams.value.pageNo,
|
||||
// 每页条数
|
||||
pageSize: queryParams.value.pageSize,
|
||||
// 订单状态 3 :审核通过
|
||||
statusEnum: 3,
|
||||
// 是否查询原始单
|
||||
originalBusNoFlg: 1,
|
||||
};
|
||||
const res = await getStockInOrderList(requestParams);
|
||||
if (res.data.records && res.data.records.length > 0) {
|
||||
// 订货单列表
|
||||
orderList.value = res.data.records || [];
|
||||
// 订货单列表总条数
|
||||
localTableDataTotal.value = res.data.total;
|
||||
} else {
|
||||
// proxy.$message.error('获取订货单列表失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取订货单列表失败:', error);
|
||||
}
|
||||
};
|
||||
// 重置所有数据
|
||||
const resetAllData = () => {
|
||||
// 重置分页参数
|
||||
queryParams.value.pageNo = 1;
|
||||
queryParams.value.pageSize = 10;
|
||||
currentLocationId.value = undefined;
|
||||
orderList.value = [];
|
||||
localTableDataTotal.value = 0;
|
||||
};
|
||||
// 提交数据
|
||||
const handleSubmit = async () => {
|
||||
// 取消按钮
|
||||
handleCancel();
|
||||
// 获取当前进货单的订单列表
|
||||
await getCurrentOrderDetail();
|
||||
// 传递数据给父组件
|
||||
emit('updateTableData', {
|
||||
currentOrderList: setCurrentOrderList.value,
|
||||
currentOrderForm: setCurrentOrderForm.value,
|
||||
});
|
||||
};
|
||||
// 设置当前进货单的订单列表
|
||||
const setCurrentOrderList = ref([]);
|
||||
// 设置当前进货单的订单表单
|
||||
const setCurrentOrderForm = ref({});
|
||||
|
||||
// 获取当前进货单的订单列表
|
||||
const getCurrentOrderDetail = async () => {
|
||||
if (!currentRow.value.supplyBusNo) {
|
||||
return;
|
||||
}
|
||||
const res = await getStockInOrderDetail({ busNo: currentRow.value.supplyBusNo });
|
||||
// 构建编辑后的表单数据
|
||||
buildEditForm(res.data.records);
|
||||
};
|
||||
// 构建编辑后的表单数据
|
||||
const buildEditForm = (data) => {
|
||||
// 构建表格数据
|
||||
if (data.length > 0) {
|
||||
// 表单数据
|
||||
setCurrentOrderForm.value = {
|
||||
// 供应商
|
||||
supplierId: data[0].supplierId,
|
||||
// 供应商联系人
|
||||
phone: data[0].phone,
|
||||
// 采购员
|
||||
practitionerId: data[0].applicantId,
|
||||
// 原始单据号
|
||||
originalBusNo: data[0].busNo,
|
||||
};
|
||||
// 表格数据
|
||||
data.forEach((item) => {
|
||||
// 表格编辑状态
|
||||
item.isEditing = true;
|
||||
// 表格查看状态
|
||||
item.isViewing = false;
|
||||
// 判断当前单位是否是最大单位
|
||||
buildPrice(item);
|
||||
// 构建单位列表
|
||||
buildUnitList(item);
|
||||
});
|
||||
// 更新表格数据
|
||||
setCurrentOrderList.value = data;
|
||||
}
|
||||
};
|
||||
// 构建进货价和销售价
|
||||
const buildPrice = (item) => {
|
||||
// 判断当前单位是最大单位还是最小单位
|
||||
const isMaxUnit = item.unitCode === item.maxUnitCode;
|
||||
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 = (item) => {
|
||||
// 表格单位列表
|
||||
(item.unitList || []).forEach((unit) => {
|
||||
// 判断当前单位是最大单位还是最小单位
|
||||
const isMaxUnit = unit.value === item.maxUnitCode;
|
||||
const isMinUnit = unit.value === item.minUnitCode;
|
||||
|
||||
// // 进货价(假)
|
||||
unit.priceMask = item.price;
|
||||
|
||||
// 销售价(假)
|
||||
unit.retailPriceMask = item.retailPrice;
|
||||
|
||||
// 进价金额(假)
|
||||
unit.totalPriceMask = (parseFloat(item.price) * parseFloat(item.itemQuantity)).toFixed(2);
|
||||
|
||||
// 销售金额(假)
|
||||
unit.totalRetailPriceMask = (
|
||||
parseFloat(item.retailPrice) * parseFloat(item.itemQuantity)
|
||||
).toFixed(2);
|
||||
|
||||
// 规格库存
|
||||
unit.specificationInventoryOriginal = item.specificationInventory;
|
||||
|
||||
// 规格库存显示逻辑
|
||||
if (isMaxUnit) {
|
||||
// 最大单位:显示为 "X盒"
|
||||
unit.specificationInventoryMax = Math.floor(
|
||||
item.specificationInventory / parseInt(item.partPercent)
|
||||
);
|
||||
unit.specificationInventoryMaxUnit =
|
||||
unit.specificationInventoryMax > 0 ? item.maxUnitCode_dictText : '';
|
||||
unit.specificationInventoryMin = item.specificationInventory % parseInt(item.partPercent);
|
||||
unit.specificationInventoryMinUnit =
|
||||
unit.specificationInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
|
||||
// 批次库存
|
||||
unit.batchInventoryMax = Math.floor(item.batchInventory / parseInt(item.partPercent));
|
||||
unit.batchInventoryMaxUnit = unit.batchInventoryMax > 0 ? item.maxUnitCode_dictText : '';
|
||||
unit.batchInventoryMin = item.batchInventory % parseInt(item.partPercent);
|
||||
unit.batchInventoryMinUnit = unit.batchInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
} else if (isMinUnit) {
|
||||
// 最小单位:显示为 "X瓶"
|
||||
unit.specificationInventoryMax = item.specificationInventory;
|
||||
unit.specificationInventoryMaxUnit =
|
||||
unit.specificationInventoryMax > 0 ? item.minUnitCode_dictText : '';
|
||||
unit.specificationInventoryMin = 0;
|
||||
unit.specificationInventoryMinUnit =
|
||||
unit.specificationInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
|
||||
// 批次库存
|
||||
unit.batchInventoryMax = item.batchInventory;
|
||||
unit.batchInventoryMaxUnit = unit.batchInventoryMax > 0 ? item.minUnitCode_dictText : '';
|
||||
unit.batchInventoryMin = 0;
|
||||
unit.batchInventoryMinUnit = unit.batchInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
} else {
|
||||
// 其他单位:显示为 "X瓶"
|
||||
unit.specificationInventoryMax = item.specificationInventory;
|
||||
unit.specificationInventoryMaxUnit =
|
||||
unit.specificationInventoryMax > 0 ? item.minUnitCode_dictText : '';
|
||||
unit.specificationInventoryMin = 0;
|
||||
unit.specificationInventoryMinUnit =
|
||||
unit.specificationInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
|
||||
// 批次库存
|
||||
unit.batchInventoryMax = item.batchInventory;
|
||||
unit.batchInventoryMaxUnit = unit.batchInventoryMax > 0 ? item.minUnitCode_dictText : '';
|
||||
unit.batchInventoryMin = 0;
|
||||
unit.batchInventoryMinUnit = unit.batchInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
}
|
||||
});
|
||||
};
|
||||
// 取消按钮
|
||||
const handleCancel = () => {
|
||||
emit('dialogCancel', {
|
||||
dialogVisible: false,
|
||||
});
|
||||
};
|
||||
defineOptions({
|
||||
name: 'orderDialog',
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
getOrderList,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
1058
openhis-ui-vue3/src/views/medicineStorage/returnOrder/index.vue
Normal file
1058
openhis-ui-vue3/src/views/medicineStorage/returnOrder/index.vue
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,83 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
// 药库订货单初始化
|
||||
export function getInit () {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/returnToWarehouse-order/init',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
// 订货单单据列表:显示所有单据 左边框
|
||||
export function getOrderList (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/returnToWarehouse-order/returnToWarehouse-order-page',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
// 根据供应商获取药品:对应添加/编辑时加下一行数据后,点击项目时调用的接口
|
||||
export function getMedicineList (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/returnToWarehouse-order/medication-info',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
// 获取单据号:添加时,获取新单据号。编辑的逻辑是先删除后新增。
|
||||
export function getBusNo () {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/returnToWarehouse-order/busNo-init',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
// 添加/编辑采购单:添加/编辑采购单
|
||||
export function addOrEditOrder (data) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/returnToWarehouse-order/addOrEdit-returnToWarehouseOrder',
|
||||
method: 'PUT',
|
||||
data,
|
||||
});
|
||||
}
|
||||
// 删除单据
|
||||
export function deleteOrder (data) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/returnToWarehouse-order/delete-returnToWarehouseOrder?busNo=' +
|
||||
data,
|
||||
method: 'DELETE',
|
||||
});
|
||||
}
|
||||
// 同意审批
|
||||
export function agreeApproval (data) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/returnToWarehouse-order/agree-approval?busNo=' + data,
|
||||
method: 'PUT',
|
||||
});
|
||||
}
|
||||
// 获取单据详情
|
||||
export function getOrderDetail (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/returnToWarehouse-order/returnToWarehouse-order-detail-page',
|
||||
method: 'GET',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
// 订货单单据列表
|
||||
export function getPurchaseOrderList (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/purchase-order/purchase-order-page',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
// 获取单据详情
|
||||
export function getPurchaseOrderDetail (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/purchase-order/purchase-order-detail-page',
|
||||
method: 'GET',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-table ref="medicineRef" height="400" :data="medicineList" @cell-click="clickRow">
|
||||
<el-table-column label="项目编码" align="center" prop="busNo" width="150" />
|
||||
<el-table-column label="项目名称" align="center" prop="name" width="180" />
|
||||
<el-table-column label="进货价" align="center" prop="price" />
|
||||
<el-table-column label="零售价" align="center" prop="retailPrice" />
|
||||
<el-table-column label="包装单位" align="center" prop="unitCode_dictText" />
|
||||
<el-table-column label="最小单位" align="center" prop="minUnitCode_dictText" />
|
||||
<el-table-column label="规格" align="center" prop="totalVolume" />
|
||||
<el-table-column label="规格库存" align="center" prop="specificationInventory" />
|
||||
<el-table-column label="供应商" align="center" prop="supplierId_dictText" />
|
||||
<el-table-column label="生产厂家" align="center" prop="manufacturerText" />
|
||||
<el-table-column label="批准文号" align="center" prop="approvalNumber" />
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getMedicineList } from './api';
|
||||
import { watch } from 'vue';
|
||||
import { throttle } from 'lodash-es';
|
||||
|
||||
const props = defineProps({
|
||||
searchKey: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
locationId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
// 选择药品
|
||||
const emit = defineEmits(['selectRow']);
|
||||
//
|
||||
const queryParams = ref({
|
||||
pageNum: 1,
|
||||
pageSize: 50,
|
||||
searchKey: props.searchKey,
|
||||
});
|
||||
// 药品列表
|
||||
const medicineList = ref([]);
|
||||
|
||||
// 节流函数
|
||||
const throttledGetList = throttle(
|
||||
() => {
|
||||
getList();
|
||||
},
|
||||
300,
|
||||
{ leading: true, trailing: true }
|
||||
);
|
||||
|
||||
// 获取药品列表
|
||||
const getList = (query) => {
|
||||
queryParams.value = {
|
||||
...queryParams.value,
|
||||
...query,
|
||||
locationId: props.locationId,
|
||||
}
|
||||
getMedicineList(query || queryParams.value).then((res) => {
|
||||
medicineList.value = res.data.records;
|
||||
});
|
||||
};
|
||||
|
||||
// 点击行
|
||||
const clickRow = (row) => {
|
||||
// console.log(row, 'row');
|
||||
emit('selectRow', row);
|
||||
};
|
||||
|
||||
// 监听搜索关键字
|
||||
watch(
|
||||
() => props,
|
||||
(newValue) => {
|
||||
queryParams.value.searchKey = newValue.searchKey;
|
||||
throttledGetList();
|
||||
},
|
||||
{ immdiate: true, deep: true }
|
||||
);
|
||||
|
||||
// 获取药品列表
|
||||
getList();
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,343 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog
|
||||
title="订单列表"
|
||||
v-model="localDialogVisible"
|
||||
width="960px"
|
||||
append-to-body
|
||||
@close="resetAllData"
|
||||
>
|
||||
<el-table
|
||||
:data="orderList"
|
||||
ref="tableRef"
|
||||
width="100%"
|
||||
highlight-current-row
|
||||
height="470px"
|
||||
@row-dblclick="handleRowDBClick"
|
||||
@row-click="handleRowClick"
|
||||
>
|
||||
<el-table-column
|
||||
label="订单编号"
|
||||
prop="supplyBusNo"
|
||||
width="200"
|
||||
align="center"
|
||||
></el-table-column>
|
||||
<el-table-column label="采购员" prop="applicantId_dictText" width="100" align="center" />
|
||||
<el-table-column label="供应商" prop="supplierId_dictText" width="220" align="center" />
|
||||
<el-table-column label="审核状态" prop="statusEnum_enumText" width="100" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.statusEnum_enumText === '同意'" type="success">
|
||||
{{ scope.row.statusEnum_enumText }}
|
||||
</el-tag>
|
||||
<el-tag v-else type="danger">{{ scope.row.statusEnum_enumText }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="单据类型" prop="typeEnum_enumText" width="100" align="center" />
|
||||
<el-table-column label="单据日期" prop="applyTime" width="200" align="center">
|
||||
<template #default="scope">
|
||||
{{ parseTime(scope.row.applyTime, '{yy}-{mm}-{dd} {hh}:{ii}:{ss}') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-row justify="end" style="margin-top: 10px">
|
||||
<el-pagination
|
||||
:current-page="queryParams.pageNo"
|
||||
:page-size="queryParams.pageSize"
|
||||
:page-sizes="[10, 50, 100, 200]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="localTableDataTotal"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
v-show="localTableDataTotal > 0"
|
||||
/>
|
||||
</el-row>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="handleCancel">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit"> 确认 </el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getPurchaseOrderList, getPurchaseOrderDetail } from './api';
|
||||
import { ref, watch, getCurrentInstance } from 'vue';
|
||||
import { parseTime } from '@/utils/his';
|
||||
// 调用父组件方法
|
||||
const emit = defineEmits(['dialogSubmit', 'dialogCancel', 'updateTableData']);
|
||||
// 获取当前实例
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
// 属性
|
||||
const props = defineProps({
|
||||
// 对话框x显示
|
||||
dialogVisible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
// 本地对话框显示
|
||||
const localDialogVisible = ref(false);
|
||||
// 监听属性
|
||||
watch(
|
||||
() => props.dialogVisible,
|
||||
(newValue) => {
|
||||
localDialogVisible.value = newValue;
|
||||
}
|
||||
);
|
||||
// 获取当前行
|
||||
const currentRow = ref({});
|
||||
// 行点击 双击
|
||||
const handleRowClick = (row) => {
|
||||
// 设置当前行
|
||||
currentRow.value = row;
|
||||
};
|
||||
// 行点击 双击
|
||||
const handleRowDBClick = (row) => {
|
||||
// 设置当前行
|
||||
currentRow.value = row;
|
||||
// 提交
|
||||
handleSubmit();
|
||||
};
|
||||
// 订单列表
|
||||
const orderList = ref([]);
|
||||
// 订单列表总条数
|
||||
const localTableDataTotal = ref(0);
|
||||
// 当前locationId
|
||||
const currentLocationId = ref(undefined);
|
||||
// 查询参数
|
||||
const queryParams = ref({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
locationId: undefined,
|
||||
});
|
||||
// 分页每页条数
|
||||
const handleSizeChange = (size) => {
|
||||
queryParams.value.pageSize = size;
|
||||
queryParams.value.pageNo = 1; // 切换每页条数时重置到第一页
|
||||
// 重新获取数据
|
||||
if (currentLocationId.value) {
|
||||
getOrderList(currentLocationId.value);
|
||||
}
|
||||
};
|
||||
// 分页当前页
|
||||
const handleCurrentChange = (page) => {
|
||||
queryParams.value.pageNo = page;
|
||||
// 重新获取数据
|
||||
if (currentLocationId.value) {
|
||||
getOrderList(currentLocationId.value);
|
||||
}
|
||||
};
|
||||
|
||||
// 获取订货单列表
|
||||
const getOrderList = async (locationId) => {
|
||||
try {
|
||||
// 保存当前locationId
|
||||
currentLocationId.value = locationId;
|
||||
|
||||
// 构建请求参数
|
||||
const requestParams = {
|
||||
// 仓库ID
|
||||
locationId: locationId,
|
||||
// 页码
|
||||
pageNo: queryParams.value.pageNo,
|
||||
// 每页条数
|
||||
pageSize: queryParams.value.pageSize,
|
||||
// 订单状态 3 :审核通过
|
||||
statusEnum: 3,
|
||||
};
|
||||
const res = await getPurchaseOrderList(requestParams);
|
||||
if (res.data.records && res.data.records.length > 0) {
|
||||
// 订货单列表
|
||||
orderList.value = res.data.records || [];
|
||||
// 订货单列表总条数
|
||||
localTableDataTotal.value = res.data.total;
|
||||
} else {
|
||||
proxy.$message.error('获取订货单列表失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取订货单列表失败:', error);
|
||||
}
|
||||
};
|
||||
// 重置所有数据
|
||||
const resetAllData = () => {
|
||||
// 重置分页参数
|
||||
queryParams.value.pageNo = 1;
|
||||
queryParams.value.pageSize = 10;
|
||||
currentLocationId.value = undefined;
|
||||
orderList.value = [];
|
||||
localTableDataTotal.value = 0;
|
||||
};
|
||||
// 提交数据
|
||||
const handleSubmit = async () => {
|
||||
// 取消按钮
|
||||
handleCancel();
|
||||
// 获取当前进货单的订单列表
|
||||
await getCurrentOrderDetail();
|
||||
// 传递数据给父组件
|
||||
emit('updateTableData', {
|
||||
currentOrderList: setCurrentOrderList.value,
|
||||
currentOrderForm: setCurrentOrderForm.value,
|
||||
});
|
||||
};
|
||||
// 设置当前进货单的订单列表
|
||||
const setCurrentOrderList = ref([]);
|
||||
// 设置当前进货单的订单表单
|
||||
const setCurrentOrderForm = ref({});
|
||||
|
||||
// 获取当前进货单的订单列表
|
||||
const getCurrentOrderDetail = async () => {
|
||||
const res = await getPurchaseOrderDetail({ busNo: currentRow.value.supplyBusNo });
|
||||
// 构建编辑后的表单数据
|
||||
buildEditForm(res.data.records);
|
||||
};
|
||||
// 构建编辑后的表单数据
|
||||
const buildEditForm = (data) => {
|
||||
// 构建表格数据
|
||||
if (data.length > 0) {
|
||||
// 表单数据
|
||||
setCurrentOrderForm.value = {
|
||||
// 供应商
|
||||
supplierId: data[0].supplierId,
|
||||
// 供应商联系人
|
||||
phone: data[0].phone,
|
||||
// 采购员
|
||||
practitionerId: data[0].applicantId,
|
||||
};
|
||||
// 表格数据
|
||||
data.forEach((item) => {
|
||||
// 表格编辑状态
|
||||
item.isEditing = true;
|
||||
// 表格查看状态
|
||||
item.isViewing = false;
|
||||
// 判断当前单位是否是最大单位
|
||||
buildPrice(item);
|
||||
// 构建单位列表
|
||||
buildUnitList(item);
|
||||
});
|
||||
// 更新表格数据
|
||||
setCurrentOrderList.value = data;
|
||||
}
|
||||
};
|
||||
// 构建进货价和销售价
|
||||
const buildPrice = (item) => {
|
||||
// 判断当前单位是最大单位还是最小单位
|
||||
const isMaxUnit = item.unitCode === item.maxUnitCode;
|
||||
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 = (item) => {
|
||||
// 表格单位列表
|
||||
(item.unitList || []).forEach((unit) => {
|
||||
// 判断当前单位是最大单位还是最小单位
|
||||
const isMaxUnit = unit.value === item.maxUnitCode;
|
||||
const isMinUnit = unit.value === item.minUnitCode;
|
||||
|
||||
// // 进货价(假)
|
||||
unit.priceMask = item.price;
|
||||
|
||||
// 销售价(假)
|
||||
unit.retailPriceMask = item.retailPrice;
|
||||
|
||||
// 进价金额(假)
|
||||
unit.totalPriceMask = (parseFloat(item.price) * parseFloat(item.itemQuantity)).toFixed(2);
|
||||
|
||||
// 销售金额(假)
|
||||
unit.totalRetailPriceMask = (
|
||||
parseFloat(item.retailPrice) * parseFloat(item.itemQuantity)
|
||||
).toFixed(2);
|
||||
|
||||
// 规格库存
|
||||
unit.specificationInventoryOriginal = item.specificationInventory;
|
||||
|
||||
// 规格库存显示逻辑
|
||||
if (isMaxUnit) {
|
||||
// 最大单位:显示为 "X盒"
|
||||
unit.specificationInventoryMax = Math.floor(
|
||||
item.specificationInventory / parseInt(item.partPercent)
|
||||
);
|
||||
unit.specificationInventoryMaxUnit =
|
||||
unit.specificationInventoryMax > 0 ? item.maxUnitCode_dictText : '';
|
||||
unit.specificationInventoryMin = item.specificationInventory % parseInt(item.partPercent);
|
||||
unit.specificationInventoryMinUnit =
|
||||
unit.specificationInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
|
||||
// 批次库存
|
||||
unit.batchInventoryMax = Math.floor(item.batchInventory / parseInt(item.partPercent));
|
||||
unit.batchInventoryMaxUnit = unit.batchInventoryMax > 0 ? item.maxUnitCode_dictText : '';
|
||||
unit.batchInventoryMin = item.batchInventory % parseInt(item.partPercent);
|
||||
unit.batchInventoryMinUnit = unit.batchInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
} else if (isMinUnit) {
|
||||
// 最小单位:显示为 "X瓶"
|
||||
unit.specificationInventoryMax = item.specificationInventory;
|
||||
unit.specificationInventoryMaxUnit =
|
||||
unit.specificationInventoryMax > 0 ? item.minUnitCode_dictText : '';
|
||||
unit.specificationInventoryMin = 0;
|
||||
unit.specificationInventoryMinUnit =
|
||||
unit.specificationInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
|
||||
// 批次库存
|
||||
unit.batchInventoryMax = item.batchInventory;
|
||||
unit.batchInventoryMaxUnit = unit.batchInventoryMax > 0 ? item.minUnitCode_dictText : '';
|
||||
unit.batchInventoryMin = 0;
|
||||
unit.batchInventoryMinUnit = unit.batchInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
} else {
|
||||
// 其他单位:显示为 "X瓶"
|
||||
unit.specificationInventoryMax = item.specificationInventory;
|
||||
unit.specificationInventoryMaxUnit =
|
||||
unit.specificationInventoryMax > 0 ? item.minUnitCode_dictText : '';
|
||||
unit.specificationInventoryMin = 0;
|
||||
unit.specificationInventoryMinUnit =
|
||||
unit.specificationInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
|
||||
// 批次库存
|
||||
unit.batchInventoryMax = item.batchInventory;
|
||||
unit.batchInventoryMaxUnit = unit.batchInventoryMax > 0 ? item.minUnitCode_dictText : '';
|
||||
unit.batchInventoryMin = 0;
|
||||
unit.batchInventoryMinUnit = unit.batchInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
}
|
||||
});
|
||||
};
|
||||
// 取消按钮
|
||||
const handleCancel = () => {
|
||||
emit('dialogCancel', {
|
||||
dialogVisible: false,
|
||||
});
|
||||
};
|
||||
defineOptions({
|
||||
name: 'orderDialog',
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
getOrderList,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,83 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
// 药库订货单初始化
|
||||
export function getInit () {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/stockIn-order/init',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
// 订货单单据列表:显示所有单据 左边框
|
||||
export function getOrderList (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/stockIn-order/stockIn-order-page',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
// 根据供应商获取药品:对应添加/编辑时加下一行数据后,点击项目时调用的接口
|
||||
export function getMedicineList (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/stockIn-order/medication-info',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
// 获取单据号:添加时,获取新单据号。编辑的逻辑是先删除后新增。
|
||||
export function getBusNo () {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/stockIn-order/busNo-init',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
// 添加/编辑采购单:添加/编辑采购单
|
||||
export function addOrEditOrder (data) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/stockIn-order/addOrEdit-stockInOrder',
|
||||
method: 'PUT',
|
||||
data,
|
||||
});
|
||||
}
|
||||
// 删除单据
|
||||
export function deleteOrder (data) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/stockIn-order/delete-stockInOrder?busNo=' +
|
||||
data,
|
||||
method: 'DELETE',
|
||||
});
|
||||
}
|
||||
// 同意审批
|
||||
export function agreeApproval (data) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/stockIn-order/agree-approval?busNo=' + data,
|
||||
method: 'PUT',
|
||||
});
|
||||
}
|
||||
// 获取单据详情
|
||||
export function getOrderDetail (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/stockIn-order/stockIn-order-detail-page',
|
||||
method: 'GET',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
// 订货单单据列表
|
||||
export function getPurchaseOrderList (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/purchase-order/purchase-order-page',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
// 获取单据详情
|
||||
export function getPurchaseOrderDetail (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/purchase-order/purchase-order-detail-page',
|
||||
method: 'GET',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-table ref="medicineRef" height="400" :data="medicineList" @cell-click="clickRow">
|
||||
<el-table-column label="项目编码" align="center" prop="busNo" width="150" />
|
||||
<el-table-column label="项目名称" align="center" prop="name" width="180" />
|
||||
<el-table-column label="进货价" align="center" prop="price" />
|
||||
<el-table-column label="零售价" align="center" prop="retailPrice" />
|
||||
<el-table-column label="包装单位" align="center" prop="unitCode_dictText" />
|
||||
<el-table-column label="最小单位" align="center" prop="minUnitCode_dictText" />
|
||||
<el-table-column label="规格" align="center" prop="totalVolume" />
|
||||
<el-table-column label="规格库存" align="center" prop="specificationInventory" />
|
||||
<!-- <el-table-column label="批次库存" align="center" prop="batchInventory" /> -->
|
||||
<el-table-column label="生产厂家" align="center" prop="manufacturerText" />
|
||||
<el-table-column label="批准文号" align="center" prop="approvalNumber" />
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getMedicineList } from './api';
|
||||
import { watch } from 'vue';
|
||||
import { throttle } from 'lodash-es';
|
||||
|
||||
const props = defineProps({
|
||||
searchKey: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
// 选择药品
|
||||
const emit = defineEmits(['selectRow']);
|
||||
//
|
||||
const queryParams = ref({
|
||||
pageNum: 1,
|
||||
pageSize: 50,
|
||||
searchKey: props.searchKey,
|
||||
});
|
||||
// 药品列表
|
||||
const medicineList = ref([]);
|
||||
|
||||
// 节流函数
|
||||
const throttledGetList = throttle(
|
||||
() => {
|
||||
getList();
|
||||
},
|
||||
300,
|
||||
{ leading: true, trailing: true }
|
||||
);
|
||||
|
||||
// 获取药品列表
|
||||
const getList = (query) => {
|
||||
getMedicineList(query || queryParams.value).then((res) => {
|
||||
medicineList.value = res.data.records;
|
||||
});
|
||||
};
|
||||
|
||||
// 点击行
|
||||
const clickRow = (row) => {
|
||||
// console.log(row, 'row');
|
||||
emit('selectRow', row);
|
||||
};
|
||||
|
||||
// 监听搜索关键字
|
||||
watch(
|
||||
() => props,
|
||||
(newValue) => {
|
||||
queryParams.value.searchKey = newValue.searchKey;
|
||||
throttledGetList();
|
||||
},
|
||||
{ immdiate: true, deep: true }
|
||||
);
|
||||
|
||||
// 获取药品列表
|
||||
getList();
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,350 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog
|
||||
title="订单列表"
|
||||
v-model="localDialogVisible"
|
||||
width="960px"
|
||||
append-to-body
|
||||
@close="resetAllData"
|
||||
>
|
||||
<el-table
|
||||
:data="orderList"
|
||||
ref="tableRef"
|
||||
width="100%"
|
||||
highlight-current-row
|
||||
height="470px"
|
||||
@row-dblclick="handleRowDBClick"
|
||||
@row-click="handleRowClick"
|
||||
>
|
||||
<el-table-column
|
||||
label="订单编号"
|
||||
prop="supplyBusNo"
|
||||
width="200"
|
||||
align="center"
|
||||
></el-table-column>
|
||||
<el-table-column label="采购员" prop="applicantId_dictText" width="100" align="center" />
|
||||
<el-table-column label="供应商" prop="supplierId_dictText" width="220" align="center" />
|
||||
<el-table-column label="审核状态" prop="statusEnum_enumText" width="100" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.statusEnum_enumText === '同意'" type="success">
|
||||
{{ scope.row.statusEnum_enumText }}
|
||||
</el-tag>
|
||||
<el-tag v-else type="danger">{{ scope.row.statusEnum_enumText }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="单据类型" prop="typeEnum_enumText" width="100" align="center" />
|
||||
<el-table-column label="单据日期" prop="applyTime" width="200" align="center">
|
||||
<template #default="scope">
|
||||
{{ parseTime(scope.row.applyTime, '{yy}-{mm}-{dd} {hh}:{ii}:{ss}') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-row justify="end" style="margin-top: 10px">
|
||||
<el-pagination
|
||||
:current-page="queryParams.pageNo"
|
||||
:page-size="queryParams.pageSize"
|
||||
:page-sizes="[10, 50, 100, 200]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="localTableDataTotal"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
v-show="localTableDataTotal > 0"
|
||||
/>
|
||||
</el-row>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="handleCancel">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit"> 确认 </el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getPurchaseOrderList, getPurchaseOrderDetail } from './api';
|
||||
import { ref, watch, getCurrentInstance } from 'vue';
|
||||
import { parseTime } from '@/utils/his';
|
||||
// 调用父组件方法
|
||||
const emit = defineEmits(['dialogSubmit', 'dialogCancel', 'updateTableData']);
|
||||
// 获取当前实例
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
// 属性
|
||||
const props = defineProps({
|
||||
// 对话框x显示
|
||||
dialogVisible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
// 本地对话框显示
|
||||
const localDialogVisible = ref(false);
|
||||
// 监听属性
|
||||
watch(
|
||||
() => props.dialogVisible,
|
||||
(newValue) => {
|
||||
localDialogVisible.value = newValue;
|
||||
}
|
||||
);
|
||||
// 获取当前行
|
||||
const currentRow = ref({});
|
||||
// 行点击 双击
|
||||
const handleRowClick = (row) => {
|
||||
// 设置当前行
|
||||
currentRow.value = row;
|
||||
};
|
||||
// 行点击 双击
|
||||
const handleRowDBClick = (row) => {
|
||||
// 设置当前行
|
||||
currentRow.value = row;
|
||||
// 提交
|
||||
handleSubmit();
|
||||
};
|
||||
// 订单列表
|
||||
const orderList = ref([]);
|
||||
// 订单列表总条数
|
||||
const localTableDataTotal = ref(0);
|
||||
// 当前locationId
|
||||
const currentLocationId = ref(undefined);
|
||||
// 查询参数
|
||||
const queryParams = ref({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
locationId: undefined,
|
||||
});
|
||||
// 分页每页条数
|
||||
const handleSizeChange = (size) => {
|
||||
queryParams.value.pageSize = size;
|
||||
queryParams.value.pageNo = 1; // 切换每页条数时重置到第一页
|
||||
// 重新获取数据
|
||||
if (currentLocationId.value) {
|
||||
getOrderList(currentLocationId.value);
|
||||
}
|
||||
};
|
||||
// 分页当前页
|
||||
const handleCurrentChange = (page) => {
|
||||
queryParams.value.pageNo = page;
|
||||
// 重新获取数据
|
||||
if (currentLocationId.value) {
|
||||
getOrderList(currentLocationId.value);
|
||||
}
|
||||
};
|
||||
|
||||
// 获取订货单列表
|
||||
const getOrderList = async (locationId) => {
|
||||
try {
|
||||
// 保存当前locationId
|
||||
currentLocationId.value = locationId;
|
||||
|
||||
// 构建请求参数
|
||||
const requestParams = {
|
||||
// 仓库ID
|
||||
locationId: locationId,
|
||||
// 页码
|
||||
pageNo: queryParams.value.pageNo,
|
||||
// 每页条数
|
||||
pageSize: queryParams.value.pageSize,
|
||||
// 订单状态 3 :审核通过
|
||||
statusEnum: 3,
|
||||
// 是否查询原始单
|
||||
originalBusNoFlg: 1,
|
||||
};
|
||||
const res = await getPurchaseOrderList(requestParams);
|
||||
if (res.data.records && res.data.records.length > 0) {
|
||||
// 订货单列表
|
||||
orderList.value = res.data.records || [];
|
||||
// 订货单列表总条数
|
||||
localTableDataTotal.value = res.data.total;
|
||||
} else {
|
||||
proxy.$message.error('获取订货单列表失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取订货单列表失败:', error);
|
||||
}
|
||||
};
|
||||
// 重置所有数据
|
||||
const resetAllData = () => {
|
||||
// 重置分页参数
|
||||
queryParams.value.pageNo = 1;
|
||||
queryParams.value.pageSize = 10;
|
||||
currentLocationId.value = undefined;
|
||||
orderList.value = [];
|
||||
localTableDataTotal.value = 0;
|
||||
};
|
||||
// 提交数据
|
||||
const handleSubmit = async () => {
|
||||
// 取消按钮
|
||||
handleCancel();
|
||||
// 获取当前进货单的订单列表
|
||||
await getCurrentOrderDetail();
|
||||
// 传递数据给父组件
|
||||
emit('updateTableData', {
|
||||
currentOrderList: setCurrentOrderList.value,
|
||||
currentOrderForm: setCurrentOrderForm.value,
|
||||
});
|
||||
};
|
||||
// 设置当前进货单的订单列表
|
||||
const setCurrentOrderList = ref([]);
|
||||
// 设置当前进货单的订单表单
|
||||
const setCurrentOrderForm = ref({});
|
||||
|
||||
// 获取当前进货单的订单列表
|
||||
const getCurrentOrderDetail = async () => {
|
||||
if (!currentRow.value.supplyBusNo) {
|
||||
return;
|
||||
}
|
||||
const res = await getPurchaseOrderDetail({ busNo: currentRow.value.supplyBusNo });
|
||||
// 构建编辑后的表单数据
|
||||
buildEditForm(res.data.records);
|
||||
};
|
||||
// 构建编辑后的表单数据
|
||||
const buildEditForm = (data) => {
|
||||
// 构建表格数据
|
||||
if (data.length > 0) {
|
||||
// 表单数据
|
||||
setCurrentOrderForm.value = {
|
||||
// 供应商
|
||||
supplierId: data[0].supplierId,
|
||||
// 供应商联系人
|
||||
phone: data[0].phone,
|
||||
// 采购员
|
||||
practitionerId: data[0].applicantId,
|
||||
// 原始单据号
|
||||
originalBusNo: data[0].busNo,
|
||||
};
|
||||
// 表格数据
|
||||
data.forEach((item) => {
|
||||
// 表格编辑状态
|
||||
item.isEditing = true;
|
||||
// 表格查看状态
|
||||
item.isViewing = false;
|
||||
// 判断当前单位是否是最大单位
|
||||
buildPrice(item);
|
||||
// 构建单位列表
|
||||
buildUnitList(item);
|
||||
});
|
||||
// 更新表格数据
|
||||
setCurrentOrderList.value = data;
|
||||
}
|
||||
};
|
||||
// 构建进货价和销售价
|
||||
const buildPrice = (item) => {
|
||||
// 判断当前单位是最大单位还是最小单位
|
||||
const isMaxUnit = item.unitCode === item.maxUnitCode;
|
||||
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 = (item) => {
|
||||
// 表格单位列表
|
||||
(item.unitList || []).forEach((unit) => {
|
||||
// 判断当前单位是最大单位还是最小单位
|
||||
const isMaxUnit = unit.value === item.maxUnitCode;
|
||||
const isMinUnit = unit.value === item.minUnitCode;
|
||||
|
||||
// // 进货价(假)
|
||||
unit.priceMask = item.price;
|
||||
|
||||
// 销售价(假)
|
||||
unit.retailPriceMask = item.retailPrice;
|
||||
|
||||
// 进价金额(假)
|
||||
unit.totalPriceMask = (parseFloat(item.price) * parseFloat(item.itemQuantity)).toFixed(2);
|
||||
|
||||
// 销售金额(假)
|
||||
unit.totalRetailPriceMask = (
|
||||
parseFloat(item.retailPrice) * parseFloat(item.itemQuantity)
|
||||
).toFixed(2);
|
||||
|
||||
// 规格库存
|
||||
unit.specificationInventoryOriginal = item.specificationInventory;
|
||||
|
||||
// 规格库存显示逻辑
|
||||
if (isMaxUnit) {
|
||||
// 最大单位:显示为 "X盒"
|
||||
unit.specificationInventoryMax = Math.floor(
|
||||
item.specificationInventory / parseInt(item.partPercent)
|
||||
);
|
||||
unit.specificationInventoryMaxUnit =
|
||||
unit.specificationInventoryMax > 0 ? item.maxUnitCode_dictText : '';
|
||||
unit.specificationInventoryMin = item.specificationInventory % parseInt(item.partPercent);
|
||||
unit.specificationInventoryMinUnit =
|
||||
unit.specificationInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
|
||||
// 批次库存
|
||||
unit.batchInventoryMax = Math.floor(item.batchInventory / parseInt(item.partPercent));
|
||||
unit.batchInventoryMaxUnit = unit.batchInventoryMax > 0 ? item.maxUnitCode_dictText : '';
|
||||
unit.batchInventoryMin = item.batchInventory % parseInt(item.partPercent);
|
||||
unit.batchInventoryMinUnit = unit.batchInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
} else if (isMinUnit) {
|
||||
// 最小单位:显示为 "X瓶"
|
||||
unit.specificationInventoryMax = item.specificationInventory;
|
||||
unit.specificationInventoryMaxUnit =
|
||||
unit.specificationInventoryMax > 0 ? item.minUnitCode_dictText : '';
|
||||
unit.specificationInventoryMin = 0;
|
||||
unit.specificationInventoryMinUnit =
|
||||
unit.specificationInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
|
||||
// 批次库存
|
||||
unit.batchInventoryMax = item.batchInventory;
|
||||
unit.batchInventoryMaxUnit = unit.batchInventoryMax > 0 ? item.minUnitCode_dictText : '';
|
||||
unit.batchInventoryMin = 0;
|
||||
unit.batchInventoryMinUnit = unit.batchInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
} else {
|
||||
// 其他单位:显示为 "X瓶"
|
||||
unit.specificationInventoryMax = item.specificationInventory;
|
||||
unit.specificationInventoryMaxUnit =
|
||||
unit.specificationInventoryMax > 0 ? item.minUnitCode_dictText : '';
|
||||
unit.specificationInventoryMin = 0;
|
||||
unit.specificationInventoryMinUnit =
|
||||
unit.specificationInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
|
||||
// 批次库存
|
||||
unit.batchInventoryMax = item.batchInventory;
|
||||
unit.batchInventoryMaxUnit = unit.batchInventoryMax > 0 ? item.minUnitCode_dictText : '';
|
||||
unit.batchInventoryMin = 0;
|
||||
unit.batchInventoryMinUnit = unit.batchInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
}
|
||||
});
|
||||
};
|
||||
// 取消按钮
|
||||
const handleCancel = () => {
|
||||
emit('dialogCancel', {
|
||||
dialogVisible: false,
|
||||
});
|
||||
};
|
||||
defineOptions({
|
||||
name: 'orderDialog',
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
getOrderList,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
1056
openhis-ui-vue3/src/views/medicineStorage/stockInOrder/index.vue
Normal file
1056
openhis-ui-vue3/src/views/medicineStorage/stockInOrder/index.vue
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,83 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
// 药库订货单初始化
|
||||
export function getInit () {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/stockOut-order/init',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
// 订货单单据列表:显示所有单据 左边框
|
||||
export function getOrderList (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/stockOut-order/stockOut-order-page',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
// 根据供应商获取药品:对应添加/编辑时加下一行数据后,点击项目时调用的接口
|
||||
export function getMedicineList (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/stockOut-order/medication-info',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
// 获取单据号:添加时,获取新单据号。编辑的逻辑是先删除后新增。
|
||||
export function getBusNo () {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/stockOut-order/busNo-init',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
// 添加/编辑采购单:添加/编辑采购单
|
||||
export function addOrEditOrder (data) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/stockOut-order/addOrEdit-stockOutOrder',
|
||||
method: 'PUT',
|
||||
data,
|
||||
});
|
||||
}
|
||||
// 删除单据
|
||||
export function deleteOrder (data) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/stockOut-order/delete-stockOutOrder?busNo=' +
|
||||
data,
|
||||
method: 'DELETE',
|
||||
});
|
||||
}
|
||||
// 同意审批
|
||||
export function agreeApproval (data) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/stockOut-order/agree-approval?busNo=' + data,
|
||||
method: 'PUT',
|
||||
});
|
||||
}
|
||||
// 获取单据详情
|
||||
export function getOrderDetail (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/stockOut-order/stockOut-order-detail-page',
|
||||
method: 'GET',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
// 订货单单据列表
|
||||
export function getPurchaseOrderList (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/purchase-order/purchase-order-page',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
// 获取单据详情
|
||||
export function getPurchaseOrderDetail (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/purchase-order/purchase-order-detail-page',
|
||||
method: 'GET',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-table ref="medicineRef" height="400" :data="medicineList" @cell-click="clickRow">
|
||||
<el-table-column label="项目编码" align="center" prop="busNo" width="150" />
|
||||
<el-table-column label="项目名称" align="center" prop="name" width="180" />
|
||||
<el-table-column label="进货价" align="center" prop="price" />
|
||||
<el-table-column label="零售价" align="center" prop="retailPrice" />
|
||||
<el-table-column label="包装单位" align="center" prop="unitCode_dictText" />
|
||||
<el-table-column label="最小单位" align="center" prop="minUnitCode_dictText" />
|
||||
<el-table-column label="规格" align="center" prop="totalVolume" />
|
||||
<el-table-column label="规格库存" align="center" prop="specificationInventory" />
|
||||
<el-table-column label="供应商" align="center" prop="supplierId_dictText" />
|
||||
<el-table-column label="生产厂家" align="center" prop="manufacturerText" />
|
||||
<el-table-column label="批准文号" align="center" prop="approvalNumber" />
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getMedicineList } from './api';
|
||||
import { watch } from 'vue';
|
||||
import { throttle } from 'lodash-es';
|
||||
|
||||
const props = defineProps({
|
||||
searchKey: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
locationId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
// 选择药品
|
||||
const emit = defineEmits(['selectRow']);
|
||||
//
|
||||
const queryParams = ref({
|
||||
pageNum: 1,
|
||||
pageSize: 50,
|
||||
searchKey: props.searchKey,
|
||||
});
|
||||
// 药品列表
|
||||
const medicineList = ref([]);
|
||||
|
||||
// 节流函数
|
||||
const throttledGetList = throttle(
|
||||
() => {
|
||||
getList();
|
||||
},
|
||||
300,
|
||||
{ leading: true, trailing: true }
|
||||
);
|
||||
|
||||
// 获取药品列表
|
||||
const getList = (query) => {
|
||||
queryParams.value = {
|
||||
...queryParams.value,
|
||||
...query,
|
||||
locationId: props.locationId,
|
||||
}
|
||||
getMedicineList(query || queryParams.value).then((res) => {
|
||||
medicineList.value = res.data.records;
|
||||
});
|
||||
};
|
||||
|
||||
// 点击行
|
||||
const clickRow = (row) => {
|
||||
// console.log(row, 'row');
|
||||
emit('selectRow', row);
|
||||
};
|
||||
|
||||
// 监听搜索关键字
|
||||
watch(
|
||||
() => props,
|
||||
(newValue) => {
|
||||
queryParams.value.searchKey = newValue.searchKey;
|
||||
throttledGetList();
|
||||
},
|
||||
{ immdiate: true, deep: true }
|
||||
);
|
||||
|
||||
// 获取药品列表
|
||||
getList();
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,343 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog
|
||||
title="订单列表"
|
||||
v-model="localDialogVisible"
|
||||
width="960px"
|
||||
append-to-body
|
||||
@close="resetAllData"
|
||||
>
|
||||
<el-table
|
||||
:data="orderList"
|
||||
ref="tableRef"
|
||||
width="100%"
|
||||
highlight-current-row
|
||||
height="470px"
|
||||
@row-dblclick="handleRowDBClick"
|
||||
@row-click="handleRowClick"
|
||||
>
|
||||
<el-table-column
|
||||
label="订单编号"
|
||||
prop="supplyBusNo"
|
||||
width="200"
|
||||
align="center"
|
||||
></el-table-column>
|
||||
<el-table-column label="采购员" prop="applicantId_dictText" width="100" align="center" />
|
||||
<el-table-column label="供应商" prop="supplierId_dictText" width="220" align="center" />
|
||||
<el-table-column label="审核状态" prop="statusEnum_enumText" width="100" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.statusEnum_enumText === '同意'" type="success">
|
||||
{{ scope.row.statusEnum_enumText }}
|
||||
</el-tag>
|
||||
<el-tag v-else type="danger">{{ scope.row.statusEnum_enumText }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="单据类型" prop="typeEnum_enumText" width="100" align="center" />
|
||||
<el-table-column label="单据日期" prop="applyTime" width="200" align="center">
|
||||
<template #default="scope">
|
||||
{{ parseTime(scope.row.applyTime, '{yy}-{mm}-{dd} {hh}:{ii}:{ss}') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-row justify="end" style="margin-top: 10px">
|
||||
<el-pagination
|
||||
:current-page="queryParams.pageNo"
|
||||
:page-size="queryParams.pageSize"
|
||||
:page-sizes="[10, 50, 100, 200]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="localTableDataTotal"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
v-show="localTableDataTotal > 0"
|
||||
/>
|
||||
</el-row>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="handleCancel">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit"> 确认 </el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getPurchaseOrderList, getPurchaseOrderDetail } from './api';
|
||||
import { ref, watch, getCurrentInstance } from 'vue';
|
||||
import { parseTime } from '@/utils/his';
|
||||
// 调用父组件方法
|
||||
const emit = defineEmits(['dialogSubmit', 'dialogCancel', 'updateTableData']);
|
||||
// 获取当前实例
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
// 属性
|
||||
const props = defineProps({
|
||||
// 对话框x显示
|
||||
dialogVisible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
// 本地对话框显示
|
||||
const localDialogVisible = ref(false);
|
||||
// 监听属性
|
||||
watch(
|
||||
() => props.dialogVisible,
|
||||
(newValue) => {
|
||||
localDialogVisible.value = newValue;
|
||||
}
|
||||
);
|
||||
// 获取当前行
|
||||
const currentRow = ref({});
|
||||
// 行点击 双击
|
||||
const handleRowClick = (row) => {
|
||||
// 设置当前行
|
||||
currentRow.value = row;
|
||||
};
|
||||
// 行点击 双击
|
||||
const handleRowDBClick = (row) => {
|
||||
// 设置当前行
|
||||
currentRow.value = row;
|
||||
// 提交
|
||||
handleSubmit();
|
||||
};
|
||||
// 订单列表
|
||||
const orderList = ref([]);
|
||||
// 订单列表总条数
|
||||
const localTableDataTotal = ref(0);
|
||||
// 当前locationId
|
||||
const currentLocationId = ref(undefined);
|
||||
// 查询参数
|
||||
const queryParams = ref({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
locationId: undefined,
|
||||
});
|
||||
// 分页每页条数
|
||||
const handleSizeChange = (size) => {
|
||||
queryParams.value.pageSize = size;
|
||||
queryParams.value.pageNo = 1; // 切换每页条数时重置到第一页
|
||||
// 重新获取数据
|
||||
if (currentLocationId.value) {
|
||||
getOrderList(currentLocationId.value);
|
||||
}
|
||||
};
|
||||
// 分页当前页
|
||||
const handleCurrentChange = (page) => {
|
||||
queryParams.value.pageNo = page;
|
||||
// 重新获取数据
|
||||
if (currentLocationId.value) {
|
||||
getOrderList(currentLocationId.value);
|
||||
}
|
||||
};
|
||||
|
||||
// 获取订货单列表
|
||||
const getOrderList = async (locationId) => {
|
||||
try {
|
||||
// 保存当前locationId
|
||||
currentLocationId.value = locationId;
|
||||
|
||||
// 构建请求参数
|
||||
const requestParams = {
|
||||
// 仓库ID
|
||||
locationId: locationId,
|
||||
// 页码
|
||||
pageNo: queryParams.value.pageNo,
|
||||
// 每页条数
|
||||
pageSize: queryParams.value.pageSize,
|
||||
// 订单状态 3 :审核通过
|
||||
statusEnum: 3,
|
||||
};
|
||||
const res = await getPurchaseOrderList(requestParams);
|
||||
if (res.data.records && res.data.records.length > 0) {
|
||||
// 订货单列表
|
||||
orderList.value = res.data.records || [];
|
||||
// 订货单列表总条数
|
||||
localTableDataTotal.value = res.data.total;
|
||||
} else {
|
||||
proxy.$message.error('获取订货单列表失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取订货单列表失败:', error);
|
||||
}
|
||||
};
|
||||
// 重置所有数据
|
||||
const resetAllData = () => {
|
||||
// 重置分页参数
|
||||
queryParams.value.pageNo = 1;
|
||||
queryParams.value.pageSize = 10;
|
||||
currentLocationId.value = undefined;
|
||||
orderList.value = [];
|
||||
localTableDataTotal.value = 0;
|
||||
};
|
||||
// 提交数据
|
||||
const handleSubmit = async () => {
|
||||
// 取消按钮
|
||||
handleCancel();
|
||||
// 获取当前进货单的订单列表
|
||||
await getCurrentOrderDetail();
|
||||
// 传递数据给父组件
|
||||
emit('updateTableData', {
|
||||
currentOrderList: setCurrentOrderList.value,
|
||||
currentOrderForm: setCurrentOrderForm.value,
|
||||
});
|
||||
};
|
||||
// 设置当前进货单的订单列表
|
||||
const setCurrentOrderList = ref([]);
|
||||
// 设置当前进货单的订单表单
|
||||
const setCurrentOrderForm = ref({});
|
||||
|
||||
// 获取当前进货单的订单列表
|
||||
const getCurrentOrderDetail = async () => {
|
||||
const res = await getPurchaseOrderDetail({ busNo: currentRow.value.supplyBusNo });
|
||||
// 构建编辑后的表单数据
|
||||
buildEditForm(res.data.records);
|
||||
};
|
||||
// 构建编辑后的表单数据
|
||||
const buildEditForm = (data) => {
|
||||
// 构建表格数据
|
||||
if (data.length > 0) {
|
||||
// 表单数据
|
||||
setCurrentOrderForm.value = {
|
||||
// 供应商
|
||||
supplierId: data[0].supplierId,
|
||||
// 供应商联系人
|
||||
phone: data[0].phone,
|
||||
// 采购员
|
||||
practitionerId: data[0].applicantId,
|
||||
};
|
||||
// 表格数据
|
||||
data.forEach((item) => {
|
||||
// 表格编辑状态
|
||||
item.isEditing = true;
|
||||
// 表格查看状态
|
||||
item.isViewing = false;
|
||||
// 判断当前单位是否是最大单位
|
||||
buildPrice(item);
|
||||
// 构建单位列表
|
||||
buildUnitList(item);
|
||||
});
|
||||
// 更新表格数据
|
||||
setCurrentOrderList.value = data;
|
||||
}
|
||||
};
|
||||
// 构建进货价和销售价
|
||||
const buildPrice = (item) => {
|
||||
// 判断当前单位是最大单位还是最小单位
|
||||
const isMaxUnit = item.unitCode === item.maxUnitCode;
|
||||
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 = (item) => {
|
||||
// 表格单位列表
|
||||
(item.unitList || []).forEach((unit) => {
|
||||
// 判断当前单位是最大单位还是最小单位
|
||||
const isMaxUnit = unit.value === item.maxUnitCode;
|
||||
const isMinUnit = unit.value === item.minUnitCode;
|
||||
|
||||
// // 进货价(假)
|
||||
unit.priceMask = item.price;
|
||||
|
||||
// 销售价(假)
|
||||
unit.retailPriceMask = item.retailPrice;
|
||||
|
||||
// 进价金额(假)
|
||||
unit.totalPriceMask = (parseFloat(item.price) * parseFloat(item.itemQuantity)).toFixed(2);
|
||||
|
||||
// 销售金额(假)
|
||||
unit.totalRetailPriceMask = (
|
||||
parseFloat(item.retailPrice) * parseFloat(item.itemQuantity)
|
||||
).toFixed(2);
|
||||
|
||||
// 规格库存
|
||||
unit.specificationInventoryOriginal = item.specificationInventory;
|
||||
|
||||
// 规格库存显示逻辑
|
||||
if (isMaxUnit) {
|
||||
// 最大单位:显示为 "X盒"
|
||||
unit.specificationInventoryMax = Math.floor(
|
||||
item.specificationInventory / parseInt(item.partPercent)
|
||||
);
|
||||
unit.specificationInventoryMaxUnit =
|
||||
unit.specificationInventoryMax > 0 ? item.maxUnitCode_dictText : '';
|
||||
unit.specificationInventoryMin = item.specificationInventory % parseInt(item.partPercent);
|
||||
unit.specificationInventoryMinUnit =
|
||||
unit.specificationInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
|
||||
// 批次库存
|
||||
unit.batchInventoryMax = Math.floor(item.batchInventory / parseInt(item.partPercent));
|
||||
unit.batchInventoryMaxUnit = unit.batchInventoryMax > 0 ? item.maxUnitCode_dictText : '';
|
||||
unit.batchInventoryMin = item.batchInventory % parseInt(item.partPercent);
|
||||
unit.batchInventoryMinUnit = unit.batchInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
} else if (isMinUnit) {
|
||||
// 最小单位:显示为 "X瓶"
|
||||
unit.specificationInventoryMax = item.specificationInventory;
|
||||
unit.specificationInventoryMaxUnit =
|
||||
unit.specificationInventoryMax > 0 ? item.minUnitCode_dictText : '';
|
||||
unit.specificationInventoryMin = 0;
|
||||
unit.specificationInventoryMinUnit =
|
||||
unit.specificationInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
|
||||
// 批次库存
|
||||
unit.batchInventoryMax = item.batchInventory;
|
||||
unit.batchInventoryMaxUnit = unit.batchInventoryMax > 0 ? item.minUnitCode_dictText : '';
|
||||
unit.batchInventoryMin = 0;
|
||||
unit.batchInventoryMinUnit = unit.batchInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
} else {
|
||||
// 其他单位:显示为 "X瓶"
|
||||
unit.specificationInventoryMax = item.specificationInventory;
|
||||
unit.specificationInventoryMaxUnit =
|
||||
unit.specificationInventoryMax > 0 ? item.minUnitCode_dictText : '';
|
||||
unit.specificationInventoryMin = 0;
|
||||
unit.specificationInventoryMinUnit =
|
||||
unit.specificationInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
|
||||
// 批次库存
|
||||
unit.batchInventoryMax = item.batchInventory;
|
||||
unit.batchInventoryMaxUnit = unit.batchInventoryMax > 0 ? item.minUnitCode_dictText : '';
|
||||
unit.batchInventoryMin = 0;
|
||||
unit.batchInventoryMinUnit = unit.batchInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
}
|
||||
});
|
||||
};
|
||||
// 取消按钮
|
||||
const handleCancel = () => {
|
||||
emit('dialogCancel', {
|
||||
dialogVisible: false,
|
||||
});
|
||||
};
|
||||
defineOptions({
|
||||
name: 'orderDialog',
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
getOrderList,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
1058
openhis-ui-vue3/src/views/medicineStorage/stockOutOrder/index.vue
Normal file
1058
openhis-ui-vue3/src/views/medicineStorage/stockOutOrder/index.vue
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,83 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
// 药库订货单初始化
|
||||
export function getInit () {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/stocktaking-order/init',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
// 订货单单据列表:显示所有单据 左边框
|
||||
export function getOrderList (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/stocktaking-order/stocktaking-order-page',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
// 根据供应商获取药品:对应添加/编辑时加下一行数据后,点击项目时调用的接口
|
||||
export function getMedicineList (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/stocktaking-order/medication-info',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
// 获取单据号:添加时,获取新单据号。编辑的逻辑是先删除后新增。
|
||||
export function getBusNo () {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/stocktaking-order/busNo-init',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
// 添加/编辑采购单:添加/编辑采购单
|
||||
export function addOrEditOrder (data) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/stocktaking-order/addOrEdit-stocktakingOrder',
|
||||
method: 'PUT',
|
||||
data,
|
||||
});
|
||||
}
|
||||
// 删除单据
|
||||
export function deleteOrder (data) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/stocktaking-order/delete-stocktakingOrder?busNo=' +
|
||||
data,
|
||||
method: 'DELETE',
|
||||
});
|
||||
}
|
||||
// 同意审批
|
||||
export function agreeApproval (data) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/stocktaking-order/agree-approval?busNo=' + data,
|
||||
method: 'PUT',
|
||||
});
|
||||
}
|
||||
// 获取单据详情
|
||||
export function getOrderDetail (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/stocktaking-order/stocktaking-order-detail-page',
|
||||
method: 'GET',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
// 订货单单据列表
|
||||
export function getPurchaseOrderList (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/purchase-order/purchase-order-page',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
// 获取单据详情
|
||||
export function getPurchaseOrderDetail (query) {
|
||||
return request ({
|
||||
url: '/pharmacy-warehouse/purchase-order/purchase-order-detail-page',
|
||||
method: 'GET',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-table ref="medicineRef" height="400" :data="medicineList" @cell-click="clickRow">
|
||||
<el-table-column label="项目编码" align="center" prop="busNo" width="150" />
|
||||
<el-table-column label="项目名称" align="center" prop="name" width="180" />
|
||||
<el-table-column label="进货价" align="center" prop="price" />
|
||||
<el-table-column label="零售价" align="center" prop="retailPrice" />
|
||||
<el-table-column label="包装单位" align="center" prop="unitCode_dictText" />
|
||||
<el-table-column label="最小单位" align="center" prop="minUnitCode_dictText" />
|
||||
<el-table-column label="规格" align="center" prop="totalVolume" />
|
||||
<el-table-column label="规格库存" align="center" prop="specificationInventory" />
|
||||
<el-table-column label="批次库存" align="center" prop="batchInventory" />
|
||||
<el-table-column label="供应商" align="center" prop="supplierId_dictText" />
|
||||
<el-table-column label="生产厂家" align="center" prop="manufacturerText" />
|
||||
<el-table-column label="批准文号" align="center" prop="approvalNumber" />
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getMedicineList } from './api';
|
||||
import { watch } from 'vue';
|
||||
import { throttle } from 'lodash-es';
|
||||
|
||||
const props = defineProps({
|
||||
searchKey: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
locationId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
// 选择药品
|
||||
const emit = defineEmits(['selectRow']);
|
||||
//
|
||||
const queryParams = ref({
|
||||
pageNum: 1,
|
||||
pageSize: 50,
|
||||
searchKey: props.searchKey,
|
||||
});
|
||||
// 药品列表
|
||||
const medicineList = ref([]);
|
||||
|
||||
// 节流函数
|
||||
const throttledGetList = throttle(
|
||||
() => {
|
||||
getList();
|
||||
},
|
||||
300,
|
||||
{ leading: true, trailing: true }
|
||||
);
|
||||
|
||||
// 获取药品列表
|
||||
const getList = (query) => {
|
||||
queryParams.value = {
|
||||
...queryParams.value,
|
||||
...query,
|
||||
locationId: props.locationId,
|
||||
}
|
||||
getMedicineList(query || queryParams.value).then((res) => {
|
||||
medicineList.value = res.data.records;
|
||||
});
|
||||
};
|
||||
|
||||
// 点击行
|
||||
const clickRow = (row) => {
|
||||
// console.log(row, 'row');
|
||||
emit('selectRow', row);
|
||||
};
|
||||
|
||||
// 监听搜索关键字
|
||||
watch(
|
||||
() => props,
|
||||
(newValue) => {
|
||||
queryParams.value.searchKey = newValue.searchKey;
|
||||
throttledGetList();
|
||||
},
|
||||
{ immdiate: true, deep: true }
|
||||
);
|
||||
|
||||
// 获取药品列表
|
||||
getList();
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,343 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog
|
||||
title="订单列表"
|
||||
v-model="localDialogVisible"
|
||||
width="960px"
|
||||
append-to-body
|
||||
@close="resetAllData"
|
||||
>
|
||||
<el-table
|
||||
:data="orderList"
|
||||
ref="tableRef"
|
||||
width="100%"
|
||||
highlight-current-row
|
||||
height="470px"
|
||||
@row-dblclick="handleRowDBClick"
|
||||
@row-click="handleRowClick"
|
||||
>
|
||||
<el-table-column
|
||||
label="订单编号"
|
||||
prop="supplyBusNo"
|
||||
width="200"
|
||||
align="center"
|
||||
></el-table-column>
|
||||
<el-table-column label="采购员" prop="applicantId_dictText" width="100" align="center" />
|
||||
<el-table-column label="供应商" prop="supplierId_dictText" width="220" align="center" />
|
||||
<el-table-column label="审核状态" prop="statusEnum_enumText" width="100" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.statusEnum_enumText === '同意'" type="success">
|
||||
{{ scope.row.statusEnum_enumText }}
|
||||
</el-tag>
|
||||
<el-tag v-else type="danger">{{ scope.row.statusEnum_enumText }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="单据类型" prop="typeEnum_enumText" width="100" align="center" />
|
||||
<el-table-column label="单据日期" prop="applyTime" width="200" align="center">
|
||||
<template #default="scope">
|
||||
{{ parseTime(scope.row.applyTime, '{yy}-{mm}-{dd} {hh}:{ii}:{ss}') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-row justify="end" style="margin-top: 10px">
|
||||
<el-pagination
|
||||
:current-page="queryParams.pageNo"
|
||||
:page-size="queryParams.pageSize"
|
||||
:page-sizes="[10, 50, 100, 200]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="localTableDataTotal"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
v-show="localTableDataTotal > 0"
|
||||
/>
|
||||
</el-row>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="handleCancel">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit"> 确认 </el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getPurchaseOrderList, getPurchaseOrderDetail } from './api';
|
||||
import { ref, watch, getCurrentInstance } from 'vue';
|
||||
import { parseTime } from '@/utils/his';
|
||||
// 调用父组件方法
|
||||
const emit = defineEmits(['dialogSubmit', 'dialogCancel', 'updateTableData']);
|
||||
// 获取当前实例
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
// 属性
|
||||
const props = defineProps({
|
||||
// 对话框x显示
|
||||
dialogVisible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
// 本地对话框显示
|
||||
const localDialogVisible = ref(false);
|
||||
// 监听属性
|
||||
watch(
|
||||
() => props.dialogVisible,
|
||||
(newValue) => {
|
||||
localDialogVisible.value = newValue;
|
||||
}
|
||||
);
|
||||
// 获取当前行
|
||||
const currentRow = ref({});
|
||||
// 行点击 双击
|
||||
const handleRowClick = (row) => {
|
||||
// 设置当前行
|
||||
currentRow.value = row;
|
||||
};
|
||||
// 行点击 双击
|
||||
const handleRowDBClick = (row) => {
|
||||
// 设置当前行
|
||||
currentRow.value = row;
|
||||
// 提交
|
||||
handleSubmit();
|
||||
};
|
||||
// 订单列表
|
||||
const orderList = ref([]);
|
||||
// 订单列表总条数
|
||||
const localTableDataTotal = ref(0);
|
||||
// 当前locationId
|
||||
const currentLocationId = ref(undefined);
|
||||
// 查询参数
|
||||
const queryParams = ref({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
locationId: undefined,
|
||||
});
|
||||
// 分页每页条数
|
||||
const handleSizeChange = (size) => {
|
||||
queryParams.value.pageSize = size;
|
||||
queryParams.value.pageNo = 1; // 切换每页条数时重置到第一页
|
||||
// 重新获取数据
|
||||
if (currentLocationId.value) {
|
||||
getOrderList(currentLocationId.value);
|
||||
}
|
||||
};
|
||||
// 分页当前页
|
||||
const handleCurrentChange = (page) => {
|
||||
queryParams.value.pageNo = page;
|
||||
// 重新获取数据
|
||||
if (currentLocationId.value) {
|
||||
getOrderList(currentLocationId.value);
|
||||
}
|
||||
};
|
||||
|
||||
// 获取订货单列表
|
||||
const getOrderList = async (locationId) => {
|
||||
try {
|
||||
// 保存当前locationId
|
||||
currentLocationId.value = locationId;
|
||||
|
||||
// 构建请求参数
|
||||
const requestParams = {
|
||||
// 仓库ID
|
||||
locationId: locationId,
|
||||
// 页码
|
||||
pageNo: queryParams.value.pageNo,
|
||||
// 每页条数
|
||||
pageSize: queryParams.value.pageSize,
|
||||
// 订单状态 3 :审核通过
|
||||
statusEnum: 3,
|
||||
};
|
||||
const res = await getPurchaseOrderList(requestParams);
|
||||
if (res.data.records && res.data.records.length > 0) {
|
||||
// 订货单列表
|
||||
orderList.value = res.data.records || [];
|
||||
// 订货单列表总条数
|
||||
localTableDataTotal.value = res.data.total;
|
||||
} else {
|
||||
proxy.$message.error('获取订货单列表失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取订货单列表失败:', error);
|
||||
}
|
||||
};
|
||||
// 重置所有数据
|
||||
const resetAllData = () => {
|
||||
// 重置分页参数
|
||||
queryParams.value.pageNo = 1;
|
||||
queryParams.value.pageSize = 10;
|
||||
currentLocationId.value = undefined;
|
||||
orderList.value = [];
|
||||
localTableDataTotal.value = 0;
|
||||
};
|
||||
// 提交数据
|
||||
const handleSubmit = async () => {
|
||||
// 取消按钮
|
||||
handleCancel();
|
||||
// 获取当前进货单的订单列表
|
||||
await getCurrentOrderDetail();
|
||||
// 传递数据给父组件
|
||||
emit('updateTableData', {
|
||||
currentOrderList: setCurrentOrderList.value,
|
||||
currentOrderForm: setCurrentOrderForm.value,
|
||||
});
|
||||
};
|
||||
// 设置当前进货单的订单列表
|
||||
const setCurrentOrderList = ref([]);
|
||||
// 设置当前进货单的订单表单
|
||||
const setCurrentOrderForm = ref({});
|
||||
|
||||
// 获取当前进货单的订单列表
|
||||
const getCurrentOrderDetail = async () => {
|
||||
const res = await getPurchaseOrderDetail({ busNo: currentRow.value.supplyBusNo });
|
||||
// 构建编辑后的表单数据
|
||||
buildEditForm(res.data.records);
|
||||
};
|
||||
// 构建编辑后的表单数据
|
||||
const buildEditForm = (data) => {
|
||||
// 构建表格数据
|
||||
if (data.length > 0) {
|
||||
// 表单数据
|
||||
setCurrentOrderForm.value = {
|
||||
// 供应商
|
||||
supplierId: data[0].supplierId,
|
||||
// 供应商联系人
|
||||
phone: data[0].phone,
|
||||
// 采购员
|
||||
practitionerId: data[0].applicantId,
|
||||
};
|
||||
// 表格数据
|
||||
data.forEach((item) => {
|
||||
// 表格编辑状态
|
||||
item.isEditing = true;
|
||||
// 表格查看状态
|
||||
item.isViewing = false;
|
||||
// 判断当前单位是否是最大单位
|
||||
buildPrice(item);
|
||||
// 构建单位列表
|
||||
buildUnitList(item);
|
||||
});
|
||||
// 更新表格数据
|
||||
setCurrentOrderList.value = data;
|
||||
}
|
||||
};
|
||||
// 构建进货价和销售价
|
||||
const buildPrice = (item) => {
|
||||
// 判断当前单位是最大单位还是最小单位
|
||||
const isMaxUnit = item.unitCode === item.maxUnitCode;
|
||||
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 = (item) => {
|
||||
// 表格单位列表
|
||||
(item.unitList || []).forEach((unit) => {
|
||||
// 判断当前单位是最大单位还是最小单位
|
||||
const isMaxUnit = unit.value === item.maxUnitCode;
|
||||
const isMinUnit = unit.value === item.minUnitCode;
|
||||
|
||||
// // 进货价(假)
|
||||
unit.priceMask = item.price;
|
||||
|
||||
// 销售价(假)
|
||||
unit.retailPriceMask = item.retailPrice;
|
||||
|
||||
// 进价金额(假)
|
||||
unit.totalPriceMask = (parseFloat(item.price) * parseFloat(item.itemQuantity)).toFixed(2);
|
||||
|
||||
// 销售金额(假)
|
||||
unit.totalRetailPriceMask = (
|
||||
parseFloat(item.retailPrice) * parseFloat(item.itemQuantity)
|
||||
).toFixed(2);
|
||||
|
||||
// 规格库存
|
||||
unit.specificationInventoryOriginal = item.specificationInventory;
|
||||
|
||||
// 规格库存显示逻辑
|
||||
if (isMaxUnit) {
|
||||
// 最大单位:显示为 "X盒"
|
||||
unit.specificationInventoryMax = Math.floor(
|
||||
item.specificationInventory / parseInt(item.partPercent)
|
||||
);
|
||||
unit.specificationInventoryMaxUnit =
|
||||
unit.specificationInventoryMax > 0 ? item.maxUnitCode_dictText : '';
|
||||
unit.specificationInventoryMin = item.specificationInventory % parseInt(item.partPercent);
|
||||
unit.specificationInventoryMinUnit =
|
||||
unit.specificationInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
|
||||
// 批次库存
|
||||
unit.batchInventoryMax = Math.floor(item.batchInventory / parseInt(item.partPercent));
|
||||
unit.batchInventoryMaxUnit = unit.batchInventoryMax > 0 ? item.maxUnitCode_dictText : '';
|
||||
unit.batchInventoryMin = item.batchInventory % parseInt(item.partPercent);
|
||||
unit.batchInventoryMinUnit = unit.batchInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
} else if (isMinUnit) {
|
||||
// 最小单位:显示为 "X瓶"
|
||||
unit.specificationInventoryMax = item.specificationInventory;
|
||||
unit.specificationInventoryMaxUnit =
|
||||
unit.specificationInventoryMax > 0 ? item.minUnitCode_dictText : '';
|
||||
unit.specificationInventoryMin = 0;
|
||||
unit.specificationInventoryMinUnit =
|
||||
unit.specificationInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
|
||||
// 批次库存
|
||||
unit.batchInventoryMax = item.batchInventory;
|
||||
unit.batchInventoryMaxUnit = unit.batchInventoryMax > 0 ? item.minUnitCode_dictText : '';
|
||||
unit.batchInventoryMin = 0;
|
||||
unit.batchInventoryMinUnit = unit.batchInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
} else {
|
||||
// 其他单位:显示为 "X瓶"
|
||||
unit.specificationInventoryMax = item.specificationInventory;
|
||||
unit.specificationInventoryMaxUnit =
|
||||
unit.specificationInventoryMax > 0 ? item.minUnitCode_dictText : '';
|
||||
unit.specificationInventoryMin = 0;
|
||||
unit.specificationInventoryMinUnit =
|
||||
unit.specificationInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
|
||||
// 批次库存
|
||||
unit.batchInventoryMax = item.batchInventory;
|
||||
unit.batchInventoryMaxUnit = unit.batchInventoryMax > 0 ? item.minUnitCode_dictText : '';
|
||||
unit.batchInventoryMin = 0;
|
||||
unit.batchInventoryMinUnit = unit.batchInventoryMin > 0 ? item.minUnitCode_dictText : '';
|
||||
}
|
||||
});
|
||||
};
|
||||
// 取消按钮
|
||||
const handleCancel = () => {
|
||||
emit('dialogCancel', {
|
||||
dialogVisible: false,
|
||||
});
|
||||
};
|
||||
defineOptions({
|
||||
name: 'orderDialog',
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
getOrderList,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
1071
openhis-ui-vue3/src/views/medicineStorage/stocktakingOrder/index.vue
Normal file
1071
openhis-ui-vue3/src/views/medicineStorage/stocktakingOrder/index.vue
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user