feat: terminal日志相关

This commit is contained in:
chenjinsong
2021-02-20 18:51:51 +08:00
parent eb2a7bcd85
commit 700eecaf85
14 changed files with 713 additions and 530 deletions

View File

@@ -20,6 +20,39 @@ Created by iconfont
/>
<missing-glyph />
<glyph glyph-name="fast-forward" unicode="&#59130;" d="M170.08082177-39.14113205000001C136.50949938-39.14113205000001 120.80526686-1.62024150000002 120.80526686 31.38685650000002V736.66674459C120.80526686 772.68303734 137.92005867 807.19473315 170.08082177 807.19473315c12.50696323-0.94037342 24.54373978-4.9839776 34.88784483-11.9427397l557.35918571-352.63994361a70.33991404 70.33991404 0 0 0 35.5461069-61.03021926 70.33991404 70.33991404 0 0 0-35.5461069-61.03022008L202.1475472-32.088333120000016a64.13345084 64.13345084 0 0 0-32.06672543-6.95876128zM621.45994971-39.14113205000001c-33.5713224 0-49.2755549 37.42685289-49.27555491 70.52798856V736.66674459c0 36.01629275 17.11479181 70.52798856 49.27555491 70.52798856 12.50696323-0.94037342 24.54373978-4.9839776 34.88784483-11.9427397l557.35918572-352.63994361a70.33991404 70.33991404 0 0 0 35.54610688-61.03021926 70.33991404 70.33991404 0 0 0-35.54610688-61.03022008l-560.18030513-352.63994362a64.13345084 64.13345084 0 0 0-32.06672542-6.95876128z" horiz-adv-x="1365" />
<glyph glyph-name="replay" unicode="&#59121;" d="M230.26081622 205.72049206999998l125.72164273 182.98336441a15.88397269 15.88397269 0 0 1-13.18369679 24.69957716h-78.14914534A333.56342394 333.56342394 0 0 0 549.29040543 713.37225613a335.54892053 335.54892053 0 0 0 360.32791752-204.90324669A330.62488941 330.62488941 0 0 0 792.15634589 113.59345166000003a337.53441712 337.53441712 0 0 0-380.18288338-4.84461214 46.85771893 46.85771893 0 0 1-62.90053127-10.0863226 46.06352064 46.06352064 0 0 1 11.03936054-66.71268479 431.88521445 431.88521445 0 0 1 491.92663102 9.37154413 423.06960999 423.06960999 0 0 1 142.63807405 508.28712268C917.63972912 731.32114523 724.80830247 836.71130312 528.7206611 804.30799911c-196.00822152-32.48272385-343.96742585-194.18156461-357.38938298-390.90456547H91.03779655a15.88397269 15.88397269 0 0 1-13.18369765-24.62015734L203.97284163 205.72049206999998a15.96339252 15.96339252 0 0 1 26.28797459 0z" horiz-adv-x="1117" />
<glyph glyph-name="play" unicode="&#59123;" d="M213.36854709-52.78764302000002C178.68528487-52.78764302000002 162.52305909-14.085664749999978 162.52305909 20.160781179999958V748.07247933C162.52305909 785.20191632 180.17046204 820.84617615 213.36854709 820.84617615c12.92978081-0.87363348 25.33538117-5.24180258 36.081077-12.40560038L824.73749408 444.4847267c22.71447903-13.10450733 36.69262068-37.04207374 36.69261983-62.90163448 0-26.03428812-13.9781408-50.0592178-36.69261983-63.07636187L246.39190562-45.44911870999999a66.22144358 66.22144358 0 0 0-33.19808506-7.25116021z" horiz-adv-x="1024" />
<glyph glyph-name="suspend" unicode="&#59128;" d="M207.96632006 820.84617615m87.36923523 0l0 0q87.36923523 0 87.36923523-87.36923524l0-698.95388182q0-87.36923523-87.36923523-87.36923524l0 0q-87.36923523 0-87.36923523 87.36923524l0 698.95388182q0 87.36923523 87.36923523 87.36923524ZM644.81249621 820.84617615m87.36923523 0l0 0q87.36923523 0 87.36923522-87.36923524l0-698.95388182q0-87.36923523-87.36923522-87.36923524l0 0q-87.36923523 0-87.36923523 87.36923524l0 698.95388182q0 87.36923523 87.36923523 87.36923524Z" horiz-adv-x="1024" />
<glyph glyph-name="drop-down" unicode="&#59120;" d="M86.7501044 722.52498402l433.03370011-418.33978344a40.11042154 40.11042154 0 0 1 59.01394754 0L1011.75202551 722.52498402a37.17163787 37.17163787 0 0 1 0.23827997 53.93064588 40.42812817 40.42812817 0 0 1-55.8368839 0.23827997l-0.23827996-0.23827997L549.33049118 383.53235134 142.74584159 776.53505655A40.42812817 40.42812817 0 0 1 86.90895771 776.77333652a37.17163787 37.17163787 0 0 1-0.23827997-54.01007254l0.07942666-0.23827996zM1014.37310257 481.30646813a40.50755481 40.50755481 0 0 1-55.83688389 0L551.55443582 88.22433625999997 144.89035872 481.30646813a40.42812817 40.42812817 0 0 1-55.91631054 0.15885331 37.33049118 37.33049118 0 0 1-0.15885331-53.93064588l0.15885331-0.15885331L522.32545492 8.877185510000004l1.50910473-1.66795805a39.71328913 39.71328913 0 0 1 55.83688475 0l1.50910474 1.58853139 433.03370012 418.49863674a37.17163787 37.17163787 0 0 1 0.15885331 53.93064588z" horiz-adv-x="1117" />
<glyph glyph-name="replay2" unicode="&#59122;" d="M511.99927221-52.84617615000002A437.42771482 437.42771482 0 0 0 75.15382385 383.99927220999996v33.98980732a26.78425915 26.78425915 0 0 0 26.78425915 26.78425915h2.18349968a32.38857496 32.38857496 0 0 0 31.00569147-33.69867408v-26.78425917a377.67261424 377.67261424 0 0 1 377.67261424-377.67261422A377.89096395 377.89096395 0 1 1 253.25459267 658.5379307000001l-26.78426-26.78425915 89.23234236-24.67354301a20.88881098 20.88881098 0 0 0 14.41109633-25.11024328 19.57871101 19.57871101 0 0 0-18.99644454-14.77501308h-5.09483201L146.62703814 611.9566099900001a16.88572837 16.88572837 0 0 0-11.71811371 21.39829476l11.49976315 42.86937135L178.50612931 799.1552934a16.88572837 16.88572837 0 0 0 17.1768616 12.59151257h4.51256555a18.19582835 18.19582835 0 0 0 12.59151339-21.98056039L183.09147837 678.91725874l50.94831921 42.28710574a436.84544836 436.84544836 0 1 0 277.95947463-774.05054063zM436.74132589 231.59101312999996c-12.5915134 0-18.48696159 14.19274576-18.4869616 26.78426v267.84259415c0 13.68326281 6.40493198 26.78425915 18.4869616 26.78425915a26.78425915 26.78425915 0 0 0 13.10099635-4.51256554l209.17924381-133.92129664a26.78425915 26.78425915 0 0 0 0-46.36297101l-210.27099323-133.9212975a23.87292683 23.87292683 0 0 0-12.00924694-2.69298261z" horiz-adv-x="1024" />
<glyph glyph-name="JC" unicode="&#59124;" d="M510.45038204 506.72575677a123.79044134 123.79044134 0 0 1 0-247.58088267 123.79044134 123.79044134 0 0 1 0 247.58088267z m0-191.33885552a67.54841419 67.54841419 0 0 0 0 135.02435114 67.54841419 67.54841419 0 0 0 0-135.02435114z m406.52259184 95.66942775h-30.07788906a377.02451795 377.02451795 0 0 1-109.51250376 239.31852342A376.15479561 376.15479561 0 0 1 538.35396481 760.1772633200001V790.25515153a28.12101357 28.12101357 0 1 1-56.09707356 0v-30.07788821A376.15479561 376.15479561 0 0 1 243.44570666 650.44732878 377.02451795 377.02451795 0 0 1 133.93320206 411.056329H103.34797589a28.12101357 28.12101357 0 0 1 0-56.24202715H134.00567927A377.02451795 377.02451795 0 0 1 243.44570666 115.49577843999998a376.15479561 376.15479561 0 0 1 238.88366181-109.80241177v-28.91825869a28.12101357 28.12101357 0 1 1 56.16955078 0v28.91825869a376.15479561 376.15479561 0 0 1 238.88366181 109.80241177 377.02451795 377.02451795 0 0 1 109.51250376 239.31852341h30.07788906a28.12101357 28.12101357 0 0 1 0 56.24202715zM538.42644204 62.152824630000055V127.67188696000005a28.12101357 28.12101357 0 1 1-56.16955079 0v-65.5915387a322.23202747 322.23202747 0 0 0-292.08166204 292.66147638h68.49061373a28.12101357 28.12101357 0 0 1 0 56.24202715h-68.41813653a322.23202747 322.23202747 0 0 0 291.93670848 292.589v-63.41723412a28.12101357 28.12101357 0 1 1 56.09707357 0v63.48971134a322.23202747 322.23202747 0 0 0 292.22661563-292.66147722h-68.99795086a28.12101357 28.12101357 0 0 1 0-56.24202715h68.99795086a322.23202747 322.23202747 0 0 0-292.08166205-292.66147638z" horiz-adv-x="1024" />
<glyph glyph-name="A-" unicode="&#59125;" d="M417.66990745 820.84617615h144.76410199l321.18275026-833.83853948H746.98471736L668.75564795 201.93595533999996H310.20574812l-78.22906941-214.92831867H96.48715719L417.66990745 820.84617615zM348.71541853 307.04786608999996H630.11156287L492.33699969 684.28134071h-4.63729025L348.84983319 307.04786608999996h-0.13441466z m599.08412519 377.56951001H1171.8008213V595.03030696h-358.41548516V684.6173761h134.41420758z" horiz-adv-x="1260" />
<glyph glyph-name="A" unicode="&#59126;" d="M421.28438951 785.86139981h140.2402238l311.14578932-807.78108513H740.30811161L664.52370062 186.29212340000004H317.17848516l-75.78441099-208.21180872H110.13860019L421.28438951 785.86139981zM354.48472837 288.11928693000004H627.0872432L493.61813512 653.56421547h-4.49237493L354.61494257 288.11928693000004h-0.1302142z m580.36274628 365.77046283v130.21376442H1021.6349487v-130.21376442h130.21376359V567.1022765299999h-130.21376359v-130.21376443h-86.78747405v130.21376443h-130.2137636V653.88974976h130.2137636z" horiz-adv-x="1260" />
<glyph glyph-name="terminal-log" unicode="&#59127;" d="M593.90865802 33.759595880000006H129.75959587c-32.76346322 0-54.60577202 21.8423088-54.60577202 54.60577202v655.26926422C75.15382385 776.39809534 96.99613266 798.24040414 129.75959587 798.24040414H730.42308807c32.76346322 0 54.60577202-21.8423088 54.60577203-54.60577202v-294.87116889H730.42308807V743.63463212H129.75959587v-655.26926422h409.54329014l54.60577202-54.60577202zM703.12020206 416.00000001c103.75096683 0 191.12020206-87.36923523 191.12020207-191.12020206s-87.36923523-191.12020206-191.12020207-191.12020207S512 121.12883111999997 512 224.87979795 599.36923523 416.00000001 703.12020206 416.00000001z m0 54.60577202A244.70666606 244.70666606 0 0 1 457.39422798 224.87979795C457.39422798 88.36536790000002 566.60577202-20.84617614000001 703.12020206-20.84617614000001S948.84617615 88.36536790000002 948.84617615 224.87979795 839.63463211 470.60577203 703.12020206 470.60577203z m-491.45194816 109.21154403h436.84617615c16.38173161 0 27.30288601-10.9211544 27.30288601-27.302886s-10.9211544-27.30288601-27.30288601-27.30288601h-436.84617615c-16.38173161 0-27.30288601 10.9211544-27.30288601 27.30288601s10.9211544 27.30288601 27.30288601 27.302886z m0-163.81731605h218.42308807c16.38173161 0 27.30288601-10.9211544 27.30288602-27.30288601s-10.9211544-27.30288601-27.30288602-27.30288601h-218.42308807c-16.38173161 0-27.30288601 10.9211544-27.30288601 27.30288601S195.28652229 416.00000001 211.6682539 416.00000001z m0-163.81731606h163.81731605c16.38173161 0 27.30288601-10.9211544 27.30288601-27.302886S391.86730157 197.57691193999995 375.48556995 197.57691193999995h-163.81731605C195.28652229 197.57691193999995 184.36536789 208.49806633000003 184.36536789 224.87979795s10.9211544 27.30288601 27.30288601 27.302886z m611.5846466-87.36923522h-87.36923522c-32.76346322 0-54.60577202 21.8423088-54.60577202 54.60577201V334.09134199000005c0 16.38173161 10.9211544 27.30288601 27.30288601 27.302886s27.30288601-10.9211544 27.30288601-27.302886v-120.13269845h87.36923522c10.9211544 0 21.8423088-10.9211544 21.84230882-21.84230881s-10.9211544-27.30288601-21.84230882-27.302886z" horiz-adv-x="1024" />
<glyph glyph-name="ZD" unicode="&#59129;" d="M619.53696675 554.58775367c0 16.3089242-10.9211544 27.15727033-27.23007776 27.15727032H265.69156407c-16.3089242 0-27.2300786-10.9211544-27.23007776-27.15727032 0-16.38173161 10.9211544-27.2300786 27.23007776-27.23007859h326.61532492c16.3089242 0 27.2300786 10.9211544 27.23007776 27.23007859z m-353.84540268-136.15039214c-16.3089242 0-27.2300786-10.9211544-27.23007776-27.15727033 0-16.38173161 10.9211544-27.2300786 27.23007776-27.2300786H428.99922654c16.3089242 0 27.2300786 10.9211544 27.23007859 27.2300786s-10.9211544 27.15727033-27.23007859 27.15727033H265.69156407z m435.4628302 54.46015719A243.90578197 243.90578197 0 0 1 456.22930512 227.97242873000005a243.90578197 243.90578197 0 0 1 244.92508916-244.99789655 243.90578197 243.90578197 0 0 1 244.9978974 244.99789655 243.90578197 243.90578197 0 0 1-244.9978974 244.92508999z m1e-8-435.46283021c-103.38692806 0-190.53774021 87.07800474-190.53774022 190.53774022 0 103.38692806 87.15081214 190.4649328 190.53774021 190.4649328s190.53774021-87.07800474 190.53774021-190.4649328c0-103.45973634-87.07800474-190.53774021-190.53774021-190.53774022zM810.00189955 255.12969991h-217.69501056c-16.3089242 0-27.2300786-10.9211544-27.23007859-27.15727118 0-16.38173161 10.9211544-27.2300786 27.23007859-27.23007774h217.69501056c16.38173161 0 27.2300786 10.9211544 27.2300786 27.23007774s-10.9211544 27.15727033-27.2300786 27.15727118zM428.99922654 37.43468851H184.00132913c-32.61784753 0-54.38734893 21.76950139-54.38734894 54.38734894V690.66533753c0 32.61784753 21.76950139 54.38734893 54.38734894 54.38734894h489.99579481c32.61784753 0 54.38734893-21.76950139 54.38734893-54.38734894v-136.15039213c0-16.3089242 10.9211544-27.15727033 27.23007775-27.15727032s27.2300786 10.9211544 27.23007859 27.23007859V690.66533753A109.21154404 109.21154404 0 0 1 673.92431567 799.5128428099999H184.00132913A109.21154404 109.21154404 0 0 1 75.15382385 690.66533753V91.82203745000004a109.21154404 109.21154404 0 0 1 108.84750528-108.84750527H428.99922654c16.3089242 0 27.2300786 10.9211544 27.23007859 27.23007774s-10.9211544 27.2300786-27.23007859 27.23007859z" horiz-adv-x="1024" />
<glyph glyph-name="revoke1" unicode="&#59118;" d="M444.51696428 665.85277317h437.50983336L796.94424055 752.48106438a40.05466394 40.05466394 0 0 0 0 56.45288137 38.44172462 38.44172462 0 0 0 55.51200003 0l152.01954619-154.57336599a40.05466394 40.05466394 0 0 0 0-56.52008827L852.38903539 443.13271339a39.1809878 39.1809878 0 0 0-55.51200089 0 40.05466394 40.05466394 0 0 0 0 56.45288222l85.2169692 86.22505574H444.51696428c-160.48747825 0-290.79954668-125.47325044-290.79954667-279.57617577 0-154.23733744 130.37927447-279.64338183 290.79954667-279.64338269h401.75634153c21.64027172 0 39.1137826-17.74233424 39.11378259-39.78584057a39.3153999 39.3153999 0 0 0-39.11378259-39.71863452H444.51696428C240.74894344-52.84617615000002 75.15382385 108.44777135000004 75.15382385 306.70491625c0 197.78670337 165.59511959 359.14785692 369.36314043 359.14785692z" horiz-adv-x="1102" />
@@ -38,7 +71,7 @@ Created by iconfont
<glyph glyph-name="batch-edit" unicode="&#58880;" d="M744.7552 374.88127999999995l-58.71616-58.7264-174.92992-174.91968c-0.34816-0.28672-0.7424-0.4352-1.08544-0.73728-1.42848-1.28-3.01568-2.37056-4.736-3.20512-0.5888-0.25088-1.18784-0.64512-1.87904-0.8448-2.22208-0.83456-4.63872-1.3824-7.15264-1.3824H437.59104a21.06368 21.06368 0 0 0-21.07392 21.0688v58.72128c0.0512 2.46272 0.50176 4.87936 1.3824 7.15264 0.25088 0.58368 0.59392 1.22368 0.93696 1.8688 0.8448 1.72544 1.87392 3.30752 3.15904 4.736l-0.05632-0.0512c0.30208 0.35328 0.39936 0.78848 0.74752 1.13664l174.96576 174.9248 58.71616 58.72128a21.04832 21.04832 0 0 0 29.75744 0.0512l58.6752-58.7264a21.00224 21.00224 0 0 0-0.04608-29.78816z m-132.29056-14.90944l-145.17248-145.16224 28.96384-28.91776 145.27488 145.17248-28.96384 28.96384-0.1024-0.05632z m29.8496 29.80352l28.96384-28.90752 28.91776 28.90752-28.91776 28.91264-28.96384-28.91264zM862.44352 659.54304H304.91648c-41.18528 0-75.05408-33.86368-75.05408-75.04896v-557.65504c0-41.1904 33.86368-75.05408 75.05408-75.05408h557.65504c41.1904 0 75.05408 33.86368 75.05408 75.05408V584.4940799999999c-0.13312 41.3184-33.86368 75.04896-75.18208 75.04896z m-4.18304-584.84736c0-24.05888-19.74272-43.80672-43.80672-43.80672H352.768c-24.05888 0-43.8016 19.74272-43.8016 43.80672V536.50944c0 24.05888 19.74272 43.8016 43.8016 43.8016h461.81376c24.05888 0 43.8016-19.74272 43.8016-43.8016v-461.81376h-0.12288zM263.33696 156.93312000000003h-20.00384c-24.05888 0-43.8016 19.74272-43.8016 43.8016V662.42048c0 24.05888 19.7376 43.8016 43.8016 43.8016h461.81376c24.05888 0 43.8016-19.74272 43.8016-43.8016v-38.57408h79.24224V710.4102399999999c0 41.18528-33.86368 75.04896-75.05408 75.04896H195.34336c-41.18528 0-75.04896-33.86368-75.04896-75.04896v-557.66016c0-41.18528 33.86368-75.04896 75.04896-75.04896h67.9936v79.232z" horiz-adv-x="1024" />
<glyph glyph-name="sanjiaoxing" unicode="&#59087;" d="M959.51284282 384L85.82049052 820.84617615v-873.6923523z" horiz-adv-x="1024" />
<glyph glyph-name="triangle" unicode="&#59087;" d="M959.51284282 384L85.82049052 820.84617615v-873.6923523z" horiz-adv-x="1024" />
<glyph glyph-name="push-pin-line" unicode="&#59217;" d="M768 810.66666668v-85.333333h-42.666667v-256l85.333334-128v-85.333334h-256v-298.666666h-85.333334v298.666666H213.333333v85.333334l85.333334 128V725.33333368H256V810.66666668h512zM384 725.33333368v-281.856L315.904 341.33333368h392.192L640 443.47733368V725.33333368H384z" horiz-adv-x="1024" />

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 143 KiB

