index.vue 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357
  1. <template>
  2. <view class="content">
  3. <!-- 第一排盒子开始 -->
  4. <view class="box-first">
  5. <view class="machineStatus">
  6. <SubTitle title="机器人状态" titleEng="ROBOT STATUS"></SubTitle>
  7. <view class="bottom">
  8. <view class="list">
  9. <view class="plcConnect">
  10. <PannelItem show="true" words="PLC通讯" :status="robotInfoVo.plcState ? '正常' : '异常'"
  11. :flag="robotInfoVo.plcState" />
  12. </view>
  13. <view class="plcModel">
  14. <PannelItem show="true" words="机器人模式" :status="PlcMode" :flag="robotInfoVo.exchangeMode" />
  15. </view>
  16. </view>
  17. <view class="status-only">
  18. <view class="circle">
  19. <image :src="PlcState[0]"></image>
  20. </view>
  21. <view class="descript">机器人状态</view>
  22. <view class="frame">
  23. <span :class="PlcState[1]">{{PlcState[2] || '—'}}</span>
  24. <view class="shinning"></view>
  25. </view>
  26. </view>
  27. <PannelItem show="true" words="急停状态" :status="robotInfoVo.emergencyMode == 1 ? '急停' : robotInfoVo.emergencyMode == 0 ?'未急停' :'—'"
  28. :flag="robotInfoVo.emergencyMode == 0" />
  29. <PannelItem show="true" words="暂停状态" :status="robotInfoVo.pause == 1 ? '暂停' : robotInfoVo.pause == 0?'未暂停':'—' " handle="true"
  30. @ExchangeMessage='ExchangeMessage' :flag="robotInfoVo.pause == 0" />
  31. </view>
  32. </view>
  33. <view class="machineStatus carInfo">
  34. <SubTitle title="车辆信息" titleEng="VEHICLE INFORMATION"></SubTitle>
  35. <view class="bottom">
  36. <view class="list">
  37. <view class="carLeft">
  38. <PannelTitle words="车牌号" :value="vehicleInfo.plate" Isblue="true" :circle="true"
  39. :flag="vehicleInfo.plateState" @ShowCarline="ShowCarline" />
  40. </view>
  41. <view class="carRight">
  42. <PannelTitle words="在线车辆" circle="false" :value="vehicleInfo.onlineNum" flag="true"
  43. @ShowCarline="ShowCarline" />
  44. </view>
  45. </view>
  46. <view class="list">
  47. <view class="carLeft">
  48. <PannelTitle words="车辆识别" :value="vehicleInfo.plateState == 1 ? '成功' : '未识别'"
  49. :flag="vehicleInfo.plateState" @handleStatusShow="handleStatusShow"/>
  50. </view>
  51. <view class="carRight">
  52. <PannelTitle words="鉴权状态" :value="vehicleInfo.authState ? '已通过' : '未通过'"
  53. :flag="vehicleInfo.authState" />
  54. </view>
  55. </view>
  56. <view class="list">
  57. <view class="carLeft">
  58. <PannelTitle words="连接状态" :value="vehicleInfo.conState == 1 ? '已连接' : vehicleInfo.conState == 0 ?'未连接':'—'"
  59. :flag="vehicleInfo.conState == 1" />
  60. </view>
  61. <view class="carRight">
  62. <PannelTitle words="车辆到位" :value="vehicleInfo.sensorState ? '已到位' : '未到位'"
  63. :flag="vehicleInfo.sensorState" />
  64. </view>
  65. </view>
  66. <view class="list">
  67. <view class="carLeft">
  68. <PannelTitle circle="false" words="解锁状态"
  69. :value="vehicleInfo.lockState==null ? '—': vehicleInfo.lockState?'已上锁' : '已解锁'"
  70. @ExchangeMessage="ExchangeMessage" :flag="vehicleInfo.lockState == 0" />
  71. </view>
  72. </view>
  73. </view>
  74. </view>
  75. </view>
  76. <!-- 第一排盒子结束-->
  77. <!-- 选电模式开始 -->
  78. <view class="getModel">
  79. <view class="subtilte-only">
  80. <view class="title">
  81. <view class="icon"></view>
  82. <view class="name">选电模式</view>
  83. <view class="letter">POWER SELECTION MODE</view>
  84. <view class="handle-model">
  85. <view class="leftBtn" :class="[pamars.batChooseMode===0 ? 'active' : '']"
  86. @click="ChangeModel(0)">自动选电</view>
  87. <view class="leftBtn Rbtn" :class="[pamars.batChooseMode===1 ? 'active' : '']"
  88. @click="ChangeModel(1)">手动选电</view>
  89. </view>
  90. <view class="freeze">
  91. <view class="active" @click="HandleLock(1)">锁定仓位</view>
  92. <view class="active" @click="HandleLock(0)">解锁仓位</view>
  93. <view class="active" @click="HandleFreeze(1)">冻结</view>
  94. <view @click="HandleFreeze(0)">解冻</view>
  95. </view>
  96. </view>
  97. </view>
  98. <view class="storeList">
  99. <scroll-view scroll-x="true" class="scroll_x">
  100. <view v-for="(item, index) in storeInfoList">
  101. <!-- 电池列表信息 -->
  102. <BatteryInfo :soc="item.soc"
  103. :chgState="item.chargerInfoVo.chgState" :chgEstimatedTime="item.chargerInfoVo.chgEstimatedTime"
  104. :key="index" :storeState="item.storeState" :storeCode="item.storeCode" :isLocked="item.isLocked"
  105. :freezeState="item.freezeState" :comState="item.comState" :lineType="item.chargerInfoVo.linktype"
  106. :chargerComState="item.chargerInfoVo.comState" :BatterySelectAllArr="BatterySelectAllArr" :ascription="item.ascription"
  107. :BatterySelected="BatterySelected" :IsSelect="BatteryIsSelectArr[index]" />
  108. <!-- 电池信息结束 -->
  109. </view>
  110. </scroll-view>
  111. </view>
  112. </view>
  113. <!-- 选电模式结束-->
  114. <!-- 底部开始 -->
  115. <view class="box-last">
  116. <view class="Exchange-done">
  117. <view class="subtilte-only">
  118. <view class="title">
  119. <view class="icon"></view>
  120. <view class="name">换电操作</view>
  121. <view class="letter">POWER EXCHANGE OPERATION</view>
  122. <view class="switch">
  123. <view class="uni-list-cell-db">{{powerChangeStatus?'开启中':'已关闭'}}</view>
  124. <switch color="#91FDB9" style="transform:scale(0.6)" @change="switchChange" :checked="powerChangeStatus" />
  125. </view>
  126. </view>
  127. </view>
  128. <view class="Exchange-bottom">
  129. <view class="Exchange-times">
  130. <view class="Progress-btn" :class='!powerChangeStatus?"isshowactive":""' @click="BeginChangePower">开始换电</view>
  131. <view class="Exchange-status" v-if="!TcInfoVoData.sourceCode && !TcInfoVoData.targetCode && !xfTargetCodeData.xfTargetCode">
  132. <view class="lock">
  133. <span>{{ forbidLockState ? '锁止已屏蔽' : '锁止已放开'}}</span>
  134. <span class="time">换电时长:<font>{{PlcChangerTime || '—'}}</font></span>
  135. </view>
  136. <view class="percent">
  137. <view class="percent-bar">
  138. <view class="bar">
  139. <view class="bar-green" :style="{ 'width': swapPercent + '%' }">
  140. <view class="bar-percent" :class="[swapPercent <15 ? 'bar-ten' : '']">
  141. {{ swapPercent }}%
  142. </view>
  143. </view>
  144. </view>
  145. </view>
  146. <view class="count-step">
  147. <font>{{swapProcess.step || 0}}</font>/{{swapProcess.plcStep || 0}}
  148. </view>
  149. </view>
  150. <view class="lock">
  151. <span></span>
  152. <span class="time">机器人工作时长:<font>{{PlcWorkTime || '—'}}</font></span>
  153. </view>
  154. </view>
  155. <view class="Exchange-status" v-if="TcInfoVoData.sourceCode && TcInfoVoData.targetCode">
  156. <view class="Exchange-status-left">
  157. <view class="Exchange-status-left-box">
  158. <text class="text1">仓位</text><text
  159. class="text2">{{TcInfoVoData.sourceCode}}—>{{TcInfoVoData.targetCode}}号仓位</text>
  160. </view>
  161. <view class="Exchange-status-left-box">
  162. <text class="text1">电池状态</text><text
  163. class="text2">{{TcInfoVoData.chargerState?'充电中':'未充电'}}</text>
  164. </view>
  165. </view>
  166. <view class="Exchange-status-left">
  167. <view class="Exchange-status-left-box">
  168. <text class="text1">动作流程</text><text
  169. class="text2">{{TcInfoVoData.actionFlow || '-'}}</text>
  170. </view>
  171. <view class="Exchange-status-left-box">
  172. <text class="text1">工作时长</text><text class="text2">{{warehouse || '-'}}</text>
  173. </view>
  174. </view>
  175. </view>
  176. <view class="Exchange-status" v-if="xfTargetCodeData.xfTargetCode">
  177. <view class="Exchange-status-left">
  178. <view class="Exchange-status-left-box change-store">
  179. <text class="text1">仓位</text><text
  180. class="text2">{{xfTargetCodeData.xfTargetCode}}号仓位</text>
  181. </view>
  182. <view class="Exchange-status-left-box">
  183. <text class="text1">电池状态</text><text
  184. class="text2">{{xfTargetCodeData.chargerState?'充电中':'未充电'}}</text>
  185. </view>
  186. </view>
  187. <view class="Exchange-status-left">
  188. <view class="Exchange-status-left-box">
  189. <text class="text1">动作流程</text><text
  190. class="text2">{{xfTargetCodeData.actionFlow || '-'}}</text>
  191. </view>
  192. <view class="Exchange-status-left-box">
  193. <text class="text1">工作时长</text><text class="text2">{{changeWareHouse || '-'}}</text>
  194. </view>
  195. </view>
  196. </view>
  197. </view>
  198. <view class="Exchange-handle">
  199. <view class="handle" :class='!powerChangeStatus?"isshowactive":""' @click="HandleIsLock(1)">锁止屏蔽</view>
  200. <view class="handle" :class='!powerChangeStatus?"isshowactive":""' @click="HandleChangeStore">调仓</view>
  201. <view class="handle" :class='!powerChangeStatus?"isshowactive":""' @click="PausePLC(1)">急停</view>
  202. <view class="handle" :class='!powerChangeStatus?"isshowactive":""' @click="HandleFireStore">消防换仓</view>
  203. <view class="handle" :class='!powerChangeStatus?"isshowactive":""' @click="HandleIsLock(0)">锁止放开</view>
  204. <view class="handle" :class='!powerChangeStatus?"isshowactive":""' @click="PausePLC(6)">中止</view>
  205. </view>
  206. </view>
  207. </view>
  208. <view class="Exchange-log">
  209. <view class="subtilte-only">
  210. <view class="title">
  211. <view class="icon"></view>
  212. <view class="name">换电日志</view>
  213. <view class="letter">POWER EXCHANGE OPERATION</view>
  214. <!-- <view class="log-descript">支持手动急停充电机,倒计时1分钟</view> -->
  215. </view>
  216. </view>
  217. <view class="log_bottom">
  218. <scroll-view scroll-y="true" class="scroll_x">
  219. <view class="log-list" v-for="item in logList" :key="item.id">
  220. <view class="log-times" :class="[item.remark=='error'?'logRed':'']">{{item.createTime}}</view>
  221. <view class="log-info" :class="[item.remark=='error'?'logRed':'']">{{item.content}}</view>
  222. </view>
  223. </scroll-view>
  224. </view>
  225. </view>
  226. </view>
  227. <!-- 底部结束 -->
  228. <!-- 顶部公共提示信息 -->
  229. <uni-popup ref="Exchangepopup" type="message">
  230. <uni-popup-message :type="popupType" :message="popupMessage" :duration="2000"></uni-popup-message>
  231. </uni-popup>
  232. <uni-popup ref="popup" :mask-click="false">
  233. <view class="popup-container">
  234. <view class="popup-title">
  235. <view class="title-text">
  236. 车辆识别设备
  237. </view>
  238. <view class="title-close" @click="closePopup">
  239. 关闭
  240. </view>
  241. </view>
  242. <view class="popup-content">
  243. <PannelTitle words="车牌识别器" :value="vehicleInfo.plateComState == 1 ? '已连接' : '未连接'" :flag="vehicleInfo.plateComState"/>
  244. </view>
  245. <view class="popup-content">
  246. <PannelTitle words="RFID识别器" :value="vehicleInfo.rfidConnState ? '已连接' : '未连接'" :flag="vehicleInfo.rfidConnState"/>
  247. </view>
  248. </view>
  249. </uni-popup>
  250. <!-- 顶部提示信息结束-->
  251. <!--在线、编辑车辆抽屉 -->
  252. <uni-drawer ref="carlineDrawer" mode="right" :width="400" :mask-click="true">
  253. <scroll-view style="height: 100%;" scroll-y="true">
  254. <PublicDrawer :flag="isDrawer" title="在线车辆" @closeDrawer="closeDrawer" v-if="isDrawer">
  255. <view class="carPosition">
  256. <view class="CarnoData" v-if="CarlineList.length==0"></view>
  257. <view class="Carlist" v-for="item in CarlineList" :key="item.id">
  258. <view class="carDetail">
  259. <view class="plateNumber">
  260. <view class="icon">
  261. <image src="/static/change/car.png"></image>
  262. </view>
  263. <view class="pNumber">{{item.vehiclePlate}}</view>
  264. </view>
  265. <view class="vinMa">
  266. <view>VIN码</view>
  267. <view>{{item.vehicleVin}}</view>
  268. </view>
  269. <view class="vinMa">
  270. <view>熄火状态</view>
  271. <view>{{item.keyState}}</view>
  272. </view>
  273. <view class="vinMa">
  274. <view>解锁状态</view>
  275. <view>{{item.lockState?'已上锁':'已解锁'}}</view>
  276. </view>
  277. </view>
  278. </view>
  279. </view>
  280. </PublicDrawer>
  281. <PublicDrawer :flag="isDrawer" title="编辑车牌" @HandleEditPlate="HandleEditPlate"
  282. :plate="vehicleInfo.plate" @closeDrawer="closeDrawer" v-if="!isDrawer">
  283. <view class="carPosition">
  284. <view class="carForm">
  285. <view>编辑车牌号:</view>
  286. <input class="uni-input" type="text" v-model="plate" placeholder="请输入车牌号" />
  287. </view>
  288. </view>
  289. </PublicDrawer>
  290. </scroll-view>
  291. </uni-drawer>
  292. <!-- 在线、编辑车辆抽屉结束-->
  293. </view>
  294. </template>
  295. <script>
  296. export default {
  297. data() {
  298. return {
  299. popupMessage: '成功消息',
  300. popupType: 'success',
  301. robotInfoVo: {}, //机器人状态对象
  302. vehicleInfo: {}, //车辆信息对象
  303. batteryInfo: {}, //电池信息对象
  304. swapProcess: {}, //换电进度对象
  305. storeInfoList: [], //电池仓列表数组
  306. logList: [], //日志列表
  307. BatteryIsSelectArr: [false, false, false, false, false, false, false, false], //存储电池的选中状态
  308. BatteryFullStatus: true, //切换满电、亏点电池状态
  309. BatterySelectAllArr: [], //存储所有选中的电池仓位号
  310. CarlineList: [], //在线车辆列表
  311. pamars: {
  312. batChooseMode: 0,
  313. batChosenIndex: 0,
  314. startMode: 0,
  315. userId: 1,
  316. userName: 'admin'
  317. }, //开始换电参数
  318. ws: null, //ws连接对象
  319. timer: null, //ws连接
  320. isDrawer: true, //切换抽屉显示内容
  321. plate: '—', //弹窗车牌号
  322. powerChangeStatus: false,
  323. isSelectstoreState: [], //选择的仓位存储电池状态
  324. TcInfoVoData: {}, //调仓信息对象
  325. xfTargetCodeData: {}, //消防换仓对象
  326. heartbeatTimer:null,
  327. onMessageTime:null,
  328. TcNumber:0,//调仓计数器 大于5时显示换电页面
  329. XfNumber:0,//消防调仓计数器 大于5时显示换电页面
  330. forbidLockState:true,//锁止状态
  331. selectStoreCode: [],
  332. }
  333. },
  334. mounted() {
  335. this.onMessageTime = new Date();
  336. this.InitWs()
  337. this.heartbeatTimer = setInterval(()=>{
  338. let newDate = new Date();
  339. if(newDate-this.onMessageTime>5000){
  340. if(this.ws!=null){
  341. this.ws.close()
  342. this.ws=null
  343. }
  344. }
  345. },5000)
  346. },
  347. destroyed(){
  348. clearInterval(this.timer)
  349. this.ws.close()
  350. },
  351. onUnload() {
  352. if(this.timer!=null){
  353. clearInterval(this.timer)
  354. this.timer = null
  355. }
  356. if(this.ws!=null){
  357. this.ws.close()
  358. this.ws=null
  359. }
  360. if(this.heartbeatTimer!=null){
  361. this.heartbeatTimer.close()
  362. this.heartbeatTimer=null
  363. }
  364. },
  365. computed: {
  366. //换电时长
  367. PlcChangerTime() {
  368. if (this.swapProcess.swapStartTime) {
  369. let end_time = this.$moment()
  370. let seconds = end_time.diff(this.swapProcess.swapStartTime, "seconds")
  371. return parseInt(seconds / 60) + '分' + (seconds % 60) + '秒'
  372. }
  373. },
  374. //机器人工作时长
  375. PlcWorkTime() {
  376. if (this.swapProcess.plcStartTime) {
  377. let end_time = this.$moment()
  378. let seconds = end_time.diff(this.swapProcess.plcStartTime, "seconds")
  379. return parseInt(seconds / 60) + '分' + (seconds % 60) + '秒'
  380. }
  381. },
  382. //调仓工作时长
  383. warehouse() {
  384. if (this.TcInfoVoData.startTime) {
  385. let end_time = this.$moment()
  386. let seconds = end_time.diff(this.TcInfoVoData.startTime, "seconds")
  387. return parseInt(seconds / 60) + '分' + (seconds % 60) + '秒'
  388. }
  389. },
  390. //消防换仓工作时长
  391. changeWareHouse() {
  392. if (this.xfTargetCodeData.startTime) {
  393. let end_time = this.$moment()
  394. let seconds = end_time.diff(this.xfTargetCodeData.startTime, "seconds")
  395. return parseInt(seconds / 60) + '分' + (seconds % 60) + '秒'
  396. }
  397. },
  398. //换电百分比
  399. swapPercent() {
  400. if (this.swapProcess.plcPercentage) {
  401. return this.swapProcess.plcPercentage
  402. } else {
  403. return 0
  404. }
  405. },
  406. //换电解锁状态
  407. swapIsLock() {
  408. switch (this.swapProcess.lockState) {
  409. case true:
  410. return '已上锁'
  411. case false:
  412. return '已解锁'
  413. default:
  414. return '—'
  415. }
  416. },
  417. //机器人状态
  418. PlcState() {
  419. switch (this.robotInfoVo.robotState) {
  420. case 1:
  421. return ['/static/change/green.png', '', '就绪']
  422. case 2:
  423. return ['/static/change/blue.png', 'isblue', '运行']
  424. case 3:
  425. return ['/static/change/yellow.png', 'isflag', '完成']
  426. case 4:
  427. return ['/static/change/yellow.png', 'isflag', '故障']
  428. case 5:
  429. return ['/static/change/yellow.png', 'isflag', '中止']
  430. default:
  431. return ['/static/change/yellow.png', 'isflag', '未就绪']
  432. }
  433. },
  434. //机器人模式
  435. PlcMode() {
  436. switch (this.robotInfoVo.exchangeMode) {
  437. case 0:
  438. return '无效';
  439. case 1:
  440. return '手动模式';
  441. case 2:
  442. return '自动模式';
  443. case 3:
  444. return '单步模式';
  445. }
  446. },
  447. },
  448. methods: {
  449. handleStatusShow() {
  450. this.$refs.popup.open('center');
  451. },
  452. closePopup() {
  453. this.$refs.popup.close();
  454. },
  455. //修改车牌号提交
  456. HandleEditPlate(plate) {
  457. let that = this
  458. if (this.$checks.validateLicensePlateNumber(this.plate)) {
  459. this.$http.EditPlate(this.plate)
  460. .then(res => {
  461. if (res.code === 0) {
  462. that.ExchangeMessage('success', '修改成功!')
  463. that.closeDrawer()
  464. } else {
  465. that.ExchangeMessage('error', '修改失败!')
  466. }
  467. }).catch(err => {
  468. console.error(err)
  469. })
  470. } else {
  471. that.ExchangeMessage('warn', '请填写新能源车牌号!')
  472. }
  473. },
  474. closeDrawer() {
  475. this.$refs.carlineDrawer.close();
  476. },
  477. //顶部公共消息提示
  478. ExchangeMessage(type, message) {
  479. this.popupType = type
  480. this.popupMessage = message ? message : '后端接口404错误!'
  481. this.$refs.Exchangepopup.open()
  482. },
  483. //切换换电模式(0自动、1手动)
  484. ChangeModel(id) {
  485. let that = this
  486. let modelText = id === 1 ? '手动' : '自动'
  487. uni.showModal({
  488. title: `请确认选电模式切换为${modelText}?`,
  489. content: '',
  490. success: function(res) {
  491. if (res.confirm) {
  492. that.$http.setMode(id + '').then(res => {
  493. if (res.code === 0) {
  494. that.pamars.batChooseMode = id === 1 ? 1 : 0
  495. }
  496. that.ExchangeMessage(res.code === 0 ? 'success' : 'error',
  497. res.code === 0 ? '选电模式切换成功!' : '选电模式切换失败!')
  498. })
  499. } else if (res.cancel) {
  500. return false
  501. //用户点击取消按钮触发
  502. }
  503. }
  504. })
  505. },
  506. //解/锁仓
  507. HandleLock(type) {
  508. let that = this;
  509. const text = type === 1 ? '锁定' : '解锁'
  510. if(that.selectStoreCode && that.selectStoreCode.length == 0) {
  511. return that.ExchangeMessage('warn',`请选择一个仓位进行${text}!`)
  512. }
  513. if(that.selectStoreCode && that.selectStoreCode.length == 2) {
  514. return that.ExchangeMessage('warn',`只能一个仓位进行${text}!`)
  515. }
  516. let param = {
  517. code: that.selectStoreCode[0],
  518. type: type
  519. }
  520. uni.showModal({
  521. title: `请确认${text}【${that.selectStoreCode[0]}】号仓?`,
  522. content: '',
  523. success: function(res) {
  524. if (res.confirm) {
  525. that.$http.chgLock(param).then(res => {
  526. if (res.code === 0) {
  527. that.ExchangeMessage('warn',type===1?'锁定仓位成功':'解锁仓位成功')
  528. // that.BatteryIsSelectArr = [false, false, false, false, false, false, false, false];
  529. // that.selectStoreCode = [];
  530. }else{
  531. that.ExchangeMessage('warn',type===1?'锁定仓位失败':'解锁仓位失败')
  532. }
  533. })
  534. } else if (res.cancel) {
  535. return false
  536. //用户点击取消按钮触发
  537. }
  538. }
  539. })
  540. },
  541. //冻结、解冻
  542. HandleFreeze(isFree) {
  543. let that=this
  544. const text = isFree === 1 ? '冻结' : '解冻'
  545. if (this.BatterySelectAllArr.length !== 1 || this.BatterySelectAllArr[0].storeState!==1) {
  546. this.ExchangeMessage('warn',`请选择一个电池进行${text}!`)
  547. }
  548. else if(isFree === 1 && this.BatterySelectAllArr[0].freezeState==1){
  549. this.ExchangeMessage('warn',`选择电池已冻结,无需再次冻结!`)
  550. }
  551. else if(isFree === 0 && this.BatterySelectAllArr[0].freezeState==0){
  552. this.ExchangeMessage('warn',`选择电池已解冻,无需再次解冻!`)
  553. }
  554. else {
  555. const pamars={
  556. code:this.BatterySelectAllArr[0].storeCode,
  557. type:isFree
  558. }
  559. uni.showModal({
  560. title: `请确认${text}【${this.BatterySelectAllArr[0].storeCode}】号电池?`,
  561. content: '',
  562. success: function(res) {
  563. if (res.confirm) {
  564. that.$http.batteryfreeze(pamars).then(res => {
  565. if (res.code === 0) {
  566. that.clearStore()
  567. that.ExchangeMessage('warn',isFree===1?'冻结成功':'解冻成功')
  568. }else{
  569. that.ExchangeMessage('warn',isFree===1?'冻结失败':'解冻失败')
  570. }
  571. })
  572. } else if (res.cancel) {
  573. return false
  574. //用户点击取消按钮触发
  575. }
  576. }
  577. })
  578. }
  579. },
  580. //开始换电
  581. BeginChangePower() {
  582. if (this.powerChangeStatus) {
  583. if (this.pamars.batChooseMode === 1) {
  584. //手动模式下传仓位号参数
  585. if (this.BatterySelectAllArr.length !== 1 || this.BatterySelectAllArr[0].storeState !== 1) {
  586. this.ExchangeMessage('warn', '请手动选择一个电池进行换电!')
  587. return
  588. } else {
  589. this.pamars.batChosenIndex = this.BatterySelectAllArr[0].storeCode
  590. }
  591. } else {
  592. this.pamars.batChosenIndex = 0
  593. if (this.BatterySelectAllArr.length !== 0) {
  594. this.ExchangeMessage('warn', '自动换电不用选择电池,请取消选中的电池!')
  595. return
  596. }
  597. }
  598. const pamars = this.pamars
  599. let that = this
  600. uni.showModal({
  601. title: '请确认站控发起换电?',
  602. content: '',
  603. success: function(res) {
  604. if (res.confirm) {
  605. // that.ExchangeMessage('success', '换电指令已下发,请等待!')
  606. that.$http.beginSwap(pamars)
  607. .then(res => {
  608. that.clearStore()
  609. that.ExchangeMessage(res.code === 0 ? 'success' : 'error',
  610. res.code === 0 ? '发起换电成功!' : res.msg)
  611. })
  612. .catch(err => {
  613. console.error(err)
  614. })
  615. } else if (res.cancel) {
  616. return false
  617. //用户点击取消按钮触发
  618. }
  619. }
  620. })
  621. } else {
  622. this.PowerChangeStatusTips()
  623. }
  624. },
  625. //switch开关
  626. switchChange(e) {
  627. this.powerChangeStatus = e.detail.value
  628. },
  629. //实时车辆弹窗
  630. ShowCarline(pamars) {
  631. this.$refs.carlineDrawer.open();
  632. if (pamars == 'line') {
  633. this.getCarOnline()
  634. this.isDrawer = true
  635. } else {
  636. this.isDrawer = false
  637. this.plate = pamars
  638. }
  639. },
  640. //已连接站控车辆列表
  641. getCarOnline() {
  642. this.$http.CarOnline().then(res => {
  643. this.CarlineList = res.data; //[{vehicleVin:123,keyState:2,vehiclePlate:"渝AFB3182"}]
  644. this.CarlineList.forEach(item => {
  645. if (item.keyState == 0) {
  646. item.keyState = '熄火'
  647. } else if (item.keyState == 1) {
  648. item.keyState = '未点火'
  649. } else if (item.keyState == 2) {
  650. item.keyState = '启动'
  651. } else {
  652. item.keyState = '-'
  653. }
  654. })
  655. })
  656. },
  657. //切换满电、亏电电池信息
  658. ChangeBattery(id) {
  659. this.BatteryFullStatus = id === 1 ? true : false
  660. },
  661. //锁止屏蔽、放开
  662. HandleIsLock(islock) {
  663. if (this.powerChangeStatus) {
  664. let that = this
  665. let lockTest = islock ? '锁止屏蔽' : '锁止放开'
  666. uni.showModal({
  667. title: `请确认${lockTest}`,
  668. content: '',
  669. success: function(res) {
  670. if (res.confirm) {
  671. that.$http.EditforbidLock(islock + '')
  672. .then(res => {
  673. if (res.code === 0) {
  674. that.ExchangeMessage('success', islock ? '屏蔽成功' : '放开成功')
  675. } else {
  676. that.ExchangeMessage('error', islock ? '屏蔽失败' : '放开失败')
  677. }
  678. }).catch(err => {
  679. console.error(err)
  680. })
  681. } else if (res.cancel) {
  682. return false
  683. //用户点击取消按钮触发
  684. }
  685. }
  686. })
  687. } else {
  688. this.PowerChangeStatusTips()
  689. }
  690. },
  691. //急停、中止
  692. PausePLC(isStop) {
  693. if (this.powerChangeStatus) {
  694. let that = this
  695. const text = isStop == 1 ? '急停机器人' : '中止机器人'
  696. uni.showModal({
  697. title: `请确认${text}?`,
  698. content: '',
  699. success: function(res) {
  700. if (res.confirm) {
  701. that.$http.plcStop(isStop + '')
  702. .then(res => {
  703. if (res.code === 0) {
  704. that.ExchangeMessage('success', isStop == 1 ? '急停指令下发成功' : '中止指令下发成功')
  705. } else {
  706. that.ExchangeMessage('error', isStop == 1 ? '急停指令下发失败' : '中止指令下发失败')
  707. }
  708. }).catch(err => {
  709. console.error(err)
  710. })
  711. } else if (res.cancel) {
  712. return false
  713. //用户点击取消按钮触发
  714. }
  715. }
  716. })
  717. } else {
  718. this.PowerChangeStatusTips()
  719. }
  720. },
  721. //选择电池仓位数
  722. BatterySelected(CurrentStore) {
  723. if(this.selectStoreCode.length == 0) {
  724. this.selectStoreCode.push(CurrentStore.storeCode);
  725. } else if(this.selectStoreCode.length == 1) {
  726. if(this.selectStoreCode.indexOf(CurrentStore.storeCode) > -1) {
  727. this.selectStoreCode = [];
  728. } else {
  729. this.selectStoreCode.push(CurrentStore.storeCode);
  730. }
  731. } else if(this.selectStoreCode.length == 2) {
  732. if(this.selectStoreCode.indexOf(CurrentStore.storeCode) > -1) {
  733. this.selectStoreCode.forEach((item, index) => {
  734. if(item == CurrentStore.storeCode) {
  735. this.selectStoreCode.splice(index, 1);
  736. }
  737. });
  738. } else {
  739. this.selectStoreCode.splice(0, 1);
  740. this.selectStoreCode.push(CurrentStore.storeCode);
  741. }
  742. }
  743. this.$set(this.BatteryIsSelectArr, CurrentStore.storeCode - 1, !this.BatteryIsSelectArr[CurrentStore
  744. .storeCode - 1]) //选中电池取反
  745. if (this.BatteryIsSelectArr[CurrentStore.storeCode - 1]) {
  746. this.BatterySelectAllArr = [...this.BatterySelectAllArr, CurrentStore] //将选中的电池放入数组中
  747. } else {
  748. this.BatterySelectAllArr = this.BatterySelectAllArr.filter(item => item.storeCode != CurrentStore
  749. .storeCode) //将取消选中的电池从数组中移除
  750. }
  751. if (this.BatterySelectAllArr.length === 3) {
  752. this.$set(this.BatteryIsSelectArr, this.BatterySelectAllArr[0].storeCode - 1, false)
  753. this.BatterySelectAllArr.shift() //删除第一个元素
  754. }
  755. // console.log(this.BatterySelectAllArr)
  756. },
  757. //开始调仓
  758. HandleChangeStore() {
  759. let that = this
  760. if (this.powerChangeStatus) {
  761. let source = 0
  762. let target = 0
  763. if (this.BatterySelectAllArr.length === 2) {
  764. source = this.BatterySelectAllArr[0].storeState ? 1 : 0
  765. target = this.BatterySelectAllArr[1].storeState ? 1 : 0
  766. }
  767. if (this.BatterySelectAllArr.length !== 2 || source == target) {
  768. that.ExchangeMessage('warn', '请选择一个电池和一个空仓位!')
  769. return
  770. } else if (this.BatterySelectAllArr[0].getChgState == 2 || this.BatterySelectAllArr[1].getChgState ==
  771. 2) {
  772. that.ExchangeMessage('warn',
  773. `【${this.BatterySelectAllArr[0].storeState===1?this.BatterySelectAllArr[0].storeCode:this.BatterySelectAllArr[1].storeCode}】号仓位电池未断电,请断电后在进行调仓!`
  774. )
  775. } else {
  776. const params = {
  777. sourceCode: this.BatterySelectAllArr[0].storeState === 1 ? this.BatterySelectAllArr[0]
  778. .storeCode : this.BatterySelectAllArr[1].storeCode, //选有电池的仓位号
  779. targetCode: this.BatterySelectAllArr[1].storeState !== 1 ? this.BatterySelectAllArr[1]
  780. .storeCode : this.BatterySelectAllArr[0].storeCode //选空仓的仓位号
  781. }
  782. uni.showModal({
  783. title: '',
  784. content: `请确认将【${params.sourceCode}】号仓位电池移至【${params.targetCode}号】仓位?`,
  785. success: function(res) {
  786. if (res.confirm) {
  787. // that.ExchangeMessage('success', '调仓指令已下发,请等待!')
  788. that.$http.RuleChangestorage(params)
  789. .then(res => {
  790. if (res.code === 0) {
  791. that.clearStore()
  792. }
  793. that.ExchangeMessage(res.code === 0 ? 'success' : 'error', res
  794. .code === 0 ? '调仓指令下发成功!' : res.msg)
  795. }).catch(err => {
  796. console.error(err)
  797. })
  798. } else if (res.cancel) {
  799. return false
  800. //用户点击取消按钮触发
  801. }
  802. }
  803. })
  804. }
  805. } else {
  806. this.PowerChangeStatusTips()
  807. }
  808. },
  809. //消防换仓
  810. HandleFireStore() {
  811. let that = this
  812. if (this.powerChangeStatus) {
  813. if (this.BatterySelectAllArr.length !== 1 || this.BatterySelectAllArr[0].storeState !== 1) {
  814. this.ExchangeMessage('warn', '请选择一个电池操作消防换仓!')
  815. } else if (this.BatterySelectAllArr[0].getChgState == 2) {
  816. that.ExchangeMessage('warn', `【${this.BatterySelectAllArr[0].storeCode}】号仓位电池未断电,请断电后在进行消防换仓!`)
  817. } else {
  818. const params = {
  819. targetCode: this.BatterySelectAllArr[0].storeCode
  820. }
  821. uni.showModal({
  822. title: '',
  823. content: `请确认消防换仓,将【${that.BatterySelectAllArr[0].storeCode}】号仓位电池移至消防仓?`,
  824. success: function(res) {
  825. if (res.confirm) {
  826. // that.ExchangeMessage('success', '消防换仓指令已下发,请等待!')
  827. that.$http.FireChangestorage(params)
  828. .then(res => {
  829. if (res.code === 0) {
  830. that.clearStore()
  831. }
  832. that.ExchangeMessage(res.code === 0 ? 'success' : 'error',
  833. res.code === 0 ? '消防换仓指令下发成功!' : '消防换仓指令下发失败!')
  834. }).catch(err => {
  835. console.error(err)
  836. })
  837. } else if (res.cancel) {
  838. return false
  839. //用户点击取消按钮触发
  840. }
  841. }
  842. })
  843. }
  844. } else {
  845. this.PowerChangeStatusTips()
  846. }
  847. },
  848. //换电操作开关提示公用方法
  849. PowerChangeStatusTips() {
  850. this.ExchangeMessage('warn', '请先开启换电操作!')
  851. },
  852. //清空选择的仓位
  853. clearStore() {
  854. this.BatterySelectAllArr = []
  855. this.BatteryIsSelectArr = [false, false, false, false, false, false, false, false]
  856. },
  857. //websocket连接函数
  858. InitWs() {
  859. // uni.showLoading({
  860. // title:'数据加载中...'
  861. // })
  862. if (this.ws != null) {
  863. this.ws.close()
  864. this.ws = null
  865. }
  866. if (this.timer != null) {
  867. clearInterval(this.timer)
  868. this.timer = null
  869. }
  870. let token = this.$storage.getJson('token');
  871. if (token == null) {
  872. uni.navigateTo({
  873. url: '/pages/login/index'
  874. })
  875. return false;
  876. }
  877. this.ws = uni.connectSocket({
  878. url: this.$config.web_socket_url + token,
  879. header: {
  880. 'content-type': 'application/json'
  881. },
  882. complete: () => {}
  883. })
  884. this.ws.onOpen(() => {
  885. console.log('socket连接成功')
  886. let msg = {
  887. type: "page",
  888. payload: "power-change-monitoring"
  889. }
  890. this.ws.send({
  891. data: JSON.stringify(msg)
  892. })
  893. })
  894. this.ws.onMessage((res) => {
  895. this.onMessageTime = new Date();
  896. let d = JSON.parse(res.data)
  897. // console.log(d)
  898. // uni.hideLoading()
  899. //电池仓位列表
  900. if (d.storeInfoList) {
  901. this.storeInfoList = d.storeInfoList
  902. uni.hideLoading()
  903. }
  904. //日志列表
  905. if (d.logList) {
  906. this.logList = d.logList.reverse()
  907. }
  908. // 车辆信息
  909. if (d.vehicleInfo) {
  910. this.vehicleInfo = d.vehicleInfo
  911. }
  912. // 电池信息
  913. if (d.batteryInfo) {
  914. this.batteryInfo = d.batteryInfo
  915. }
  916. //机器人状态
  917. if (d.robotInfoVo) {
  918. this.robotInfoVo = d.robotInfoVo
  919. }
  920. //换电进度
  921. if (d.swapProcess) {
  922. this.swapProcess = d.swapProcess
  923. //清空调仓数据
  924. if(d.swapProcess.swapId){
  925. this.xfTargetCodeData={}//消防调仓
  926. this.TcInfoVoData={}//调仓
  927. }
  928. }
  929. //选电模式
  930. if (d.batChooseMode >= 0) {
  931. this.pamars.batChooseMode = d.batChooseMode
  932. //锁止状态
  933. }
  934. if(d.hasOwnProperty('forbidLockState')){
  935. this.forbidLockState=d.forbidLockState
  936. }
  937. //调仓
  938. if (d.sourceCode && d.targetCode) {
  939. this.TcInfoVoData = {
  940. sourceCode: d.sourceCode,
  941. targetCode: d.targetCode,
  942. actionFlow: d.actionFlow,
  943. startTime: d.startTime,
  944. chargerState: d.chargerState,
  945. }
  946. this.xfTargetCodeData={}
  947. this.TcNumber=0
  948. }else{
  949. if(this.TcNumber<=5){
  950. this.TcNumber=this.TcNumber+1
  951. }else{
  952. this.TcInfoVoData={}//调仓
  953. }
  954. }
  955. //消防换仓
  956. if (d.xfTargetCode) {
  957. this.xfTargetCodeData = {
  958. xfTargetCode: d.xfTargetCode,
  959. chargerState: d.chargerState,
  960. startTime: d.startTime,
  961. actionFlow: d.actionFlow,
  962. }
  963. this.TcInfoVoData={}
  964. this.XfNumber=0
  965. }else{
  966. if(this.XfNumber<=5){
  967. this.XfNumber=this.XfNumber+1
  968. }else{
  969. this.xfTargetCodeData={}//调仓
  970. }
  971. }
  972. })
  973. // 监听WebSocket关闭事件
  974. this.ws.onClose(() => {
  975. console.log('WebSocket连接已关闭!')
  976. })
  977. this.ws.onError(() => {
  978. console.log("WebSocket连接错误")
  979. })
  980. if(this.timer == null){
  981. //检查断开重连
  982. this.timer = setInterval(() => {
  983. // if (this.ws==null || this.ws.readyState != 1) {
  984. // this.ws.close()
  985. // this.ws = null
  986. // console.log('检查断开重连')
  987. // this.InitWs()
  988. // }
  989. if(this.ws==null){
  990. console.log('ws为null,检查断开重连')
  991. this.InitWs()
  992. }else if(this.ws.readyState != 1){
  993. this.ws.close()
  994. this.ws = null
  995. console.log('未连接成功,检查断开重连')
  996. this.InitWs()
  997. }
  998. }, 2000)
  999. }
  1000. },
  1001. },
  1002. }
  1003. </script>
  1004. <style lang="scss" scoped>
  1005. @import './index.scss';
  1006. .popup-container {
  1007. width: 300px;
  1008. height: 200px;
  1009. background: #263042;
  1010. .popup-title {
  1011. height: 60px;
  1012. display: flex;
  1013. padding: 0 15px;
  1014. border-bottom: 1px solid #C7D2DF;
  1015. position: relative;
  1016. .title-text {
  1017. text-align: left;
  1018. background: #263042;
  1019. font-weight: 500;
  1020. color: #FFFFFF;
  1021. font-size: 20px;
  1022. line-height: 60px;
  1023. width: 200px;
  1024. }
  1025. .title-close {
  1026. text-align: right;
  1027. background: #263042;
  1028. font-weight: 500;
  1029. color: #FFFFFF;
  1030. font-size: 20px;
  1031. line-height: 60px;
  1032. width: 60px;
  1033. }
  1034. }
  1035. .popup-content {
  1036. display: flex;
  1037. margin-top: 20px;
  1038. padding: 0 20px 0 10px;
  1039. }
  1040. }
  1041. .carPosition {
  1042. // margin-top: 76px;
  1043. .carForm {
  1044. display: flex;
  1045. justify-items: flex-end;
  1046. view:first-child {
  1047. font-weight: 400;
  1048. color: rgba(153, 174, 197, 0.65);
  1049. font-size: 14px;
  1050. flex: 1;
  1051. text-align: right;
  1052. line-height: 34px;
  1053. }
  1054. .uni-input {
  1055. width: 245px;
  1056. height: 34px;
  1057. background: rgba(255, 255, 255, 0);
  1058. border-radius: 2px;
  1059. border: 1px solid #263042;
  1060. text-indent: 15px;
  1061. font-size: 14px;
  1062. font-weight: 400;
  1063. color: #FFFFFF;
  1064. }
  1065. }
  1066. .CarnoData {
  1067. width: 274px;
  1068. height: 227px;
  1069. background-image: url('/static/change/noData.png');
  1070. background-size: 100% 100%;
  1071. margin: 20px 43px;
  1072. }
  1073. .Carlist {
  1074. display: flex;
  1075. flex-direction: column;
  1076. width: 100%;
  1077. .carDetail {
  1078. width: 360px;
  1079. height: 169px;
  1080. border-radius: 8px;
  1081. margin-bottom: 16px;
  1082. background-image: url('/static/change/car-bg.png');
  1083. background-size: 100% 100%;
  1084. box-sizing: border-box;
  1085. padding: 20px;
  1086. display: flex;
  1087. flex-direction: column;
  1088. justify-content: space-between;
  1089. .plateNumber {
  1090. display: flex;
  1091. align-items: center;
  1092. height: 24px;
  1093. line-height: 24px;
  1094. .icon {
  1095. margin-right: 8px;
  1096. }
  1097. .pNumber {
  1098. font-size: 16px;
  1099. font-weight: 600;
  1100. color: #FFFFFF;
  1101. }
  1102. image {
  1103. width: 18px;
  1104. height: 18px;
  1105. vertical-align: middle;
  1106. margin-bottom: 3px;
  1107. }
  1108. }
  1109. .vinMa {
  1110. display: flex;
  1111. view:first-child {
  1112. width: 60px;
  1113. font-size: 14px;
  1114. font-weight: 400;
  1115. color: rgba(153, 174, 197, 0.65);
  1116. }
  1117. view:last-child {
  1118. flex: 1;
  1119. font-size: 14px;
  1120. font-weight: 400;
  1121. color: rgba(255, 255, 255, 0.85);
  1122. }
  1123. }
  1124. }
  1125. }
  1126. }
  1127. .status-only {
  1128. display: flex;
  1129. width: 100%;
  1130. align-items: center;
  1131. .circle {
  1132. width: 24px;
  1133. height: 24px;
  1134. margin-right: 4px;
  1135. image {
  1136. width: 24px;
  1137. height: 24px;
  1138. }
  1139. }
  1140. .descript {
  1141. font-size: 14px;
  1142. font-weight: 500;
  1143. width: 78px;
  1144. color: rgba(153, 174, 197, 0.65);
  1145. text-shadow: 0px 0px 4px rgba(39, 69, 201, 0.5);
  1146. }
  1147. .carTitle {
  1148. width: 68px !important;
  1149. }
  1150. .frameText {
  1151. color: #C7D2DF;
  1152. text-shadow: 0px 0px 4px #0027D8;
  1153. }
  1154. .frame {
  1155. flex: 1;
  1156. position: relative;
  1157. height: 32px;
  1158. text-indent: 15px;
  1159. font-size: 14px;
  1160. font-weight: 500;
  1161. color: #91FDB9;
  1162. line-height: 32px;
  1163. text-shadow: 0px 0px 4px #0027D8;
  1164. border: 1px solid #334568;
  1165. box-sizing: border-box;
  1166. .shinning {
  1167. position: absolute;
  1168. border: 1px solid #c9f8ff;
  1169. border-radius: 1px;
  1170. left: -1px;
  1171. top: -1px;
  1172. }
  1173. .editCar {
  1174. cursor: pointer;
  1175. position: absolute;
  1176. right: 20px;
  1177. top: 3px;
  1178. width: 18px;
  1179. height: 18px;
  1180. img {
  1181. width: 18px;
  1182. height: 18px;
  1183. }
  1184. }
  1185. .isflag {
  1186. color: #ED7735;
  1187. text-shadow: 0px 0px 4px rgba(39, 69, 201, 0.5);
  1188. }
  1189. .isblue {
  1190. color: #148CFA;
  1191. }
  1192. .btn {
  1193. display: flex;
  1194. position: absolute;
  1195. right: 15px;
  1196. top: 5px;
  1197. button {
  1198. width: 48px;
  1199. height: 28px;
  1200. background: #91FDB9;
  1201. border-radius: 2px 2px 2px 2px;
  1202. font-size: 16px;
  1203. font-weight: 400;
  1204. line-height: 28px;
  1205. text-align: center;
  1206. border: none;
  1207. padding: 0;
  1208. color: black;
  1209. }
  1210. button:hover {
  1211. background: #69b889;
  1212. }
  1213. }
  1214. }
  1215. }
  1216. .subtilte-only {
  1217. display: flex;
  1218. flex-direction: column;
  1219. border-top: $lineColor solid 1px;
  1220. border-bottom: $lineColor solid 1px;
  1221. width: 100%;
  1222. .title {
  1223. width: 100%;
  1224. background-color: $titColor;
  1225. margin: 1px 0px;
  1226. height: 24px;
  1227. display: flex;
  1228. .icon {
  1229. width: 17px;
  1230. height: 10px;
  1231. background-image: url('/static/public/ico2.png');
  1232. background-size: 100% 100%;
  1233. margin-left: 2px;
  1234. }
  1235. .name {
  1236. font-size: 16px;
  1237. margin-left: -5px;
  1238. height: 24px;
  1239. line-height: 22px;
  1240. font-weight: 600;
  1241. letter-spacing: 1px;
  1242. text-shadow: 0 0 2px #1753ce, 0 0 2px #1753ce, 0 0 2px #1753ce, 0 0 2px #1753ce;
  1243. color: white;
  1244. }
  1245. .letter {
  1246. color: #2A3855;
  1247. font-size: 10px;
  1248. margin-left: 5px;
  1249. padding-top: 5px;
  1250. font-weight: 600;
  1251. }
  1252. .freeze{
  1253. margin-left: auto;
  1254. display: flex;
  1255. view{
  1256. padding: 3px 8px;
  1257. width: auto;
  1258. text-align: center;
  1259. background: #263042;
  1260. font-weight: 400;
  1261. color: #FFFFFF;
  1262. font-size: 14px;
  1263. height: 24px;
  1264. box-sizing: border-box;
  1265. line-height: 18px;
  1266. border-radius: 2px;
  1267. margin-right: 12px;
  1268. }
  1269. .active{
  1270. background: #91FDB9;
  1271. color: #000000;
  1272. }
  1273. }
  1274. .switch {
  1275. margin-left: auto;
  1276. color: white;
  1277. height: 20px;
  1278. font-size: 12px;
  1279. width: 100px;
  1280. display: flex;
  1281. align-items: center;
  1282. uni-switch {
  1283. margin-top: 3px;
  1284. }
  1285. }
  1286. .log-descript {
  1287. margin-left: auto;
  1288. font-size: 12px;
  1289. font-weight: 400;
  1290. color: rgba(153, 174, 197, 0.65);
  1291. line-height: 22px;
  1292. padding-right: 26px;
  1293. }
  1294. }
  1295. }
  1296. .carLeft{
  1297. color: #fff !important;
  1298. }
  1299. .carRight{
  1300. color: #fff !important;
  1301. }
  1302. .isshowactive{
  1303. color: rgba(153, 174, 197, 0.65) !important;
  1304. }
  1305. </style>