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

294 lines
6.3 KiB

fix(订单管理): 修复宠物档案跳转缺少订单ID的问题 修复订单详情页跳转宠物档案页面时未传递orderId参数的问题 ``` ```msg refactor(认证考试): 重构考试答案提交逻辑 将单个题目提交改为批量提交,优化考试流程: 1. 基础考试和培训考试都改为最后统一提交答案 2. 添加加载状态提示 3. 使用Promise.all处理并发请求 ``` ```msg fix(认证考试): 修复考试完成状态判断逻辑 修改answeBaseIsFinish和answeTrainIsFinish接口的返回判断逻辑,从检查code改为检查data字段 ``` ```msg feat(认证考试): 新增重新考试和成为伴宠师接口 1. 添加retakeExam和appletUsersTeacher接口 2. 在错误详情页添加重新考试功能 3. 在考试完成页添加成为伴宠师功能 ``` ```msg style(时间轴组件): 优化操作按钮布局 1. 添加按钮间距(gap) 2. 使用flex:1使按钮等宽 3. 根据状态显示不同按钮文本 4. 添加serviceBtn属性控制档案按钮显示 ``` ```msg refactor(订单弹窗): 重构服务档案弹窗组件 1. 使用timelineService组件替代原有实现 2. 简化数据结构处理 3. 添加状态判断逻辑 4. 优化弹窗标题和样式 ``` ```msg fix(表单验证): 添加认证考试结束页表单验证 1. 添加姓名、电话、地址的必填验证 2. 添加格式验证(电话格式、姓名格式) 3. 添加长度验证 4. 添加错误状态样式 5. 优化错误提示体验 ``` ```msg refactor(工作台): 重构伴宠师申请流程 1. 优化申请条件判断逻辑 2. 添加用户状态检查 3. 完善考试状态跳转逻辑 4. 统一使用store获取用户信息
2 weeks ago
fix(订单管理): 修复宠物档案跳转缺少订单ID的问题 修复订单详情页跳转宠物档案页面时未传递orderId参数的问题 ``` ```msg refactor(认证考试): 重构考试答案提交逻辑 将单个题目提交改为批量提交,优化考试流程: 1. 基础考试和培训考试都改为最后统一提交答案 2. 添加加载状态提示 3. 使用Promise.all处理并发请求 ``` ```msg fix(认证考试): 修复考试完成状态判断逻辑 修改answeBaseIsFinish和answeTrainIsFinish接口的返回判断逻辑,从检查code改为检查data字段 ``` ```msg feat(认证考试): 新增重新考试和成为伴宠师接口 1. 添加retakeExam和appletUsersTeacher接口 2. 在错误详情页添加重新考试功能 3. 在考试完成页添加成为伴宠师功能 ``` ```msg style(时间轴组件): 优化操作按钮布局 1. 添加按钮间距(gap) 2. 使用flex:1使按钮等宽 3. 根据状态显示不同按钮文本 4. 添加serviceBtn属性控制档案按钮显示 ``` ```msg refactor(订单弹窗): 重构服务档案弹窗组件 1. 使用timelineService组件替代原有实现 2. 简化数据结构处理 3. 添加状态判断逻辑 4. 优化弹窗标题和样式 ``` ```msg fix(表单验证): 添加认证考试结束页表单验证 1. 添加姓名、电话、地址的必填验证 2. 添加格式验证(电话格式、姓名格式) 3. 添加长度验证 4. 添加错误状态样式 5. 优化错误提示体验 ``` ```msg refactor(工作台): 重构伴宠师申请流程 1. 优化申请条件判断逻辑 2. 添加用户状态检查 3. 完善考试状态跳转逻辑 4. 统一使用store获取用户信息
2 weeks ago
fix(订单管理): 修复宠物档案跳转缺少订单ID的问题 修复订单详情页跳转宠物档案页面时未传递orderId参数的问题 ``` ```msg refactor(认证考试): 重构考试答案提交逻辑 将单个题目提交改为批量提交,优化考试流程: 1. 基础考试和培训考试都改为最后统一提交答案 2. 添加加载状态提示 3. 使用Promise.all处理并发请求 ``` ```msg fix(认证考试): 修复考试完成状态判断逻辑 修改answeBaseIsFinish和answeTrainIsFinish接口的返回判断逻辑,从检查code改为检查data字段 ``` ```msg feat(认证考试): 新增重新考试和成为伴宠师接口 1. 添加retakeExam和appletUsersTeacher接口 2. 在错误详情页添加重新考试功能 3. 在考试完成页添加成为伴宠师功能 ``` ```msg style(时间轴组件): 优化操作按钮布局 1. 添加按钮间距(gap) 2. 使用flex:1使按钮等宽 3. 根据状态显示不同按钮文本 4. 添加serviceBtn属性控制档案按钮显示 ``` ```msg refactor(订单弹窗): 重构服务档案弹窗组件 1. 使用timelineService组件替代原有实现 2. 简化数据结构处理 3. 添加状态判断逻辑 4. 优化弹窗标题和样式 ``` ```msg fix(表单验证): 添加认证考试结束页表单验证 1. 添加姓名、电话、地址的必填验证 2. 添加格式验证(电话格式、姓名格式) 3. 添加长度验证 4. 添加错误状态样式 5. 优化错误提示体验 ``` ```msg refactor(工作台): 重构伴宠师申请流程 1. 优化申请条件判断逻辑 2. 添加用户状态检查 3. 完善考试状态跳转逻辑 4. 统一使用store获取用户信息
2 weeks ago
fix(订单管理): 修复宠物档案跳转缺少订单ID的问题 修复订单详情页跳转宠物档案页面时未传递orderId参数的问题 ``` ```msg refactor(认证考试): 重构考试答案提交逻辑 将单个题目提交改为批量提交,优化考试流程: 1. 基础考试和培训考试都改为最后统一提交答案 2. 添加加载状态提示 3. 使用Promise.all处理并发请求 ``` ```msg fix(认证考试): 修复考试完成状态判断逻辑 修改answeBaseIsFinish和answeTrainIsFinish接口的返回判断逻辑,从检查code改为检查data字段 ``` ```msg feat(认证考试): 新增重新考试和成为伴宠师接口 1. 添加retakeExam和appletUsersTeacher接口 2. 在错误详情页添加重新考试功能 3. 在考试完成页添加成为伴宠师功能 ``` ```msg style(时间轴组件): 优化操作按钮布局 1. 添加按钮间距(gap) 2. 使用flex:1使按钮等宽 3. 根据状态显示不同按钮文本 4. 添加serviceBtn属性控制档案按钮显示 ``` ```msg refactor(订单弹窗): 重构服务档案弹窗组件 1. 使用timelineService组件替代原有实现 2. 简化数据结构处理 3. 添加状态判断逻辑 4. 优化弹窗标题和样式 ``` ```msg fix(表单验证): 添加认证考试结束页表单验证 1. 添加姓名、电话、地址的必填验证 2. 添加格式验证(电话格式、姓名格式) 3. 添加长度验证 4. 添加错误状态样式 5. 优化错误提示体验 ``` ```msg refactor(工作台): 重构伴宠师申请流程 1. 优化申请条件判断逻辑 2. 添加用户状态检查 3. 完善考试状态跳转逻辑 4. 统一使用store获取用户信息
2 weeks ago
fix(订单管理): 修复宠物档案跳转缺少订单ID的问题 修复订单详情页跳转宠物档案页面时未传递orderId参数的问题 ``` ```msg refactor(认证考试): 重构考试答案提交逻辑 将单个题目提交改为批量提交,优化考试流程: 1. 基础考试和培训考试都改为最后统一提交答案 2. 添加加载状态提示 3. 使用Promise.all处理并发请求 ``` ```msg fix(认证考试): 修复考试完成状态判断逻辑 修改answeBaseIsFinish和answeTrainIsFinish接口的返回判断逻辑,从检查code改为检查data字段 ``` ```msg feat(认证考试): 新增重新考试和成为伴宠师接口 1. 添加retakeExam和appletUsersTeacher接口 2. 在错误详情页添加重新考试功能 3. 在考试完成页添加成为伴宠师功能 ``` ```msg style(时间轴组件): 优化操作按钮布局 1. 添加按钮间距(gap) 2. 使用flex:1使按钮等宽 3. 根据状态显示不同按钮文本 4. 添加serviceBtn属性控制档案按钮显示 ``` ```msg refactor(订单弹窗): 重构服务档案弹窗组件 1. 使用timelineService组件替代原有实现 2. 简化数据结构处理 3. 添加状态判断逻辑 4. 优化弹窗标题和样式 ``` ```msg fix(表单验证): 添加认证考试结束页表单验证 1. 添加姓名、电话、地址的必填验证 2. 添加格式验证(电话格式、姓名格式) 3. 添加长度验证 4. 添加错误状态样式 5. 优化错误提示体验 ``` ```msg refactor(工作台): 重构伴宠师申请流程 1. 优化申请条件判断逻辑 2. 添加用户状态检查 3. 完善考试状态跳转逻辑 4. 统一使用store获取用户信息
2 weeks ago
  1. <template>
  2. <!-- <view>伴宠师认证</view> -->
  3. <view class="page">
  4. <view class="box">
  5. <view class="content bg-fff">
  6. <!-- 选择题部分 -->
  7. <view class="question-section" v-if="basicQuestions.length > 0 && !baseSuccess">
  8. <view class="section-title">选择题</view>
  9. <view class="question__view display" v-for="(question, index) in basicQuestions" :key="index">
  10. <view class="size-28 mb20 question">
  11. {{ `${question.title}` }}
  12. </view>
  13. <view class="size-28 option" v-for="(option, oIdx) in question.answerList"
  14. :key="`${index}-option-${oIdx}`"
  15. :class="[
  16. option.isTrue ? 'is-correct' : '',
  17. isOptionSelected(question, option.id) && !option.isTrue ? 'is-error' : ''
  18. ]">
  19. {{ option.title }}
  20. <view class="icon icon-correct" v-if="option.isTrue">
  21. <up-icon name="checkmark" color="#05C160" size="35rpx"></up-icon>
  22. </view>
  23. <view class="icon icon-error" v-if="isOptionSelected(question, option.id) && !option.isTrue">
  24. <up-icon name="close" color="#FF2A2A" size="35rpx"></up-icon>
  25. </view>
  26. </view>
  27. </view>
  28. </view>
  29. <!-- 培训题部分 -->
  30. <view class="question-section" v-if="trainQuestions.length > 0">
  31. <view class="section-title">培训题</view>
  32. <view class="question__view display" v-for="(question, index) in trainQuestions" :key="index">
  33. <view class="size-28 mb20 question">
  34. {{ `${question.title}` }}
  35. </view>
  36. <view class="textarea">
  37. <view class="answer-content">{{ question.userAppletAnswerTrain?.answer || '未作答' }}</view>
  38. <view class="highlight" v-if="question.answer">{{ question.answer }}</view>
  39. </view>
  40. </view>
  41. </view>
  42. <view class="question-section" v-if="detail.reason">
  43. <view class="section-title">驳回原因</view>
  44. <view class="question__view display" style="color: #f60;font-size: 28rpx;">
  45. {{ detail.reason }}
  46. </view>
  47. </view>
  48. </view>
  49. </view>
  50. <view class="footer-btn flex-colc">
  51. <view class="size-22 color-777 tips-rest" v-if="!baseSuccess">
  52. <!-- todo -->
  53. 剩余考试机会<text class="highlight">{{ restTimes - examNumber }}</text>
  54. </view>
  55. <view class="btn" @click="onClick">
  56. 重新考试
  57. </view>
  58. </view>
  59. </view>
  60. </template>
  61. <script setup>
  62. import { ref, computed, onMounted } from 'vue'
  63. import { onShow } from '@dcloudio/uni-app'
  64. import { getAnswerBuildData, retakeExam } from '@/api/examination'
  65. import { useStore } from 'vuex'
  66. import { isOptionSelected, isAnswerCorrect, isQuestionAnswered, isSuccessPrecision } from '@/utils/exam.js'
  67. const store = useStore()
  68. const questionList = ref([])
  69. const detail = ref({})
  70. const baseSuccess = ref(false)
  71. const configList = computed(() => {
  72. return store.getters.configList
  73. })
  74. const userInfo = computed(() => {
  75. return store.state.user.userInfo
  76. })
  77. const restTimes = ref(0)
  78. const examNumber = ref(0)
  79. // 选择题列表
  80. const basicQuestions = computed(() => {
  81. return questionList.value.filter(item => item.type === '基本')
  82. })
  83. // 培训题列表
  84. const trainQuestions = computed(() => {
  85. return questionList.value.filter(item => item.type === '培训' && isQuestionAnswered(item))
  86. })
  87. onMounted(() => {
  88. getExamData()
  89. })
  90. const getExamData = () => {
  91. getAnswerBuildData(userInfo.value.userId).then(res => {
  92. detail.value = res
  93. questionList.value = res.answerList
  94. examNumber.value = res.examNumber || 0
  95. baseSuccess.value = isSuccessPrecision(res.answerList)
  96. })
  97. }
  98. onShow(() => {
  99. restTimes.value = parseInt(configList.value.pet_work_num.paramValueText || 0)
  100. })
  101. const onClick = () => {
  102. retakeExam({
  103. userId: userInfo.value.userId,
  104. type : baseSuccess.value ? 1 : 0,//1清除培训考核的答案,0清除全部
  105. }).then(res => {
  106. if(baseSuccess.value){
  107. uni.reLaunch({
  108. url: "/otherPages/authentication/examination/baseCompleted"
  109. })
  110. }else{
  111. uni.reLaunch({
  112. url: "/otherPages/authentication/examination/start"
  113. })
  114. }
  115. })
  116. }
  117. </script>
  118. <style lang="scss" scoped>
  119. $bar-height: 163rpx;
  120. .page {
  121. padding-bottom: $bar-height;
  122. }
  123. .box {
  124. // background-image: linear-gradient(to bottom, #ffbf60, #f2f2f2);
  125. padding: 16rpx;
  126. .step {
  127. width: 720rpx;
  128. height: 32rpx;
  129. border-radius: 32rpx;
  130. background-color: #D9D9D9;
  131. .in {
  132. width: 50%;
  133. height: 32rpx;
  134. background-color: #ffbf60;
  135. border-radius: 32rpx;
  136. }
  137. }
  138. }
  139. .content {
  140. border-radius: 20rpx;
  141. padding: 15rpx 20rpx;
  142. .label {
  143. width: 86rpx;
  144. padding: 5rpx 15rpx;
  145. color: #fff;
  146. background-color: #FFBF60;
  147. justify-content: center;
  148. }
  149. }
  150. .group + .group {
  151. margin-top: 68rpx;
  152. }
  153. .level {
  154. display: flex;
  155. }
  156. .footer-btn {
  157. height: $bar-height;
  158. }
  159. .tips {
  160. &-rest {
  161. color: #707070;
  162. font-size: 22rpx;
  163. margin: 9rpx 0 13rpx 0;
  164. .highlight {
  165. color: #FF8DC6;
  166. }
  167. }
  168. }
  169. .question-section {
  170. margin-bottom: 40rpx;
  171. }
  172. .section-title {
  173. font-size: 32rpx;
  174. font-weight: bold;
  175. color: #333;
  176. margin: 30rpx 0;
  177. padding-left: 20rpx;
  178. border-left: 8rpx solid #FFBF60;
  179. }
  180. .question {
  181. color: #000000;
  182. }
  183. .option {
  184. background-color: #F3F3F3;
  185. color: #707070;
  186. line-height: 37rpx;
  187. padding: 23rpx;
  188. border-radius: 28rpx;
  189. position: relative;
  190. &+& {
  191. margin-top: 20rpx;
  192. }
  193. .icon {
  194. position: absolute;
  195. right: 45rpx;
  196. bottom: 23rpx;
  197. display: none;
  198. }
  199. &.is-correct {
  200. background-color: rgba($color: #05C160, $alpha: 0.08);
  201. color: #05C160;
  202. .icon-correct {
  203. display: block;
  204. }
  205. }
  206. &.is-error {
  207. background-color: rgba($color: #FFEBCE, $alpha: 0.36);
  208. color: #FF2A2A;
  209. .icon-error {
  210. display: block;
  211. }
  212. }
  213. }
  214. .textarea {
  215. background-color: #F3F3F3;
  216. padding: 23rpx;
  217. border-radius: 16rpx;
  218. margin-top: 20rpx;
  219. .answer-content {
  220. font-size: 28rpx;
  221. color: #333;
  222. line-height: 1.6;
  223. margin-bottom: 20rpx;
  224. }
  225. .highlight {
  226. color: #FF2A2A;
  227. font-size: 28rpx;
  228. line-height: 1.6;
  229. padding-top: 20rpx;
  230. border-top: 1px solid rgba(0, 0, 0, 0.1);
  231. }
  232. }
  233. .footer-btn {
  234. position: fixed;
  235. left: 0;
  236. right: 0;
  237. bottom: 0;
  238. height: $bar-height;
  239. background: #fff;
  240. box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
  241. }
  242. .btn {
  243. width: 600rpx;
  244. height: 80rpx;
  245. line-height: 80rpx;
  246. text-align: center;
  247. background: #FFBF60;
  248. color: #fff;
  249. border-radius: 40rpx;
  250. font-size: 32rpx;
  251. }
  252. </style>