form.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  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="openStationPickerCascader">
  102. <view class="station-display" v-if="formData.station">
  103. <text class="area-tag" v-if="formData.areaPath">{{ formData.areaPath }}</text>
  104. <text class="station-name">{{ formData.station }}</text>
  105. </view>
  106. <text v-else style="color: #ccc">请选择所属站点</text>
  107. <!-- 灰色箭头 SVG -->
  108. <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">
  109. <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>
  110. </svg>
  111. </view>
  112. </view>
  113. </view>
  114. <!-- ... (Bottom content) ... -->
  115. <!-- 自定义日期选择器 (已存在) -->
  116. <!-- ... (Picker content) ... -->
  117. <!-- 自定义站点选择器 (级联版) -->
  118. <view class="picker-mask" :class="{show: showStationPickerCascader}" @click="closeStationPickerCascader">
  119. <view class="picker-content" @click.stop>
  120. <view class="picker-header">
  121. <text class="picker-btn-cancel" @click="closeStationPickerCascader">取消</text>
  122. <text class="picker-title">请选择所属站点</text>
  123. <text class="picker-btn-confirm" @click="closeStationPickerCascader">关闭</text>
  124. </view>
  125. <view class="picker-body">
  126. <!-- 左侧:垂直路径 -->
  127. <view class="timeline-area">
  128. <!-- 已选节点 -->
  129. <view
  130. class="timeline-item"
  131. v-for="(item, index) in selectedPathway"
  132. :key="index"
  133. @click="jumpToStep(index)"
  134. >
  135. <view class="timeline-dot"></view>
  136. <text>{{ item.name }}</text>
  137. </view>
  138. <!-- 当前正在选的提示 (如果还没选完) -->
  139. <view
  140. class="timeline-item active"
  141. v-if="selectStep === selectedPathway.length"
  142. >
  143. <view class="timeline-dot"></view>
  144. <text>请选择</text>
  145. </view>
  146. </view>
  147. <!-- 右侧:待选项列表 -->
  148. <scroll-view scroll-y class="list-area">
  149. <view
  150. class="list-item"
  151. v-for="(item, index) in currentList"
  152. :key="item.id"
  153. @click="selectStationItem(item)"
  154. >
  155. {{ item.name }}
  156. </view>
  157. <view v-if="currentList.length === 0" style="padding:20rpx;color:#999">
  158. 无数据
  159. </view>
  160. </scroll-view>
  161. </view>
  162. </view>
  163. </view>
  164. <!-- 底部协议与按钮 -->
  165. <view class="footer-actions">
  166. <view class="agreement-row">
  167. <view class="checkbox" :class="{checked: isAgreed}" @click="isAgreed = !isAgreed">
  168. <text v-if="isAgreed" class="check-mark">✓</text>
  169. </view>
  170. <text class="agree-text">我已阅读并同意 <text style="color:#2979ff" @click.stop="openPrivacy">《宠宝履约者说明》</text></text>
  171. </view>
  172. <view class="footer-btn-area">
  173. <button class="submit-btn" @click="goToAuth">下一步,实名认证</button>
  174. </view>
  175. </view>
  176. <!-- 自定义日期选择器 -->
  177. <view class="picker-mask" :class="{show: showPicker}" @click="closePicker">
  178. <view class="picker-content" @click.stop>
  179. <view class="picker-header">
  180. <text class="picker-btn-cancel" @click="closePicker">取消</text>
  181. <text class="picker-title">选择出生日期</text>
  182. <text class="picker-btn-confirm" @click="confirmPicker">确定</text>
  183. </view>
  184. <picker-view
  185. class="picker-view"
  186. indicator-style="height: 50px;"
  187. :value="pickerValue"
  188. @change="onPickerChange"
  189. >
  190. <picker-view-column>
  191. <view class="picker-item" v-for="(item,index) in years" :key="index">{{item}}年</view>
  192. </picker-view-column>
  193. <picker-view-column>
  194. <view class="picker-item" v-for="(item,index) in months" :key="index">{{item}}月</view>
  195. </picker-view-column>
  196. <picker-view-column>
  197. <view class="picker-item" v-for="(item,index) in days" :key="index">{{item}}日</view>
  198. </picker-view-column>
  199. </picker-view>
  200. </view>
  201. </view>
  202. <!-- 协议弹窗 公共组件 -->
  203. <agreement
  204. :visible="showPrivacy"
  205. :title="agreementTitle"
  206. :content="agreementContent"
  207. @close="showPrivacy = false"
  208. >
  209. </agreement>
  210. </view>
  211. </template>
  212. <script>// 使用脚本文件
  213. import logic from './logic.js';
  214. import Agreement from '@/components/agreement/index.vue';
  215. export default {
  216. ...logic,
  217. components: {
  218. Agreement
  219. }
  220. }
  221. </script>
  222. <style>
  223. @import './style.css';
  224. </style>