index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. <!-- eslint-disable prettier/prettier -->
  2. <template>
  3. <div class="bodycontent">
  4. <div class="sheard">
  5. <div class="searchheard">
  6. <div class="item">
  7. <div>文件名称:</div>
  8. <div>
  9. <el-input
  10. v-model="searchForm.originalName"
  11. style="width: 240px"
  12. placeholder="请输入文件名称"
  13. />
  14. </div>
  15. </div>
  16. <div class="item">
  17. <div>丘权号:</div>
  18. <div>
  19. <el-input
  20. v-model="searchForm.qiuquan"
  21. style="width: 240px"
  22. placeholder="请输入丘权号"
  23. />
  24. </div>
  25. </div>
  26. </div>
  27. <div
  28. style="
  29. position: absolute;
  30. right: 0;
  31. top: 10px;
  32. display: flex;
  33. flex-direction: column;
  34. align-items: flex-end;
  35. "
  36. >
  37. <div>
  38. <el-button type="primary" @click="reset">重置</el-button>
  39. <el-button type="primary" @click="getnextdata(1)">查询</el-button>
  40. </div>
  41. </div>
  42. </div>
  43. <div>
  44. <el-table
  45. :data="tableData"
  46. border
  47. style="width: 100%; height: 70vh"
  48. :row-class-name="tableRowClassName"
  49. >
  50. <el-table-column prop="originalName" label="文件名称">
  51. <template #default="scope">
  52. <div style="display: flex">
  53. <img
  54. style="width: 25px; height: 25px"
  55. :src="gettypeicon(scope.row.fileSuffix)"
  56. />
  57. <div>{{ scope.row.originalName }}</div>
  58. </div>
  59. </template>
  60. </el-table-column>
  61. <el-table-column prop="size" label="文件大小" width="190">
  62. <template #default="scope">
  63. {{
  64. scope.row.size > 1024
  65. ? scope.row.size > 1024 * 1024
  66. ? (scope.row.size / 1024 / 1024).toFixed(2) + " MB"
  67. : (scope.row.size / 1024).toFixed(2) + " KB"
  68. : scope.row.size + " B"
  69. }}
  70. </template>
  71. </el-table-column>
  72. <el-table-column prop="createTime" label="上传日期" width="160" />
  73. <el-table-column prop="address" label="操作">
  74. <template #default="scope">
  75. <div
  76. style="
  77. display: flex;
  78. justify-content: flex-start;
  79. align-items: center;
  80. flex-wrap: wrap;
  81. align-content: center;
  82. flex-direction: row;
  83. "
  84. >
  85. <div>
  86. <el-button type="text" size="small" @click="filepreview(scope.row)" v-hasPermi="['filemanager.file.preview']"
  87. >预览</el-button
  88. >
  89. </div>
  90. <div>
  91. <el-button type="text" size="small" @click="downloadfile(scope.row)" v-hasPermi="['filemanager.file.download']"
  92. >下载</el-button
  93. >
  94. </div>
  95. <div>
  96. <el-button type="text" size="small" @click="filelogs(scope.row)" v-hasPermi="['filemanager.file.log']"
  97. >记录</el-button
  98. >
  99. </div>
  100. </div>
  101. </template>
  102. </el-table-column>
  103. </el-table>
  104. <div style="display: flex; justify-content: flex-end">
  105. <el-pagination
  106. small
  107. background
  108. layout="prev, pager, next"
  109. :total="totalnum"
  110. class="mt-4"
  111. @current-change="getnextdata"
  112. />
  113. </div>
  114. </div>
  115. <el-dialog v-model="pdfviewshow" :title="`文件预览`" width="60vw">
  116. <div style="position: relative; min-height: 70vh">
  117. <el-affix :offset="400" style="width: 100%">
  118. <div style="position: absolute">
  119. <el-button
  120. type="primary"
  121. icon="DArrowLeft"
  122. :disabled="ccindex <= 0"
  123. @click="fileindexlook(ccindex - 1)"
  124. ></el-button>
  125. </div>
  126. <div style="float: right">
  127. <el-button
  128. type="primary"
  129. icon="DArrowRight"
  130. :disabled="ccindex + 1 >= tableData.length"
  131. @click="fileindexlook(ccindex + 1)"
  132. ></el-button>
  133. </div>
  134. </el-affix>
  135. <pdfview :src="currentfile.url" :size="currentfile.size"></pdfview>
  136. </div>
  137. <template #footer>
  138. <div class="dialog-footer">
  139. <el-button @click="pdfviewshow = false">关闭</el-button>
  140. <el-button type="primary" @click="downloadfile" v-hasPermi="['filemanager.file.download']"> 下载 </el-button>
  141. </div>
  142. </template>
  143. </el-dialog>
  144. <el-drawer
  145. v-model="logsshow"
  146. title="文件信息"
  147. :direction="'rtl'"
  148. >
  149. <div>
  150. <el-descriptions title="项目信息" border :column="2">
  151. <el-descriptions-item label="电子编号">{{
  152. currentproject.ecode
  153. }}</el-descriptions-item>
  154. <el-descriptions-item label="丘权号">{{
  155. currentproject.qiuquan
  156. }}</el-descriptions-item>
  157. <el-descriptions-item label="区域">{{
  158. currentproject.area
  159. }}</el-descriptions-item>
  160. <el-descriptions-item label="创建时间">
  161. {{ currentproject.achievementDate }}
  162. </el-descriptions-item>
  163. <el-descriptions-item label="建设单位" :span="2">
  164. {{ currentproject.buildUnit }}
  165. </el-descriptions-item>
  166. <el-descriptions-item label="地址" :span="2">
  167. {{ currentproject.addr }}
  168. </el-descriptions-item>
  169. <el-descriptions-item label="备注" :span="2">
  170. {{ currentproject.remark }}
  171. </el-descriptions-item>
  172. </el-descriptions>
  173. </div>
  174. <el-divider />
  175. <div>
  176. <div style="max-height: 50vh;overflow-y: auto;">
  177. <el-timeline style="max-width: 600px; ">
  178. <el-timeline-item
  179. v-for="(activity, index) in activities"
  180. :key="index"
  181. :timestamp="activity.timestamp"
  182. :color="activity.color"
  183. >
  184. {{ activity.content }}
  185. </el-timeline-item>
  186. </el-timeline>
  187. </div>
  188. </div>
  189. </el-drawer>
  190. </div>
  191. </template>
  192. <script lang="ts" setup>
  193. import txticon from "@/assets/icons/svg/txt.svg";
  194. import picicon from "@/assets/icons/svg/pic.svg";
  195. import pdficon from "@/assets/icons/svg/pdf1.svg";
  196. import docicon from "@/assets/icons/svg/doc.svg";
  197. import xlsicon from "@/assets/icons/svg/xls.svg";
  198. import ppticon from "@/assets/icons/svg/ppt.svg";
  199. import mp4icon from "@/assets/icons/svg/mp4.svg";
  200. import cadicon from "@/assets/icons/svg/cad.svg";
  201. import unknownicon from "@/assets/icons/svg/unknown.svg";
  202. import { ref, onMounted } from "vue";
  203. const { proxy } = getCurrentInstance() as ComponentInternalInstance;
  204. import { listByIds, listArchivesFileList } from "@/api/system/oss/index";
  205. import _ from "lodash";
  206. import { getArchives } from "@/api/archives/index";
  207. import { list } from "@/api/monitor/operlog/index";
  208. import {ElLoading} from "element-plus";
  209. // const { proxy } = getCurrentInstance() as ComponentInternalInstance;
  210. // const { sys_area, sys_project_status } = toRefs<any>(
  211. // proxy?.useDict("sys_area", "sys_project_status")
  212. // );
  213. const searchForm = ref({
  214. qiuquan: "",
  215. originalName: "",
  216. });
  217. const reset = () => {
  218. searchForm.value = {
  219. qiuquan: "",
  220. originalName: "",
  221. };
  222. getnextdata(1);
  223. };
  224. const tableData = ref([]);
  225. const currentpage = ref(0);
  226. const totalnum = ref(0);
  227. const getnextdata = (page: number) => {
  228. currentpage.value = page;
  229. listArchivesFileList({ pageSize: 10, pageNum: page, ...searchForm.value }).then(
  230. (res) => {
  231. tableData.value = res.rows;
  232. totalnum.value = res.total;
  233. }
  234. );
  235. };
  236. onMounted(() => {
  237. getnextdata(1);
  238. });
  239. const tableRowClassName = ({ row, rowIndex }: { row: any; rowIndex: number }) => {
  240. return "";
  241. };
  242. const pdfviewshow = ref(false);
  243. const currentfile = ref();
  244. const ccindex = ref(0);
  245. const fileindexlook = (index) => {
  246. var item = tableData.value[index];
  247. filepreview(item);
  248. };
  249. const filepreview = (file) => {
  250. ccindex.value = tableData.value.indexOf(file);
  251. currentfile.value = file;
  252. listByIds(file.ossId).then((res) => {
  253. currentfile.value.url = res.data[0].url;
  254. pdfviewshow.value = true;
  255. });
  256. };
  257. const downloadfile = (file) => {
  258. // proxy?.$download.oss(file.ossId);
  259. // currentfile.value = file;
  260. const loadingInstance1 = ElLoading.service({ fullscreen: true,text:"下载中..." })
  261. listByIds(file.ossId).then((res) => {
  262. fetch(res.data[0].url)
  263. .then(response => response.blob())
  264. .then(blob => {
  265. loadingInstance1.close();
  266. const link = document.createElement('a');
  267. link.href = URL.createObjectURL(blob);
  268. link.download = file.originalName;
  269. link.target = "_blank"; // 可选,如果希望在新窗口中下载文件,请取消注释此行
  270. link.click();
  271. });
  272. });
  273. };
  274. const currentproject = ref({
  275. area: "",
  276. ecode: "",
  277. qiuquan: "",
  278. buildUnit: "",
  279. addr: "",
  280. saveAddr: "",
  281. remark: "",
  282. });
  283. const logsshow = ref(false);
  284. const filelogs = (file) => {
  285. logsshow.value = true;
  286. getArchives(file.archiveId).then((res) => {
  287. currentproject.value = res.data;
  288. });
  289. activities.value = [];
  290. list({ title: "OSS对象存储", jsonResult: file.ossId }).then((res) => {
  291. var ll = res.rows.map((item) => {
  292. var re = { content: item.operName + " 预览文件", timestamp: item.operTime, color: '#0bbd87', };
  293. if ((item.operParam + "").indexOf("type") != -1) {
  294. re.content = item.operName + " 预览文件";
  295. }
  296. if (item.requestMethod == "POST") {
  297. re.content = item.operName + " 上传了文件";
  298. re.color = '#1e90ff';
  299. }
  300. return re;
  301. });
  302. activities.value = activities.value.concat(ll);
  303. _.sortedIndexBy(activities.value, function (o) {
  304. return o.timestamp;
  305. });
  306. });
  307. list({ title: "OSS对象存储", businessType: 5, operUrl: file.ossId }).then((res) => {
  308. var ll = res.rows.map((item) => {
  309. var re = { content: item.operName + " 下载了文件", timestamp: item.operTime , color: '#c4000a',};
  310. return re;
  311. });
  312. activities.value = activities.value.concat(ll);
  313. _.sortedIndexBy(activities.value, function (o) {
  314. return o.timestamp;
  315. });
  316. });
  317. };
  318. const activities = ref([
  319. ]);
  320. const gettypeicon = (type) => {
  321. if (type.indexOf("png") != -1 || type.indexOf("jp") != -1) {
  322. return picicon;
  323. }
  324. if (type.indexOf("ppt") != -1) {
  325. return ppticon;
  326. }
  327. if (type.indexOf("xl") != -1) {
  328. return xlsicon;
  329. }
  330. if (type.indexOf("doc") != -1) {
  331. return docicon;
  332. }
  333. if (type.indexOf("txt") != -1) {
  334. return txticon;
  335. }
  336. if (type.indexOf("ca") != -1) {
  337. return cadicon;
  338. }
  339. if (type.indexOf("mp4") != -1) {
  340. return mp4icon;
  341. }
  342. if (type.indexOf("pdf") != -1) {
  343. return pdficon;
  344. }
  345. return unknownicon;
  346. };
  347. </script>
  348. <style type="scss" scoped>
  349. .bodycontent {
  350. padding: 10px 15px;
  351. .sheard {
  352. position: relative;
  353. padding: 10px 0px;
  354. .searchheard {
  355. display: flex;
  356. align-items: center;
  357. .item {
  358. display: flex;
  359. align-items: center;
  360. margin-right: 20px;
  361. font-size: 14px;
  362. }
  363. }
  364. }
  365. .formitem {
  366. display: flex;
  367. gap: 20px;
  368. align-items: center;
  369. font-size: 14px;
  370. }
  371. }
  372. </style>
  373. <style>
  374. .el-table .warning-row {
  375. --el-table-tr-bg-color: var(--el-color-warning-light-9);
  376. }
  377. .el-table .success-row {
  378. --el-table-tr-bg-color: var(--el-color-success-light-9);
  379. }
  380. .el-table .danger-row {
  381. --el-table-tr-bg-color: var(--el-color-danger-light-9);
  382. }
  383. </style>