File diff suppressed because one or more lines are too long

View File

@@ -31,8 +31,8 @@
@changeTab="changeTab" :targetTab.sync="targetTab" :detail="detail"></panel-tab>
<!--terminal-log的记录和回放-->
<terminal-log-cmd-tab :from="from" :obj="obj" @changeTab="changeTab" ref="reminalLogCMDTab" v-if="from == $CONSTANTS.fromRoute.terminalLog && targetTab == 'cmd'"></terminal-log-cmd-tab>
<terminal-log-record-tab :from="from" :obj="obj" @changeTab="changeTab" ref="reminalLogRecordTab" v-if="from == $CONSTANTS.fromRoute.terminalLog && targetTab == 'record'"></terminal-log-record-tab>
<terminal-log-replay-tab :from="from" :obj="obj" @changeTab="changeTab" ref="reminalLogReplayTab" v-if="from == $CONSTANTS.fromRoute.terminalLog && targetTab == 'replay'"></terminal-log-replay-tab>
</div>
</div>
@@ -45,7 +45,7 @@
import endpointTab from "./tabs/endpointTab";
import panelTab from "./tabs/panelTab";
import terminalLogRecordTab from "./tabs/terminalLogRecordTab";
import terminalLogReplayTab from "./tabs/terminalLogReplayTab";
import terminalLogCMDTab from "./tabs/terminalLogCMDTab";
export default {
name: "bottomBox",
@@ -56,7 +56,7 @@
'endpoint-tab': endpointTab,
'panel-tab': panelTab,
terminalLogRecordTab,
terminalLogReplayTab
'terminal-log-cmd-tab': terminalLogCMDTab
},
props: {
isFullScreen: false, //是否全屏
@@ -95,6 +95,10 @@
afterResize() {
if (this.from == this.$CONSTANTS.fromRoute.endpoint && this.targetTab == 'endpointQuery') {
this.$refs.endpointQuery.tableReload();
} else if (this.from == this.$CONSTANTS.fromRoute.terminalLog && this.targetTab == 'record') {
setTimeout(() => {
this.$refs.reminalLogRecordTab.consoleResize();
}, 600);
}
}
},

