AddSite.vue 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446
  1. <template>
  2. <div class="view-container">
  3. <div class="view-content" v-loading="pageLoading">
  4. <el-form
  5. ref="addSiteForm"
  6. :rules="rules"
  7. :model="siteForm"
  8. label-position="left"
  9. label-width="100px"
  10. style="width: 100%;">
  11. <el-row :gutter="20">
  12. <el-col :span="12">
  13. <div class="section-title">
  14. Site Information
  15. </div>
  16. <el-form-item
  17. label="Site Name:"
  18. prop="siteInformation.siteName">
  19. <el-input
  20. v-model="siteForm.siteInformation.siteName"
  21. class="input-text" />
  22. </el-form-item>
  23. <el-form-item
  24. prop="siteInformation.latitude"
  25. label="Latitude:">
  26. <el-input
  27. v-model="siteForm.siteInformation.latitude"
  28. class="input-text" />
  29. </el-form-item>
  30. <el-form-item
  31. prop="siteInformation.longitude"
  32. label="Longitude:">
  33. <el-input
  34. v-model="siteForm.siteInformation.longitude"
  35. class="input-text" />
  36. </el-form-item>
  37. </el-col>
  38. <el-col :span="12">
  39. <div class="section-title">
  40. Additional Information
  41. </div>
  42. <div style="display: flex; ">
  43. <el-form-item
  44. label-width="130px"
  45. label="Operating Hours:"
  46. class="flex-item">
  47. <el-input
  48. :disabled="siteForm.additionalInformation.endlessService"
  49. v-model="siteForm.additionalInformation.operatingHours"
  50. class="input-text" />
  51. </el-form-item>
  52. <el-switch
  53. style="margin-left: 10px"
  54. inactive-text="24/7"
  55. @change="endlessServiceSwitchChange"
  56. v-model="siteForm.additionalInformation.endlessService">
  57. </el-switch>
  58. </div>
  59. <div style="display: flex; ">
  60. <el-form-item
  61. label-width="130px"
  62. label="Parking Fee:"
  63. class="flex-item">
  64. <el-input
  65. :disabled="siteForm.additionalInformation.free"
  66. v-model="siteForm.additionalInformation.parkingFee"
  67. class="input-text" />
  68. </el-form-item>
  69. <el-switch
  70. style="margin-left: 10px"
  71. inactive-text="Free"
  72. @change="freeSwitchChange"
  73. v-model="siteForm.additionalInformation.free">
  74. </el-switch>
  75. </div>
  76. <div class="flex">
  77. <el-form-item
  78. label-width="130px"
  79. label="Additional Notes:"
  80. class="flex-item flex">
  81. <el-input
  82. v-model="siteForm.additionalInformation.additionalNotes"
  83. type="textarea"
  84. :autosize="additionalNotesAutosize"
  85. class="input-text" />
  86. </el-form-item>
  87. <div class="flexl" style="font-size: 13px; margin-left: 10px;">
  88. <span>Enable</span>
  89. <span>Idle Fee</span>
  90. </div>
  91. <el-switch
  92. style="margin-left: 5px;"
  93. v-model="siteForm.idle.enableIdleFee"/>
  94. </div>
  95. </el-col>
  96. </el-row>
  97. <el-row :gutter="20">
  98. <el-col :span="12">
  99. <el-form-item
  100. prop="siteInformation.type"
  101. label="Type:">
  102. <div class="type-row" v-for="(item, index) in siteTypeTable">
  103. <el-time-picker
  104. v-model="item.startTime"
  105. format="HH:mm"
  106. value-format="HH:mm"
  107. :placeholder="item.label"
  108. :disabled="isSiteTypeEnable(index)"/>
  109. <el-time-picker
  110. v-model="item.endTime"
  111. format="HH:mm"
  112. value-format="HH:mm"
  113. placeholder="End Time"
  114. :disabled="isSiteTypeEnable(index)"/>
  115. </div>
  116. </el-form-item>
  117. </el-col>
  118. </el-row>
  119. <div class="sparator"></div>
  120. <div class="section-title">
  121. EMAIL
  122. </div>
  123. <el-form
  124. :model="this"
  125. :rules="rule"
  126. ref="recipForm"
  127. label-position="left"
  128. label-width="150px">
  129. <el-row :gutter="20">
  130. <el-col :xs="24" :sm="16" :md="10" :lg="9">
  131. <el-form-item
  132. label="Recipients:"
  133. prop="recipient">
  134. <el-input
  135. class="add-text"
  136. v-model="recipient"
  137. placeholder="Add text"
  138. maxlength="50"/>
  139. </el-form-item>
  140. </el-col>
  141. <el-col :span="8">
  142. <el-button
  143. type="primary"
  144. icon="el-icon-plus"
  145. @click="addRecipient">
  146. Add
  147. </el-button>
  148. </el-col>
  149. </el-row>
  150. <el-row :gutter="20">
  151. <el-col :span="24">
  152. <el-form-item
  153. label="Added Recipients:">
  154. <div class="receip-item" v-for="(item, index) in recipients" :key="index">
  155. <span>{{item}}</span>
  156. <i class="el-icon-close" @click="deleteRecipient(index)"></i>
  157. </div>
  158. <div
  159. class="link-button"
  160. v-if="recipients.length > 0"
  161. @click="clearAllRecipient">Clear All</div>
  162. </el-form-item>
  163. </el-col>
  164. </el-row>
  165. </el-form>
  166. <!-- <div class="sparator"></div>
  167. <div class="section-title">
  168. TIME CONFIGURATION
  169. </div>
  170. <el-table
  171. :data="siteTypeTable"
  172. fit
  173. style="width: 100%; max-width: 1000px;">
  174. <el-table-column
  175. label="Site Type With Schedule"
  176. prop="label"/>
  177. <el-table-column
  178. label="All Day"
  179. width="150px">
  180. <template slot-scope="{row, $index}">
  181. <el-switch v-model="row.allDay" :disabled="isSiteTypeEnable($index, true)"></el-switch>
  182. </template>
  183. </el-table-column>
  184. <el-table-column
  185. label="Start Time">
  186. <template slot-scope="{row, $index}">
  187. <el-time-picker
  188. v-model="row.startTime"
  189. format="HH:mm"
  190. value-format="HH:mm"
  191. placeholder="Start Time"
  192. :disabled="isSiteTypeEnable($index)">
  193. </el-time-picker>
  194. </template>
  195. </el-table-column>
  196. <el-table-column
  197. label="End Time">
  198. <template slot-scope="{row, $index}">
  199. <el-time-picker
  200. v-model="row.endTime"
  201. format="HH:mm"
  202. value-format="HH:mm"
  203. placeholder="End Time"
  204. :disabled="isSiteTypeEnable($index)">
  205. </el-time-picker>
  206. </template>
  207. </el-table-column>
  208. </el-table> -->
  209. <!-- prop="siteInformation.type"
  210. label="Type">
  211. <el-select
  212. v-model="siteForm.siteInformation.type"
  213. class="input-text">
  214. <el-option
  215. v-for="item in siteTypeOptions"
  216. :key="item.name"
  217. :label="item.name"
  218. :value="item.value" />
  219. </el-select>
  220. </el-form-item> -->
  221. <div class="sparator"></div>
  222. <div class="section-title">
  223. ADDRESS
  224. </div>
  225. <el-row :gutter="20">
  226. <el-col :span="12">
  227. <el-form-item
  228. prop="address.country"
  229. label="Country:">
  230. <el-select
  231. v-model="siteForm.address.country"
  232. class="input-text">
  233. <el-option
  234. v-for="item in countryOptions"
  235. :key="item.name"
  236. :label="item.name"
  237. :value="item.value" />
  238. </el-select>
  239. </el-form-item>
  240. </el-col>
  241. <el-col :span="12">
  242. <el-form-item
  243. prop="address.street"
  244. label-width="130px"
  245. label="Street:">
  246. <el-input
  247. v-model="siteForm.address.street"
  248. class="input-text" />
  249. </el-form-item>
  250. </el-col>
  251. </el-row>
  252. <el-row :gutter="20">
  253. <el-col :span="12">
  254. <el-form-item
  255. prop="address.city"
  256. label="City:">
  257. <el-input
  258. v-model="siteForm.address.city"
  259. class="input-text"
  260. @keyup.enter.native="handleFilter" />
  261. </el-form-item>
  262. </el-col>
  263. <el-col :span="12">
  264. <el-form-item
  265. prop="address.postalCode"
  266. label-width="130px"
  267. label="Postal Code:">
  268. <el-input
  269. v-model="siteForm.address.postalCode"
  270. class="input-text"
  271. @keyup.enter.native="handleFilter" />
  272. </el-form-item>
  273. </el-col>
  274. </el-row>
  275. <div class="sparator"></div>
  276. <div class="section-title">
  277. CHARGE RATE
  278. </div>
  279. <div
  280. class="rate-list-view"
  281. v-for="(item, index) in siteForm.chargeRates"
  282. :key="item.ratePk">
  283. <el-form-item
  284. label="Type"
  285. label-width="60px"
  286. :prop="'chargeRates.' + index + '.chargeTypePk'"
  287. :rules="rules.chargeRate.chargeTypePk">
  288. <el-select
  289. v-model="item.chargeTypePk"
  290. class="rate-text">
  291. <el-option
  292. v-for="item in chargeTypeOptions"
  293. :key="item.chargeTypePk"
  294. :label="item.chargeType"
  295. :value="item.chargeTypePk" />
  296. </el-select>
  297. </el-form-item>
  298. <el-form-item
  299. label="Rate"
  300. label-width="60px"
  301. :prop="'chargeRates.' + index + '.rate'"
  302. :rules="rules.chargeRate.rate">
  303. <el-input
  304. v-model="item.rate"
  305. class="rate-text" />
  306. </el-form-item>
  307. <div class="ratePunit">/</div>
  308. <el-form-item
  309. label-width="0px"
  310. prop="type">
  311. <el-select
  312. v-model="item.rateType"
  313. class="rate-type">
  314. <el-option
  315. v-for="item in rateTypeOptions"
  316. :key="item.name"
  317. :label="item.value"
  318. :value="item.value" />
  319. </el-select>
  320. </el-form-item>
  321. <img
  322. class="list-item-icon"
  323. @click="handleClickSubChargeRateButton(item, index)"
  324. src="../../assets/form-list-sub.png"/>
  325. </div>
  326. <div class="rate-list-view">
  327. <el-form-item
  328. label="Type"
  329. label-width="50px"
  330. prop="tempChargeRate.chargeTypePk"
  331. :rules="rules.chargeRate.chargeTypePk">
  332. <el-select
  333. v-model="siteForm.tempChargeRate.chargeTypePk"
  334. class="rate-text">
  335. <el-option
  336. v-for="item in chargeTypeOptions"
  337. :key="item.chargeTypePk"
  338. :label="item.chargeType"
  339. :value="item.chargeTypePk" />
  340. </el-select>
  341. </el-form-item>
  342. <el-form-item
  343. label="Rate"
  344. label-width="50px"
  345. prop="tempChargeRate.rate"
  346. :rules="rules.chargeRate.rate">
  347. <el-input
  348. v-model="siteForm.tempChargeRate.rate"
  349. class="rate-text" />
  350. </el-form-item>
  351. <div class="ratePunit">/</div>
  352. <el-form-item
  353. label-width="0px">
  354. <el-select
  355. v-model="siteForm.tempChargeRate.rateType"
  356. class="rate-type">
  357. <el-option
  358. v-for="item in rateTypeOptions"
  359. :key="item.name"
  360. :label="item.value"
  361. :value="item.value" />
  362. </el-select>
  363. </el-form-item>
  364. <img
  365. class="list-item-icon"
  366. @click="handleClickSubTempChargeRateButton"
  367. src="../../assets/form-list-sub.png"/>
  368. <img
  369. class="list-item-icon"
  370. @click="handleClickAddChargeRateButton"
  371. src="../../assets/form-list-add.png"/>
  372. </div>
  373. <div class="sparator" ></div>
  374. <div class="specialChangeRate">
  375. <div class="section-title">
  376. SPECIAL CHARGE RATE
  377. <el-switch v-model="swtSpecialRate"/>
  378. </div>
  379. <div
  380. v-for="(item, index) in siteForm.specialChargeRates"
  381. :key="index"
  382. v-if="swtSpecialRate"
  383. class="rate-list-view">
  384. <el-form-item
  385. label="Company:"
  386. label-width="90px"
  387. :prop="'specialChargeRates.' + index + '.fleetCompanyId'"
  388. :rules="rules.specialChargeRates.fleetCompanyId">
  389. <el-select
  390. v-model="item.fleetCompanyId"
  391. class="rate-text-max">
  392. <el-option
  393. v-for="item in companyOptions"
  394. :key="item.fleetCompanyId"
  395. :label="item.fleetCompanyName"
  396. :value="item.fleetCompanyId">
  397. </el-option>
  398. </el-select>
  399. </el-form-item>
  400. <el-form-item
  401. label="Type:"
  402. label-width="55px"
  403. :prop="'specialChargeRates.' + index + '.chargeTypePk'"
  404. :rules="rules.specialChargeRates.chargeTypePk">
  405. <el-select v-model="item.chargeTypePk" class="rate-text">
  406. <el-option
  407. v-for="item in chargeTypeOptions"
  408. :key="item.chargeTypePk"
  409. :label="item.chargeType"
  410. :value="item.chargeTypePk">
  411. </el-option>
  412. </el-select>
  413. </el-form-item>
  414. <el-form-item
  415. label="Rate:"
  416. label-width="55px"
  417. :prop="'specialChargeRates.' + index + '.rate'"
  418. :rules="rules.specialChargeRates.rate">
  419. <el-input v-model="item.rate" class="rate-text"></el-input>
  420. </el-form-item>
  421. <div class="ratePunit">/</div>
  422. <el-form-item
  423. label=""
  424. label-width="0px"
  425. :prop="'specialChargeRates.' + index + '.rateType'"
  426. :rules="rules.specialChargeRates.rateType">
  427. <el-select v-model="item.rateType" class="rate-type">
  428. <el-option
  429. v-for="item in rateTypeOptions"
  430. :key="item.name"
  431. :label="item.value"
  432. :value="item.value"/>
  433. </el-select>
  434. </el-form-item>
  435. <img
  436. class="list-item-icon"
  437. @click="handleClickSubSpecialRateButton(item, index)"
  438. src="../../assets/form-list-sub.png"/>
  439. <img
  440. v-if="siteForm.specialChargeRates.length - 1 === index"
  441. class="list-item-icon"
  442. @click="handleClickAddSpecialRateButton"
  443. src="../../assets/form-list-add.png"/>
  444. </div>
  445. </div>
  446. <reservation
  447. :enable="siteForm.reservation.enable"
  448. :timeLimit="siteForm.reservation.timeLimit"
  449. @enable="reservationTimeLimitEnable"
  450. @time-limit-change="reservationTimeLimitChange"
  451. />
  452. <div class="sparator" ></div>
  453. <div class="specialChangeRate">
  454. <div class="section-title">
  455. LOAD BALANCING
  456. </div>
  457. <Balancing v-model="balancingForm" title="Add"/>
  458. <!-- <el-row
  459. :gutter="20"
  460. v-for="(item, index) in balancingForm.siteChargingProfiles"
  461. :key="index">
  462. <el-col :span="6" :offset="0">
  463. <el-form-item
  464. label="Chargers In-Use:"
  465. label-width="150px">
  466. <el-select v-model="item.boxInUse">
  467. <el-option
  468. v-for="(item,index) in [1,2]"
  469. :key="index"
  470. :label="item"
  471. :value="item"
  472. />
  473. </el-select>
  474. </el-form-item>
  475. </el-col>
  476. <el-col :span="8" :offset="1">
  477. <el-form-item
  478. label="Charging Profile:"
  479. label-width="150px">
  480. <el-select v-model="item.chargingProfilePk" filterable>
  481. <el-option
  482. v-for="(item,index) in chargingProfileOPtions"
  483. :key="index"
  484. :label="item.description"
  485. :value="item.chargingProfilePk"
  486. />
  487. </el-select>
  488. </el-form-item>
  489. </el-col>
  490. <el-col :span="4" :offset="0">
  491. <img
  492. class="list-item-icon"
  493. @click="handelSubSiteChargingProfiles(index)"
  494. src="../../assets/form-list-sub.png"
  495. />
  496. <img
  497. v-if="balancingForm.siteChargingProfiles.length - 1 === index"
  498. class="list-item-icon"
  499. @click="handleAddSiteChargingProfiles"
  500. src="../../assets/form-list-add.png"
  501. />
  502. </el-col>
  503. </el-row> -->
  504. </div>
  505. <div v-if="enableFleetWhiteList()">
  506. <div class="sparator"></div>
  507. <div class="section-title">
  508. WHITELIST FLEET
  509. </div>
  510. <div
  511. class="rate-list-view"
  512. v-for="(item, index) in siteForm.fleetWhitelist"
  513. :key="index">
  514. <el-form-item
  515. label-width="50px"
  516. label="Fleet">
  517. <el-select
  518. v-model="item.fleetCompanyId"
  519. style="margin-right: 10px;">
  520. <el-option
  521. v-for="item in companyOptions"
  522. :key="item.fleetCompanyId"
  523. :label="item.fleetCompanyName"
  524. :value="item.fleetCompanyId">
  525. </el-option>
  526. </el-select>
  527. </el-form-item>
  528. <img
  529. class="list-item-icon"
  530. @click="handleClickSubWhiteFleetButton(item, index)"
  531. src="../../assets/form-list-sub.png"/>
  532. <img
  533. v-if="index === siteForm.fleetWhitelist.length - 1"
  534. class="list-item-icon"
  535. @click="handleClickAddWhiteFleetButton"
  536. src="../../assets/form-list-add.png"/>
  537. </div>
  538. </div>
  539. <div v-if="enableUserWhiteList()">
  540. <div class="sparator"></div>
  541. <div class="section-title">
  542. WHITELIST USERS
  543. </div>
  544. <div
  545. class="rate-list-view"
  546. v-for="(item, index) in siteForm.whitelistUser"
  547. :key="index">
  548. <el-form-item
  549. label-width="130px"
  550. label="Mobile Number"
  551. :rules="rules.whitelistUser.mobileNumber"
  552. :prop="'whitelistUser.' + index + '.mobileNumber'">
  553. <el-input
  554. v-model="item.mobileNumber"
  555. class="rate-text" />
  556. </el-form-item>
  557. <el-form-item
  558. label-width="140px"
  559. label="Licence Number"
  560. :rules="rules.whitelistUser.licenceNumber"
  561. :prop="'whitelistUser.' + index + '.licenceNumber'">
  562. <el-input
  563. v-model="item.licenceNumber"
  564. class="rate-text" />
  565. </el-form-item>
  566. <img
  567. class="list-item-icon"
  568. @click="handleClickSubWhiteUserButton(item, index)"
  569. src="../../assets/form-list-sub.png"/>
  570. <img
  571. v-if="index === siteForm.whitelistUser.length - 1"
  572. class="list-item-icon"
  573. @click="handleClickAddWhiteUserButton"
  574. src="../../assets/form-list-add.png"/>
  575. </div>
  576. </div>
  577. <div v-if="siteForm.idle.enableIdleFee">
  578. <div class="sparator"></div>
  579. <div class="section-title">Idle Fee SETTINGS</div>
  580. <el-row :gutter="20">
  581. <el-col :span="12">
  582. <el-form-item
  583. label="Effective From:"
  584. label-width="130px"
  585. prop="idle.effectiveFrom">
  586. <el-time-picker
  587. v-model="siteForm.idle.effectiveFrom"
  588. class="input-text"
  589. format="HH:mm"
  590. value-format="HH:mm"/>
  591. </el-form-item>
  592. </el-col>
  593. <el-col :span="12">
  594. <el-form-item
  595. label="Effective To:"
  596. label-width="130px"
  597. prop="idle.effectiveTo">
  598. <el-time-picker
  599. v-model="siteForm.idle.effectiveTo"
  600. class="input-text"
  601. format="HH:mm"
  602. value-format="HH:mm"/>
  603. </el-form-item>
  604. </el-col>
  605. <el-col :span="12">
  606. <el-form-item
  607. label="Idle Fee:"
  608. label-width="130px"
  609. prop="idle.idleFee">
  610. <el-input
  611. v-model="siteForm.idle.idleFee"
  612. class="input-text"
  613. oninput="value=value.replace(/[^\d.]/g, '').replace(/\.{2,}/g, '.').replace('.', '$#$').replace(/\./g, '').replace('$#$', '.').replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3').replace(/^\./g, '')"
  614. maxlength="6"/>
  615. </el-form-item>
  616. </el-col>
  617. <el-col :span="12">
  618. <el-form-item
  619. label="Every (minute):"
  620. label-width="130px"
  621. prop="idle.everyMinute">
  622. <el-input
  623. maxlength="4"
  624. v-model.number="siteForm.idle.everyMinute"
  625. class="input-text"/>
  626. </el-form-item>
  627. </el-col>
  628. <el-col :span="12">
  629. <el-form-item
  630. label="Effective Date:"
  631. label-width="130px"
  632. prop="idle.effectiveDate">
  633. <el-date-picker
  634. v-model="siteForm.idle.effectiveDate"
  635. class="input-text"
  636. format="yyyy-MM-dd"
  637. value-format="yyyy-MM-dd"/>
  638. </el-form-item>
  639. </el-col>
  640. </el-row>
  641. </div>
  642. <div class="sparator" style="margin: 10px -80px;"></div>
  643. <div class="buttons">
  644. <el-button
  645. class="cancel-button"
  646. type="primary"
  647. @click="handleClickCancleButton">
  648. Cancel
  649. </el-button>
  650. <el-button
  651. class="confirm-button"
  652. type="primary"
  653. @click="handleClickConfigUpateButton">
  654. Save
  655. </el-button>
  656. </div>
  657. </el-form>
  658. </div>
  659. </div>
  660. </template>
  661. <script>
  662. import Balancing from './components/Balancing'
  663. import Reservation from './components/Reservation'
  664. import waves from '@/directive/waves' // waves directive
  665. import site from '../../http/api/site'
  666. import { fetchFleetCompanyOptions } from '@/http/api/driver'
  667. export default {
  668. name: 'AddSite',
  669. directives: { waves },
  670. components: { Balancing, Reservation },
  671. async created() {
  672. this.pageLoading = true;
  673. this.getChargeTypeOptions()
  674. this.getRateTypeOptions()
  675. this.getSiteTypeOptions()
  676. this.getCountryOptions()
  677. await this.getCompanyOptions()
  678. //this.getChargingProfileOPtions()
  679. this.pageLoading = false;
  680. },
  681. data() {
  682. return {
  683. pageLoading: false,
  684. rateTypeOptions: [],
  685. chargeTypeOptions: [],
  686. siteTypeOptions: [],
  687. countryOptions: [],
  688. companyOptions: [],
  689. chargingProfileOPtions: [],
  690. recipient: '',
  691. recipients: [],
  692. siteTypeTable: [{
  693. siteType: "",
  694. allDay: false,
  695. startTime: "",
  696. endTime: ""
  697. }],
  698. additionalNotesAutosize: {
  699. minRows: 3,
  700. maxRows: 6,
  701. },
  702. balancingForm: {
  703. loadBalancing: 'dynamic',
  704. staticMaxAmpere: 0,
  705. siteChargingProfiles: [{
  706. boxInUse: '',
  707. chargingProfilePk: ''
  708. }],
  709. },
  710. siteForm: {
  711. specialChargeRates: [
  712. {
  713. fleetCompanyId: '',
  714. chargeTypePk: '',
  715. rate: '',
  716. rateType: '',
  717. }
  718. ],
  719. siteInformation: {
  720. siteName: '',
  721. latitude: '',
  722. longitude: '',
  723. type: 'PUBLIC',
  724. },
  725. additionalInformation: {
  726. operatingHours: '',
  727. parkingFee: '',
  728. additionalNotes: '',
  729. endlessService: false,
  730. free: false,
  731. },
  732. address: {
  733. street: '',
  734. postalCode: '',
  735. city: '',
  736. country: '',
  737. },
  738. tempChargeRate: {
  739. chargeTypePk: '',
  740. rate: '',
  741. rateType: '',
  742. },
  743. chargeRates: [],
  744. whitelistUser: [{
  745. licenceNumber: '',
  746. mobileNumber: '',
  747. }],
  748. fleetWhitelist: [{
  749. //siteFleetId: "",
  750. fleetCompanyId: ''
  751. }],
  752. reservation: {
  753. enable: false,
  754. timeLimit: 15,
  755. },
  756. idle: {
  757. enableIdleFee: false,
  758. idleFee: '',
  759. effectiveDate: '',
  760. effectiveFrom: '',
  761. effectiveTo: '',
  762. everyMinute: ''
  763. }
  764. },
  765. rule: {
  766. "recipient": {
  767. pattern: /^[a-zA-Z0-9]+[\S]+@[a-zA-Z0-9_-]+[\.][\Sa-zA-Z]+$/,
  768. trigger: 'blur',
  769. message: 'Please type a correct recipient'
  770. }
  771. },
  772. rules: {
  773. siteInformation: {
  774. siteName: {
  775. required: true,
  776. trigger: 'blur',
  777. message: 'Site Name is required',
  778. },
  779. latitude: [{
  780. required: true,
  781. trigger: 'blur',
  782. message: 'Latitude is required',
  783. }, {
  784. pattern: /^[\-\+]?((0|([1-8]\d?))(\.\d{1,8})?|90(\.0{1,8})?)$/,
  785. trigger: 'blur',
  786. message: 'Please type a correct latitude',
  787. }],
  788. longitude: [{
  789. required: true,
  790. trigger: 'blur',
  791. message: 'Longitude is required',
  792. }, {
  793. pattern: /^[\-\+]?(0(\.\d{1,8})?|([1-9](\d)?)(\.\d{1,8})?|1[0-7]\d{1}(\.\d{1,8})?|180\.0{1,8})$/,
  794. trigger: 'blur',
  795. message: 'Please type a correct longitude',
  796. }],
  797. type: {
  798. required: true,
  799. trigger: 'change',
  800. message: 'Site Type is required',
  801. },
  802. },
  803. siteChargingProfiles: {
  804. boxInUse: [{
  805. required: true,
  806. trigger: 'change',
  807. message: 'Chargers In-Use is required',
  808. }, {
  809. type: 'number',
  810. message: 'Chargers In-Use is a number',
  811. }],
  812. chargingProfilePk: {
  813. required: true,
  814. trigger: 'change',
  815. message: 'Charging Profileis required',
  816. },
  817. },
  818. address: {
  819. street: {
  820. required: true,
  821. trigger: 'blur',
  822. message: 'Address is required',
  823. },
  824. postalCode: {
  825. required: true,
  826. trigger: 'blur',
  827. message: 'Postal Code is required',
  828. },
  829. city: {
  830. required: true,
  831. trigger: 'blur',
  832. message: 'City is required',
  833. },
  834. country: {
  835. required: true,
  836. trigger: 'blur',
  837. message: 'Country is required',
  838. },
  839. },
  840. chargeRate: {
  841. chargeTypePk: {
  842. required: true,
  843. trigger: 'change',
  844. message: 'Charge Type is required',
  845. },
  846. rate: [{
  847. required: true,
  848. trigger: 'blur',
  849. message: 'Rate is required',
  850. }, {
  851. pattern: /^\d+(\.\d+)?$/,
  852. trigger: 'blur',
  853. message: 'Please type a correct rate',
  854. }],
  855. rateType: {
  856. required: true,
  857. trigger: 'change',
  858. message: 'Rate Type is required',
  859. }
  860. },
  861. specialChargeRates: {
  862. fleetCompanyId: {
  863. required: true,
  864. trigger: 'change',
  865. message: 'Fleet Company is required',
  866. },
  867. chargeTypePk: {
  868. required: true,
  869. trigger: 'change',
  870. message: 'Charge Type is required',
  871. },
  872. rate: [{
  873. required: true,
  874. trigger: 'blur',
  875. message: 'Rate is required',
  876. }, {
  877. pattern: /^\d+(\.\d+)?$/,
  878. trigger: 'blur',
  879. message: 'Please type a correct rate',
  880. }],
  881. rateType: {
  882. required: true,
  883. trigger: 'change',
  884. message: 'Rate Type is required',
  885. }
  886. },
  887. whitelistUser: {
  888. licenceNumber: {
  889. required: true,
  890. trigger: 'blur',
  891. message: 'Licence Number is required',
  892. },
  893. mobileNumber: {
  894. required: true,
  895. trigger: 'blur',
  896. message: 'Mobile Number is required',
  897. },
  898. },
  899. idle: {
  900. idleFee: {
  901. required: true,
  902. trigger: 'blur',
  903. message: 'Idle fee is required'
  904. },
  905. effectiveDate: {
  906. required: true,
  907. trigger: 'change',
  908. message: 'Effective Date is required'
  909. },
  910. effectiveFrom: {
  911. required: true,
  912. trigger: 'change',
  913. message: 'Effective From is required'
  914. },
  915. effectiveTo: {
  916. required: true,
  917. trigger: 'change',
  918. message: 'Effective To is required'
  919. },
  920. everyMinute: [{
  921. required: true,
  922. trigger: 'blur',
  923. message: 'Every is required'
  924. }, {
  925. type: 'number',
  926. message: 'Every is a number'
  927. }]
  928. }
  929. },
  930. swtSpecialRate: false
  931. }
  932. },
  933. methods: {
  934. handleClickAddSpecialRateButton() {
  935. this.siteForm.specialChargeRates.push(
  936. {
  937. fleetCompanyId: this.companyOptions[0].fleetCompanyId,
  938. chargeTypePk: this.chargeTypeOptions[0].chargeTypePk,
  939. rate: '',
  940. rateType: this.rateTypeOptions[0].value,
  941. }
  942. )
  943. },
  944. handleClickSubSpecialRateButton(specialRate, index) {
  945. this.siteForm.specialChargeRates.splice(index, 1)
  946. if (this.siteForm.specialChargeRates.length === 0) {
  947. this.siteForm.specialChargeRates.push(
  948. {
  949. fleetCompanyId: this.companyOptions[0].fleetCompanyId,
  950. chargeTypePk: this.chargeTypeOptions[0].chargeTypePk,
  951. rate: '',
  952. rateType: this.rateTypeOptions[0].value,
  953. }
  954. )
  955. }
  956. },
  957. reservationTimeLimitEnable(enable) {
  958. this.siteForm.reservation.enable = enable
  959. },
  960. reservationTimeLimitChange(timeLimit) {
  961. this.siteForm.reservation.timeLimit = timeLimit
  962. },
  963. endlessServiceSwitchChange(value) {
  964. if (value) {
  965. this.siteForm.additionalInformation.operatingHours = ""
  966. }
  967. },
  968. freeSwitchChange(value) {
  969. if (value) {
  970. this.siteForm.additionalInformation.parkingFee = ""
  971. }
  972. },
  973. getChargeTypeOptions() {
  974. site.getChargeTypeList().then((response) => {
  975. const { data = [] } = response
  976. this.chargeTypeOptions = data
  977. this.setTempChargeTypeDefaultValue()
  978. this.siteForm.specialChargeRates[0].chargeTypePk = data[0].chargeTypePk
  979. });
  980. },
  981. setTempChargeTypeDefaultValue() {
  982. if (this.chargeTypeOptions.length > 0) {
  983. const defaultValue = this.chargeTypeOptions[0].chargeTypePk
  984. this.siteForm.tempChargeRate.chargeTypePk = defaultValue
  985. }
  986. },
  987. getRateTypeOptions() {
  988. site.getRateTypeList().then((response) => {
  989. const { data = [] } = response
  990. this.rateTypeOptions = data
  991. this.setTempRateTypeDefaultValue()
  992. this.siteForm.specialChargeRates[0].rateType = data[0].value
  993. });
  994. },
  995. setTempRateTypeDefaultValue() {
  996. if (this.rateTypeOptions.length > 0) {
  997. const defaultValue = this.rateTypeOptions[0].value
  998. this.siteForm.tempChargeRate.rateType = defaultValue
  999. }
  1000. },
  1001. getSiteTypeOptions() {
  1002. site.getSiteTypeList().then((response) => {
  1003. this.siteTypeOptions = response.data
  1004. const { data } = response;
  1005. if (data && data.length > 0) {
  1006. this.siteTypeTable = [];
  1007. data.forEach(item => {
  1008. this.siteTypeTable.push({
  1009. label: item.name,
  1010. siteType: item.value,
  1011. allDay: false,
  1012. startTime: "",
  1013. endTime: ""
  1014. })
  1015. })
  1016. //this.siteForm.siteInformation.type = data[0].value
  1017. }
  1018. });
  1019. },
  1020. getCompanyOptions() {
  1021. fetchFleetCompanyOptions().then((response) => {
  1022. const { data, success } = response
  1023. if (success) {
  1024. this.companyOptions = data
  1025. if (data && data.length > 0) {
  1026. this.siteForm.specialChargeRates[0].fleetCompanyId = data[0].fleetCompanyId
  1027. }
  1028. }
  1029. })
  1030. },
  1031. getCountryOptions() {
  1032. site.getCountryList().then(({ data }) => {
  1033. this.countryOptions = data
  1034. if (data && data.length > 0) {
  1035. this.siteForm.address.country = data[0].value
  1036. }
  1037. })
  1038. },
  1039. getChargingProfileOPtions() {
  1040. site.getChargingProfiles().then(({ data }) => {
  1041. this.chargingProfileOPtions = data
  1042. })
  1043. },
  1044. handleClickSubChargeRateButton(chargeRate, index) {
  1045. this.siteForm.chargeRates.splice(index, 1)
  1046. },
  1047. handleClickSubTempChargeRateButton() {
  1048. if (this.siteForm.chargeRates.length > 0) {
  1049. const {
  1050. rate,
  1051. rateType,
  1052. chargeTypePk,
  1053. } = this.siteForm.chargeRates.pop()
  1054. this.siteForm.tempChargeRate.chargeTypePk = chargeTypePk
  1055. this.siteForm.tempChargeRate.rateType = rateType
  1056. this.siteForm.tempChargeRate.rate = rate
  1057. } else {
  1058. this.resetTempChargeRate()
  1059. }
  1060. },
  1061. handleClickAddChargeRateButton() {
  1062. this.siteForm.chargeRates.push({
  1063. ...this.siteForm.tempChargeRate
  1064. })
  1065. this.resetTempChargeRate()
  1066. },
  1067. resetTempChargeRate() {
  1068. this.setTempRateTypeDefaultValue()
  1069. this.siteForm.tempChargeRate.rate = ''
  1070. this.setTempChargeTypeDefaultValue()
  1071. },
  1072. handleClickAddWhiteUserButton() {
  1073. this.siteForm.whitelistUser.push({
  1074. mobileNumber: '',
  1075. licenceNumber: '',
  1076. })
  1077. },
  1078. handleClickSubWhiteUserButton(user, index) {
  1079. this.siteForm.whitelistUser.splice(index, 1)
  1080. if (this.siteForm.whitelistUser.length === 0) {
  1081. this.siteForm.whitelistUser.push({
  1082. mobileNumber: '',
  1083. licenceNumber: '',
  1084. })
  1085. }
  1086. },
  1087. handleClickAddWhiteFleetButton() {
  1088. this.siteForm.fleetWhitelist.push({
  1089. fleetCompanyId: ''
  1090. })
  1091. },
  1092. handleClickSubWhiteFleetButton(fleet, index) {
  1093. this.siteForm.fleetWhitelist.splice(index, 1)
  1094. if (this.siteForm.fleetWhitelist.length === 0) {
  1095. this.siteForm.fleetWhitelist.push({
  1096. fleetCompanyId: ''
  1097. })
  1098. }
  1099. },
  1100. handleClickCancleButton() {
  1101. this.$router.go(-1)
  1102. },
  1103. handleClickConfigUpateButton() {
  1104. this.$refs['addSiteForm'].validate(result => {
  1105. if (result) {
  1106. this.addSiteWithForm();
  1107. }
  1108. })
  1109. },
  1110. addRecipient() {
  1111. if (this.recipient) {
  1112. this.$refs["recipForm"].validate(result => {
  1113. if (result) {
  1114. this.recipients.push(this.recipient);
  1115. this.recipient = "";
  1116. }
  1117. });
  1118. }
  1119. },
  1120. deleteRecipient(index) {
  1121. this.recipients.splice(index, 1);
  1122. },
  1123. clearAllRecipient() {
  1124. this.$confirm('Clear all recipients?', 'Prompt', {
  1125. confirmButtonText: 'Confirm',
  1126. cancelButtonText: 'Cancel',
  1127. type: 'warning'
  1128. }).then(res => {
  1129. this.recipients = [];
  1130. })
  1131. },
  1132. addSiteWithForm() {
  1133. const {
  1134. siteName,
  1135. //type: siteType,
  1136. latitude: locationLatitude,
  1137. longitude: locationLongitude,
  1138. } = this.siteForm.siteInformation
  1139. const {
  1140. street,
  1141. postalCode,
  1142. city,
  1143. country,
  1144. } = this.siteForm.address;
  1145. const chargeRates = [...this.siteForm.chargeRates]
  1146. const chargeProfiles = []
  1147. const {
  1148. chargeTypePk,
  1149. rate,
  1150. rateType,
  1151. } = this.siteForm.tempChargeRate
  1152. if (chargeTypePk && rate && rateType) {
  1153. chargeRates.push({
  1154. chargeTypePk,
  1155. rate,
  1156. rateType,
  1157. })
  1158. }
  1159. if (this.swtSpecialRate) {
  1160. this.siteForm.specialChargeRates.forEach(({
  1161. fleetCompanyId,
  1162. chargeTypePk,
  1163. rate,
  1164. rateType,
  1165. }) => {
  1166. if (chargeTypePk && fleetCompanyId && rate && rateType) {
  1167. chargeRates.push({
  1168. fleetCompanyId,
  1169. chargeTypePk,
  1170. rate,
  1171. rateType,
  1172. })
  1173. }
  1174. })
  1175. }
  1176. this.balancingForm.siteChargingProfiles.forEach(item => {
  1177. if (item.boxInUse && item.chargingProfilePk)
  1178. chargeProfiles.push(item)
  1179. })
  1180. const {
  1181. free,
  1182. parkingFee,
  1183. endlessService,
  1184. additionalNotes,
  1185. operatingHours,
  1186. } = this.siteForm.additionalInformation
  1187. const { whitelistUser, fleetWhitelist, siteChargingProfiles } = this.siteForm
  1188. const siteTypes = [];
  1189. if (this.isSiteTypeEnable(0, false)) {
  1190. this.siteTypeTable.forEach(item => {
  1191. siteTypes.push({
  1192. siteType: item.siteType,
  1193. allDay: item.allDay,
  1194. startTime: "",
  1195. endTime: ""
  1196. })
  1197. })
  1198. } else {
  1199. siteTypes.push(...this.siteTypeTable);
  1200. }
  1201. const data = {
  1202. siteName,
  1203. siteTypes,
  1204. locationLatitude,
  1205. locationLongitude,
  1206. enableReservation: this.siteForm.reservation.enable,
  1207. timeLimit: this.siteForm.reservation.timeLimit,
  1208. address: {
  1209. street,
  1210. city,
  1211. country,
  1212. countryCode: country,
  1213. zipCode: postalCode
  1214. },
  1215. chargeRates,
  1216. whitelistUser,
  1217. fleetWhitelist,
  1218. siteChargingProfiles: chargeProfiles,
  1219. free,
  1220. endlessService,
  1221. operatingHours,
  1222. parkingFee,
  1223. additionalNotes,
  1224. loadBalancing: this.balancingForm.loadBalancing,
  1225. staticMaxAmpere: this.balancingForm.staticMaxAmpere,
  1226. ...this.siteForm.idle,
  1227. emails: this.recipients
  1228. };
  1229. site.addSite(data)
  1230. .then(() => {
  1231. this.$router.go(-1)
  1232. this.$notify({
  1233. title: "add site success",
  1234. type: 'success',
  1235. duration: 5000,
  1236. })
  1237. })
  1238. .catch((error) => {
  1239. this.$message({
  1240. message: error,
  1241. type: "error",
  1242. duration: 5 * 1000,
  1243. })
  1244. this.pageLoading = false;
  1245. })
  1246. },
  1247. siteTypeSpanMethod({ row, column, rowIndex, columnIndex }) {
  1248. if (columnIndex == 2) {
  1249. return [1,2]
  1250. } else if (columnIndex == 3) {
  1251. return [0,0]
  1252. }
  1253. },
  1254. enableUserWhiteList() {
  1255. for (let type of this.siteTypeTable) {
  1256. if (type.siteType == "PRI_USR_WHI") {
  1257. return (type.allDay || (type.startTime && type.endTime))
  1258. } else {
  1259. continue;
  1260. }
  1261. }
  1262. return false;
  1263. },
  1264. enableFleetWhiteList() {
  1265. for (let type of this.siteTypeTable) {
  1266. if (type.siteType == "PRI_FLE_WHI") {
  1267. return (type.allDay || (type.startTime && type.endTime))
  1268. } else {
  1269. continue;
  1270. }
  1271. }
  1272. return false;
  1273. },
  1274. isSiteTypeEnable(index, isSwitch) {
  1275. for (let i = 0; i < this.siteTypeTable.length; i++) {
  1276. let type = this.siteTypeTable[i];
  1277. if (type.allDay) {
  1278. if (index == i && isSwitch) {
  1279. return false;
  1280. } else {
  1281. return true;
  1282. }
  1283. } else {
  1284. continue;
  1285. }
  1286. }
  1287. return false;
  1288. }
  1289. }
  1290. }
  1291. </script>
  1292. <style scoped lang='scss'>
  1293. @import '../../styles/element-ui.scss';
  1294. @import '../../styles/variables.scss';
  1295. .view-container {
  1296. width: 100%;
  1297. padding: 20px 60px;
  1298. min-height: $mainAppMinHeight;
  1299. background-color: #F0F5FC;
  1300. }
  1301. .view-content {
  1302. padding: 15px 60px;
  1303. border-radius: 6px;
  1304. background-color: white;
  1305. }
  1306. .sparator {
  1307. margin: 10px -40px;
  1308. height: 2px;
  1309. background-color: #F0F5FC;
  1310. }
  1311. .section-title {
  1312. color: #333333;
  1313. margin-top: 20px;
  1314. margin-bottom: 30px;
  1315. font-size: 16px;
  1316. line-height: 24px;
  1317. font-weight: 500;
  1318. font-family: sans-serif;
  1319. text-transform: uppercase;
  1320. }
  1321. .input-text {
  1322. width: 100%;
  1323. max-width: 300px;
  1324. }
  1325. .input-text .el-textarea__inner {
  1326. font-family: sans-serif;
  1327. }
  1328. .rate-list-view {
  1329. display: flex;
  1330. flex-wrap: wrap;
  1331. align-items: center;
  1332. }
  1333. .rate-text-max {
  1334. max-width: 200px;
  1335. padding-right: 14px;
  1336. }
  1337. .rate-text {
  1338. max-width: 150px;
  1339. padding-right: 14px;
  1340. }
  1341. .rate-type {
  1342. max-width: 100px;
  1343. padding-right: 14px;
  1344. }
  1345. .list-item-icon {
  1346. width: 30px;
  1347. height: 30px;
  1348. cursor: pointer;
  1349. margin: 5px 10px 22px;
  1350. }
  1351. .cancel-button {
  1352. width: 94px;
  1353. height: 40px;
  1354. }
  1355. .confirm-button {
  1356. width: 94px;
  1357. height: 40px;
  1358. margin-left: 20px;
  1359. background: $--color-primary;
  1360. border: 1px solid $--color-primary;
  1361. box-sizing: border-box;
  1362. border-radius: 4px;
  1363. }
  1364. ::v-deep .el-switch__label.el-switch__label--left span {
  1365. font-size: 14px;
  1366. color: black;
  1367. }
  1368. .ratePunit {
  1369. height: 39px;
  1370. font-size: 20px;
  1371. margin-left: -5px;
  1372. padding-right: 10px;
  1373. }
  1374. .type-row {
  1375. display: flex;
  1376. align-items: center;
  1377. padding-bottom: 10px;
  1378. }
  1379. .type-row > div {
  1380. margin-right: 10px;
  1381. }
  1382. .link-button {
  1383. color: #3179E4;
  1384. font-size: 14px;
  1385. cursor: pointer;
  1386. margin: 0 -10px;
  1387. padding: 0 10px;
  1388. display: inline-block;
  1389. white-space: nowrap;
  1390. text-decoration: underline;
  1391. }
  1392. .receip-item {
  1393. display: flex;
  1394. align-items: center;
  1395. font-size: 14px;
  1396. line-height: 1em;
  1397. padding-top: 10px;
  1398. }
  1399. .receip-item i {
  1400. color: #666;
  1401. padding: 0 10px;
  1402. cursor: pointer;
  1403. }
  1404. .receip-item i:hover,
  1405. .receip-item i:active,
  1406. .link-button:hover {
  1407. color: #ff5500;
  1408. }
  1409. </style>