Просмотр исходного кода

Enhance system transactions
https://dev.wormwood.com.sg/zentao/task-view-11.html

vbea 2 лет назад
Родитель
Сommit
de7c9b9326

+ 28 - 1
Strides-Admin/src/http/api/financial.js

@@ -72,7 +72,34 @@ const financial = {
   },
   },
   getBillingTypeOptions() {
   getBillingTypeOptions() {
     return get("dawn/api/v1/billing-type-select")
     return get("dawn/api/v1/billing-type-select")
-  }
+  },
+  /*信用余额操作部分-Start*/
+  getCreditTypeOptions() {
+    return get("dawn/api/v1/credit-action-type-select")
+  },
+  getCreditStatusOptions() {
+    return get("dawn/api/v1/credit_action_status-select")
+  },
+  getCreaitActionPages(data) {
+    return post("dawn/api/v1/credit-action-pages", data)
+  },
+  createCreditApply(data) {
+    return post("dawn/api/v1/credit-action-application", data)
+  },
+  approveCreditApply(data) {
+    return put("dawn/api/v1/credit-action-application", data)
+  },
+  viewCreditApply(creditActionId) {
+    return get("dawn/api/v1/credit-action-application/" + creditActionId)
+  },
+  /**
+   * 获取用户列表(模糊查询)
+   * @param {Object} data {email}
+   */
+  getUserOptions(data) {
+    return get("dawn/api/v1/user-select", data)
+  },
+  /*信用余额操作部分-End*/
 }
 }
 
 
 export default financial;
 export default financial;

+ 12 - 1
Strides-Admin/src/router/FinancialRouter.js