View File

@@ -0,0 +1,250 @@
<template>
<div style="height: 100%;">
<div class="sub-top-tools">
<div class="sub-list-tabs">
<div class="sub-list-tab-title">ID{{obj.id}}</div><div
@click="changeTab('record')" class="sub-list-tab">{{$t("config.terminallog.record.record")}}</div><div
class="sub-list-tab sub-list-tab-active">{{$t("config.terminallog.cmd.cmd")}}</div>
</div>
</div>
<div class="record-container">
<div class="record-container--record-tip">
<span class="record--title">{{$t('config.terminallog.cmd.legendTip')}}:</span>
<span class="detail--cmd"><span class="detail--cmd__red"><i class="nz-icon nz-icon-jinggao" style="color: #f35844; margin-right: 8px"></i>{{$t("config.terminallog.cmd.dangerTip")}}</span></span>
</div>
<div class="record-container--record">
<div class="record--title">{{$t('config.terminallog.cmd.history')}}</div>
<div class="record--list">
<template v-for="(record, index) in records">
<template v-for="item in record.list">
<div class="detail--time"><span>{{calcTime(item.time)}}</span></div>
<div class="detail--cmd"><span :class="matchBgColor(item.cmd)">{{item.cmd}}</span></div>
</template>
</template>
</div>
<div :style="{visibility: hasNext ? 'visible' : 'hidden'}" class="record--more">
<span @click="loadMore" class="more-btn"><i class="nz-icon nz-icon-drop-down"></i></span>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "terminalLogRecordTab",
components: {
},
props: {
obj: Object, //关联的实体对象
},
computed: {
calcTime() {
return function(time) {
if (this.obj.startTime) {
let startTime = new Date(this.obj.startTime).getTime();
if (startTime) {
let thisTime = startTime+time;
return this.dateFormat(thisTime);
}
}
return "-";
}
},
matchBgColor() {
return function(cmd) {
let className = "";
let dangerCmd = this.$CONSTANTS.terminalLog.dangerCmd;
let infoCmd = this.$CONSTANTS.terminalLog.infoCmd;
let cmdSplit = cmd.split(" ");
if (this.intersection(infoCmd, cmdSplit).length > 0) {
className = "detail--cmd__green";
}
if (this.intersection(dangerCmd, cmdSplit).length > 0) {
className = "detail--cmd__red";
}
return className;
}
},
hasNext() {
if (this.records.length > 0) {
return this.records[this.records.length-1].hasNext;
}
return false;
}
},
data() {
return {
filter: {
uuid: "",
cmd: "",
time: "",
size: 200
},
records: [ // 加载更多时有多个record否则只有一个
],
}
},
methods: {
initData(filter) {
this.$get("/terminal/cmd", filter).then(res => {
if (res.code === 200) {
this.records.push(res.data);
} else {
this.$message.error(res.msg);
}
});
},
loadMore() {
let filter = Object.assign({}, this.filter);
filter.time = this.records[this.records.length-1].time;
this.initData(filter);
},
// 切换tab
changeTab(tab) {
this.$emit('changeTab', tab);
},
intersection(a, b) {
let s = new Set(b);
return a.filter(x => s.has(x));
},
dateFormat(time) {
if (!time) {
return '-';
}
let date = new Date(time);
let year = date.getFullYear();
let month = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;
let day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
let hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
let minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
let seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
return year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds;
},
formatUpdateTime(date) {
let time=new Date(date);
let hours=time.getHours()>9?time.getHours():'0'+time.getHours();
let minutes=time.getMinutes()>9?time.getMinutes():'0'+time.getMinutes();
return hours+':'+minutes;
},
},
watch: {
obj: {
immediate: true,
deep: true,
handler(n) {
this.records = [];
this.filter.uuid = n.uuid;
this.initData(this.filter);
}
},
},
}
</script>
<style lang="scss">
.record-container {
height: calc(100% - 50px);
overflow: auto;
position: relative;
}
.record-container--record {
background-color: white;
width: calc(100% - 6px);
padding: 16px 15px 6px 15px;
border: 1px solid #d8dce1;
box-sizing: border-box;
min-height: 100px;
.record--title {
color: #333;
font-size: 14px;
font-weight: bold;
margin-bottom: 12px;
}
.record--list {
display: grid;
gap: 6px 12px;
grid-template-columns: 150px auto;
font-size: 14px;
color: #333;
.detail--time {
line-height: 22px;
grid-column: 1/span 1;
display: flex;
font-size: 12px;
align-items: flex-start;
span {
background-color: #ECECEC;
padding: 2px 10px;
}
}
.detail--cmd {
line-height: 22px;
grid-column: 2/span 1;
display: flex;
span {
padding: 2px 10px;
}
}
.detail--cmd__green {
background-color: #B4FDB1;
}
.detail--cmd__red {
background-color: #FFD2C2;
}
}
.record--more {
text-align: center;
margin-top: 15px;
.more-btn {
color: #999;
cursor: pointer;
.nz-icon {
font-size: 14px;
}
}
}
}
.record-container--record-tip {
position: absolute;
right: 20px;
top: 17px;
.record--title {
color: #333;
font-size: 14px;
font-weight: bold;
margin-bottom: 12px;
}
.detail--cmd {
line-height: 22px;
font-size: 14px;
padding-left: 20px;
span {
padding: 3px 10px;
}
}
.detail--cmd__green {
background-color: #A7F29E;
}
.detail--cmd__red {
background-color: #FBe2DE;
}
}
</style>

