国外MOSE官网
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

453 lines
12 KiB

6 days ago
  1. <template>
  2. <view class="volunteer-apply-page">
  3. <!-- 头部背景图 -->
  4. <view class="header-section">
  5. <image src="../static/volunteer_bg@2x.png" class="bg-image" mode="aspectFit"></image>
  6. </view>
  7. <!-- 提示信息 -->
  8. <view class="tip-section">
  9. <uv-icon name="info-circle-fill" color="#1488DB" size="32"></uv-icon>
  10. <text class="tip-text">以下内容均为必填项请根据您的实际情况认真填写</text>
  11. </view>
  12. <!-- 表单内容 -->
  13. <view class="form-section">
  14. <uv-form ref="form" :model="formData" :rules="rules" labelPosition="left" labelWidth="120">
  15. <!-- 姓名 -->
  16. <uv-form-item label="姓名" prop="name" borderBottom>
  17. <uv-input
  18. v-model="formData.name"
  19. placeholder="请输入您的姓名"
  20. border="none"
  21. clearable
  22. ></uv-input>
  23. </uv-form-item>
  24. <!-- 手机号 -->
  25. <uv-form-item label="手机号" prop="phone" borderBottom>
  26. <uv-input
  27. v-model="formData.phone"
  28. placeholder="请输入您的手机号"
  29. border="none"
  30. clearable
  31. type="number"
  32. ></uv-input>
  33. </uv-form-item>
  34. <!-- 性别 -->
  35. <uv-form-item label="性别" prop="gender" borderBottom>
  36. <uv-input
  37. v-model="formData.genderText"
  38. placeholder="请选择"
  39. border="none"
  40. readonly
  41. @click="showGenderPicker = true"
  42. suffixIcon="arrow-right"
  43. ></uv-input>
  44. </uv-form-item>
  45. <!-- 所在地区 -->
  46. <uv-form-item label="所在地区" prop="region" borderBottom>
  47. <uv-input
  48. v-model="formData.regionText"
  49. placeholder="请选择"
  50. border="none"
  51. readonly
  52. @click="showRegionPicker = true"
  53. suffixIcon="arrow-right"
  54. ></uv-input>
  55. </uv-form-item>
  56. <!-- 详细地址 -->
  57. <uv-form-item label="详细地址" prop="address" borderBottom>
  58. <uv-input
  59. v-model="formData.address"
  60. placeholder="请输入详细地址"
  61. border="none"
  62. clearable
  63. ></uv-input>
  64. </uv-form-item>
  65. <!-- 职业类型 -->
  66. <uv-form-item label="职业类型" prop="profession" borderBottom>
  67. <uv-input
  68. v-model="formData.professionText"
  69. placeholder="请选择"
  70. border="none"
  71. readonly
  72. @click="showProfessionPicker = true"
  73. suffixIcon="arrow-right"
  74. ></uv-input>
  75. </uv-form-item>
  76. <!-- 最高学历 -->
  77. <uv-form-item label="最高学历" prop="education" borderBottom>
  78. <uv-input
  79. v-model="formData.educationText"
  80. placeholder="请选择"
  81. border="none"
  82. readonly
  83. @click="showEducationPicker = true"
  84. suffixIcon="arrow-right"
  85. ></uv-input>
  86. </uv-form-item>
  87. <!-- 技能特长 -->
  88. <uv-form-item label="技能特长" prop="skills">
  89. <uv-textarea
  90. v-model="formData.skills"
  91. placeholder="请输入您的技能特长"
  92. border="none"
  93. :maxlength="200"
  94. count
  95. height="120"
  96. ></uv-textarea>
  97. </uv-form-item>
  98. </uv-form>
  99. <!-- 紧急联系人信息 -->
  100. <view class="emergency-section">
  101. <view class="section-title">紧急联系人信息</view>
  102. <uv-form ref="emergencyForm" :model="emergencyData" labelPosition="left" labelWidth="120">
  103. <!-- 联系人姓名 -->
  104. <uv-form-item label="姓名" prop="name" borderBottom>
  105. <uv-input
  106. v-model="emergencyData.name"
  107. placeholder="请输入您的紧急联系人姓名"
  108. border="none"
  109. clearable
  110. ></uv-input>
  111. </uv-form-item>
  112. <!-- 联系人手机号 -->
  113. <uv-form-item label="手机号" prop="phone" borderBottom>
  114. <uv-input
  115. v-model="emergencyData.phone"
  116. placeholder="请输入您的紧急联系人手机号"
  117. border="none"
  118. clearable
  119. type="number"
  120. ></uv-input>
  121. </uv-form-item>
  122. </uv-form>
  123. </view>
  124. </view>
  125. <!-- 提交按钮 -->
  126. <view class="submit-section">
  127. <!-- 圆角的 -->
  128. <uv-button
  129. type="primary"
  130. shape="circle"
  131. size="large"
  132. :loading="submitting"
  133. @click="submitApplication"
  134. >
  135. 提交申请
  136. </uv-button>
  137. </view>
  138. <!-- 性别选择器 -->
  139. <uv-picker
  140. ref="genderPicker"
  141. v-model="showGenderPicker"
  142. :columns="genderOptions"
  143. @confirm="onGenderConfirm"
  144. @cancel="showGenderPicker = false"
  145. ></uv-picker>
  146. <!-- 地区选择器 -->
  147. <uv-picker
  148. ref="regionPicker"
  149. v-model="showRegionPicker"
  150. :columns="regionOptions"
  151. @confirm="onRegionConfirm"
  152. @cancel="showRegionPicker = false"
  153. ></uv-picker>
  154. <!-- 职业选择器 -->
  155. <uv-picker
  156. ref="professionPicker"
  157. v-model="showProfessionPicker"
  158. :columns="professionOptions"
  159. @confirm="onProfessionConfirm"
  160. @cancel="showProfessionPicker = false"
  161. ></uv-picker>
  162. <!-- 学历选择器 -->
  163. <uv-picker
  164. ref="educationPicker"
  165. v-model="showEducationPicker"
  166. :columns="educationOptions"
  167. @confirm="onEducationConfirm"
  168. @cancel="showEducationPicker = false"
  169. ></uv-picker>
  170. </view>
  171. </template>
  172. <script>
  173. export default {
  174. name: 'VolunteerApply',
  175. data() {
  176. return {
  177. submitting: false,
  178. showGenderPicker: false,
  179. showRegionPicker: false,
  180. showProfessionPicker: false,
  181. showEducationPicker: false,
  182. formData: {
  183. name: '',
  184. phone: '',
  185. gender: '',
  186. genderText: '',
  187. region: '',
  188. regionText: '',
  189. address: '',
  190. profession: '',
  191. professionText: '',
  192. education: '',
  193. educationText: '',
  194. skills: ''
  195. },
  196. emergencyData: {
  197. name: '',
  198. phone: ''
  199. },
  200. rules: {
  201. name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
  202. phone: [
  203. { required: true, message: '请输入手机号', trigger: 'blur' },
  204. { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' }
  205. ],
  206. gender: [{ required: true, message: '请选择性别', trigger: 'change' }],
  207. region: [{ required: true, message: '请选择所在地区', trigger: 'change' }],
  208. address: [{ required: true, message: '请输入详细地址', trigger: 'blur' }],
  209. profession: [{ required: true, message: '请选择职业类型', trigger: 'change' }],
  210. education: [{ required: true, message: '请选择最高学历', trigger: 'change' }]
  211. },
  212. genderOptions: [['男', '女']],
  213. regionOptions: [[
  214. '北京市', '上海市', '广州市', '深圳市', '杭州市', '南京市',
  215. '武汉市', '成都市', '西安市', '长沙市', '湖南省长沙市区'
  216. ]],
  217. professionOptions: [[
  218. '学生', '教师', '医生', '工程师', '设计师', '销售',
  219. '服务员', '公务员', '自由职业', '专业技术人员', '其他'
  220. ]],
  221. educationOptions: [[
  222. '高中及以下', '大专', '本科', '硕士', '博士'
  223. ]]
  224. }
  225. },
  226. onLoad(options) {
  227. // 如果是编辑模式,加载已有数据
  228. if (options.edit && options.data) {
  229. this.loadExistingData(JSON.parse(decodeURIComponent(options.data)));
  230. }
  231. },
  232. methods: {
  233. // 加载已有数据(编辑模式)
  234. loadExistingData(data) {
  235. this.formData = {
  236. name: data.name || '李双欢',
  237. phone: data.phone || '15478451233',
  238. gender: data.gender || '男',
  239. genderText: data.gender || '男',
  240. region: data.region || '湖南省长沙市区',
  241. regionText: data.region || '湖南省长沙市区',
  242. address: data.address || '阳光小区45栋二单元1203',
  243. profession: data.profession || '专业技术人员',
  244. professionText: data.profession || '专业技术人员',
  245. education: data.education || '本科',
  246. educationText: data.education || '本科',
  247. skills: data.skills || '计算机、跑步'
  248. };
  249. this.emergencyData = {
  250. name: data.emergencyName || '李四',
  251. phone: data.emergencyPhone || '14563236320'
  252. };
  253. },
  254. // 性别选择确认
  255. onGenderConfirm(value) {
  256. this.formData.gender = value[0];
  257. this.formData.genderText = value[0];
  258. this.showGenderPicker = false;
  259. },
  260. // 地区选择确认
  261. onRegionConfirm(value) {
  262. this.formData.region = value[0];
  263. this.formData.regionText = value[0];
  264. this.showRegionPicker = false;
  265. },
  266. // 职业选择确认
  267. onProfessionConfirm(value) {
  268. this.formData.profession = value[0];
  269. this.formData.professionText = value[0];
  270. this.showProfessionPicker = false;
  271. },
  272. // 学历选择确认
  273. onEducationConfirm(value) {
  274. this.formData.education = value[0];
  275. this.formData.educationText = value[0];
  276. this.showEducationPicker = false;
  277. },
  278. // 提交申请
  279. async submitApplication() {
  280. try {
  281. // 验证主表单
  282. const valid = await this.$refs.form.validate();
  283. if (!valid) return;
  284. // 验证紧急联系人信息
  285. if (!this.emergencyData.name || !this.emergencyData.phone) {
  286. uni.showToast({
  287. title: '请填写紧急联系人信息',
  288. icon: 'none'
  289. });
  290. return;
  291. }
  292. this.submitting = true;
  293. // 模拟提交
  294. await this.submitVolunteerApplication();
  295. uni.showToast({
  296. title: '申请提交成功',
  297. icon: 'success'
  298. });
  299. setTimeout(() => {
  300. uni.navigateBack();
  301. }, 1500);
  302. } catch (error) {
  303. console.error('提交失败:', error);
  304. uni.showToast({
  305. title: '提交失败,请重试',
  306. icon: 'none'
  307. });
  308. } finally {
  309. this.submitting = false;
  310. }
  311. },
  312. // 提交志愿者申请API
  313. async submitVolunteerApplication() {
  314. // 模拟API调用
  315. return new Promise((resolve) => {
  316. setTimeout(() => {
  317. console.log('志愿者申请数据:', {
  318. ...this.formData,
  319. emergency: this.emergencyData
  320. });
  321. resolve();
  322. }, 1000);
  323. });
  324. }
  325. }
  326. }
  327. </script>
  328. <style lang="scss" scoped>
  329. // @import '@/uni.scss';
  330. .volunteer-apply-page {
  331. min-height: 100vh;
  332. background-color: #f5f5f5;
  333. }
  334. .header-section {
  335. position: relative;
  336. width: 96%;
  337. height: 290rpx;
  338. margin: 25rpx auto;
  339. .bg-image {
  340. width: 100%;
  341. height: 100%;
  342. }
  343. }
  344. .tip-section {
  345. display: flex;
  346. align-items: center;
  347. padding: 30rpx;
  348. background-color: #fff;
  349. margin: 20rpx 30rpx;
  350. border-radius: 16rpx;
  351. box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
  352. .tip-text {
  353. margin-left: 16rpx;
  354. font-size: 28rpx;
  355. color: #666;
  356. line-height: 1.5;
  357. }
  358. }
  359. .form-section {
  360. background-color: #fff;
  361. margin: 20rpx 30rpx;
  362. border-radius: 16rpx;
  363. padding: 40rpx 30rpx;
  364. box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
  365. }
  366. .emergency-section {
  367. margin-top: 40rpx;
  368. padding-top: 40rpx;
  369. border-top: 1rpx solid #f0f0f0;
  370. .section-title {
  371. font-size: 32rpx;
  372. font-weight: bold;
  373. color: #333;
  374. margin-bottom: 30rpx;
  375. }
  376. }
  377. .submit-section {
  378. padding: 40rpx 30rpx;
  379. padding-bottom: 60rpx;
  380. }
  381. // 覆盖uvUI样式
  382. :deep(.uv-form-item__body__right__content__input) {
  383. font-size: 28rpx !important;
  384. }
  385. :deep(.uv-form-item__body__left__text) {
  386. font-size: 28rpx !important;
  387. color: #333 !important;
  388. }
  389. :deep(.uv-input__content__field-wrapper__field) {
  390. font-size: 28rpx !important;
  391. }
  392. :deep(.uv-textarea__content__field) {
  393. font-size: 28rpx !important;
  394. }
  395. </style>