Files
xk-client-wx/subPackages/follow-up/medication-info.vue
2026-06-01 09:52:26 +08:00

931 lines
32 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view v-if="mode === 'clinic_post_register'">
<AssistantConsultationShell
header-title="复诊用药确认"
:show-notice="showPostRegisterNotice"
:parsed-notice-parts="parsedPostRegisterNoticeParts"
:show-agreement.sync="showPostRegisterAgreement"
:agreement-content="postRegisterAgreementContent"
:current-agreement-name="postRegisterCurrentAgreementName"
:displayed-messages="postRegisterDisplayedMessages"
:assistant-avatar="postRegAssistantAvatar"
:assistant-name="postRegAssistantName"
user-avatar="https://xiaokang88.oss-cn-hangzhou.aliyuncs.com/xk-client-wx/static/images/user-avatar.png"
:prescription-info="postRegisterPrescriptionInfo"
:is-typing="postRegisterIsTyping"
:scroll-into-view="postRegisterScrollIntoView"
:show-question-buttons="postRegisterStep === 'await_answer'"
:current-question="postRegisterCurrentQuestion"
:current-question-answers="postRegisterQuestionAnswers"
:is-submitting="postRegisterSubmitting"
:show-waiting="postRegisterWaiting"
@back="handlePostRegisterBack"
@answer="onPostRegisterShellAnswer"
@view-agreement="viewPostRegisterAgreement"
/>
<u-toast ref="uToast" />
</view>
<view v-else class="page">
<view class="page-inner safe-area-bottom">
<view class="page-title">{{ pageTitle }}</view>
<!-- 药店商品摘要 -->
<block v-if="mode === 'pharmacy'">
<view class="product-info-row">
<image class="p-img" :src="productDetail.image" mode="aspectFill"></image>
<view class="p-info">
<view class="p-name">{{ productDetail.drug_name }}</view>
<view class="p-spec">{{ productDetail.specification || '暂无规格' }}</view>
<view class="p-price">¥{{ productPrice }}</view>
</view>
</view>
<view class="quantity-row">
<text class="label">购买数量</text>
<u-number-box v-model="prescriptionQuantity" :min="1" :max="999" integer :step="1"></u-number-box>
</view>
<u-form :model="prescriptionFormData" ref="prescriptionForm">
<u-form-item label="是否就诊过" prop="hasVisited" label-width="200">
<u-radio-group v-model="prescriptionFormData.hasVisited">
<u-radio name="1" active-color="#2B85E4" style="margin-right: 40rpx;"></u-radio>
<u-radio name="0" active-color="#2B85E4"></u-radio>
</u-radio-group>
</u-form-item>
<u-form-item label="是否用过此药" prop="hasUsedDrug" label-width="200">
<u-radio-group v-model="prescriptionFormData.hasUsedDrug">
<u-radio name="1" active-color="#2B85E4" style="margin-right: 40rpx;"></u-radio>
<u-radio name="0" active-color="#2B85E4"></u-radio>
</u-radio-group>
</u-form-item>
<view class="illness-section">
<view class="illness-label">症状</view>
<view class="illness-tags">
<u-tag
v-for="(item, index) in illnessOptions"
:key="index"
:text="item.label"
mode="dark"
:bg-color="selectedIllnessIndexes.includes(index) ? '#2B85E4' : 'rgba(43,133,228,0.08)'"
:color="selectedIllnessIndexes.includes(index) ? '#FFFFFF' : '#475569'"
@tap="toggleIllnessTag(index)"
/>
</view>
<u-input
v-if="showIllnessOtherInput"
v-model="illnessOtherText"
placeholder="请填写具体症状"
:border="true"
@input="syncIllnessInfo"
/>
</view>
</u-form>
</block>
<!-- 诊所复诊用药确认仅聊天内入口 -->
<block v-else-if="mode === 'clinic_followup'">
<view v-if="clinicQuestion" class="clinic-question">{{ clinicQuestion }}</view>
<view v-if="clinicDrugs.length" class="clinic-drugs">
<view class="sub-title">涉及药品</view>
<view v-for="(row, idx) in clinicDrugs" :key="'d-' + idx" class="drug-line">
<text class="n">{{ row.name || '药品' }}</text>
<text class="q">×{{ row.quantity != null ? row.quantity : 1 }}</text>
</view>
</view>
<u-form :model="clinicForm" ref="clinicFormRef">
<u-form-item label="是否用过此类药" prop="hasUsedDrug" label-width="220">
<u-radio-group v-model="clinicForm.hasUsedDrug">
<u-radio name="1" active-color="#2B85E4" style="margin-right: 40rpx;"></u-radio>
<u-radio name="0" active-color="#2B85E4"></u-radio>
</u-radio-group>
</u-form-item>
</u-form>
</block>
<view class="popup-actions">
<button class="btn-cancel" @click="goBack">取消</button>
<button class="btn-confirm" @click="onSubmit">{{ submitButtonText }}</button>
</view>
</view>
<u-toast ref="uToast" />
</view>
</template>
<script>
import { getStoreDrugDetailApi, checkOnlineConsultationConfigApi } from '@/request/api/product';
import request from '@/request/api/request';
import { confirmFollowUpDrugUseApi } from '@/request/api/order';
import {
CLINIC_POST_REGISTER_STORAGE_KEY,
markFollowUpAssistSent,
sendFollowUpDrugAssistantMessage,
wasFollowUpAssistSent,
} from '@/utils/clinicFollowUpAssistantIm';
import AssistantConsultationShell from '@/components/AssistantConsultationShell.vue';
import {
getTransferAssistantConfigApi,
getTransferConsultationAgreementInfoApi,
getAgreementDetailApi,
} from '@/request/api/transferPrescription.js';
const FOLLOWUP_PAYLOAD_KEY = '__medication_followup_payload';
export default {
components: { AssistantConsultationShell },
data() {
return {
mode: 'pharmacy',
productDetail: {
id: '',
type: 2,
drug_name: '',
image: '',
price: 0,
specification: '',
indications_array: [],
},
prescriptionQuantity: 1,
prescriptionFormData: {
hasVisited: '1',
hasUsedDrug: '1',
illnessInfo: '',
},
illnessOptions: [],
selectedIllnessIndexes: [],
illnessOtherText: '',
delegateStoreId: '',
doctorIdFromQuery: '',
submitted: false,
// clinic
registerInfoId: '',
messageId: '',
clinicQuestion: '',
clinicDrugs: [],
clinicForm: {
hasUsedDrug: '1',
},
postRegisterRoomId: '',
postRegisterDoctorId: '',
postRegisterPatientId: '',
postRegisterDoctorPrefixed: '',
postRegisterRegisterId: '',
// clinic_post_register与转诊咨询壳共用 UI
postRegisterQuestionList: [],
postRegisterQuestionIndex: -1,
postRegisterUserAnswers: [],
postRegisterReplyDelay: 0.65,
postRegisterIsTyping: false,
postRegisterShowWelcome: true,
/** idle | await_answer | typing_after | submitting */
postRegisterStep: 'idle',
postRegisterScrollIntoView: '',
postRegisterSubmitting: false,
postRegisterWaiting: false,
postRegAssistantAvatar: 'https://xiaokang88.oss-cn-hangzhou.aliyuncs.com/xk-client-wx/static/images/assistant-avatar.png',
postRegAssistantName: '医生助理',
showPostRegisterNotice: true,
parsedPostRegisterNoticeParts: [],
postRegisterAgreements: [],
postRegisterNoticeText: '',
showPostRegisterAgreement: false,
postRegisterAgreementContent: '',
postRegisterCurrentAgreementName: '',
};
},
computed: {
pageTitle() {
if (this.mode === 'clinic_followup') return '请填写用药信息';
return '请填写用药信息';
},
submitButtonText() {
return '提交';
},
postRegisterPrescriptionInfo() {
if (!this.clinicDrugs || !this.clinicDrugs.length) return '相关药品';
return this.clinicDrugs
.map((row) => `${row.name || '药品'}×${row.quantity != null ? row.quantity : 1}`)
.join('、');
},
postRegisterDisplayedMessages() {
const messages = [];
if (this.postRegisterShowWelcome) {
messages.push({ type: 'welcome', id: 'welcome-msg', timestamp: 0 });
}
const qs = this.postRegisterQuestionList;
const idx = this.postRegisterQuestionIndex;
for (let i = 0; i <= idx && i < qs.length; i++) {
const q = qs[i];
messages.push({
type: 'question',
id: `question-${q.id}`,
questionId: q.id,
content: q.question,
timestamp: i * 2 + 1,
});
if (i < this.postRegisterUserAnswers.length) {
messages.push({
type: 'answer',
id: `answer-${i}`,
content: this.postRegisterUserAnswers[i],
timestamp: i * 2 + 2,
});
}
}
if (this.postRegisterWaiting) {
messages.push({
type: 'waiting',
id: 'waiting-msg',
timestamp: messages.length,
});
}
return messages;
},
postRegisterCurrentQuestion() {
if (this.postRegisterStep !== 'await_answer') return null;
if (!this.postRegisterQuestionList.length) return null;
return this.postRegisterQuestionList[0];
},
postRegisterQuestionAnswers() {
return ['是', '否'];
},
productPrice() {
if (this.productDetail.drug_store_drug && this.productDetail.drug_store_drug.price) {
return parseFloat(this.productDetail.drug_store_drug.price);
}
return parseFloat(this.productDetail.price || 0);
},
showIllnessOtherInput() {
return this.selectedIllnessIndexes.some(
(idx) => this.illnessOptions[idx] && this.illnessOptions[idx].value === '__other__',
);
},
},
onLoad(options) {
if (options.mode === 'clinic_post_register') {
this.mode = 'clinic_post_register';
try {
const raw = uni.getStorageSync(CLINIC_POST_REGISTER_STORAGE_KEY);
if (raw) {
const o = typeof raw === 'string' ? JSON.parse(raw) : raw;
this.registerInfoId = String(o.register_info_id || '');
this.clinicQuestion = o.question || '您是否曾使用过此类药品?';
this.clinicDrugs = Array.isArray(o.drugs) ? o.drugs : [];
this.postRegisterRoomId = o.room_id || '';
this.postRegisterDoctorId = o.doctor_id != null ? String(o.doctor_id) : '';
this.postRegisterPatientId = String(o.patient_id || '');
this.postRegisterDoctorPrefixed = o.doctor_prefixed || '';
this.postRegisterRegisterId = String(o.register_id || '');
}
} catch (e) {
console.error('medication-info clinic_post_register', e);
}
uni.removeStorageSync(CLINIC_POST_REGISTER_STORAGE_KEY);
if (!this.registerInfoId || !this.postRegisterRoomId || !this.postRegisterDoctorId || !this.postRegisterRegisterId) {
uni.showToast({ title: '参数无效', icon: 'none' });
} else {
this.postRegisterQuestionList = [
{
id: 'clinic-post-reg-1',
question: this.clinicQuestion || '您是否曾使用过此类药品?',
answers: ['是', '否'],
},
];
this.loadPostRegisterAssistantConfig();
this.loadPostRegisterAgreementInfo();
this.$nextTick(() => this.beginPostRegisterAssistantFlow());
}
return;
}
this.mode = options.mode === 'clinic_followup' ? 'clinic_followup' : 'pharmacy';
if (this.mode === 'clinic_followup') {
this.messageId = options.message_id || '';
try {
const raw = uni.getStorageSync(FOLLOWUP_PAYLOAD_KEY);
if (raw) {
const o = typeof raw === 'string' ? JSON.parse(raw) : raw;
this.registerInfoId = String(o.register_info_id || '');
this.clinicQuestion = o.question || '';
this.clinicDrugs = Array.isArray(o.drugs) ? o.drugs : [];
}
} catch (e) {
console.error('medication-info clinic payload', e);
}
uni.removeStorageSync(FOLLOWUP_PAYLOAD_KEY);
if (!this.registerInfoId) {
uni.showToast({ title: '参数无效', icon: 'none' });
}
return;
}
this.productDetail.id = options.id || '';
this.doctorIdFromQuery = options.doctor_id || '';
this.delegateStoreId = options.delegate_store_id || '';
if (options.drug_name) {
try {
this.productDetail.drug_name = decodeURIComponent(options.drug_name);
} catch {
this.productDetail.drug_name = options.drug_name;
}
}
if (options.image) {
try {
this.productDetail.image = decodeURIComponent(options.image);
} catch {
this.productDetail.image = options.image;
}
}
if (options.price) this.productDetail.price = parseFloat(options.price);
if (options.type) this.productDetail.type = parseInt(options.type, 10) || 2;
if (this.productDetail.id) {
this.getDetail();
} else {
uni.showToast({ title: '缺少商品信息', icon: 'none' });
}
},
onBackPress() {
if (this.mode === 'clinic_post_register' && this.showPostRegisterAgreement) {
this.showPostRegisterAgreement = false;
return true;
}
return false;
},
methods: {
postRegisterScrollToBottom() {
this.postRegisterScrollIntoView = 'bottom-anchor';
setTimeout(() => {
this.postRegisterScrollIntoView = '';
}, 120);
},
beginPostRegisterAssistantFlow() {
this.postRegisterStep = 'idle';
this.postRegisterShowWelcome = true;
this.postRegisterUserAnswers = [];
this.postRegisterWaiting = false;
this.postRegisterQuestionIndex = -1;
this.postRegisterIsTyping = true;
const delayMs = Math.max(200, (this.postRegisterReplyDelay || 0.65) * 1000);
setTimeout(() => {
this.postRegisterIsTyping = false;
this.postRegisterQuestionIndex = 0;
this.postRegisterStep = 'await_answer';
this.$nextTick(() => this.postRegisterScrollToBottom());
}, delayMs);
},
onPostRegisterShellAnswer(answer) {
if (this.postRegisterStep !== 'await_answer' || this.submitted) return;
this.postRegisterUserAnswers = [answer];
this.clinicForm.hasUsedDrug = answer === '是' ? '1' : '0';
this.postRegisterStep = 'typing_after';
this.postRegisterIsTyping = true;
this.$nextTick(() => this.postRegisterScrollToBottom());
const typingMs = Math.max(200, (this.postRegisterReplyDelay || 0.65) * 1000);
setTimeout(() => {
this.postRegisterIsTyping = false;
this.$nextTick(() => this.postRegisterScrollToBottom());
// 与转诊一致:最后一题答完后短延迟再自动提交
setTimeout(() => {
this.submitClinicPostRegister();
}, 500);
}, typingMs);
},
resetPostRegisterAfterSubmitFailure() {
this.submitted = false;
this.postRegisterWaiting = false;
this.postRegisterStep = 'await_answer';
if (this.clinicForm.hasUsedDrug === '0' || this.clinicForm.hasUsedDrug === '1') {
this.postRegisterUserAnswers = [this.clinicForm.hasUsedDrug === '1' ? '是' : '否'];
} else {
this.postRegisterUserAnswers = [];
}
this.$nextTick(() => this.postRegisterScrollToBottom());
},
async loadPostRegisterAssistantConfig() {
try {
const res = await getTransferAssistantConfigApi();
if (res.data && res.data.code === 0) {
const config = res.data.result || {};
this.postRegAssistantName = config.name || '医生助理';
this.postRegAssistantAvatar = config.avatar || 'https://xiaokang88.oss-cn-hangzhou.aliyuncs.com/xk-client-wx/static/images/assistant-avatar.png';
const d = parseFloat(config.reply_delay);
if (!Number.isNaN(d) && d > 0) {
this.postRegisterReplyDelay = d;
}
}
} catch (e) {
console.warn('loadPostRegisterAssistantConfig', e);
}
},
async loadPostRegisterAgreementInfo() {
try {
const res = await getTransferConsultationAgreementInfoApi();
if (res.data && res.data.code === 0) {
const result = res.data.result || {};
this.postRegisterNoticeText = result.notice_text || '';
this.postRegisterAgreements = result.agreements || [];
this.parsePostRegisterNoticeText();
this.showPostRegisterNotice =
this.parsedPostRegisterNoticeParts.length > 0 || !!this.postRegisterNoticeText;
}
} catch (e) {
console.warn('loadPostRegisterAgreementInfo', e);
this.postRegisterNoticeText =
'根据国家互联网医院管理办法要求,平台仅为复诊患者提供服务。为了保障您的用药安全,请根据真实情况回答,并请仔细阅读《互联网医疗风险告知及知情同意书》,继续咨询即表示您已知悉相关规则与风险并同意相关条款。';
this.parsePostRegisterNoticeText();
this.showPostRegisterNotice =
this.parsedPostRegisterNoticeParts.length > 0 || !!this.postRegisterNoticeText;
}
},
parsePostRegisterNoticeText() {
if (!this.postRegisterNoticeText) {
this.parsedPostRegisterNoticeParts = [];
return;
}
const parts = [];
const regex = /《([^》]+)》/g;
let lastIndex = 0;
let match;
while ((match = regex.exec(this.postRegisterNoticeText)) !== null) {
if (match.index > lastIndex) {
parts.push({
type: 'text',
text: this.postRegisterNoticeText.substring(lastIndex, match.index),
});
}
const agreementName = match[1];
const agreement = this.postRegisterAgreements.find(
(ag) => ag.name === agreementName || (ag.name && ag.name.includes(agreementName)),
);
if (agreement) {
parts.push({
type: 'agreement',
text: agreementName,
agreementId: agreement.id,
});
} else {
parts.push({ type: 'text', text: match[0] });
}
lastIndex = regex.lastIndex;
}
if (lastIndex < this.postRegisterNoticeText.length) {
parts.push({
type: 'text',
text: this.postRegisterNoticeText.substring(lastIndex),
});
}
this.parsedPostRegisterNoticeParts = parts;
},
async viewPostRegisterAgreement(agreementId) {
if (!agreementId) {
uni.showToast({ title: '协议ID不能为空', icon: 'none' });
return;
}
const agreement = this.postRegisterAgreements.find((ag) => ag.id === agreementId);
this.postRegisterCurrentAgreementName = agreement ? agreement.name : '协议详情';
this.showPostRegisterAgreement = true;
try {
const res = await getAgreementDetailApi(agreementId);
if (res.data && res.data.code === 0) {
const result = res.data.result || {};
this.postRegisterAgreementContent = result.content || '';
if (result.name) {
this.postRegisterCurrentAgreementName = result.name;
}
} else {
throw new Error((res.data && res.data.message) || '获取协议详情失败');
}
} catch (error) {
console.error('viewPostRegisterAgreement', error);
uni.showToast({
title: (error && error.message) || '获取协议详情失败',
icon: 'none',
});
this.showPostRegisterAgreement = false;
}
},
handlePostRegisterBack() {
if (this.showPostRegisterAgreement) {
this.showPostRegisterAgreement = false;
return;
}
uni.showModal({
title: '提示',
content: '确定返回首页吗?未完成确认将无法同步给医生。',
success: (res) => {
if (res.confirm) {
uni.switchTab({ url: '/pages/home/home' });
}
},
});
},
goBack() {
if (this.mode === 'clinic_post_register') {
uni.switchTab({ url: '/pages/home/home' });
return;
}
uni.navigateBack({ delta: 1 });
},
getDetail() {
getStoreDrugDetailApi({ id: this.productDetail.id }).then((res) => {
if (res.data.code === 0) {
const data = res.data.result;
Object.assign(this.productDetail, data);
const options = (data.indications_array || []).map((item) => ({
value: item.label || item.value,
label: item.label || item.value,
}));
options.push({ value: '__other__', label: '其他' });
this.illnessOptions = options;
}
});
},
toggleIllnessTag(index) {
const pos = this.selectedIllnessIndexes.indexOf(index);
if (pos === -1) {
this.selectedIllnessIndexes.push(index);
} else {
this.selectedIllnessIndexes.splice(pos, 1);
if (this.illnessOptions[index] && this.illnessOptions[index].value === '__other__') {
this.illnessOtherText = '';
}
}
this.syncIllnessInfo();
},
syncIllnessInfo() {
const parts = this.selectedIllnessIndexes
.map((idx) => {
const opt = this.illnessOptions[idx];
if (!opt) return '';
if (opt.value === '__other__') {
return (this.illnessOtherText || '').trim();
}
return opt.label || opt.value;
})
.filter(Boolean);
this.prescriptionFormData.illnessInfo = parts.join('、');
},
async getDefaultDoctorId() {
try {
const storeId = uni.getStorageSync('store_id');
if (!storeId) {
return { data: { result: { doctor_id: null } } };
}
const res = await request('/xkApi/online-consultation/get-default-doctor-id', {
method: 'GET',
data: { store_id: storeId },
}, 0);
return res;
} catch (error) {
console.error('获取默认医生ID失败:', error);
return { data: { result: { doctor_id: null } } };
}
},
onSubmit() {
if (this.mode === 'clinic_followup') {
this.submitClinic();
} else {
this.submitPharmacy();
}
},
submitClinicPostRegister() {
if (!this.registerInfoId || !this.postRegisterRoomId || !this.postRegisterDoctorId || !this.postRegisterRegisterId) {
uni.showToast({ title: '参数缺失', icon: 'none' });
return;
}
if (this.clinicForm.hasUsedDrug !== '0' && this.clinicForm.hasUsedDrug !== '1') {
uni.showToast({ title: '请先选择是否用过药', icon: 'none' });
return;
}
if (this.submitted) return;
this.submitted = true;
this.postRegisterSubmitting = true;
this.postRegisterWaiting = true;
this.postRegisterStep = 'submitting';
this.$nextTick(() => this.postRegisterScrollToBottom());
const val = this.clinicForm.hasUsedDrug;
const answerStatus = val === '1' ? 'yes' : 'no';
confirmFollowUpDrugUseApi({
register_info_id: this.registerInfoId,
has_used_drug: val,
})
.then(async (res) => {
const d = res.data || {};
const ok = d.errcode === 0 || d.code === 0 || d.status === true;
if (!ok) {
this.resetPostRegisterAfterSubmitFailure();
uni.showToast({ title: d.msg || d.message || '提交失败', icon: 'none' });
return;
}
try {
if (!wasFollowUpAssistSent(this.postRegisterRegisterId)) {
await sendFollowUpDrugAssistantMessage({
roomId: this.postRegisterRoomId,
doctorId: this.postRegisterDoctorId,
registerId: this.postRegisterRegisterId,
registerInfoId: this.registerInfoId,
drugsPayload: this.clinicDrugs,
question: this.clinicQuestion,
answerStatus,
});
markFollowUpAssistSent(this.postRegisterRegisterId);
}
} catch (e) {
console.error('sendFollowUpDrugAssistantMessage', e);
this.resetPostRegisterAfterSubmitFailure();
uni.showToast({ title: '发送消息失败,请重试', icon: 'none' });
return;
}
const encUser = encodeURIComponent(
this.postRegisterDoctorPrefixed || `doctor-${this.postRegisterDoctorId}`,
);
const chatUrl = `/subPackages/chat/chat?user_id=${encUser}&room_id=${this.postRegisterRoomId}&register_id=${this.postRegisterRegisterId}`;
uni.redirectTo({ url: chatUrl });
})
.catch(() => {
this.resetPostRegisterAfterSubmitFailure();
uni.showToast({ title: '提交失败', icon: 'none' });
})
.finally(() => {
this.postRegisterSubmitting = false;
this.postRegisterWaiting = false;
});
},
submitClinic() {
if (!this.registerInfoId) {
uni.showToast({ title: '缺少登记信息', icon: 'none' });
return;
}
if (this.clinicForm.hasUsedDrug !== '0' && this.clinicForm.hasUsedDrug !== '1') {
uni.showToast({ title: '请选择是否用过药', icon: 'none' });
return;
}
uni.showLoading({ title: '提交中', mask: true });
confirmFollowUpDrugUseApi({
register_info_id: this.registerInfoId,
has_used_drug: this.clinicForm.hasUsedDrug,
})
.then((res) => {
const d = res.data || {};
const ok = d.errcode === 0 || d.code === 0 || d.status === true;
if (ok) {
const val = this.clinicForm.hasUsedDrug;
const answerStatus = val === '1' ? 'yes' : 'no';
try {
const ec = this.getOpenerEventChannel && this.getOpenerEventChannel();
if (ec && ec.emit) {
ec.emit('followUpDrugCompleted', {
messageId: this.messageId,
answerStatus,
raw: val,
});
}
} catch (e) {
console.warn('eventChannel', e);
}
uni.showToast({ title: '已记录', icon: 'success' });
setTimeout(() => uni.navigateBack({ delta: 1 }), 400);
} else {
uni.showToast({ title: d.msg || d.message || '提交失败', icon: 'none' });
}
})
.catch(() => {
uni.showToast({ title: '提交失败', icon: 'none' });
})
.finally(() => {
uni.hideLoading();
});
},
async submitPharmacy() {
if (!this.prescriptionFormData.hasVisited || !this.prescriptionFormData.hasUsedDrug) {
uni.showToast({ title: '请填写完整信息', icon: 'none' });
return;
}
if (!this.selectedIllnessIndexes.length) {
uni.showToast({ title: '请选择症状', icon: 'none' });
return;
}
if (this.showIllnessOtherInput && !(this.illnessOtherText || '').trim()) {
uni.showToast({ title: '请填写具体症状', icon: 'none' });
return;
}
this.syncIllnessInfo();
if (!this.prescriptionFormData.illnessInfo) {
uni.showToast({ title: '请选择症状', icon: 'none' });
return;
}
if (this.submitted) return;
const formData = { ...this.prescriptionFormData };
const quantity = this.prescriptionQuantity;
this.submitted = true;
try {
const storeId = uni.getStorageSync('store_id');
let delegateStoreId = this.delegateStoreId;
let doctorId = this.doctorIdFromQuery || null;
if (!delegateStoreId) {
const configRes = await checkOnlineConsultationConfigApi({ store_id: storeId });
if (!configRes.data?.result?.can_use) {
uni.showToast({
title: configRes.data?.result?.message || '该门店暂不支持在线复诊功能',
icon: 'none',
duration: 2000,
});
this.submitted = false;
return;
}
delegateStoreId = configRes.data.result.delegate_store_id || storeId;
doctorId = configRes.data.result.doctor_id;
} else if (!doctorId) {
const doctorRes = await this.getDefaultDoctorId();
doctorId = doctorRes.data.result?.doctor_id;
}
if (!doctorId) {
uni.showToast({ title: '该门店暂不支持在线复诊', icon: 'none', duration: 2000 });
this.submitted = false;
return;
}
const createRes = await request('/xkApi/order/create-register-info', {
method: 'POST',
data: {
doctor_id: doctorId,
drug_id: this.productDetail.id,
has_visited: formData.hasVisited,
has_used_drug: formData.hasUsedDrug,
illnessInfo: formData.illnessInfo,
type: this.productDetail.type || 2,
number: quantity,
},
}, 1);
const infoId = createRes.data?.result?.info_id || createRes.data?.info_id;
if (!infoId) {
throw new Error('创建就诊信息失败');
}
const rInfo = {
info_id: infoId,
doctor_id: doctorId,
has_visited: formData.hasVisited,
has_used_drug: formData.hasUsedDrug,
illness_info: formData.illnessInfo,
drug_name: this.productDetail.drug_name,
drug_id: this.productDetail.id,
number: quantity,
type: this.productDetail.type || 2,
created_at: new Date().toLocaleString('zh-CN'),
};
uni.navigateTo({
url: `/subPackages/doctor/doctor-userinfo?id=${doctorId}&r_type=3&r_info=${encodeURIComponent(JSON.stringify(rInfo))}&delegate_store_id=${delegateStoreId}`,
});
} catch (error) {
console.error('提交处方药信息失败:', error);
uni.showToast({ title: '提交失败,请重试', icon: 'none' });
this.submitted = false;
}
},
},
};
</script>
<style lang="scss" scoped>
.page {
min-height: 100vh;
background: #f5f7fa;
}
.page-inner {
padding: 30rpx;
background: #fff;
min-height: 100vh;
}
.page-title {
text-align: center;
font-size: 32rpx;
font-weight: bold;
margin-bottom: 30rpx;
}
.product-info-row {
display: flex;
margin-bottom: 30rpx;
.p-img {
width: 160rpx;
height: 160rpx;
border-radius: 12rpx;
background: #f8f8f8;
margin-right: 20rpx;
}
.p-info {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
.p-name {
font-size: 30rpx;
font-weight: bold;
color: #333;
}
.p-spec {
font-size: 24rpx;
color: #999;
}
.p-price {
font-size: 36rpx;
color: #ff4d4f;
font-weight: bold;
}
}
}
.quantity-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx 0;
border-top: 1rpx solid #f5f5f5;
border-bottom: 1rpx solid #f5f5f5;
margin-bottom: 40rpx;
.label {
font-size: 28rpx;
color: #333;
}
}
.illness-section {
padding: 20rpx 0;
.illness-label {
font-size: 28rpx;
color: #333;
margin-bottom: 16rpx;
}
.illness-tags {
display: flex;
flex-wrap: wrap;
::v-deep .u-tag {
margin: 0 20rpx 16rpx 0;
}
}
}
.popup-actions {
display: flex;
gap: 30rpx;
margin-top: 40rpx;
&.post-register-actions {
flex-direction: column;
}
button {
flex: 1;
height: 80rpx;
border-radius: 40rpx;
font-size: 30rpx;
border: none;
&.btn-cancel {
background: #f5f7fa;
color: #606266;
}
&.btn-confirm {
background: #2b85e4;
color: #fff;
}
&.btn-confirm-block {
flex: none;
width: 100%;
}
}
}
.post-register-exit {
text-align: center;
margin-top: 28rpx;
font-size: 26rpx;
color: #909399;
padding: 16rpx 0;
}
.clinic-question {
font-size: 28rpx;
color: #333;
line-height: 1.6;
margin-bottom: 24rpx;
padding: 20rpx;
background: #f7f8fa;
border-radius: 12rpx;
}
.clinic-drugs {
margin-bottom: 24rpx;
.sub-title {
font-size: 26rpx;
color: #909399;
margin-bottom: 12rpx;
}
.drug-line {
display: flex;
justify-content: space-between;
font-size: 28rpx;
padding: 12rpx 0;
border-bottom: 1rpx solid #eee;
.n {
color: #333;
}
.q {
color: #666;
}
}
}
.safe-area-bottom {
padding-bottom: calc(30rpx + env(safe-area-inset-bottom));
}
</style>