reporting_list.vue 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. <template>
  2. <div class="mainTitle">文章列表</div>
  3. <br />
  4. <div class="lists">
  5. <!-- @click="() => toDetail(item)" -->
  6. <el-table :data="listTable" style="width: 100%">
  7. <el-table-column prop="title" label="标题" width="450px" />
  8. <el-table-column prop="phone" label="用户名" />
  9. <el-table-column prop="source" label="来源">
  10. <template #default="scope">
  11. {{ source[scope.row.source - 1] }}
  12. </template>
  13. </el-table-column>
  14. <el-table-column prop="" label="回复状态">
  15. <template #default="scope">
  16. {{ replyFlag[scope.row.replyFlag] }}
  17. </template>
  18. </el-table-column>
  19. <el-table-column prop="createTime" label="更新时间">
  20. <template #default="scope">
  21. {{ format(scope.row.createTime) }}
  22. </template>
  23. </el-table-column>
  24. <el-table-column prop="modifyTime" label="推送时间">
  25. <template #default="scope">
  26. {{ format(scope.row.modifyTime) }}
  27. </template>
  28. </el-table-column>
  29. <el-table-column prop="clueInfoCount" label="数量" />
  30. <el-table-column prop="" label="操作" width="200px">
  31. <template #default="scope">
  32. <el-popconfirm
  33. v-if="scope.row.status === 0"
  34. confirm-button-text="通过"
  35. cancel-button-text="不通过"
  36. @confirm="() => confirm(scope)"
  37. @cancel="() => cancel(scope)"
  38. title="是否通过该报料?"
  39. >
  40. <template #reference>
  41. <el-button link type="primary" size="small">审核</el-button>
  42. </template>
  43. </el-popconfirm>
  44. <el-button
  45. link
  46. type="primary"
  47. size="small"
  48. @click="() => lookBL(scope)"
  49. >
  50. 查看
  51. </el-button>
  52. <el-button
  53. link
  54. v-if="scope.row.replyFlag != 1"
  55. type="primary"
  56. size="small"
  57. @click="() => replyBL(scope)"
  58. >
  59. 回复
  60. </el-button>
  61. <el-popconfirm
  62. confirm-button-text="删除"
  63. cancel-button-text="不删除"
  64. @confirm="() => deleteBL(scope)"
  65. title="是否删除该报料?"
  66. >
  67. <template #reference>
  68. <el-button link type="danger" size="small"> 删除 </el-button>
  69. </template>
  70. </el-popconfirm>
  71. </template>
  72. </el-table-column>
  73. </el-table>
  74. <el-dialog v-model="reportingDetail" title="报料详情" width="30%">
  75. <div style="overflow-y: auto">
  76. <el-row>
  77. <el-col :span="5">联系方式:</el-col>
  78. <el-col :span="19">
  79. <div v-text="reportingDetailData.row.phone"></div>
  80. </el-col>
  81. </el-row>
  82. <el-row>
  83. <el-col :span="5">上报地址:</el-col>
  84. <el-col :span="19">
  85. <div v-text="reportingDetailData.row.address"></div>
  86. </el-col>
  87. </el-row>
  88. <el-row>
  89. <el-col :span="5">报料详情:</el-col>
  90. <el-col :span="19">
  91. <div
  92. v-for="(v, i) in reportingDetailData.row.clueInfos"
  93. :key="i"
  94. style="padding: 2px 0; position: relative;padding-right: 112px;"
  95. >
  96. <span v-if="v.type == 0" v-text="v.materialUrl"></span>
  97. <el-image v-if="v.type == 1" style="width: 100px; height: 100px" :src="v.localUrl" fit="contain" :preview-src-list="[v.localUrl]" />
  98. <small
  99. style="
  100. color: #999;
  101. position: absolute;
  102. right: 0;
  103. top: 50%;
  104. transform: translateY(-50%);
  105. "
  106. v-text="format(v.addTime)"
  107. ></small>
  108. </div>
  109. </el-col>
  110. </el-row>
  111. <el-row
  112. v-if="
  113. reportingDetailData.row.clueReplies &&
  114. reportingDetailData.row.clueReplies.length
  115. "
  116. >
  117. <el-col :span="5">回复内容:</el-col>
  118. <el-col :span="19">
  119. <div v-text="reportingDetailData.row.clueReplies[0].content"></div>
  120. </el-col>
  121. </el-row>
  122. </div>
  123. </el-dialog>
  124. <el-dialog v-model="reportingReplyStatus" title="回复" width="30%">
  125. <el-row>
  126. <el-col :span="5">报料内容:</el-col>
  127. <el-col :span="19">
  128. <div
  129. v-for="(v, i) in reportingDetailData.row.clueInfos"
  130. :key="i"
  131. style="padding: 2px 0; position: relative;padding-right: 112px;"
  132. >
  133. <span v-if="v.type == 0" v-text="v.materialUrl"></span>
  134. <el-image v-if="v.type == 1" style="width: 100px; height: 100px" :src="v.localUrl" fit="contain" :preview-src-list="[v.localUrl]" />
  135. <small
  136. style="
  137. color: #999;
  138. position: absolute;
  139. right: 0;
  140. top: 50%;
  141. transform: translateY(-50%);
  142. "
  143. v-text="format(v.addTime)"
  144. ></small>
  145. </div>
  146. </el-col>
  147. </el-row>
  148. <br />
  149. <el-row>
  150. <el-col :span="5">回复内容:</el-col>
  151. <el-col :span="19">
  152. <el-input
  153. v-model="reportingDetailData.row.reply"
  154. :rows="2"
  155. type="textarea"
  156. placeholder="请输入回复内容"
  157. />
  158. </el-col>
  159. </el-row>
  160. <template #footer>
  161. <span class="dialog-footer">
  162. <el-button type="primary" @click="replySave"> 确定 </el-button>
  163. </span>
  164. </template>
  165. </el-dialog>
  166. </div>
  167. </template>
  168. <script setup>
  169. import { ref, defineExpose, defineEmits } from 'vue';
  170. // import { useRouter } from 'vue-router';
  171. import dayjs from 'dayjs';
  172. import { ElMessage } from 'element-plus';
  173. import {
  174. getreporting,
  175. delreporting,
  176. getreportingDetail,
  177. reportingShenhe,
  178. reportingReply,
  179. } from '../../../api/index';
  180. let T = undefined;
  181. let total = -1;
  182. // const router = useRouter();
  183. const listTable = ref([]);
  184. const reportingDetail = ref(false);
  185. const reportingReplyStatus = ref(false);
  186. const reportingDetailData = ref({});
  187. const source = ['热线电话', '微信公众号', 'app', '小程序'];
  188. const replyFlag = ['未回复', '已回复'];
  189. const emit = defineEmits(['setTotal']);
  190. const format = value => {
  191. return dayjs(value).format('YYYY-MM-DD HH:mm:ss');
  192. };
  193. // const toDetail = item => {
  194. // router.push({
  195. // path: '/analysis_detail',
  196. // query: {
  197. // detail: JSON.stringify(item),
  198. // },
  199. // });
  200. // };
  201. const getlist = search => {
  202. if (search.page === 1) {
  203. listTable.value = [];
  204. total = -1;
  205. } else if ((search.page - 1) * search.pageSize >= total) return;
  206. if (T) T = window.clearTimeout(T);
  207. T = window.setTimeout(() => {
  208. getreporting({
  209. data: search,
  210. })
  211. .then(res => {
  212. listTable.value = res.records || [];
  213. total = res.total || 0;
  214. emit('setTotal', total);
  215. if (T) T = window.clearTimeout(T);
  216. })
  217. .catch(() => {
  218. if (T) T = window.clearTimeout(T);
  219. });
  220. }, 200);
  221. };
  222. const deleteBL = item => {
  223. delreporting({ data: { id: item.row.id } }).then(() => {
  224. ElMessage({
  225. type: 'success',
  226. message: '删除成功',
  227. });
  228. listTable.value.splice(item.$index, 1);
  229. });
  230. };
  231. const lookBL = item => {
  232. getreportingDetail({ data: { id: item.row.id } }).then(res => {
  233. reportingDetail.value = true;
  234. reportingDetailData.value.row = res;
  235. });
  236. };
  237. const replyBL = item => {
  238. getreportingDetail({ data: { id: item.row.id } }).then(res => {
  239. reportingReplyStatus.value = true;
  240. reportingDetailData.value.row = res;
  241. reportingDetailData.value.$index = item.$index;
  242. });
  243. };
  244. const replySave = () => {
  245. reportingReplyStatus.value = false;
  246. reportingReply({
  247. data: {
  248. clueId: reportingDetailData.value.row.id,
  249. content: reportingDetailData.value.row.reply || '',
  250. userName: reportingReplyStatus.value.author || '',
  251. },
  252. }).then(() => {
  253. listTable.value[reportingDetailData.value.$index].replyFlag = 1;
  254. });
  255. };
  256. const confirm = item => {
  257. reportingShenhe({ data: { id: item.row.id, status: 1 } }).then(() => {
  258. ElMessage({
  259. type: 'success',
  260. message: '审核通过',
  261. });
  262. listTable.value[item.$index].status = 1;
  263. });
  264. };
  265. const cancel = item => {
  266. reportingShenhe({ data: { id: item.row.id, status: -1 } }).then(() => {
  267. ElMessage({
  268. type: 'success',
  269. message: '拒绝通过',
  270. });
  271. listTable.value[item.$index].status = -1;
  272. });
  273. };
  274. defineExpose({
  275. getlist,
  276. });
  277. </script>
  278. <style scoped>
  279. .mainTitle {
  280. padding: 0 20px;
  281. position: relative;
  282. line-height: 60px;
  283. border-bottom: 1px solid #f5f5f5;
  284. }
  285. .lists {
  286. padding: 0.5em;
  287. }
  288. .list {
  289. border-radius: 5px;
  290. padding: 0.5em;
  291. cursor: pointer;
  292. line-height: 1.8em;
  293. font-size: 14px;
  294. }
  295. .list:hover {
  296. background-color: rgba(64, 158, 255, 0.1);
  297. }
  298. .list:not(:last-child) {
  299. border-bottom: 1px dashed #b9c0d3;
  300. }
  301. </style>
  302. <style>
  303. .lists .el-row {
  304. line-height: 2em;
  305. }
  306. </style>