index.vue 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. <template>
  2. <div
  3. v-loading="loading"
  4. class="l-flex--col"
  5. >
  6. <template v-if="!loading">
  7. <warning
  8. v-if="error"
  9. @click="getDefaults"
  10. />
  11. <template v-else>
  12. <template v-if="isSuperAdmin || info">
  13. <tabs
  14. :items="tabs"
  15. :active.sync="active"
  16. />
  17. <keep-alive>
  18. <component
  19. :is="activeComponent"
  20. class="l-flex__fill"
  21. :info="info"
  22. @change="getDefaults"
  23. />
  24. </keep-alive>
  25. </template>
  26. <template v-else>
  27. <div class="l-flex__fill l-flex--row center u-color--info">
  28. <div class="l-flex--col center">
  29. <div class="has-padding">未绑定接收卡,请联系管理员</div>
  30. </div>
  31. </div>
  32. </template>
  33. </template>
  34. </template>
  35. </div>
  36. </template>
  37. <script>
  38. import { mapGetters } from 'vuex'
  39. import { getReceivingCard } from '@/api/external'
  40. import Tabs from '@/views/device/detail/components/Tabs'
  41. import ReceivingCardTopology from './ReceivingCardTopology'
  42. import ReceivingCardInfo from './ReceivingCardInfo'
  43. import ReceivingCardInfoEdit from './ReceivingCardInfoEdit'
  44. export default {
  45. name: 'ReceivingCard',
  46. components: {
  47. Tabs,
  48. ReceivingCardTopology,
  49. ReceivingCardInfo,
  50. ReceivingCardInfoEdit
  51. },
  52. props: {
  53. device: {
  54. type: Object,
  55. required: true
  56. }
  57. },
  58. data () {
  59. return {
  60. active: 'topology',
  61. tabs: [
  62. { key: 'topology', name: '接收卡状态监测' },
  63. { key: 'info', name: '接收卡信息' }
  64. ],
  65. loading: false,
  66. error: false,
  67. info: null
  68. }
  69. },
  70. computed: {
  71. ...mapGetters(['isSuperAdmin']),
  72. activeComponent () {
  73. switch (this.active) {
  74. case 'topology':
  75. return 'ReceivingCardTopology'
  76. case 'info':
  77. return this.isSuperAdmin ? 'ReceivingCardInfoEdit' : 'ReceivingCardInfo'
  78. default:
  79. return null
  80. }
  81. }
  82. },
  83. activated () {
  84. this.getDefaults()
  85. },
  86. methods: {
  87. getDefaults () {
  88. if (this.loading) {
  89. return
  90. }
  91. this.info = null
  92. this.loading = true
  93. this.error = false
  94. getReceivingCard(this.device.id).then(
  95. ({ data }) => {
  96. if (data?.topology) {
  97. data.topology = JSON.parse(data.topology)
  98. }
  99. this.info = data
  100. },
  101. () => {
  102. this.error = true
  103. }
  104. ).finally(() => {
  105. this.loading = false
  106. })
  107. }
  108. }
  109. }
  110. </script>
  111. <style lang="scss" scoped>
  112. .c-card-grid {
  113. display: grid;
  114. overflow: auto;
  115. &.empty {
  116. position: relative;
  117. background: url("~@/assets/screen.png") 0 0 / 96px 96px repeat;
  118. &::after {
  119. content: "未录入";
  120. display: inline-flex;
  121. justify-content: center;
  122. align-items: center;
  123. position: absolute;
  124. top: 50%;
  125. left: 50%;
  126. width: 200px;
  127. height: 64px;
  128. color: #fff;
  129. font-size: 18px;
  130. letter-spacing: 6px;
  131. background-color: rgba($info--dark, 0.8);
  132. transform: translate(-50%, -50%);
  133. }
  134. }
  135. }
  136. .o-receiving-card {
  137. position: relative;
  138. display: inline-flex;
  139. justify-content: center;
  140. align-items: center;
  141. color: $info;
  142. background: url("~@/assets/screen.png") 0 0 / 100% 100% no-repeat;
  143. &.normal,
  144. &.error {
  145. color: $success--dark;
  146. }
  147. &::after {
  148. content: attr(status);
  149. position: absolute;
  150. top: 0;
  151. right: 0;
  152. width: 40px;
  153. padding: 4px 0;
  154. color: #fff;
  155. font-size: 12px;
  156. line-height: 1;
  157. text-align: center;
  158. background-color: $info;
  159. transform-origin: top right;
  160. transform: scale(0.8);
  161. }
  162. &.normal::after {
  163. background-color: $black;
  164. }
  165. &.error::after {
  166. background-color: $error;
  167. }
  168. &__status {
  169. display: inline-flex;
  170. justify-content: center;
  171. align-items: center;
  172. width: 36px;
  173. height: 36px;
  174. padding-bottom: 4px;
  175. color: $black;
  176. font-size: 14px;
  177. font-weight: bold;
  178. background: url("~@/assets/icon_card_unknown.png") 0 0 / 100% 100% no-repeat;
  179. }
  180. &.normal {
  181. .o-receiving-card__status {
  182. color: $error;
  183. background-image: url("~@/assets/icon_card_normal.png");
  184. }
  185. }
  186. &.error {
  187. .o-receiving-card__status {
  188. background-image: url("~@/assets/icon_card_abnormal.png");
  189. }
  190. }
  191. &__arrow {
  192. position: absolute;
  193. z-index: 1;
  194. &.left {
  195. transform: rotate(-90deg);
  196. }
  197. &.right {
  198. transform: rotate(90deg);
  199. }
  200. &.bottom {
  201. transform: rotate(180deg);
  202. }
  203. &::before {
  204. content: "";
  205. position: absolute;
  206. left: 50%;
  207. bottom: 20px;
  208. width: 6px;
  209. height: 46px;
  210. background-color: currentColor;
  211. transform: translateX(-50%);
  212. }
  213. &::after {
  214. content: "";
  215. position: absolute;
  216. left: 50%;
  217. bottom: 66px;
  218. border-left: 10px solid transparent;
  219. border-right: 10px solid transparent;
  220. border-bottom: 10px solid currentColor;
  221. transform: translateX(-50%);
  222. }
  223. }
  224. }
  225. </style>