index.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. <template>
  2. <div class="header">
  3. <a-upload
  4. accept="image/*"
  5. multiple
  6. :beforeUpload="beforeUpload"
  7. :showUploadList="false"
  8. name="file"
  9. >
  10. <a-button
  11. v-if="butText"
  12. @click="addImage"
  13. :disabled="props.disabled"
  14. type="primary"
  15. size="samll"
  16. class="mr-10"
  17. >{{ butText }}</a-button
  18. >
  19. </a-upload>
  20. <div style="width: 300px" v-if="list.length">
  21. <a-slider
  22. :max="300"
  23. :min="60"
  24. id="test"
  25. v-model:value="baseSize"
  26. @change="changeZoom"
  27. />
  28. </div>
  29. </div>
  30. <div
  31. class="picture-wall-box"
  32. :style="{
  33. gridTemplateColumns: `repeat(auto-fill, ${baseSize}px)`,
  34. }"
  35. >
  36. <a-image-preview-group>
  37. <div
  38. class="picture-wall-item"
  39. v-for="(item, index) in list"
  40. :key="item.attachmentid"
  41. :style="{
  42. width: baseSize + 'px',
  43. height: baseSize + 'px',
  44. }"
  45. :draggable="!props.disabled && pic"
  46. @dragstart="dragStart(index)"
  47. @dragover="dragOver(index)"
  48. @dragend="dragEnd"
  49. >
  50. <div v-if="item.uid">
  51. <a-progress
  52. type="circle"
  53. :percent="item.progress"
  54. :status="item.exception"
  55. :size="[baseSize - 40, baseSize - 40]"
  56. />
  57. </div>
  58. <a-popover
  59. v-else
  60. :open="false && hovered == index"
  61. @openChange="handleHoverChange($event, index)"
  62. >
  63. <template #content>
  64. <a-image
  65. :src="item.cover"
  66. width="200px"
  67. :previewMask="false"
  68. fallback="data:image/png;base64,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"
  69. >
  70. <template #placeholder>
  71. <a-image :src="item.cover" :width="200" :preview="false" />
  72. </template>
  73. </a-image>
  74. </template>
  75. <div>
  76. <a-image
  77. :src="item.cover"
  78. :preview="{
  79. src: item.url,
  80. }"
  81. :style="{
  82. width: baseSize - (baseSize &gt; 100 ? 30 : 15) + 'px',
  83. height: baseSize - (baseSize &gt; 100 ? 30 : 15) + 'px',
  84. objectFit: 'cover',
  85. fontSize: 0,
  86. }"
  87. fallback="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMIAAADDCAYAAADQvc6UAAABRWlDQ1BJQ0MgUHJvZmlsZQAAKJFjYGASSSwoyGFhYGDIzSspCnJ3UoiIjFJgf8LAwSDCIMogwMCcmFxc4BgQ4ANUwgCjUcG3awyMIPqyLsis7PPOq3QdDFcvjV3jOD1boQVTPQrgSkktTgbSf4A4LbmgqISBgTEFyFYuLykAsTuAbJEioKOA7DkgdjqEvQHEToKwj4DVhAQ5A9k3gGyB5IxEoBmML4BsnSQk8XQkNtReEOBxcfXxUQg1Mjc0dyHgXNJBSWpFCYh2zi+oLMpMzyhRcASGUqqCZ16yno6CkYGRAQMDKMwhqj/fAIcloxgHQqxAjIHBEugw5sUIsSQpBobtQPdLciLEVJYzMPBHMDBsayhILEqEO4DxG0txmrERhM29nYGBddr//5/DGRjYNRkY/l7////39v///y4Dmn+LgeHANwDrkl1AuO+pmgAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAwqADAAQAAAABAAAAwwAAAAD9b/HnAAAHlklEQVR4Ae3dP3PTWBSGcbGzM6GCKqlIBRV0dHRJFarQ0eUT8LH4BnRU0NHR0UEFVdIlFRV7TzRksomPY8uykTk/zewQfKw/9znv4yvJynLv4uLiV2dBoDiBf4qP3/ARuCRABEFAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghgg0Aj8i0JO4OzsrPv69Wv+hi2qPHr0qNvf39+iI97soRIh4f3z58/u7du3SXX7Xt7Z2enevHmzfQe+oSN2apSAPj09TSrb+XKI/f379+08+A0cNRE2ANkupk+ACNPvkSPcAAEibACyXUyfABGm3yNHuAECRNgAZLuYPgEirKlHu7u7XdyytGwHAd8jjNyng4OD7vnz51dbPT8/7z58+NB9+/bt6jU/TI+AGWHEnrx48eJ/EsSmHzx40L18+fLyzxF3ZVMjEyDCiEDjMYZZS5wiPXnyZFbJaxMhQIQRGzHvWR7XCyOCXsOmiDAi1HmPMMQjDpbpEiDCiL358eNHurW/5SnWdIBbXiDCiA38/Pnzrce2YyZ4//59F3ePLNMl4PbpiL2J0L979+7yDtHDhw8vtzzvdGnEXdvUigSIsCLAWavHp/+qM0BcXMd/q25n1vF57TYBp0a3mUzilePj4+7k5KSLb6gt6ydAhPUzXnoPR0dHl79WGTNCfBnn1uvSCJdegQhLI1vvCk+fPu2ePXt2tZOYEV6/fn31dz+shwAR1sP1cqvLntbEN9MxA9xcYjsxS1jWR4AIa2Ibzx0tc44fYX/16lV6NDFLXH+YL32jwiACRBiEbf5KcXoTIsQSpzXx4N28Ja4BQoK7rgXiydbHjx/P25TaQAJEGAguWy0+2Q8PD6/Ki4R8EVl+bzBOnZY95fq9rj9zAkTI2SxdidBHqG9+skdw43borCXO/ZcJdraPWdv22uIEiLA4q7nvvCug8WTqzQveOH26fodo7g6uFe/a17W3+nFBAkRYENRdb1vkkz1CH9cPsVy/jrhr27PqMYvENYNlHAIesRiBYwRy0V+8iXP8+/fvX11Mr7L7ECueb/r48eMqm7FuI2BGWDEG8cm+7G3NEOfmdcTQw4h9/55lhm7DekRYKQPZF2ArbXTAyu4kDYB2YxUzwg0gi/41ztHnfQG26HbGel/crVrm7tNY+/1btkOEAZ2M05r4FB7r9GbAIdxaZYrHdOsgJ/wCEQY0J74TmOKnbxxT9n3FgGGWWsVdowHtjt9Nnvf7yQM2aZU/TIAIAxrw6dOnAWtZZcoEnBpNuTuObWMEiLAx1HY0ZQJEmHJ3HNvGCBBhY6jtaMoEiJB0Z29vL6ls58vxPcO8/zfrdo5qvKO+d3Fx8Wu8zf1dW4p/cPzLly/dtv9Ts/EbcvGAHhHyfBIhZ6NSiIBTo0LNNtScABFyNiqFCBChULMNNSdAhJyNSiECRCjUbEPNCRAhZ6NSiAARCjXbUHMCRMjZqBQiQIRCzTbUnAARcjYqhQgQoVCzDTUnQIScjUohAkQo1GxDzQkQIWejUogAEQo121BzAkTI2agUIkCEQs021JwAEXI2KoUIEKFQsw01J0CEnI1KIQJEKNRsQ80JECFno1KIABEKNdtQcwJEyNmoFCJAhELNNtScABFyNiqFCBChULMNNSdAhJyNSiECRCjUbEPNCRAhZ6NSiAARCjXbUHMCRMjZqBQiQIRCzTbUnAARcjYqhQgQoVCzDTUnQIScjUohAkQo1GxDzQkQIWejUogAEQo121BzAkTI2agUIkCEQs021JwAEXI2KoUIEKFQsw01J0CEnI1KIQJEKNRsQ80JECFno1KIABEKNdtQcwJEyNmoFCJAhELNNtScABFyNiqFCBChULMNNSdAhJyNSiECRCjUbEPNCRAhZ6NSiAARCjXbUHMCRMjZqBQiQIRCzTbUnAARcjYqhQgQoVCzDTUnQIScjUohAkQo1GxDzQkQIWejUogAEQo121BzAkTI2agUIkCEQs021JwAEXI2KoUIEKFQsw01J0CEnI1KIQJEKNRsQ80JECFno1KIABEKNdtQcwJEyNmoFCJAhELNNtScABFyNiqFCBChULMNNSdAhJyNSiEC/wGgKKC4YMA4TAAAAABJRU5ErkJggg=="
  88. >
  89. <template #previewMask>
  90. <a-popconfirm
  91. v-if="!props.disabled"
  92. :open="linksid == item.linksid"
  93. title="确定删除当前资源吗?"
  94. @confirm="confirmDeleteImage"
  95. @cancel="linksid = null"
  96. >
  97. <DeleteOutlined
  98. v-if="isDeletable"
  99. class="previewMaskIcon"
  100. :style="{ fontSize: (baseSize &gt; 200 ? '24px' : '20px') }"
  101. @click.stop="linksid = item.linksid"
  102. />
  103. </a-popconfirm>
  104. </template>
  105. </a-image>
  106. </div>
  107. </a-popover>
  108. </div>
  109. </a-image-preview-group>
  110. </div>
  111. <div class="empty" v-if="!list.length">
  112. <a-empty :image="simpleImage" />
  113. </div>
  114. </template>
  115. <script setup>
  116. import { ref, reactive, defineProps, watch } from "vue";
  117. import Api from "@/api/api";
  118. import Up from "@/api/upload";
  119. import utils from "@/utils/utils";
  120. import { ExpandOutlined, DeleteOutlined } from "@ant-design/icons-vue";
  121. import { Empty } from "ant-design-vue";
  122. const simpleImage = Empty.PRESENTED_IMAGE_SIMPLE;
  123. const props = defineProps({
  124. butText: {
  125. type: String,
  126. default: "添加图片",
  127. },
  128. disabled: {
  129. type: Boolean,
  130. default: true,
  131. },
  132. attinfos: {
  133. type: Array,
  134. },
  135. coverType: {
  136. //列表显示的类型
  137. type: String,
  138. default: "thumbnail",
  139. },
  140. pic: {
  141. //pic支持排序
  142. type: Boolean,
  143. default: false,
  144. },
  145. startSequence: {
  146. //设置排序的起量,比如说第二页每页20条数据 起量为21
  147. type: [String, Number],
  148. default: 0,
  149. },
  150. total: {
  151. //考虑分页情况传递,上传图片顺序会在此向后顺延
  152. type: [Number, String],
  153. default: 0,
  154. },
  155. ownertable: {
  156. type: String,
  157. },
  158. ownerid: {
  159. type: [String, Number],
  160. },
  161. isDeletable: {
  162. type: Boolean,
  163. default: true,
  164. },
  165. });
  166. let baseSize = ref("140"),
  167. zoom = ref("50"),
  168. list = ref([]);
  169. const appfolderid = ref("");
  170. Api.requested({
  171. classname: "webmanage.site.site",
  172. method: "querySite_Parameter",
  173. content: {},
  174. }).then((res) => {
  175. appfolderid.value = res.data.appfolderid;
  176. });
  177. function beforeUpload(file) {
  178. file.document = file.name;
  179. const filetype = file.document.substr(file.document.lastIndexOf(".") + 1);
  180. file.sequence = list.value.length;
  181. file.progress = 0;
  182. file.linksid = -1;
  183. file.attachmentid = Date.now();
  184. list.value.push(reactive({ ...file }));
  185. Api.requested({
  186. classname: "system.attachment.huawei.OBS",
  187. method: "getFileName",
  188. content: {
  189. filename: file.name,
  190. filetype,
  191. parentid: appfolderid.value, //归属文件夹ID
  192. },
  193. }).then((res) => {
  194. if (res.code != 1)
  195. return (list.value[file.sequence].exception = "exception");
  196. console.log("获取上传链接", res);
  197. const { uploadurl, serialfilename } = res.data;
  198. Up.upload(uploadurl, file, {
  199. headers: {
  200. "Content-Type": "application/octet-stream",
  201. },
  202. onUploadProgress: function (e) {
  203. list.value[file.sequence].progress = parseInt(e.progress * 100);
  204. console.log(list.value[file.sequence]);
  205. },
  206. }).then((upload) => {
  207. console.log("上传结果", upload);
  208. if (upload.status != 200)
  209. return (list.value[file.sequence].exception = "exception");
  210. Api.requested({
  211. classname: "system.attachment.huawei.OBS",
  212. method: "uploadSuccess",
  213. content: {
  214. serialfilename,
  215. ownerid: props.ownerid,
  216. ownertable: props.ownertable,
  217. usetype: "file",
  218. },
  219. }).then((feedback) => {
  220. console.log("feedback", feedback);
  221. if (feedback.code != 1)
  222. return (list.value[file.sequence].exception = "exception");
  223. const attachmentid = feedback.data.attachmentids[0];
  224. Api.requested({
  225. id: 20240407135802,
  226. content: {
  227. ownerid: props.ownerid,
  228. ownertable: props.ownertable,
  229. attachmentid,
  230. sequence: file.sequence,
  231. },
  232. }).then((binding) => {
  233. console.log(binding, "binding");
  234. if (binding.code != 1)
  235. return (list.value[file.sequence].exception = "exception");
  236. Api.requested({
  237. id: "20240407140002",
  238. content: {
  239. ownerid: props.ownerid,
  240. ownertable: props.ownertable,
  241. pageNumber: 1,
  242. pageSize: 100,
  243. where: {
  244. // condition: serialfilename,
  245. },
  246. },
  247. }).then((getList) => {
  248. if (getList.code != 1)
  249. return (list.value[file.sequence].exception = "exception");
  250. list.value[file.sequence] = getList.data
  251. .filter((v) => v.attachmentid == attachmentid)
  252. .map((v) => {
  253. v = Object.assign(v, v.attinfos[0]);
  254. delete v.attinfos;
  255. v.cover = props.coverType
  256. ? v.subfiles.find((s) => s.type == props.coverType).url ||
  257. v.url
  258. : v.url;
  259. return v;
  260. })[0];
  261. });
  262. });
  263. });
  264. });
  265. });
  266. }
  267. /* 初始化列表 */
  268. watch(
  269. () => props.attinfos,
  270. (newVal) => {
  271. init(newVal);
  272. },
  273. () => showStyle,
  274. (newVal) => {
  275. console.log("showStyle", newVal);
  276. }
  277. );
  278. function init(attinfos, pic = props.pic) {
  279. if(!attinfos.length) return;
  280. list.value = pic ? attinfos : attinfos.filter((v) => v.fileType == "image");
  281. list.value = list.value.map((v) => {
  282. if (pic) {
  283. v = Object.assign(v, v.attinfos[0]);
  284. delete v.attinfos;
  285. }
  286. v.cover = props.coverType
  287. ? v.subfiles.find((s) => s.type == props.coverType).url || v.url
  288. : v.url;
  289. return v;
  290. });
  291. if (
  292. pic &&
  293. list.value[list.value.length - 1].sequence !=
  294. props.startSequence + list.value.length
  295. ) {
  296. setSequenceAll();
  297. }
  298. }
  299. function addImage() {
  300. console.log("添加图片");
  301. }
  302. let linksid = ref(null);
  303. async function confirmDeleteImage() {
  304. await handleDeleteImage([linksid.value]);
  305. linksid.value = null;
  306. }
  307. /* 处理删除图片 */
  308. function handleDeleteImage(linksids = [], setSequence = true) {
  309. return new Promise((resolve, reject) => {
  310. if (linksids.length) {
  311. Api.requested({
  312. id: "20240407135902",
  313. content: { linksids },
  314. }).then((res) => {
  315. console.log("删除图片", res);
  316. utils.message(res, "操作成功", async () => {
  317. list.value = list.value.filter((v) => !linksids.includes(v.linksid));
  318. //如果考虑分页情况再这个节点去重新获取数据 setSequence=false
  319. if (setSequence) await setSequenceAll();
  320. });
  321. resolve(res.code == 1);
  322. });
  323. } else {
  324. resolve();
  325. }
  326. });
  327. }
  328. /* 拖拽与显示气泡 */
  329. let startIndex = null,
  330. targetIndex = null,
  331. hovered = ref(null),
  332. prohibitHovered = false;
  333. function dragStart(index) {
  334. startIndex = index;
  335. targetIndex = index;
  336. prohibitHovered = true;
  337. hovered.value = null;
  338. }
  339. function dragOver(index) {
  340. if (targetIndex == index) return;
  341. let item = list.value.splice(targetIndex, 1);
  342. list.value.splice(index, 0, item[0]);
  343. targetIndex = index;
  344. }
  345. function dragEnd() {
  346. prohibitHovered = false;
  347. if (startIndex != targetIndex) setSequenceAll();
  348. }
  349. function setSequenceAll() {
  350. return new Promise((resolve, reject) => {
  351. Api.requested({
  352. id: "20221201134901",
  353. content: {
  354. ownertable: "sys_attachment_links",
  355. sequencesorts: list.value.map((v, i) => {
  356. return {
  357. ownerid: v.linksid,
  358. sequence: Number(props.startSequence) + i,
  359. };
  360. }),
  361. },
  362. }).then((res) => {
  363. console.log("设置排序", res);
  364. resolve(res.code == 1);
  365. });
  366. });
  367. }
  368. function handleHoverChange(visible, index) {
  369. if (prohibitHovered) return (hovered.value = null);
  370. hovered.value = visible ? index : null;
  371. }
  372. </script>
  373. <style scoped>
  374. .header {
  375. display: flex;
  376. justify-content: space-between;
  377. align-items: center;
  378. width: 100%;
  379. }
  380. .picture-wall-box {
  381. display: grid;
  382. justify-content: space-between;
  383. grid-gap: 10px;
  384. margin-top: 20px;
  385. user-select: none;
  386. }
  387. .picture-wall-box .picture-wall-item {
  388. display: flex;
  389. align-items: center;
  390. justify-content: center;
  391. border: 1px solid #d9d9d9;
  392. border-radius: 8px;
  393. box-sizing: border-box;
  394. }
  395. .previewMaskIcon {
  396. opacity: 0.6;
  397. }
  398. .previewMaskIcon:hover {
  399. opacity: 1;
  400. }
  401. .empty {
  402. width: 100%;
  403. padding: 50px 0;
  404. display: flex;
  405. justify-content: center;
  406. }
  407. </style>