JointDuty.vue 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. <template>
  2. <div class="duty-card">
  3. <div class="common-title gradient-text">联合值守</div>
  4. <div class="more-btn" @click="handleShowQrCode">
  5. <div class="code-icon"></div>
  6. <div class="text">签到码</div>
  7. </div>
  8. <div class="card-content">
  9. <div class="custom-table">
  10. <div class="table-header">
  11. <div class="td">值守单位</div>
  12. <div class="td">值守人员</div>
  13. <div class="td2">联系方式</div>
  14. </div>
  15. <div class="table-content">
  16. <div v-for="(item, index) in listData" :key="index" class="tr">
  17. <div class="td">{{ item.dept_name }}</div>
  18. <div class="td">
  19. <div>{{ item.nick_name }}({{ item.duties }})</div>
  20. </div>
  21. <div class="td2 text">
  22. <div class="phone-btn"></div>
  23. {{ item.phone }}
  24. </div>
  25. </div>
  26. </div>
  27. </div>
  28. </div>
  29. </div>
  30. <Dialog v-model="showQrCode" title="签到码" type="sm" hide-footer>
  31. <div style="display: flex; flex-direction: column; justify-content: center; align-items: center; width: 100%; height: 100%">
  32. <div id="qrCodeBox" style="display: flex; flex-direction: column; justify-content: center; align-items: center">
  33. <div class="print-title" style="margin: 30px 0; color: #ffffff">请联合值守人员通过粤政易扫描二维码进行签到、签退</div>
  34. <img :src="qrCodeUrl" alt="" style="width: 800px; height: 800px" />
  35. </div>
  36. <div class="flex" style="margin-top: 20px">
  37. <div class="common-btn-primary" v-print="printObj">打印</div>
  38. <div class="common-btn-primary" @click="handleDownLoad">下载</div>
  39. </div>
  40. </div>
  41. </Dialog>
  42. </template>
  43. <script lang="ts" setup>
  44. import { getCheckinList } from '@/api/emergencyCommandMap/JointDuty';
  45. import print from 'vue3-print-nb';
  46. directives: {
  47. print;
  48. }
  49. const route = useRoute();
  50. const listData = ref([]);
  51. let eventId = ref('');
  52. let qrCodeUrl = ref('');
  53. let printObj = reactive({
  54. id: 'qrCodeBox', // 这里是要打印元素的ID
  55. popTitle: '',
  56. extraCss: '/print.css'
  57. });
  58. const showQrCode = ref(false);
  59. const handleShowQrCode = () => {
  60. showQrCode.value = true;
  61. };
  62. const base64ToBlob = (code) => {
  63. let parts = code.split(';base64,');
  64. let contentType = parts[0].split(':')[1];
  65. let raw = window.atob(parts[1]);
  66. let rawLength = raw.length;
  67. let uInt8Array = new Uint8Array(rawLength);
  68. for (let i = 0; i < rawLength; ++i) {
  69. uInt8Array[i] = raw.charCodeAt(i);
  70. }
  71. return new Blob([uInt8Array], { type: contentType });
  72. };
  73. // 下载
  74. const handleDownLoad = () => {
  75. let image = new Image();
  76. image.crossOrigin = '';
  77. image.src = qrCodeUrl.value;
  78. image.onload = () => {
  79. let canvas = document.createElement('canvas');
  80. canvas.width = 370;
  81. canvas.height = 370;
  82. let ctx = canvas.getContext('2d');
  83. ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
  84. let dataUrl = canvas.toDataURL();
  85. const a = document.createElement('a');
  86. a.href = dataUrl;
  87. a.download = '签到码.png';
  88. document.body.appendChild(a);
  89. a.click();
  90. document.body.removeChild(a);
  91. };
  92. };
  93. onMounted(() => {
  94. eventId.value = route.query.event_id as string;
  95. listData.value = [
  96. {
  97. dept_name: '市应急局',
  98. nick_name: '张平安',
  99. phone: '13856642378',
  100. duties: '职务'
  101. },
  102. {
  103. dept_name: '市应急局',
  104. nick_name: '张平安',
  105. phone: '13856642378',
  106. duties: '职务'
  107. },
  108. {
  109. dept_name: '市应急局',
  110. nick_name: '张平安',
  111. phone: '13856642378',
  112. duties: '职务'
  113. },
  114. {
  115. dept_name: '市应急局',
  116. nick_name: '张平安',
  117. phone: '13856642378',
  118. duties: '职务'
  119. },
  120. {
  121. dept_name: '市应急局',
  122. nick_name: '张平安',
  123. phone: '13856642378',
  124. duties: '职务'
  125. },
  126. {
  127. dept_name: '市应急局',
  128. nick_name: '张平安',
  129. phone: '13856642378',
  130. duties: '职务'
  131. }
  132. ];
  133. // getCheckinList(eventId.value).then((res) => {
  134. // listData.value = res.data;
  135. // });
  136. qrCodeUrl.value = import.meta.env.VITE_APP_BASE_API2 + 'api/event_management/checkin/qrcode?event_id=' + eventId.value;
  137. });
  138. </script>
  139. <style lang="scss" scoped>
  140. .duty-card {
  141. width: 529px;
  142. height: 223px;
  143. background: url('@/assets/images/emergencyCommandMap/duty/dutyBg.png') no-repeat;
  144. background-size: 100% 100%;
  145. position: relative;
  146. color: #fff;
  147. animation-name: slideRight;
  148. animation-duration: 2s;
  149. .card-content {
  150. display: flex;
  151. flex-wrap: wrap;
  152. padding-top: 47px;
  153. height: 223px;
  154. }
  155. }
  156. .search-box {
  157. display: flex;
  158. width: 100%;
  159. justify-content: space-between;
  160. align-items: center;
  161. }
  162. .more-btn {
  163. position: absolute;
  164. top: 14px;
  165. right: 52px;
  166. color: #eaf3fc;
  167. font-size: 14px;
  168. cursor: pointer;
  169. z-index: 2;
  170. display: flex;
  171. align-items: center;
  172. .text {
  173. margin-top: -3px;
  174. }
  175. .code-icon {
  176. width: 35px;
  177. height: 35px;
  178. background: url('@/assets/images/emergencyCommandMap/duty/code.png') no-repeat;
  179. background-size: 100% 100%;
  180. }
  181. }
  182. .custom-table {
  183. width: 100%;
  184. margin-top: 10px;
  185. .table-header {
  186. display: flex;
  187. width: 520px;
  188. height: 21px;
  189. background: url('@/assets/images/emergencyCommandMap/duty/header.png') no-repeat;
  190. background-size: 100% 100%;
  191. font-size: 16px;
  192. padding: 0 13px;
  193. .td {
  194. flex: 1;
  195. }
  196. .td2 {
  197. width: 155px;
  198. text-align: center;
  199. }
  200. }
  201. .table-content {
  202. height: 130px;
  203. overflow-y: auto;
  204. .tr {
  205. display: flex;
  206. align-items: center;
  207. width: 520px;
  208. height: 21px;
  209. background-color: rgba(44, 129, 255, 0.1);
  210. //background: url('@/assets/images/emergencyCommandMap/duty/tr.png') no-repeat;
  211. //background-size: 100% 100%;
  212. font-size: 14px;
  213. margin-top: 12px;
  214. padding: 0 15px;
  215. }
  216. .td {
  217. flex: 1;
  218. }
  219. .td2 {
  220. width: 155px;
  221. text-align: center;
  222. position: relative;
  223. .phone-btn {
  224. position: absolute;
  225. top: -12px;
  226. left: 0;
  227. cursor: pointer;
  228. width: 49px;
  229. height: 49px;
  230. background: url('@/assets/images/emergencyCommandMap/duty/phone.png') no-repeat;
  231. background-size: 100% 100%;
  232. }
  233. }
  234. .text {
  235. color: #08d9ff;
  236. font-family: 'BEBAS-1';
  237. }
  238. }
  239. }
  240. </style>