猫妈狗爸伴宠师小程序前端代码
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.

430 lines
8.0 KiB

10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
  1. <template>
  2. <view class="containers po-r">
  3. <image src="" mode="" class="mainBg"></image>
  4. <view class="w-100 po-a content">
  5. <stepProgress :step="1"></stepProgress>
  6. <view class="bg-fff mt22 form ">
  7. <view class="title fw700 size-30 flex-rowl">
  8. 基本信息
  9. </view>
  10. <dForm ref="formRef" :list="state.list" labelWidth="220rpx" :isFooter="false" @input="onFormInput"></dForm>
  11. </view>
  12. <view class="license__view" v-if="form.isHave">
  13. <view class="license">
  14. <up-checkbox-group
  15. v-model="licenseData.selected"
  16. shape="circle"
  17. activeColor="#FFBF60"
  18. labelColor="#000000"
  19. labelSize="26rpx"
  20. >
  21. <view class="license-options">
  22. <up-checkbox
  23. v-for="item in licenseOptions"
  24. :key="`license-${item.id}`"
  25. :label="item.title"
  26. :name="item.id"
  27. >
  28. </up-checkbox>
  29. </view>
  30. </up-checkbox-group>
  31. <view class="tips">
  32. {{ configList.pet_news.paramValueText }}
  33. </view>
  34. <up-upload
  35. :fileList="licenseData.fileList"
  36. @afterRead="afterRead"
  37. @delete="deletePic"
  38. multiple
  39. >
  40. <image src="../static/list/icon-upload.png" style="width: 144rpx;height: 144rpx;"></image>
  41. </up-upload>
  42. </view>
  43. </view>
  44. <view class="bg-fff mt22 form bt120">
  45. <view class="title fw700 size-30 flex-rowl">
  46. 个人宠物类型
  47. </view>
  48. <view class="flex-between wrap mt32">
  49. <view class="type" v-for="item in petTypeOptions" :key="`petType-${item.id}`">
  50. <image :src="item.imageNo" mode="widthFix" @click="onSelectPetType(item.id)"></image>
  51. <template v-if="petType === item.id">
  52. <image class="active" :src="item.image" mode="widthFix"></image>
  53. <view class="active-icon">
  54. <up-icon name="checkmark-circle" color="#FFBF60" size="32rpx"></up-icon>
  55. </view>
  56. </template>
  57. </view>
  58. </view>
  59. </view>
  60. <view class="footer-btn" @click="toNext">
  61. <view class="btn">
  62. 下一步
  63. </view>
  64. </view>
  65. </view>
  66. </view>
  67. </template>
  68. <script setup>
  69. import { ref, reactive, computed } from "vue";
  70. import { useStore } from 'vuex'
  71. import { onLoad } from '@dcloudio/uni-app'
  72. import { ossUpload } from '@/utils/oss-upload/oss/index.js'
  73. import { getLicenseList } from '@/api/examination'
  74. import { insertUser, udpateUser, getUserOne } from '@/api/userTeacher'
  75. import dForm from "@/components/dForm/index.vue"
  76. import stepProgress from '../components/stepProgress.vue';
  77. const store = useStore()
  78. const configList = computed(() => {
  79. return store.getters.configList
  80. })
  81. const userId = computed(() => {
  82. return store.state.user.userInfo.userId
  83. })
  84. const id = ref(null)
  85. const state = reactive({
  86. list: [{
  87. type: "input",
  88. label: "姓名",
  89. key: "name",
  90. placeholder: "请输入您的真实姓名",
  91. },
  92. {
  93. type: "input",
  94. label: "身份证号",
  95. key: "idCard",
  96. placeholder: "请输入您的真实身份证号",
  97. },
  98. {
  99. type: "radio",
  100. label: "性别",
  101. key: "sex",
  102. options: [{
  103. name: "男",
  104. value: 0,
  105. },
  106. {
  107. name: "女",
  108. value: 1,
  109. }
  110. ]
  111. },
  112. {
  113. type: "input",
  114. label: "年龄",
  115. key: "age",
  116. placeholder: "请输入您的年龄",
  117. },
  118. {
  119. type: "input",
  120. label: "手机号",
  121. key: "phone",
  122. placeholder: "请输入您的手机号",
  123. },
  124. {
  125. type: "input",
  126. label: "养宠经验",
  127. key: "experience",
  128. placeholder: "请输入您的养宠年限",
  129. unit: "年"
  130. },
  131. {
  132. type: "radio",
  133. label: "是否有专业执照",
  134. key: "isHave",
  135. placeholder: "请选择",
  136. options: [{
  137. name: "是",
  138. value: 1,
  139. }, {
  140. name: "没有",
  141. value: 0,
  142. }]
  143. },
  144. ]
  145. })
  146. const formRef = ref()
  147. const form = ref({})
  148. const onFormInput = (e) => {
  149. form.value = e
  150. }
  151. const fetchUserInfo = async () => {
  152. try {
  153. const { userTelephone } = store.state.user.userInfo
  154. const data = await getUserOne(userId.value)
  155. if (data) {
  156. const {
  157. id: _id,
  158. status,
  159. name,
  160. idCard,
  161. sex,
  162. age,
  163. phone,
  164. experience,
  165. isHave,
  166. license,
  167. images,
  168. petType: _petType,
  169. } = data
  170. if ([1,2].includes(status)) { // status: 0-审核中 1-通过 2-不通过
  171. uni.navigateTo({
  172. url: `/otherPages/authentication/examination/trainCompleted/index?status=${status}`
  173. })
  174. return
  175. }
  176. id.value = _id
  177. formRef.value.setData({
  178. name,
  179. idCard,
  180. sex,
  181. age,
  182. phone: phone || userTelephone,
  183. experience,
  184. isHave,
  185. })
  186. licenseData.selected = license?.split?.(';').map(str => parseInt(str)) || []
  187. licenseData.fileList = images?.split?.(';').map(url => ({ url })) || []
  188. petType.value = _petType
  189. } else {
  190. formRef.value.setData({
  191. phone: userTelephone,
  192. })
  193. }
  194. store.dispatch('fetchPetTypeOptions')
  195. fetchLicenseOptions()
  196. } catch (err) {
  197. console.log('--err', err)
  198. }
  199. }
  200. const licenseData = reactive({
  201. selected: [],
  202. fileList: []
  203. })
  204. const licenseOptions = ref([])
  205. const fetchLicenseOptions = async () => {
  206. try {
  207. licenseOptions.value = await getLicenseList()
  208. } catch (err) {
  209. }
  210. }
  211. const afterRead = (event) => {
  212. event.file.forEach(n => {
  213. ossUpload(n.url)
  214. .then(url => {
  215. licenseData.fileList.push({
  216. url
  217. })
  218. })
  219. })
  220. };
  221. const deletePic = (event) => {
  222. licenseData.fileList.splice(event.index, 1);
  223. };
  224. const petType = ref()
  225. const petTypeOptions = computed(() => {
  226. return store.getters.petTypeOptions
  227. })
  228. const onSelectPetType = (type) => {
  229. petType.value = type
  230. }
  231. const toNext = async () => {
  232. try {
  233. const {
  234. name,
  235. idCard,
  236. sex,
  237. age,
  238. phone,
  239. experience,
  240. isHave,
  241. } = form.value
  242. const data = {
  243. userId: userId.value,
  244. name,
  245. idCard,
  246. sex,
  247. age,
  248. phone,
  249. experience,
  250. isHave,
  251. petType: petType.value,
  252. }
  253. if (isHave) {
  254. const { selected, fileList } = licenseData
  255. data.license = selected.join(';')
  256. data.images = fileList.map(item => item.url).join(';')
  257. }
  258. if (id.value) {
  259. data.id = id.value
  260. await udpateUser(data)
  261. } else {
  262. await insertUser(data)
  263. }
  264. uni.navigateTo({
  265. url: `/otherPages/authentication/examination/start?petType=${petType.value}`
  266. })
  267. } catch (err) {
  268. }
  269. }
  270. onLoad(() => {
  271. fetchUserInfo()
  272. store.dispatch('fetchPetTypeOptions')
  273. })
  274. </script>
  275. <style lang="scss" scoped>
  276. .bt120 {
  277. margin-bottom: 120rpx;
  278. width: 716rpx;
  279. box-sizing: border-box;
  280. }
  281. .footer-btn {
  282. width: 100vw;
  283. height: 144rpx;
  284. background-color: #fff;
  285. display: flex;
  286. justify-content: center;
  287. position: fixed;
  288. bottom: 0;
  289. left: 0;
  290. align-items: center;
  291. .btn {
  292. font-size: 30rpx;
  293. color: #fff;
  294. display: flex;
  295. justify-content: center;
  296. align-items: center;
  297. width: 574rpx;
  298. height: 94rpx;
  299. border-radius: 94rpx;
  300. background-color: #FFBF60;
  301. }
  302. }
  303. .type {
  304. width: 190rpx;
  305. margin-bottom: 74rpx;
  306. position: relative;
  307. image {
  308. width: 100%;
  309. }
  310. .active {
  311. position: absolute;
  312. top: 0;
  313. left: 0;
  314. &-icon {
  315. position: absolute;
  316. top: 14rpx;
  317. right: 18rpx;
  318. }
  319. }
  320. }
  321. .form {
  322. padding: 40rpx 32rpx;
  323. box-sizing: border-box;
  324. width: 716rpx;
  325. }
  326. .title {
  327. &::before {
  328. content: "";
  329. display: block;
  330. width: 9rpx;
  331. height: 33rpx;
  332. background-color: #FFBF60;
  333. margin-right: 7rpx;
  334. }
  335. }
  336. .mb6 {
  337. margin-bottom: 6rpx;
  338. }
  339. .containers {
  340. .mainBg {
  341. width: 100vw;
  342. height: 442rpx;
  343. background-image: linear-gradient(to bottom, #FFBF60, #f5f5f5);
  344. }
  345. .content {
  346. top: 0;
  347. left: 0;
  348. padding: 16rpx;
  349. }
  350. }
  351. .license__view {
  352. width: 716rpx;
  353. padding-bottom: 40rpx;
  354. box-sizing: border-box;
  355. background-color: #FFFFFF;
  356. .license {
  357. width: 100%;
  358. padding: 13rpx 16rpx;
  359. box-sizing: border-box;
  360. background-color: #FFFCF1;
  361. &-options {
  362. display: grid;
  363. grid-template-columns: repeat(2, 1fr);
  364. }
  365. }
  366. .tips {
  367. margin: 22rpx 0 24rpx 0;
  368. color: #FFBF60;
  369. font-size: 22rpx;
  370. width: 100%;
  371. word-break: break-all;
  372. }
  373. }
  374. </style>