vision-detail.vue 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. <template>
  2. <view class="page">
  3. <view class="bg-gradient"></view>
  4. <van-nav-bar title="视力数据详情" left-arrow @click-left="onBack" fixed :z-index="999" />
  5. <view class="header">
  6. <view class="student-info">
  7. <view class="info-row">
  8. <image class="gender-icon" :src="studentInfo.gender === '男' ? '/static/images/icon/man.png' : '/static/images/icon/woman.png'" mode="aspectFit"></image>
  9. <text class="student-name">{{ studentInfo.name }}</text>
  10. </view>
  11. <view class="detail-row">
  12. <text>学校:{{ schoolName }}</text>
  13. </view>
  14. <view class="detail-row">
  15. <text>班级:{{ studentInfo.class }}</text>
  16. </view>
  17. <view class="detail-row">
  18. <text>身份证:{{ studentInfo.idCard }}</text>
  19. </view>
  20. </view>
  21. </view>
  22. <view class="content">
  23. <view class="section-header">
  24. <text class="section-title">视力数据</text>
  25. </view>
  26. <view class="form-item">
  27. <text class="label">左眼远视力</text>
  28. <input class="value-input" v-model="formData.leftVision" type="digit" placeholder="请输入" @blur="formatVision('leftVision')" />
  29. </view>
  30. <view class="form-item">
  31. <text class="label">右眼远视力</text>
  32. <input class="value-input" v-model="formData.rightVision" type="digit" placeholder="请输入" @blur="formatVision('rightVision')" />
  33. </view>
  34. <view class="section-header" style="margin-top: 40rpx;">
  35. <text class="section-title">屈光度数据</text>
  36. </view>
  37. <view class="form-item">
  38. <text class="label">左眼屈光度</text>
  39. <input class="value-input" v-model="formData.leftRefraction" type="number" placeholder="请输入" />
  40. </view>
  41. <view class="form-item">
  42. <text class="label">右眼屈光度</text>
  43. <input class="value-input" v-model="formData.rightRefraction" type="number" placeholder="请输入" />
  44. </view>
  45. </view>
  46. <view class="footer">
  47. <view class="footer-btns">
  48. <van-button plain type="primary" round size="large" @click="onBack" icon="replay">返回</van-button>
  49. <van-button type="primary" round size="large" icon="success" @click="handleSave">保存</van-button>
  50. </view>
  51. </view>
  52. </view>
  53. </template>
  54. <script setup>
  55. import { getStudentVisionData, updateVisionData } from '@/services/common'
  56. const studentInfo = ref({})
  57. const schoolName = ref('')
  58. const visionDataId = ref('')
  59. const userName = ref('')
  60. const userPhone = ref('')
  61. const formData = ref({
  62. leftVision: '',
  63. rightVision: '',
  64. leftRefraction: '',
  65. rightRefraction: ''
  66. })
  67. onLoad(async (options) => {
  68. studentInfo.value = {
  69. id: options.studentId || '',
  70. name: decodeURIComponent(options.studentName || ''),
  71. gender: decodeURIComponent(options.studentGender || ''),
  72. idCard: decodeURIComponent(options.studentIdCard || ''),
  73. class: `${decodeURIComponent(options.grade || '')} ${decodeURIComponent(options.className || '')}`
  74. }
  75. schoolName.value = decodeURIComponent(options.schoolName || '')
  76. userName.value = decodeURIComponent(options.userName || '')
  77. userPhone.value = decodeURIComponent(options.userPhone || '')
  78. await fetchVisionData()
  79. })
  80. const fetchVisionData = async () => {
  81. try {
  82. const res = await getStudentVisionData(studentInfo.value.id)
  83. if (res && res.code === 200 && res.data) {
  84. const data = res.data
  85. visionDataId.value = data.id || ''
  86. formData.value.leftVision = data.left_eye_vision !== null && data.left_eye_vision !== undefined ? data.left_eye_vision : ''
  87. formData.value.rightVision = data.right_eye_vision !== null && data.right_eye_vision !== undefined ? data.right_eye_vision : ''
  88. formData.value.leftRefraction = data.left_eye_refraction !== null && data.left_eye_refraction !== undefined ? data.left_eye_refraction : ''
  89. formData.value.rightRefraction = data.right_eye_refraction !== null && data.right_eye_refraction !== undefined ? data.right_eye_refraction : ''
  90. }
  91. } catch (error) {
  92. console.error('获取视力数据失败', error)
  93. }
  94. }
  95. const formatVision = (field) => {
  96. const value = parseFloat(formData.value[field])
  97. if (!isNaN(value)) {
  98. formData.value[field] = value.toFixed(1)
  99. }
  100. }
  101. const handleSave = async () => {
  102. if (!formData.value.leftVision || !formData.value.rightVision || !formData.value.leftRefraction || !formData.value.rightRefraction) {
  103. return uni.showToast({
  104. title: '请填写完整信息',
  105. icon: 'none'
  106. })
  107. }
  108. try {
  109. const params = {
  110. left_eye_vision: parseFloat(formData.value.leftVision),
  111. right_eye_vision: parseFloat(formData.value.rightVision),
  112. left_eye_refraction: parseFloat(formData.value.leftRefraction),
  113. right_eye_refraction: parseFloat(formData.value.rightRefraction),
  114. input_user: userName.value,
  115. operator_phone: userPhone.value
  116. }
  117. const res = await updateVisionData(visionDataId.value, params)
  118. if (res && res.code === 200) {
  119. uni.showToast({
  120. title: '保存成功',
  121. icon: 'success',
  122. duration: 1000
  123. })
  124. setTimeout(() => {
  125. uni.navigateBack()
  126. }, 1000)
  127. }
  128. } catch (error) {
  129. console.error('保存失败', error)
  130. }
  131. }
  132. const onBack = () => {
  133. uni.navigateBack()
  134. }
  135. </script>
  136. <style lang="scss" scoped>
  137. .page {
  138. min-height: 100vh;
  139. position: relative;
  140. }
  141. .bg-gradient {
  142. position: fixed;
  143. top: 0;
  144. left: 0;
  145. right: 0;
  146. bottom: 0;
  147. background: linear-gradient(180deg, #4A9FF5 0%, #E8F5FF 100%);
  148. z-index: 0;
  149. pointer-events: none;
  150. }
  151. .header {
  152. padding: 20rpx 30rpx;
  153. padding-top: calc(20rpx + 46px);
  154. position: relative;
  155. z-index: 1;
  156. }
  157. .student-info {
  158. background: rgba(255, 255, 255, 0.9);
  159. border-radius: 20rpx;
  160. padding: 30rpx;
  161. }
  162. .info-row {
  163. display: flex;
  164. align-items: center;
  165. margin-bottom: 20rpx;
  166. }
  167. .gender-icon {
  168. width: 40rpx;
  169. height: 40rpx;
  170. margin-right: 10rpx;
  171. }
  172. .student-name {
  173. font-size: 32rpx;
  174. font-weight: bold;
  175. color: #333;
  176. }
  177. .detail-row {
  178. font-size: 26rpx;
  179. color: #666;
  180. margin-top: 10rpx;
  181. }
  182. .content {
  183. padding: 30rpx;
  184. position: relative;
  185. z-index: 1;
  186. padding-bottom: 150rpx;
  187. }
  188. .section-header {
  189. display: flex;
  190. align-items: center;
  191. justify-content: space-between;
  192. margin-bottom: 20rpx;
  193. }
  194. .section-title {
  195. font-size: 32rpx;
  196. font-weight: bold;
  197. color: #333;
  198. }
  199. .form-item {
  200. background: #fff;
  201. border-radius: 20rpx;
  202. padding: 30rpx;
  203. margin-bottom: 20rpx;
  204. display: flex;
  205. align-items: center;
  206. justify-content: space-between;
  207. }
  208. .label {
  209. font-size: 28rpx;
  210. color: #333;
  211. }
  212. .value-input {
  213. font-size: 32rpx;
  214. font-weight: bold;
  215. color: #0063F5;
  216. flex: 1;
  217. text-align: center;
  218. }
  219. .footer {
  220. position: fixed;
  221. bottom: 0;
  222. left: 0;
  223. right: 0;
  224. padding: 30rpx;
  225. background: #fff;
  226. z-index: 10;
  227. }
  228. .footer-btns {
  229. display: flex;
  230. gap: 20rpx;
  231. button {
  232. flex: 1;
  233. }
  234. }
  235. </style>