图书馆综合管理系统
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

329 lines
10 KiB

  1. <template>
  2. <div class="venue-preview">
  3. <!-- v-show="currentMarkData && currentMarkData.signPoint" -->
  4. <div v-show="currentMarkData && currentMarkData.signPoint">
  5. <canvas :id="`canvasPreview${currentMarkData && currentMarkData.id}`" :width="width" :height="height" />
  6. </div>
  7. <img v-if="currentMarkData && !currentMarkData.signPoint" :src="imageUrl" :onerror="defaultImg" alt="">
  8. <div id="tooltip" class="tooltip-style">
  9. <!-- <div class="tooltip-top">
  10. <h4>区域名称</h4>
  11. <span class="update-time">2024-11-28 09:46</span>
  12. </div>
  13. <ul>
  14. <li><p>在架</p><span><i>15000</i></span></li>
  15. <li><p>错架</p><span><i>300</i></span> <span class="percentage">2.00%</span></li>
  16. <li><p>错序</p><span><i>0</i></span><span class="percentage">0.00%</span></li>
  17. </ul> -->
  18. </div>
  19. </div>
  20. </template>
  21. <script>
  22. import defaultImg from '@/assets/images/system/default-img.jpg'
  23. import { fabric } from 'fabric'
  24. import { mapGetters } from 'vuex'
  25. export default {
  26. name: 'Mark',
  27. props: {
  28. currentMarkData: {
  29. type: Object,
  30. require: true,
  31. default: function() {
  32. return {}
  33. }
  34. },
  35. imageUrl: {
  36. type: String,
  37. default: ''
  38. },
  39. pagePreview: {
  40. type: String,
  41. default: ''
  42. }
  43. },
  44. data() {
  45. return {
  46. defaultImg: defaultImg,
  47. canvasPreview: {},
  48. width: 1200,
  49. height: 600,
  50. drawWidth: 2,
  51. tooltipInfo: null
  52. }
  53. },
  54. computed: {
  55. ...mapGetters([
  56. 'user',
  57. 'baseApi'
  58. ])
  59. },
  60. watch: {
  61. width() {
  62. this.canvasPreview.setWidth(this.width)
  63. },
  64. height() {
  65. this.canvasPreview.setHeight(this.height)
  66. },
  67. currentMarkData: {
  68. handler(newVal, oldVal) {
  69. // 检查 newVal 是否为 null 或 undefined
  70. if (!newVal) {
  71. console.log('newVal-null')
  72. return
  73. }
  74. },
  75. deep: true
  76. },
  77. imageUrl(newVal, oldVal) {
  78. if (newVal !== oldVal) {
  79. console.log('imageUrl', newVal)
  80. }
  81. }
  82. },
  83. mounted() {
  84. },
  85. beforeDestroy() {
  86. // if (this.canvasPreview) {
  87. // this.canvasPreview.clear()
  88. // this.canvasPreview.dispose()
  89. // }
  90. },
  91. methods: {
  92. initCanvasPreview(drawinfo, tabIndex) {
  93. if (!this.currentMarkData) {
  94. console.error('currentMarkData-null')
  95. return
  96. }
  97. const canvasId = `canvasPreview${this.currentMarkData.id}`
  98. this.canvasPreview = new fabric.Canvas(canvasId, {
  99. skipTargetFind: false,
  100. selectable: false,
  101. selection: false
  102. })
  103. this.$nextTick(() => {
  104. this.canvasPreview.selectionColor = 'rgba(0,0,0,0.05)'
  105. this.loadDrawPreview(drawinfo, tabIndex)
  106. this.canvasPreview.on('mouse:wheel', this.mouse)
  107. })
  108. },
  109. // 鼠标滚轮放大缩小
  110. mouse(e) {
  111. if (undefined === e) return
  112. let zoom = (e.e.deltaY > 0 ? -0.1 : 0.1) + this.canvasPreview.getZoom()
  113. zoom = Math.max(0.8, zoom)
  114. // 最小为原来的1/10
  115. zoom = Math.min(3, zoom)
  116. // 最大是原来的3倍
  117. const zoomPoint = new fabric.Point(e.e.pageX, e.e.pageY)
  118. this.canvasPreview.zoomToPoint(zoomPoint, zoom)
  119. },
  120. // 回显详情信息
  121. loadDrawPreview(drawinfo, tabIndex) {
  122. const self = this
  123. const pointGroup = drawinfo.pointInfo
  124. const imgInfo = drawinfo.imgInfo
  125. imgInfo.src = self.imageUrl
  126. // 加载底图
  127. fabric.util.enlivenObjects([imgInfo], objects => {
  128. objects.forEach(o => {
  129. o.selectable = false
  130. o.hasControls = false
  131. o.centeredScaling = false
  132. self.canvasPreview.add(o)
  133. })
  134. // 处理多边形绘制回显操作
  135. pointGroup.forEach(async(item, index) => {
  136. if (item.pointInfo !== '') {
  137. const polygon = new fabric.Polygon(item.pointInfo, {
  138. id: item.id,
  139. name: item.name,
  140. floorId: item.floorId,
  141. rowType: item.rowType,
  142. toward: item.toward,
  143. floorName: item.floorName,
  144. regionName: item.regionName,
  145. stroke: 'rgba(196,43, 1, 1)',
  146. strokeWidth: self.drawWidth,
  147. fill: 'rgba(196,43, 1, 0.3)',
  148. opacity: 1,
  149. selectable: false,
  150. hasBorders: false,
  151. hasControls: false,
  152. originX: 'left', // 设置原点为左上角
  153. originY: 'top' // 设置原点为左上角
  154. })
  155. self.canvasPreview.add(polygon)
  156. let lastClickTime = 0
  157. const doubleClickInterval = 300
  158. polygon.on('mousedown', function(e) {
  159. const currentTime = new Date().getTime()
  160. const timeDiff = currentTime - lastClickTime
  161. if (timeDiff <= doubleClickInterval) {
  162. console.log('双击事件', e)
  163. lastClickTime = 0
  164. const toReigonsData = {
  165. id: e.target.id,
  166. name: e.target.name,
  167. floorId: e.target.floorId,
  168. rowType: e.target.rowType,
  169. toward: e.target.toward,
  170. regionName: e.target.regionName,
  171. floorName: e.target.floorName
  172. }
  173. if (self.pagePreview === 'floor') {
  174. self.handleToRegions(toReigonsData, tabIndex)
  175. } else if (self.pagePreview === 'region') {
  176. self.handleToShelfs(toReigonsData, tabIndex)
  177. }
  178. } else {
  179. lastClickTime = currentTime
  180. }
  181. })
  182. polygon.on('mouseover', function(e) {
  183. console.log('e', e)
  184. console.log('e.target', e.target)
  185. console.log('e.target.name', e.target.name)
  186. this.tooltipInfo = {
  187. 'id': e.target.id,
  188. 'name': e.target.name
  189. }
  190. console.log('this.tooltipInfo', this.tooltipInfo)
  191. // this.set({ opacity: 0.3, hoverCursor: 'pointer' })
  192. if (self.pagePreview === 'floor') {
  193. document.getElementById('tooltip').innerHTML =
  194. `<div class="tooltip-top">
  195. <h4>${this.tooltipInfo.name}</h4>
  196. <span class="update-time">2024-11-28 09:46</span>
  197. </div>
  198. <ul>
  199. <li><p>在架</p><span><i>15000</i></span></li>
  200. <li><p>错架</p><span><i>300</i></span> <span class="percentage">2.00%</span></li>
  201. <li><p>错序</p><span><i>0</i></span><span class="percentage">0.00%</span></li>
  202. </ul>`
  203. } else if (self.pagePreview === 'region') {
  204. document.getElementById('tooltip').innerHTML =
  205. `<div class="tooltip-top">
  206. <h4>书架概况</h4>
  207. <span class="update-time">2024-11-28 09:46</span>
  208. </div>
  209. <ul>
  210. <li><p>书架</p><span><i>${this.tooltipInfo.name}</i></span></li>
  211. <li><p>规则</p><span><i>双面6*8</i></span></li>
  212. <li><p>在架</p><span><i>15000</i></span></li>
  213. <li><p>错架</p><span><i>300</i></span> <span class="percentage">2.00%</span></li>
  214. <li><p>错序</p><span><i>0</i></span><span class="percentage">0.00%</span></li>
  215. </ul>`
  216. }
  217. var rectLeft = e.target.left + e.target.width - 100
  218. var rectTop = e.target.top + e.target.height - 40
  219. document.getElementById('tooltip').style.left = rectLeft + 'px'
  220. document.getElementById('tooltip').style.top = rectTop + 'px'
  221. document.getElementById('tooltip').style.display = 'block'
  222. self.canvasPreview.renderAll()
  223. })
  224. polygon.on('mouseout', function() {
  225. this.set({ opacity: 1 })
  226. document.getElementById('tooltip').style.display = 'none'
  227. self.canvasPreview.renderAll()
  228. })
  229. }
  230. })
  231. // 计算画布的中心点
  232. const centerX = self.canvasPreview.width / 2
  233. const centerY = self.canvasPreview.height / 2
  234. const centerPoint = new fabric.Point(centerX, centerY)
  235. // 设置画布的缩放比例为最小值并居中显示
  236. self.canvasPreview.zoomToPoint(centerPoint, 0.8)
  237. self.canvasPreview.renderAll()
  238. setTimeout(() => {
  239. self.$parent.prewLoading = false
  240. }, 500)
  241. })
  242. },
  243. handleToRegions(data, tabIndex) {
  244. this.$router.push({ path: '/dataScreening/regions' })
  245. localStorage.setItem('dataScreenFloor', JSON.stringify(data))
  246. localStorage.setItem('dataScreenFloorTableIndex', tabIndex)
  247. },
  248. handleToShelfs(data, tabIndex) {
  249. this.$router.push({ path: '/dataScreening/shelf' })
  250. localStorage.setItem('dataScreenRegion', JSON.stringify(data))
  251. localStorage.setItem('dataScreenRegionTableIndex', tabIndex)
  252. }
  253. }
  254. }
  255. </script>
  256. <style>
  257. .tooltip-style{
  258. display:none;
  259. position:absolute;
  260. width: 300px;
  261. background:rgba(0,0,0,.6);
  262. color: #fff;
  263. border-radius: 6px;
  264. }
  265. .tooltip-top{
  266. display: flex;
  267. justify-content: space-between;
  268. align-items: center;
  269. height: 40px;
  270. line-height: 40px;
  271. padding: 0 10px;
  272. border-bottom: 1px solid #fff;
  273. }
  274. .tooltip-top span{
  275. font-size: 12px;
  276. }
  277. #tooltip ul{
  278. padding: 10px;
  279. }
  280. #tooltip ul li{
  281. display: flex;
  282. justify-content: flex-start;
  283. align-items: center;
  284. line-height: 36px;
  285. font-style: normal;
  286. }
  287. #tooltip ul li p{
  288. width: 80px;
  289. font-weight: bold;
  290. text-align: right;
  291. }
  292. #tooltip ul li span{
  293. width: 100px;
  294. display: block;
  295. text-align: right;
  296. }
  297. #tooltip ul li i{
  298. font-style: normal;
  299. font-weight: bold;
  300. padding: 0 10px;
  301. color: #0348f3;
  302. }
  303. #tooltip ul li span.percentage{
  304. width: auto;
  305. }
  306. </style>
  307. <style lang="scss" scoped>
  308. #expImg{
  309. display: none;
  310. }
  311. .venue-preview{
  312. background-color: #e8f2ff;
  313. }
  314. </style>