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

186 lines
3.8 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获取用户信息
4 days ago
  1. <template>
  2. <view class="mt32 question__view" :class="[props.mode]">
  3. <view class="size-28 mb20 question">
  4. {{ props.data.title }}
  5. <!-- {{ `${props.index + 1}${props.data.title}` }} -->
  6. </view>
  7. <template v-if="props.mode === 'edit'">
  8. <template v-if="props.data.options?.length">
  9. <view class="size-28 option" v-for="(option, oIdx) in props.data.options"
  10. :key="`${props.index}-option-${oIdx}`" :class="[value === option.id ? 'is-selected' : '']"
  11. @click="onChange(option.id)">
  12. {{ option.title }}
  13. </view>
  14. </template>
  15. <template v-else>
  16. <view class="textarea">
  17. <textarea v-model="value" :placeholder="`请输入您的答案,不得低于${props.data.numberWords || 0}个字`" :rows="10"
  18. @blur="onChange($event.detail.value)" :maxlength="2000"></textarea>
  19. </view>
  20. </template>
  21. </template>
  22. <template v-else>
  23. <template v-if="props.data.options?.length">
  24. <view class="size-28 option" v-for="(option, oIdx) in props.data.options"
  25. :key="`${props.index}-option-${oIdx}`" :class="[
  26. props.data.answer === option.id ? 'is-correct' : '',
  27. props.data.value === option.id && props.data.answer !== option.id ? 'is-error' : '',
  28. ]">
  29. {{ option.title }}
  30. <view class="icon icon-correct">
  31. <up-icon name="checkmark" color="#05C160" size="35rpx"></up-icon>
  32. </view>
  33. <view class="icon icon-error">
  34. <up-icon name="close" color="#FF2A2A" size="35rpx"></up-icon>
  35. </view>
  36. </view>
  37. </template>
  38. <template v-else>
  39. <view class="textarea">
  40. <view>{{ props.data.value }}</view>
  41. <view class="highlight">{{ props.data.answer }}</view>
  42. </view>
  43. </template>
  44. </template>
  45. </view>
  46. </template>
  47. <script setup>
  48. import {
  49. computed,
  50. watch
  51. } from 'vue'
  52. import {
  53. addBaseAnswer,
  54. addTrainAnswer
  55. } from '@/api/examination'
  56. import {
  57. store
  58. } from '@/store'
  59. const userId = computed(() => {
  60. return store.state.user.userInfo.userId
  61. })
  62. const props = defineProps({
  63. index: {
  64. type: Number,
  65. default: null,
  66. },
  67. data: {
  68. type: Object,
  69. default () {
  70. return {}
  71. }
  72. },
  73. modelValue: {
  74. type: [String, Number],
  75. default: null,
  76. },
  77. mode: {
  78. type: String,
  79. default: 'edit', // edit | display
  80. },
  81. type: {
  82. type: String,
  83. default: null, // '基本' | '培训'
  84. }
  85. })
  86. const min = 700
  87. const emit = defineEmits(['update:modelValue'])
  88. const value = computed({
  89. set(val) {
  90. emit('update:modelValue', val)
  91. },
  92. get() {
  93. return props.modelValue
  94. }
  95. })
  96. const onChange = (val) => {
  97. value.value = val
  98. // const data = {
  99. // userId: userId.value,
  100. // questionId: props.data.id,
  101. // }
  102. // if (props.type === '基本') {
  103. // data.answerId = val
  104. // addBaseAnswer(data)
  105. // } else if (props.type === '培训') {
  106. // data.answer = val
  107. // addTrainAnswer(data)
  108. // }
  109. }
  110. </script>
  111. <style lang="scss" scoped>
  112. .question {
  113. color: #000000;
  114. }
  115. .option {
  116. background-color: #F3F3F3;
  117. color: #707070;
  118. line-height: 37rpx;
  119. padding: 23rpx;
  120. border-radius: 28rpx;
  121. position: relative;
  122. &+& {
  123. margin-top: 20rpx;
  124. }
  125. .icon {
  126. position: absolute;
  127. right: 45rpx;
  128. bottom: 23rpx;
  129. display: none;
  130. }
  131. }
  132. .textarea {
  133. background-color: #F3F3F3;
  134. padding: 23rpx;
  135. border-radius: 16rpx;
  136. .highlight {
  137. color: #FF2A2A;
  138. font-size: 28rpx;
  139. }
  140. }
  141. .question__view.edit {
  142. .option.is-selected {
  143. background-color: rgba($color: #FFBF60, $alpha: 0.22);
  144. color: #FFBF60;
  145. }
  146. }
  147. .question__view.display {
  148. .option {
  149. &.is-correct {
  150. background-color: rgba($color: #05C160, $alpha: 0.08);
  151. color: #05C160;
  152. .icon-correct {
  153. display: block;
  154. }
  155. }
  156. &.is-error {
  157. background-color: rgba($color: #FFEBCE, $alpha: 0.36);
  158. color: #FF2A2A;
  159. .icon-error {
  160. display: block;
  161. }
  162. }
  163. }
  164. }
  165. </style>