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

434 lines
8.0 KiB

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