mx-question-subjective.vue 3.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. <template>
  2. <view class="py-20 fx-col gap-20">
  3. <view v-if="!disabled" class="fx-row fx-bet-cen">
  4. <view class="fx-row">
  5. <!-- NOTE:uv-subsection必须有外部宽度才能正常工作 -->
  6. <mx-subsection v-model="current" :list="list" key-name="text" width="50vw" @change="handleTypeChange">
  7. <template #="{item,style}">
  8. <view class="flex flex-row items-center gap-5">
  9. <uv-icon :name="item.icon" :color="style.color"/>
  10. <text>{{ item.text }}</text>
  11. </view>
  12. </template>
  13. </mx-subsection>
  14. </view>
  15. <uv-tags icon="reload" type="error" plain text="重做" custom-style="height:28px" @click="handleRedo"/>
  16. </view>
  17. <uv-textarea v-if="current==0" :model-value="modelValue" :disabled="disabled" height="150" :count="!disabled"
  18. maxlength="500" :placeholder="disabled?'':'这里输入答案'"
  19. @update:modelValue="handleAnswerChange"/>
  20. <view v-else class="h-[169px] p-[10px] box-border mx-border rounded fx-col relative">
  21. <text v-if="imageLimit>1" class="absolute bottom-[2px] right-[5px] text-tips text-2xs">
  22. {{ attachments.length }}/{{ imageLimit }}
  23. </text>
  24. <view class="flex-1 grid gap-10" :class="`grid-cols-${imageLimit}`">
  25. <view v-for="(i, idx) in attachments">
  26. <uv-image :src="i" width="100%" height="auto" mode="widthFix"
  27. @click="previewImage(attachments, idx)"/>
  28. </view>
  29. <view v-if="allowImages&&!disabled" class="fx-col fx-cen-cen">
  30. <uv-icon name="plus" size="60" color="var(--light-color)" @click="handleAddImage"/>
  31. </view>
  32. </view>
  33. </view>
  34. </view>
  35. </template>
  36. <script setup>
  37. import {ref, onMounted, computed} from 'vue'
  38. import {createPropDefine} from "@/utils";
  39. import {empty} from "@/uni_modules/uv-ui-tools/libs/function/test";
  40. import {toast} from "@/uni_modules/uv-ui-tools/libs/function";
  41. import {useChooseImage} from "@/hooks/useChooseImage";
  42. const props = defineProps({
  43. modelValue: createPropDefine(''),
  44. attachments: createPropDefine([], [Array, String]),
  45. disabled: createPropDefine(false, Boolean)
  46. })
  47. const emits = defineEmits(['update:modelValue', 'update:attachments'])
  48. const current = ref(0)
  49. const imageLimit = ref(3)
  50. const list = [
  51. {icon: 'edit-pen', text: '手动答题'},
  52. {icon: 'camera', text: '拍照答题'}
  53. ]
  54. const {chooseImage, previewImage} = useChooseImage()
  55. const noImages = computed(() => empty(props.attachments))
  56. const allowImages = computed(() => imageLimit.value - props.attachments.length)
  57. const handleTypeChange = (index) => {
  58. if (index == 1 && noImages.value) handleAddImage()
  59. }
  60. const handleAddImage = () => {
  61. if (allowImages.value <= 0) return toast(`最多上传${imageLimit.value}张图片!`)
  62. chooseImage((result) => {
  63. const arr = []
  64. if (!empty(props.attachments)) arr.push(...props.attachments)
  65. handleAttachmentsChange(arr.concat(result.msg))
  66. }, 6, 1)
  67. }
  68. const handleAnswerChange = (val) => {
  69. emits('update:modelValue', val)
  70. emits('update:attachments', [])
  71. }
  72. const handleAttachmentsChange = (val) => {
  73. emits('update:modelValue', '')
  74. emits('update:attachments', val)
  75. }
  76. const handleRedo = () => {
  77. emits('update:modelValue', '')
  78. emits('update:attachments', [])
  79. }
  80. onMounted(() => {
  81. // 初始化时,根据当前答题情况选中
  82. if (!empty(props.attachments)) current.value = 1
  83. })
  84. </script>
  85. <style scoped>
  86. </style>