View File

@@ -1,154 +1,295 @@
<template>
<div style="height: 100%;">
<div class="replay-tab" ref="replayTab">
<div class="sub-top-tools">
<div class="sub-list-tabs">
<div class="sub-list-tab-title">ID{{obj.id}}</div><div
@click="changeTab('replay')" class="sub-list-tab">{{$t("config.terminallog.replay")}}</div><div
class="sub-list-tab sub-list-tab-active">{{$t("config.terminallog.record.record")}}</div>
class="sub-list-tab sub-list-tab-active">{{$t("config.terminallog.record.record")}}</div><div
@click="changeTab('cmd')" class="sub-list-tab">{{$t("config.terminallog.cmd.cmd")}}</div>
</div>
</div>
<div class="record-container">
<div class="record-container--record">
<div class="record--title">{{$t('config.terminallog.record.history')}}</div>
<div class="record--list">
<template v-for="(record, index) in records">
<template v-for="item in record.list">
<div class="detail--time"><span>{{calcTime(item.time)}}</span></div>
<div class="detail--cmd"><span :class="matchBgColor(item.cmd)">{{item.cmd}}</span></div>
</template>
</template>
<div class="replay-container">
<div class="replay-operate">
<div>
<button :title="$t('config.terminallog.record.pause')" @click="pause" class="nz-btn nz-btn-style-light nz-btn-size-large" id="terminal-replay-pause" v-show="isPlaying"><i class="nz-icon nz-icon-suspend"></i></button>
<button :title="$t('config.terminallog.record.play')" @click="play" class="nz-btn nz-btn-style-light nz-btn-size-large" id="terminal-replay-play" v-show="isFinish || !isPlaying"><i class="nz-icon nz-icon-play"></i></button>
<button :title="$t('config.terminallog.record.replay')" @click="restart" class="nz-btn nz-btn-style-light nz-btn-size-large" id="terminal-replay-restart"><i class="nz-icon nz-icon-replay"></i></button>
<button @click="speedChange" class="nz-btn nz-btn-style-light nz-btn-size-large" id="terminal-replay-speed-change"><i class="nz-icon nz-icon-fast-forward"></i>&nbsp;{{speedTable[speedOffset].name}}</button>
<el-checkbox class="operate-skip" id="terminal-replay-skip" v-model="needSkip">{{$t("config.terminallog.record.skipTip")}}</el-checkbox>
<el-tag class="time-box" color="#23bf9a" effect="dark" size="medium">{{parseCurrentTime}}&nbsp;s</el-tag>
</div>
<div class="record--more" v-if="hasNext">
<span @click="loadMore" class="nz-btn nz-btn-size-small nz-btn-style-light"><i class="nz-icon nz-icon-arrow-down"></i></span>
<div @click="jumpProgress" class="terminal-replay-progress">
<el-progress :percentage="progress" :show-text="false" class="terminal-replay-progress-bar" ref="terminalProgress"></el-progress>
<div @mousedown="startDragging" class="progress-controller" id="progressController" ref="progressController"></div>
</div>
</div>
<div class="record-container--record record-container--record__tip">
<div class="record--title">{{$t('config.terminallog.record.legendTip')}}</div>
<div class="record--list">
<div class="detail--time"><span>yyyy-MM-dd HH:mm:ss</span></div>
<div class="detail--cmd"><span class="detail--cmd__red">{{$t("config.terminallog.record.dangerTip")}}</span></div>
</div>
<div class="record-console" ref="recordConsole">
<div :id="obj.uuid" class="record-terminal"></div>
</div>
</div>
</div>
</template>
<script>
import Terminal from '../../js/Xterm';
import bus from "../../../../libs/bus";
export default {
name: "terminalLogRecordTab",
name: "terminalLogReplayTab",
components: {
Terminal
},
props: {
obj: Object, //关联的实体对象
},
computed: {
calcTime() {
return function(time) {
if (this.obj.startTime) {
let startTime = new Date(this.obj.startTime).getTime();
if (startTime) {
let thisTime = startTime+time;
return this.dateFormat(thisTime);
}
}
return "-";
}
},
matchBgColor() {
return function(cmd) {
let className = "";
let dangerCmd = this.$CONSTANTS.terminalLog.dangerCmd;
let infoCmd = this.$CONSTANTS.terminalLog.infoCmd;
let cmdSplit = cmd.split(" ");
if (this.intersection(infoCmd, cmdSplit).length > 0) {
className = "detail--cmd__green";
}
if (this.intersection(dangerCmd, cmdSplit).length > 0) {
className = "detail--cmd__red";
}
return className;
}
},
hasNext() {
if (this.records.length > 0) {
return this.records[this.records.length-1].hasNext;
}
return false;
}
},
data() {
return {
filter: {
uuid: this.obj.uuid,
cmd: "",
time: "",
size: 200
size: 1,
uuid: ""
},
records: [ // 加载更多时有多个record否则只有一个
terminal: null,
recordData: [],
isNeedStop: false, // 是否需要停止
playedCount: 0, // 当前已经播放完的数量
isPlaying: true, // 是否正在播放
isFinish: false, //是否已结束
isDragging: false, //是否正在拖动进度条
draggingOriginalX: 0, //开始拖拽时鼠标的x
draggingOriginalProgress: 0, //开始拖拽时的进度
recordTick: 50, // 输出间隔时间ms默认50
playerTimer: null, // 定时器
playerCurrentTime: 0, // 当前时间进度
speedTable: [ // 快进倍速选项
{speed: 1, name: '×1'},
{speed: 2, name: '×2'},
{speed: 4, name: '×4'},
{speed: 8, name: '×8'},
{speed: 16, name: '×16'}
],
/*record: { // cmd记录含hasNext、time(最后一条时间)、total和list
total: 4,
hasNext: true,
time: 9889,
list: [
{
id: 1,
uuid: 1,
time: 1024,
cmd: "ls -ef|grep java"
},
{
id: 2,
uuid: 2,
time: 3824,
cmd: "su root ls -ef|grep java|afaewrafaser aolewr | awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|ls -ef|grep java|afaewrafaser aolewr | awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|ls -ef|grep java|afaewrafaser aolewr | awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|ls -ef|grep java|afaewrafaser aolewr | awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|ls -ef|grep java|afaewrafaser aolewr | awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|ls -ef|grep java|afaewrafaser aolewr | awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|ls -ef|grep java|afaewrafaser aolewr | awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|"
},
{
id: 3,
uuid: 3,
time: 7740,
cmd: "rm -rf /"
},
{
id: 4,
uuid: 4,
time: 9889,
cmd: "exit"
},
]
}*/
speedOffset: 0, // 快进倍数index
progress: 0, // 进度条进度
needSkip: true, // 是否跳过无操作时间为true时表示需要即不跳过无操作时间
timeUsed: 0,
}
},
methods: {
initData(filter) {
this.$get("/terminal/cmd", filter).then(res => {
if (res.code === 200) {
this.records.push(res.data);
} else {
this.$message.error(res.msg);
}
});
},
loadMore() {
let filter = Object.assign({}, this.filter);
filter.time = this.records[this.records.length-1].time;
this.initData(filter);
},
// 切换tab
changeTab(tab) {
this.$emit('changeTab', tab);
},
intersection(a, b) {
let s = new Set(b);
return a.filter(x => s.has(x));
getRecordData() {
return new Promise(resolve => {
this.$get("/terminal/record", this.filter).then(res => {
if (res.code === 200) {
this.recordData = res.data.list;
this.timeUsed = res.data.endTime;
}
resolve();
});
});
},
consoleResize() {
this.terminal && this.terminal.resize(parseInt(this.$refs.recordConsole.offsetWidth/11), parseInt(this.$refs.recordConsole.offsetHeight/18));
this.$nextTick(() => {
this.terminal && this.terminal.fit();
});
},
initAndPlay() {
this.$nextTick(() => {
// terminal初始化
if (this.terminal) {
this.terminal.reset(parseInt(this.$refs.recordConsole.offsetWidth/11), parseInt(this.$refs.recordConsole.offsetHeight/18));
} else {
this.terminal = new Terminal({
rows: parseInt(this.$refs.recordConsole.offsetHeight/18),
cols: parseInt(this.$refs.recordConsole.offsetWidth/11)
});
this.terminal.open(document.getElementById(this.obj.uuid));
}
if (this.recordData.length > 0) {
this.isNeedStop = false;
this.isPlaying = true;
this.isFinished = false;
this.playedCount = 0;
this.doPlay();
} else {
let req = this.getRecordData();
req.then(() => {
if (this.recordData.length > 0) {
// 请求得到数据后,开始播放
this.isNeedStop = false;
this.isPlaying = true;
this.isFinished = false;
this.playedCount = 0;
this.doPlay();
}
});
}
});
},
/*原理利用setTimeout和数据的时间偏移量来模拟实现视频播放效果*/
doPlay() {
if (this.isNeedStop) {
this.isPlaying = false;
return;
}
if (this.recordData.length <= this.playedCount) {
this.playerTimer = setTimeout(this.doPlay, this.recordTick);
return;
}
this.playerCurrentTime += this.recordTick * this.speedTable[this.speedOffset].speed;
let recordTick = this.recordTick;
let playData;
for (let i = this.playedCount; i < this.recordData.length; i++) {
if (this.isNeedStop) {
break;
}
playData = this.recordData[i];
if (playData.t < this.playerCurrentTime) {
this.terminal.write(playData.c);
if ((this.playedCount + 1) === this.recordData.length) {
//播放完成
this.progress = 100;
this.isFinished = true;
this.isPlaying = false;
return;
} else {
this.playedCount++;
}
} else {
break;
}
}
if (this.isNeedStop) {
return;
}
if (this.needSkip) {
if (playData.t - this.playerCurrentTime > 800) {
this.playerCurrentTime = playData.t; // - this.record_tick * this.speed_table[this.speed_offset].speed;
recordTick = 800;
}
}
// 同步进度条
this.progress = parseInt(this.playerCurrentTime * 100 / this.timeUsed);
if (this.playedCount >= this.recordData.length) {
this.progress = 100;
//播放完成
this.isFinished = true;
this.isPlaying = false;
} else {
if (!this.isNeedStop)
this.playerTimer = setTimeout(this.doPlay, recordTick);
}
},
play() {
if (this.isPlaying) {
return;
}
if (this.isFinished) {
this.restart();
return;
}
this.isNeedStop = false;
this.isPlaying = true;
this.playerTimer = setTimeout(this.doPlay, this.recordTick);
},
speedChange() {
let length = this.speedTable.length;
this.speedOffset += 1;
if (this.speedOffset === length) {
this.speedOffset = 0;
}
},
pause() {
if (this.playerTimer) {
clearTimeout(this.playerTimer);
}
this.isNeedStop = true;
this.isPlaying = false;
},
restart() {
if (this.playerTimer) {
clearTimeout(this.playerTimer);
}
this.playerCurrentTime = 0;
this.initAndPlay();
},
jumpProgress(e) {
e.preventDefault();
if (this.playerTimer) {
clearTimeout(this.playerTimer);
}
this.progress = parseInt(e.offsetX*100/500);
this.playerCurrentTime = parseInt(this.timeUsed * this.progress / 100);
this.initAndPlay();
},
startDragging(e) {
e.preventDefault();
if (this.playerTimer) {
clearTimeout(this.playerTimer);
}
let vm = this;
this.pause();
this.draggingOriginalX = e.clientX;
this.draggingOriginalProgress = this.progress;
this.isDragging = true;
document.addEventListener("mousemove", dragging);
document.addEventListener("mouseup", endDragging);
function endDragging(e) {
e.preventDefault();
vm.isDragging = false;
document.removeEventListener("mousemove", dragging);
document.removeEventListener("mouseup", endDragging);
vm.initAndPlay();
}
function dragging(e) {
e.preventDefault();
if (vm.isDragging) {
let nowX = e.clientX;
let diff = nowX - vm.draggingOriginalX; // x变化量
let diffProgress = parseInt(diff*100/500);
if ((diffProgress + vm.draggingOriginalProgress) > 100) {
vm.progress = 100;
} else if ((diffProgress + vm.draggingOriginalProgress) < 0) {
vm.progress = 0;
} else {
vm.progress = diffProgress + vm.draggingOriginalProgress;
}
vm.playerCurrentTime = parseInt(vm.timeUsed * vm.progress / 100);
}
}
},
dateFormat(time) {
if (!time) {
return '-';
}
let date = new Date(time);
let date = new Date(time * 1000);
let year = date.getFullYear();
let month = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;
let day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
@@ -167,86 +308,99 @@
},
},
watch: {
// 入口监听terminal session的变化开始功能
obj: {
immediate: true,
deep: true,
handler(n) {
if (n.uuid) {
this.recordData = [];
this.filter.uuid = n.uuid;
this.playerCurrentTime = 0;
if (this.playerTimer) {
clearTimeout(this.playerTimer);
}
setTimeout(() => {this.initAndPlay();}, 200);
}
}
},
progress(n) {
let progressController = document.getElementById("progressController");
progressController.style.left = `${n}%`;
}
},
mounted() {
this.initData(this.filter);
computed: {
parseCurrentTime() {
let currentTime = parseInt(this.playerCurrentTime/1000);
let totalTime = parseInt(this.timeUsed/1000);
if (currentTime > totalTime) {
currentTime = totalTime;
}
return `${currentTime} / ${totalTime}`;
}
},
created() {
window.addEventListener('resize', bus.debounce(this.consoleResize, 1000));
},
beforeDestroy() {
window.removeEventListener('resize', bus.debounce);
}
}
</script>
<style lang="scss">
.record-container {
height: calc(100% - 50px);
overflow: auto;
.replay-tab {
height: 100%;
}
.record-container--record {
background-color: white;
width: calc(50% - 14px);
padding: 16px 15px 14px 15px;
border: 1px solid #d8dce1;
box-sizing: border-box;
min-height: 100px;
.record--title {
color: #333;
font-size: 14px;
font-weight: bold;
margin-bottom: 12px;
}
.record--list {
display: grid;
gap: 6px 12px;
grid-template-columns: 150px auto;
font-size: 12px;
color: #333;
padding-left: 16px;
.detail--time {
line-height: 18px;
grid-column: 1/span 1;
display: flex;
align-items: flex-start;
span {
background-color: #ECECEC;
border-radius: 3px;
padding: 2px 5px;
}
}
.detail--cmd {
line-height: 18px;
grid-column: 2/span 1;
display: flex;
span {
border-radius: 3px;
padding: 2px 5px;
}
}
.detail--cmd__green {
background-color: #B4FDB1;
}
.detail--cmd__red {
background-color: #FFD2C2;
}
}
.record--more {
text-align: center;
.replay-container {
height: calc(100% - 40px);
}
.record-console {
padding: 10px 4px 10px 10px;
background-color: black;
height: calc(100% - 80px);
}
.terminal-replay-progress {
height: 20px;
padding: 3px 0;
position: relative;
width: 500px;
}
.terminal-replay-progress-bar {
top: 50%;
transform: translateY(-50%);
.el-progress-bar__inner {
transition: unset;
user-select: none;
}
}
.record-container--record.record-container--record__tip {
margin-top: 10px;
min-height: unset;
.replay-operate {
.nz-btn {
margin-right: 8px;
.nz-icon {
font-size: 14px;
}
}
}
.operate-skip {
margin: 0 12px !important;
}
.time-box {
border: none;
border-radius: 16px;
}
.progress-controller {
position: absolute;
height: 14px;
width: 14px;
border-radius: 50%;
background-color: #409eef;
top: 50%;
transform: translate(-7px, -50%);
}
.progress-controller:hover {
background-color: #207ecf;
}
</style>

View File

@@ -1,268 +0,0 @@
<template>
<div style="height: 100%;">
<div class="sub-top-tools">
<div class="sub-list-tabs">
<div class="sub-list-tab-title">ID{{obj.id}}</div><div
class="sub-list-tab sub-list-tab-active">{{$t("config.terminallog.replay")}}</div><div
@click="changeTab('record')" class="sub-list-tab">{{$t("config.terminallog.record.record")}}</div>
</div>
</div>
<div class="replay-container">
<div class="replay-operate">
<button @click="pause" class="nz-btn nz-btn-style-light nz-btn-size-large">暂停</button>
<button @click="play" class="nz-btn nz-btn-style-light nz-btn-size-large">播放</button>
<button @click="restart" class="nz-btn nz-btn-style-light nz-btn-size-large">重新播放</button>
<el-tag>{{progress}}</el-tag>
</div>
<div class="replay-console">
<div :id="obj.uuid" class="replay-terminal"></div>
</div>
</div>
</div>
</template>
<script>
import Terminal from '../../js/Xterm';
export default {
name: "terminalLogReplayTab",
components: {
Terminal
},
props: {
obj: Object, //关联的实体对象
},
data() {
return {
filter: {
size: 1,
uuid: ""
},
operate: {
pause: false, // 是否暂停
},
terminal: null,
recordData: [],
isNeedStop: false, // 是否需要停止
playedCount: 0, // 当前已经播放完的数量
isPlaying: true, // 是否正在播放
isFinish: false, //是否已结束
recordTick: 50, // 输出间隔时间ms默认50
playerTimer: null, // 定时器
playerCurrentTime: 0, // 当前时间进度
speedTable: [ // 快进倍速选项
{speed: 1, name: 'Normal'},
{speed: 2, name: 'x2'},
{speed: 4, name: 'x4'},
{speed: 8, name: 'x8'},
{speed: 16, name: 'x16'}
],
speedOffset: 0, // 快进倍数index
progress: 0, // 进度条进度
needSkip: false, // 需要时间刻度即是否跳过无操作时间为true时表示需要即不跳过无操作时间
timeUsed: 0,
}
},
methods: {
// 切换tab
changeTab(tab) {
this.$emit('changeTab', tab);
},
getReplayData() {
return new Promise(resolve => {
this.$get("/terminal/record", this.filter).then(res => {
if (res.code === 200) {
this.recordData = res.data.list;
this.timeUsed = res.data.endTime;
}
resolve();
});
});
},
initAndPlay() {
// terminal初始化
if (!this.terminal) {
this.terminal = new Terminal(
{
cols: 70,
rows: 28
}
);
} else {
this.terminal.destroy();
}
setTimeout(() => {
this.terminal.open(document.getElementById(this.obj.uuid));
this.terminal.resize(70, 28);
this.$nextTick(() => {
if (this.recordData.length > 0) {
this.isNeedStop = false;
this.isPlaying = true;
this.isFinished = false;
this.playedCount = 0;
this.doPlay();
} else {
let req = this.getReplayData();
req.then(() => {
if (this.recordData.length > 0) {
// 请求得到数据后,开始播放
this.isNeedStop = false;
this.isPlaying = true;
this.isFinished = false;
this.playedCount = 0;
this.doPlay();
}
});
}
});
}, 800);
},
/*原理利用setTimeout和数据的时间偏移量来模拟实现视频播放效果*/
doPlay() {
if (this.isNeedStop) {
this.isPlaying = false;
return;
}
if (this.recordData.length <= this.playedCount) {
this.playerTimer = setTimeout(this.doPlay, this.recordTick);
return;
}
this.playerCurrentTime += this.recordTick * this.speedTable[this.speedOffset].speed;
let recordTick = this.recordTick;
let playData;
for (let i = this.playedCount; i < this.recordData.length; i++) {
if (this.isNeedStop) {
break;
}
playData = this.recordData[i];
if (playData.t < this.playerCurrentTime) {
this.terminal.write(playData.c);
if ((this.playedCount + 1) === this.recordData.length) {
//播放完成
this.progress = 100;
this.isFinished = true;
this.isPlaying = false;
return;
} else {
this.playedCount++;
}
} else {
break;
}
}
if (this.isNeedStop) {
return;
}
if (this.needSkip) {
if (playData.t - this.playerCurrentTime > 800) {
this.playerCurrentTime = playData.t; // - this.record_tick * this.speed_table[this.speed_offset].speed;
recordTick = 800;
}
}
// 同步进度条
this.progress = parseInt(this.playerCurrentTime * 100 / this.timeUsed);
if (this.playedCount >= this.recordData.length) {
this.progress = 100;
//播放完成
this.isFinished = true;
this.isPlaying = false;
} else {
if (!this.isNeedStop)
this.playerTimer = setTimeout(this.doPlay, recordTick);
}
},
play() {
if (this.isPlaying) {
return;
}
if (this.isFinished) {
this.restart();
return;
}
this.isNeedStop = false;
this.isPlaying = true;
this.playerTimer = setTimeout(this.doPlay, this.recordTick);
},
pause() {
if (this.playerTimer) {
clearTimeout(this.playerTimer);
}
this.isNeedStop = true;
this.isPlaying = false;
},
restart() {
if (this.playerTimer) {
clearTimeout(this.playerTimer);
}
this.playerCurrentTime = 0;
this.initAndPlay();
},
dateFormat(time) {
if (!time) {
return '-';
}
let date = new Date(time * 1000);
let year = date.getFullYear();
let month = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;
let day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
let hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
let minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
let seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
return year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds;
},
formatUpdateTime(date) {
let time=new Date(date);
let hours=time.getHours()>9?time.getHours():'0'+time.getHours();
let minutes=time.getMinutes()>9?time.getMinutes():'0'+time.getMinutes();
return hours+':'+minutes;
},
},
watch: {
// 入口监听terminal session的变化开始功能
obj: {
immediate: true,
deep: true,
handler(n) {
if (n.uuid) {
this.filter.uuid = n.uuid;
this.initAndPlay();
}
}
},
},
mounted() {
},
}
</script>
<style lang="scss">
.replay-console {
width: 660px;
height: 480px;
padding: 10px 4px 10px 10px;
background-color: black;
}
</style>

View File

@@ -383,7 +383,6 @@ export const chartResizeTool = {
//将resize-box的宽高设为resize-shadow的宽高
box.style.width = `${shadow.offsetWidth}px`;
box.style.height = `${Math.round((shadow.offsetHeight )/chartPaddingTop)*chartPaddingTop}px`;
console.log('box height:',box.style.height)
data.height = Math.round((box.offsetHeight+chartPaddingTop)/stepHeight)*stepHeight;
data.span = Math.round((box.offsetWidth+chartBlankWidth)/stepWidth);
//请求后台,保存变更

View File

@@ -641,7 +641,6 @@ const cn = {
},
option: "操作",
host: "主机",
cmd: "命令",
port: "端口",
userId: "用户ID",
protocol: "协议",
@@ -668,12 +667,20 @@ const cn = {
duration: "持续",
remote: "远程连接",
replay: "回放",
source: "源IP",
log: "日志",
cmd: {
cmd: "命令",
history: "历史命令",
dangerTip: "可能是危险命令",
legendTip: "图例说明"
},
record: {
record: "记录",
history: "历史记录",
dangerTip: "这条命令可能是危险的",
legendTip: "图例说明",
record: "回放",
pause: "暂停",
play: "播放",
replay: "重播",
skipTip: "跳过无操作时间"
}
},
dc: {

View File

@@ -679,7 +679,6 @@ const en = {
},
option: 'Operation',//"操作",
host: 'Host',
cmd: 'CMD',
port: 'Port',
userId: 'UserID',
protocol: 'Protocol',
@@ -705,13 +704,20 @@ const en = {
startTime: "Start time",
duration: "Duration",
remote: "Remote",
replay: "Replay",
log: "Log",
source: "Source IP",
cmd: {
cmd: "Command",
history: "History command",
dangerTip: "This command may be dangerous",
legendTip: "Legend description",
},
record: {
record: "Record",
history: "History record",
dangerTip: "This CMD may be dangerous",
legendTip: "Legend description",
pause: "Pause",
play: "Play",
replay: "Replay",
skipTip: "Skip no operation time"
}
},
operationlog: {

View File

@@ -58,9 +58,9 @@
<span>{{getDuration(scope.row)}}</span>
</template>
<template v-else-if="item.prop == 'option'">
<span :id="'terminalLog-replay-'+scope.row.id" :title="$t('config.terminallog.replay')" @click="showReplay(scope.row)" class="content-right-option"><i class="el-icon-video-play"></i></span>
<span :id="'terminalLog-replay-'+scope.row.id" :title="$t('config.terminallog.record.record')" @click="showRecord(scope.row)" class="content-right-option"><i class="nz-icon nz-icon-replay2"></i></span>
&nbsp;
<span :id="'terminalLog-log-'+scope.row.id" :title="$t('config.terminallog.log')" @click="showRecord(scope.row)" class="content-right-option"><i class="el-icon-tickets"></i></span>
<span :id="'terminalLog-log-'+scope.row.id" :title="$t('config.terminallog.log')" @click="showHistoryCMD(scope.row)" class="content-right-option"><i class="nz-icon nz-icon-terminal-log"></i></span>
</template>
<span v-else>{{scope.row[item.prop]}}</span>
@@ -159,6 +159,11 @@
prop: 'username',
show: true,
},
{
label: this.$t('config.terminallog.source'),
prop: 'remoteAddr',
show: true,
},
{
label: this.$t('config.terminallog.remote'),
prop: 'remote',
@@ -233,43 +238,6 @@
searchLabel: {}, //搜索参数
scrollbarWrap: null,
testData: {
code: 200,
data: {
pageNo: 1,
pageSize: 20,
total: 2,
pages: 1,
list: [
{
id: 1,
uuid: "abcdde",
host: "192.168.40.42",
port: 22,
protocol: "SSH",
authType: 1,
username: "admin",
loginUser: "root",
startTime: "2021-02-01 14:20:08",
endTime: "2021-02-01 14:30:08",
status: 3,
killUserName: "leader",
}, {
id: 2,
uuid: "zpppoe",
host: "192.168.40.42",
port: 22,
protocol: "SSH",
authType: 1,
username: "admin",
loginUser: "root",
startTime: "2021-02-01 14:41:08",
endTime: "2021-02-01 14:51:08",
status: 2,
},
]
},
}
}
},
computed: {
@@ -292,11 +260,16 @@
}
},
},
watch: {
'bottomBox.showSubList': function (n) {
let vm = this;
this.$bottomBoxWindow.showSubListWatch(vm, n);
},
},
methods: {
getTableData() {
this.$get('terminal/session', this.searchLabel).then(response => {
this.tools.loading = false;
//response = this.testData;
if (response.code === 200) {
this.tableData = response.data.list;
this.pageObj.total = response.data.total;
@@ -310,32 +283,13 @@
})
},
/*getTableData: function () {
this.$set(this.searchLabel, "pageNo", this.pageObj.pageNo);
this.$set(this.searchLabel, "pageSize", this.pageObj.pageSize);
this.tools.loading = true;
this.$get('terminal/log', this.searchLabel).then(response => {
this.tools.loading = false;
response = this.testData;
if (response.code === 200) {
this.tableData = response.data.list;
this.pageObj.total = response.data.total;
if (!this.scrollbarWrap) {
this.$nextTick(() => {
this.scrollbarWrap = this.$refs.terminalLogTable.bodyWrapper;
this.toTopBtnHandler(this.scrollbarWrap);
});
}
}
})
},*/
showReplay(record) {
this.bottomBox.targetTab = 'replay';
showRecord(record) {
this.bottomBox.targetTab = 'record';
this.bottomBox.terminalLog = JSON.parse(JSON.stringify(record));
this.bottomBox.showSubList = true;
},
showRecord(record) {
this.bottomBox.targetTab = 'record';
showHistoryCMD(record) {
this.bottomBox.targetTab = 'cmd';
this.bottomBox.terminalLog = JSON.parse(JSON.stringify(record));
this.bottomBox.showSubList = true;
},