feat:配片单验光参数调整优化

This commit is contained in:
一休哥哥6666
2026-07-14 14:53:12 +08:00
parent 9be6fd6ec9
commit 324679964c
6 changed files with 492 additions and 87 deletions

View File

@@ -535,17 +535,26 @@
</el-table-column>
<el-table-column label="球镜S" align="center" min-width="90">
<template slot-scope="scope">
<el-input-number v-model="scope.row.sphereS" :precision="2" :step="0.25" controls-position="right" style="width: 100%" />
<el-input-number v-model="scope.row.sphereS" :precision="2" :step="0.25" controls-position="right" style="width: 100%" @change="val => onSphereSChange(val, scope.row)" />
</template>
</el-table-column>
<el-table-column label="柱镜C" align="center" min-width="90">
<template slot-scope="scope">
<el-input-number v-model="scope.row.cylinderC" :precision="2" :step="0.25" controls-position="right" style="width: 100%" />
<el-input-number
v-model="scope.row.cylinderC"
:precision="2"
:step="0.25"
:min="getCylinderCMin(scope.row)"
:max="getCylinderCMax(scope.row)"
controls-position="right"
style="width: 100%"
@change="val => onCylinderCChange(val, scope.row)"
/>
</template>
</el-table-column>
<el-table-column label="轴位A" align="center" min-width="80">
<template slot-scope="scope">
<el-input-number v-model="scope.row.axisA" :min="0" :max="180" controls-position="right" style="width: 100%" />
<el-input-number v-model="scope.row.axisA" :min="0" :max="180" :disabled="!isAxisAEditable(scope.row)" controls-position="right" style="width: 100%" />
</template>
</el-table-column>
<el-table-column label="瞳距(mm)" align="center" min-width="90">
@@ -553,7 +562,7 @@
<el-input-number v-model="scope.row.pd" :precision="2" :min="0" controls-position="right" style="width: 100%" />
</template>
</el-table-column>
<el-table-column label="瞳高(mm)" align="center" min-width="80">
<el-table-column v-if="form.progressiveMultifocal === 1" label="瞳高(mm)" align="center" min-width="80">
<template slot-scope="scope">
<el-input-number v-model="scope.row.pupilHeight" :precision="2" :min="0" controls-position="right" style="width: 100%" />
</template>
@@ -563,9 +572,9 @@
<el-input v-model="scope.row.distanceVa" placeholder="远用VA" />
</template>
</el-table-column>
<el-table-column label="近用ADD(屈光度)" align="center" min-width="100">
<el-table-column v-if="form.progressiveMultifocal === 1" label="近用ADD(屈光度)" align="center" min-width="100">
<template slot-scope="scope">
<el-input-number v-model="scope.row.nearAdd" :precision="2" :min="0" controls-position="right" style="width: 100%" />
<el-input-number v-model="scope.row.nearAdd" :precision="2" :step="0.25" :min="0.75" :max="4" controls-position="right" style="width: 100%" />
</template>
</el-table-column>
</el-table>
@@ -963,7 +972,7 @@
<span>{{ formatDetailPdValue(scope.row, scope.$index) }}</span>
</template>
</el-table-column>
<el-table-column label="瞳高(mm)" align="center" min-width="80">
<el-table-column v-if="detail.progressiveMultifocal === 1" label="瞳高(mm)" align="center" min-width="80">
<template slot-scope="scope">
<span>{{ scope.row.pupilHeight != null ? scope.row.pupilHeight : '-' }}</span>
</template>
@@ -973,7 +982,7 @@
<span>{{ scope.row.distanceVa != null && scope.row.distanceVa !== '' ? scope.row.distanceVa : '-' }}</span>
</template>
</el-table-column>
<el-table-column label="近用ADD(屈光度)" align="center" min-width="100">
<el-table-column v-if="detail.progressiveMultifocal === 1" label="近用ADD(屈光度)" align="center" min-width="100">
<template slot-scope="scope">
<span>{{ formatDetailNearAdd(scope.row.nearAdd) }}</span>
</template>
@@ -1471,8 +1480,8 @@ export default {
},
createDefaultOptometryList() {
return [
{ eyeSide: 'OS', sphereS: null, cylinderC: null, axisA: null, pd: null, dualPd: null, pupilHeight: null, distanceVa: null, nearAdd: null },
{ eyeSide: 'OD', sphereS: null, cylinderC: null, axisA: null, pd: null, dualPd: null, pupilHeight: null, distanceVa: null, nearAdd: null }
{ eyeSide: 'OS', sphereS: 0, cylinderC: null, axisA: null, pd: null, dualPd: null, pupilHeight: null, distanceVa: null, nearAdd: null },
{ eyeSide: 'OD', sphereS: 0, cylinderC: null, axisA: null, pd: null, dualPd: null, pupilHeight: null, distanceVa: null, nearAdd: null }
];
},
detectPdMode(optometryList) {
@@ -1516,6 +1525,45 @@ export default {
if (Number.isNaN(num)) return String(value);
return '+' + num.toFixed(2);
},
isAxisAEditable(row) {
const val = row && row.cylinderC;
if (val == null || val === '') return false;
const num = Number(val);
return !Number.isNaN(num) && num !== 0;
},
getSphereSign(sphereS) {
if (sphereS == null || sphereS === '') return 0;
const num = Number(sphereS);
if (Number.isNaN(num) || num === 0) return 0;
return num > 0 ? 1 : -1;
},
getCylinderCMin(row) {
return this.getSphereSign(row && row.sphereS) > 0 ? 0 : -10;
},
getCylinderCMax(row) {
return this.getSphereSign(row && row.sphereS) < 0 ? 0 : 10;
},
alignCylinderSignWithSphere(row) {
if (!row || row.cylinderC == null || row.cylinderC === '') return;
let cylinder = Number(row.cylinderC);
if (Number.isNaN(cylinder) || cylinder === 0) return;
const sphereSign = this.getSphereSign(row.sphereS);
if (sphereSign > 0 && cylinder < 0) cylinder = Math.abs(cylinder);
else if (sphereSign < 0 && cylinder > 0) cylinder = -Math.abs(cylinder);
row.cylinderC = Math.min(this.getCylinderCMax(row), Math.max(this.getCylinderCMin(row), cylinder));
},
onSphereSChange(val, row) {
this.alignCylinderSignWithSphere(row);
if (!this.isAxisAEditable(row)) row.axisA = null;
},
onCylinderCChange(val, row) {
if (val == null || val === '' || Number(val) === 0) {
row.axisA = null;
return;
}
this.alignCylinderSignWithSphere(row);
if (!this.isAxisAEditable(row)) row.axisA = null;
},
cancel() {
this.open = false;
this.reset();
@@ -1523,6 +1571,12 @@ export default {
handleProgressiveMultifocalChange(value) {
if (Number(value) !== 1) {
this.form.progressiveMultifocalPrice = 0;
if (this.form.optometryList) {
this.form.optometryList.forEach(row => {
row.nearAdd = null;
row.pupilHeight = null;
});
}
return;
}
if (!this.form.lensFactoryTenantId) {
@@ -1979,6 +2033,19 @@ export default {
? this.resolveProgressiveMultifocalPrice()
: 0
};
if (Number(payload.progressiveMultifocal) !== 1 && payload.optometryList) {
payload.optometryList.forEach(row => {
row.nearAdd = null;
row.pupilHeight = null;
});
}
if (payload.optometryList) {
payload.optometryList.forEach(row => {
if (!this.isAxisAEditable(row)) {
row.axisA = null;
}
});
}
if (Number(payload.progressiveMultifocal) === 1) {
if (!payload.lensFactoryTenantId) {
this.$modal.msgWarning("选择渐进多焦点时需先选择镜片厂");

View File

@@ -251,7 +251,7 @@
<span>{{ formatDetailPdValue(scope.row, scope.$index) }}</span>
</template>
</el-table-column>
<el-table-column label="瞳高(mm)" align="center" min-width="80">
<el-table-column v-if="detail.progressiveMultifocal === 1" label="瞳高(mm)" align="center" min-width="80">
<template slot-scope="scope">
<span>{{ scope.row.pupilHeight != null ? scope.row.pupilHeight : '-' }}</span>
</template>
@@ -261,7 +261,7 @@
<span>{{ scope.row.distanceVa != null && scope.row.distanceVa !== '' ? scope.row.distanceVa : '-' }}</span>
</template>
</el-table-column>
<el-table-column label="近用ADD(屈光度)" align="center" min-width="100">
<el-table-column v-if="detail.progressiveMultifocal === 1" label="近用ADD(屈光度)" align="center" min-width="100">
<template slot-scope="scope">
<span>{{ formatDetailNearAdd(scope.row.nearAdd) }}</span>
</template>

View File

@@ -279,12 +279,14 @@
<div class="section-body">
<div class="pd-mode-switch">
<span class="pd-mode-label">瞳距类型</span>
<el-radio-group v-model="pdMode" size="small" @change="handlePdModeChange">
<el-radio-group v-model="pdMode" size="small" :disabled="form.progressiveMultifocal === 1" @change="handlePdModeChange">
<el-radio-button label="single">单瞳距</el-radio-button>
<el-radio-button label="dual">双瞳距</el-radio-button>
</el-radio-group>
<span :key="'pd-tip-text-' + pdMode" class="pd-mode-tip">{{ pdColumnHeaderTip }}</span>
</div>
<el-table
:key="'optometry-table-' + pdMode + '-' + form.progressiveMultifocal"
:data="form.optometryList"
:span-method="formOptometrySpanMethod"
class="lens-optometry-table"
@@ -302,8 +304,8 @@
</el-table-column>
<el-table-column align="center" min-width="90">
<template slot="header">
<el-tooltip content="可录入范围:-20 ~ +20 度(负数为近视,正数为远视)" placement="top">
<span class="optometry-header-tip">镜S</span>
<el-tooltip content="可录入范围:-14.00 ~ +10.00(负数为近视,正数为远视)" placement="top">
<span class="optometry-header-tip">面度数(SPH)</span>
</el-tooltip>
</template>
<template slot-scope="scope">
@@ -319,18 +321,19 @@
v-model="scope.row.sphereS"
:precision="2"
:step="0.25"
:min="-SPHERE_S_MAX"
:min="SPHERE_S_MIN"
:max="SPHERE_S_MAX"
controls-position="right"
style="width: 100%"
@change="val => onSphereSChange(val, scope.row)"
/>
</div>
</template>
</el-table-column>
<el-table-column align="center" min-width="90">
<template slot="header">
<el-tooltip content="可录入范围:-10 ~ 0 度(仅负数,表示散光" placement="top">
<span class="optometry-header-tip">柱镜C</span>
<el-tooltip content="取值范围:-6.00 ~ +6.00球面为正则散光需为正球面为负则散光需为负球面为0时散光可正可负" placement="top">
<span class="optometry-header-tip">散光度数(CYL)</span>
</el-tooltip>
</template>
<template slot-scope="scope">
@@ -345,8 +348,8 @@
v-model="scope.row.cylinderC"
:precision="2"
:step="0.25"
:min="CYLINDER_C_MIN"
:max="0"
:min="getCylinderCMin(scope.row)"
:max="getCylinderCMax(scope.row)"
controls-position="right"
style="width: 100%"
@change="val => onCylinderCChange(val, scope.row)"
@@ -356,15 +359,21 @@
</el-table-column>
<el-table-column align="center" min-width="100">
<template slot="header">
<el-tooltip content="可录入范围0 ~ 180 度" placement="top">
<span class="optometry-header-tip">轴位A</span>
<el-tooltip content="有散光时轴位须为 1 ~ 180不能为 0" placement="top">
<span class="optometry-header-tip">(散光请填写)(AXI)</span>
</el-tooltip>
</template>
<template slot-scope="scope">
<div class="axis-input-wrap">
<div
class="axis-input-wrap"
:class="{
'is-disabled': !isAxisAEditable(scope.row),
'is-error': isAxisAInvalid(scope.row)
}"
>
<div class="axis-step-actions">
<button type="button" class="axis-step-btn" @click="adjustAxisA(scope.row, -5)">-5</button>
<button type="button" class="axis-step-btn" @click="adjustAxisA(scope.row, 5)">+5</button>
<button type="button" class="axis-step-btn" :disabled="!isAxisAEditable(scope.row)" @click="adjustAxisA(scope.row, -5)">-5</button>
<button type="button" class="axis-step-btn" :disabled="!isAxisAEditable(scope.row)" @click="adjustAxisA(scope.row, 5)">+5</button>
</div>
<el-input-number
v-model="scope.row.axisA"
@@ -372,16 +381,19 @@
:step="1"
:min="0"
:max="180"
:disabled="!isAxisAEditable(scope.row)"
controls-position="right"
style="width: 100%"
@change="val => onAxisAChange(val, scope.row)"
/>
<div v-if="isAxisAInvalid(scope.row)" class="axis-error-tip">轴位不能为0</div>
</div>
</template>
</el-table-column>
<el-table-column align="center" min-width="100">
<el-table-column :key="'pd-col-' + pdMode" align="center" min-width="120">
<template slot="header">
<el-tooltip :content="pdColumnHeaderTip" placement="top">
<span class="optometry-header-tip">瞳距(mm)</span>
<el-tooltip :key="'pd-tip-' + pdMode" :content="pdColumnHeaderTip" placement="top">
<span class="optometry-header-tip">{{ pdColumnHeaderLabel }}</span>
</el-tooltip>
</template>
<template slot-scope="scope">
@@ -392,9 +404,9 @@
</div>
<el-input-number
v-model="scope.row.dualPd"
:precision="0"
:step="1"
:min="0"
:precision="2"
:step="0.5"
:min="DUAL_PD_MIN"
:max="DUAL_PD_MAX"
controls-position="right"
style="width: 100%"
@@ -407,9 +419,9 @@
</div>
<el-input-number
v-model="singlePd"
:precision="0"
:step="1"
:min="0"
:precision="2"
:step="0.5"
:min="SINGLE_PD_MIN"
:max="SINGLE_PD_MAX"
controls-position="right"
style="width: 100%"
@@ -418,6 +430,59 @@
</div>
</template>
</el-table-column>
<el-table-column v-if="form.progressiveMultifocal === 1" align="center" min-width="100">
<template slot="header">
<el-tooltip content="可录入范围15 ~ 25 mm" placement="top">
<span class="optometry-header-tip">瞳高(mm)</span>
</el-tooltip>
</template>
<template slot-scope="scope">
<div class="axis-input-wrap">
<div class="axis-step-actions">
<button type="button" class="axis-step-btn" @click="adjustPupilHeight(scope.row, -1)">-1</button>
<button type="button" class="axis-step-btn" @click="adjustPupilHeight(scope.row, 1)">+1</button>
</div>
<el-input-number
v-model="scope.row.pupilHeight"
:precision="0"
:step="1"
:min="PUPIL_HEIGHT_MIN"
:max="PUPIL_HEIGHT_MAX"
controls-position="right"
style="width: 100%"
/>
</div>
</template>
</el-table-column>
<el-table-column v-if="form.progressiveMultifocal === 1" align="center" min-width="110">
<template slot="header">
<el-tooltip content="可录入范围:+0.75 ~ +4.00 屈光度(渐进多焦点近用加光)" placement="top">
<span class="optometry-header-tip">ADD(屈光度)</span>
</el-tooltip>
</template>
<template slot-scope="scope">
<div
class="axis-input-wrap"
:class="{ 'is-error': isNearAddInvalid(scope.row) }"
>
<div class="axis-step-actions">
<button type="button" class="axis-step-btn" @click="adjustNearAdd(scope.row, -0.25)">-0.25</button>
<button type="button" class="axis-step-btn" @click="adjustNearAdd(scope.row, 0.25)">+0.25</button>
</div>
<el-input-number
v-model="scope.row.nearAdd"
:precision="2"
:step="0.25"
:min="NEAR_ADD_MIN"
:max="NEAR_ADD_MAX"
controls-position="right"
style="width: 100%"
@change="val => onNearAddChange(val, scope.row)"
/>
<div v-if="isNearAddInvalid(scope.row)" class="axis-error-tip">ADD不能为0请填写+0.75~+4.00</div>
</div>
</template>
</el-table-column>
</el-table>
</div>
</section>
@@ -595,19 +660,19 @@
<span>{{ scope.row.eyeSide === 'OS' ? '左眼(OS)' : '右眼(OD)' }}</span>
</template>
</el-table-column>
<el-table-column label="球镜S" align="center" min-width="90">
<el-table-column label="球面度数(SPH)" align="center" min-width="90">
<template slot-scope="scope">
<span>{{ formatDetailOptometryDecimal(scope.row.sphereS) }}</span>
</template>
</el-table-column>
<el-table-column label="柱镜C" align="center" min-width="90">
<el-table-column label="散光度数(CYL)" align="center" min-width="90">
<template slot-scope="scope">
<span>{{ formatDetailOptometryDecimal(scope.row.cylinderC) }}</span>
</template>
</el-table-column>
<el-table-column align="center" min-width="80">
<template slot="header">
<span>轴位A</span>
<span>(AXI)</span>
</template>
<template slot-scope="scope">
<span>{{ scope.row.axisA != null ? scope.row.axisA : '-' }}</span>
@@ -618,7 +683,7 @@
<span>{{ formatDetailPdValue(scope.row, scope.$index) }}</span>
</template>
</el-table-column>
<el-table-column label="瞳高(mm)" align="center" min-width="80">
<el-table-column v-if="detail.progressiveMultifocal === 1" label="瞳高(mm)" align="center" min-width="80">
<template slot-scope="scope">
<span>{{ scope.row.pupilHeight != null ? scope.row.pupilHeight : '-' }}</span>
</template>
@@ -628,7 +693,7 @@
<span>{{ scope.row.distanceVa != null && scope.row.distanceVa !== '' ? scope.row.distanceVa : '-' }}</span>
</template>
</el-table-column>
<el-table-column label="近用ADD(屈光度)" align="center" min-width="100">
<el-table-column v-if="detail.progressiveMultifocal === 1" label="ADD(屈光度)" align="center" min-width="100">
<template slot-scope="scope">
<span>{{ formatDetailNearAdd(scope.row.nearAdd) }}</span>
</template>
@@ -870,11 +935,17 @@ export default {
pdMode: 'single',
singlePd: 50,
SINGLE_PD_DEFAULT: 50,
SINGLE_PD_MAX: 100,
DUAL_PD_DEFAULT: 25,
DUAL_PD_MAX: 50,
SPHERE_S_MAX: 20,
CYLINDER_C_MIN: -10,
SINGLE_PD_MIN: 40,
SINGLE_PD_MAX: 80,
DUAL_PD_DEFAULT: 30,
DUAL_PD_MIN: 20,
DUAL_PD_MAX: 40,
SPHERE_S_MIN: -14.00,
SPHERE_S_MAX: 10.00,
CYLINDER_C_MIN: -6.00,
CYLINDER_C_MAX: 6.00,
NEAR_ADD_MIN: 0.75,
NEAR_ADD_MAX: 4.00,
PUPIL_HEIGHT_MIN: 15,
PUPIL_HEIGHT_MAX: 25,
detailPdMode: 'single',
@@ -1005,10 +1076,13 @@ export default {
}
return '填写原因后提交换货申请'
},
pdColumnHeaderLabel() {
return this.pdMode === 'dual' ? '双瞳距(mm)' : '单瞳距(mm)'
},
pdColumnHeaderTip() {
return this.pdMode === 'dual'
? '可录入范围:0 ~ 50 mm单眼双瞳距'
: '可录入范围0 ~ 100 mm单瞳距'
? '双瞳距可录入范围:20.00 ~ 40.00 mm左右眼分别填写'
: '单瞳距可录入范围:40.00 ~ 80.00 mm左右眼共用一个值'
},
logisticsDialogSubtitle() {
if (this.logisticsBasic && this.logisticsBasic.orderNo) {
@@ -1288,8 +1362,8 @@ export default {
},
createDefaultOptometryList() {
return [
{ eyeSide: 'OS', sphereS: null, cylinderC: null, axisA: null, pd: this.SINGLE_PD_DEFAULT, dualPd: null, pdType: '1', pupilHeight: null, distanceVa: null, nearAdd: null },
{ eyeSide: 'OD', sphereS: null, cylinderC: null, axisA: null, pd: this.SINGLE_PD_DEFAULT, dualPd: null, pdType: '1', pupilHeight: null, distanceVa: null, nearAdd: null }
{ eyeSide: 'OS', sphereS: 0, cylinderC: null, axisA: null, pd: this.SINGLE_PD_DEFAULT, dualPd: null, pdType: '1', pupilHeight: null, distanceVa: null, nearAdd: null },
{ eyeSide: 'OD', sphereS: 0, cylinderC: null, axisA: null, pd: this.SINGLE_PD_DEFAULT, dualPd: null, pdType: '1', pupilHeight: null, distanceVa: null, nearAdd: null }
]
},
detectPdMode(optometryList) {
@@ -1348,7 +1422,7 @@ export default {
const osRow = this.form.optometryList.find(item => item.eyeSide === 'OS')
const odRow = this.form.optometryList.find(item => item.eyeSide === 'OD')
const pd = osRow && osRow.pd != null ? osRow.pd : (odRow && odRow.pd != null ? odRow.pd : this.SINGLE_PD_DEFAULT)
this.singlePd = Math.min(this.SINGLE_PD_MAX, Math.max(0, Number(pd)))
this.singlePd = Math.min(this.SINGLE_PD_MAX, Math.max(this.SINGLE_PD_MIN, Number(pd)))
this.form.optometryList.forEach(row => {
if (row.pd == null) {
row.pd = this.singlePd
@@ -1357,7 +1431,7 @@ export default {
},
onSinglePdChange(val) {
if (this.pdMode !== 'single' || !this.form.optometryList) return
const pd = val == null || val === '' ? null : Math.min(this.SINGLE_PD_MAX, Math.max(0, Number(val)))
const pd = val == null || val === '' ? null : Math.min(this.SINGLE_PD_MAX, Math.max(this.SINGLE_PD_MIN, Number(val)))
if (pd != null && Number.isNaN(pd)) return
this.singlePd = pd
this.form.optometryList.forEach(row => {
@@ -1371,7 +1445,7 @@ export default {
const num = Number(val)
if (Number.isNaN(num) || num === 0) return ''
const degree = Math.abs(num).toFixed(2)
return num > 0 ? `远视 ${degree} ` : `近视 ${degree} `
return num > 0 ? `远视 ${degree} ` : `近视 ${degree} `
},
getSphereSHintClass(row) {
const num = Number(row.sphereS)
@@ -1384,33 +1458,141 @@ export default {
const num = Number(val)
if (Number.isNaN(num) || num === 0) return ''
const degree = Math.abs(num).toFixed(2)
return `散光 ${degree} `
return `散光 ${degree} `
},
getSphereSign(sphereS) {
if (sphereS == null || sphereS === '') return 0
const num = Number(sphereS)
if (Number.isNaN(num) || num === 0) return 0
return num > 0 ? 1 : -1
},
getCylinderCMin(row) {
const sign = this.getSphereSign(row && row.sphereS)
return sign > 0 ? 0 : this.CYLINDER_C_MIN
},
getCylinderCMax(row) {
const sign = this.getSphereSign(row && row.sphereS)
return sign < 0 ? 0 : this.CYLINDER_C_MAX
},
alignCylinderSignWithSphere(row) {
if (!row) return
if (row.cylinderC == null || row.cylinderC === '') return
let cylinder = Number(row.cylinderC)
if (Number.isNaN(cylinder) || cylinder === 0) return
const sphereSign = this.getSphereSign(row.sphereS)
if (sphereSign > 0 && cylinder < 0) {
cylinder = Math.abs(cylinder)
} else if (sphereSign < 0 && cylinder > 0) {
cylinder = -Math.abs(cylinder)
}
row.cylinderC = Math.min(this.CYLINDER_C_MAX, Math.max(this.CYLINDER_C_MIN, cylinder))
},
isAxisAEditable(row) {
const val = row && row.cylinderC
if (val == null || val === '') return false
const num = Number(val)
return !Number.isNaN(num) && num !== 0
},
isAxisAInvalid(row) {
if (!this.isAxisAEditable(row)) return false
if (row.axisA == null || row.axisA === '') return true
const axis = Number(row.axisA)
return Number.isNaN(axis) || axis === 0
},
onAxisAChange(val, row) {
if (!this.isAxisAEditable(row)) {
row.axisA = null
return
}
if (val == null || val === '') {
row.axisA = 0
return
}
const axis = Number(val)
if (Number.isNaN(axis)) {
row.axisA = 0
return
}
row.axisA = Math.min(180, Math.max(0, axis))
},
onSphereSChange(val, row) {
if (val == null || val === '') {
row.sphereS = 0
} else {
const num = Number(val)
if (Number.isNaN(num)) {
row.sphereS = 0
} else {
row.sphereS = Math.min(this.SPHERE_S_MAX, Math.max(this.SPHERE_S_MIN, num))
}
}
this.alignCylinderSignWithSphere(row)
if (!this.isAxisAEditable(row)) {
row.axisA = null
}
},
onCylinderCChange(val, row) {
if (val == null || val === '') return
if (val == null || val === '') {
row.axisA = null
return
}
let num = Number(val)
if (Number.isNaN(num)) return
if (num > 0) {
const sphereSign = this.getSphereSign(row.sphereS)
if (sphereSign > 0 && num < 0) {
num = Math.abs(num)
} else if (sphereSign < 0 && num > 0) {
num = -Math.abs(num)
}
row.cylinderC = Math.min(0, Math.max(this.CYLINDER_C_MIN, num))
num = Math.min(this.getCylinderCMax(row), Math.max(this.getCylinderCMin(row), num))
row.cylinderC = num
if (num === 0) {
row.axisA = null
}
},
validateCylinderSignWithSphere() {
const list = this.form.optometryList || []
for (const row of list) {
if (row.cylinderC == null || row.cylinderC === '') continue
const cylinder = Number(row.cylinderC)
if (Number.isNaN(cylinder) || cylinder === 0) continue
const sphereSign = this.getSphereSign(row.sphereS)
const eyeLabel = row.eyeSide === 'OS' ? '左眼' : '右眼'
if (sphereSign > 0 && cylinder < 0) {
return `${eyeLabel}:球面为正时,散光度数须为正`
}
if (sphereSign < 0 && cylinder > 0) {
return `${eyeLabel}:球面为负时,散光度数须为负`
}
}
return null
},
validateAxisARequired() {
const list = this.form.optometryList || []
for (const row of list) {
if (!this.isAxisAInvalid(row)) continue
const eyeLabel = row.eyeSide === 'OS' ? '左眼' : '右眼'
return `${eyeLabel}有散光时轴位不能为0请填写1~180`
}
return null
},
adjustAxisA(row, delta) {
if (!this.isAxisAEditable(row)) return
const current = row.axisA == null || row.axisA === '' ? 0 : Number(row.axisA)
if (Number.isNaN(current)) return
row.axisA = Math.min(180, Math.max(0, current + delta))
},
adjustSinglePd(delta) {
const current = this.singlePd == null || this.singlePd === '' ? 0 : Number(this.singlePd)
const current = this.singlePd == null || this.singlePd === '' ? this.SINGLE_PD_DEFAULT : Number(this.singlePd)
if (Number.isNaN(current)) return
const next = Math.min(this.SINGLE_PD_MAX, Math.max(0, current + delta))
const next = Math.min(this.SINGLE_PD_MAX, Math.max(this.SINGLE_PD_MIN, current + delta))
this.singlePd = next
this.onSinglePdChange(next)
},
adjustDualPd(row, delta) {
const current = row.dualPd == null || row.dualPd === '' ? 0 : Number(row.dualPd)
const current = row.dualPd == null || row.dualPd === '' ? this.DUAL_PD_DEFAULT : Number(row.dualPd)
if (Number.isNaN(current)) return
row.dualPd = Math.min(this.DUAL_PD_MAX, Math.max(0, current + delta))
row.dualPd = Math.min(this.DUAL_PD_MAX, Math.max(this.DUAL_PD_MIN, current + delta))
},
adjustPupilHeight(row, delta) {
const current = row.pupilHeight == null || row.pupilHeight === '' ? this.PUPIL_HEIGHT_MIN : Number(row.pupilHeight)
@@ -1427,20 +1609,53 @@ export default {
const current = row.nearAdd == null || row.nearAdd === '' ? 0 : Number(row.nearAdd)
if (Number.isNaN(current)) return
const next = Math.round((current + delta) * 100) / 100
row.nearAdd = Math.min(3, Math.max(0.5, next))
row.nearAdd = Math.min(this.NEAR_ADD_MAX, Math.max(this.NEAR_ADD_MIN, next))
},
isNearAddInvalid(row) {
if (Number(this.form.progressiveMultifocal) !== 1) return false
if (row.nearAdd == null || row.nearAdd === '') return true
const num = Number(row.nearAdd)
return Number.isNaN(num) || num === 0 || num < this.NEAR_ADD_MIN || num > this.NEAR_ADD_MAX
},
onNearAddChange(val, row) {
if (Number(this.form.progressiveMultifocal) !== 1) {
row.nearAdd = null
return
}
if (val == null || val === '') {
row.nearAdd = null
return
}
const num = Number(val)
if (Number.isNaN(num) || num === 0) {
row.nearAdd = null
return
}
row.nearAdd = Math.min(this.NEAR_ADD_MAX, Math.max(this.NEAR_ADD_MIN, num))
},
validateNearAddRequired() {
if (Number(this.form.progressiveMultifocal) !== 1) return null
const list = this.form.optometryList || []
for (const row of list) {
if (!this.isNearAddInvalid(row)) continue
const eyeLabel = row.eyeSide === 'OS' ? '左眼' : '右眼'
return `${eyeLabel}选择渐进多焦点时ADD不能为0请填写+0.75~+4.00`
}
return null
},
handlePdModeChange(mode) {
this.pdMode = mode === 'dual' ? 'dual' : 'single'
if (!this.form.optometryList) return
if (mode === 'dual') {
if (this.pdMode === 'dual') {
this.form.optometryList.forEach(row => {
row.dualPd = this.DUAL_PD_DEFAULT
row.dualPd = row.dualPd != null ? row.dualPd : this.DUAL_PD_DEFAULT
row.pd = null
})
this.singlePd = null
} else {
this.singlePd = this.SINGLE_PD_DEFAULT
this.singlePd = this.singlePd != null ? this.singlePd : this.SINGLE_PD_DEFAULT
this.form.optometryList.forEach(row => {
row.pd = this.SINGLE_PD_DEFAULT
row.pd = this.singlePd
row.dualPd = null
})
}
@@ -1460,6 +1675,19 @@ export default {
row.pdType = pdType
})
}
if (Number(this.form.progressiveMultifocal) !== 1 && this.form.optometryList) {
this.form.optometryList.forEach(row => {
row.nearAdd = null
row.pupilHeight = null
})
}
if (this.form.optometryList) {
this.form.optometryList.forEach(row => {
if (!this.isAxisAEditable(row)) {
row.axisA = null
}
})
}
},
cancel() {
this.open = false
@@ -1468,8 +1696,19 @@ export default {
this.reset()
},
handleProgressiveMultifocalChange(value) {
if (Number(value) !== 1) {
this.form.progressiveMultifocalPrice = 0
if (Number(value) === 1) {
this.pdMode = 'dual'
this.handlePdModeChange('dual')
return
}
this.form.progressiveMultifocalPrice = 0
this.pdMode = 'single'
this.handlePdModeChange('single')
if (this.form.optometryList) {
this.form.optometryList.forEach(row => {
row.nearAdd = null
row.pupilHeight = null
})
}
},
reset() {
@@ -1553,43 +1792,57 @@ export default {
row.distanceVa = Math.min(2, Math.max(0.02, num))
}
}
if (row.sphereS == null || row.sphereS === '') {
row.sphereS = 0
} else {
const sphereS = Number(row.sphereS)
if (Number.isNaN(sphereS)) {
row.sphereS = 0
} else {
row.sphereS = Math.min(this.SPHERE_S_MAX, Math.max(this.SPHERE_S_MIN, sphereS))
}
}
if (row.cylinderC != null && row.cylinderC !== '') {
let cylinder = Number(row.cylinderC)
if (!Number.isNaN(cylinder)) {
if (cylinder > 0) {
const sphereSign = this.getSphereSign(row.sphereS)
if (sphereSign > 0 && cylinder < 0) {
cylinder = Math.abs(cylinder)
} else if (sphereSign < 0 && cylinder > 0) {
cylinder = -Math.abs(cylinder)
}
row.cylinderC = Math.min(0, Math.max(this.CYLINDER_C_MIN, cylinder))
row.cylinderC = Math.min(this.getCylinderCMax(row), Math.max(this.getCylinderCMin(row), cylinder))
}
}
if (row.sphereS != null && row.sphereS !== '') {
const sphereS = Number(row.sphereS)
if (!Number.isNaN(sphereS)) {
row.sphereS = Math.min(this.SPHERE_S_MAX, Math.max(-this.SPHERE_S_MAX, sphereS))
}
if (!this.isAxisAEditable(row)) {
row.axisA = null
}
if (row.nearAdd != null && row.nearAdd !== '') {
if (Number(form.progressiveMultifocal) === 1 && row.nearAdd != null && row.nearAdd !== '') {
const nearAdd = Number(row.nearAdd)
if (!Number.isNaN(nearAdd)) {
row.nearAdd = Math.min(3, Math.max(0.5, nearAdd))
row.nearAdd = Math.min(this.NEAR_ADD_MAX, Math.max(this.NEAR_ADD_MIN, nearAdd))
}
} else {
row.nearAdd = null
}
if (Number(form.progressiveMultifocal) !== 1) {
row.pupilHeight = null
} else if (row.pupilHeight != null && row.pupilHeight !== '') {
const pupilHeight = Number(row.pupilHeight)
if (!Number.isNaN(pupilHeight)) {
row.pupilHeight = Math.min(this.PUPIL_HEIGHT_MAX, Math.max(this.PUPIL_HEIGHT_MIN, pupilHeight))
}
}
if (row.pd != null && row.pd !== '') {
const pd = Number(row.pd)
if (!Number.isNaN(pd)) {
row.pd = Math.min(this.SINGLE_PD_MAX, Math.max(0, pd))
row.pd = Math.min(this.SINGLE_PD_MAX, Math.max(this.SINGLE_PD_MIN, pd))
}
}
if (row.dualPd != null && row.dualPd !== '') {
const dualPd = Number(row.dualPd)
if (!Number.isNaN(dualPd)) {
row.dualPd = Math.min(this.DUAL_PD_MAX, Math.max(0, dualPd))
}
}
if (row.pupilHeight != null && row.pupilHeight !== '') {
const pupilHeight = Number(row.pupilHeight)
if (!Number.isNaN(pupilHeight)) {
row.pupilHeight = Math.min(this.PUPIL_HEIGHT_MAX, Math.max(this.PUPIL_HEIGHT_MIN, pupilHeight))
row.dualPd = Math.min(this.DUAL_PD_MAX, Math.max(this.DUAL_PD_MIN, dualPd))
}
}
})
@@ -1604,7 +1857,9 @@ export default {
if (!this.form.optometryList || this.form.optometryList.length === 0) {
this.form.optometryList = this.createDefaultOptometryList()
}
this.pdMode = this.detectPdMode(this.form.optometryList)
this.pdMode = Number(this.form.progressiveMultifocal) === 1
? 'dual'
: this.detectPdMode(this.form.optometryList)
if (this.pdMode === 'single') {
this.initSinglePd()
} else {
@@ -1613,6 +1868,8 @@ export default {
if (row.dualPd == null) {
row.dualPd = this.DUAL_PD_DEFAULT
}
row.pd = null
row.pdType = this.PD_TYPE_DUAL
})
}
this.formMode = mode
@@ -1923,6 +2180,21 @@ export default {
})
},
saveForm(orderStatus, successMsg) {
const cylinderErr = this.validateCylinderSignWithSphere()
if (cylinderErr) {
this.$modal.msgWarning(cylinderErr)
return Promise.reject(new Error(cylinderErr))
}
const axisErr = this.validateAxisARequired()
if (axisErr) {
this.$modal.msgWarning(axisErr)
return Promise.reject(new Error(axisErr))
}
const nearAddErr = this.validateNearAddRequired()
if (nearAddErr) {
this.$modal.msgWarning(nearAddErr)
return Promise.reject(new Error(nearAddErr))
}
this.prepareOptometryForSave()
const progressiveMultifocal = this.form.progressiveMultifocal != null
? Number(this.form.progressiveMultifocal) : 0
@@ -2140,13 +2412,22 @@ export default {
.pd-mode-switch {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 8px;
margin-bottom: 12px;
.pd-mode-label {
margin-right: 12px;
margin-right: 4px;
color: #606266;
font-size: 14px;
}
.pd-mode-tip {
margin-left: 8px;
color: #909399;
font-size: 12px;
line-height: 1.4;
}
}
.degree-sup {
@@ -2220,11 +2501,41 @@ export default {
background: #eff6ff;
}
&:disabled {
color: #94a3b8;
background: #f1f5f9;
border-color: #e2e8f0;
cursor: not-allowed;
}
&:active {
background: #dbeafe;
}
}
.axis-input-wrap.is-disabled {
opacity: 0.72;
}
.axis-input-wrap.is-error {
::v-deep .el-input-number .el-input__inner {
border-color: #f56c6c;
background-color: #fef0f0;
}
::v-deep .el-input-number.is-controls-right .el-input-number__decrease,
::v-deep .el-input-number.is-controls-right .el-input-number__increase {
border-color: #f56c6c;
}
}
.axis-error-tip {
margin-top: 4px;
font-size: 12px;
line-height: 1.2;
color: #f56c6c;
}
.sphere-s-hint {
position: absolute;
top: 0;
@@ -2389,6 +2700,7 @@ export default {
.pd-mode-switch {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 12px;
margin-bottom: 14px;
padding: 10px 14px;
@@ -2402,6 +2714,13 @@ export default {
color: #475569;
}
.pd-mode-tip {
margin-left: 4px;
font-size: 12px;
color: #64748b;
line-height: 1.4;
}
.el-radio-button__inner {
border-color: rgba(37, 99, 235, 0.2);
color: #475569;

View File

@@ -62,6 +62,9 @@ public class JySysOrder extends BaseEntity
@Excel(name = "渐进多焦点价格")
private BigDecimal progressiveMultifocalPrice;
@Excel(name = "是否老花", readConverterExp = "0=否,1=是")
private Integer presbyopia;
@Excel(name = "订单状态", dictType = "jy_order_status")
private String orderStatus;
@@ -261,6 +264,16 @@ public class JySysOrder extends BaseEntity
this.progressiveMultifocalPrice = progressiveMultifocalPrice;
}
public Integer getPresbyopia()
{
return presbyopia;
}
public void setPresbyopia(Integer presbyopia)
{
this.presbyopia = presbyopia;
}
public String getOrderStatus()
{
return orderStatus;
@@ -385,6 +398,7 @@ public class JySysOrder extends BaseEntity
.append("priceC", getPriceC())
.append("logisticsFee", getLogisticsFee())
.append("progressiveMultifocal", getProgressiveMultifocal())
.append("presbyopia", getPresbyopia())
.append("orderStatus", getOrderStatus())
.append("purchaseSettleStatus", getPurchaseSettleStatus())
.append("saleSettleStatus", getSaleSettleStatus())

View File

@@ -22,6 +22,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="logisticsFee" column="logistics_fee" />
<result property="progressiveMultifocal" column="progressive_multifocal" />
<result property="progressiveMultifocalPrice" column="progressive_multifocal_price" />
<result property="presbyopia" column="presbyopia" />
<result property="orderStatus" column="order_status" />
<result property="purchaseSettleStatus" column="purchase_settle_status" />
<result property="saleSettleStatus" column="sale_settle_status" />
@@ -42,7 +43,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
o.lens_factory_tenant_id, lt.name as lens_factory_tenant_name,
o.product_id, p.product_model, p.product_name,
o.lens_id, l.product_name as lens_product_name, l.material as lens_material,
o.price_b, o.price_c, o.logistics_fee, o.progressive_multifocal, o.progressive_multifocal_price, o.order_status, o.purchase_settle_status, o.sale_settle_status,
o.price_b, o.price_c, o.logistics_fee, o.progressive_multifocal, o.progressive_multifocal_price, o.presbyopia, o.order_status, o.purchase_settle_status, o.sale_settle_status,
o.receiver_name, o.receiver_phone, o.receiver_address, o.attachment,
o.remark, o.del_flag, o.create_by, o.create_time, o.update_by, o.update_time
from jy_sys_order o
@@ -98,6 +99,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="logisticsFee != null">logistics_fee,</if>
<if test="progressiveMultifocal != null">progressive_multifocal,</if>
<if test="progressiveMultifocalPrice != null">progressive_multifocal_price,</if>
<if test="presbyopia != null">presbyopia,</if>
<if test="orderStatus != null">order_status,</if>
<if test="purchaseSettleStatus != null">purchase_settle_status,</if>
<if test="saleSettleStatus != null">sale_settle_status,</if>
@@ -123,6 +125,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="logisticsFee != null">#{logisticsFee},</if>
<if test="progressiveMultifocal != null">#{progressiveMultifocal},</if>
<if test="progressiveMultifocalPrice != null">#{progressiveMultifocalPrice},</if>
<if test="presbyopia != null">#{presbyopia},</if>
<if test="orderStatus != null">#{orderStatus},</if>
<if test="purchaseSettleStatus != null">#{purchaseSettleStatus},</if>
<if test="saleSettleStatus != null">#{saleSettleStatus},</if>
@@ -152,6 +155,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="logisticsFee != null">logistics_fee = #{logisticsFee},</if>
<if test="progressiveMultifocal != null">progressive_multifocal = #{progressiveMultifocal},</if>
<if test="progressiveMultifocalPrice != null">progressive_multifocal_price = #{progressiveMultifocalPrice},</if>
<if test="presbyopia != null">presbyopia = #{presbyopia},</if>
<if test="orderStatus != null">order_status = #{orderStatus},</if>
<if test="purchaseSettleStatus != null">purchase_settle_status = #{purchaseSettleStatus},</if>
<if test="saleSettleStatus != null">sale_settle_status = #{saleSettleStatus},</if>
@@ -196,7 +200,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
select o.id, o.order_no, o.brand_tenant_id, bt.name as brand_tenant_name,
o.lens_factory_tenant_id, lf.name as lens_factory_tenant_name,
o.product_id, o.lens_id, o.price_b, o.price_c, o.logistics_fee,
o.progressive_multifocal, o.progressive_multifocal_price, o.order_status,
o.progressive_multifocal, o.progressive_multifocal_price, o.presbyopia, o.order_status,
o.purchase_settle_status, o.sale_settle_status,
o.receiver_name, o.receiver_phone, o.receiver_address, o.attachment, o.remark,
o.del_flag, o.create_by, o.create_time, o.update_by, o.update_time

View File

@@ -16,6 +16,7 @@ CREATE TABLE `jy_sys_order` (
`logistics_fee` decimal(10, 2) NULL DEFAULT NULL COMMENT '物流费用',
`progressive_multifocal` tinyint(4) NULL DEFAULT 0 COMMENT '是否渐进多焦点0否 1是',
`progressive_multifocal_price` decimal(10, 2) NULL DEFAULT 0 COMMENT '渐进多焦点价格',
`presbyopia` tinyint(4) NULL DEFAULT 0 COMMENT '是否老花0否 1是',
`order_status` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '1' COMMENT '订单状态(字典 jy_order_status',
`purchase_settle_status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '采购结算状态0未结算 1已结算',
`sale_settle_status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '销售结算状态0未结算 1已结算',