|
@@ -479,10 +479,11 @@
|
|
|
<el-col :span="12">
|
|
<el-col :span="12">
|
|
|
<el-form-item label="商品分类" prop="cateId">
|
|
<el-form-item label="商品分类" prop="cateId">
|
|
|
<treeselect v-model="form.cateId" :options="categoryOptions" :normalizer="normalizer"
|
|
<treeselect v-model="form.cateId" :options="categoryOptions" :normalizer="normalizer"
|
|
|
- placeholder="请选择上级分类"/>
|
|
|
|
|
|
|
+ placeholder="请选择上级分类" @input="onCategoryOrStoreChange"/>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-col>
|
|
</el-col>
|
|
|
</el-row>
|
|
</el-row>
|
|
|
|
|
+
|
|
|
<el-row>
|
|
<el-row>
|
|
|
<el-col :span="12">
|
|
<el-col :span="12">
|
|
|
<el-form-item label="商品类型" prop="productType">
|
|
<el-form-item label="商品类型" prop="productType">
|
|
@@ -499,7 +500,7 @@
|
|
|
</el-col>
|
|
</el-col>
|
|
|
<el-col :span="12">
|
|
<el-col :span="12">
|
|
|
<el-form-item label="所属店铺" prop="storeId" v-if="medicalMallConfig.isStores">
|
|
<el-form-item label="所属店铺" prop="storeId" v-if="medicalMallConfig.isStores">
|
|
|
- <el-select style="width: 240px" v-model="form.storeId" placeholder="请选择店铺" clearable size="small">
|
|
|
|
|
|
|
+ <el-select style="width: 240px" v-model="form.storeId" placeholder="请选择店铺" clearable size="small" @change="onCategoryOrStoreChange">
|
|
|
<el-option
|
|
<el-option
|
|
|
v-for="item in storeOptions"
|
|
v-for="item in storeOptions"
|
|
|
:key="item.storeId"
|
|
:key="item.storeId"
|
|
@@ -511,6 +512,15 @@
|
|
|
</el-col>
|
|
</el-col>
|
|
|
</el-row>
|
|
</el-row>
|
|
|
|
|
|
|
|
|
|
+ <el-row>
|
|
|
|
|
+ <el-col :span="12">
|
|
|
|
|
+ <el-form-item label="器械编码" prop="medicalDeviceCode" v-if="showMedicalDeviceCode">
|
|
|
|
|
+ <el-input v-model="form.medicalDeviceCode" placeholder="请输入器械编码" @blur="onCategoryOrStoreChange" @input="onMedicalDeviceCodeInput" style="width: calc(100% - 120px);"/>
|
|
|
|
|
+ <el-button type="primary" @click="showExemptDeviceDialog" style="margin-left: 10px;">显示器免</el-button>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+
|
|
|
<el-row>
|
|
<el-row>
|
|
|
<el-col :span="12">
|
|
<el-col :span="12">
|
|
|
<el-form-item label="关键字" prop="keyword">
|
|
<el-form-item label="关键字" prop="keyword">
|
|
@@ -1096,9 +1106,39 @@
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
</el-table>
|
|
</el-table>
|
|
|
<span slot="footer" class="dialog-footer">
|
|
<span slot="footer" class="dialog-footer">
|
|
|
- <el-button type="primary" @click="authVisible = false">关 闭</el-button>
|
|
|
|
|
- </span>
|
|
|
|
|
|
|
+ <el-button type="primary" @click="authVisible = false">关 闭</el-button>
|
|
|
|
|
+ </span>
|
|
|
</el-dialog>
|
|
</el-dialog>
|
|
|
|
|
+
|
|
|
|
|
+<!-- 免于经营备案的第二类医疗器械产品弹窗 -->
|
|
|
|
|
+<el-dialog title="免于经营备案的第二类医疗器械产品" :visible.sync="exemptDeviceDialogVisible" width="80%" append-to-body modal-append-to-body="false" z-index="9999" top="5vh" custom-class="exempt-device-dialog">
|
|
|
|
|
+ <el-form :model="exemptDeviceQueryParams" ref="exemptDeviceQueryForm" :inline="true" label-width="80px">
|
|
|
|
|
+ <el-form-item label="产品名称">
|
|
|
|
|
+ <el-input v-model="exemptDeviceQueryParams.productName" placeholder="请输入产品名称" clearable size="small" @keyup.enter.native="handleExemptDeviceQuery" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item>
|
|
|
|
|
+ <el-button type="primary" icon="el-icon-search" size="mini" @click="handleExemptDeviceQuery">搜索</el-button>
|
|
|
|
|
+ <el-button icon="el-icon-refresh" size="mini" @click="resetExemptDeviceQuery">重置</el-button>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+
|
|
|
|
|
+ <el-table v-loading="exemptDeviceLoading" :data="exemptDeviceList" border>
|
|
|
|
|
+ <el-table-column label="产品序号" align="center" prop="serialNumber" />
|
|
|
|
|
+ <el-table-column label="产品名称" align="center" prop="productName" />
|
|
|
|
|
+ <el-table-column label="目录名称" align="center" prop="directoryName" />
|
|
|
|
|
+ <el-table-column label="产品描述" align="center" prop="productDescription" />
|
|
|
|
|
+ <el-table-column label="产品用途" align="center" prop="usageStr" />
|
|
|
|
|
+ <el-table-column label="创建时间" align="center" prop="createTime" width="180" />
|
|
|
|
|
+ <el-table-column label="更新时间" align="center" prop="updateTime" width="180" />
|
|
|
|
|
+ </el-table>
|
|
|
|
|
+
|
|
|
|
|
+ <div slot="footer" class="dialog-footer">
|
|
|
|
|
+ <el-button @click="exemptDeviceDialogVisible = false">关 闭</el-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</el-dialog>
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
@@ -1113,7 +1153,7 @@ import {
|
|
|
importTemplate,
|
|
importTemplate,
|
|
|
batchModify,
|
|
batchModify,
|
|
|
sync580,
|
|
sync580,
|
|
|
- updateIsShow, exportDrugProduct,getAuthInfo,copyProduct,selectForbiddenKeywords,checkStoreLicense
|
|
|
|
|
|
|
+ updateIsShow, exportDrugProduct,getAuthInfo,copyProduct,selectForbiddenKeywords,checkStoreLicense,getExemptSecondMedicalDeviceList
|
|
|
} from "@/api/hisStore/storeProduct";
|
|
} from "@/api/hisStore/storeProduct";
|
|
|
import {getAllStoreProductCategory} from "@/api/hisStore/storeProductCategory";
|
|
import {getAllStoreProductCategory} from "@/api/hisStore/storeProductCategory";
|
|
|
import {getAllStoreProductRule} from "@/api/hisStore/storeProductRule";
|
|
import {getAllStoreProductRule} from "@/api/hisStore/storeProductRule";
|
|
@@ -1128,14 +1168,13 @@ import {getCompanyList} from "@/api/company/company";
|
|
|
import {listStore} from '@/api/hisStore/store'
|
|
import {listStore} from '@/api/hisStore/store'
|
|
|
import {getConfigByKey} from '@/api/system/config'
|
|
import {getConfigByKey} from '@/api/system/config'
|
|
|
import {qualifications} from "@/api/hisStore/storeProduct";
|
|
import {qualifications} from "@/api/hisStore/storeProduct";
|
|
|
-
|
|
|
|
|
export default {
|
|
export default {
|
|
|
name: "HisStoreProduct",
|
|
name: "HisStoreProduct",
|
|
|
components: {
|
|
components: {
|
|
|
Treeselect,
|
|
Treeselect,
|
|
|
Editor,
|
|
Editor,
|
|
|
Material,
|
|
Material,
|
|
|
- singleImg,
|
|
|
|
|
|
|
+ singleImg
|
|
|
},
|
|
},
|
|
|
created() {
|
|
created() {
|
|
|
this.$nextTick(() => {
|
|
this.$nextTick(() => {
|
|
@@ -1251,6 +1290,13 @@ export default {
|
|
|
this.displayDemo = false;
|
|
this.displayDemo = false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // 判断是否为II类器械或III类器械,如果是则显示器械编码输入框
|
|
|
|
|
+ if (cateName !== undefined && (cateName.includes('II类器械') || cateName.includes('III类器械'))) {
|
|
|
|
|
+ this.showMedicalDeviceCode = true;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.showMedicalDeviceCode = false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// 判断是否包含"处方药"
|
|
// 判断是否包含"处方药"
|
|
|
const isPrescriptionDrug = cateName !== undefined && cateName.includes('处方药');
|
|
const isPrescriptionDrug = cateName !== undefined && cateName.includes('处方药');
|
|
|
|
|
|
|
@@ -1349,6 +1395,7 @@ export default {
|
|
|
ingredientError: '', // 成分禁止提示
|
|
ingredientError: '', // 成分禁止提示
|
|
|
displayDemo: false,
|
|
displayDemo: false,
|
|
|
cateIdToNameMap: {},
|
|
cateIdToNameMap: {},
|
|
|
|
|
+ showMedicalDeviceCode: false, // 是否显示器械编码输入框
|
|
|
businessArr: [],
|
|
businessArr: [],
|
|
|
licenseArr: [],
|
|
licenseArr: [],
|
|
|
certificateArr: [],
|
|
certificateArr: [],
|
|
@@ -1444,6 +1491,18 @@ export default {
|
|
|
// 企业列表
|
|
// 企业列表
|
|
|
companyOptions: [],
|
|
companyOptions: [],
|
|
|
storeOptions: [],
|
|
storeOptions: [],
|
|
|
|
|
+ // 防抖定时器
|
|
|
|
|
+ categoryOrStoreChangeTimer: null,
|
|
|
|
|
+ medicalDeviceCodeInputTimer: null,
|
|
|
|
|
+ // 免于经营备案的第二类医疗器械产品相关变量
|
|
|
|
|
+ exemptDeviceDialogVisible: false,
|
|
|
|
|
+ exemptDeviceList: [],
|
|
|
|
|
+ allExemptDeviceList: [], // 保存所有数据用于本地搜索
|
|
|
|
|
+ exemptDeviceLoading: false,
|
|
|
|
|
+ exemptDeviceTotal: 0,
|
|
|
|
|
+ exemptDeviceQueryParams: {
|
|
|
|
|
+ productName: null
|
|
|
|
|
+ },
|
|
|
// 遮罩层
|
|
// 遮罩层
|
|
|
loading: true,
|
|
loading: true,
|
|
|
// 选中数组
|
|
// 选中数组
|
|
@@ -1510,6 +1569,7 @@ export default {
|
|
|
isCertificatePermanent:null,
|
|
isCertificatePermanent:null,
|
|
|
isLicensePermanent:null,
|
|
isLicensePermanent:null,
|
|
|
isBusinessPermanent:null,
|
|
isBusinessPermanent:null,
|
|
|
|
|
+ medicalDeviceCode: null, // 器械编码
|
|
|
},
|
|
},
|
|
|
// 表单校验
|
|
// 表单校验
|
|
|
rules: {
|
|
rules: {
|
|
@@ -1547,6 +1607,9 @@ export default {
|
|
|
cateId: [
|
|
cateId: [
|
|
|
{required: true, message: "分类id不能为空", trigger: "blur"}
|
|
{required: true, message: "分类id不能为空", trigger: "blur"}
|
|
|
],
|
|
],
|
|
|
|
|
+ medicalDeviceCode: [
|
|
|
|
|
+ {required: true, message: "器械编码不能为空", trigger: "blur"}
|
|
|
|
|
+ ],
|
|
|
price: [
|
|
price: [
|
|
|
{required: true, message: "商品价格不能为空", trigger: "blur"}
|
|
{required: true, message: "商品价格不能为空", trigger: "blur"}
|
|
|
],
|
|
],
|
|
@@ -1665,12 +1728,36 @@ export default {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // 获取分类名称
|
|
|
|
|
+ const cateName = this.cateIdToNameMap[this.form.cateId];
|
|
|
|
|
+
|
|
|
|
|
+ // 判断是否为II类器械或III类器械
|
|
|
|
|
+ const isMedicalDevice = cateName !== undefined && (cateName.includes('II类器械') || cateName.includes('III类器械'));
|
|
|
|
|
+
|
|
|
|
|
+ // 如果是II类或III类器械,需要检查器械编码是否为空
|
|
|
|
|
+ if (isMedicalDevice && (!this.form.medicalDeviceCode || this.form.medicalDeviceCode.trim() === '')) {
|
|
|
|
|
+ this.$message.error('请选择II类器械或III类器械分类时,器械编码不能为空');
|
|
|
|
|
+ this.storeLicenseCheckFailed = true;
|
|
|
|
|
+ this.storeLicenseErrorMessage = '请选择II类器械或III类器械分类时,器械编码不能为空';
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// 添加检查中标志,防止重复调用
|
|
// 添加检查中标志,防止重复调用
|
|
|
if (this.isCheckingLicense) {
|
|
if (this.isCheckingLicense) {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
this.isCheckingLicense = true;
|
|
this.isCheckingLicense = true;
|
|
|
- checkStoreLicense(this.form.storeId, this.form.cateId).then(response => {
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // 准备请求参数
|
|
|
|
|
+ let cateId = this.form.cateId;
|
|
|
|
|
+ let medicalDeviceCode = null;
|
|
|
|
|
+
|
|
|
|
|
+ // 如果是II类或III类器械,传递器械编码
|
|
|
|
|
+ if (isMedicalDevice) {
|
|
|
|
|
+ medicalDeviceCode = this.form.medicalDeviceCode;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ checkStoreLicense(this.form.storeId, cateId, medicalDeviceCode).then(response => {
|
|
|
if (response.code === 200) {
|
|
if (response.code === 200) {
|
|
|
if (!response.data.flag) {
|
|
if (!response.data.flag) {
|
|
|
// 权限检查失败
|
|
// 权限检查失败
|
|
@@ -1747,22 +1834,100 @@ export default {
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
|
|
+ // 当商品分类或所属店铺改变时触发
|
|
|
|
|
+ onCategoryOrStoreChange() {
|
|
|
|
|
+ // 使用防抖机制,避免频繁调用
|
|
|
|
|
+ clearTimeout(this.categoryOrStoreChangeTimer);
|
|
|
|
|
+ this.categoryOrStoreChangeTimer = setTimeout(() => {
|
|
|
|
|
+ this.checkStoreLicensePermission();
|
|
|
|
|
+ }, 500);
|
|
|
|
|
+ },
|
|
|
|
|
+ // 器械编码输入事件
|
|
|
|
|
+ onMedicalDeviceCodeInput() {
|
|
|
|
|
+ // 使用防抖机制,避免频繁调用
|
|
|
|
|
+ clearTimeout(this.medicalDeviceCodeInputTimer);
|
|
|
|
|
+ this.medicalDeviceCodeInputTimer = setTimeout(() => {
|
|
|
|
|
+ // 只有当分类和店铺都已选择时才检查
|
|
|
|
|
+ if (this.form.cateId && this.form.storeId) {
|
|
|
|
|
+ this.checkStoreLicensePermission();
|
|
|
|
|
+ }
|
|
|
|
|
+ }, 500);
|
|
|
|
|
+ },
|
|
|
|
|
+ // 显示免于经营备案的第二类医疗器械产品弹窗
|
|
|
|
|
+ showExemptDeviceDialog() {
|
|
|
|
|
+ this.exemptDeviceDialogVisible = true;
|
|
|
|
|
+ // 重置搜索条件
|
|
|
|
|
+ this.exemptDeviceQueryParams = {
|
|
|
|
|
+ productName: null
|
|
|
|
|
+ };
|
|
|
|
|
+ // 只有在没有数据时才获取数据
|
|
|
|
|
+ if (this.allExemptDeviceList.length === 0) {
|
|
|
|
|
+ this.getExemptDeviceList();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 如果已有数据,直接显示
|
|
|
|
|
+ this.exemptDeviceList = this.allExemptDeviceList;
|
|
|
|
|
+ this.exemptDeviceTotal = this.exemptDeviceList.length;
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ // 获取免于经营备案的第二类医疗器械产品列表
|
|
|
|
|
+ getExemptDeviceList() {
|
|
|
|
|
+ this.exemptDeviceLoading = true;
|
|
|
|
|
+ // 调用实际的API接口来获取数据
|
|
|
|
|
+ getExemptSecondMedicalDeviceList(this.exemptDeviceQueryParams).then(response => {
|
|
|
|
|
+ this.allExemptDeviceList = response.rows || response.data || [];
|
|
|
|
|
+ // 根据搜索条件过滤数据
|
|
|
|
|
+ if (this.exemptDeviceQueryParams.productName) {
|
|
|
|
|
+ const searchTerm = this.exemptDeviceQueryParams.productName.toLowerCase();
|
|
|
|
|
+ this.exemptDeviceList = this.allExemptDeviceList.filter(item =>
|
|
|
|
|
+ item.productName && item.productName.toLowerCase().includes(searchTerm)
|
|
|
|
|
+ );
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.exemptDeviceList = this.allExemptDeviceList;
|
|
|
|
|
+ }
|
|
|
|
|
+ this.exemptDeviceTotal = this.exemptDeviceList.length;
|
|
|
|
|
+ this.exemptDeviceLoading = false;
|
|
|
|
|
+ }).catch(error => {
|
|
|
|
|
+ console.error('获取免于经营备案的第二类医疗器械产品列表失败:', error);
|
|
|
|
|
+ this.$message.error('获取免于经营备案的第二类医疗器械产品列表失败');
|
|
|
|
|
+ this.exemptDeviceLoading = false;
|
|
|
|
|
+ this.exemptDeviceList = [];
|
|
|
|
|
+ this.allExemptDeviceList = [];
|
|
|
|
|
+ this.exemptDeviceTotal = 0;
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+ // 搜索免于经营备案的第二类医疗器械产品
|
|
|
|
|
+ handleExemptDeviceQuery() {
|
|
|
|
|
+ // 在本地数据中搜索
|
|
|
|
|
+ if (this.exemptDeviceQueryParams.productName) {
|
|
|
|
|
+ const searchTerm = this.exemptDeviceQueryParams.productName.toLowerCase();
|
|
|
|
|
+ this.exemptDeviceList = this.allExemptDeviceList.filter(item =>
|
|
|
|
|
+ item.productName && item.productName.toLowerCase().includes(searchTerm)
|
|
|
|
|
+ );
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.exemptDeviceList = this.allExemptDeviceList;
|
|
|
|
|
+ }
|
|
|
|
|
+ this.exemptDeviceTotal = this.exemptDeviceList.length;
|
|
|
|
|
+ },
|
|
|
|
|
+ // 重置免于经营备案的第二类医疗器械产品搜索
|
|
|
|
|
+ resetExemptDeviceQuery() {
|
|
|
|
|
+ this.exemptDeviceQueryParams = {
|
|
|
|
|
+ productName: null
|
|
|
|
|
+ };
|
|
|
|
|
+ // 重置时显示所有数据
|
|
|
|
|
+ this.exemptDeviceList = this.allExemptDeviceList;
|
|
|
|
|
+ this.exemptDeviceTotal = this.exemptDeviceList.length;
|
|
|
|
|
+ },
|
|
|
handleNoticeInfo() {
|
|
handleNoticeInfo() {
|
|
|
qualifications()
|
|
qualifications()
|
|
|
.then(response => {
|
|
.then(response => {
|
|
|
- console.log("noticeInfo接口完整响应:", response);
|
|
|
|
|
if (response.code === 200) {
|
|
if (response.code === 200) {
|
|
|
this.promptList = response.data;
|
|
this.promptList = response.data;
|
|
|
if (this.promptList && this.promptList.length > 0) {
|
|
if (this.promptList && this.promptList.length > 0) {
|
|
|
this.dialogVisible = true;
|
|
this.dialogVisible = true;
|
|
|
}
|
|
}
|
|
|
- console.log("通知信息请求完成!", this.promptList);
|
|
|
|
|
- } else {
|
|
|
|
|
- console.warn("接口返回非成功状态:", response.code);
|
|
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
.catch(err => {
|
|
.catch(err => {
|
|
|
- console.error("获取通知信息失败:", err);
|
|
|
|
|
this.$message.error("加载通知信息失败,请稍后重试");
|
|
this.$message.error("加载通知信息失败,请稍后重试");
|
|
|
});
|
|
});
|
|
|
},
|
|
},
|
|
@@ -2577,6 +2742,29 @@ export default {
|
|
|
{ required: true, message: "注意事项不能为空", trigger: "blur" }
|
|
{ required: true, message: "注意事项不能为空", trigger: "blur" }
|
|
|
]);
|
|
]);
|
|
|
},
|
|
},
|
|
|
|
|
+ // 组件销毁前清理定时器
|
|
|
|
|
+ beforeDestroy() {
|
|
|
|
|
+ if (this.categoryOrStoreChangeTimer) {
|
|
|
|
|
+ clearTimeout(this.categoryOrStoreChangeTimer);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (this.medicalDeviceCodeInputTimer) {
|
|
|
|
|
+ clearTimeout(this.medicalDeviceCodeInputTimer);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
</script>
|
|
</script>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped>
|
|
|
|
|
+.exempt-device-dialog {
|
|
|
|
|
+ z-index: 9999 !important;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.exempt-device-dialog .el-dialog {
|
|
|
|
|
+ z-index: 9999 !important;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.exempt-device-dialog .el-dialog__wrapper {
|
|
|
|
|
+ z-index: 9999 !important;
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|