web/src/components/inventory/goods/Edit.vue

790 lines
28 KiB
Vue

<template>
<Mask :is-show="isShow" :height="900" @close="exit" title="新增" :show-footer="true">
<template #default>
<el-scrollbar>
<div class="header">
<el-button type="primary" style="margin-top: 10px" round class="btn" @click="openCreateSearch" v-if="_type!=0"
plain>
一键建档
</el-button>
</div>
<div class="common-layout">
<el-container>
<el-aside width="800px">
<div class="body">
<el-form ref="formRef"
:model="edit_data"
:rules="rules" style="width: 100%">
<el-descriptions title="基础" border direction="vertical">
<el-descriptions-item label="名称">
<el-form-item label="" prop="name" class="form-item">
<el-input v-model="edit_data.name"/>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="通用名">
<el-form-item label="" prop="commonName" class="form-item">
<el-input v-model="edit_data.commonName"/>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="类型" style="display: flex">
<el-form-item label="" prop="cateId" class="form-item">
<el-select v-model="edit_data.cateId" placeholder="请选择" style="width: 70%">
<el-option
v-for="item in cate_list"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
<el-button @click="showCateEdit">
<el-icon>
<Setting/>
</el-icon>
</el-button>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="进口|国产" v-if="_type==1306">
<el-select
v-model="edit_data.extra.maintainCate"
placeholder="进口|国产"
clearable
style="width: 240px"
>
<el-option
v-for="item in imported"
:key="item.label"
:label="item.label"
:value="item.label"
/>
</el-select>
</el-descriptions-item>
<el-descriptions-item label="效期预警(天)">
<el-form-item lable="" prop="expiryWarnDays" class="form-item">
<el-input-number v-model="edit_data.expiryWarnDays" class="input" style="width: 100%;" :min="0">
</el-input-number>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="库存预警">
<el-form-item lable="" prop="inventoryWarnNumber" class="form-item">
<el-input-number v-model="edit_data.inventoryWarnNumber" class="input" style="width: 100%;"
:min="0">
</el-input-number>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="批准文号" v-if="_type==1301">
<el-form-item lable="" prop="approvalCode" class="form-item">
<el-input v-model="edit_data.approvalCode" class="input">
</el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="批准文号" v-if="_type==1301">
<el-form-item lable="" prop="approvalCode" class="form-item">
<el-input v-model="edit_data.approvalCode" class="input">
</el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="进价参考">
<el-form-item label="" prop="purchaseUnitPrice" class="form-item">
<el-input v-model.number="edit_data.purchaseUnitPrice">
<template #append>元</template>
</el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="生产企业" v-if="_type!=1302">
<el-form-item label="" prop="producer" class="form-item">
<el-input v-model="edit_data.producer"/>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="注册证名称" v-if="_type==1306">
<el-form-item>
<el-input v-model="edit_data.extra.registrationCertificateName" class="input">
</el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="条形码">
<el-form-item>
<el-input v-model="edit_data.barcode"/>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="规格" v-if="_type==1302||_type==1306||_type==0">
<el-form-item>
<el-input v-model="edit_data.medicineDosageNum" class="input">
</el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="最小制剂数量|单位" v-if="_type==1301">
<el-form-item>
<div class="unit-item">
<el-input ref="medicineDosageRef" v-model="edit_data.medicineDosageNum" class="input"
style="width: 200px;">
</el-input>
<el-popover
placement="bottom"
title="Title"
:width="200"
trigger="click"
>
<template #reference>
<div class="unit">{{ edit_data.medicineDosageUnit }}</div>
</template>
<UnitSelector :units="dosageUnitList" v-model="edit_data.medicineDosageUnit"></UnitSelector>
</el-popover>
</div>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="最小包装数量|单位">
<el-form-item>
<div class="unit-item">
<el-input ref="minPackagingRef" v-model="edit_data.minPackagingNumber" type="number"
class="input"
style="width: 200px;">
</el-input>
<el-popover
placement="bottom"
title="Title"
:width="200"
trigger="click"
>
<template #reference>
<div class="unit">{{ edit_data.minPackagingUnit }}</div>
</template>
<UnitSelector :units="packagingUnit" v-model="edit_data.minPackagingUnit"></UnitSelector>
</el-popover>
</div>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="包装单位">
<el-form-item>
<div class="unit-item">
<el-popover
placement="bottom"
title="Title"
:width="200"
trigger="click"
>
<template #reference>
<div class="unit" style="width: 232px">{{ edit_data.packagingUnit }}</div>
</template>
<UnitSelector :units="packagingUnit" v-model="edit_data.packagingUnit"></UnitSelector>
</el-popover>
</div>
</el-form-item>
</el-descriptions-item>
<!-- <el-descriptions-item :label="_type==1301?'国药准字':'国械注准'" v-if="_type==1301 || _type==1306">-->
<!-- <el-input v-model="edit_data.approvalCode"/>-->
<!-- </el-descriptions-item>-->
<el-descriptions-item label="注册剂型" v-if="_type==1301">
<el-form-item>
<el-input v-model="edit_data.extra.regType" class="input">
</el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="药品标识码">
<el-form-item>
<el-popover
:visible="showPopover"
placement="bottom"
:width="200"
id="code-pop"
class="code-popo"
>
<div style="color: #6c6b6b;font-size: 12px">已关联({{
idCodeList ? idCodeList.length : 0
}})
</div>
<Divider/>
<div class="item">
<div v-for="(item,index) in idCodeList" :key="index">
<div class="remove">
<el-icon @click="removeIdCode(item)" id="code-remove">
<Close/>
</el-icon>
</div>
<div style="width: 70%" class="text">
{{ item }}
</div>
</div>
</div>
<template #reference>
<el-input v-model="idCode" id="code-input" @keydown.enter="addIdCode"
@click="clickIdCodeInput"></el-input>
</template>
</el-popover>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="标签">
<el-form-item>
<el-input-tag
draggable
v-model="edit_data.tags"
class="input"
>
</el-input-tag>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="备注">
<el-form-item>
<el-input v-model="edit_data.remark" class="input"/>
</el-form-item>
</el-descriptions-item>
</el-descriptions>
<el-descriptions title="扩展" border style="margin-top: 20px" direction="vertical">
<el-descriptions-item label="养护分类">
<el-select
v-model="edit_data.extra.maintainCate"
placeholder="选择养护分类"
clearable
style="width: 240px"
>
<el-option
v-for="item in maintainOptions"
:key="item.label"
:label="item.label"
:value="item.label"
/>
</el-select>
</el-descriptions-item>
<el-descriptions-item label="储存条件">
<el-select
v-model="edit_data.extra.storageConditions"
placeholder="选择养护分类"
clearable
style="width: 240px;"
>
<el-option
v-for="item in storageConditionsOptions"
:key="item.label"
:label="item.label"
:value="item.label"
/>
</el-select>
</el-descriptions-item>
<el-descriptions-item label="保质期">
<el-input v-model="edit_data.expiryTime" type="number">
<template #append>月</template>
</el-input>
</el-descriptions-item>
<el-descriptions-item label="柜号">
<el-input v-model="edit_data.extra.cabinetNumber">
</el-input>
</el-descriptions-item>
<el-descriptions-item label="用法用量" v-if="_type==1301">
<el-input v-model="edit_data.extra.usage">
</el-input>
</el-descriptions-item>
<el-descriptions-item label="处方药/OTC" v-if="_type==1301">
<el-select
v-model="edit_data.extra.drugCategory"
placeholder="选择药品分类"
clearable
style="width: 240px"
>
<el-option
v-for="item in drugCategoryOptions"
:key="item.label"
:label="item.label"
:value="item.label"
/>
</el-select>
</el-descriptions-item>
<el-descriptions-item label="精麻毒放|麻黄碱" v-if="_type==1301">
<el-select
v-model="edit_data.extra.JMDF"
placeholder="选择精麻毒放|麻黄碱"
clearable
style="width: 240px"
>
<el-option
v-for="item in JMDFList"
:key="item.label"
:label="item.label"
:value="item.label"
/>
</el-select>
</el-descriptions-item>
<el-descriptions-item label="抗菌药物" v-if="_type==1301">
<el-input v-model="edit_data.extra.isAntibacterialAgents"></el-input>
</el-descriptions-item>
<el-descriptions-item label="基药" v-if="_type==1301">
<el-input v-model="edit_data.extra.baseMedicine"></el-input>
</el-descriptions-item>
<el-descriptions-item label="医疗器械分类" v-if="_type==1306">
<el-input v-model="edit_data.extra.instrumentCategroy"></el-input>
</el-descriptions-item>
<el-descriptions-item label="上市许可持有人">
<el-input v-model="edit_data.extra.authorizationMaster"></el-input>
</el-descriptions-item>
<el-descriptions-item label="批准文号有效期" v-if="_type==1306">
<el-input v-model="edit_data.extra.approvalNumberExpirDate"></el-input>
</el-descriptions-item>
</el-descriptions>
</el-form>
</div>
</el-aside>
<el-aside width="350px" style="border-left: 1px #ddd solid">
<el-form style="width: 100%;" :rules="rules" ref="formRef" label-width="100px">
<el-descriptions title="定价" border direction="vertical" :column="2" style="margin-left: 5px">
<el-descriptions-item label="定价模式" width="180">
<el-select v-model="edit_data.pricingModel" placeholder="请选择">
<el-option
v-for="item in pricingModelOptions"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-descriptions-item>
<el-descriptions-item label="加成率" v-if="edit_data.pricingModel==1">
<el-input v-model="edit_data.makeUp" type="number">
<template #append>%</template>
</el-input>
</el-descriptions-item>
<el-descriptions-item label="零售价格" v-else>
<el-input v-model="edit_data.unitPrice" type="number"
>
<template #prefix>¥</template>
<template #append>/{{ edit_data.packagingUnit }}</template>
</el-input>
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<el-checkbox v-model="edit_data.trdnFlag" label="是否允许拆零" size="large"/>
</template>
<el-input v-model="edit_data.disassemblyPrice" type="number" :disabled="!edit_data.trdnFlag">
<template #prefix>¥</template>
<template #append>/{{ edit_data.minPackagingUnit }}</template>
</el-input>
</el-descriptions-item>
</el-descriptions>
<el-descriptions title="医保" border direction="vertical" :column="1" style="margin-left: 5px">
<el-descriptions-item label="医保对码">
<SocialInfo v-model="edit_data.hilistCode" v-if="edit_data.hilistCode"
@openSearch="openContrastCodeSearch"></SocialInfo>
</el-descriptions-item>
</el-descriptions>
</el-form>
</el-aside>
</el-container>
</div>
</el-scrollbar>
</template>
<template #footer>
<div class="footer">
<el-button @click="returnInit" type="primary" v-if="edit_data.id != null">医保库存重新初始化</el-button>
<el-button v-if="edit_data.saleStatus" type="danger" @click="disableSale">停售</el-button>
<el-button v-else type="danger" @click="enableSale">起售</el-button>
<el-button @click="save" type="primary">保存</el-button>
<el-button @click="exit" plain>关闭</el-button>
</div>
</template>
</Mask>
<!-- 新增关闭按钮 -->
<Search ref="createSearchRef" @confirm="createConfirm"/>
<Search ref="contrastCodeSearch" @confirm="contrastCodeConfirm"/>
<Cate :type="_type" @close="cateCloseCallBack" ref="cateRef"/>
</template>
<script setup lang="ts">
import {nextTick, ref, watch} from "vue";
import {dosageUnitList, packagingUnit} from "@/utils/unitList.ts"
import {Setting, Close} from "@element-plus/icons-vue";
import Mask from "@/components/common/Mask.vue";
import Search from "@/components/inventory/goods/Search.vue";
import {post} from "@/utils/request.ts";
import Cate from "@/components/inventory/goods/Cate.vue";
import {ElMessage, ElMessageBox} from "element-plus";
import Divider from "@/components/Divider.vue";
import UnitSelector from "@/components/inventory/UnitSelector.vue";
import SocialInfo from "@/components/inventory/goods/SocialInfo.vue";
import {apiConfig} from "@/assets/config/apiConfig.ts";
let _type = ref(0);
let type = ref(0);
const isShow = ref<any>(false)
const imported = [{
label: '进口',
}, {label: '国产'}]
const pricingModelOptions = [
{
label: '进价加成',
value: 1,
}, {
label: '固定售价',
value: 0,
}
]
const JMDFList = [
{
label: '精I',
},
{
label: '精II',
},
{
label: '麻',
},
{
label: '毒',
},
{
label: '放',
},
{
label: '麻黄碱',
}
]
const maintainOptions = [
{
label: '一般养护',
},
{
label: '重点养护',
},
{
label: '无需养护',
}
]
const storageConditionsOptions =
[
{
label: '常温',
}
,
{
label: '阴凉',
}
,
{
label: '冷藏',
}
,
{
label: '冷冻',
}
,
{
label: '避光',
}
,
{
label: '密封',
}
]
const emit = defineEmits(['close'])
let edit_data: any = ref({
trdnFlag: false,
extra: {},
minPackagingUnit: "只",
packagingUnit: "盒",
pricingModel: 0,
expiryWarnDays: 0,
});
const idCode = ref("");
const showPopover = ref(false);
const idCodeList = ref<string[]>([]);
const addIdCode = () => {
let index = idCodeList.value.indexOf(idCode.value);
if (index != -1) {
ElMessage({
message: '编码已存在',
type: 'warning',
plain: true,
})
return
}
if (idCode.value.length < 7 && (_type.value == 1301 || _type.value == 1302)) {
ElMessage({
message: '最少7位',
type: 'warning',
plain: true,
})
return
}
if (idCode.value.length > 7 && (_type.value == 1301 || _type.value == 1302)) {
idCode.value = idCode.value.substring(0, 7);
}
idCodeList.value.push(idCode.value);
idCode.value = "";
showPopover.value = true;
}
const removeIdCode = (item: string) => {
let index = idCodeList.value.indexOf(item);
if (index != -1) {
idCodeList.value.splice(index, 1)
}
showPopover.value = idCodeList.value.length > 0;
}
const init = (type: number, id: number) => {
isShow.value = true
_type.value = type;
if (id != null && id != 0) {
post("goods/goods/get", {id: id}).then((res: any) => {
edit_data.value = res;
edit_data.value.tags = edit_data.value.tags ? edit_data.value.tags.split(",") : null;
edit_data.value.extra = JSON.parse(edit_data.value.extra);
edit_data.value.trdnFlag = edit_data.value.trdnFlag ? edit_data.value.trdnFlag == 1 : false;
idCodeList.value = edit_data.value.idCode ? edit_data.value.idCode.split(",") : [];
idCode.value = idCodeList.value.length > 0 ? idCodeList.value.length + "项" : "";
getHilistInfo()
})
}
getCateList()
document.addEventListener("click", handleClickOutside);
};
defineExpose({init});
const createSearchRef = ref<InstanceType<typeof Search>>();
const openCreateSearch = () => {
nextTick(() => {
createSearchRef.value?.init(_type.value, edit_data.value.name);
});
}
const createConfirm = (data: any) => {
let id = edit_data.value.id
edit_data.value = data
edit_data.value.id = id
}
const contrastCodeSearch = ref()
const openContrastCodeSearch = () => {
nextTick(() => {
contrastCodeSearch.value?.init(_type.value, edit_data.value.name);
});
}
const contrastCodeConfirm = (data: any) => {
edit_data.value.hilistCode = data.hilistCode
}
let save = async () => {
try {
await formRef.value.validate()
const data = JSON.parse(JSON.stringify(edit_data.value));
data.tags = data.tags ? data.tags.join(",") : null;
data.idCode = idCodeList.value.join(",");
data.type = _type.value;
post("goods/goods/save", data).then((res: any) => {
exit()
})
// ...原有保存逻辑...
} catch (e) {
ElMessage.error('请正确填写表单内容')
}
}
//获取分类列表
const cate_list: any = ref([]);
const getCateList = () => {
post("goods/cate/list", {type: _type.value}).then((res: any) => {
cate_list.value = res
})
}
const cateRef = ref()
const showCateEdit = () => {
cateRef.value.init(cate_list.value)
}
const cateCloseCallBack = () => {
getCateList()
}
let exit = () => {
document.addEventListener("click", handleClickOutside);
isShow.value = false
edit_data.value = {}
emit('close');
}
const handleClickOutside = (event: MouseEvent) => {
const target = event.target as HTMLElement;
if (!target.closest('#code-pop') && !target.closest('#code-input') && !target.closest('#code-remove')) {
showPopover.value = false;
idCode.value = idCodeList.value.length > 0 ? idCodeList.value.length + "项" : "";
}
}
const clickIdCodeInput = () => {
showPopover.value = true
idCode.value = ""
}
const returnInit = () => {
ElMessageBox.confirm(
`确定要重新初始化医保库存码?`,
'提升',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
post("goods/goods/returnInit", {id: edit_data.value.id})
})
}
// 添加表单校验
const rules = ref({
name: [
{required: true, message: '商品名称不能为空', trigger: 'blur'},
],
cateId: [
{required: true, message: '请选择商品类型', trigger: 'change'}
],
approvalCode: [
{required: true, message: '批准文号不能为空', trigger: 'blur'}
],
purchaseUnitPrice: [
{type: 'number', message: '必须为数字', trigger: 'blur'},
],
producer: [
{required: true, message: '生产企业不能为空', trigger: 'blur'}
],
makeUp: [
{required: true, message: '不能为空', trigger: 'blur'}
],
unitPrice: [
{type: 'number', message: '不能为空', trigger: 'blur'},
]
})
// 修改保存逻辑
const formRef = ref()
const hilistInfo = ref<any>({})
const getHilistInfo = () => {
if (edit_data.value.hilistCode) {
post("social/directory/getByCode", {code: edit_data.value.hilistCode}).then((res: any) => {
hilistInfo.value = res
type.value = res.type
})
}
}
watch(() => edit_data.value.hilistCode, (newVal) => {
if (newVal) {
getHilistInfo()
}
})
const drugCategoryOptions = [
{
label: '西药',
value: 1301
},
{
label: '中药',
value: 1302
},
{
label: '非药品',
value: 1303
},
{
label: '其他',
value: 1304
}
]
const disableSale = () => {
ElMessageBox.confirm(
`确定要下架该商品吗?`,
'提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
post(apiConfig.GoodsDisableSale, {id: edit_data.value.id}).then((res: any) => {
ElMessage.success("下架成功")
exit()
})
})
}
const enableSale = () => {
ElMessageBox.confirm(
`确定要起售该商品吗?`,
'提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
post(apiConfig.GoodsEnableSale, {id: edit_data.value.id}).then((res: any) => {
ElMessage.success("启用成功")
exit()
})
})
}
</script>
<style scoped lang="scss">
.header {
.title {
font-size: 18px;
font-weight: bold;
}
.btn {
display: block;
width: 200px;
height: 40px;
margin: auto;
}
}
.common-layout {
margin-top: 10px;
padding: 0 24px 24px;
}
.item {
margin-top: 5px;
.text {
font-weight: bold;
}
.remove {
font-size: 16px;
position: absolute;
right: 15px;
&:hover {
color: #2e7eb3;
}
}
}
.unit-item {
display: flex;
.unit {
width: 32px;
height: 32px;
border: 1px #ddd solid;
color: #818080;
display: flex;
align-items: center;
justify-content: center;
}
}
.footer {
height: 100%;
display: flex;
justify-content: flex-end;
align-items: center;
padding: 0 24px;
}
</style>