@@ -3,7 +3,7 @@ import Layout from '@/layout'
 export default {
 export default {
   path: '/financial-management',
   path: '/financial-management',
   component: Layout,
   component: Layout,
-  redirect: '/financial-management/charging-transactions',
+  redirect: 'noRedirect',
   alwaysShow: true,
   alwaysShow: true,
   meta: {
   meta: {
     title: 'Financial Management',
     title: 'Financial Management',
@@ -22,6 +22,17 @@ export default {
         affix: false
         affix: false
       }
       }
     },
     },
+    {
+      path: '/financial-management/credit-amendment',
+      component: () => import('@/views/financial/CreditAmendment'),
+      name: 'CreditAmendment',
+      meta: {
+        title: 'Credit Amendment',
+        icon: 'sidebar-submenu-item',
+        activeIcon: 'sidebar-submenu-item-active',
+        affix: false
+      }
+    },
     {
     {
       path: '/financial-management/billing-account-mgmt',
       path: '/financial-management/billing-account-mgmt',
       component: () => import('@/views/settlement/BillingAccount'),
       component: () => import('@/views/settlement/BillingAccount'),

+ 1 - 0
Strides-Admin/src/styles/index.scss

@@ -388,6 +388,7 @@ aside {
 }
 }
 .filter-view-item {
 .filter-view-item {
   min-width: 200px;
   min-width: 200px;
+  max-width: 300px;
   &.el-select {
   &.el-select {
     min-width: 120px;
     min-width: 120px;
     max-width: 200px;
     max-width: 200px;

+ 2 - 2
Strides-Admin/src/views/company/detail.vue

@@ -102,7 +102,7 @@
           </el-form-item>
           </el-form-item>
           <el-form-item
           <el-form-item
             prop="discount"
             prop="discount"
-            label="Discount:">
+            label="Basic Discount:">
             <el-input
             <el-input
               v-model="form.discount"
               v-model="form.discount"
               class="add-text"
               class="add-text"
@@ -136,7 +136,7 @@
             <Summary :info="form.quickSummary"/>
             <Summary :info="form.quickSummary"/>
           </div>
           </div>
           <div class="content flex1">
           <div class="content flex1">
-            <div class="section-title">Discount Assignment</div>
+            <div class="section-title">Specific Discount Assignment</div>
             <discounts
             <discounts
               :data="form.discounts"
               :data="form.discounts"
               :group="form.groupPk"
               :group="form.groupPk"

+ 2 - 2
Strides-Admin/src/views/company/index.vue

@@ -112,9 +112,9 @@
         align="center"
         align="center"
         label="Eligible Sites (Discount)"
         label="Eligible Sites (Discount)"
         prop="eligibleSiteCount"
         prop="eligibleSiteCount"
-        min-width="120">
+        min-width="140">
         <template slot="header">
         <template slot="header">
-          Eligible Sites<br/><span style="white-space: nowrap;">(Discount)</span>
+          Eligible Sites<br/><span style="white-space: nowrap;">(w Basic Discount)</span>
         </template>
         </template>
         <template slot-scope="{row}">
         <template slot-scope="{row}">
           {{getEligibleCount(row.eligibleSiteCount)}}
           {{getEligibleCount(row.eligibleSiteCount)}}

+ 390 - 0
Strides-Admin/src/views/financial/CreditActionDialog.vue

@@ -0,0 +1,390 @@
+<template>
+  <el-dialog
+    :title="isApprove ? 'APPROVE CREDIT' : 'AMEND CREDIT'"
+    :visible="visible"
+    custom-class="toptop-dialog"
+    :before-close="hideDialog"
+    :close-on-click-modal="false">
+    <el-form
+      ref="creditForm"
+      :model="form"
+      :rules="rules"
+      label-width="130px"
+      label-position="right"
+      v-loading="loading">
+      <el-form-item
+        label="User-Email:"
+        v-if="isApprove">
+        <el-input
+          class="input-text"
+          :value="form.userEmail"
+          readonly/>
+      </el-form-item>
+      <el-form-item
+        label="Select User:"
+        prop="userPk"
+        v-else>
+        <el-select
+          v-model="userInfo.index"
+          class="input-text"
+          filterable
+          remote
+          clearable
+          :remote-method="getUserOptions"
+          placeholder="Search user email"
+          @change="changeUser">
+          <el-option
+            v-for="(item,index) in options.user"
+            :key="index"
+            :label="item.email"
+            :value="index"/>
+        </el-select>
+      </el-form-item>
+      <el-form-item
+        label="Current Balance:">
+        <el-input
+          class="input-text"
+          :value="userInfo.currentBalance"
+          readonly/>
+      </el-form-item>
+      <el-form-item
+        label="Credit Action:"
+        v-if="isApprove">
+        <el-input
+          class="input-text"
+          v-model="form.creditActionType"
+          readonly/>
+      </el-form-item>
+      <el-form-item
+        label="Credit Action:"
+        prop="creditActionType"
+        v-else>
+        <el-select
+          v-model="form.creditActionType"
+          class="input-text"
+          clearable>
+          <el-option
+            v-for="(item,index) in options.action"
+            :key="index"
+            :label="item"
+            :value="item"/>
+        </el-select>
+      </el-form-item>
+      <el-form-item
+        label="Amount:"
+        v-if="isApprove">
+        <el-input
+          class="input-text"
+          v-model="form.creditActionAmount"
+          readonly/>
+      </el-form-item>
+      <el-form-item
+        label="Amount:"
+        prop="creditActionAmount"
+        v-else>
+        <el-input
+          class="input-text"
+          v-model="form.creditActionAmount"
+          maxlength="6"/>
+      </el-form-item>
+      <el-form-item
+        label="Remarks:"
+        prop="creditActionRemarks">
+        <el-input
+          class="input-text"
+          v-model="form.creditActionRemarks"
+          type="textarea"
+          maxlength="300"
+          :readonly="isApprove"
+          :autosize="autoSize"/>
+      </el-form-item>
+      <el-form-item
+        label="Status:"
+        v-if="isApprove">
+        <el-input
+          class="input-text"
+          v-model="form.creditActionStatus"
+          readonly/>
+      </el-form-item>
+      <el-form-item
+        label="Requester:"
+        v-if="isApprove">
+        <el-input
+          class="input-text"
+          v-model="form.requester"
+          readonly/>
+      </el-form-item>
+      <div
+        class="flexcc"
+        style="padding-top: 20px;"
+        v-if="isApprove"
+        v-show="form.creditActionStatus == 'Pending Approval'">
+        <el-button
+          class="cancel-button button-reject"
+          @click="onApprove('Rejected')"
+          :disabled="loadingBtn">
+          REJECT
+        </el-button>
+        <el-button
+          type="accent"
+          @click="onApprove('Approved')"
+          :disabled="loadingBtn">
+          APPROVE
+        </el-button>
+      </div>
+      <div
+        class="flexcc"
+        style="padding-top: 20px;"
+        v-else>
+        <el-button
+          class="cancel-button"
+          @click="hideDialog">
+          CANCEL
+        </el-button>
+        <el-button
+          type="primary"
+          @click="onSubmit"
+          :loading="loadingBtn">
+          SUBMIT
+        </el-button>
+      </div>
+    </el-form>
+  </el-dialog>
+</template>
+
+<script>
+import financial from '@/http/api/financial';
+export default {
+  name: "CreditActionDialog",
+  props: {
+    visible: {
+      type: Boolean,
+      default: false
+    },
+    request: {
+      type: String,
+      default: ""
+    }
+  },
+  data() {
+    return {
+      loading: false,
+      loadingBtn: false,
+      isApprove: false,
+      form: {
+        userPk: "",
+        creditActionId: "",
+        creditActionType: "",
+        creditActionAmount: "",
+        creditActionRemarks: ""
+      },
+      rules: {
+        userPk: {
+          required: true,
+          trigger: 'change',
+          message: 'Please select user'
+        },
+        creditActionAmount: [{
+          required: true,
+          trigger: 'blur',
+          message: 'Please type amount',
+        }, {
+          pattern: /^[1-9]+\d*\.?\d*$/,
+          trigger: 'blur',
+          message: 'Please type a correct number'
+        }],
+        creditActionType: {
+          required: true,
+          trigger: 'change',
+          message: 'Please select credit action'
+        },
+        creditActionRemarks: {
+          required: true,
+          trigger: 'blur',
+          message: 'Please type remarks'
+        }
+      },
+      options: {
+        user: [],
+        action: []
+      },
+      approve: {
+        creditActionId: "",
+        creditActionStatus: ""
+      },
+      userInfo: {
+        index: "",
+        currentBalance: ""
+      },
+      autoSize: {
+        minRows: 3,
+        maxRows: 8
+      }
+    };
+  },
+  watch: {
+    visible: {
+      handler(n, o) {
+        if (n) {
+          this.userInfo = {};
+          if (this.request) {
+            this.isApprove = true;
+            this.approve.creditActionId = this.request;
+            this.getActionInfo();
+          } else {
+            this.isApprove = false;
+            this.form = {
+              userPk: "",
+              creditActionId: "",
+              creditActionType: "",
+              creditActionAmount: "",
+              creditActionRemarks: ""
+            }
+          }
+          this.$nextTick(() => {
+            this.$refs.creditForm.clearValidate();
+          })
+        }
+      }
+    }
+  },
+  mounted() {
+    this.getUserOptions();
+    this.getActionOptions();
+  },
+  methods: {
+    hideDialog(e, h) {
+      this.$emit("hide", h);
+    },
+    getUserOptions(word) {
+      financial.getUserOptions({
+        email: word
+      }).then(res => {
+        if (res.data) {
+          this.options.user = res.data
+        } else {
+          this.options.user = []
+        }
+      }).catch(() => {
+        this.$message({
+          message: err,
+          type: 'error',
+          duration: 3000,
+        })
+        this.options.user = []
+      })
+    },
+    getActionOptions() {
+      financial.getCreditTypeOptions().then(res => {
+        if (res.data) {
+          this.options.action = res.data
+        } else {
+          this.options.action = []
+        }
+      }).catch(err => {
+        this.$message({
+          message: error,
+          type: 'error'
+        })
+        this.options.action = []
+      })
+    },
+    getActionInfo() {
+      this.loading = true;
+      financial.viewCreditApply(this.approve.creditActionId).then(res => {
+        if (res.data) {
+          this.form = res.data;
+          this.userInfo.currentBalance = res.data.currentBalance;
+        }
+        this.loading = false;
+      }).catch(err => {
+        this.$message({
+          message: error,
+          type: 'error'
+        })
+        this.loading = false;
+      })
+    },
+    changeUser(index) {
+      const user = this.options.user[index];
+      this.form.userPk = user.userPk;
+      this.userInfo.currentBalance = user.currentBalance;
+    },
+    onSubmit() {
+      this.$refs.creditForm.validate((valid) => {
+        if (valid) {
+          this.createAction();
+        }
+      })
+    },
+    onApprove(status) {
+      this.$confirm("Confirm operation?", status, {
+        confirmButtonText: 'Confirm',
+        cancelButtonText: 'Cancel',
+        type: 'warning'
+      }).then(res => {
+        this.approve.creditActionStatus = status;
+        this.$nextTick(() => {
+          this.approveAction();
+        })
+      })
+    },
+    createAction() {
+      this.loadingBtn = true;
+      financial.createCreditApply(this.form).then(res => {
+        this.loadingBtn = false;
+        this.$message({
+          message: res.msg,
+          type: 'success',
+        })
+        this.hideDialog(true, true);
+      }).catch(err => {
+        this.loadingBtn = false;
+        this.$message({
+          message: err,
+          type: 'error',
+        })
+      })
+    },
+    approveAction() {
+      this.loadingBtn = true;
+      financial.approveCreditApply(this.approve).then(res => {
+        this.loadingBtn = false;
+        this.$message({
+          message: res.msg,
+          type: 'success',
+        })
+        this.hideDialog(true, true);
+      }).catch(err => {
+        this.loadingBtn = false;
+        this.$message({
+          message: err,
+          type: 'error',
+        })
+      })
+    }
+  }
+}
+</script>
+
+<style scoped>
+>>> .toptop-dialog {
+  width: 100%;
+  padding: 0 10px;
+  max-width: 520px;
+}
+.input-text {
+  width: 100%;
+  max-width: 350px;
+}
+.input-text >>> .el-textarea__inner {
+  font-family: sans-serif;
+}
+.cancel-button.button-reject {
+  border-color: #ED3F3F;
+}
+.cancel-button.button-reject >>> span {
+  color: #ED3F3F;
+}
+
+</style>

+ 250 - 0
Strides-Admin/src/views/financial/CreditAmendment.vue

@@ -0,0 +1,250 @@
+<template>
+  <div class="app-container">
+    <div class="filter-container">
+      <div class="filter-view">
+        <el-date-picker
+          v-model="filters.pageVo.dateRange"
+          type="daterange"
+          value-format="yyyy-MM-dd"
+          start-placeholder="Start Date"
+          end-placeholder="End Date"
+          clearable
+          class="filter-view-item"
+          @change="toSearch"/>
+        <el-select
+          class="filter-view-item"
+          v-model="filters.pageVo.creditActionType"
+          placeholder="Credit Action"
+          @change="toSearch"
+          clearable>
+          <el-option
+            v-for="item in options.action"
+            :key="item"
+            :label="item"
+            :value="item" />
+        </el-select>
+        <el-select
+          class="filter-view-item"
+          v-model="filters.pageVo.creditActionStatus"
+          placeholder="Status"
+          @change="toSearch"
+          clearable>
+          <el-option
+            v-for="item in options.status"
+            :key="item"
+            :label="item"
+            :value="item" />
+        </el-select>
+        <el-input
+          v-model="filters.pageVo.criteria"
+          placeholder="E-mail, Request ID"
+          prefix-icon="el-icon-search"
+          style="max-width: 300px;"
+          @change="toSearch"
+          @keyup.enter.native="toSearch"
+          clearable/>
+        <div class="filter-flex-button">
+          <el-button
+            type="primary"
+            @click="onClickAdd">
+            Amend Credit
+          </el-button>
+        </div>
+      </div>
+    </div>
+    <el-table
+      v-loading="table.loading"
+      :data="table.list">
+      <el-table-column
+        align="center"
+        label="Request ID"
+        prop="entityName"
+        min-width="170">
+        <template slot-scope="{row}">
+          <div
+            class="link-type"
+            @click="onClickEdit(row)">
+            {{row.creditActionId}}
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column
+        align="center"
+        label="User E-mail"
+        prop="userEmail"
+        min-width="150"/>
+      <el-table-column
+        align="center"
+        label="Current Balance"
+        prop="currentBalance"
+        min-width="150"/>
+      <el-table-column
+        align="center"
+        label="Credit Action"
+        prop="creditActionType"
+        min-width="150"/>
+      <el-table-column
+        align="center"
+        label="Amount"
+        prop="creditActionAmount"
+        min-width="150"/>
+      <el-table-column
+        align="center"
+        label="Remarks"
+        prop="creditActionRemarks"
+        min-width="150"/>
+      <el-table-column
+        align="center"
+        label="Status"
+        prop="creditActionStatus"
+        min-width="150">
+        <template slot-scope="{row}">
+          <div
+            :class="'action-status ' + row.creditActionStatus"
+            @click="onClickEdit(row)">
+            {{row.creditActionStatus}}
+          </div>
+        </template>
+      </el-table-column>
+    </el-table>
+    <div class="right">
+      <pagination
+        v-show="table.total > 0"
+        :total="table.total"
+        :page.sync="filters.pageNum"
+        :limit.sync="filters.pageSize"
+        @pagination="getTableData" />
+    </div>
+    <CreditActionDialog
+      v-bind="dialog"
+      @hide="hideDialog"/>
+  </div>
+</template>
+
+<script>
+import financial from '@/http/api/financial';
+import Pagination from '@/components/Pagination';
+import CreditActionDialog from './CreditActionDialog.vue';
+export default {
+  data() {
+    return {
+      filters: {
+        pageNum: 1,
+        pageSize: 10,
+        pageVo: {
+          criteria: "",
+          dateRange: [],
+          creditActionType: "",
+          creditActionStatus: ""
+        }
+      },
+      table: {
+        list: [],
+        total: 0,
+        loading: false
+      },
+      options: {
+        action: [],
+        status: []
+      },
+      dialog: {
+        visible: false,
+        request: ""
+      }
+    };
+  },
+  components: {Pagination, CreditActionDialog},
+  created() {
+    this.getActionOptions();
+    this.getStatusOptions();
+    this.toSearch();
+  },
+  methods: {
+    toSearch() {
+      this.filters.pageNum = 1
+      this.getTableData()
+    },
+    getActionOptions() {
+      financial.getCreditTypeOptions().then(res => {
+        if (res.data) {
+          this.options.action = res.data
+        } else {
+          this.options.action = []
+        }
+      }).catch(err => {
+        this.$message({
+          message: error,
+          type: 'error'
+        })
+        this.options.action = []
+      })
+    },
+    getStatusOptions() {
+      financial.getCreditStatusOptions().then(res => {
+        if (res.data) {
+          this.options.status = res.data
+        } else {
+          this.options.status = []
+        }
+      }).catch(err => {
+        this.$message({
+          message: error,
+          type: 'error'
+        })
+        this.options.status = []
+      })
+    },
+    getTableData() {
+      this.table.loading = true;
+      financial.getCreaitActionPages(this.filters).then(res => {
+        if (res.data.totalRow && res.data.records) {
+          this.table.total = res.data.totalRow;
+          this.table.list = res.data.records;
+        } else {
+          this.table.total = 0;
+          this.table.list = [];
+        }
+      }).catch(err => {
+        this.$message({
+          type: 'error',
+          message: err
+        })
+        this.table.total = 0;
+        this.table.list = [];
+      }).finally(() => {
+        this.table.loading = false;
+      })
+    },
+    onClickAdd() {
+      this.dialog.request = "";
+      this.dialog.visible = true;
+    },
+    onClickEdit(row) {
+      this.dialog.request = row.creditActionId;
+      this.dialog.visible = true;
+    },
+    hideDialog(e) {
+      this.dialog.request = "";
+      this.dialog.visible = false;
+      if (e) {
+        this.toSearch();
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+.action-status {
+  color: #F8A300;
+  font-size: 13px;
+  cursor: pointer;
+  text-decoration: underline;
+}
+.action-status.Approved {
+ color: #1ABD00;
+}
+.action-status.Rejected {
+  color: #ED3F3F;
+}
+</style>

+ 1 - 0
Strides-Admin/src/views/ocpp/OCPPOperations.vue

@@ -163,6 +163,7 @@
           <el-select
           <el-select
             v-model="operationForm.idTagInfo"
             v-model="operationForm.idTagInfo"
             filterable
             filterable
+            remote
             :remote-method="filterMobile"
             :remote-method="filterMobile"
             class="flex-item"
             class="flex-item"
             :loading="tagLoading"
             :loading="tagLoading"

+ 3 - 0
Strides-Admin/src/views/settlement/BillingAccount.vue

@@ -183,12 +183,15 @@ export default {
       financial.getBillingAccountTypes().then(res => {
       financial.getBillingAccountTypes().then(res => {
         if (res.data) {
         if (res.data) {
           this.options.types = res.data
           this.options.types = res.data
+        } else {
+          this.options.types = []
         }
         }
       }).catch(err => {
       }).catch(err => {
         this.$message({
         this.$message({
           message: error,
           message: error,
           type: 'error'
           type: 'error'
         })
         })
+        this.options.types = []
       })
       })
     },
     },
     getTableData() {
     getTableData() {

+ 6 - 6
Strides-Admin/src/views/settlement/assignment.vue

@@ -98,12 +98,12 @@
               <div v-for="item in row.serviceProviders" :key="item">{{item}}</div>
               <div v-for="item in row.serviceProviders" :key="item">{{item}}</div>
             </template>
             </template>
           </el-table-column>
           </el-table-column>
-          <el-table-column
-            align="center"
-            label="Assignment Status"
-            prop="assignmentStatus"
-            min-width="150"/>
         </template>
         </template>
+        <el-table-column
+          align="center"
+          label="Assignment Status"
+          prop="assignmentStatus"
+          min-width="150"/>
         <el-table-column
         <el-table-column
           align="center"
           align="center"
           label="Select"
           label="Select"
@@ -170,7 +170,7 @@ export default {
   components: {Pagination},
   components: {Pagination},
   computed: {
   computed: {
     title() {
     title() {
-      return this.isGroup ? "ASSIGN GROUP (SITE WHITELIST)" : "ASSIGN SITES" 
+      return this.isGroup ? "ASSIGN GROUPS" : "ASSIGN SITES";
     }
     }
   },
   },
   watch: {
   watch: {

+ 2 - 1
Strides-Admin/src/views/transaction/view_transaction.vue

@@ -136,8 +136,9 @@
           <el-button
           <el-button
             type="primary"
             type="primary"
             style="margin: 0 10px;"
             style="margin: 0 10px;"
-            v-if="!details.endDateTime"
+            v-if="!details.endDateTime || !details.totalPower"
             @click="onClickEnd"
             @click="onClickEnd"
+            icon="el-icon-switch-button"
             :loading="endLoading">
             :loading="endLoading">
             End Transaction
             End Transaction
           </el-button>
           </el-button>

+ 5 - 1
Strides-Admin/src/views/user/detail.vue

@@ -134,7 +134,11 @@
             <el-col :xs="24" :md="12">
             <el-col :xs="24" :md="12">
               <el-form-item
               <el-form-item
                 label="Credit Amount:">
                 label="Credit Amount:">
-                <div class="flexc input-text">
+                <el-input
+                  class="input-text"
+                  :value="userForm.currencySymbol + ' ' + userForm.credit"
+                  readonly/>
+                <div class="flexc input-text" v-if="false">
                   <el-input
                   <el-input
                     class="input-text-1"
                     class="input-text-1"
                     :value="userForm.currencySymbol + ' ' + userForm.credit"
                     :value="userForm.currencySymbol + ' ' + userForm.credit"

+ 1 - 1
Strides-Admin/src/views/user/views/TopUp.vue

@@ -40,7 +40,7 @@
         <el-input
         <el-input
           class="input-text"
           class="input-text"
           v-model="remarks"
           v-model="remarks"
-          maxlength="5"/>
+          maxlength="300"/>
       </el-form-item>
       </el-form-item>
       <div class="flexcc" style="padding-top: 20px;">
       <div class="flexcc" style="padding-top: 20px;">
         <el-button
         <el-button