form.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. <template>
  2. <view class="container">
  3. <!-- 个人信息卡片 -->
  4. <view class="card">
  5. <!-- 手机号 -->
  6. <view class="form-item">
  7. <text class="label">手机号</text>
  8. <view class="input-box">
  9. <view class="prefix-area">
  10. <text class="prefix">+86</text>
  11. <text class="arrow-down">﹀</text>
  12. </view>
  13. <input class="input" type="number" v-model="formData.mobile" />
  14. </view>
  15. </view>
  16. <!-- 验证码 -->
  17. <view class="form-item">
  18. <text class="label">验证码</text>
  19. <view class="input-box">
  20. <input class="input" type="number" v-model="formData.code" placeholder="验证码" />
  21. <text class="get-code-text" @click="getVerifyCode">{{ countDown > 0 ? countDown + 's' : '获取验证码' }}</text>
  22. </view>
  23. </view>
  24. <!-- 姓名 -->
  25. <view class="form-item">
  26. <text class="label">姓名</text>
  27. <view class="input-box">
  28. <input class="input" type="text" v-model="formData.name" />
  29. </view>
  30. </view>
  31. <!-- 性别 -->
  32. <view class="form-item">
  33. <text class="label">性别</text>
  34. <view class="gender-group">
  35. <view class="radio-item" @click="formData.gender = 1">
  36. <text class="radio-icon" :class="{active: formData.gender === 1}">{{ formData.gender === 1 ? '♂' : '○' }}</text>
  37. <text class="radio-label" :class="{active: formData.gender === 1}"> 男</text>
  38. </view>
  39. <view class="radio-item" @click="formData.gender = 2">
  40. <text class="radio-icon" :class="{active: formData.gender === 2}">{{ formData.gender === 2 ? '♀' : '○' }}</text>
  41. <text class="radio-label" :class="{active: formData.gender === 2}"> 女</text>
  42. </view>
  43. </view>
  44. </view>
  45. <!-- 生日 -->
  46. <view class="form-item">
  47. <text class="label">生日</text>
  48. <view class="input-box" @click="openPicker">
  49. <text>{{ formData.birthday || '请选择生日' }}</text>
  50. <!-- 灰色箭头 SVG -->
  51. <svg class="arrow-right" style="width:24rpx; height:24rpx; margin-left: auto;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg">
  52. <path d="M340.864 149.312a30.592 30.592 0 0 0 0 42.752L652.736 512 340.864 831.872a30.592 30.592 0 0 0 0 42.752 29.12 29.12 0 0 0 41.728 0L714.24 534.336a32 32 0 0 0 0-45.056L382.592 149.312a29.12 29.12 0 0 0-41.728 0z" fill="#CCCCCC"></path>
  53. </svg>
  54. </view>
  55. </view>
  56. <!-- 密码 -->
  57. <view class="form-item">
  58. <text class="label">密码</text>
  59. <view class="input-box">
  60. <input class="input" :password="!showPwd" v-model="formData.password" placeholder="设置登录密码" />
  61. <view class="monkey-icon" @click="showPwd = !showPwd">
  62. <template v-if="showPwd">
  63. <!-- 睁眼线框图标 -->
  64. <svg class="svg-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
  65. <path d="M12 4.5C7 4.5 2.73 7.61 1 12C2.73 16.39 7 19.5 12 19.5C17 19.5 21.27 16.39 23 12C21.27 7.61 17 4.5 12 4.5ZM12 17C9.24 17 7 14.76 7 12C7 9.24 9.24 7 12 7C14.76 7 17 9.24 17 12C17 14.76 14.76 17 12 17ZM12 9C10.34 9 9 10.34 9 12C9 13.66 10.34 15 12 15C13.66 15 15 13.66 15 12C15 10.34 13.66 9 12 9Z" fill="#CCCCCC"/>
  66. </svg>
  67. </template>
  68. <template v-else>
  69. <!-- 闭眼线框图标 (带睫毛) -->
  70. <svg class="svg-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
  71. <path d="M12 7C7 7 2.73 10.11 1 14.5" stroke="#CCCCCC" stroke-width="2" stroke-linecap="round"/>
  72. <path d="M23 14.5C21.27 10.11 17 7 12 7" stroke="#CCCCCC" stroke-width="2" stroke-linecap="round"/>
  73. <path d="M12 7V4" stroke="#CCCCCC" stroke-width="2" stroke-linecap="round"/>
  74. <path d="M16 8L18 5" stroke="#CCCCCC" stroke-width="2" stroke-linecap="round"/>
  75. <path d="M8 8L6 5" stroke="#CCCCCC" stroke-width="2" stroke-linecap="round"/>
  76. <path d="M20 10L22 8" stroke="#CCCCCC" stroke-width="2" stroke-linecap="round"/>
  77. <path d="M4 10L2 8" stroke="#CCCCCC" stroke-width="2" stroke-linecap="round"/>
  78. </svg>
  79. </template>
  80. </view>
  81. </view>
  82. </view>
  83. </view>
  84. <!-- 服务类型卡片 -->
  85. <view class="card">
  86. <view class="section-title">服务类型</view>
  87. <view class="service-types">
  88. <view
  89. class="type-btn"
  90. v-for="(item, index) in serviceTypes"
  91. :key="item.id"
  92. :class="{selected: formData.serviceType.includes(item.id)}"
  93. @click="toggleService(item)"
  94. >
  95. {{ item.name }}
  96. </view>
  97. </view>
  98. <!-- 工作城市 -->
  99. <view class="form-item">
  100. <text class="label">工作城市</text>
  101. <view class="input-box" @click="openCityPicker">
  102. <text :style="{color: formData.city ? '#333' : '#ccc'}">{{ formData.city || '请选择工作城市' }}</text>
  103. <!-- 灰色箭头 SVG -->
  104. <svg class="arrow-right" style="width:24rpx; height:24rpx; margin-left: auto;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg">
  105. <path d="M340.864 149.312a30.592 30.592 0 0 0 0 42.752L652.736 512 340.864 831.872a30.592 30.592 0 0 0 0 42.752 29.12 29.12 0 0 0 41.728 0L714.24 534.336a32 32 0 0 0 0-45.056L382.592 149.312a29.12 29.12 0 0 0-41.728 0z" fill="#CCCCCC"></path>
  106. </svg>
  107. </view>
  108. </view>
  109. <!-- 服务站点 -->
  110. <view class="form-item">
  111. <text class="label">服务站点</text>
  112. <view class="input-box" @click="openStationPicker">
  113. <text :style="{color: formData.station ? '#333' : '#ccc'}">{{ formData.station || '请选择服务站点' }}</text>
  114. <!-- 灰色箭头 SVG -->
  115. <svg class="arrow-right" style="width:24rpx; height:24rpx; margin-left: auto;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg">
  116. <path d="M340.864 149.312a30.592 30.592 0 0 0 0 42.752L652.736 512 340.864 831.872a30.592 30.592 0 0 0 0 42.752 29.12 29.12 0 0 0 41.728 0L714.24 534.336a32 32 0 0 0 0-45.056L382.592 149.312a29.12 29.12 0 0 0-41.728 0z" fill="#CCCCCC"></path>
  117. </svg>
  118. </view>
  119. </view>
  120. </view>
  121. <!-- ... (Bottom content) ... -->
  122. <!-- 自定义日期选择器 (已存在) -->
  123. <!-- ... (Picker content) ... -->
  124. <!-- 自定义城市选择器 (级联版) -->
  125. <view class="picker-mask" :class="{show: showCityPicker}" @click="closeCityPicker">
  126. <view class="picker-content" @click.stop>
  127. <view class="picker-header">
  128. <text class="picker-btn-cancel" @click="closeCityPicker">取消</text>
  129. <text class="picker-title">请选择工作城市</text>
  130. <text class="picker-btn-confirm" @click="confirmCity">确定</text>
  131. </view>
  132. <view class="picker-body">
  133. <!-- 左侧:垂直路径 -->
  134. <view class="timeline-area">
  135. <!-- 已选节点 -->
  136. <view
  137. class="timeline-item"
  138. v-for="(item, index) in selectedPathway"
  139. :key="index"
  140. @click="jumpToStep(index)"
  141. >
  142. <view class="timeline-dot"></view>
  143. <text>{{ item.name }}</text>
  144. </view>
  145. <!-- 当前正在选的提示 (如果还没选完) -->
  146. <view
  147. class="timeline-item active"
  148. v-if="selectStep === selectedPathway.length"
  149. >
  150. <view class="timeline-dot"></view>
  151. <text>请选择</text>
  152. </view>
  153. </view>
  154. <!-- 右侧:待选项列表 -->
  155. <scroll-view scroll-y class="list-area">
  156. <view
  157. class="list-item"
  158. v-for="(item, index) in currentList"
  159. :key="item.id"
  160. @click="selectCityItem(item)"
  161. >
  162. {{ item.name }}
  163. </view>
  164. <view v-if="currentList.length === 0" style="padding:20rpx;color:#999">
  165. 无数据
  166. </view>
  167. </scroll-view>
  168. </view>
  169. </view>
  170. </view>
  171. <!-- 自定义站点选择器 -->
  172. <view class="picker-mask" :class="{show: showStationPicker}" @click="closeStationPicker">
  173. <view class="picker-content" @click.stop>
  174. <view class="picker-header" style="justify-content: center; position: relative;">
  175. <text class="picker-btn-cancel" style="position: absolute; left: 30rpx;" @click="closeStationPicker">取消</text>
  176. <text class="picker-title">选择服务站点</text>
  177. </view>
  178. <scroll-view scroll-y class="picker-list">
  179. <view
  180. class="station-item"
  181. v-for="(item, index) in stationList"
  182. :key="index"
  183. @click="selectStation(item)"
  184. >
  185. {{ item.name }}
  186. </view>
  187. </scroll-view>
  188. </view>
  189. </view>
  190. <!-- 底部协议与按钮 -->
  191. <view class="footer-actions">
  192. <view class="agreement-row">
  193. <view class="checkbox" :class="{checked: isAgreed}" @click="isAgreed = !isAgreed">
  194. <text v-if="isAgreed" class="check-mark">✓</text>
  195. </view>
  196. <text class="agree-text">我已阅读并同意 <text style="color:#2979ff" @click.stop="openPrivacy">《宠宝履约者说明》</text></text>
  197. </view>
  198. <view class="footer-btn-area">
  199. <button class="submit-btn" @click="goToAuth">下一步,实名认证</button>
  200. </view>
  201. </view>
  202. <!-- 自定义日期选择器 -->
  203. <view class="picker-mask" :class="{show: showPicker}" @click="closePicker">
  204. <view class="picker-content" @click.stop>
  205. <view class="picker-header">
  206. <text class="picker-btn-cancel" @click="closePicker">取消</text>
  207. <text class="picker-title">选择出生日期</text>
  208. <text class="picker-btn-confirm" @click="confirmPicker">确定</text>
  209. </view>
  210. <picker-view
  211. class="picker-view"
  212. indicator-style="height: 50px;"
  213. :value="pickerValue"
  214. @change="onPickerChange"
  215. >
  216. <picker-view-column>
  217. <view class="picker-item" v-for="(item,index) in years" :key="index">{{item}}年</view>
  218. </picker-view-column>
  219. <picker-view-column>
  220. <view class="picker-item" v-for="(item,index) in months" :key="index">{{item}}月</view>
  221. </picker-view-column>
  222. <picker-view-column>
  223. <view class="picker-item" v-for="(item,index) in days" :key="index">{{item}}日</view>
  224. </picker-view-column>
  225. </picker-view>
  226. </view>
  227. </view>
  228. <!-- 协议弹窗 -->
  229. <privacy-popup
  230. :visible="showPrivacy"
  231. :title="privacyTitle"
  232. :content="privacyContent"
  233. @close="showPrivacy = false"
  234. >
  235. </privacy-popup>
  236. </view>
  237. </template>
  238. <script>
  239. import logic from './logic.js';
  240. import PrivacyPopup from '@/components/privacy-popup/privacy-popup.vue';
  241. export default {
  242. ...logic,
  243. components: {
  244. PrivacyPopup
  245. }
  246. }
  247. </script>
  248. <style>
  249. @import './style.css';
  250. </style>