Files
xk-client-wx/subPackages/follow-up/medication-info.vue

935 lines
32 KiB
Vue
Raw Normal View History

<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"
2026-05-15 16:42:32 +08:00
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>
2026-05-15 16:28:11 +08:00
<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
2026-05-15 16:28:11 +08:00
v-if="showIllnessOtherInput"
v-model="illnessOtherText"
placeholder="请填写具体症状"
:border="true"
@input="syncIllnessInfo"
/>
2026-05-15 16:28:11 +08:00
</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: [],
2026-05-15 16:28:11 +08:00
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,
2026-05-15 16:42:32 +08:00
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() {
const rel = this.productDetail.drug_store_relations;
if (rel && rel.price) {
return parseFloat(rel.price);
}
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);
},
2026-05-15 16:28:11 +08:00
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' });
}
},
2026-06-01 09:52:26 +08:00
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 || '医生助理';
2026-05-15 16:42:32 +08:00
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() {
2026-06-01 09:52:26 +08:00
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);
2026-05-15 16:28:11 +08:00
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;
}
});
},
2026-05-15 16:28:11 +08:00
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() {
2026-05-15 16:28:11 +08:00
if (!this.prescriptionFormData.hasVisited || !this.prescriptionFormData.hasUsedDrug) {
uni.showToast({ title: '请填写完整信息', icon: 'none' });
return;
}
2026-05-15 16:28:11 +08:00
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;
}
}
2026-05-15 16:28:11 +08:00
.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>