LoadBalanceView.vue 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. <template>
  2. <div class="view-container" v-loading="loading">
  3. <div class="flexr">
  4. <div class="view-content card">
  5. <div class="section-title">Connector Utilization Rate Today</div>
  6. <CircleChart
  7. v-if="detailData.connectorUtilization"
  8. :chartData="detailData.connectorUtilization"/>
  9. </div>
  10. <div class="view-content form">
  11. <div class="section-title">Hourly Utilization(kWh)</div>
  12. <LineChart :chartData="detailData.hourlyUsage"/>
  13. </div>
  14. </div>
  15. <div class="flexr">
  16. <div class="view-content card">
  17. <div class="section-title">Power Delivery Summary</div>
  18. <div class="flexcw">
  19. <div class="summary-text">Highest Delivered (kWh)</div>
  20. <div class="summary-text">{{detailData.highestDelivered}}</div>
  21. </div>
  22. <div class="flexcw">
  23. <div class="summary-text">Lowest Delivered (kWh)</div>
  24. <div class="summary-text">{{detailData.lowestDelivered}}</div>
  25. </div>
  26. <div class="flexcw">
  27. <div class="summary-text">Total Connectors</div>
  28. <div class="summary-text">{{detailData.connectorUtilization.allConnectorCount || "0"}}</div>
  29. </div>
  30. <div class="flexcw">
  31. <div class="summary-text">Max Connectors Used</div>
  32. <div class="summary-text">{{detailData.staticMaxAmpere || "0"}}</div>
  33. </div>
  34. </div>
  35. <el-form class="view-content form">
  36. <div class="section-title flexcr">
  37. LOAD BALANCING Settings
  38. <div class="section-sub-title" v-if="detailData.siteName">(<b>Site Name:</b> {{detailData.siteName}})</div>
  39. </div>
  40. <Balancing v-model="balancingForm" :isEdit="true"/>
  41. </el-form>
  42. </div>
  43. <div class="view-content flexcr">
  44. <div class="buttons">
  45. <el-button
  46. class="cancel-button"
  47. type="primary"
  48. @click="onBack">
  49. Cancel
  50. </el-button>
  51. <el-button
  52. type="primary"
  53. @click="onClickSave">
  54. Save
  55. </el-button>
  56. </div>
  57. <div class="update-by">
  58. <span
  59. class="add-text"
  60. :title='"CREATED BY " + detailData.createdBy + " ON " + detailData.createdOn'>
  61. LAST UPDATED BY {{detailData.updatedBy}} TIMESTAMP: {{detailData.updatedOn}}
  62. </span>
  63. </div>
  64. </div>
  65. </div>
  66. </template>
  67. <script>
  68. import api from '@/http/api/apiBalancing.js';
  69. import Balancing from '../site/components/Balancing';
  70. import LineChart from '../dashboard/chart/LineChart.vue';
  71. import CircleChart from '../dashboard/chart/CircleChart.vue';
  72. export default {
  73. data() {
  74. return {
  75. loading: false,
  76. detailData: {
  77. sitePk: "",
  78. siteName: "",
  79. hourlyUsage: {
  80. xdata: [],
  81. ydata: []
  82. },
  83. highestDelivered: "",
  84. lowestDelivered: "",
  85. connectorUtilization: {}
  86. },
  87. balancingForm: {
  88. sitePk: "",
  89. loadBalancing: 'dynamic',
  90. staticMaxAmpere: 0,
  91. siteChargingProfiles: [{
  92. boxInUse: '',
  93. chargingProfilePk: ''
  94. }]
  95. },
  96. };
  97. },
  98. components: {Balancing,CircleChart,LineChart},
  99. created() {
  100. if (this.$route.params.id) {
  101. this.getBalanceDetail();
  102. }
  103. },
  104. methods: {
  105. onBack() {
  106. this.$router.push({
  107. path: "/smart-energy-management/site-load-balancing"
  108. });
  109. },
  110. getBalanceDetail() {
  111. this.loading = true;
  112. api.viewBalancing({
  113. sitePk: this.$route.params.id,
  114. }).then(res => {
  115. if (res.data) {
  116. this.detailData = res.data;
  117. this.balancingForm = {
  118. sitePk: this.detailData.sitePk,
  119. loadBalancing: this.detailData.loadBalancing || 'dynamic',
  120. staticMaxAmpere: this.detailData.staticMaxAmpere || 0,
  121. siteChargingProfiles: this.detailData.siteChargingProfiles || [{
  122. boxInUse: '',
  123. chargingProfilePk: ''
  124. }]
  125. }
  126. }
  127. this.loading = false;
  128. }).catch(() => {
  129. this.$message({
  130. message: err,
  131. type: 'error',
  132. duration: 3000,
  133. })
  134. this.loading = false;
  135. })
  136. },
  137. onClickSave() {
  138. if (this.balancingForm.loadBalancing == 'dynamic') {
  139. this.balancingForm.staticMaxAmpere = ""
  140. }
  141. const chargeProfiles = []
  142. this.balancingForm.siteChargingProfiles.forEach(item => {
  143. if (item.boxInUse && item.chargingProfilePk)
  144. chargeProfiles.push(item)
  145. })
  146. if (chargeProfiles.length > 0) {
  147. this.balancingForm.siteChargingProfiles = chargeProfiles;
  148. } else {
  149. this.$message({
  150. message: "Please add at least one charging profile",
  151. type: 'error'
  152. })
  153. return;
  154. }
  155. this.loading = true;
  156. api.updateBalancing(this.balancingForm).then(res => {
  157. this.$message({
  158. message: "Saved successfully",
  159. type: 'success',
  160. duration: 3000
  161. })
  162. this.onBack();
  163. }).catch(() => {
  164. this.$message({
  165. message: err,
  166. type: 'error',
  167. duration: 3000,
  168. })
  169. this.loading = false;
  170. })
  171. }
  172. }
  173. }
  174. </script>
  175. <style scoped lang='scss'>
  176. @import '../../styles/variables.scss';
  177. .view-container {
  178. width: 100%;
  179. padding: 20px 40px;
  180. min-height: $mainAppMinHeight;
  181. background-color: #F0F5FC;
  182. }
  183. .view-content {
  184. margin: 0 8px 16px;
  185. padding: 15px 40px;
  186. border-radius: 6px;
  187. background-color: white;
  188. &.card {
  189. flex: 1;
  190. min-width: 200px;
  191. max-width: 320px;
  192. padding-bottom: 30px;
  193. }
  194. &.form {
  195. flex: 1;
  196. min-width: 300px;
  197. }
  198. }
  199. .section-title {
  200. color: #333333;
  201. margin-top: 20px;
  202. margin-bottom: 20px;
  203. font-size: 15px;
  204. line-height: 24px;
  205. font-weight: 700;
  206. font-family: sans-serif;
  207. text-transform: uppercase;
  208. }
  209. .section-sub-title {
  210. color: #333333;
  211. font-size: 15px;
  212. line-height: 24px;
  213. padding-left: 10px;
  214. font-weight: normal;
  215. font-family: sans-serif;
  216. text-transform: uppercase;
  217. }
  218. .summary-text {
  219. color: #333;
  220. padding: 5px 0;
  221. font-size: 14px;
  222. + .summary-text {
  223. white-space: nowrap;
  224. padding-left: 10px;
  225. }
  226. }
  227. @media screen and (max-width: 800px) {
  228. .view-container {
  229. padding: 10px 20px;
  230. }
  231. .view-content {
  232. padding: 15px 20px;
  233. }
  234. }
  235. @media screen and (max-width: 620px) {
  236. .view-content {
  237. max-width: unset !important;
  238. margin: 0 8px 10px;
  239. }
  240. }
  241. @media screen and (max-width: 500px) {
  242. .view-container {
  243. padding: 0px;
  244. }
  245. .view-content {
  246. padding: 15px 20px;
  247. }
  248. }
  249. </style>