FinishProtocol.vue 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. <script setup lang="ts">
  2. import { onMounted } from 'vue';
  3. import { message } from 'ant-design-vue';
  4. import SvgIcon from '@/components/SvgIcon.vue';
  5. import { useRequest } from '@/hooks/request';
  6. import { t } from '@/i18n';
  7. import { downloadUserProtocol } from '@/api';
  8. import { downloadBlob } from '@/utils';
  9. import type { SetupProtocolForm, UseGuideStepItemProps } from '@/types';
  10. const props = defineProps<UseGuideStepItemProps<SetupProtocolForm>>();
  11. let fileName = '';
  12. onMounted(() => {
  13. const { protocolType, protocolName } = props.form.protocolInfo;
  14. fileName = `${protocolType} - ${protocolName}.xlsx`;
  15. });
  16. const { handleRequest } = useRequest();
  17. const downloadProtocol = () => {
  18. handleRequest(async () => {
  19. const { id } = props.form.protocolInfo;
  20. if (id) {
  21. const file = await downloadUserProtocol(id);
  22. downloadBlob(file, fileName);
  23. message.success(t('setupProtocol.downloadProtocolSuccessful', { name: fileName }));
  24. }
  25. });
  26. };
  27. </script>
  28. <template>
  29. <div class="finish-container">
  30. <div class="finish-bg">
  31. <div class="finish-circle">
  32. <div class="circle-first-line"></div>
  33. <div class="circle-second-line"></div>
  34. </div>
  35. <div class="finish-desktop">
  36. <div class="desktop-header">
  37. <span class="desktop-header-dot" v-for="i in 3" :key="i"></span>
  38. </div>
  39. <div class="desktop-content">
  40. <div class="desktop-content-item" v-for="i in 3" :key="i">
  41. <div class="desktop-content-item-check">
  42. <SvgIcon class="desktop-content-check-icon" name="check" />
  43. </div>
  44. <div class="desktop-content-item-right">
  45. <li class="desktop-content-item-line" v-for="i in 2" :key="i"></li>
  46. </div>
  47. </div>
  48. </div>
  49. </div>
  50. <div class="finish-mobile">
  51. <div class="mobile-header"></div>
  52. <div class="mobile-content">
  53. <div class="mobile-content-item">
  54. <li class="mobile-content-item-line" v-for="i in 3" :key="i"></li>
  55. </div>
  56. <SvgIcon class="mobile-content-check-icon" name="check-circle" />
  57. </div>
  58. </div>
  59. </div>
  60. <div class="finish-tip">{{ $t('setupProtocol.protocolConfigCompleted') }}</div>
  61. <AButton class="finish-button" type="primary" @click="downloadProtocol">
  62. {{ $t('setupProtocol.downloadProtocolToLocal') }}
  63. </AButton>
  64. </div>
  65. </template>
  66. <style lang="scss" scoped>
  67. .modal-guidance-modal {
  68. .finish-container {
  69. margin-top: 50px;
  70. }
  71. }
  72. .finish-container {
  73. display: flex;
  74. flex-direction: column;
  75. align-items: center;
  76. margin-top: 149px;
  77. }
  78. .finish-bg {
  79. position: relative;
  80. width: 302px;
  81. height: 232px;
  82. }
  83. .finish-circle {
  84. position: absolute;
  85. top: 0;
  86. right: 0;
  87. width: 201px;
  88. height: 201px;
  89. background-color: var(--antd-color-primary-bg);
  90. border: 1px solid var(--antd-color-primary-border);
  91. border-radius: 50%;
  92. }
  93. .circle-first-line {
  94. position: absolute;
  95. top: 38px;
  96. left: 135px;
  97. width: 13.04px;
  98. height: 1px;
  99. background-color: var(--antd-color-primary);
  100. transform: rotate(-58deg);
  101. }
  102. .circle-second-line {
  103. position: absolute;
  104. top: 45px;
  105. left: 142px;
  106. width: 15.65px;
  107. height: 1px;
  108. background-color: var(--antd-color-primary);
  109. transform: rotate(-26.57deg);
  110. }
  111. .finish-desktop {
  112. position: absolute;
  113. top: 48px;
  114. left: 0;
  115. }
  116. .desktop-header {
  117. display: flex;
  118. align-items: center;
  119. width: 240px;
  120. height: 22px;
  121. padding-left: 16px;
  122. background-color: var(--antd-color-primary);
  123. border-top-left-radius: 8px;
  124. border-top-right-radius: 8px;
  125. }
  126. .desktop-header-dot {
  127. width: 6px;
  128. height: 6px;
  129. background-color: white;
  130. border-radius: 50%;
  131. & + & {
  132. margin-left: 6px;
  133. }
  134. }
  135. .desktop-content {
  136. width: 240px;
  137. padding: 12px;
  138. background-color: #fafafa;
  139. border: 1px solid var(--antd-color-primary);
  140. border-bottom-right-radius: 8px;
  141. border-bottom-left-radius: 8px;
  142. }
  143. .desktop-content-item {
  144. display: flex;
  145. align-items: center;
  146. height: 36px;
  147. padding: 6px;
  148. padding-right: 12px;
  149. background: #fff;
  150. border: 1px solid #d9dbe2;
  151. border-radius: 4px;
  152. & + & {
  153. margin-top: 8px;
  154. }
  155. }
  156. .desktop-content-item-check {
  157. display: flex;
  158. align-items: center;
  159. justify-content: center;
  160. width: 24px;
  161. height: 24px;
  162. margin-right: 8px;
  163. background-color: var(--antd-color-primary-bg-hover);
  164. border: 1px solid var(--antd-color-primary);
  165. border-radius: 4px;
  166. }
  167. .desktop-content-check-icon {
  168. font-size: 11px;
  169. font-weight: bold;
  170. color: var(--antd-color-primary);
  171. }
  172. .desktop-content-item-right {
  173. flex: 1;
  174. }
  175. .desktop-content-item-line {
  176. height: 3px;
  177. background-color: var(--antd-color-primary-bg-hover);
  178. border-radius: 2px;
  179. & + & {
  180. margin-top: 6px;
  181. }
  182. &:last-child {
  183. width: 109.2px;
  184. }
  185. }
  186. .finish-mobile {
  187. position: absolute;
  188. right: 38px;
  189. bottom: 0;
  190. width: 99px;
  191. height: 117px;
  192. padding: 12px 8px;
  193. background-color: rgb(255 255 255 / 10%);
  194. backdrop-filter: blur(4px);
  195. border: 1px solid var(--antd-color-primary);
  196. border-radius: 8px;
  197. }
  198. .mobile-header {
  199. height: 24px;
  200. margin-bottom: 8px;
  201. background-color: var(--antd-color-primary-border-hover);
  202. border-radius: 4px;
  203. }
  204. .mobile-content {
  205. text-align: center;
  206. }
  207. .mobile-content-item-line {
  208. height: 3px;
  209. background-color: var(--antd-color-primary-bg-hover);
  210. border-radius: 1px;
  211. & + & {
  212. margin-top: 8px;
  213. }
  214. &:last-child {
  215. width: 56px;
  216. }
  217. }
  218. .mobile-content-check-icon {
  219. margin-top: 12px;
  220. font-size: 24px;
  221. color: var(--antd-color-primary);
  222. }
  223. .finish-tip {
  224. margin-top: 16px;
  225. margin-bottom: 40px;
  226. font-size: 16px;
  227. line-height: 32px;
  228. color: var(--antd-color-text);
  229. }
  230. .finish-button {
  231. width: 160px;
  232. height: 40px;
  233. }
  234. </style>