图书馆综合管理系统
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.

302 lines
8.8 KiB

5 months ago
  1. <template>
  2. <div class="service-all">
  3. <div v-if="serviceTop" class="service-top-text" :class="!serviceTop ? 'false-active' : 'true-active'">AI处理终端</div>
  4. <!-- <i class="iconfont icon-zhongduanjiankong" />终端连接正常 -->
  5. <ul v-if="serviceTop" class="service-list">
  6. <li v-for="(item, index) in serviceItems" :key="index">
  7. <p :class="index <= currentIndex && item.status === 'running'? 'true-active' : 'false-active' ">
  8. {{ item.serviceName }}
  9. </p>
  10. <!-- {{ item.serviceName }} -->
  11. <!-- <i v-if="index <= currentIndex && item.status === 'running'" class="iconfont icon-shi" />
  12. <i v-else-if="index <= currentIndex" class="iconfont icon-cuowu1" /> -->
  13. </li>
  14. </ul>
  15. <div v-if="servicesDisplayed && isAllServicesRunning" class="service-bottom-text" :class="{ 'fade-in': servicesDisplayed && isAllServicesRunning }" style="color: rgb(18, 196, 122);">所有服务均正常运行请放心使用</div>
  16. <div v-else-if="servicesDisplayed && !isAllServicesRunning" class="service-bottom-text" :class="{ 'fade-in': servicesDisplayed &&!isAllServicesRunning }" style="color: #ED4A41;">请尽快联系系统维护人员进行恢复</div>
  17. <div v-if="!serviceTop" class="tip-service" :class="{ 'fade-in': !serviceTop }">
  18. <i class="iconfont icon-lianjieduankai" />
  19. <div class="tip-service-content">
  20. <p>AI处理终端连接超时请检查配置是否正确或终端是否运行成功!</p>
  21. <p>请尽快联系系统维护人员进行恢复</p>
  22. </div>
  23. </div>
  24. </div></template>
  25. <script>
  26. import crudStockTask, { FetchAITerminalStatusQuery } from '@/api/stockTask/index'
  27. import { mapGetters } from 'vuex'
  28. export default {
  29. name: 'ServeTerminal',
  30. components: { },
  31. props: {
  32. },
  33. data() {
  34. return {
  35. service: {
  36. 'service_imgCamera': { 'last_heartbeat': 1736496962.2368362, 'status': '' },
  37. 'service_imgProcess': { 'last_heartbeat': 1736496960.8598323, 'status': '' },
  38. 'service_imgYolo': { 'last_heartbeat': 1736496961.953832, 'status': '' },
  39. 'service_imgOcr': { 'last_heartbeat': 1736496961.6238313, 'status': '' },
  40. 'service_imgResult': { 'last_heartbeat': 1736496963.4378026, 'status': '' }
  41. },
  42. serviceItems: [],
  43. currentIndex: -1,
  44. timer: null,
  45. servicesDisplayed: false,
  46. serviceTop: false
  47. }
  48. },
  49. computed: {
  50. ...mapGetters([
  51. 'baseApi'
  52. ]),
  53. isAllServicesRunning() {
  54. return Object.values(this.service).every(service => service.status === 'running')
  55. }
  56. },
  57. mounted() {
  58. },
  59. methods: {
  60. initData() {
  61. crudStockTask.FetchInitSetting().then(res => {
  62. if (res) {
  63. this.handleService(res.ip)
  64. }
  65. }).catch(() => {
  66. })
  67. },
  68. handleService(ip) {
  69. this.servicesDisplayed = false
  70. FetchAITerminalStatusQuery({ 'ip': ip }).then(res => {
  71. // {
  72. // "service_imgCamera":{"last_heartbeat":1736496962.2368362,"status":"running"},
  73. // "service_imgProcess":{"last_heartbeat":1736496960.8598323,"status":"running"},
  74. // "service_imgYolo":{"last_heartbeat":1736496961.953832,"status":"running"}
  75. // "service_imgOcr":{"last_heartbeat":1736496961.6238313,"status":"running"},
  76. // "service_imgResult":{"last_heartbeat":1736496963.4378026,"status":"running"},
  77. // }
  78. if (res) {
  79. this.serviceTop = true
  80. this.service = JSON.parse(res)
  81. this.serviceItems = []
  82. const keysOrder = ['service_imgCamera', 'service_imgProcess', 'service_imgYolo', 'service_imgOcr', 'service_imgResult']
  83. keysOrder.forEach(key => {
  84. let serviceName = ''
  85. switch (key) {
  86. case 'service_imgCamera':
  87. serviceName = '图像采集'
  88. break
  89. case 'service_imgProcess':
  90. serviceName = '图像处理'
  91. break
  92. case 'service_imgYolo':
  93. serviceName = '图像识别'
  94. break
  95. case 'service_imgOcr':
  96. serviceName = '文字识别'
  97. break
  98. case 'service_imgResult':
  99. serviceName = '同步服务'
  100. break
  101. }
  102. this.serviceItems.push({
  103. serviceName: serviceName,
  104. status: this.service[key].status
  105. })
  106. })
  107. this.showServicesSequentially()
  108. } else {
  109. this.serviceTop = false
  110. }
  111. }).catch(() => {
  112. })
  113. },
  114. showServicesSequentially() {
  115. let index = 0
  116. const interval = 300
  117. this.timer = setInterval(() => {
  118. this.currentIndex = index
  119. index++
  120. if (index >= this.serviceItems.length) {
  121. clearInterval(this.timer)
  122. setTimeout(() => {
  123. this.servicesDisplayed = true
  124. }, 500)
  125. }
  126. }, interval)
  127. }
  128. }
  129. }
  130. </script>
  131. <style lang="scss" scoped>
  132. .tip-service{
  133. display: flex;
  134. justify-content: center;
  135. color: #0C0E1E;
  136. font-size: 16px;
  137. line-height: 40px;
  138. padding: 40px 0;
  139. .iconfont{
  140. font-size: 30px;
  141. margin-right: 10px;
  142. color: #ED4A41;
  143. }
  144. p{
  145. &:first-child{
  146. color: #ED4A41;
  147. }
  148. }
  149. }
  150. .service-all{
  151. position: relative;
  152. height: 230px;
  153. color: #0C0E1E;
  154. }
  155. .service-top-text{
  156. position: relative;
  157. font-size: 12px;
  158. margin: 0 65px;
  159. height: 72px;
  160. text-align: center;
  161. background: url('~@/assets/images/serve1.png') no-repeat center center;
  162. background-size: 40px auto;
  163. &.false-active{
  164. background: url('~@/assets/images/serve1-1.png') no-repeat center center;
  165. background-size: 40px auto;
  166. }
  167. &.true-active{
  168. &::before{
  169. content: "";
  170. position: absolute;
  171. left: 50%;
  172. bottom: -10px;
  173. width: 1px;
  174. height: 16px;
  175. background-color:#9098a4;
  176. margin-left: -1px;
  177. }
  178. &::after{
  179. content: "";
  180. position: absolute;
  181. left: 0;
  182. bottom: -10px;
  183. width: 100%;
  184. height: 1px;
  185. background-color: #9098a4;
  186. margin-left: -1px;
  187. }
  188. }
  189. }
  190. .service-list{
  191. display: flex;
  192. justify-content: space-between;
  193. padding: 30px 40px 10px 40px;
  194. li{
  195. position: relative;
  196. &::before{
  197. content: "";
  198. position: absolute;
  199. left: 50%;
  200. top: -20px;
  201. width: 1px;
  202. height: 10px;
  203. background-color: #9098a4;
  204. margin-left: -1px;
  205. }
  206. p{
  207. width: 50px;
  208. height: 70px;
  209. font-size: 12px;
  210. }
  211. &:nth-child(1){
  212. p{
  213. &.false-active{
  214. background: url('~@/assets/images/ter1-1.png') no-repeat center center;
  215. background-size: 36px auto;
  216. }
  217. &.true-active{
  218. background: url('~@/assets/images/ter1.png') no-repeat center center;
  219. background-size: 36px auto;
  220. }
  221. }
  222. }
  223. &:nth-child(2){
  224. p{
  225. &.false-active{
  226. background: url('~@/assets/images/ter2-1.png') no-repeat center center;
  227. background-size: 32px auto;
  228. }
  229. &.true-active{
  230. background: url('~@/assets/images/ter2.png') no-repeat center center;
  231. background-size: 32px auto;
  232. }
  233. }
  234. }
  235. &:nth-child(3){
  236. p{
  237. &.false-active{
  238. background: url('~@/assets/images/ter3-1.png') no-repeat center center;
  239. background-size: 36px auto;
  240. }
  241. &.true-active{
  242. background: url('~@/assets/images/ter3.png') no-repeat center center;
  243. background-size: 36px auto;
  244. }
  245. }
  246. }
  247. &:nth-child(4){
  248. p{
  249. &.false-active{
  250. background: url('~@/assets/images/ter4-1.png') no-repeat center center;
  251. background-size: 36px auto;
  252. }
  253. &.true-active{
  254. background: url('~@/assets/images/ter4.png') no-repeat center center;
  255. background-size: 36px auto;
  256. }
  257. }
  258. }
  259. &:nth-child(5){
  260. p{
  261. &.false-active{
  262. background: url('~@/assets/images/ter5-1.png') no-repeat center center;
  263. background-size: 36px auto;
  264. }
  265. &.true-active{
  266. background: url('~@/assets/images/ter5.png') no-repeat center center;
  267. background-size: 36px auto;
  268. }
  269. }
  270. }
  271. }
  272. }
  273. .service-bottom-text{
  274. font-size: 12px;
  275. text-align: center;
  276. }
  277. .fade-enter-active,
  278. .fade-leave-active {
  279. transition: all 0.5s ease;
  280. }
  281. .fade-enter,
  282. .fade-leave-to {
  283. opacity: 0;
  284. transform: translateY(20px);
  285. }
  286. .fade-in {
  287. animation: fadeIn 0.5s ease;
  288. }
  289. @keyframes fadeIn {
  290. from {
  291. opacity: 0;
  292. transform: translateY(20px);
  293. }
  294. to {
  295. opacity: 1;
  296. transform: translateY(0);
  297. }
  298. }
  299. </style>