bodyParams.nvue 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. <template>
  2. <view class="page">
  3. <image class="content-bg" src="/static/device/devicebg.png" mode="scaleToFill"></image>
  4. <view class="pageContent">
  5. <view class="status-bar" :style="{height: statusBarHeight + 'px'}"></view>
  6. <view class="customHead">
  7. <view class="back-wrap" @click="goBack">
  8. <image src="/static/public/back.png" mode="aspectFill" class="backimg"></image>
  9. </view>
  10. <text class="customTitle">体形参数</text>
  11. <view class="placeholder"></view>
  12. </view>
  13. <text class="tipTxt">请录入体形参数,用于精准定位穴位</text>
  14. <scroll-view class="formArea" scroll-y="true">
  15. <view class="formInner">
  16. <!-- 用户姓名 -->
  17. <view class="formItem">
  18. <text class="formLabel">姓名</text>
  19. <view class="inputWrap">
  20. <input class="formInput" v-model="form.name" placeholder="请输入姓名" placeholder-class="pholder" maxlength="10" />
  21. </view>
  22. </view>
  23. <!-- 性别 -->
  24. <view class="formItem">
  25. <text class="formLabel">性别</text>
  26. <view class="genderRow">
  27. <view class="genderBtn" :class="{'genderActive': form.gender === 1}" @click="form.gender = 1">
  28. <text class="genderTxt" :style="{color: form.gender === 1 ? '#FFFFFF' : '#545F71'}">男</text>
  29. </view>
  30. <view class="genderBtn" :class="{'genderActive': form.gender === 2}" @click="form.gender = 2">
  31. <text class="genderTxt" :style="{color: form.gender === 2 ? '#FFFFFF' : '#545F71'}">女</text>
  32. </view>
  33. </view>
  34. </view>
  35. <!-- 年龄 -->
  36. <view class="formItem">
  37. <text class="formLabel">年龄</text>
  38. <view class="inputWrap">
  39. <input class="formInput" v-model="form.age" type="number" placeholder="例如:28" placeholder-class="pholder" maxlength="3" />
  40. <text class="unitTxt">岁</text>
  41. </view>
  42. </view>
  43. <!-- 肩高 -->
  44. <view class="formItem">
  45. <text class="formLabel">肩高(地面到肩膀的高度)</text>
  46. <view class="inputWrap">
  47. <input class="formInput" v-model="form.shoulderHeight" type="digit" placeholder="例如:135" placeholder-class="pholder" />
  48. <text class="unitTxt">cm</text>
  49. </view>
  50. </view>
  51. <!-- 肩宽 -->
  52. <view class="formItem">
  53. <text class="formLabel">肩宽(两肩之间的宽度)</text>
  54. <view class="inputWrap">
  55. <input class="formInput" v-model="form.shoulderWidth" type="digit" placeholder="例如:42" placeholder-class="pholder" />
  56. <text class="unitTxt">cm</text>
  57. </view>
  58. </view>
  59. <!-- 体重 -->
  60. <view class="formItem">
  61. <text class="formLabel">体重</text>
  62. <view class="inputWrap">
  63. <input class="formInput" v-model="form.weight" type="digit" placeholder="例如:65" placeholder-class="pholder" />
  64. <text class="unitTxt">kg</text>
  65. </view>
  66. </view>
  67. <!-- 保存按钮 -->
  68. <view class="saveBtn" @click="onSave">
  69. <text class="saveTxt">保存</text>
  70. </view>
  71. <view class="bottomSpace"></view>
  72. </view>
  73. </scroll-view>
  74. </view>
  75. <ay-toast ref="ayToast" />
  76. </view>
  77. </template>
  78. <script>
  79. import ayToast from '@/components/ay-toast/ay-toast.nvue'
  80. export default {
  81. components: {
  82. ayToast
  83. },
  84. data() {
  85. return {
  86. statusBarHeight: 44,
  87. mode: 'add', // add / edit
  88. userId: '',
  89. form: {
  90. name: '',
  91. gender: 1,
  92. age: '',
  93. shoulderHeight: '',
  94. shoulderWidth: '',
  95. weight: ''
  96. }
  97. }
  98. },
  99. onLoad(options) {
  100. const sysInfo = uni.getSystemInfoSync()
  101. this.statusBarHeight = sysInfo.statusBarHeight || 44
  102. this.mode = options.mode || 'add'
  103. this.userId = options.userId || ''
  104. if (this.mode === 'edit' && this.userId) {
  105. this.loadUserData()
  106. }
  107. },
  108. methods: {
  109. goBack() {
  110. uni.navigateBack()
  111. },
  112. /** 加载编辑数据 */
  113. loadUserData() {
  114. const list = uni.getStorageSync('user_manage_list') || []
  115. const user = list.find(u => u.id === this.userId)
  116. if (user) {
  117. this.form.name = user.name || ''
  118. this.form.gender = user.gender || 1
  119. this.form.age = user.age ? String(user.age) : ''
  120. this.form.shoulderHeight = user.shoulderHeight ? String(user.shoulderHeight) : ''
  121. this.form.shoulderWidth = user.shoulderWidth ? String(user.shoulderWidth) : ''
  122. this.form.weight = user.weight ? String(user.weight) : ''
  123. }
  124. },
  125. /** 校验并保存 */
  126. onSave() {
  127. // 校验
  128. if (!this.form.name.trim()) {
  129. this.$refs.ayToast.error('请输入姓名')
  130. return
  131. }
  132. const height = Number(this.form.shoulderHeight)
  133. if (!height || height < 50 || height > 250) {
  134. this.$refs.ayToast.error('肩高范围为50-250cm')
  135. return
  136. }
  137. const width = Number(this.form.shoulderWidth)
  138. if (!width || width < 20 || width > 80) {
  139. this.$refs.ayToast.error('肩宽范围为20-80cm')
  140. return
  141. }
  142. const weight = Number(this.form.weight)
  143. if (!weight || weight < 10 || weight > 300) {
  144. this.$refs.ayToast.error('体重范围为10-300kg')
  145. return
  146. }
  147. let list = uni.getStorageSync('user_manage_list') || []
  148. if (this.mode === 'add') {
  149. // 再次检查是否超过10个
  150. if (list.length >= 10) {
  151. this.$refs.ayToast.error('最多可添加10个用户')
  152. return
  153. }
  154. const newUser = {
  155. id: 'user_' + Date.now() + '_' + Math.random().toString(36).substr(2, 6),
  156. name: this.form.name.trim(),
  157. gender: this.form.gender,
  158. age: Number(this.form.age) || 0,
  159. shoulderHeight: height,
  160. shoulderWidth: width,
  161. weight: weight,
  162. createTime: Date.now()
  163. }
  164. list.push(newUser)
  165. uni.setStorageSync('user_manage_list', list)
  166. // 如果是第一个用户,自动设为当前用户
  167. if (list.length === 1) {
  168. uni.setStorageSync('current_manage_user_id', newUser.id)
  169. uni.setStorageSync('current_manage_user', newUser)
  170. }
  171. this.$refs.ayToast.success('添加成功')
  172. } else {
  173. // 编辑模式
  174. const index = list.findIndex(u => u.id === this.userId)
  175. if (index === -1) {
  176. this.$refs.ayToast.error('用户信息已过期,请刷新')
  177. return
  178. }
  179. list[index] = {
  180. ...list[index],
  181. name: this.form.name.trim(),
  182. gender: this.form.gender,
  183. age: Number(this.form.age) || 0,
  184. shoulderHeight: height,
  185. shoulderWidth: width,
  186. weight: weight
  187. }
  188. uni.setStorageSync('user_manage_list', list)
  189. // 如果编辑的是当前用户,更新当前用户缓存
  190. const curId = uni.getStorageSync('current_manage_user_id')
  191. if (curId === this.userId) {
  192. uni.setStorageSync('current_manage_user', list[index])
  193. }
  194. this.$refs.ayToast.success('保存成功')
  195. }
  196. setTimeout(() => {
  197. uni.navigateBack()
  198. }, 800)
  199. }
  200. }
  201. }
  202. </script>
  203. <style>
  204. .page {
  205. flex: 1;
  206. position: relative;
  207. }
  208. .content-bg {
  209. position: absolute;
  210. left: 0;
  211. top: 0;
  212. width: 750rpx;
  213. height: 2000px;
  214. }
  215. .pageContent {
  216. flex: 1;
  217. background-image: linear-gradient(to bottom, rgba(56,149,136,1), rgba(56,149,136,0.5));
  218. }
  219. .status-bar {
  220. background-color: rgba(0,0,0,0);
  221. }
  222. .customHead {
  223. flex-direction: row;
  224. justify-content: space-between;
  225. align-items: center;
  226. height: 88rpx;
  227. padding-left: 30rpx;
  228. padding-right: 30rpx;
  229. }
  230. .back-wrap {
  231. width: 50rpx;
  232. height: 50rpx;
  233. justify-content: center;
  234. align-items: center;
  235. }
  236. .backimg {
  237. width: 50rpx;
  238. height: 50rpx;
  239. }
  240. .customTitle {
  241. font-weight: bold;
  242. font-size: 32rpx;
  243. color: #FFFFFF;
  244. }
  245. .placeholder {
  246. width: 50rpx;
  247. }
  248. .tipTxt {
  249. font-size: 24rpx;
  250. color: rgba(255,255,255,0.7);
  251. margin-left: 38rpx;
  252. margin-top: 10rpx;
  253. margin-bottom: 20rpx;
  254. }
  255. .formArea {
  256. flex: 1;
  257. }
  258. .formInner {
  259. padding-left: 30rpx;
  260. padding-right: 30rpx;
  261. }
  262. .formItem {
  263. background-color: #FFFFFF;
  264. border-radius: 16rpx;
  265. padding: 28rpx;
  266. margin-bottom: 20rpx;
  267. }
  268. .formLabel {
  269. font-size: 26rpx;
  270. color: #9BA5B7;
  271. margin-bottom: 16rpx;
  272. }
  273. .inputWrap {
  274. flex-direction: row;
  275. align-items: center;
  276. background-color: #F5F7FA;
  277. border-radius: 12rpx;
  278. padding-left: 20rpx;
  279. padding-right: 20rpx;
  280. height: 80rpx;
  281. }
  282. .formInput {
  283. flex: 1;
  284. font-size: 30rpx;
  285. color: #333333;
  286. }
  287. .unitTxt {
  288. font-size: 26rpx;
  289. color: #9BA5B7;
  290. margin-left: 10rpx;
  291. }
  292. .genderRow {
  293. flex-direction: row;
  294. }
  295. .genderBtn {
  296. width: 160rpx;
  297. height: 72rpx;
  298. border-radius: 36rpx;
  299. background-color: #F5F7FA;
  300. justify-content: center;
  301. align-items: center;
  302. margin-right: 24rpx;
  303. }
  304. .genderActive {
  305. background-color: #389588;
  306. }
  307. .genderTxt {
  308. font-size: 28rpx;
  309. }
  310. .saveBtn {
  311. background-color: #389588;
  312. border-radius: 44rpx;
  313. height: 88rpx;
  314. justify-content: center;
  315. align-items: center;
  316. margin-top: 30rpx;
  317. margin-left: 20rpx;
  318. margin-right: 20rpx;
  319. }
  320. .saveTxt {
  321. font-size: 32rpx;
  322. color: #FFFFFF;
  323. font-weight: bold;
  324. }
  325. .bottomSpace {
  326. height: 60rpx;
  327. }
  328. </style>