OCPPOperations.vue 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845
  1. <template>
  2. <div class="card-container">
  3. <div class="card-content">
  4. <div class="ocpp-content">
  5. <div class="section-title">Selected Stations</div>
  6. <div class="filter-view">
  7. <el-select
  8. class="filter-view-item"
  9. v-model="listQuery.pageVo.providerPk"
  10. placeholder="Service Provider"
  11. @change="changeSite"
  12. clearable>
  13. <el-option
  14. v-for="(item, index) in providerOptions"
  15. :key="index"
  16. :label="item.providerName"
  17. :value="item.providerPk"/>
  18. </el-select>
  19. <el-select
  20. class="filter-view-item"
  21. clearable
  22. filterable
  23. remote
  24. v-model="listQuery.pageVo.sitePk"
  25. :remote-method="filterSite"
  26. :loading="siteLoading"
  27. placeholder="Site Name"
  28. @change="changeSite">
  29. <el-option
  30. v-for="(item, index) in siteList"
  31. :key="index"
  32. :label="item.siteName"
  33. :value="item.sitePk"/>
  34. </el-select>
  35. </div>
  36. <div class="flexc" style="padding: 20px 0; justify-content: flex-end;">
  37. <el-button
  38. type="primary"
  39. @click="selectNone">
  40. Select None
  41. </el-button>
  42. <el-button
  43. style="margin-left: 15px;"
  44. type="primary"
  45. @click="selectAll">
  46. Select All
  47. </el-button>
  48. </div>
  49. <el-table
  50. style="width: 100%;min-height: 50vh;"
  51. v-loading="listLoading"
  52. :data="stationList">
  53. <el-table-column
  54. :label="item.label"
  55. align="center"
  56. class-name="fixed-width"
  57. v-for="(item, index) in columns"
  58. :key="index"
  59. :width="item.width">
  60. <template slot-scope="{row, $index}">
  61. <el-checkbox
  62. v-if="item.action"
  63. v-model="row[item.key]"
  64. @change="checked => changeRow($index, checked)"/>
  65. <span v-else>{{ row[item.key] }}</span>
  66. </template>
  67. </el-table-column>
  68. </el-table>
  69. <div class="right">
  70. <pagination
  71. v-show="total > 0"
  72. :total="total"
  73. :page.sync="listQuery.pageNo"
  74. :limit.sync="listQuery.pageSize"
  75. @pagination="handlePageChange" />
  76. </div>
  77. </div>
  78. <div class="ocpp-content">
  79. <el-form
  80. :model="operationForm"
  81. :rules="rule"
  82. ref="operationForm"
  83. label-width="200px"
  84. label-position="left">
  85. <div class="section-title">OCPP Operation</div>
  86. <el-form-item
  87. label="Operation:"
  88. prop="operation">
  89. <el-select
  90. class="flex-item"
  91. v-model="operationForm.operation"
  92. @change="changeOperation">
  93. <el-option
  94. v-for="(item, index) in operationList"
  95. :key="index"
  96. :label="item.name"
  97. :value="index"
  98. v-if="item.api"/>
  99. </el-select>
  100. </el-form-item>
  101. <div class="section-title" style="padding-top: 20px;" v-loading="paramLoading">Parameters</div>
  102. <el-form-item
  103. label="Filter Type:"
  104. prop="filterType"
  105. v-if="paramsOption.filterTypeOption.length > 0">
  106. <el-select
  107. v-model="operationForm.filterType"
  108. class="flex-item"
  109. @change="changeFilterType">
  110. <el-option
  111. v-for="(item, index) in paramsOption.filterTypeOption"
  112. :key="index"
  113. :label="item.name"
  114. :value="item.value"/>
  115. </el-select>
  116. </el-form-item>
  117. <el-form-item
  118. label="Charging Profile ID:"
  119. prop="chargingProfilePk"
  120. v-if="paramsOption.needChargingProfile">
  121. <el-select
  122. v-model="operationForm.chargingProfilePk"
  123. class="flex-item">
  124. <el-option
  125. v-for="(item, index) in paramsOption.chargingProfileOption"
  126. :key="index"
  127. :label="item.value + ' (' + item.name + ')'"
  128. :value="item.value"/>
  129. </el-select>
  130. </el-form-item>
  131. <el-form-item
  132. label="Connector ID:"
  133. prop="connectorId"
  134. v-if="paramsOption.needConnector">
  135. <el-select
  136. v-model="operationForm.connectorId"
  137. class="flex-item">
  138. <el-option
  139. v-for="(item, index) in paramsOption.connectorIds"
  140. :key="index"
  141. :label="item"
  142. :value="item"/>
  143. </el-select>
  144. </el-form-item>
  145. <el-form-item
  146. label="Transaction ID:"
  147. prop="transactionId"
  148. v-if="paramsOption.needActConnector">
  149. <el-select
  150. v-model="operationForm.transactionId"
  151. class="flex-item">
  152. <el-option
  153. v-for="(item, index) in paramsOption.connectorActIds"
  154. :key="index"
  155. :label="item"
  156. :value="item"/>
  157. </el-select>
  158. </el-form-item>
  159. <el-form-item
  160. label="Mobile Number/E-mail:"
  161. prop="idTagInfo"
  162. v-if="paramsOption.idTagAll.length > 0">
  163. <el-select
  164. v-model="operationForm.idTagInfo"
  165. filterable
  166. remote
  167. :remote-method="filterMobile"
  168. class="flex-item"
  169. :loading="tagLoading"
  170. placeholder="Search with mobile / email">
  171. <el-option
  172. v-for="(item, index) in paramsOption.idTags"
  173. :key="index"
  174. :label="item.name"
  175. :value="item.value"/>
  176. </el-select>
  177. </el-form-item>
  178. <el-form-item
  179. label="Availability Type:"
  180. prop="availType"
  181. v-if="paramsOption.availTypeOption.length > 0">
  182. <el-select
  183. v-model="operationForm.availType"
  184. class="flex-item"
  185. placeholder="Select">
  186. <el-option
  187. v-for="(item, index) in paramsOption.availTypeOption"
  188. :key="index"
  189. :label="item.name"
  190. :value="item.value"/>
  191. </el-select>
  192. </el-form-item>
  193. <el-form-item
  194. label="Charging Profile Purpose:"
  195. prop="chargingProfilePurpose"
  196. v-if="paramsOption.needChargingProfilePurpose">
  197. <el-select
  198. v-model="operationForm.chargingProfilePurpose"
  199. class="flex-item">
  200. <el-option
  201. v-for="(item, index) in paramsOption.chargingPurposeOption"
  202. :key="index"
  203. :label="item.name"
  204. :value="item.value"/>
  205. </el-select>
  206. </el-form-item>
  207. <el-form-item
  208. label="Stack Level (integer):"
  209. v-if="paramsOption.needChargingProfilePurpose">
  210. <el-input
  211. v-model="operationForm.stackLevel"
  212. class="flex-item"/>
  213. </el-form-item>
  214. <el-form-item
  215. label="Key Type:"
  216. prop="keyType"
  217. v-if="paramsOption.keyTypeOption.length > 0">
  218. <el-select
  219. v-model="operationForm.keyType"
  220. class="flex-item"
  221. placeholder="Select"
  222. @change="changeKeyType">
  223. <el-option
  224. v-for="(item, index) in paramsOption.keyTypeOption"
  225. :key="index"
  226. :label="item.name"
  227. :value="item.value"/>
  228. </el-select>
  229. </el-form-item>
  230. <div
  231. class="multi-select"
  232. v-if="paramsOption.confKeyOption.length > 0 && paramsOption.selectMultConfig">
  233. <span class="note-span">Info: If none selected, the charge point returns a list of all configuration settings.</span>
  234. <el-form-item
  235. label="Configuration Key:">
  236. <el-select
  237. v-model="operationForm.confKeyList"
  238. class="flex-item"
  239. style="align-items: flex-start;"
  240. placeholder="Select multiple"
  241. :multiple="true">
  242. <el-option
  243. v-for="(item, index) in paramsOption.confKeyOption"
  244. :key="index"
  245. :label="item.name"
  246. :value="item.value"/>
  247. </el-select>
  248. </el-form-item>
  249. </div>
  250. <el-form-item
  251. label="Configuration Key:"
  252. prop="confKey"
  253. v-else-if="paramsOption.confKeyOption.length > 0 && operationForm.keyType == 'PREDEFINED'">
  254. <el-select
  255. v-model="operationForm.confKey"
  256. class="flex-item"
  257. placeholder="Select">
  258. <el-option
  259. v-for="(item, index) in paramsOption.confKeyOption"
  260. :key="index"
  261. :label="item.name"
  262. :value="item.value"/>
  263. </el-select>
  264. </el-form-item>
  265. <el-form-item
  266. label="Custom Configuration Key:"
  267. prop="customConfKey"
  268. label-width="205px"
  269. v-if="paramsOption.keyTypeOption.length > 0 && operationForm.keyType == 'CUSTOM'">
  270. <el-input
  271. v-model="operationForm.customConfKey"
  272. class="flex-item"/>
  273. </el-form-item>
  274. <el-form-item
  275. label="Value:"
  276. v-if="paramsOption.keyTypeOption.length > 0">
  277. <el-input
  278. v-model="operationForm.value"
  279. class="flex-item"/>
  280. </el-form-item>
  281. <el-form-item
  282. label="Reset Type:"
  283. prop="resetType"
  284. v-if="paramsOption.resetTypeOption.length > 0">
  285. <el-select
  286. class="flex-item"
  287. v-model="operationForm.resetType">
  288. <el-option
  289. v-for="(item, index) in paramsOption.resetTypeOption"
  290. :key="index"
  291. :label="item.name"
  292. :value="item.value"/>
  293. </el-select>
  294. </el-form-item>
  295. <template v-if="operationInfo.value == 'UF'">
  296. <el-form-item
  297. label="Location(directory URI):"
  298. prop="location">
  299. <el-input
  300. v-model="operationForm.location"
  301. class="flex-item"/>
  302. </el-form-item>
  303. <el-form-item
  304. label="Retries(integer):">
  305. <el-input
  306. v-model="operationForm.retries"
  307. class="flex-item"/>
  308. </el-form-item>
  309. <el-form-item
  310. label="Retry Interval(integer):">
  311. <el-input
  312. v-model="operationForm.retryInterval"
  313. class="flex-item"/>
  314. </el-form-item>
  315. <el-form-item
  316. label="Retrieve Date/Time:"
  317. prop="retrieve">
  318. <el-date-picker
  319. v-model="operationForm.retrieve"
  320. type="datetime"
  321. format="yyyy-MM-dd HH:mm"
  322. value-format="yyyy-MM-dd HH:mm"
  323. default-time="12:00:00"
  324. class="flex-item"/>
  325. </el-form-item>
  326. </template>
  327. <template v-if="operationInfo.value == 'ICA'">
  328. <el-form-item
  329. label="Certificate Type:"
  330. prop="certificateType"
  331. v-if="paramsOption.certificateTypeOption">
  332. <el-select
  333. v-model="operationForm.certificateType"
  334. class="flex-item">
  335. <el-option
  336. v-for="(item, index) in paramsOption.certificateTypeOption"
  337. :key="index"
  338. :label="item"
  339. :value="item"/>
  340. </el-select>
  341. </el-form-item>
  342. <el-form-item
  343. label="Certificate:"
  344. prop="certificate">
  345. <el-input
  346. v-model="operationForm.certificate"
  347. class="flex-item"
  348. type="textarea"
  349. :autosize="autosize"/>
  350. </el-form-item>
  351. </template>
  352. <div class="perform">
  353. <el-button
  354. style="margin-left: 15px;"
  355. type="primary"
  356. :loading="btnLoading"
  357. @click="perform">
  358. Perform
  359. </el-button>
  360. </div>
  361. </el-form>
  362. </div>
  363. </div>
  364. </div>
  365. </template>
  366. <script>
  367. import {getServiceProviderOptions} from '../../utils'
  368. import Pagination from '@/components/Pagination'
  369. import site from '../../http/api/site'
  370. import ocpp from '../../http/api/ocpp'
  371. import util from './operationUtil'
  372. const NOT_SPECIFIC = 'Not for a specific connector'
  373. export default {
  374. data() {
  375. return {
  376. tagLoading: false,
  377. listLoading: false,
  378. siteLoading: false,
  379. paramLoading: false,
  380. btnLoading: false,
  381. siteList: [],
  382. siteKeyword: '',
  383. stationList: [],
  384. providerOptions: [],
  385. total: 0,
  386. listQuery: {
  387. pageNo: 1,
  388. pageSize: 10,
  389. pageVo: {
  390. sitePk: '',
  391. stationId: '',
  392. providerPk: ''
  393. }
  394. },
  395. operationInfo: {},
  396. operationList: ocpp.getOperationList(),
  397. operationForm: {
  398. value: '',
  399. confKey: '',
  400. keyType: '',
  401. resetType: '',
  402. operation: '',
  403. availType: '',
  404. idTagInfo: '',
  405. filterType: '',
  406. location: "",
  407. retrieve: "",
  408. retries: "",
  409. retryInterval: "",
  410. confKeyList: [],
  411. stationIds: [],
  412. stackLevel: '',
  413. connectorId: '',
  414. transactionId: '',
  415. customConfKey: '',
  416. chargingProfilePk: '',
  417. chargingProfilePurpose: undefined,
  418. certificateType: '',
  419. certificate: ''
  420. },
  421. paramsOption: {
  422. idTags: [],
  423. idTagAll: [],
  424. connectorIds: [],
  425. connectorActIds: [],
  426. needConnector: false,
  427. needActConnector: false,
  428. selectMultConfig: false,
  429. confKeyOption: [],
  430. keyTypeOption: [],
  431. availTypeOption: [],
  432. resetTypeOption: [],
  433. filterTypeOption: [],
  434. needCustomCoinfig: false,
  435. needChargingProfile: false,
  436. chargingProfileOption: [],
  437. chargingPurposeOption: [],
  438. certificateTypeOption: [],
  439. needChargingProfilePurpose: false
  440. },
  441. rule: {
  442. idTagInfo: {
  443. required: true,
  444. trigger: 'change',
  445. message: 'Please select ID tag'
  446. },
  447. operation: {
  448. required: true,
  449. trigger: 'change',
  450. message: 'Please select operation'
  451. },
  452. confKey: {
  453. required: true,
  454. trigger: 'change',
  455. message: 'Please select configuration key'
  456. },
  457. keyType: {
  458. required: true,
  459. trigger: 'change',
  460. message: 'Please select key type'
  461. },
  462. resetType: {
  463. required: true,
  464. trigger: 'change',
  465. message: 'Please select reset type'
  466. },
  467. availType: {
  468. required: true,
  469. trigger: 'change',
  470. message: 'Please select availability type'
  471. },
  472. filterType: {
  473. required: true,
  474. trigger: 'change',
  475. message: 'Please select filter type'
  476. },
  477. connectorId: {
  478. required: true,
  479. trigger: 'change',
  480. message: 'Please select a connector ID'
  481. },
  482. confKeyList: {
  483. required: true,
  484. trigger: 'change',
  485. message: 'Please select at last least 1 config key'
  486. },
  487. transactionId: {
  488. required: true,
  489. trigger: 'change',
  490. message: 'Please select a active transaction ID'
  491. },
  492. customConfKey: {
  493. required: true,
  494. trigger: 'blur',
  495. message: 'Please input custom configuration key'
  496. },
  497. chargingProfilePk: {
  498. required: true,
  499. trigger: 'change',
  500. message: 'Please select Charging Profile ID'
  501. },
  502. chargingProfilePurpose: {
  503. required: true,
  504. trigger: 'change',
  505. message: 'Please select Charging Profile Purpose'
  506. },
  507. certificateType: {
  508. required: true,
  509. trigger: 'change',
  510. message: 'Please select certificate type'
  511. },
  512. certificate: {
  513. required: true,
  514. trigger: 'blur',
  515. message: 'Please input certificate'
  516. },
  517. location: {
  518. required: true,
  519. trigger: 'blur',
  520. message: 'Please input location'
  521. },
  522. retrieve: {
  523. required: true,
  524. trigger: 'change',
  525. message: 'Please select retrieve date time'
  526. }
  527. },
  528. columns: [{
  529. key: 'siteName',
  530. label: 'Site Name'
  531. }, {
  532. key: 'stationId',
  533. label: 'Station ID'
  534. }, {
  535. key: 'lastHeartbeat',
  536. label: 'Last Heartbeat'
  537. }, {
  538. key: 'checked',
  539. label: 'Select',
  540. action: true,
  541. width: 70
  542. }],
  543. autosize: {
  544. minRows: 5,
  545. maxRows: 10
  546. },
  547. searchTag: ""
  548. }
  549. },
  550. components: { Pagination },
  551. created() {
  552. this.getAllProvider();
  553. this.getAllSite();
  554. },
  555. methods: {
  556. filterSite(word) {
  557. this.siteKeyword = word;
  558. this.siteLoading = true;
  559. this.getAllSite();
  560. },
  561. getAllSite() {
  562. site.getAllSiteList({siteName: this.siteKeyword}).then(res => {
  563. var list = []
  564. /*if (this.siteKeyword == '') {
  565. list = [{siteName: 'All', sitePk: ''}]
  566. }*/
  567. if (res.data && res.data.length > 0) {
  568. this.siteList = list.concat(res.data)
  569. } else {
  570. this.siteList = []
  571. }
  572. this.siteLoading = false;
  573. this.changeSite();
  574. }).catch(error => {
  575. this.siteLoading = false;
  576. this.$message({
  577. message: error,
  578. type: 'error'
  579. })
  580. });
  581. },
  582. getAllProvider() {
  583. getServiceProviderOptions(list => {
  584. this.providerOptions = list;
  585. });
  586. },
  587. changeSite() {
  588. this.listLoading = true;
  589. const res = ocpp.getStationPages(this.listQuery).then(res => {
  590. if (res.success) {
  591. this.total = res.total;
  592. this.stationList = res.data;
  593. }
  594. }).catch(error => {
  595. this.$message({
  596. message: error,
  597. type: 'error'
  598. })
  599. }).finally(() => {
  600. this.listLoading = false;
  601. });
  602. },
  603. async changeOperation(index) {
  604. this.paramLoading = true;
  605. this.operationForm = {
  606. operation: this.operationForm.operation,
  607. value: '',
  608. confKey: '',
  609. keyType: '',
  610. resetType: '',
  611. availType: '',
  612. idTagInfo: '',
  613. filterType: '',
  614. location: "",
  615. retrieve: "",
  616. retries: "",
  617. retryInterval: "",
  618. confKeyList: [],
  619. stationIds: [],
  620. stackLevel: '',
  621. connectorId: '',
  622. transactionId: '',
  623. customConfKey: '',
  624. chargingProfilePk: '',
  625. chargingProfilePurpose: undefined
  626. }
  627. this.operationInfo = this.operationList[index];
  628. this.selectNone();
  629. this.paramsOption = await util.getOperationParams(this.operationInfo, /*this.getCheckedStation()*/);
  630. //console.log('-----', paramsOption);
  631. this.paramLoading = false;
  632. this.$refs['operationForm'].clearValidate()
  633. },
  634. async changeRow(index, checked) {
  635. if (checked && this.operationInfo.singleStation) {
  636. this.selectNone();
  637. this.stationList[index].checked = true;
  638. }
  639. this.operationForm.stationIds = this.getCheckedStation();
  640. if (this.paramsOption.needConnector) {
  641. this.operationForm.connectorId = '';
  642. let list = await util.getConnectorIds(this.operationForm.stationIds);
  643. if (this.operationInfo.value == 'RSTART') {
  644. list.unshift(NOT_SPECIFIC)
  645. }
  646. this.paramsOption.connectorIds = list
  647. }
  648. if (this.paramsOption.needActConnector) {
  649. this.operationForm.transactionId = '';
  650. let list = await util.getActiveConnectorIds(this.operationForm.stationIds);
  651. this.paramsOption.connectorActIds = list;
  652. }
  653. },
  654. changeKeyType() {
  655. if (this.operationForm.keyType == 'PREDEFINED') {
  656. this.operationForm.confKey = '';
  657. } else {
  658. this.operationForm.customConfKey = '';
  659. }
  660. this.$refs['operationForm'].clearValidate()
  661. },
  662. changeFilterType() {
  663. if (this.operationForm.filterType == 'ChargingProfileId') {
  664. this.operationForm.connectorId = '';
  665. this.paramsOption.needConnector = false;
  666. this.paramsOption.needChargingProfile = true;
  667. this.operationForm.chargingProfilePurpose = undefined;
  668. this.paramsOption.needChargingProfilePurpose = false;
  669. } else {
  670. this.paramsOption.needConnector = true;
  671. this.operationForm.chargingProfilePk = '';
  672. this.paramsOption.needChargingProfile = false;
  673. this.paramsOption.needChargingProfilePurpose = true;
  674. if (this.paramsOption.connectorIds.length == 0) {
  675. this.changeRow();
  676. }
  677. }
  678. this.$refs['operationForm'].clearValidate()
  679. },
  680. getCheckedStation() {
  681. let list = [];
  682. this.stationList.forEach(item => {
  683. if (item.checked)
  684. list.push(item.stationId)
  685. })
  686. return list;
  687. },
  688. selectNone() {
  689. this.stationList.forEach(item => {
  690. item.checked = false;
  691. })
  692. this.paramsOption.connectorIds = [];
  693. this.operationForm.connectorId = '';
  694. this.operationForm.stationIds = [];
  695. },
  696. selectAll() {
  697. if (!this.operationInfo.singleStation) {
  698. this.stationList.forEach(item => {
  699. item.checked = true;
  700. })
  701. } else {
  702. this.stationList[0].checked = true;
  703. }
  704. this.changeRow();
  705. },
  706. handlePageChange() {
  707. this.changeSite()
  708. },
  709. perform() {
  710. this.$forceUpdate();
  711. this.$refs['operationForm'].validate(result => {
  712. if (result) {
  713. //this.addStation();
  714. if (this.operationForm.stationIds.length == 0) {
  715. this.$message({
  716. type: 'error',
  717. message: 'Please select at least 1 charge point'
  718. })
  719. } else if (this.operationInfo.api) {
  720. this.btnLoading = true;
  721. const params = Object.assign({}, this.operationForm)
  722. //对参数做特殊处理
  723. if (params.connectorId === NOT_SPECIFIC) {
  724. params.connectorId = ''
  725. }
  726. if (params.idTagInfo !== '') {
  727. params.idTagInfo = JSON.parse(params.idTagInfo)
  728. }
  729. ocpp.sendPerform(this.operationInfo.api, params).then(res => {
  730. this.btnLoading = false;
  731. if (res.data.taskId) {
  732. this.$router.push({path: '/ocpp-operations/result/' + res.data.taskId});
  733. }
  734. }).catch(err => {
  735. this.btnLoading = false;
  736. this.$message({
  737. type: 'error',
  738. message: err
  739. })
  740. });
  741. }
  742. }
  743. })
  744. },
  745. filterMobile(word) {
  746. if (word) {
  747. this.searchTag = word;
  748. setTimeout(() => {
  749. this.searchMobile(word)
  750. }, 300)
  751. } else {
  752. this.paramsOption.idTags = []
  753. this.paramsOption.idTags.push(...this.paramsOption.idTagAll)
  754. }
  755. },
  756. searchMobile(word) {
  757. console.log(this.searchTag, word);
  758. if (this.searchTag === word) {
  759. this.tagLoading = true;
  760. util.filterMobile(word, tags => {
  761. this.paramsOption.idTags = tags;
  762. this.tagLoading = false;
  763. })
  764. }
  765. }
  766. }
  767. }
  768. </script>
  769. <style scoped="scoped" lang='scss'>
  770. @import '../../styles/variables.scss';
  771. .card-container {
  772. width: 100%;
  773. padding: 20px 40px;
  774. min-height: $mainAppMinHeight;
  775. background-color: #F0F5FC;
  776. }
  777. .card-content {
  778. display: flex;
  779. overflow-x: auto;
  780. padding: 15px 5px;
  781. border-radius: 6px;
  782. flex-direction: row;
  783. flex-wrap: wrap-reverse;
  784. background-color: white;
  785. }
  786. .ocpp-content {
  787. flex: 1;
  788. min-width: 520px;
  789. padding: 0 35px 0 15px;
  790. }
  791. .section-title {
  792. color: #333;
  793. margin-top: 20px;
  794. margin-bottom: 30px;
  795. font-size: 16px;
  796. user-select: none;
  797. line-height: 24px;
  798. font-weight: 500;
  799. white-space: nowrap;
  800. font-family: sans-serif;
  801. text-transform: uppercase;
  802. }
  803. .perform {
  804. text-align: center;
  805. padding: 20px 80px 30px 0;
  806. }
  807. .multi-select {
  808. position: relative;
  809. min-height: 200px;
  810. }
  811. .note-span {
  812. top: 40px;
  813. left: 0px;
  814. width: 180px;
  815. color: #333333;
  816. padding: 6px 10px;
  817. font-size: 12px;
  818. border-radius: 3px;
  819. position: absolute;
  820. background-color: #56D905;
  821. }
  822. .flex-item {
  823. width: 100%;
  824. max-width: 320px;
  825. }
  826. @media screen and (max-width: 500px) {
  827. .card-container {
  828. padding: 0px;
  829. }
  830. .card-content {
  831. padding: 10px;
  832. }
  833. .ocpp-content {
  834. flex: 1;
  835. min-width: 320px;
  836. padding-right: 20px;
  837. }
  838. .perform {
  839. padding: 20px 0;
  840. }
  841. }
  842. </style>