add.vue 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. <template>
  2. <view>
  3. <uv-popup ref="popup_ref" mode="bottom" custom-style="min-height: 800rpx;padding:15rpx;overflow-y:scroll;" round="10" closeable safeAreaInsetTop
  4. @close="close">
  5. <view class="w100 flex-center">纠错上报</view>
  6. <uv-form
  7. labelPosition="top"
  8. labelWidth="100"
  9. :model="state.ruleForm"
  10. :rules="state.rules"
  11. ref="feedback_form_ref">
  12. <uv-form-item label="概要描述" prop="title">
  13. <uv-input required="true" type="text" :readonly="state.mode==='detail'" v-model="state.ruleForm.title" placeholder="请填写概要描述" clearable count
  14. maxlength="100">
  15. </uv-input>
  16. </uv-form-item>
  17. <uv-form-item label="问题类别" prop="type" @click="handleShowAction">
  18. <uv-input v-model="state.ruleForm.typeName" disabled disabledColor="#ffffff" placeholder="请选择" border="none">
  19. </uv-input>
  20. <template v-slot:right>
  21. <uv-icon name="arrow-right"></uv-icon>
  22. </template>
  23. </uv-form-item>
  24. <uv-form-item label="详细描述" prop="content">
  25. <uv-textarea autoHeight required="true" height="50" :disabled="state.mode==='detail'" v-model="state.ruleForm.content" placeholder="请填写详细描述信息" count
  26. maxlength="300">
  27. </uv-textarea>
  28. </uv-form-item>
  29. <uv-form-item label="问题截图" prop="attachList">
  30. <uv-upload
  31. :fileList="state.attachList"
  32. name="1"
  33. multiple
  34. :maxCount="9"
  35. @delete="handleDelete"
  36. @afterRead="handleUpload"
  37. :previewFullImage="true"
  38. ></uv-upload>
  39. </uv-form-item>
  40. <uv-form-item label="平台答复" prop="content" v-if="state.mode==='detail'">
  41. <uv-textarea readonly height="50" v-model="state.ruleForm.replyContent" placeholder="请等待平台回复">
  42. </uv-textarea>
  43. </uv-form-item>
  44. <uv-form-item label="答复时间" prop="content" v-if="state.mode==='detail'">
  45. <uv-text>{{ fmtDateTime(state.ruleForm.replyTime) }}</uv-text>
  46. </uv-form-item>
  47. </uv-form>
  48. <view class="w100 text-right">
  49. <!-- <uv-text type="info" @click="close" :customStyle="{'width':'120px','margin-left':'10px'}"> 取 消</uv-text>-->
  50. <view class="text-right_btn" @click="handleSubmit" v-if="state.mode==='add'">提交反馈
  51. </view>
  52. </view>
  53. </uv-popup>
  54. <uv-action-sheet ref="type_select_ref"
  55. :actions="state.feedbackTypeList" title="请选择问题类型" description="选择本次上报问题的类型"
  56. @select="handleTypeSelect">
  57. </uv-action-sheet>
  58. </view>
  59. </template>
  60. <script setup lang="ts">
  61. import {reactive, ref} from "vue";
  62. import {onHide} from "@dcloudio/uni-app";
  63. import {body, formatUrl, upload} from "@/utils/https";
  64. import {fmtDateTime} from "@/utils/common";
  65. const popup_ref = ref()
  66. const feedback_form_ref = ref()
  67. const type_select_ref = ref()
  68. const initState = () => ({
  69. attachList: [] as any[],
  70. ruleForm: {
  71. title: '',
  72. content: '',
  73. replay: '',
  74. type: '',
  75. typeName: '',
  76. attachList: ''
  77. },
  78. rules: {
  79. 'title': {
  80. type: 'string',
  81. required: true,
  82. message: '请填写概要描述',
  83. trigger: ['blur', 'change']
  84. },
  85. },
  86. feedbackTypeList: [] as any[],
  87. mode: 'add'
  88. })
  89. const emit = defineEmits(['refresh'])
  90. const state = reactive(initState())
  91. onHide(() => {
  92. console.log("hidenee")
  93. // Object.assign(state, initState());
  94. })
  95. const handleSubmit = () => {
  96. console.log("submit")
  97. feedback_form_ref.value?.validate().then((res: any) => {
  98. uni.showToast({
  99. icon: 'success',
  100. title: '校验通过'
  101. })
  102. state.ruleForm.attachList = JSON.stringify(state.attachList)
  103. body(`/feedback/add`, state.ruleForm).then(() => {
  104. uni.showToast({
  105. icon: 'success',
  106. title: '提交成功,感谢您的反馈'
  107. })
  108. emit('refresh')
  109. setTimeout(() => {
  110. close();
  111. }, 1000)
  112. })
  113. }).catch((errors: any) => {
  114. uni.showToast({
  115. icon: 'error',
  116. title: '校验失败'
  117. })
  118. })
  119. }
  120. const handleUpload = (event: any) => {
  121. let file = event.file[0];
  122. upload(`/file/upload`, file).then((res: any) => {
  123. console.log(res)
  124. state.attachList.push({
  125. name: res.data.name,
  126. url: res.data.url
  127. })
  128. })
  129. }
  130. const handleDelete = (event: any) => {
  131. let {file, index, name} = event;
  132. state.ruleForm.attachList.splice(index, 1);
  133. }
  134. const loadDict = () => {
  135. body(`/dict/list`, {code: 'Feedback.type'}).then((res: any) => {
  136. state.feedbackTypeList = res;
  137. state.ruleForm.typeName = state.feedbackTypeList.find(k => k.value == state.ruleForm?.type)?.name
  138. })
  139. }
  140. const handleShowAction = () => {
  141. if (state.mode === 'detail') {
  142. return;
  143. }
  144. type_select_ref.value?.open();
  145. uni.hideKeyboard();
  146. }
  147. const handleTypeSelect = (e: any) => {
  148. console.log(e)
  149. state.ruleForm.type = e.value;
  150. state.ruleForm.typeName = e.name;
  151. }
  152. const close = () => {
  153. Object.assign(state, initState());
  154. popup_ref.value.close()
  155. }
  156. const open = (item: any, mode = 'add') => {
  157. popup_ref.value.open();
  158. state.mode = mode;
  159. if (mode === 'detail') {
  160. state.ruleForm = {...item}
  161. if (item.attachList) {
  162. state.attachList = JSON.parse(item.attachList)
  163. }
  164. state.ruleForm.typeName = state.feedbackTypeList.find(k => k.value == item.type)?.name
  165. }
  166. loadDict();
  167. }
  168. defineExpose({
  169. open
  170. })
  171. </script>
  172. <style scoped lang="scss">
  173. .text-right {
  174. text-align: right;
  175. .text-right_btn {
  176. /* margin-right: 10px; */
  177. background-color: #19A497;
  178. color: white;
  179. font-size: 15px;
  180. padding: 5px 12px;
  181. border-radius: 3px;
  182. text-align: center;
  183. }
  184. }
  185. </style>