|
|
@@ -151,7 +151,6 @@
|
|
|
placeholder="请输入生产企业地址"
|
|
|
clearable
|
|
|
size="small"
|
|
|
-
|
|
|
/>
|
|
|
</el-form-item>
|
|
|
|
|
|
@@ -161,7 +160,6 @@
|
|
|
placeholder="请输入功能主治"
|
|
|
clearable
|
|
|
size="small"
|
|
|
-
|
|
|
/>
|
|
|
</el-form-item>
|
|
|
|
|
|
@@ -171,7 +169,6 @@
|
|
|
placeholder="请输入用法用量"
|
|
|
clearable
|
|
|
size="small"
|
|
|
-
|
|
|
/>
|
|
|
</el-form-item>
|
|
|
|
|
|
@@ -191,7 +188,6 @@
|
|
|
placeholder="请输入禁忌"
|
|
|
clearable
|
|
|
size="small"
|
|
|
-
|
|
|
/>
|
|
|
</el-form-item>
|
|
|
|
|
|
@@ -620,6 +616,17 @@
|
|
|
<el-input v-model="form.indications" type="textarea" placeholder="请输入功能主治"/>
|
|
|
</el-form-item>
|
|
|
|
|
|
+ <el-form-item label="成分" prop="ingredient" v-if="!displayDemo">
|
|
|
+ <el-input
|
|
|
+ v-model="form.ingredient"
|
|
|
+ type="textarea"
|
|
|
+ placeholder="请输入成分"
|
|
|
+ @blur="checkForbiddenKeywords"
|
|
|
+ @input="onIngredientInput"
|
|
|
+ />
|
|
|
+ <div v-if="ingredientError" class="el-form-item__error">{{ ingredientError }}</div>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
<el-form-item label="用法用量" prop="dosage">
|
|
|
<el-input v-model="form.dosage" type="textarea" placeholder="请输入用法用量"/>
|
|
|
</el-form-item>
|
|
|
@@ -1056,25 +1063,10 @@
|
|
|
<!-- </el-date-picker>-->
|
|
|
<!-- </el-form-item>-->
|
|
|
|
|
|
- <!-- GMP/GSP认证证书-->
|
|
|
- <el-form-item v-if="form.isShow === '1'" label="GMP/GSP认证证书" prop="gmpAuth">
|
|
|
- <Material v-model="gmpAuthArr" type="image" :num="1" :width="150" :height="150"/>
|
|
|
- </el-form-item>
|
|
|
-
|
|
|
- <el-form-item v-if="form.isShow === '1' && gmpAuthArr.length > 0" label="GMP/GSP认证有效期" prop="gmpAuthExpire">
|
|
|
- <el-date-picker
|
|
|
- v-model="form.gmpAuthExpire"
|
|
|
- type="daterange"
|
|
|
- value-format="yyyy-MM-dd"
|
|
|
- range-separator="至"
|
|
|
- start-placeholder="开始日期"
|
|
|
- end-placeholder="结束日期"
|
|
|
- @change="validateGmpAuthExpire">
|
|
|
- </el-date-picker>
|
|
|
- <div v-if="gmpAuthExpireError" style="color: #F56C6C; font-size: 12px; line-height: 1; padding-top: 4px;">
|
|
|
- <i class="el-icon-warning"></i> {{ gmpAuthExpireError }}
|
|
|
- </div>
|
|
|
- </el-form-item>
|
|
|
+ <!-- GMP/GSP认证证书(后续不需要了)-->
|
|
|
+<!-- <el-form-item v-if="form.isShow === '1'" label="GMP/GSP认证证书" prop="gmpAuth">-->
|
|
|
+<!-- <Material v-model="gmpAuthArr" type="image" :num="1" :width="150" :height="150"/>-->
|
|
|
+<!-- </el-form-item>-->
|
|
|
|
|
|
<el-form-item label="国药准字" v-if="form.productType==2" prop="prescribeCode">
|
|
|
<el-input v-model="form.prescribeCode" placeholder="请输入国药准字"/>
|
|
|
@@ -1181,7 +1173,7 @@ import {
|
|
|
importTemplate,
|
|
|
batchModify,
|
|
|
sync580,
|
|
|
- updateIsShow, exportDrugProduct,getAuthInfo,copyProduct
|
|
|
+ updateIsShow, exportDrugProduct,getAuthInfo,copyProduct,selectForbiddenKeywords,checkStoreLicense
|
|
|
} from "@/api/hisStore/storeProduct";
|
|
|
import {getAllStoreProductCategory} from "@/api/hisStore/storeProductCategory";
|
|
|
import {getAllStoreProductRule} from "@/api/hisStore/storeProductRule";
|
|
|
@@ -1321,11 +1313,12 @@ export default {
|
|
|
// ];
|
|
|
}
|
|
|
const cateName = this.cateIdToNameMap[newVal];
|
|
|
- if(cateName !== undefined && cateName.includes('器械')){
|
|
|
- this.displayDemo=true;
|
|
|
- }else {
|
|
|
- this.displayDemo=false;
|
|
|
- }
|
|
|
+ if(cateName !== undefined && cateName.includes('器械')){
|
|
|
+ this.displayDemo=true;
|
|
|
+ }else {
|
|
|
+ this.displayDemo=false;
|
|
|
+ }
|
|
|
+ this.ingredientError = '';
|
|
|
// 清除验证状态
|
|
|
this.$nextTick(() => {
|
|
|
if (this.$refs.form) {
|
|
|
@@ -1334,13 +1327,37 @@ export default {
|
|
|
});
|
|
|
},
|
|
|
immediate: true
|
|
|
+ },
|
|
|
+ // 合并监听 form.cateId 和 form.storeId
|
|
|
+ form: {
|
|
|
+ handler(newVal, oldVal) {
|
|
|
+ // 只有当两个值都存在且至少有一个发生变化时才进行检查
|
|
|
+ if (newVal.cateId && newVal.storeId) {
|
|
|
+ // 避免在初始化时重复调用,只在值真正改变时调用
|
|
|
+ const oldCateId = oldVal ? oldVal.cateId : null;
|
|
|
+ const oldStoreId = oldVal ? oldVal.storeId : null;
|
|
|
+
|
|
|
+ // 只有当至少一个值发生变化时才检查
|
|
|
+ if (newVal.cateId !== oldCateId || newVal.storeId !== oldStoreId) {
|
|
|
+ // 添加防抖,避免短时间内多次调用
|
|
|
+ clearTimeout(this.licenseCheckTimer);
|
|
|
+ this.licenseCheckTimer = setTimeout(() => {
|
|
|
+ this.checkStoreLicensePermission();
|
|
|
+ }, 300);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ deep: true
|
|
|
}
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
+ isCheckingLicense: false, // 正在检查许可证标志
|
|
|
+ licenseCheckTimer: null, // 添加防抖定时器
|
|
|
+ storeLicenseCheckFailed: false, // 店铺许可证接口检查是否失败
|
|
|
auditLogs:[],
|
|
|
titleValue:null,
|
|
|
-
|
|
|
+ ingredientError: '', // 成分禁止提示
|
|
|
displayDemo: false,
|
|
|
cateIdToNameMap: {},
|
|
|
businessArr: [],
|
|
|
@@ -1352,7 +1369,6 @@ export default {
|
|
|
businessExpireError: '',
|
|
|
licenseExpireError: '',
|
|
|
certificateExpireError: '',
|
|
|
- gmpAuthExpireError: '',
|
|
|
activeValue: '1',
|
|
|
orderOptions: [],
|
|
|
medicalMallConfig: {},
|
|
|
@@ -1486,6 +1502,7 @@ export default {
|
|
|
},
|
|
|
// 表单参数
|
|
|
form: {
|
|
|
+ ingredient: null,
|
|
|
cateId: null,
|
|
|
businessExpire: null,
|
|
|
indications: '',
|
|
|
@@ -1499,7 +1516,6 @@ export default {
|
|
|
voucher:null,
|
|
|
voucherExpire:null,
|
|
|
gmpAuth:null,
|
|
|
- gmpAuthExpire:null,
|
|
|
businessLink:null,
|
|
|
isGmpAuthPermanent:null,
|
|
|
isCertificatePermanent:null,
|
|
|
@@ -1508,6 +1524,19 @@ export default {
|
|
|
},
|
|
|
// 表单校验
|
|
|
rules: {
|
|
|
+ ingredient: [
|
|
|
+ { required: true, message: "成分不能为空", trigger: "blur" },
|
|
|
+ {
|
|
|
+ validator: (rule, value, callback) => {
|
|
|
+ if (this.ingredientError) {
|
|
|
+ callback(new Error(this.ingredientError));
|
|
|
+ } else {
|
|
|
+ callback();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ trigger: "blur"
|
|
|
+ }
|
|
|
+ ],
|
|
|
image: [
|
|
|
{required: true, message: "商品图片不能为空", trigger: "blur"}
|
|
|
],
|
|
|
@@ -1608,9 +1637,6 @@ export default {
|
|
|
gmpAuth: [
|
|
|
{ required: true, message: "GMP认证不能为空!", trigger: "blur" }
|
|
|
],
|
|
|
- gmpAuthExpire: [
|
|
|
- { required: true, message: "GMP认证有效期不能为空!", trigger: "change" }
|
|
|
- ],
|
|
|
businessLink: [
|
|
|
{ required: true, message: "非首营链接不能为空!", trigger: "change" }
|
|
|
],
|
|
|
@@ -1665,6 +1691,92 @@ export default {
|
|
|
// }
|
|
|
// },
|
|
|
methods: {
|
|
|
+
|
|
|
+ // 检查店铺许可证权限
|
|
|
+ // 修改 checkStoreLicensePermission 方法
|
|
|
+ checkStoreLicensePermission() {
|
|
|
+ // 确保分类ID和店铺ID都存在
|
|
|
+ if (!this.form.cateId || !this.form.storeId) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 添加检查中标志,防止重复调用
|
|
|
+ if (this.isCheckingLicense) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ this.isCheckingLicense = true;
|
|
|
+
|
|
|
+ checkStoreLicense(this.form.storeId, this.form.cateId).then(response => {
|
|
|
+ if (response.code === 200) {
|
|
|
+ if (!response.data.flag) {
|
|
|
+ // 权限检查失败
|
|
|
+ this.$message.error(response.data.message || '当前店铺无权限经营该类商品');
|
|
|
+ this.storeLicenseCheckFailed = true;
|
|
|
+ } else {
|
|
|
+ // 权限检查通过
|
|
|
+ this.storeLicenseCheckFailed = false;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ this.$message.error('店铺许可证检查接口调用失败');
|
|
|
+ }
|
|
|
+ }).catch(error => {
|
|
|
+ console.error('店铺许可证检查失败:', error);
|
|
|
+ this.$message.error('店铺许可证检查失败');
|
|
|
+ this.storeLicenseCheckFailed = true;
|
|
|
+ }).finally(() => {
|
|
|
+ this.isCheckingLicense = false;
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+
|
|
|
+ // 成分关键字检查
|
|
|
+ checkForbiddenKeywords() {
|
|
|
+ // Clear error first
|
|
|
+ this.ingredientError = '';
|
|
|
+
|
|
|
+ if (this.form.ingredient && this.form.ingredient.trim()) {
|
|
|
+ selectForbiddenKeywords(this.form.ingredient).then(response => {
|
|
|
+ if (response.code === 200) {
|
|
|
+ if (!response.data) {
|
|
|
+ // Forbidden keywords found
|
|
|
+ this.ingredientError = response.msg || '包含禁用关键字';
|
|
|
+ // Trigger validation to show error
|
|
|
+ this.$nextTick(() => {
|
|
|
+ if (this.$refs.form) {
|
|
|
+ this.$refs.form.validateField('ingredient');
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ // No forbidden keywords - clear error (this is the key improvement)
|
|
|
+ this.ingredientError = '';
|
|
|
+ // Clear validation error state
|
|
|
+ this.$nextTick(() => {
|
|
|
+ if (this.$refs.form) {
|
|
|
+ this.$refs.form.clearValidate('ingredient');
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }).catch(error => {
|
|
|
+ console.error('检查禁用关键字失败:', error);
|
|
|
+ this.$message.error('检查禁用关键字失败');
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ onIngredientInput() {
|
|
|
+ // Optionally clear error as user types to provide real-time feedback
|
|
|
+ if (this.ingredientError) {
|
|
|
+ this.ingredientError = '';
|
|
|
+ // Clear validation state
|
|
|
+ this.$nextTick(() => {
|
|
|
+ if (this.$refs.form) {
|
|
|
+ this.$refs.form.clearValidate('ingredient');
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
handleNoticeInfo() {
|
|
|
qualifications()
|
|
|
.then(response => {
|
|
|
@@ -1927,7 +2039,9 @@ export default {
|
|
|
},
|
|
|
// 表单重置
|
|
|
reset() {
|
|
|
+ this.ingredientError = '';
|
|
|
this.form = {
|
|
|
+ ingredient: null,
|
|
|
productId: null,
|
|
|
image: null,
|
|
|
video: null,
|
|
|
@@ -2086,7 +2200,6 @@ export default {
|
|
|
const productId = row.productId || this.ids
|
|
|
getStoreProduct(productId).then(response => {
|
|
|
this.form = response.data;
|
|
|
- console.log("都要xxxxxxxxxxxxxxxxxxx->>>>>",response.data)
|
|
|
this.form.isShow = response.data.isShow.toString();
|
|
|
this.form.isHot = response.data.isHot.toString();
|
|
|
this.form.isGood = response.data.isGood.toString();
|
|
|
@@ -2131,7 +2244,6 @@ export default {
|
|
|
{ expireKey: 'licenseExpire', startKey: 'licenseStart', endKey: 'licenseEnd' },
|
|
|
{ expireKey: 'certificateExpire', startKey: 'certificateStart', endKey: 'certificateEnd' },
|
|
|
{ expireKey: 'voucherExpire', startKey: 'voucherStart', endKey: 'voucherEnd' },
|
|
|
- { expireKey: 'gmpAuthExpire', startKey: 'gmpAuthStart', endKey: 'gmpAuthEnd' },
|
|
|
{ expireKey: 'qualificationExpire', startKey: 'qualificationCertificateStart', endKey: 'qualificationCertificateEnd' }
|
|
|
];
|
|
|
|
|
|
@@ -2212,7 +2324,14 @@ export default {
|
|
|
this.title = "修改商品";
|
|
|
// 加载数据后立即校验过期状态
|
|
|
this.$nextTick(() => {
|
|
|
- this.validateAllExpires();
|
|
|
+ // 清除之前的定时器
|
|
|
+ if (this.licenseCheckTimer) {
|
|
|
+ clearTimeout(this.licenseCheckTimer);
|
|
|
+ }
|
|
|
+ // 直接调用检查方法
|
|
|
+ if (this.form.storeId && this.form.cateId) {
|
|
|
+ this.checkStoreLicensePermission();
|
|
|
+ }
|
|
|
});
|
|
|
});
|
|
|
},
|
|
|
@@ -2220,6 +2339,11 @@ export default {
|
|
|
submitForm() {
|
|
|
this.$refs["form"].validate(valid => {
|
|
|
if (valid) {
|
|
|
+ // 检查店铺许可证权限
|
|
|
+ if (this.storeLicenseCheckFailed) {
|
|
|
+ this.$message.error('当前店铺无权限经营该类商品,请重新选择分类或店铺');
|
|
|
+ return;
|
|
|
+ }
|
|
|
// 统一校验所有证书是否过期
|
|
|
const expireError = this.checkAllCertificatesExpire();
|
|
|
if (expireError) {
|
|
|
@@ -2258,7 +2382,6 @@ export default {
|
|
|
this.form.isBusinessPermanent = 0;
|
|
|
this.form.isLicensePermanent = 0;
|
|
|
this.form.isCertificatePermanent = 0;
|
|
|
- this.form.isGmpAuthPermanent = 0;
|
|
|
|
|
|
// // 组装companyIds
|
|
|
// if (this.form.companyIds != null && this.form.companyIds != undefined) {
|
|
|
@@ -2388,7 +2511,6 @@ export default {
|
|
|
this.businessExpireError = '';
|
|
|
this.licenseExpireError = '';
|
|
|
this.certificateExpireError = '';
|
|
|
- this.gmpAuthExpireError = '';
|
|
|
},
|
|
|
|
|
|
// 统一校验证书有效期(返回错误信息或null)
|
|
|
@@ -2408,19 +2530,16 @@ export default {
|
|
|
checkAllCertificatesExpire() {
|
|
|
// 按顺序检查,返回第一个过期的证书错误信息
|
|
|
let error = null;
|
|
|
-
|
|
|
+
|
|
|
error = this.checkCertificateExpire(this.form.businessExpire, '营业执照');
|
|
|
if (error) return error + '后再提交!';
|
|
|
-
|
|
|
+
|
|
|
error = this.checkCertificateExpire(this.form.licenseExpire, '生产许可证');
|
|
|
if (error) return error + '后再提交!';
|
|
|
-
|
|
|
+
|
|
|
error = this.checkCertificateExpire(this.form.certificateExpire, '注册证');
|
|
|
if (error) return error + '后再提交!';
|
|
|
-
|
|
|
- error = this.checkCertificateExpire(this.form.gmpAuthExpire, 'GMP/GSP认证');
|
|
|
- if (error) return error + '后再提交!';
|
|
|
-
|
|
|
+
|
|
|
return null;
|
|
|
},
|
|
|
|
|
|
@@ -2429,7 +2548,6 @@ export default {
|
|
|
this.validateBusinessExpire(this.form.businessExpire);
|
|
|
this.validateLicenseExpire(this.form.licenseExpire);
|
|
|
this.validateCertificateExpire(this.form.certificateExpire);
|
|
|
- this.validateGmpAuthExpire(this.form.gmpAuthExpire);
|
|
|
},
|
|
|
|
|
|
// 验证营业执照有效期
|
|
|
@@ -2448,13 +2566,7 @@ export default {
|
|
|
validateCertificateExpire(dates) {
|
|
|
const error = this.checkCertificateExpire(dates, '注册证');
|
|
|
this.certificateExpireError = error ? error + '!' : '';
|
|
|
- },
|
|
|
-
|
|
|
- // 验证GMP/GSP认证有效期
|
|
|
- validateGmpAuthExpire(dates) {
|
|
|
- const error = this.checkCertificateExpire(dates, 'GMP/GSP认证');
|
|
|
- this.gmpAuthExpireError = error ? error + '!' : '';
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
-</script>
|
|
|
+</script>
|