1. 开方2.0优化重构

This commit is contained in:
李琦
2026-05-07 14:25:26 +08:00
parent b862fc1817
commit 45996a26b6
5 changed files with 127 additions and 132 deletions

View File

@@ -246,6 +246,7 @@ export function getCommonPrescriptionListApi(storeId) {
}
// 获取常用方详情
// 注意prescription_v2 选用常用方已改走 list与 PC 对齐,主表行 + 平行药品行一次返回),不再调用此接口
export function getCommonPrescriptionDetailApi(id, type) {
return req.request({
url: '/newApi/common-prescription/detail',

View File

@@ -20,8 +20,8 @@
<view
class="prescription-item white b-r-8 m-t-2"
v-for="(item, index) in prescriptionList"
:key="getItemKey(item, index)"
@click="handleSelectPrescription(item)"
:key="item.id"
@click="handleSelectPrescription(item, index)"
>
<view class="item-header flex-row flex-jus-sp flex-ali-center">
<view class="flex-row flex-ali-center">
@@ -36,7 +36,7 @@
<view class="label">药品</view>
<view class="drug-list">
<text
v-for="(drug, idx) in getDrugList(item)"
v-for="(drug, idx) in getDrugList(item, index)"
:key="idx"
class="drug-item"
>
@@ -46,7 +46,7 @@
</view>
<view class="item-footer m-t-24 btnBox" v-if="!isSelectMode">
<view @click.stop="handleDeletePrescription(item, index)" class="btn left">移除</view>
<view @click.stop="handleSelectPrescription(item)" class="btn right">使用</view>
<view @click.stop="handleSelectPrescription(item, index)" class="btn right">使用</view>
</view>
</view>
</view>
@@ -58,14 +58,28 @@
</view>
<!-- 底部按钮 -->
<view class="modal-footer" v-if="!isSelectMode">
<u-button
<view class="modal-footer flex-jus-between flex-ali-center" v-if="!isSelectMode">
<u-button
:throttle-time="0"
@click="handleClose"
:custom-style="{ backgroundColor: '#f5f5f5', color: '#333' }"
shape="circle"
:custom-style="{
backgroundColor: '#f5f5f5',
color: '#333',
height: '86rpx',
width: '320rpx'
}"
>取消</u-button>
<u-button
<u-button
:throttle-time="0"
@click="handleAddNew"
:custom-style="{ backgroundColor: '#6ACDBB', color: '#fff' }"
shape="circle"
:custom-style="{
backgroundColor: '#6ACDBB',
color: '#fff',
height: '86rpx',
width: '320rpx'
}"
>新建常用方</u-button>
</view>
</view>
@@ -104,6 +118,8 @@ export default {
return {
show: false,
prescriptionList: [],
// 与 prescriptionList 平行的药品数组list 接口里 west/chinese/granular 字段,按下标一一对应
recipesByIndex: [],
loading: false
};
},
@@ -162,16 +178,20 @@ export default {
const res = await getCommonPrescriptionListApi(storeId);
if (res && res.code === 0) {
// 根据类型过滤常用方
// 根据类型过滤常用方主表行 + 平行药品行
const listKey = this.getListKey(type);
this.prescriptionList = res.result?.[listKey] || [];
// type 即 west/chinese/granular正好是 list 接口里平行药品数组的 key
this.recipesByIndex = res.result?.[type] || [];
} else {
this.prescriptionList = [];
this.recipesByIndex = [];
}
} catch (error) {
console.error('获取常用方列表失败:', error);
this.$toast('获取常用方列表失败');
this.prescriptionList = [];
this.recipesByIndex = [];
} finally {
this.loading = false;
}
@@ -208,18 +228,14 @@ export default {
},
/**
* 获取药品列表
* @param {Object} prescription - 常用方数据
* 获取某条常用方对应的药品列表
* 与 PC 一致list 接口返回的主表行与药品行按下标对齐,从 recipesByIndex[index] 取
* @param {Object} _prescription - 主表行(保留参数为可调试用,未使用)
* @param {number} index - 列表中的下标
* @returns {Array} 药品列表
*/
getDrugList(prescription) {
// 根据常用方类型获取对应的药品列表
const type = this.getCommonPrescriptionType(this.prescriptionType);
const listKey = type === 'chinese' ? 'chinese' : type === 'west' ? 'west' : 'granular';
// 从常用方数据中获取药品列表
// 这里需要根据实际数据结构调整
return prescription.drugs || prescription[listKey] || [];
getDrugList(_prescription, index) {
return this.recipesByIndex[index] || [];
},
/**
@@ -262,11 +278,13 @@ export default {
/**
* 选择常用方
* @param {Object} prescription - 常用方数据
* 职责触发select事件传递选中的常用方
* 直接 emit 整条主表行(已包含后端组装好的 apply_payload
* 父组件读 item.apply_payload 即可直接 spread 覆盖编辑区。
* @param {Object} item - 主表行(含 apply_payload
* @param {number} _index - 列表中的下标(保留以维持模板调用兼容,未使用)
*/
handleSelectPrescription(prescription) {
this.$emit('select', prescription);
handleSelectPrescription(item, _index) {
this.$emit('select', item);
this.handleClose();
},
@@ -439,13 +457,10 @@ export default {
.modal-footer {
display: flex;
gap: 24rpx;
justify-content: space-between;
align-items: center;
padding: 32rpx;
border-top: 1rpx solid #eee;
.u-button {
flex: 1;
}
}
.white {

View File

@@ -99,14 +99,28 @@
</view>
<!-- 底部按钮 -->
<view class="modal-footer">
<u-button
<view class="modal-footer flex-jus-between flex-ali-center">
<u-button
:throttle-time="0"
@click="handleClose"
:custom-style="{ backgroundColor: '#f5f5f5', color: '#333' }"
shape="circle"
:custom-style="{
backgroundColor: '#f5f5f5',
color: '#333',
height: '86rpx',
width: '320rpx'
}"
>取消</u-button>
<u-button
<u-button
:throttle-time="0"
@click="handleConfirm"
:custom-style="{ backgroundColor: '#6ACDBB', color: '#fff' }"
shape="circle"
:custom-style="{
backgroundColor: '#6ACDBB',
color: '#fff',
height: '86rpx',
width: '320rpx'
}"
>确定</u-button>
</view>
</view>
@@ -506,12 +520,9 @@ export default {
.modal-footer {
display: flex;
gap: 24rpx;
justify-content: space-between;
align-items: center;
padding: 32rpx;
border-top: 1rpx solid #eee;
.u-button {
flex: 1;
}
}
</style>

View File

@@ -85,14 +85,28 @@
</view>
<!-- 底部按钮 -->
<view class="modal-footer">
<u-button
<view class="modal-footer flex-jus-between flex-ali-center">
<u-button
:throttle-time="0"
@click="handleClose"
:custom-style="{ backgroundColor: '#f5f5f5', color: '#333' }"
shape="circle"
:custom-style="{
backgroundColor: '#f5f5f5',
color: '#333',
height: '86rpx',
width: '320rpx'
}"
>取消</u-button>
<u-button
<u-button
:throttle-time="0"
@click="handleConfirm"
:custom-style="{ backgroundColor: '#6ACDBB', color: '#fff' }"
shape="circle"
:custom-style="{
backgroundColor: '#6ACDBB',
color: '#fff',
height: '86rpx',
width: '320rpx'
}"
>确定</u-button>
</view>
</view>
@@ -412,12 +426,9 @@ export default {
.modal-footer {
display: flex;
gap: 24rpx;
justify-content: space-between;
align-items: center;
padding: 32rpx;
border-top: 1rpx solid #eee;
.u-button {
flex: 1;
}
}
</style>

View File

@@ -31,7 +31,7 @@
<d-text text="诊断" className="light-c fs-32 m-l-16"></d-text>
</view>
<view class="m-t-16 flex flex-wrap">
<view class="m-r-2 m-t-16" v-for="(item, i) in diagnoses" :key="item.id ? item.id : `diag_${i}`">
<view class="m-r-2 m-t-16" v-for="(item, i) in diagnoses" :key="item.id">
<u-tag
shape="circle"
:text="item.name"
@@ -81,7 +81,7 @@
</view>
</view>
</view>
<view class="bottom-border p-col-32" v-for="(item, index) in currentDrugs" :key="index">
<view class="bottom-border p-col-32" v-for="(item, index) in currentDrugs" :key="item.index_id">
<view class="drug-item-content flex-row">
<image
v-if="item.image"
@@ -196,7 +196,7 @@
</view>
</view>
</view>
<view class="bottom-border p-col-32" v-for="(item, index) in currentDrugs" :key="index">
<view class="bottom-border p-col-32" v-for="(item, index) in currentDrugs" :key="item.index_id">
<view class="drug-item-content flex-row">
<image
v-if="item.image"
@@ -408,7 +408,6 @@ import {
getPatientInfoByPatientId,
getProcessRuleList,
getCommonPrescriptionListApi,
getCommonPrescriptionDetailApi,
saveWestCommonPrescriptionApi,
saveChineseCommonPrescriptionApi,
getCurrentStoreTypeApi
@@ -977,93 +976,51 @@ export default {
/**
* 处理选择常用方
* @param {Object} prescription - 常用方数据
* 职责:填充药品、诊断、医嘱到当前处方
* @param {Object} item - 子组件 emit 的整条主表行,必带 apply_payload
* apply_payload 由 WX 后端 CommonPrescriptionWxService::list() 组装:
* - drugs: 药品数组(已按 currentDrugs 字段命名)
* - diagnosisText: 诊断
* - medicalAdvice: 医嘱
* - chineseConfig: 仅中药附带ruleType / dosage / dayDosage / packageMethodId /
* processRuleId / childProcessRuleId / processRuleNoteId
* 职责:直接 spread 覆盖编辑区(整表替换语义),无任何字段映射
*/
async handleSelectCommonPrescription(prescription) {
async handleSelectCommonPrescription(item) {
try {
// 获取常用方详情
const detailRes = await getCommonPrescriptionDetailApi(
prescription.id,
this.getCommonPrescriptionType(this.activeCategory)
);
if (!detailRes || !detailRes.recipes) {
this.$toast('获取常用方详情失败');
const payload = item && item.apply_payload;
if (!payload || !Array.isArray(payload.drugs)) {
this.$toast('常用方数据异常');
return;
}
// 填充药品
this.currentDrugs = detailRes.recipes.map(recipe => {
if (this.activeCategory === 1) {
// 中药
return {
id: recipe.drug_id || recipe.id,
drug_id: recipe.drug_id || recipe.id,
drug_name: recipe.drug_name || recipe.name,
number: recipe.number || 1,
price: recipe.price || 0,
way_id: recipe.way_id || 0
};
} else {
// 西药
return {
id: recipe.drug_id || recipe.id,
drug_id: recipe.drug_id || recipe.id,
drug_name: recipe.drug_name,
number: recipe.number || 1,
select_number: recipe.select_number || 1,
price: recipe.price || 0,
time_id: recipe.time_id || 0,
type_id: recipe.type_id || 0,
frequency_id: recipe.frequency_id || 0,
unit_id: recipe.unit_id || 0,
image: recipe.image || '',
instruction: recipe.instruction || ''
};
this.currentDrugs.splice(0, this.currentDrugs.length, ...payload.drugs);
if (payload.diagnosisText) {
this.diagnosisText = payload.diagnosisText;
const names = payload.diagnosisText.split('').filter(Boolean);
this.diagnoses = names.map((name, index) => ({
id: `temp_${index}`,
name
}));
}
if (payload.medicalAdvice) {
this.medicalAdvice = payload.medicalAdvice;
}
if (this.activeCategory === 1 && payload.chineseConfig) {
this.chineseConfig = {
...this.chineseConfig,
...payload.chineseConfig
};
if (this.chineseConfig.processRuleId) {
await this.loadProcessRuleList(this.chineseConfig.processRuleId, 0);
}
});
// 填充诊断和医嘱
if (detailRes.prescription) {
if (detailRes.prescription.clinical_diagnose) {
this.diagnosisText = detailRes.prescription.clinical_diagnose;
const diagnosisNames = this.diagnosisText.split('').filter(Boolean);
this.diagnoses = diagnosisNames.map((name, index) => ({
id: `temp_${index}`,
name: name
}));
}
if (detailRes.prescription.doctor_order) {
this.medicalAdvice = detailRes.prescription.doctor_order;
}
// 填充中药配置
if (this.activeCategory === 1 && detailRes.prescription) {
this.chineseConfig = {
...this.chineseConfig,
ruleType: detailRes.prescription.rule_type || 1,
dosage: detailRes.prescription.dosage || 7,
dayDosage: detailRes.prescription.day_dosage || 2,
packageMethodId: detailRes.prescription.package_method_id || null,
processRuleId: detailRes.prescription.process_rule_id || null,
childProcessRuleId: detailRes.prescription.child_process_rule_id || null,
processRuleNoteId: detailRes.prescription.process_rule_note_id || null
};
// 加载加工规则列表
if (this.chineseConfig.processRuleId) {
await this.loadProcessRuleList(this.chineseConfig.processRuleId, 0);
}
if (this.chineseConfig.childProcessRuleId) {
await this.loadProcessRuleList(0, this.chineseConfig.childProcessRuleId);
}
if (this.chineseConfig.childProcessRuleId) {
await this.loadProcessRuleList(0, this.chineseConfig.childProcessRuleId);
}
}
// 保存到本地存储
this.saveToLocalStorage();
this.$toast('常用方已填充');
} catch (error) {
console.error('选择常用方失败:', error);