phone.vue 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. <template>
  2. <view class="container" :style="{paddingTop: navbarHeight + 'rpx'}">
  3. <!-- 顶部渐变背景 -->
  4. <view class="top-gradient"></view>
  5. <!-- 自定义导航栏 -->
  6. <view class="custom-navbar" :style="{paddingTop: statusBarHeight + 'px'}">
  7. <view class="navbar-content">
  8. <view class="navbar-back" @click="handleBack">
  9. <view class="iconfont icon-right back-icon"></view>
  10. </view>
  11. <text class="navbar-title">手机号码</text>
  12. <view class="navbar-right" @click="handleConfirm">
  13. <text class="confirm-text" :class="{ disabled: !canConfirm }">确定</text>
  14. </view>
  15. </view>
  16. </view>
  17. <!-- 输入区域 -->
  18. <view class="input-container">
  19. <view class="input-wrapper">
  20. <input
  21. class="phone-input"
  22. v-model="phoneValue"
  23. placeholder="请输入手机号码"
  24. maxlength="11"
  25. type="number"
  26. @input="handleInput"
  27. />
  28. <view class="char-count">{{ phoneValue.length }}/11</view>
  29. </view>
  30. </view>
  31. </view>
  32. </template>
  33. <script>
  34. import { editLawyerUser } from "@/api/api"
  35. export default {
  36. data() {
  37. return {
  38. phoneValue: '',
  39. originalPhone: '',
  40. statusBarHeight: 0,
  41. userId: null
  42. }
  43. },
  44. onLoad(options) {
  45. // 获取状态栏高度
  46. const systemInfo = uni.getSystemInfoSync()
  47. this.statusBarHeight = systemInfo.statusBarHeight || 0
  48. // 获取传入的手机号码和用户ID
  49. if (options.phone) {
  50. this.phoneValue = decodeURIComponent(options.phone)
  51. this.originalPhone = this.phoneValue
  52. }
  53. if (options.userId) {
  54. this.userId = options.userId
  55. }
  56. },
  57. computed: {
  58. navbarHeight() {
  59. // 状态栏高度(px转rpx) + 导航栏高度(88rpx) + 间距(20rpx)
  60. return (this.statusBarHeight * 2) + 88 + 20
  61. },
  62. canConfirm() {
  63. // 有输入且与原始值不同时可以确认
  64. return this.phoneValue.trim().length > 0 && this.phoneValue !== this.originalPhone
  65. }
  66. },
  67. methods: {
  68. handleInput(e) {
  69. this.phoneValue = e.detail.value
  70. },
  71. validatePhone(phone) {
  72. // 验证手机号码格式:11位数字,以1开头
  73. const phoneRegex = /^1[3-9]\d{9}$/
  74. return phoneRegex.test(phone)
  75. },
  76. handleBack() {
  77. uni.navigateBack()
  78. },
  79. handleConfirm() {
  80. if (!this.canConfirm) {
  81. return
  82. }
  83. const trimmedPhone = this.phoneValue.trim()
  84. if (trimmedPhone.length === 0) {
  85. uni.showToast({
  86. title: '请输入手机号码',
  87. icon: 'none'
  88. })
  89. return
  90. }
  91. // 验证手机号码格式
  92. if (!this.validatePhone(trimmedPhone)) {
  93. uni.showToast({
  94. title: '请输入正确的手机号码',
  95. icon: 'none'
  96. })
  97. return
  98. }
  99. // 显示加载提示
  100. uni.showLoading({
  101. title: '保存中...',
  102. mask: true
  103. })
  104. // 调用API更新手机号码
  105. const params = {
  106. id: this.userId || 1, // 如果没有传入userId,使用默认值1
  107. phone: trimmedPhone
  108. }
  109. editLawyerUser(params).then(response => {
  110. uni.hideLoading()
  111. uni.showToast({
  112. title: '保存成功',
  113. icon: 'success'
  114. })
  115. // 延迟返回,让用户看到成功提示
  116. setTimeout(() => {
  117. uni.navigateBack()
  118. }, 1500)
  119. }).catch(error => {
  120. uni.hideLoading()
  121. console.error('更新手机号码失败:', error)
  122. uni.showToast({
  123. title: error.message || '保存失败,请重试',
  124. icon: 'none'
  125. })
  126. })
  127. }
  128. }
  129. }
  130. </script>
  131. <style lang="scss" scoped>
  132. page {
  133. background-color: #f5f5f5;
  134. }
  135. .container {
  136. min-height: 100vh;
  137. padding: 0 30rpx 20rpx 30rpx;
  138. background-color: #f5f5f5;
  139. position: relative;
  140. // 顶部渐变背景
  141. .top-gradient {
  142. position: fixed;
  143. top: 0;
  144. left: 0;
  145. right: 0;
  146. height: 800rpx;
  147. background: linear-gradient(180deg, rgba(59, 130, 246, 0.1) 0%, rgba(147, 197, 253, 0.05) 50%, transparent 100%);
  148. z-index: 0;
  149. pointer-events: none;
  150. }
  151. // 自定义导航栏
  152. .custom-navbar {
  153. position: fixed;
  154. top: 0;
  155. left: 0;
  156. right: 0;
  157. z-index: 999;
  158. background-color: transparent;
  159. pointer-events: none;
  160. .navbar-content {
  161. display: flex;
  162. align-items: center;
  163. justify-content: center;
  164. height: 88rpx;
  165. pointer-events: auto;
  166. position: relative;
  167. .navbar-back {
  168. position: absolute;
  169. left: 30rpx;
  170. width: 60rpx;
  171. height: 60rpx;
  172. display: flex;
  173. align-items: center;
  174. justify-content: center;
  175. .back-icon {
  176. font-size: 36rpx;
  177. color: #000000;
  178. transform: rotate(180deg);
  179. }
  180. }
  181. .navbar-title {
  182. font-size: 36rpx;
  183. font-weight: 500;
  184. color: #000000;
  185. }
  186. .navbar-right {
  187. position: absolute;
  188. right: 30rpx;
  189. height: 60rpx;
  190. display: flex;
  191. align-items: center;
  192. justify-content: center;
  193. .confirm-text {
  194. font-size: 32rpx;
  195. color: #007AFF;
  196. font-weight: 400;
  197. &.disabled {
  198. color: #cccccc;
  199. }
  200. }
  201. }
  202. }
  203. }
  204. }
  205. // 输入区域
  206. .input-container {
  207. padding: 40rpx 0;
  208. margin-top: 20rpx;
  209. }
  210. .input-wrapper {
  211. position: relative;
  212. background-color: #f5f5f5;
  213. border-radius: 16rpx;
  214. padding: 32rpx 30rpx;
  215. min-height: 100rpx;
  216. display: flex;
  217. align-items: center;
  218. justify-content: space-between;
  219. }
  220. .phone-input {
  221. flex: 1;
  222. font-size: 32rpx;
  223. color: #000000;
  224. background-color: transparent;
  225. border: none;
  226. outline: none;
  227. padding: 0;
  228. margin: 0;
  229. }
  230. .char-count {
  231. font-size: 28rpx;
  232. color: #999999;
  233. margin-left: 20rpx;
  234. white-space: nowrap;
  235. }
  236. </style>