DocumentCards.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. <template>
  2. <main>
  3. <section :class="{ 'section-full': hasUpload }">
  4. <div v-for="(item, key) in data" :key="key" :style="{ background: item.background }">
  5. <img :src="getAssetURL(item.img)" />
  6. <div :style="{ color: item.color }">
  7. {{ item.title }}
  8. <span>{{ item.content }}</span>
  9. </div>
  10. </div>
  11. </section>
  12. <footer v-if="hasUpload">
  13. <a-popover :popup-visible="showUpload" position="tl">
  14. <div :class="{ 'text-hide': showUpload }">
  15. <div
  16. @click="
  17. () => {
  18. showUpload = true;
  19. }
  20. "
  21. >
  22. <img src="@/assets/document/3.svg" class="img-normal" v-if="!showUpload" />
  23. <img src="@/assets/document/4.svg" class="img-hover" v-if="!showUpload" />
  24. <img src="@/assets/document/5.svg" class="img-active" v-if="showUpload" />
  25. </div>
  26. <p>已选择 0/0 个文档</p>
  27. </div>
  28. <template #content>
  29. <div class="upload-wrap">
  30. <header>
  31. <p>文档解析站</p>
  32. <div
  33. @click="
  34. () => {
  35. showUpload = false;
  36. }
  37. "
  38. >
  39. <icon-close size="large" />
  40. </div>
  41. </header>
  42. <div>
  43. <section>
  44. <a-upload
  45. draggable
  46. :multiple="true"
  47. :limit="5"
  48. @before-upload="onBeforeUpload"
  49. @exceed-limit="onExceedLimit"
  50. @before-remove="onBeforeRemove"
  51. :custom-request="customRequest"
  52. :show-upload-button="{ showOnExceedLimit: true }"
  53. accept=".pdf,.doc,.docx,.txt,.csv"
  54. >
  55. <template #upload-button>
  56. <div class="upload-main">
  57. <p>拖拽文档到这里,或<span>点此上传</span></p>
  58. <span> 支持上传.pdf, .doc, .docx, .txt, .csv文档,大小不超过30M </span>
  59. </div>
  60. </template>
  61. </a-upload>
  62. </section>
  63. <div>
  64. <p>
  65. <span>已解析文件列表</span>
  66. <span>共0个</span>
  67. </p>
  68. <div>
  69. <a-table
  70. :pagination="false"
  71. row-key="name"
  72. :columns="columns"
  73. :data="tableData"
  74. :row-selection="rowSelection"
  75. v-model:selectedKeys="selectedKeys"
  76. >
  77. <template #methods="{ record }">
  78. <a-button @click="$modal.info({ title: 'Name', content: record.name })"
  79. >删除</a-button
  80. >
  81. </template>
  82. </a-table>
  83. </div>
  84. </div>
  85. </div>
  86. </div>
  87. </template>
  88. </a-popover>
  89. </footer>
  90. </main>
  91. </template>
  92. <script>
  93. import { defineComponent, ref, inject, reactive } from "vue";
  94. export default defineComponent({
  95. props: ["data", "hasUpload"],
  96. setup() {
  97. const showUpload = ref(true);
  98. const { helper } = inject("$global");
  99. const maxSize = 30 * 1024 * 1024;
  100. const fileList = [];
  101. const onBeforeUpload = (file) => {
  102. if (file.size > maxSize) {
  103. helper.message("error", `上传文件大小不能超过10M`);
  104. return false;
  105. }
  106. return true;
  107. };
  108. const onExceedLimit = () => {
  109. helper.message("error", `最多上传5个文件`);
  110. };
  111. const customRequest = async (option) => {
  112. const { onSuccess, fileItem } = option;
  113. const { file, uid } = fileItem;
  114. fileList.push({
  115. id: uid,
  116. file
  117. });
  118. onSuccess();
  119. };
  120. const onBeforeRemove = (data) => {
  121. fileList = fileList.filter((item) => item.id !== data.uid);
  122. return true;
  123. };
  124. const selectedKeys = ref(["Jane Doe", "Alisa Ross"]);
  125. const rowSelection = reactive({
  126. type: "checkbox",
  127. showCheckedAll: true,
  128. onlyCurrent: false
  129. });
  130. const columns = [
  131. {
  132. title: "文件名称",
  133. dataIndex: "name"
  134. },
  135. {
  136. title: "类型",
  137. dataIndex: "type"
  138. },
  139. {
  140. title: "大小",
  141. dataIndex: "size"
  142. },
  143. {
  144. title: "上传时间",
  145. dataIndex: "time"
  146. },
  147. {
  148. title: "操作",
  149. slotName: "methods"
  150. }
  151. ];
  152. const tableData = reactive([
  153. {
  154. key: "1",
  155. name: "文件名称1",
  156. type: "pdf",
  157. size: "13M",
  158. time: "2024.9.8"
  159. },
  160. {
  161. key: "2",
  162. name: "文件名称2",
  163. type: "pdf",
  164. size: "13M",
  165. time: "2024.9.8"
  166. },
  167. {
  168. key: "3",
  169. name: "文件名称3",
  170. type: "pdf",
  171. size: "13M",
  172. time: "2024.9.8"
  173. }
  174. ]);
  175. return {
  176. selectedKeys,
  177. getAssetURL: helper.getAssetURL,
  178. showUpload,
  179. onBeforeUpload,
  180. onExceedLimit,
  181. onBeforeRemove,
  182. customRequest,
  183. columns,
  184. tableData,
  185. rowSelection
  186. };
  187. }
  188. });
  189. </script>
  190. <style lang="scss" scoped>
  191. .upload-main {
  192. width: 800px;
  193. height: 109px;
  194. background: url("@/assets/document/upload.svg");
  195. margin: 0 auto;
  196. padding: 24px 0px 24px 277px;
  197. background-size: 100%;
  198. > p {
  199. color: #000;
  200. font-weight: bold;
  201. margin-bottom: 5px;
  202. > span {
  203. color: #00aea3;
  204. text-decoration: underline;
  205. }
  206. }
  207. > span {
  208. font-size: 13px;
  209. color: #7f7f7f;
  210. }
  211. }
  212. main {
  213. height: 100%;
  214. display: flex;
  215. flex-direction: column;
  216. overflow: hidden;
  217. > section {
  218. overflow-y: auto;
  219. display: flex;
  220. flex-wrap: wrap;
  221. gap: 20px;
  222. &.section-full {
  223. flex: 1;
  224. }
  225. > div {
  226. width: 382px;
  227. height: 120px;
  228. padding: 20px 24px;
  229. border-radius: 8px;
  230. display: flex;
  231. > img {
  232. width: 38px;
  233. height: 38px;
  234. margin-right: 12px;
  235. }
  236. > div {
  237. font-size: 18px;
  238. font-weight: bold;
  239. > span {
  240. font-size: 15px;
  241. font-weight: 400;
  242. color: #797d7f;
  243. margin-top: 8px;
  244. overflow: hidden;
  245. text-overflow: ellipsis;
  246. display: -webkit-box;
  247. -webkit-line-clamp: 2;
  248. -webkit-box-orient: vertical;
  249. line-height: 1.4;
  250. }
  251. }
  252. }
  253. }
  254. > footer {
  255. > div {
  256. display: inline-flex;
  257. align-items: center;
  258. gap: 8px;
  259. height: 32px;
  260. border-radius: 21px;
  261. border: 1px solid #e3e3e3;
  262. white-space: nowrap;
  263. overflow: hidden;
  264. transition-duration: 0.3s;
  265. width: 250px;
  266. &.text-hide {
  267. width: 110px;
  268. overflow: hidden;
  269. }
  270. > p {
  271. overflow: hidden;
  272. white-space: nowrap;
  273. }
  274. > div {
  275. cursor: pointer;
  276. width: 110px;
  277. height: 32px;
  278. .img-normal {
  279. display: block;
  280. }
  281. .img-hover {
  282. display: none;
  283. }
  284. &:hover {
  285. .img-normal {
  286. display: none;
  287. }
  288. .img-hover {
  289. display: block;
  290. }
  291. }
  292. > img {
  293. width: 110px;
  294. height: 32px;
  295. }
  296. }
  297. }
  298. }
  299. }
  300. .upload-wrap {
  301. width: 800px;
  302. height: 300px;
  303. display: flex;
  304. flex-direction: column;
  305. padding-bottom: 30px;
  306. > header {
  307. display: flex;
  308. align-items: center;
  309. justify-content: space-between;
  310. margin-bottom: 13px;
  311. > p {
  312. font-size: 18px;
  313. font-weight: bold;
  314. }
  315. > div {
  316. width: 38px;
  317. height: 38px;
  318. border-radius: 6px;
  319. cursor: pointer;
  320. justify-content: center;
  321. align-items: center;
  322. display: flex;
  323. &:hover {
  324. background: rgba(0, 0, 0, 0.05);
  325. }
  326. }
  327. }
  328. > div {
  329. flex: 1;
  330. overflow-y: auto;
  331. > div {
  332. > p {
  333. margin: 20px 0;
  334. color: #7f7f7f;
  335. font-size: 13px;
  336. display: flex;
  337. justify-content: space-between;
  338. }
  339. }
  340. }
  341. }
  342. </style>