index.vue 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. <script lang="ts" setup>
  2. import { addQuestionReportData, pageQuestionReportData } from '@/api/questionReqort'
  3. import { AddQuestionReportDataReq, QuestionListRes } from '@/api/questionReqort/types'
  4. import { ref } from 'vue'
  5. import GridAddress from '@/components/address/gridAddress/index.vue'
  6. import { showNotify } from 'vant';
  7. const active = ref(0)
  8. const formData = ref<AddQuestionReportDataReq & { location?: string }>({})
  9. const range = ref([])
  10. const rules = ref({
  11. type: [{ required: true, message: '请选择问题类型' }],
  12. title: [{ required: true, message: '请输入问题标题' }],
  13. content: [{ required: true, message: '请输入问题内容' }],
  14. location: [{ required: true, message: '请输入问题所在地' }],
  15. })
  16. /** 上报问题 */
  17. const addressList = ref([])
  18. const handleAddressFinish = (value) => {
  19. formData.value.addrName = value.selectedOptions[value.tabIndex].areaName
  20. addressList.value = value
  21. }
  22. const submit = async () => {
  23. if (!addressList.value || addressList.value.length === 0) {
  24. showNotify('请选择问题所在地')
  25. return
  26. }
  27. const { data } = await addQuestionReportData({
  28. ...formData.value,
  29. streetCode: addressList.value.selectedOptions[1] ? addressList.value.selectedOptions[1].areaCode : '',
  30. streetName: addressList.value.selectedOptions[1] ? addressList.value.selectedOptions[1].areaName : '',
  31. communityCode: addressList.value.selectedOptions[2] ? addressList.value.selectedOptions[2].areaCode : '',
  32. communityName: addressList.value.selectedOptions[2] ? addressList.value.selectedOptions[2].areaName : '',
  33. grid: addressList.value.selectedOptions[3] ? addressList.value.selectedOptions[3].areaCode : '',
  34. gridName: addressList.value.selectedOptions[3] ? addressList.value.selectedOptions[3].areaName : '',
  35. })
  36. if (data) {
  37. uni.showToast({
  38. title: '上报成功',
  39. icon: 'success',
  40. duration: 1000,
  41. })
  42. formData.value = {}
  43. }
  44. }
  45. /**
  46. * 已上报问题
  47. */
  48. const list = ref<QuestionListRes[]>([])
  49. const pageInfo = ref({
  50. pageNumber: 1,
  51. pageSize: 10,
  52. })
  53. const questList = async () => {
  54. const { data } = await pageQuestionReportData({
  55. pageNumber: pageInfo.value.pageNumber,
  56. pageSize: pageInfo.value.pageSize,
  57. })
  58. list.value = list.value.concat(data.records)
  59. pageInfo.value.pageNumber++
  60. finished.value = data.records.length < pageInfo.value.pageSize
  61. loading.value = false
  62. if (data.records.length === 0 || !data.records) {
  63. finished.value = true
  64. }
  65. }
  66. const loading = ref(false)
  67. const finished = ref(false)
  68. /** 跳转问题详情 */
  69. const handleGoDetail = (item: QuestionListRes) => {
  70. uni.navigateTo({
  71. url: `/subPages/pages/reportProblems/detail?id=${item.uuid}`,
  72. })
  73. }
  74. const areaShow = ref(false)
  75. const hanleSelectArea = () => {
  76. areaShow.value = true
  77. }
  78. </script>
  79. <template>
  80. <van-tabs v-model:active="active" type="card" class="top-tabs">
  81. <van-tab title="上报问题">
  82. <view class="tab-container">
  83. <uni-forms :modelValue="formData" :rules="rules" label-align="right" label-width="80">
  84. <uni-forms-item label="问题类型" required name="questionType">
  85. <uni-data-select v-model="formData.questionType" :localdata="range"></uni-data-select>
  86. </uni-forms-item>
  87. <!-- 问题标题 -->
  88. <uni-forms-item label="问题标题" required name="questionTitle">
  89. <uni-easyinput v-model="formData.questionTitle" placeholder="请输入问题标题"></uni-easyinput>
  90. </uni-forms-item>
  91. <!-- 问题内容 -->
  92. <uni-forms-item label="问题内容" required name="questionContent">
  93. <uni-easyinput v-model="formData.questionContent" type="textarea" placeholder="请输入问题内容"></uni-easyinput>
  94. </uni-forms-item>
  95. <!-- 问题所在地 -->
  96. <uni-forms-item label="问题所在地" required name="addrName">
  97. <uni-easyinput v-model="formData.addrName" placeholder="请输入问题所在地" @focus="hanleSelectArea"></uni-easyinput>
  98. <GridAddress v-model="areaShow" @finish="handleAddressFinish"></GridAddress>
  99. </uni-forms-item>
  100. </uni-forms>
  101. <van-button class="w-full mb-3" type="primary" @click="submit">提交</van-button>
  102. </view>
  103. </van-tab>
  104. <van-tab title="已上报问题">
  105. <view class="tab-container">
  106. <van-list v-model:loading="loading" :finished="finished" finished-text="没有更多了" @load="questList">
  107. <view v-for="item in list" :key="item.uuid" class="list-item-style">
  108. <view class="top">
  109. <view class="title">{{ item.questionTitle }}</view>
  110. <van-button plain hairline size="mini" type="primary" @click="handleGoDetail(item)">查看详情</van-button>
  111. </view>
  112. <view>定位:{{ item.addrName }}</view>
  113. <view class="flex gap-3">
  114. <view class="type">问题类型</view>
  115. <van-tag color="#CFFECE" text-color="black">{{ item.questionType }}</van-tag>
  116. </view>
  117. </view>
  118. </van-list>
  119. </view>
  120. </van-tab>
  121. </van-tabs>
  122. </template>
  123. <style lang="scss" scoped>
  124. .top-tabs {
  125. :deep(.van-tabs__nav) {
  126. margin: 0;
  127. }
  128. }
  129. .tab-container {
  130. padding: 20px;
  131. padding-bottom: 30px;
  132. min-height: calc(100vh - var(--van-tabs-card-height));
  133. box-sizing: border-box;
  134. display: flex;
  135. flex-direction: column;
  136. > uni-view:first-child {
  137. flex: 1;
  138. }
  139. }
  140. .list-item-style {
  141. padding: 20px;
  142. margin-bottom: 10px;
  143. background-color: white;
  144. > view {
  145. margin-bottom: 10px;
  146. }
  147. .top {
  148. display: flex;
  149. align-items: center;
  150. .title {
  151. font-size: 20px;
  152. font-weight: bold;
  153. flex: 1;
  154. }
  155. .type {
  156. margin-right: 10px;
  157. }
  158. }
  159. }
  160. </style>