Browse Source

Merge branch 'master' into feature/kevin

# Conflicts:
#	.env.development
#	src/components/FilterUser.vue
kevin_zhangl 2 years ago
parent
commit
8279938d53
42 changed files with 5519 additions and 143 deletions
  1. 1 0
      .eslintignore
  2. 3 0
      .gitignore
  3. 2 0
      package.json
  4. 72 0
      src/api/atlas.js
  5. 143 0
      src/api/bonus.js
  6. 9 0
      src/api/file.js
  7. 47 0
      src/api/filter.js
  8. 177 0
      src/api/finance.js
  9. 3 0
      src/components/FilterUser.vue
  10. 4 4
      src/components/Tinymce/components/EditorImage.vue
  11. 2 1
      src/components/Tinymce/index.vue
  12. 175 5
      src/lang/en.js
  13. 174 5
      src/lang/zh.js
  14. 144 0
      src/router/index.js
  15. 10 9
      src/views/ad/edit.vue
  16. 13 12
      src/views/ad/list.vue
  17. 173 0
      src/views/admin/edit.vue
  18. 274 0
      src/views/admin/index.vue
  19. 29 26
      src/views/admin/role-add.vue
  20. 3 3
      src/views/admin/role-permission.vue
  21. 10 22
      src/views/admin/role.vue
  22. 3 3
      src/views/article/category.vue
  23. 13 11
      src/views/article/edit.vue
  24. 36 35
      src/views/article/index.vue
  25. 348 0
      src/views/atlas/network-opt.vue
  26. 349 0
      src/views/atlas/relation-opt.vue
  27. 262 0
      src/views/bonus/balance-list.vue
  28. 123 0
      src/views/bonus/flow-bonus.vue
  29. 178 0
      src/views/bonus/other-period-bonus.vue
  30. 150 0
      src/views/bonus/perf-adjustment.vue
  31. 143 0
      src/views/bonus/perf-month.vue
  32. 150 0
      src/views/bonus/perf-order.vue
  33. 143 0
      src/views/bonus/perf-period-list.vue
  34. 141 0
      src/views/bonus/user-perf.vue
  35. 301 0
      src/views/file/export.vue
  36. 474 0
      src/views/finance/balance-audit-list.vue
  37. 224 0
      src/views/finance/change-balance-opt.vue
  38. 117 0
      src/views/finance/recharge-status.vue
  39. 215 0
      src/views/finance/recharge.vue
  40. 124 0
      src/views/finance/transfer-list.vue
  41. 549 0
      src/views/finance/withdraw.vue
  42. 8 7
      src/views/log/user-login.vue

+ 1 - 0
.eslintignore

@@ -2,3 +2,4 @@ build/*.js
 src/*
 public
 dist
+src/

+ 3 - 0
.gitignore

@@ -21,3 +21,6 @@ selenium-debug.log
 
 package-lock.json
 yarn.lock
+
+.env.development
+vue.config.js

+ 2 - 0
package.json

@@ -39,6 +39,8 @@
     "script-loader": "0.7.2",
     "sortablejs": "1.8.4",
     "squire-rte": "^2.0.2",
+    "tinymce": "^6.4.1",
+    "tinymce-vue": "^1.0.0",
     "to-mark": "^1.1.9",
     "tui-code-snippet": "^2.3.3",
     "vue": "^2.6.10",

+ 72 - 0
src/api/atlas.js

@@ -0,0 +1,72 @@
+import request from '@/utils/request'
+
+// atlas/main-user-info
+export function mainUserInfo(query) {
+    return request({
+      url: '/v1/atlas/main-user-info',
+      method: 'get',
+      data: query,
+      params: query
+    })
+}
+
+// atlas/relation
+export function getRelation(query) {
+    return request({
+      url: '/v1/atlas/relation',
+      method: 'get',
+      data: query,
+      params: query
+    })
+}
+
+// atlas/network
+export function getNetwork(query) {
+    return request({
+      url: '/v1/atlas/network',
+      method: 'get',
+      data: query,
+      params: query
+    })
+}
+
+//atlas/relation-list
+export function relationList(query) {
+    return request({
+      url: '/v1/atlas/relation-list',
+      method: 'get',
+      data: query,
+      params: query
+    })
+}
+
+//atlas/network-list
+export function networkList(query) {
+    return request({
+      url: '/v1/atlas/network-list',
+      method: 'get',
+      data: query,
+      params: query
+    })
+}
+
+
+// 导出数据
+export function relationListExport(query) {
+    return request({
+      url: '/v1/atlas/relation-list-export',
+      method: 'get',
+      data: query,
+      params: query
+    })
+}
+
+// 导出数据
+export function networkListExport(query) {
+    return request({
+      url: '/v1/atlas/network-list-export',
+      method: 'get',
+      data: query,
+      params: query
+    })
+}

+ 143 - 0
src/api/bonus.js

@@ -0,0 +1,143 @@
+import request from '@/utils/request'
+
+export function fetchGetUserStatus() {
+  return request({
+    url: '/v1/user/status-audit-get-statuses',
+    method: 'get'
+  })
+}
+
+export function fetchBalanceList(query) {
+  return request({
+    url: '/v1/bonus/balance-list',
+    method: 'get',
+    params: query
+  })
+}
+
+export function fetchBalanceExport(query) {
+  return request({
+    url: '/v1/bonus/balance-export',
+    method: 'get',
+    params: query
+  })
+}
+
+export function fetchOtherPeriodBonusFilterTypes(query) {
+  return request({
+    url: '/v1/bonus/other-period-bonus-filter-types',
+    method: 'get',
+    params: query
+  })
+}
+
+export function fetchOtherPeriodBonus(query) {
+  return request({
+    url: '/v1/bonus/other-period-bonus',
+    method: 'get',
+    params: query
+  })
+}
+
+export function fetchOtherPeriodBonusExport(query) {
+  return request({
+    url: '/v1/bonus/other-period-bonus-export',
+    method: 'get',
+    params: query
+  })
+}
+
+export function fetchFlowBonus(query) {
+  return request({
+    url: '/v1/bonus/flow-bonus',
+    method: 'get',
+    params: query
+  })
+}
+
+export function fetchFlowBonusExport(query) {
+  return request({
+    url: '/v1/bonus/flow-bonus-export',
+    method: 'get',
+    params: query
+  })
+}
+
+export function fetchUserPerf(query) {
+  return request({
+    url: '/v1/bonus/user-perf',
+    method: 'get',
+    params: query
+  })
+}
+
+export function fetchUserPerfExport(query) {
+  return request({
+    url: '/v1/bonus/user-perf-export',
+    method: 'get',
+    params: query
+  })
+}
+export function fetchPerfOrder(query) {
+  return request({
+    url: '/v1/bonus/perf-order',
+    method: 'get',
+    params: query
+  })
+}
+
+export function fetchPerfOrderExport(query) {
+  return request({
+    url: '/v1/bonus/perf-order-export',
+    method: 'get',
+    params: query
+  })
+}
+
+export function fetchPerfPeriodList(query) {
+  return request({
+    url: '/v1/bonus/perf-period-list',
+    method: 'get',
+    params: query
+  })
+}
+
+export function fetchPerfPeriodListExport(query) {
+  return request({
+    url: '/v1/bonus/perf-period-list-export',
+    method: 'get',
+    params: query
+  })
+}
+
+export function fetchPerfMonth(query) {
+  return request({
+    url: '/v1/bonus/perf-month',
+    method: 'get',
+    params: query
+  })
+}
+
+export function fetchPerfMonthExport(query) {
+  return request({
+    url: '/v1/bonus/perf-month-export',
+    method: 'get',
+    params: query
+  })
+}
+
+export function fetchPerfAdjustment(query) {
+  return request({
+    url: '/v1/bonus/perf-adjustment',
+    method: 'get',
+    params: query
+  })
+}
+
+export function fetchPerfAdjustmentPost(data) {
+  return request({
+    url: '/v1/bonus/perf-adjustment',
+    method: 'post',
+    data
+  })
+}

+ 9 - 0
src/api/file.js

@@ -0,0 +1,9 @@
+import request from '@/utils/request'
+
+export function fetchExport(query) {
+  return request({
+    url: '/v1/file/export',
+    method: 'get',
+    params: query
+  })
+}

+ 47 - 0
src/api/filter.js

@@ -71,3 +71,50 @@ export function editRolePermission(id, query) {
     data: query
   })
 }
+
+// 管理员添加/编辑/修改密码
+export function adminAddAndEditAndChangePassword(path, query) {
+  return request({
+    url: '/v1/' + path,
+    method: 'post',
+    data: query
+  })
+}
+
+// 管理员列表
+export function adminList(query) {
+  return request({
+    url: '/v1/admin/index',
+    method: 'get',
+    data: query,
+    params: query
+  })
+}
+
+// 添加管理员-获取角色列表
+export function adminAdd(query) {
+  return request({
+    url: '/v1/admin/add',
+    method: 'get',
+    data: query,
+    params: query
+  })
+}
+
+// 管理员-编辑获取详情
+export function adminEdit(id) {
+  return request({
+    url: '/v1/admin/edit/' + id,
+    method: 'get'
+  })
+}
+
+// 删除管理员
+export function adminDelete(query) {
+  return request({
+    url: '/v1/admin/admin-delete',
+    method: 'post',
+    data: query
+  })
+}
+

+ 177 - 0
src/api/finance.js

@@ -0,0 +1,177 @@
+import request from '@/utils/request'
+
+export function getChangeBalanceType() {
+  return request({
+    url: '/v1/finance/change-balance-type',
+    method: 'get',
+  })
+}
+
+// 余额调整列表
+export function balanceAuditList(query) {
+    return request({
+      url: '/v1/finance/balance-audit-list',
+      method: 'get',
+      data: query,
+      params: query
+    })
+}
+
+// 调整列表导出
+export function balanceAuditListExport(query) {
+    return request({
+      url: '/v1/finance/balance-audit-list-export',
+      method: 'get',
+      data: query,
+      params: query
+    })
+}
+
+// 转账列表导出
+export function transferListExport(query) {
+  return request({
+    url: '/v1/finance/transfer-list-export',
+    method: 'get',
+    data: query,
+    params: query
+  })
+}
+
+// 充值列表导出
+export function rechargeExport(query) {
+  return request({
+    url: '/v1/finance/recharge-export',
+    method: 'get',
+    data: query,
+    params: query
+  })
+}
+
+// 删除
+export function balanceAuditDelete(query) {
+    return request({
+      url: '/v1/finance/balance-audit-delete',
+      method: 'post',
+      data: query
+    })
+}
+// mult-point
+export function multPoint(query) {
+    return request({
+      url: '/v1/finance/mult-point',
+      method: 'post',
+      data: query
+    })
+}
+
+//change-balance
+export function changeBalance(query) {
+  return request({
+    url: '/v1/finance/change-balance',
+    method: 'post',
+    data: query
+  })
+}
+
+// 用户信息
+export function userFullInfo(query) {
+  return request({
+    url: '/v1/user/full-info',
+    method: 'get',
+    params: query
+  })
+}
+
+// 审核拒绝
+export function balanceAudit(query) {
+  return request({
+    url: '/v1/finance/balance-audit',
+    method: 'post',
+    data: query
+  })
+}
+
+// 审核通过-查看详情
+export function balanceAuditGet(query) {
+  return request({
+    url: '/v1/finance/balance-audit-get',
+    method: 'get',
+    params: query
+  })
+}
+
+// 审核通过
+export function balanceAuditPass(query) {
+  return request({
+    url: '/v1/finance/balance-audit-pass',
+    method: 'post',
+    data: query
+  })
+}
+
+// 转账记录列表
+export function transferList(query) {
+  return request({
+    url: '/v1/finance/transfer-list',
+    method: 'get',
+    data: query,
+    params: query
+  })
+}
+
+// 充值记录列表
+export function rechargeList(query) {
+  return request({
+    url: '/v1/finance/recharge',
+    method: 'get',
+    data: query,
+    params: query
+  })
+}
+// 状态管理获取状态
+export function getRechargeStatus(){
+  return request({
+    url: '/v1/finance/recharge-status',
+    method: 'get',
+  })
+}
+
+// 提交充值状态
+export function postRechargeStatus(query) {
+  return request({
+    url: '/v1/finance/recharge-status',
+    method: 'post',
+    data: query
+  })
+}
+
+// 提现管理列表
+// 转账记录列表
+export function withdrawList(query) {
+  return request({
+    url: '/v1/finance/withdraw',
+    method: 'get',
+    data: query,
+    params: query
+  })
+}
+
+// 提现列表导出
+export function withdrawExport(query) {
+  return request({
+    url: '/v1/finance/withdraw-export',
+    method: 'get',
+    data: query,
+    params: query
+  })
+}
+// 审核提现状态
+export function postWithdrawStatus(query) {
+  return request({
+    url: '/v1/finance/withdraw-status',
+    method: 'post',
+    data: query
+  })
+}
+
+

+ 3 - 0
src/components/FilterUser.vue

@@ -617,4 +617,7 @@ export default {
     .selected-tag {
       margin-left: 10px;
     }
+    /deep/ .el-input__inner {
+        width:203px;
+    }
   </style>

+ 4 - 4
src/components/Tinymce/components/EditorImage.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="upload-container">
     <el-button :style="{background:color,borderColor:color}" icon="el-icon-upload" size="mini" type="primary" @click=" dialogVisible=true">
-      upload
+      {{$t('article.upload')}}
     </el-button>
     <el-dialog :visible.sync="dialogVisible">
       <el-upload
@@ -18,14 +18,14 @@
         :headers="uploaderHeaders"
       >
         <el-button size="small" type="primary">
-          Click upload
+          {{$t('article.clickUpload')}}
         </el-button>
       </el-upload>
       <el-button @click="dialogVisible = false">
-        Cancel
+        {{$t('article.cancel')}}
       </el-button>
       <el-button type="primary" @click="handleSubmit">
-        Confirm
+        {{$t('article.confirm')}}
       </el-button>
     </el-dialog>
   </div>

+ 2 - 1
src/components/Tinymce/index.vue

@@ -19,6 +19,8 @@ import load from './dynamicLoadScript'
 
 // why use this cdn, detail see https://github.com/PanJiaChen/tinymce-all-in-one
 const tinymceCDN = 'https://cdn.jsdelivr.net/npm/tinymce-all-in-one@4.9.3/tinymce.min.js'
+//const tinymceCDN = 'http://lib.baomitu.com/tinymce/4.9.3/tinymce.min.js'
+
 
 export default {
   name: 'Tinymce',
@@ -117,7 +119,6 @@ export default {
   },
   methods: {
     init() {
-      console.log(this.uploaderRequestUrl)
       // dynamic load tinymce from cdn
       load(tinymceCDN, (err) => {
         if (err) {

+ 175 - 5
src/lang/en.js

@@ -103,6 +103,48 @@ export default {
     hide: 'Hide',
     unhide: 'Unhide'
   },
+  article: {
+    clickUpload: 'Click Upload',
+    confirm: 'Confirm',
+    cancel: 'Cancel',
+    upload: 'Upload',
+    id: 'ID',
+    title: 'Title',
+    category: 'Category',
+    sort: 'Sort',
+    creationTime: 'Creation Time',
+    status: 'Status',
+    action: 'Action',
+    newArticle: 'New article',
+    content: 'Content',
+    order: 'Order',
+    show: 'Show',
+    categoryName: 'Category Name'
+  },
+  file: {
+    exportName: 'Export Name',
+    route: 'Route',
+    download: 'Download',
+    operationAdministrator: 'Operation Administrator',
+    exportProgress: 'Export Progress',
+    exportStart: 'Export Start',
+    exportComplete: 'Export Complete',
+    createTime: 'Create time',
+    exportStartTime: 'Export Start Time',
+    exportEndTime: 'Export End Time',
+    creationTime: 'Creation Time',
+    all: 'All'
+  },
+  bonus: {
+    welcomePackOrder: 'Welcome Pack Order',
+    memberCode: 'Member Code',
+    balancePerformance: 'Balance Performance',
+    entryBalancePerformance:'Entry Balance Performance',
+    reconditioningBalancePerformance: 'Reconditioning Balance Performance',
+    LMarketBalancePerformance: 'L. Market Balance Performance',
+    RMarketBalancePerformance: 'R. Market Balance Performance',
+    confirmAndReviseMemberPerformance: 'Confirm and revise member performance?'
+  },
   documentation: {
     documentation: 'Documentation',
     github: 'Github Repository'
@@ -154,7 +196,8 @@ export default {
     draft: 'Draft',
     delete: 'Delete',
     cancel: 'Cancel',
-    confirm: 'Confirm'
+    confirm: 'Confirm',
+    adopted:'Adopted',
   },
   example: {
     warning: 'Creating and editing pages cannot be cached by keep-alive because keep-alive include does not currently support caching based on routes, so it is currently cached based on component name. If you want to achieve a similar caching effect, you can use a browser caching scheme such as localStorage. Or do not use keep-alive include to cache all pages directly. See details'
@@ -232,8 +275,19 @@ export default {
     selectMonth: '选择月份',
     pleaseInputContent: '请输入内容',
     relation: '关系',
+    reset: '重置',
+    exportExcel:'Export Excel',
     desc: '描述',
-    upload: 'Upload'
+    upload: 'Upload',
+    hide: 'Hide',
+    unhide: 'Unhide',
+    selectData: 'Select Data',
+    deleteSelectedData: 'Are you sure to delete the selected data?',
+    notice: 'Notice',
+    hideSelectedData: 'Are you sure to hide the selected data?',
+    unHideSelectedData: 'Are you sure to un-hide the selected data?',
+    exportCurrentData: 'Are you sure you want to export the current data?',
+    all: 'All'
   },
 
   filter: {
@@ -500,9 +554,107 @@ export default {
     otherAbout: '其他'
   },
 
-  // 财务
+  // 财务管理
   financial: {
-    serviceCharge: '服务费(%)'
+    serviceCharge: '服务费(%)',
+    all:"All",
+    toBeReviewed:'To be reviewed',
+    toBePaid:'To be paid',
+    reviewed:'Reviewed',
+    paid:'Paid',
+    paymentFailed:'Payment failed',
+    returned:'Returned',
+    approved:'Approved',
+    approve:'Approve',
+    auditReject:'Audit reject',
+    action:'Action',
+    delData:'Delete data',
+    selectedData:'Selected data',
+    batchAuditPassed:'Batch audit passed',
+    batchReturn:'Batch return',
+    batchSetToBePaid:'Batch set to be paid',
+    batchSetPaid:'Batch set paid',
+    batchSetPaymentFailure:'Batch set payment failure',
+    modifyWithdrawalInfo:'modify the withdrawal information',
+    approveWithdrawalNotice:'Are you sure to approve the current withdrawal?',
+    setWithdrawalPaymentAction:'Are you sure to set the current withdrawal as payment action?',
+    setWithdrawalPaidNotice:'Are you sure to set the current withdrawal as paid?',
+    setPayFailedWithdrawal:'Are you sure to set payment failure for the current withdrawal?',
+    setWithdrawalReturnNotice:'Determines that the current withdrawal is set to a withdrawal return operation?',
+    noteWithdrawalReturn:'Note on withdrawal return',
+    memberInvoiceWithdrawalReturnNotice:'The member has provided the invoice, please confirm whether to process the withdrawal return?',
+    withdrawSetFailed:'Failed',
+    withdrawSetReturn:'Return',
+    negativeAllowedBatchApproval:'Negative number allowed for batch approval',
+    cannotNegativeBatch:'Batch approval cannot be negative',
+    batchReject:'Batch rejection',
+    batchDel:'Delete in batches',
+    applyChangeEcoin:'Apply for change of member Ecoin',
+    modifyEcoinChangeInfo:'Modify member Ecoin change information',
+    memberCode:'Member code',
+    memberName:'Member name',
+    memberLevel:'Member level',
+    idCardNumber:'身份证号',
+    registerType:'注册类型',
+    pleaseSelectRegisterType:'请选择注册类型',
+    withdrawAmount:'提现金额',
+    estimatedDatePayment:'Estimated date of payment',
+    selectDate:'Select date',
+    accountType:'Account type',
+    pleaseSelectAccountType:'Please select account type',
+    adjustmentAmount:'Adjustment amount',
+    transactionType:'Transaction type',
+    pleaseSelectTranserType:'Please select transaction type',
+    forgeDisplayRemark:'Remarks foreground display',
+    selectRecordOperateNotice:'Please select the record to operate',
+    modifyData:'Modifying data',
+    balanceInsufficientSubmitNotice:'The member account balance is insufficient, continue to submit',
+    passingAudit:'Passing the audit',
+    handleAuditDefaultNotice:'Are you sure to pass the approval (negative number is not allowed for member account) ? Note:',
+    handleAuditRejectNotice:'Are you sure you want to reject the approval? Note:',
+    handleAuditPassNotice:'Are you sure to pass the approval (negative number is allowed for member account) ? Note:',
+    okDelData:"OK to delete the selected data?",
+    exportNotice:"Are you sure you want to export the current data?",
+    manuallyAdd:'Manually add',
+    adjustAmount:'Adjust amount',
+    ecoinInsufficientNotice:'Ecoin of member is insufficient, whether to continue to submit.',
+    reviewRemberEcoinInfo:'Review member Ecoin change information',
+    statusManagement:'Status management',
+    viewVoucher:'View voucher',
+    checkRechargeVoucher:'Check recharge voucher',
+    rechargeStatusState:'State',
+    reviewWithdrawalInfoNotice:'Review withdrawal info',
+    datePayment:'Date of payment',
+    selectRecordOperateNotice:'Select the record to operate on',
+    surePassReviewNoteNotice:'Be sure to pass the review ? Note: ',
+    sureUnpaidReviewNotice:'Be sure to unpaid the review ? Note: ',
+    surePaymentFailureReview:'Be sure to payment failure the review ? Note: ',
+    surePaidReviewNotice:'Be sure to paid the review ? Note: ',
+    sureReturnReviewNotice:'Be sure to return the review ? Note: ',
+    changeStateSelectedDataNotice:'Are you sure to change the state of the selected data',
+  },
+
+  // 网络管理
+  atlas: {
+    exportNotice:"Are you sure you want to export the current data?",
+    sponsorNetworkDiagram:'Sponsor Network Diagram',
+    sponsorNetworkList:'Sponsor Network List',
+    topMember:'Top Member',
+    spreadDepth:'Spread Depth',
+    numberOfPeriods:'Number Of Periods',
+    algebra:'Algebra',
+    memberCode:'Member Code',
+    name:'Name',
+    level:'Level',
+    highest:'Highest',
+    depth:'Depth',
+    subordinatesMember:'View the subordinates of this member',
+    getDataWait:'Getting data, please wait',
+    resettlementNetworkDiagram:'Resettlement network diagram',
+    numberOfLayers:'Number Of Layers',
+    location:'Location',
+    joiningPeriod:'Joining Period',
+    placementNetworkList:'Placement network list',
   },
 
   // 管理员管理
@@ -515,6 +667,24 @@ export default {
     updateAt: '修改时间',
     addRole: '添加角色',
     selectData: '所选数据',
-    roleName: '角色名称'
+    roleName: '角色名称',
+    module: '模块',
+    loginAccount: '登录账号',
+    name: '姓名',
+    pleaseSelectRole: '请选择角色',
+    password: 'password',
+    confirmPassword: 'Confirm password',
+    bindIp: '绑定IP',
+    pleaseInputContent: '请输入内容',
+    bindIpNotice: '一行一个IP;可指定ip段,如: 192.168.0.1-255',
+    isEnable: '是否启用',
+    isModifyPwd: '是否修改密码',
+    filterBtnName: 'Select',
+    loginTimes: '登录次数',
+    lastLoginIp: '最后登录IP',
+    lastLoginAt: '最后登录时间',
+    selectData: 'Selected data',
+    addAdmin: '添加管理员',
+    delNotice: '确定删除选定的数据?'
   }
 }

+ 174 - 5
src/lang/zh.js

@@ -103,6 +103,48 @@ export default {
     hide: '展示',
     unhide: '不展示'
   },
+  article: {
+    clickUpload: '点击上传',
+    confirm: '确定',
+    cancel: '取消',
+    upload: '上传',
+    id: '序号',
+    title: '标题',
+    category: '分类',
+    sort: '排序',
+    creationTime: '创建时间',
+    status: '状态',
+    action: '操作',
+    newArticle: '新增文章',
+    content: '内容',
+    order: '排序',
+    show: '展示',
+    categoryName: '分类名称'
+  },
+  file: {
+    exportName: '导出名称',
+    route: '路径',
+    download: '下载',
+    operationAdministrator: '操作管理员',
+    exportProgress: '导出进度',
+    exportStart: '导出开始',
+    exportComplete: '导出完成',
+    createTime: '创建时间',
+    exportStartTime: '导出开始时间',
+    exportEndTime: '导出结束时间',
+    creationTime: '创建时间',
+    all: '全部'
+  },
+  bonus: {
+    welcomePackOrder: '首购单',
+    memberCode:'会员编号',
+    balancePerformance: '综合结余业绩',
+    entryBalancePerformance: '首单结余业绩',
+    reconditioningBalancePerformance: '复消结余业绩',
+    LMarketBalancePerformance: '一市场结余业绩',
+    RMarketBalancePerformance: '二市场结余业绩',
+    confirmAndReviseMemberPerformance: '确认修改会员业绩?'
+  },
   documentation: {
     documentation: '文档',
     github: 'Github 地址'
@@ -139,7 +181,7 @@ export default {
     title: '标题',
     importance: '重要性',
     type: '类型',
-    remark: '点评',
+    remark: '备注',
     search: '搜索',
     add: '添加',
     export: '导出',
@@ -155,7 +197,8 @@ export default {
     draft: '草稿',
     delete: '删除',
     cancel: '取 消',
-    confirm: '确 定'
+    confirm: '确 定',
+    adopted:'通过',
   },
   example: {
     warning: '创建和编辑页面是不能被 keep-alive 缓存的,因为keep-alive 的 include 目前不支持根据路由来缓存,所以目前都是基于 component name 来进行缓存的。如果你想类似的实现缓存效果,可以使用 localStorage 等浏览器缓存方案。或者不要使用 keep-alive 的 include,直接缓存所有页面。详情见'
@@ -235,7 +278,17 @@ export default {
     relation: '关系',
     reset: '重置',
     desc: '描述',
-    upload: '上传'
+    exportExcel:'导出Excel',
+    upload: '上传',
+    hide: '展示',
+    unhide: '不展示',
+    selectData: '所选数据',
+    deleteSelectedData: '您确定要删除所选数据吗?',
+    notice: '提示',
+    hideSelectedData: '您确定要隐藏所选数据吗?',
+    unHideSelectedData: '您确定要展示所选数据吗?',
+    exportCurrentData: '您确定要导出当前数据吗?',
+    all: '全部'
   },
 
   filter: {
@@ -498,7 +551,105 @@ export default {
 
   // 财务
   financial: {
-    serviceCharge: '服务费(%)'
+    serviceCharge: '服务费(%)',
+    all:"全部",
+    toBeReviewed:'待审核',
+    toBePaid:'待付款',
+    paid:'已付款',
+    paymentFailed:'付款失败',
+    returned:'已退回',
+    reviewed:'已审核',
+    approved:'审核通过',
+    approve:'审核通过',
+    auditReject:'审核拒绝',
+    action:'操作',
+    delData:'删除数据',
+    selectedData:'所选数据',
+    batchAuditPassed:'批量审核通过',
+    batchReturn:'批量退回',
+    batchSetToBePaid:'批量设为待付款',
+    batchSetPaid:'批量设为已付款',
+    batchSetPaymentFailure:'批量设为付款失败',
+    modifyWithdrawalInfo:'修改提现信息',
+    approveWithdrawalNotice:'确定对当前提现进行审核通过操作?',
+    setWithdrawalPaymentAction:'确定对当前提现进行设为待付款操作?',
+    setWithdrawalPaidNotice:'确定对当前提现进行设为已付款操作',
+    setPayFailedWithdrawal:'确定对当前提现进行设为付款失败操作?',
+    setWithdrawalReturnNotice:'确定对当前提现进行设为提现退回操作?',
+    noteWithdrawalReturn:'提现退回备注',
+    memberInvoiceWithdrawalReturnNotice:'该会员已提供发票,请确认是否处理提现退回',
+    withdrawSetFailed:'设为付款失败',
+    withdrawSetReturn:'设为提现退回',
+    negativeAllowedBatchApproval:'批量审核允许为负数',
+    cannotNegativeBatch:'批量审核不允许为负数',
+    batchReject:'批量拒审',
+    batchDel:'批量删除',
+    applyChangeEcoin:'申请变动会员余额',
+    modifyEcoinChangeInfo:'修改会员余额变动信息',
+    memberCode:'会员编号',
+    memberName:'会员姓名',
+    memberLevel:'会员级别',
+    accountType:'账户类型',
+    idCardNumber:'身份证号',
+    registerType:'注册类型',
+    pleaseSelectRegisterType:'请选择注册类型',
+    withdrawAmount:'提现金额',
+    estimatedDatePayment:'预计付款日期',
+    selectDate:'选择日期',
+    pleaseSelectAccountType:'请选择账户类型',
+    adjustmentAmount:'调整金额',
+    transactionType:'交易类型',
+    pleaseSelectTranserType:'请选择交易类型',
+    forgeDisplayRemark:'备注前台显示',
+    selectRecordOperateNotice:'请选择要操作的记录',
+    modifyData:'正在修改数据',
+    balanceInsufficientSubmitNotice:'会员账户余额不足,是否继续提交',
+    passingAudit:'正在通过审核',
+    handleAuditDefaultNotice:'确定要通过审核(会员账户不允许为负数)?备注:',
+    handleAuditRejectNotice:'确定要拒绝审核?备注',
+    handleAuditPassNotice:'确定要通过审核(会员账户允许为负数)?备注',
+    okDelData:"确定删除选定的数据?",
+    exportNotice:"确定要导出当前数据吗?",
+    manuallyAdd:'手动添加',
+    adjustAmount:'调整金额',
+    ecoinInsufficientNotice:'会员账户余额不足,是否继续提交',
+    reviewRemberEcoinInfo:'审核会员余额变动信息',
+    statusManagement:'状态管理',
+    viewVoucher:'查看凭证',
+    checkRechargeVoucher:'查看充值凭证',
+    rechargeStatusState:'充值状态',
+    reviewWithdrawalInfoNotice:'审核提现信息',
+    datePayment:'付款日期',
+    selectRecordOperateNotice:'请选择要操作的记录',
+    surePassReviewNoteNotice:'确定要通过审核?备注:',
+    sureUnpaidReviewNotice:'确定要设为待付款?备注:',
+    surePaymentFailureReview:'确定要设为付款失败?备注:',
+    surePaidReviewNotice:'确定要设为已付款?备注:',
+    sureReturnReviewNotice:'确定要设为已退回?备注:',
+    changeStateSelectedDataNotice:'确定要对所选数据修改状态吗?',
+  },
+
+  // 网络管理
+  atlas: {
+    exportNotice:"确定要导出当前数据吗?",
+    sponsorNetworkDiagram:'开拓网络图',
+    sponsorNetworkList:'开拓网络列表',
+    topMember:'顶级会员',
+    spreadDepth:'展开深度',
+    numberOfPeriods:'期数',
+    algebra:'代数',
+    memberCode:'会员编号',
+    name:'姓名',
+    level:'级别',
+    highest:'聘级',
+    depth:'深度',
+    subordinatesMember:'查看该会员的下级',
+    getDataWait:'正在获取数据,请稍后',
+    resettlementNetworkDiagram:'安置网络图',
+    numberOfLayers:'层数',
+    location:'区位',
+    joiningPeriod:'加入期数',
+    placementNetworkList:'安置网络列表',
   },
 
   // 管理员管理
@@ -511,7 +662,25 @@ export default {
     updateAt: '修改时间',
     addRole: '添加角色',
     selectData: '所选数据',
-    roleName: '角色名称'
+    roleName: '角色名称',
+    module: '模块',
+    loginAccount: '登录账号',
+    name: '姓名',
+    pleaseSelectRole: '请选择角色',
+    password: '密码',
+    confirmPassword: '确认密码',
+    bindIp: '绑定IP',
+    pleaseInputContent: '请输入内容',
+    bindIpNotice: '一行一个IP;可指定ip段,如: 192.168.0.1-255',
+    isEnable: '是否启用',
+    isModifyPwd: '是否修改密码',
+    filterBtnName: '查询',
+    loginTimes: '登录次数',
+    lastLoginIp: '最后登录IP',
+    lastLoginAt: '最后登录时间',
+    selectData: '所选数据',
+    addAdmin: '添加管理员',
+    delNotice: '确定删除选定的数据?'
   }
 
 }

+ 144 - 0
src/router/index.js

@@ -70,9 +70,83 @@ export const constantRoutes = [
         path: '/admin/role-permission/:id',
         name: 'admin_role-permission',
         component: () => import('@/views/admin/role-permission') // 角色权限
+      },
+      {
+        path: '/admin/change-password',
+        name: 'admin_change-password',
+        component: () => import('@/views/admin/edit') // 重置密码
+      },
+      {
+        path: '/admin/index',
+        name: 'admin_index',
+        component: () => import('@/views/admin/index') // 管理员列表
+      },
+      {
+        path: '/admin/add',
+        name: 'admin_add',
+        component: () => import('@/views/admin/edit') // 添加管理员
+      },
+      {
+        path: '/admin/edit/:id',
+        name: 'admin_edit',
+        component: () => import('@/views/admin/edit') // 编辑管理员
       }
     ]
   },
+  {
+    path: '/finance',
+    component: Layout,
+    hidden: true,
+    children: [
+      {
+        path: '/finance/balance-audit-list', // 会员余额调整列表
+        component: () => import('@/views/finance/balance-audit-list'),
+        name: 'finance_balance-audit-list',
+      },
+      {
+        path: '/finance/change-balance-opt', // 申请调整会员余额
+        component: () => import('@/views/finance/change-balance-opt'),
+        name: 'finance_change-balance-opt',
+      },
+      {
+        path: '/finance/transfer-list', // 转账记录列表
+        component: () => import('@/views/finance/transfer-list'),
+        name: 'finance_transfer-list',
+      },
+      {
+        path: '/finance/recharge', // 充值管理
+        component: () => import('@/views/finance/recharge'),
+        name: 'finance_recharge',
+      },
+      {
+        path: '/finance/recharge-status', // 状态管理
+        component: () => import('@/views/finance/recharge-status'),
+        name: 'finance_recharge-status',
+      },
+      {
+        path: '/finance/withdraw', // 提现管理
+        component: () => import('@/views/finance/withdraw'),
+        name: 'finance_withdraw',
+      },
+    ]
+  },
+  {
+    path: '/atlas',
+    component: Layout,
+    hidden: true,
+    children: [
+      {
+        path: '/atlas/relation-opt', // 开拓网络
+        component: () => import('@/views/atlas/relation-opt'),
+        name: 'atlas_relation-opt',
+      },
+      {
+        path: '/atlas/network-opt', // 安置网络
+        component: () => import('@/views/atlas/network-opt'),
+        name: 'atlas_network-opt',
+      },
+    ]
+  },
   {
     path: '/login',
     component: () => import('@/views/login/index'),
@@ -270,6 +344,76 @@ export const asyncRoutes = [
       }
     ]
   },
+  {
+    path: '/file',
+    component: Layout,
+    redirect: '/file/export',
+    hidden: true,
+    children: [
+      {
+        path: 'export',
+        component: () => import('@/views/file/export'),
+        name: 'export',
+        meta: { title: 'export', noCache: true }
+      }
+    ]
+  },
+  {
+    path: '/bonus',
+    component: Layout,
+    redirect: '/bonus/balance-list',
+    hidden: true,
+    children: [
+      {
+        path: 'balance-list',
+        component: () => import('@/views/bonus/balance-list'),
+        name: 'balance-list',
+        meta: { title: 'balance-list', noCache: true }
+      },
+      {
+        path: 'other-period-bonus',
+        component: () => import('@/views/bonus/other-period-bonus'),
+        name: 'other-period-bonus',
+        meta: { title: 'other-period-bonus', noCache: true }
+      },
+      {
+        path: 'flow-bonus',
+        component: () => import('@/views/bonus/flow-bonus'),
+        name: 'flow-bonus',
+        meta: { title: 'flow-bonus', noCache: true }
+      },
+      {
+        path: 'user-perf',
+        component: () => import('@/views/bonus/user-perf'),
+        name: 'user-perf',
+        meta: { title: 'user-perf', noCache: true }
+      },
+      {
+        path: 'perf-order',
+        component: () => import('@/views/bonus/perf-order'),
+        name: 'perf-order',
+        meta: { title: 'perf-order', noCache: true }
+      },
+      {
+        path: 'perf-period-list',
+        component: () => import('@/views/bonus/perf-period-list'),
+        name: 'perf-period-list',
+        meta: { title: 'perf-period-list', noCache: true }
+      },
+      {
+        path: 'perf-month',
+        component: () => import('@/views/bonus/perf-month'),
+        name: 'perf-month',
+        meta: { title: 'perf-month', noCache: true }
+      },
+      {
+        path: 'perf-adjustment',
+        component: () => import('@/views/bonus/perf-adjustment'),
+        name: 'perf-adjustment',
+        meta: { title: 'perf-adjustment', noCache: true }
+      }
+    ]
+  },
   {
     path: '/tab',
     component: Layout,

+ 10 - 9
src/views/ad/edit.vue

@@ -57,6 +57,7 @@
 import { fetchDetail, fetchEdit, fetchAdd } from '@/api/ad'
 import tool from '@/utils/tool'
 import Upload from '@/components/Upload'
+import ElementUI from 'element-ui'
 export default {
   name: 'RoleAdd',
   components: { Upload },
@@ -107,8 +108,8 @@ export default {
           this.article = response.data.oneData.CONTENT
         }
         this.loading = false
-      }).catch(err => {
-        console.log('err---------' + err)
+      }).catch((error) => {
+          ElementUI.Message({type: 'error', message: error.message, showClose: true, duration: 0})
       })
     } else {
       fetchDetail(this.$route.params.ID).then(response => {
@@ -116,8 +117,8 @@ export default {
         this.allArticle = response.data.allArticle
 
         this.loading = false
-      }).catch(err => {
-        console.log('err---------' + err)
+      }).catch((error) => {
+          ElementUI.Message({type: 'error', message: error.message, showClose: true, duration: 0})
       })
     }
   },
@@ -133,9 +134,9 @@ export default {
             type: "$t('common.successfully')"
           })
           this.$router.go(-1)
-        }).catch(err => {
-          console.log('err---------' + err)
-        })
+       }).catch((error) => {
+           ElementUI.Message({type: 'error', message: error.message, showClose: true, duration: 0})
+       })
       } else {
         fetchAdd(this.form).then(response => {
           this.submitButtonStat = false
@@ -144,8 +145,8 @@ export default {
             type: 'success'
           })
           this.$router.go(-1)
-        }).catch(err => {
-          console.log('err---------' + err)
+        }).catch((error) => {
+            ElementUI.Message({type: 'error', message: error.message, showClose: true, duration: 0})
         })
       }
     },

+ 13 - 12
src/views/ad/list.vue

@@ -127,6 +127,7 @@ import { parseTime } from '@/utils'
 import tool from '@/utils/tool'
 import permission from '@/utils/permission'
 import Pagination from '@/components/Pagination' // secondary package based on el-pagination
+import ElementUI from 'element-ui'
 
 const calendarTypeOptions = [
   { key: 'CN', display_name: 'China' },
@@ -302,9 +303,9 @@ export default {
     },
     handleDelete(id = null) {
       const obj = this
-      obj.$confirm('Are you sure to delete the selected data?', 'Notice', { // 确定删除选定的数据?
-        confirmButtonText: 'confirm', // 确定
-        cancelButtonText: 'cancel', // 取消
+      obj.$confirm(this.$t('common.deleteSelectedData'), this.$t('common.notice'), { // 确定删除选定的数据?
+       confirmButtonText: this.$t('common.confirm'), // 确定
+       cancelButtonText: this.$t('common.cancel'), // 取消
         type: 'warning'
       }).then(() => {
         const selectedIds = []
@@ -321,14 +322,14 @@ export default {
             type: 'success'
           })
           obj.getList(obj.currentPage, obj.pageSize)
-        }).catch(response => {
-
+        }).catch((error) => {
+            ElementUI.Message({type: 'error', message: error.message, showClose: true, duration: 0})
         })
       })
     },
     handleHide(id = null) {
       const obj = this
-      obj.$confirm('Are you sure to hide the selected data?', 'Notice', { // 确定删除选定的数据?
+     obj.$confirm(this.$t('common.hideSelectedData'), this.$t('common.notice'), {  // 确定删除选定的数据?
         confirmButtonText: 'confirm', // 确定
         cancelButtonText: 'cancel', // 取消
         type: 'warning'
@@ -347,8 +348,8 @@ export default {
             type: 'success'
           })
           obj.getList(obj.currentPage, obj.pageSize)
-        }).catch(response => {
-
+        }).catch((error) => {
+            ElementUI.Message({type: 'error', message: error.message, showClose: true, duration: 0})
         })
       })
     },
@@ -357,7 +358,7 @@ export default {
     },
     handleUnhide(id = null) {
       const obj = this
-      obj.$confirm('Are you sure to hide the selected data?', 'Notice', { // 确定删除选定的数据?
+     obj.$confirm(this.$t('common.unHideSelectedData'), this.$t('common.notice'), { // 确定删除选定的数据?
         confirmButtonText: 'confirm', // 确定
         cancelButtonText: 'cancel', // 取消
         type: 'warning'
@@ -376,9 +377,9 @@ export default {
             type: 'success'
           })
           obj.getList(obj.currentPage, obj.pageSize)
-        }).catch(response => {
-
-        })
+       }).catch((error) => {
+           ElementUI.Message({type: 'error', message: error.message, showClose: true, duration: 0})
+       })
       })
     }
   }

+ 173 - 0
src/views/admin/edit.vue

@@ -0,0 +1,173 @@
+<template>
+  <div v-loading="loading">
+    <div class="white-box">
+      <el-form ref="form" :model="form" label-width="250px" class="bkele-form-page">
+        <el-form-item v-show="isAddOrEdit" :label="$t('Administrator.loginAccount')">
+          <el-input v-model="form.adminName" :disabled="isEdit" />
+        </el-form-item>
+        <el-form-item v-show="isAddOrEdit" :label="$t('Administrator.name')">
+          <el-input v-model="form.realName" />
+        </el-form-item>
+        <el-form-item v-show="isAddOrEdit" :label="$t('Administrator.role')">
+          <el-select v-model="form.roleId" :placeholder="$t('Administrator.pleaseSelectRole')">
+            <el-option v-for="item in roles" :key="item.ID" :label="item.ROLE_NAME" :value="item.ID" />
+          </el-select>
+        </el-form-item>
+        <el-form-item :label="$t('Administrator.password')"><!-- 密码 -->
+          <el-input v-model="form.password" type="password" />
+        </el-form-item>
+        <el-form-item :label="$t('Administrator.confirmPassword')"><!-- 确认密码 -->
+          <el-input v-model="form.surePassword" type="password" />
+        </el-form-item>
+        <el-form-item v-show="isAddOrEdit" :label="$t('Administrator.bindIp')">
+          <el-input
+            v-model="form.bindIp"
+            type="textarea"
+            :rows="4"
+            :placeholder="$t('Administrator.pleaseInputContent')"
+          />
+          <el-tag type="info">{{ $t("Administrator.bindIpNotice") }}</el-tag>
+        </el-form-item>
+        <el-form-item v-show="isAddOrEdit" :label="$t('common.note')">
+          <el-input v-model="form.remark" />
+        </el-form-item>
+        <el-form-item v-show="isAddOrEdit" :label="$t('Administrator.isEnable')">
+          <el-switch v-model="form.isEnable" />
+        </el-form-item>
+        <el-form-item v-show="isAddOrEdit" :label="$t('Administrator.isModifyPwd')">
+          <el-switch v-model="form.isModifyPassword" />
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" :loading="submitButtonStat" @click="onSubmit">{{ $t('common.save') }}<!--保存--></el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+  </div>
+</template>
+<script>
+import { adminAddAndEditAndChangePassword, adminAdd, adminEdit } from '@/api/filter'
+export default {
+  name: 'RoleAdd',
+  data() {
+    return {
+      form: {
+        adminName: null,
+        realName: null,
+        remark: null,
+        isEnable: true,
+        isModifyPassword: false,
+        bindIp: '',
+        roleId: null,
+        password: null,
+        surePassword: null
+      },
+      loading: true,
+      submitButtonStat: false,
+      isEdit: false,
+      roles: null
+    }
+  },
+  computed: {
+    isAddOrEdit() {
+      if (this.$route.name === 'admin_add' || this.$route.name === 'admin_edit') {
+        return true
+      }
+      return false
+    }
+  },
+  watch: {
+    '$route'() {
+      for (const i in this.form) {
+        this.form[i] = null
+      }
+    }
+  },
+  mounted() {
+    if (this.$route.name === 'admin_edit') {
+      adminEdit(this.$route.params.id).then(response => {
+        this.form = response.data.oneData
+        this.roles = response.data.adminRoles
+        this.loading = false
+        this.isEdit = true
+      }).catch(err => {
+        console.log('err=============' + err)
+        this.loading = false
+        this.$message({
+          message: err,
+          type: 'error'
+        })
+      })
+    } else if (this.$route.name === 'admin_add') {
+      adminAdd().then(response => {
+        this.roles = response.data.adminRoles
+        this.loading = false
+      }).catch(err => {
+        console.log('err=============' + err)
+        this.loading = false
+        this.$message({
+          message: err,
+          type: 'error'
+        })
+      })
+    } else {
+      this.loading = false
+    }
+  },
+  methods: {
+    onSubmit() {
+      this.submitButtonStat = true
+      let path = 'admin/add'
+      if (this.$route.name === 'admin_edit') {
+        path = 'admin/edit/' + this.$route.params.id
+      } else if (this.$route.name === 'admin_change-password') {
+        path = 'admin/change-password'
+      }
+      adminAddAndEditAndChangePassword(path, this.form).then(response => {
+        this.submitButtonStat = false
+        console.log(response)
+        this.$message({
+          message: response.data,
+          type: 'success'
+        })
+        this.$router.go(-1)
+      }).catch(err => {
+        console.log('err=============' + err)
+        this.submitButtonStat = false
+        this.$message({
+          message: err,
+          type: 'error'
+        })
+      })
+    }
+  }
+}
+</script>
+
+  <style scoped>
+  .el-form-item{
+        margin-top: 35px;
+    }
+@media (min-width: 761px) {
+    /deep/ .el-input__inner {
+      width: 500px;
+    }
+  }
+  @media (max-width:760px) {
+    /deep/ .white-box {
+    padding: 0px 0px;
+    }
+    /deep/ .el-form-item__content {
+      margin-left:150px !important;
+    }
+    /deep/ .el-form-item__label {
+      width:150px !important;
+    }
+    /deep/ .el-input__inner { 
+      width: 150px;
+    }
+    /* .el-input {
+      width: 90%;
+    } */
+
+  }
+  </style>

+ 274 - 0
src/views/admin/index.vue

@@ -0,0 +1,274 @@
+<template>
+  <div v-loading="loading">
+    <div class="white-box">
+      <div class="filter-box">
+        <filter-user
+          :filter-types.sync="filterTypes"
+          :filter-btn-name="$t('Administrator.filterBtnName')"
+          @select-value="handleFilterUser"
+        />
+      </div>
+      <el-table :data="tableData" stripe style="width: 100%;" :height="tool.getTableHeight()" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" :selectable="checkSelectable" />
+        <el-table-column :label="$t('Administrator.loginAccount')" prop="ADMIN_NAME" width="150">
+          <template slot-scope="scope">
+            <el-tag type="" size="small" class="no-border">{{ scope.row.ADMIN_NAME }}</el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column :label="$t('Administrator.name')" prop="REAL_NAME" width="150">
+          <template slot-scope="scope">
+            {{ scope.row.REAL_NAME }}
+          </template>
+        </el-table-column>
+        <el-table-column :label="$t('Administrator.remark')" prop="REMARK" width="150">
+          <template slot-scope="scope">
+            {{ scope.row.REMARK }}
+          </template>
+        </el-table-column>
+        <el-table-column :label="$t('Administrator.role')" prop="ROLE_NAME" width="150">
+          <template slot-scope="scope">
+            <el-tag type="warning" size="small" class="no-border">{{ scope.row.ROLE_NAME }}</el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column :label="$t('Administrator.isEnable')" prop="IS_ENABLE">
+          <template slot-scope="scope">
+            <el-tag :type="(scope.row.IS_ENABLE==1?'success':'danger')">
+              <template v-if="scope.row.IS_ENABLE==1">
+                {{ $t('common.yes') }}
+              </template>
+              <template v-else>
+                {{ $t('common.no') }}
+              </template>
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column :label="$t('Administrator.loginTimes')" prop="LOGIN_NUMS">
+          <template slot-scope="scope">
+            {{ scope.row.LOGIN_NUMS }}
+          </template>
+        </el-table-column>
+        <el-table-column :label="$t('Administrator.lastLoginIp')" prop="LAST_LOGIN_IP" width="150">
+          <template slot-scope="scope">
+            {{ scope.row.LAST_LOGIN_IP }}
+          </template>
+        </el-table-column>
+        <el-table-column :label="$t('Administrator.lastLoginAt')" width="180">
+          <template slot-scope="scope">
+            {{ tool.formatDate(scope.row.LAST_LOGIN_AT) }}
+          </template>
+        </el-table-column>
+        <el-table-column :label="$t('Administrator.bindIp')" width="250">
+          <template slot-scope="scope">
+            {{ scope.row.BIND_IP }}
+          </template>
+        </el-table-column>
+        <el-table-column :label="$t('Administrator.creatUser')" width="150">
+          <template slot-scope="scope">
+            {{ scope.row.CREATE_ADMIN_NAME }}
+          </template>
+        </el-table-column>
+        <el-table-column :label="$t('Administrator.creatAt')" width="180">
+          <template slot-scope="scope">
+            {{ tool.formatDate(scope.row.CREATED_AT) }}
+          </template>
+        </el-table-column>
+        <el-table-column :label="$t('Administrator.updateUser')" width="150">
+          <template slot-scope="scope">
+            {{ scope.row.UPDATE_ADMIN_NAME }}
+          </template>
+        </el-table-column>
+        <el-table-column :label="$t('Administrator.updateAt')" width="180">
+          <template slot-scope="scope">
+            {{ tool.formatDate(scope.row.UPDATED_AT) }}
+          </template>
+        </el-table-column>
+
+        <el-table-column :fixed="fixedColumn" :label="$t('table.actions')" width="180">
+          <template slot-scope="scope">
+            <el-dropdown v-if="scope.row.DONT_DEL!=='1'&&(permission.hasPermission(`admin/edit`)||permission.hasPermission(`admin/admin-delete`))" size="small" trigger="click" @command="handleRow" @click.stop="">
+              <el-button type="primary" size="small">
+                {{ $t('common.action') }}<i class="el-icon-arrow-down el-icon--right" />
+              </el-button>
+              <el-dropdown-menu slot="dropdown">
+                <el-dropdown-item v-if="permission.hasPermission(`admin/edit`)" :command="`edit|${scope.row.ID}`">{{ $t('common.edit') }}</el-dropdown-item>
+                <el-dropdown-item v-if="permission.hasPermission(`admin/admin-delete`)" :command="`delete|${scope.row.ID}`">{{ $t('common.delete') }}</el-dropdown-item>
+              </el-dropdown-menu>
+            </el-dropdown>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="white-box-footer">
+        <el-dropdown v-if="permission.hasPermission(`admin/admin-delete`)" size="small" trigger="click" @command="handleMuliDel">
+          <el-button type="primary" size="small">
+            {{ $t('Administrator.selectData') }}
+            <!--所选数据--><i class="el-icon-arrow-down el-icon--right" />
+          </el-button>
+          <el-dropdown-menu slot="dropdown">
+            <el-dropdown-item command="delete">{{ $t('common.delete') }}</el-dropdown-item>
+          </el-dropdown-menu>
+        </el-dropdown>
+        <el-button v-show="permission.hasPermission(`admin/add`)" type="primary" size="small" icon="el-icon-plus" @click="handleAdd">{{ $t('Administrator.addAdmin') }}</el-button>
+        <pagination :total="totalCount" :page_size="pageSize" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { adminList, adminDelete } from '@/api/filter'
+import tool from '@/utils/tool'
+import FilterUser from '@/components/FilterUser'
+import permission from '@/utils/permission'
+import Pagination from '@/components/Pagination'
+import filterHelper from '@/utils/filterHelper'
+import {getOperatingSystem} from "@/utils"
+
+export default {
+  name: 'DecLevel',
+  components: { FilterUser, Pagination },
+  data() {
+    return {
+      fixedColumn:false, // 固定,当手机端不固定,pc固定
+      tableData: null,
+      loading: true,
+      multipleSelection: [],
+      currentPage: 1,
+      totalPages: 1,
+      totalCount: 1,
+      pageSize: 20,
+      tool: tool,
+      permission: permission,
+      filterData: null,
+      filterTypes: {
+        'ADMIN_NAME': { isUserTable: false, name: this.$t('Administrator.loginAccount') },
+        'REAL_NAME': { isUserTable: false, name: this.$t('Administrator.name') },
+        'REMARK': { isUserTable: false, name: this.$t('Administrator.remark') },
+        'ROLE_NAME': { isUserTable: false, name: this.$t('Administrator.role') },
+        'IS_ENABLE': { isUserTable: false, name: this.$t('Administrator.isEnable'), other: 'yesOrNo' },
+        'LOGIN_NUMS': { isUserTable: false, name: this.$t('Administrator.loginTimes') },
+        'LAST_LOGIN_IP': { isUserTable: false, name: this.$t('Administrator.lastLoginIp') },
+        'LAST_LOGIN_AT': { isUserTable: false, name: this.$t('Administrator.lastLoginAt'), other: 'date' },
+        'BIND_IP': { isUserTable: false, name: this.$t('Administrator.bindIp') },
+        'CREATE_ADMIN_NAME': { isUserTable: false, name: this.$t('Administrator.creatUser') },
+        'CREATED_AT': { isUserTable: false, name: this.$t('Administrator.creatAt'), other: 'date' },
+        'UPDATE_ADMIN_NAME': { isUserTable: false, name: this.$t('Administrator.updateUser') },
+        'UPDATED_AT': { isUserTable: false, name: this.$t('Administrator.updateAt'), other: 'date' }
+      },
+      filterModel: {}
+    }
+  },
+  mounted() {
+    this.getData()
+    let system =  getOperatingSystem()
+    if (system == "Android" || system == 'ios') {
+      this.fixedColumn = false
+    } else {
+      this.fixedColumn = 'right'
+    }
+  },
+  methods: {
+    checkSelectable(row) {
+      return row.DONT_DEL !== '1'
+    },
+    handleSelectionChange(val) {
+      this.multipleSelection = val
+    },
+    handleCurrentChange(page) {
+      this.getData(page, this.pageSize)
+    },
+    handleSizeChange(pageSize) {
+      this.getData(this.currentPage, pageSize)
+    },
+    handleRow(command) {
+      const re = command.split('|')
+      this.handleCommand(re[0], re[1])
+    },
+    handleMuliDel(command) {
+      if (command === 'delete') {
+        this.delData(this)
+      }
+    },
+    handleAdd() {
+      this.$router.push({ path: `/admin/add` })
+    },
+    handleUpdate(row) {
+      this.$router.push({ path: `/admin/edit/${row.ID}` })
+    },
+    handleCommand(command, id) {
+      if (command === 'edit') {
+        this.$router.push({ path: `/admin/edit/${id}` })
+      } else if (command === 'delete') {
+        this.delData(this, id)
+      }
+    },
+    handleFilterUser(filterData) {
+      filterHelper.handleFilterUser(this, filterData)
+    },
+    handleFilter() {
+      this.getData()
+    },
+    getData(page, pageSize) {
+      const filterData = this.filterModel
+      const vueObj = this
+      const paramsData = Object.assign({
+        page: (page === null || page == undefined) ? 1 : page,
+        pageSize: (pageSize === null || pageSize == undefined) ? vueObj.pageSize : pageSize
+      }, filterData)
+      adminList(paramsData).then(response => {
+        vueObj.tableData = response.data.list
+        vueObj.currentPage = page
+        vueObj.totalPages = parseInt(response.data.totalPages)
+        vueObj.totalCount = parseInt(response.data.totalCount)
+        vueObj.pageSize = pageSize
+        this.loading = false
+      }).catch(err => {
+        console.log('err=============' + err)
+        this.loading = false
+      })
+    },
+    delData(obj, id = null) {
+      obj.$confirm(this.$t('Administrator.delNotice'), this.$t('common.hint'), {
+        confirmButtonText: this.$t('common.confirm'), // 确定
+        cancelButtonText: this.$t('common.cancel'), // 取消
+        type: 'warning'
+      }).then(() => {
+        const selectedIds = []
+        if (id === null) {
+          for (const val of obj.multipleSelection) {
+            selectedIds.push(val.ID)
+          }
+        } else {
+          selectedIds.push(id)
+        }
+        return adminDelete({
+          selected: selectedIds
+        }).then(response => {
+          obj.$message({
+            message: response.data,
+            type: 'success'
+          })
+          obj.getData()
+        }).catch(err => {
+          console.log('err---------' + err)
+        })
+        //   return network.postData(`admin/admin-delete`, {
+        //       selected: selectedIds
+        //   })
+      }).then(response => {
+        obj.$message({
+          message: response.data,
+          type: 'success'
+        })
+        obj.getData()
+      }).catch(response => {
+
+      })
+    }
+  }
+}
+
+</script>
+
+  <style scoped>
+
+  </style>

+ 29 - 26
src/views/admin/role-add.vue

@@ -1,18 +1,18 @@
 <template>
   <div v-loading="loading">
-    <div class="white-box">
-      <el-form ref="form" :model="form" label-width="250px" class="form-page">
-        <el-form-item :label="$t('Administrator.roleName')">
-          <el-input v-model="form.roleName" />
-        </el-form-item>
-        <el-form-item :label="$t('common.desc')">
-          <el-input v-model="form.remark" />
-        </el-form-item>
-        <el-form-item>
-          <el-button type="primary" :loading="submitButtonStat" @click="onSubmit">{{ $t('common.save') }}</el-button>
-        </el-form-item>
-      </el-form>
-    </div>
+      <div class="whitebox-bg">
+        <el-form ref="form" :model="form" class="role-add-form" >
+          <el-form-item :label="$t('Administrator.roleName')">
+            <el-input v-model="form.roleName"></el-input>
+          </el-form-item>
+          <el-form-item :label="$t('common.desc')">
+            <el-input v-model="form.remark"></el-input>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" :loading="submitButtonStat" @click="onSubmit">{{ $t('common.save') }}</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
   </div>
 </template>
 
@@ -56,23 +56,26 @@ export default {
         })
         this.$router.go(-1)
       }).catch(err => {
+        this.submitButtonStat = false
+        this.$message({
+          message: err,
+          type: 'error'
+        })
         console.log('err---------' + err)
       })
-      // network.postData(path, this.form).then(response => {
-      //   this.submitButtonStat = false
-      //   this.$message({
-      //     message: response,
-      //     type: 'success'
-      //   })
-      //   this.$router.go(-1)
-      // }).catch(() => {
-      //   this.submitButtonStat = false
-      // })
     }
   }
 }
 </script>
 
-  <style scoped>
-
-  </style>
+<style scoped>
+.whitebox-bg {
+  background: #fff;
+  padding: 25px;
+}
+@media (min-width: 760px) {
+  /* /deep/ .el-form-item__content {
+    width: 700px;
+  } */
+}
+</style>

+ 3 - 3
src/views/admin/role-permission.vue

@@ -2,7 +2,7 @@
   <div v-loading="loading">
     <div class="white-box admin-role-box">
       <el-table :data="tableData" border style="width: 100%">
-        <el-table-column label="模块" width="180">
+        <el-table-column :label="$t('Administrator.module')" width="180">
           <template slot-scope="scope">
             <el-checkbox
               v-model="mainCheck[scope.row.id]"
@@ -13,7 +13,7 @@
             </el-checkbox>
           </template>
         </el-table-column>
-        <el-table-column label="权限">
+        <el-table-column :label="$t('permission.permission')">
           <template slot-scope="scope">
             <el-checkbox-group
               v-model="checkedValue"
@@ -28,7 +28,7 @@
         </el-table-column>
       </el-table>
       <div style="margin-top: 20px">
-        <el-button type="primary" :loading="submitButtonStat" style="float: right;" @click="onSubmit">Submit<!-- 提交 --></el-button>
+        <el-button type="primary" :loading="submitButtonStat" style="float: right;" @click="onSubmit">{{ $t("common.submit") }}<!-- 提交 --></el-button>
       </div>
     </div>
   </div>

+ 10 - 22
src/views/admin/role.vue

@@ -36,7 +36,7 @@
             {{ tool.formatDate(scope.row.UPDATED_AT) }}
           </template>
         </el-table-column>
-        <el-table-column fixed="right" :label="$t('table.actions')" width="180">
+        <el-table-column :fixed="fixedColumn" :label="$t('table.actions')" width="180">
           <template slot-scope="scope">
             <el-dropdown v-if="scope.row.DONT_DEL==='0'&&(permission.hasPermission(`admin/role-permission`)||permission.hasPermission(`admin/role-edit`)||permission.hasPermission(`admin/role-delete`))" size="small" trigger="click" @command="handleRow" @click.stop="">
               <el-button type="primary" size="small">
@@ -74,13 +74,15 @@ import tool from '@/utils/tool'
 import FilterUser from '@/components/FilterUser'
 import permission from '@/utils/permission'
 import Pagination from '@/components/Pagination'
-import filterHelper from '../../utils/filterHelper'
+import filterHelper from '@/utils/filterHelper'
+import {getOperatingSystem} from "@/utils"
 
 export default {
   name: 'Role',
   components: { FilterUser, Pagination },
   data() {
     return {
+      fixedColumn:false, // 固定,当手机端不固定,pc固定
       tableData: null,
       loading: true,
       multipleSelection: [],
@@ -107,6 +109,12 @@ export default {
   },
   mounted() {
     this.getData()
+    let system =  getOperatingSystem()
+    if (system == "Android" || system == 'ios') {
+      this.fixedColumn = false
+    } else {
+      this.fixedColumn = 'right'
+    }
   },
   methods: {
     handleSelectionChange(val) {
@@ -151,14 +159,6 @@ export default {
         }).catch(err => {
           console.log('err---------' + err)
         })
-
-        // network.getData(`admin/role-delete/${id}`).then(response => {
-        //   this.$message({
-        //     message: response,
-        //     type: 'success'
-        //   })
-        //   this.getData()
-        // })
       })
     },
     muliDelHandle(command) {
@@ -183,15 +183,6 @@ export default {
           }).catch(err => {
             console.log('err---------' + err)
           })
-          //   network.postData(`admin/role-delete`, {
-          //     selected: selectedIds
-          //   }).then(response => {
-          //     this.$message({
-          //       message: response,
-          //       type: 'success'
-          //     })
-          //     this.getData()
-          //   })
         })
       }
     },
@@ -219,9 +210,6 @@ export default {
         console.log('err=============' + err)
         this.loading = false
       })
-      //   network.getPageData(this, 'admin/role', page, pageSize, filterData, function (response) {
-      //     vueObj.allData = response
-      //   })
     }
   }
 }

+ 3 - 3
src/views/article/category.vue

@@ -3,8 +3,8 @@
     <div class="white-box">
       <el-table :data="tableData" stripe style="width: 100%;" @selection-change="handleSelectionChange">
         <el-table-column type="selection" width="55" />
-        <el-table-column label="Category Name" prop="CATE_NAME" /><!--分类名称-->
-        <el-table-column label="Order" width="100"><!--排序-->
+        <el-table-column :label="$t('article.categoryName')" prop="CATE_NAME" /><!--分类名称-->
+        <el-table-column :label="$t('article.order')" width="100"><!--排序-->
           <template slot-scope="scope">
             <el-input
               v-model="scope.row.SORT"
@@ -14,7 +14,7 @@
             />
           </template>
         </el-table-column>
-        <el-table-column label="Creation Time"><!--创建时间-->
+        <el-table-column :label="$t('article.creationTime')"><!--创建时间-->
           <template slot-scope="scope">
             {{ tool.formatDate(scope.row.CREATED_AT) }}
           </template>

+ 13 - 11
src/views/article/edit.vue

@@ -2,18 +2,18 @@
   <div v-loading="loading">
     <div class="white-box">
       <el-form ref="form" :model="form" label-width="100px">
-        <el-form-item label="Title" style="width: 500px;"><!--标题-->
+        <el-form-item :label="$t('article.title')" style="width: 500px;"><!--标题-->
           <el-input v-model="form.title" />
         </el-form-item>
-        <el-form-item label="Category"><!--分类-->
+        <el-form-item :label="$t('article.category')"><!--分类-->
           <el-select v-model="form.cid" placeholder="please select category"><!--请选择分类-->
             <el-option v-for="item in allCategory" :key="item.ID" :label="item.CATE_NAME" :value="item.ID" />
           </el-select>
         </el-form-item>
-        <el-form-item label="Order" style="width: 500px;"><!--排序值-->
+        <el-form-item :label="$t('article.order')" style="width: 500px;"><!--排序值-->
           <el-input v-model="form.sort" />
         </el-form-item>
-        <el-form-item label="Content"><!--内容-->
+        <el-form-item :label="$t('article.content')"><!--内容-->
           <div class="components-container" style="margin:0">
             <!-- <aside>
               {{ $t('components.tinymceTips') }}
@@ -26,7 +26,7 @@
           </div>
         </el-form-item>
         <el-form-item>
-          <el-button type="primary" :loading="submitButtonStat" @click="onSubmit">Confirm<!-- 提交 --></el-button>
+          <el-button type="primary" :loading="submitButtonStat" @click="onSubmit">{{$t('article.confirm')}}<!-- 提交 --></el-button>
         </el-form-item>
       </el-form>
     </div>
@@ -36,6 +36,8 @@
 <script>
 import Tinymce from '@/components/Tinymce'
 import { fetchArticleDetail, fetchArticleAdd, fetchArticleAddList, fetchArticleEdit } from '@/api/article'
+import tool from '@/utils/tool'
+import ElementUI from 'element-ui'
 
 export default {
   name: 'ArticleEdit',
@@ -50,7 +52,7 @@ export default {
       },
       content: '',
       allCategory: null,
-      loading: false,
+      loading: true,
       submitButtonStat: false,
       isEdit: false
     }
@@ -62,7 +64,7 @@ export default {
         this.form.cid = response.data.oneData.CID
         this.form.content = response.data.oneData.CONTENT
         this.form.sort = response.data.oneData.SORT
-        this.allCategory = response.allCategory
+        this.allCategory = response.data.allCategory
         this.loading = false
         this.isEdit = true
       })
@@ -85,8 +87,8 @@ export default {
             type: 'success'
           })
           this.$router.go(-1)
-        }).catch(() => {
-          this.submitButtonStat = false
+          }).catch((error) => {
+            ElementUI.Message({type: 'error', message: error.message, showClose: true, duration: 0})
         })
       } else {
         fetchArticleAdd(this.form).then(response => {
@@ -96,8 +98,8 @@ export default {
             type: 'success'
           })
           this.$router.go(-1)
-        }).catch(() => {
-          this.submitButtonStat = false
+        }).catch((error) => {
+          ElementUI.Message({type: 'error', message: error.message, showClose: true, duration: 0})
         })
       }
     }

+ 36 - 35
src/views/article/index.vue

@@ -3,53 +3,53 @@
     <div class="white-box">
       <el-table :data="tableData" stripe style="width: 100%;" @selection-change="handleSelectionChange">
         <el-table-column type="selection" width="55" />
-        <el-table-column label="ID" prop="ID">
+        <el-table-column :label="$t('article.id')" prop="ID">
           <template slot-scope="scope">
             <router-link :to="`/article/detail/${scope.row.ID}`" target="_blank" class="islide">
               <span>{{ scope.row.ID }}</span>
             </router-link>
           </template>
         </el-table-column>
-        <el-table-column label="Title" prop="TITLE">
+        <el-table-column :label="$t('article.title')" prop="TITLE">
           <template slot-scope="scope">
             <router-link :to="`/article/detail/${scope.row.ID}`" target="_blank" class="islide">
               <span>{{ scope.row.TITLE }}</span>
             </router-link>
           </template>
         </el-table-column><!--标题-->
-        <el-table-column label="Category"><!--分类-->
+        <el-table-column :label="$t('article.category')"><!--分类-->
           <template slot-scope="scope">
             {{ allData.allCategory[scope.row.CID].CATE_NAME }}
           </template>
         </el-table-column>
-        <el-table-column label="Sort" width="100"> <!-- 排序 -->
+        <el-table-column :label="$t('article.sort')" width="100"> <!-- 排序 -->
           <template slot-scope="scope">
             <el-input v-model="scope.row.SORT" min="0" max="99" @change="handleChangeSort(scope.row, scope.row.SORT)" />
           </template>
         </el-table-column>
-        <el-table-column label="Creation Time"><!--创建时间-->
+        <el-table-column :label="$t('article.creationTime')"><!--创建时间-->
           <template slot-scope="scope">
             {{ tool.formatDate(scope.row.CREATED_AT) }}
           </template>
         </el-table-column>
-        <el-table-column label="Status"> <!-- 状态 -->
+        <el-table-column :label="$t('article.status')"> <!-- 状态 -->
           <template slot-scope="scope">
-            <div v-if="scope.row.STATUS === '1'">Show</div>
-            <div v-else>Hide</div>
+            <div v-if="scope.row.STATUS === '1'">{{$t('article.show')}}</div>
+            <div v-else>{{$t('common.hide')}}</div>
           </template>
         </el-table-column>
 
-        <el-table-column fixed="right" label="Action" width="180"><!--操作-->
+        <el-table-column fixed="right" :label="$t('article.action')" width="180"><!--操作-->
           <template slot-scope="scope">
             <el-dropdown size="small" trigger="click">
               <el-button type="primary" size="small" @click.stop="">
-                Action<i class="el-icon-arrow-down el-icon--right" />
+                {{$t('article.action')}}<i class="el-icon-arrow-down el-icon--right" />
               </el-button>
               <el-dropdown-menu slot="dropdown">
-                <el-dropdown-item command="edit" @click.native="handleEdit(scope.row)">Edit</el-dropdown-item>
-                <el-dropdown-item command="delete" @click.native="handleDelete(scope.row)">Delete</el-dropdown-item>
-                <el-dropdown-item command="hide" @click.native="handleHide(scope.row)">Hide</el-dropdown-item>
-                <el-dropdown-item command="un-hide" @click.native="handleUnHide(scope.row)">Unhide</el-dropdown-item>
+                <el-dropdown-item command="edit" @click.native="handleEdit(scope.row)">{{$t('common.edit')}}</el-dropdown-item>
+                <el-dropdown-item command="delete" @click.native="handleDelete(scope.row)">{{$t('common.delete')}}</el-dropdown-item>
+                <el-dropdown-item command="hide" @click.native="handleHide(scope.row)">{{$t('common.hide')}}</el-dropdown-item>
+                <el-dropdown-item command="un-hide" @click.native="handleUnHide(scope.row)">{{$t('common.unhide')}}</el-dropdown-item>
               </el-dropdown-menu>
             </el-dropdown>
           </template>
@@ -58,15 +58,15 @@
       <div class="white-box-footer">
         <el-dropdown size="small" trigger="click">
           <el-button type="primary" size="small">
-            Selected data<!--所选数据--><i class="el-icon-arrow-down el-icon--right" />
+            {{$t('common.selectData')}}<!--所选数据--><i class="el-icon-arrow-down el-icon--right" />
           </el-button>
           <el-dropdown-menu slot="dropdown">
-            <el-dropdown-item command="delete" @click.native="handleMuliDel()">Delete</el-dropdown-item>
-            <el-dropdown-item command="hide" @click.native="handleMultiHide()">Hide</el-dropdown-item>
-            <el-dropdown-item command="un-hide" @click.native="handleMultiUnHide()">Unhide</el-dropdown-item>
+            <el-dropdown-item command="delete" @click.native="handleMuliDel()">{{$t('common.delete')}}</el-dropdown-item>
+            <el-dropdown-item command="hide" @click.native="handleMultiHide()">{{$t('common.hide')}}</el-dropdown-item>
+            <el-dropdown-item command="un-hide" @click.native="handleMultiUnHide()">{{$t('common.unhide')}}</el-dropdown-item>
           </el-dropdown-menu>
         </el-dropdown>
-        <el-button type="primary" size="small" @click="handleAdd">New article</el-button><!--添加文章-->
+        <el-button type="primary" size="small" @click="handleAdd">{{$t('article.newArticle')}}</el-button><!--添加文章-->
         <el-pagination
           :current-page="currentPage"
           :page-sizes="[20, 50, 100, 200]"
@@ -84,6 +84,7 @@
 <script>
 import { fetchArticleIndex, fetchChangeArticleSort, fetchArticleHide, fetchArticleUnhide, fetchArticleDel } from '@/api/article'
 import tool from '@/utils/tool'
+import ElementUI from 'element-ui'
 
 export default {
   name: 'ArticleIndex',
@@ -158,9 +159,9 @@ export default {
     },
     delData(id = null) {
       const obj = this
-      obj.$confirm('Are you sure to delete the selected data?', 'Hint', { // 确定删除选定的数据
-        confirmButtonText: 'confirm', // 确定
-        cancelButtonText: 'cancel', // 取消
+      obj.$confirm(this.$t('common.deleteSelectedData'), this.$t('common.notice'), { // 确定删除选定的数据
+        confirmButtonText: this.$t('common.confirm'), // 确定
+        cancelButtonText: this.$t('common.cancel'), // 取消
         type: 'warning'
       }).then(() => {
         const selectedIds = []
@@ -177,16 +178,16 @@ export default {
             type: 'success'
           })
           obj.getData(obj.currentPage, obj.pageSize)
-        }).catch(response => {
-
+        }).catch((error) => {
+            ElementUI.Message({type: 'error', message: error.message, showClose: true, duration: 0})
         })
       })
     },
     hideData(id = null) {
       const obj = this
-      obj.$confirm('Are you sure to hide the selected data?', 'Notice', { // 确定删除选定的数据?
-        confirmButtonText: 'confirm', // 确定
-        cancelButtonText: 'cancel', // 取消
+      obj.$confirm(this.$t('common.hideSelectedData'), this.$t('common.notice'), { // 确定删除选定的数据?
+        confirmButtonText: this.$t('common.confirm'), // 确定
+        cancelButtonText: this.$t('common.cancel'), // 取消
         type: 'warning'
       }).then(() => {
         const selectedIds = []
@@ -203,16 +204,16 @@ export default {
             type: 'success'
           })
           obj.getData(obj.currentPage, obj.pageSize)
-        }).catch(response => {
-
+        }).catch((error) => {
+            ElementUI.Message({type: 'error', message: error.message, showClose: true, duration: 0})
         })
       })
     },
     unHideData(id = null) {
       const obj = this
-      obj.$confirm('Are you sure to un-hide the selected data?', 'Notice', { // 确定删除选定的数据?
-        confirmButtonText: 'confirm', // 确定
-        cancelButtonText: 'cancel', // 取消
+      obj.$confirm(this.$t('common.unHideSelectedData'), this.$t('common.notice'), { // 确定删除选定的数据?
+        confirmButtonText: this.$t('common.confirm'), // 确定
+        cancelButtonText: this.$t('common.cancel'), // 取消
         type: 'warning'
       }).then(() => {
         const selectedIds = []
@@ -229,9 +230,9 @@ export default {
             type: 'success'
           })
           obj.getData(obj.currentPage, obj.pageSize)
-        }).catch(response => {
-
-        })
+       }).catch((error) => {
+           ElementUI.Message({type: 'error', message: error.message, showClose: true, duration: 0})
+       })
       })
     }
   }

+ 348 - 0
src/views/atlas/network-opt.vue

@@ -0,0 +1,348 @@
+<template>
+    <div v-loading="loading">
+      <div class="white-box">
+        <el-tabs v-model="tabActiveName">
+          <el-tab-pane :label="$t('atlas.resettlementNetworkDiagram')" name="first" v-if="permission.hasPermission(`atlas/network`)"><!-- 安置网络图 -->
+            <div class="filter-user" @keyup.enter="enterToGetData()">
+              <el-input v-model="mainUserName" size="small" style="width:300px;">
+                <template slot="prepend">{{ $t('atlas.topMember') }}<!-- 顶级会员 --></template>
+              </el-input>
+              <el-input v-model="expandDeep" size="small" style="width:200px;">
+                <template slot="prepend">{{ $t('atlas.spreadDepth') }}<!-- 展开深度 --></template>
+              </el-input>
+              <el-input v-model="periodNum" size="small" style="width:150px;" v-show="false">
+                <template slot="prepend">{{ $t('atlas.numberOfPeriods') }}<!-- 期数 --></template>
+              </el-input>
+              <el-button type="primary" size="small" @click="getMainData()">{{ $t('common.confirm') }}<!-- 确定 --></el-button>
+            </div>
+            <el-tree :props="props" :data="treeData" node-key="USER_ID" @node-click="getChildData" ref="tree" :indent="0"
+                     default-expand-all :height="tool.getTableHeight(true)">
+              <span :id="'node_'+data.USER_ID" :class="'custom-tree-node '+data.className"
+                    slot-scope="{ node, data }">
+                <span :class="'el-icon-loading '+ data.displayNone"></span>
+                <span :class="data.icon"></span>
+                <span>
+                  <el-tag type="danger">{{ $t('atlas.numberOfLayers') }} :{{countTopDeep(data.TOP_NETWORK_DEEP,topDeep)}}</el-tag>
+                  <el-tag><!-- 会员编号 -->{{ $t('atlas.memberCode') }}:{{ node.label }}</el-tag>
+                  <el-tag>{{ $t('atlas.name') }}<!-- 姓名 -->:{{data.REAL_NAME}}</el-tag>
+                  <el-tag type="danger"><!-- 区位 -->{{ $t('atlas.location') }}:{{data.RELATIVE_LOCATION}}</el-tag>
+                  <el-tag type="success"><!-- 级别 -->{{ $t('atlas.level') }}:{{data.DEC_LV_NAME}}</el-tag>
+                  <el-tag type="warning"><!-- 聘级 -->{{ $t('atlas.highest') }}:{{data.EMP_LV_NAME}}, {{data.CROWN_LV_NAME}}</el-tag>
+                  <el-tag><!-- 加入期数 -->{{ $t('atlas.joiningPeriod') }}:{{data.PERIOD_AT}}</el-tag>
+                </span>
+              </span>
+            </el-tree>
+          </el-tab-pane>
+          <el-tab-pane :label="$t('atlas.placementNetworkList')" name="two" v-if="permission.hasPermission(`atlas/network-list`)"><!-- 安置网络列表 -->
+            <div class="filter-user">
+              <el-input v-model="filterForm.userName" size="small" style="width:300px;">
+                <template slot="prepend"><!-- 会员编号 -->{{ $t('atlas.memberCode') }}</template>
+              </el-input>
+              <el-input v-model="filterForm.deep" size="small" style="width:150px;">
+                <template slot="prepend"><!-- 深度 -->{{ $t('atlas.depth') }}</template>
+              </el-input>
+              <el-input v-model="filterForm.periodNum" size="small" style="width:150px;" v-show="false">
+                <template slot="prepend"><!-- 期数 -->{{ $t('atlas.numberOfPeriods') }}</template>
+              </el-input>
+              <el-button type="primary" size="small" @click="handleFilter">{{ $t('common.confirm') }}<!-- 确定 --></el-button>
+            </div>
+  
+            <el-table :data="tableData" stripe style="width: 100%;" :height="tool.getTableHeight(true)">
+              <el-table-column v-for="(tableHeader, key) in tableHeaders" :key="key" :label="tableHeader.header" :width="tableHeader.other.width ? tableHeader.other.width : ''">
+                <template slot-scope="scope">
+                  <template v-if="scope.row[tableHeader.index].other.tag" >
+                    <el-tag :type="scope.row[tableHeader.index].other.tag.type ? scope.row[tableHeader.index].other.tag.type : null" :size="scope.row[tableHeader.index].other.tag.size ? scope.row[tableHeader.index].other.tag.size : null" :class="scope.row[tableHeader.index].other.tag.class ? scope.row[tableHeader.index].other.tag.class : null" >{{scope.row[tableHeader.index].value}}</el-tag>
+                  </template>
+                  <template v-else-if="scope.row[tableHeader.index].other.progress" >
+                    <el-progress type="circle" :percentage="Number.parseInt(percentList['MOVE_PERCENT'][scope.row.ID])"
+                                 :width="50"
+                                 :stroke-width="3"></el-progress>
+                  </template>
+                  <template v-else>
+                    <template v-if="tableHeader.index === 'USER_NAME'">
+                      <el-tooltip class="item" effect="dark" :content="$t('atlas.subordinatesMember')" placement="top"><!-- 查看该会员的下级 -->
+                      <el-button @click.native="handleShow(scope.row)" size="small" type="primary">
+                        {{scope.row[tableHeader.index].value}}
+                      </el-button>
+                      </el-tooltip>
+                    </template>
+                    <template v-else>
+                    <div v-html="scope.row[tableHeader.index].value"></div>
+                    </template>
+                  </template>
+                </template>
+              </el-table-column>
+            </el-table>
+            <div class="white-box-footer">
+              <el-button type="success" size="small" @click="handleExport"
+                         v-show="permission.hasPermission(`atlas/network-list-export`)">{{ $t('common.exportExcel') }}<!-- 导出Excel -->
+              </el-button>
+              <pagination :total="totalCount" :page_size="pageSize" @size-change="handleSizeChange" @current-change="handleCurrentChange"></pagination>
+            </div>
+          </el-tab-pane>
+        </el-tabs>
+      </div>
+    </div>
+  </template>
+  
+  <script>
+  import tool from '@/utils/tool'
+  import store from '@/utils/vuexStore'
+  import permission from '@/utils/permission'
+  import Pagination from '@/components/Pagination'
+  import baseInfo from '@/utils/baseInfo'
+  import { mainUserInfo, getNetwork, networkList, networkListExport } from '@/api/atlas'
+  
+  export default {
+    name: 'atlas_network-opt',
+    components: {Pagination},
+    mounted() {
+      this.getData()
+      store.state.socket.onMessageCallback = this.onMessageCallback
+    },
+    data() {
+      return {
+        loading: true,
+        tabActiveName: 'first',
+        permission: permission,
+        //relation
+        props: {
+          label: 'USER_NAME',
+          children: 'children',
+          //isLeaf: 'leaf',
+          icon: 'icon',
+        },
+        treeData: null,
+        expandDeep: 2,
+        topDeep: 0,
+        mainUserName: '',
+        periodNum: null,
+        listPeriodNum: null,
+        allData: null,
+        tableHeaders: null,
+        tableData: null,
+        currentPage: 1,
+        totalPages: 1,
+        totalCount: 1,
+        pageSize: 20,
+        tool: tool,
+        filterForm: {
+          userName: null,
+          deep: 2,
+          periodNum: null,
+        },
+        listTopDeep: 0,
+      }
+    },
+    methods: {
+      getData() {
+        this.$message({
+          message: this.$t('atlas.getDataWait'), // 正在获取数据,请稍后
+        })
+        this.periodNum = baseInfo.nowPeriodNum()
+        this.filterForm.periodNum = baseInfo.nowPeriodNum()
+        if (permission.hasPermission(`atlas/network-list`) && !permission.hasPermission(`atlas/network`)) {
+          this.tabActiveName = 'two'
+          this.getListData()
+        }
+        if (permission.hasPermission(`atlas/network`)) {
+          this.tabActiveName = 'first'
+          if(permission.hasPermission(`atlas/network-list`)){
+            this.getMainData(null,true)
+          }else{
+            this.getMainData()
+          }
+        }
+      },
+      getMainData (userName = null, getList = false) {
+        this.$message.closeAll()
+        this.$message({
+          message: this.$t('atlas.getDataWait'),//正在获取数据,请稍后
+        })
+        let thisObj = this
+        let requestData = {
+          periodNum: this.periodNum
+        }
+        if (this.mainUserName !== null) {
+          requestData = {userName: this.mainUserName,periodNum: this.periodNum}
+        }
+
+        mainUserInfo(requestData).then(response=>{
+            thisObj.treeData = response.data
+            thisObj.topDeep = Number(response.data[0].TOP_NETWORK_DEEP)
+            thisObj.listPeriodNum = response.data[0].listPeriodNum
+            if(getList) thisObj.getListData()
+            thisObj.loading = false
+        }).catch(err => {
+            this.$message({
+                message: err,
+                type: 'error'
+            })
+            thisObj.loading = false
+        })
+      },
+      getChildData (data, node) {
+        let thisObj = this
+        let userId = data.USER_ID
+        let thisData = data
+        if (thisData.leaf) {
+          return ''
+        }
+        if (thisData.isExpanded) {
+          return ''
+        }
+        if (thisData.children !== null && thisData.children.length > 0) {
+          return ''
+        }
+        thisData.displayNone = ''
+        getNetwork({
+          id: userId,
+          deep: thisObj.expandDeep,
+          periodNum: this.periodNum
+        }).then(response => {
+            thisObj.$refs.tree.updateKeyChildren(userId, response.data.allData)
+            thisObj.listPeriodNum = response.data.periodNum
+            thisData.displayNone = 'display-none'
+            thisData.isExpanded = true
+        }).catch(err => {
+            this.$message({
+              message: err,
+              type: 'error'
+            })
+        })
+      },
+      countTopDeep(deep,topDeep){
+        return Number(deep)-Number(topDeep)
+      },
+      handleCurrentChange (page) {
+        this.getListData(page, this.pageSize)
+      },
+      handleSizeChange (pageSize) {
+        this.getListData(this.currentPage, pageSize)
+      },
+      handleFilter () {
+        this.getListData(1, this.pageSize)
+        this.tabActiveName = 'two'
+      },
+      handleShow(row) {
+        this.loading = true
+        this.filterForm.userName = row.SEE_USER_NAME
+        this.getListData(1, this.pageSize)
+        this.tabActiveName = 'two'
+      },
+      getListData (page, pageSize) {
+        let obj = this
+        let filterData = this.filterForm
+        const paramsData = Object.assign({
+            page: (page === null || page == undefined) ? 1 : page,
+            pageSize: (pageSize === null || pageSize == undefined) ? obj.pageSize : pageSize
+          }, filterData)
+        networkList(paramsData).then(response => {
+            obj.tableHeaders = response.data.columnsShow ? response.data.columnsShow : []
+            obj.tableData = response.data.list
+            obj.filterTypes = response.data.filterTypes
+            obj.allData = response.data.list
+            obj.listTopDeep = response.data.listTopDeep
+            obj.periodNum = response.data.periodNum
+            obj.currentPage = page
+            obj.totalPages = parseInt(response.data.totalPages)
+            obj.totalCount = parseInt(response.data.totalCount)
+            obj.pageSize = pageSize
+            obj.loading = false
+        }).catch(err => {
+            obj.loading = false
+            this.$message({
+              message: err,
+              type: 'error'
+            })
+        })
+      },
+      onMessageCallback(data) {
+        //this.getData(this.currentPage, this.pageSize, false)
+      },
+      handleExport(){
+        this.$confirm(this.$t('atlas.exportNotice'), this.$t('common.hint'), {//`确定要导出当前数据吗?`, '提示'
+          confirmButtonText: this.$t('common.confirm'), // 确定
+          cancelButtonText: this.$t('common.cancel'), // 取消
+          type: 'warning'
+        }).then(() => {
+            networkListExport(this.filterForm).then(response => {
+                this.$message({
+                    message: response.data,
+                    type: 'success'
+                })
+            }).catch(err => {
+                this.$message({
+                message: err,
+                type: 'error'
+                })
+            })
+        })
+      },
+      enterToGetData (ev) {
+        this.getMainData()
+      },
+    }
+  }
+  </script>
+  
+  <style>
+    .filter-user{font-size: 14px;margin-bottom: 20px;}
+    .filter-user:after{content: '';display: table;
+      clear: both;}
+    .filter-user .el-input-group{float: left;margin-right: 15px;}
+    .el-tree {
+      padding-bottom: 20px;
+      font-size: 14px;
+      overflow-x: auto;
+    }
+  
+    .el-tree .el-tag {
+      height: 20px;
+      line-height: 18px;vertical-align: middle;
+    }
+    .el-tree-node{position: relative;}
+  
+    .el-tree-node__content {
+      height: 30px;
+      line-height: 30px;
+    }
+  
+    .el-tree-node__children {
+      position: relative;
+      padding: 0 0 0 16px;
+    }
+  
+    .el-tree-node:before {
+      position: absolute;
+      content: '';
+      top: 0px;
+      left: -4px;
+      height: 100%;
+      border-left: 1px solid #ccc;
+    }
+    .el-tree-node:last-child:before{height: 15px;}
+  
+    .custom-tree-node {
+      position: relative;
+      padding-left: 5px;
+    }
+  
+    .first-node:before {
+      display: none;
+    }
+  
+    .custom-tree-node:before {
+      position: absolute;
+      width: 8px;
+      content: '';
+      top: 15px;
+      left: -4px;
+      border-bottom: 1px solid #ccc;
+    }
+  
+    .el-tree-node__expand-icon {
+      display: none !important;
+    }
+  </style>
+  

+ 349 - 0
src/views/atlas/relation-opt.vue

@@ -0,0 +1,349 @@
+<template>
+    <div v-loading="loading">
+      <div class="white-box">
+        <el-tabs v-model="tabActiveName">
+          <el-tab-pane :label="$t('atlas.sponsorNetworkDiagram')" name="first" v-if="permission.hasPermission(`atlas/relation`)"><!-- 开拓网络图 -->
+            <div class="filter-user">
+              <el-input v-model="mainUserName" size="small" style="width:300px;">
+                <template slot="prepend">{{ $t('atlas.topMember') }}<!-- 顶级会员 --></template>
+              </el-input>
+              <el-input v-model="expandDeep" size="small" style="width:200px;">
+                <template slot="prepend">{{ $t('atlas.spreadDepth') }}<!-- 展开深度 --></template>
+              </el-input>
+              <el-input v-model="periodNum" size="small" style="width:150px;" v-show="false">
+                <template slot="prepend">{{ $t('atlas.numberOfPeriods') }}<!-- 期数 --></template>
+              </el-input>
+              <el-button type="primary" size="small" @click="getMainData()">{{ $t('common.confirm') }}<!-- 确定 --></el-button>
+            </div>
+            <el-tree :props="props" :data="treeData" node-key="USER_ID" @node-click="getChildData" ref="tree" :indent="0"
+                     default-expand-all>
+                  <span :id="'node_'+data.USER_ID" :class="'custom-tree-node '+data.className"
+                        slot-scope="{ node, data }">
+                      <span :class="'el-icon-loading '+ data.displayNone"></span>
+                      <span :class="data.icon"></span>
+                      <span>
+                        <el-tag type="danger"><!-- 代数 -->{{ $t('atlas.algebra') }}:  {{countTopDeep(data.TOP_RELATION_DEEP,topDeep)}}</el-tag>
+                        <el-tag><!-- 会员编号 -->{{ $t('atlas.memberCode') }}:{{ node.label }}</el-tag>
+                        <el-tag type="success">{{ $t('atlas.name') }}<!-- 姓名 -->:{{data.REAL_NAME}}</el-tag>
+                        <el-tag type="warning">{{ $t('atlas.level') }}<!-- 级别 -->:{{data.DEC_LV_NAME}}</el-tag>
+                        <el-tag type="warning">{{ $t('atlas.highest') }}:<!-- 聘级 -->{{data.EMP_LV_NAME}}, {{data.CROWN_LV_NAME}}</el-tag>
+  <!--                      <el-tag type="warning">Star:&lt;!&ndash; 星级 &ndash;&gt;{{data.CROWN_LV_NAME}}</el-tag>-->
+                      </span>
+                  </span>
+            </el-tree>
+          </el-tab-pane>
+          <el-tab-pane :label="$t('atlas.sponsorNetworkList')" name="two" v-if="permission.hasPermission(`atlas/relation-list`)"><!-- 开拓网络列表 -->
+            <div class="filter-user">
+              <el-input v-model="filterForm.userName" size="small" style="width:300px;">
+                <template slot="prepend"><!-- 会员编号 -->{{ $t('atlas.memberCode') }}</template>
+              </el-input>
+              <el-input v-model="filterForm.deep" size="small" style="width:150px;">
+                <template slot="prepend"><!-- 深度 -->{{ $t('atlas.depth') }}</template>
+              </el-input>
+              <el-input v-model="filterForm.periodNum" size="small" style="width:150px;" v-show="false">
+                <template slot="prepend"><!-- 期数 -->{{ $t('atlas.numberOfPeriods') }}</template>
+              </el-input>
+              <el-button type="primary" size="small" @click="handleFilter">{{ $t('common.confirm') }}<!-- 确定 --></el-button>
+            </div>
+  
+            <el-table :data="tableData" stripe style="width: 100%;" :height="tool.getTableHeight(true)">
+              <!--<el-table-column type="selection" width="55" v-if="tableHeaders"></el-table-column>-->
+              <el-table-column v-for="(tableHeader, key) in tableHeaders" :key="key" :label="tableHeader.header" :width="tableHeader.other.width ? tableHeader.other.width : ''">
+                <template slot-scope="scope">
+                  <template v-if="scope.row[tableHeader.index].other.tag" >
+                    <el-tag :type="scope.row[tableHeader.index].other.tag.type ? scope.row[tableHeader.index].other.tag.type : null" :size="scope.row[tableHeader.index].other.tag.size ? scope.row[tableHeader.index].other.tag.size : null" :class="scope.row[tableHeader.index].other.tag.class ? scope.row[tableHeader.index].other.tag.class : null" >{{scope.row[tableHeader.index].value}}</el-tag>
+                  </template>
+                  <template v-else-if="scope.row[tableHeader.index].other.progress" >
+                    <el-progress type="circle" :percentage="Number.parseInt(percentList['MOVE_PERCENT'][scope.row.ID])"
+                                 :width="50"
+                                 :stroke-width="3"></el-progress>
+                  </template>
+                  <template v-else>
+                    <template v-if="tableHeader.index === 'USER_NAME'">
+                      <el-tooltip class="item" effect="dark" :content="$t('atlas.subordinatesMember')" placement="top"><!-- 查看该会员的下级 -->
+                        <el-button @click.native="handleShow(scope.row)" size="small" type="primary">
+                          {{scope.row[tableHeader.index].value}}
+                        </el-button>
+                      </el-tooltip>
+                    </template>
+                    <template v-else>
+                      <div v-html="scope.row[tableHeader.index].value"></div>
+                    </template>
+                  </template>
+                </template>
+              </el-table-column>
+            </el-table>
+            <div class="white-box-footer">
+              <el-button type="success" size="small" @click="handleExport"
+                         v-show="permission.hasPermission(`atlas/relation-list-export`)">{{ $t('common.exportExcel') }}<!-- 导出Excel -->
+              </el-button>
+              <pagination :total="totalCount" :page_size="pageSize" @size-change="handleSizeChange" @current-change="handleCurrentChange"></pagination>
+            </div>
+          </el-tab-pane>
+        </el-tabs>
+      </div>
+    </div>
+  </template>
+  
+  <script>
+    import tool from '@/utils/tool'
+    import store from '@/utils/vuexStore'
+    import permission from '@/utils/permission'
+    import Pagination from '@/components/Pagination'
+    import baseInfo from '@/utils/baseInfo'
+    import { mainUserInfo, getRelation, relationList, relationListExport } from '@/api/atlas'
+  
+    export default {
+      name: 'atlas_relation-opt',
+      components: {Pagination},
+      mounted() {
+        this.getData()
+        store.state.socket.onMessageCallback = this.onMessageCallback
+      },
+      data() {
+        return {
+          loading: true,
+          tabActiveName: 'first',
+          permission: permission,
+          //relation
+          props: {
+            label: 'USER_NAME',
+            children: 'children',
+            //isLeaf: 'leaf',
+            icon: 'icon',
+          },
+          treeData: null,
+          expandDeep: 2,
+          topDeep: 0,
+          mainUserName: '',
+          periodNum: null,
+          listPeriodNum: null,
+          allData: null,
+          tableHeaders: null,
+          tableData: null,
+          currentPage: 1,
+          totalPages: 1,
+          totalCount: 1,
+          pageSize: 20,
+          tool: tool,
+          filterForm: {
+            userName: null,
+            deep: 2,
+            periodNum: null,
+          },
+          listTopDeep: 0,
+        }
+      },
+      methods: {
+        getData() {
+          this.$message({
+            message: this.$t('atlas.getDataWait'),//正在获取数据,请稍后
+            duration: 0
+          })
+          this.periodNum = baseInfo.nowPeriodNum()
+          this.filterForm.periodNum = baseInfo.nowPeriodNum()
+          if (permission.hasPermission(`atlas/relation-list`) && !permission.hasPermission(`atlas/relation`)) {
+            this.tabActiveName = 'two'
+            this.getListData()
+          }
+          if (permission.hasPermission(`atlas/relation`)) {
+            this.tabActiveName = 'first'
+            if (permission.hasPermission(`atlas/relation-list`)) {
+              this.getMainData(null, true)
+            } else {
+              this.getMainData()
+            }
+          }
+        },
+        getMainData (userName = null, getList = false) {
+          this.$message.closeAll()
+          this.$message({
+            message: this.$t('atlas.getDataWait'),//正在获取数据,请稍后
+          })
+          let thisObj = this
+          let requestData = {
+            periodNum: this.periodNum
+          }
+          if (this.mainUserName !== null) {
+            requestData = {userName: this.mainUserName,periodNum: this.periodNum}
+          }
+          mainUserInfo(requestData).then(response=>{
+            thisObj.treeData = response.data
+            thisObj.topDeep = Number(response.data[0].TOP_RELATION_DEEP)
+            thisObj.listPeriodNum = response.data[0].listPeriodNum
+            if(getList) thisObj.getListData()
+            thisObj.loading = false
+          }).catch(err => {
+            this.$message({
+                message: err,
+                type: 'error'
+            })
+            thisObj.loading = false
+          })
+        },
+        getChildData (data, node) {
+          let thisObj = this
+          let userId = data.USER_ID
+          let thisData = data
+          if (thisData.leaf) {
+            return ''
+          }
+          if (thisData.isExpanded) {
+            return ''
+          }
+          if (thisData.children !== null && thisData.children.length > 0) {
+            return ''
+          }
+          this.$message({
+            message: this.$t('atlas.getDataWait'),//正在获取数据,请稍后
+          })
+          thisData.displayNone = ''
+          getRelation({
+            id: userId,
+            deep: thisObj.expandDeep,
+            periodNum: this.periodNum
+          }).then(response => {
+            thisObj.$refs.tree.updateKeyChildren(userId, response.data.allData)
+            thisData.listPeriodNum = response.data.periodNum
+            thisData.displayNone = 'display-none'
+            thisData.isExpanded = true
+          }).catch(err => {
+            this.$message({
+                message: err,
+                type: 'error'
+            })
+          })
+        },
+        countTopDeep(deep,topDeep){
+          return Number(deep)-Number(topDeep)
+        },
+        getListData(page, pageSize) {
+          let obj = this
+          let filterData = this.filterForm
+          const paramsData = Object.assign({
+            page: (page === null || page == undefined) ? 1 : page,
+            pageSize: (pageSize === null || pageSize == undefined) ? obj.pageSize : pageSize
+          }, filterData)
+          relationList(paramsData).then(response => {
+            obj.tableHeaders = response.data.columnsShow ? response.data.columnsShow : []
+            obj.tableData = response.data.list
+            obj.filterTypes = response.data.filterTypes
+            obj.allData = response.data.list
+            obj.listTopDeep = response.data.listTopDeep
+            obj.periodNum = response.data.periodNum
+            obj.currentPage = page
+            obj.totalPages = parseInt(response.data.totalPages)
+            obj.totalCount = parseInt(response.data.totalCount)
+            obj.pageSize = pageSize
+            obj.loading = false
+          }).catch(err => {
+            obj.loading = false
+            this.$message({
+                message: err,
+                type: 'error'
+            })
+          })
+        },
+        handleCurrentChange(page) {
+          this.getListData(page, this.pageSize)
+        },
+        handleSizeChange(pageSize) {
+          this.getListData(this.currentPage, pageSize)
+        },
+        handleFilter() {
+          this.getListData(1, this.pageSize)
+          this.tabActiveName = 'two'
+        },
+        handleShow(row) {
+          this.loading = true
+          this.filterForm.userName = row.SEE_USER_NAME
+          this.filterForm.deep = 1
+          this.getListData(1, this.pageSize)
+          this.tabActiveName = 'two'
+        },
+        onMessageCallback(data) {
+          //this.getData(this.currentPage, this.pageSize, false)
+        },
+        handleExport(){
+          this.$confirm(this.$t('atlas.exportNotice'), this.$t('common.hint'), {
+            confirmButtonText: this.$t('common.confirm'), // 确定
+            cancelButtonText: this.$t('common.cancel'), // 取消
+            type: 'warning'
+          }).then(() => {
+            relationListExport(this.filterForm).then(response => {
+                this.$message({
+                   message: response.data,
+                   type: 'success'
+                })
+            }).catch(err => {
+                this.$message({
+                   message: err,
+                   type: 'error'
+                })
+            })
+          })
+        },
+      }
+    }
+  </script>
+  
+  <style>
+    .filter-user{font-size: 14px;margin-bottom: 20px;}
+    .filter-user:after{content: '';display: table;
+      clear: both;}
+    .filter-user .el-input-group{float: left;margin-right: 15px;}
+    .el-tree {
+      padding-bottom: 20px;
+      font-size: 14px;
+      overflow-x: auto;
+    }
+  
+    .el-tree .el-tag {
+      height: 20px;
+      line-height: 18px;vertical-align: middle;
+    }
+    .el-tree-node{position: relative;}
+  
+    .el-tree-node__content {
+      height: 30px;
+      line-height: 30px;
+    }
+  
+    .el-tree-node__children {
+      position: relative;
+      padding: 0 0 0 16px;
+    }
+  
+    .el-tree-node:before {
+      position: absolute;
+      content: '';
+      top: 0px;
+      left: -4px;
+      height: 100%;
+      border-left: 1px solid #ccc;
+    }
+    .el-tree-node:last-child:before{height: 15px;}
+  
+    .custom-tree-node {
+      position: relative;
+      padding-left: 5px;
+    }
+  
+    .first-node:before {
+      display: none;
+    }
+  
+    .custom-tree-node:before {
+      position: absolute;
+      width: 8px;
+      content: '';
+      top: 15px;
+      left: -4px;
+      border-bottom: 1px solid #ccc;
+    }
+  
+    .el-tree-node__expand-icon {
+      display: none !important;
+    }
+  </style>
+  

+ 262 - 0
src/views/bonus/balance-list.vue

@@ -0,0 +1,262 @@
+<template>
+  <div v-loading="loading">
+    <div class="white-box">
+      <div class="filter-box">
+        <filter-user :filter-types="filterTypes"  :filter-btn-name="$t('common.screen')" @select-value="handleFilterUser" />
+      </div>
+      <el-table
+        ref="multipleTable"
+        class="table-box"
+        :data="tableData"
+        stripe
+        style="width: 100%;"
+        :summary-method="getSummaries"
+        show-summary
+        :height="tool.getTableHeight()"
+        @selection-change="handleSelectionChange"
+      >
+        <el-table-column v-if="tableHeaders" type="selection" width="70" />
+        <el-table-column v-for="(tableHeader, key) in tableHeaders" :key="key" :label="tableHeader.header" :width="tableHeader.other.width ? tableHeader.other.width : ''" :prop="tableHeader.other.prop ? tableHeader.other.prop : null">
+          <template slot-scope="scope">
+            <template v-if="scope.row[tableHeader.index].other.tag">
+              <el-tag :type="scope.row[tableHeader.index].other.tag.type ? scope.row[tableHeader.index].other.tag.type : null" :size="scope.row[tableHeader.index].other.tag.size ? scope.row[tableHeader.index].other.tag.size : null" :class="scope.row[tableHeader.index].other.tag.class ? scope.row[tableHeader.index].other.tag.class : null">{{ scope.row[tableHeader.index].value }}</el-tag>
+            </template>
+            <template v-else>
+              <div v-html="scope.row[tableHeader.index].value" />
+            </template>
+          </template>
+        </el-table-column>
+
+      </el-table>
+      <div class="white-box-footer">
+        <!--<el-button type="primary" size="small" @click="handleSendShow" icon="el-icon-plus"-->
+        <!--v-show="permission.hasPermission(`bonus/cf-lx-apply`)">年度奖申请发放-->
+        <!--</el-button>-->
+        <el-button v-show="permission.hasPermission(`bonus/balance-export`)" type="success" size="small" @click="handleExport"><!-- 导出Excel -->{{$t('common.exportExcel')}}</el-button>
+        <pagination
+          :total="totalCount"
+          :page_size="pageSize"
+          @size-change="handleSizeChange"
+          @current-change="handleCurrentChange"
+        />
+      </div>
+    </div>
+    <!--<el-dialog v-loading="dialogLoading" title="Annual award distribution" :visible.sync="dialogVisible"><!-- 年度奖发放
+      <el-form :model="form" label-width="250px" class="form-dialog">
+        <el-form-item label="Distribution type"><!-- 发放类型
+          <el-select v-model="form.sendType" placeholder="Please select the distribution type"><!-- 请选择发放类型
+            <el-option
+              v-for="(item,index) in applyTypes"
+              :key="index"
+              :label="item.NAME"
+              :value="item.ID"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="Include member status"><!-- 包含会员状态
+          <el-select v-model="form.statusValue" placeholder="Please select a status" multiple><!-- 请选择状态
+            <el-option v-for="(item,key) in statuses" :key="key" :label="item.label" :value="item.value" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="Remark"><!-- 备注
+          <el-input v-model="form.remark" type="textarea" :row="2" placeholder="Please enter the content"><!-- 请输入内容 </el-input>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisible = false"><!-- 取消 cancel</el-button>
+        <el-button type="primary" @click.native="handleSend"><!-- 发放 grant</el-button>
+      </div>
+    </el-dialog>
+    </el-dialog> -->
+  </div>
+</template>
+
+<script>
+import { fetchGetUserStatus, fetchBalanceList, fetchBalanceExport } from '@/api/bonus'
+import tool from '@/utils/tool'
+import baseInfo from '@/utils/baseInfo'
+import FilterUser from '@/components/FilterUser'
+import permission from '@/utils/permission'
+import Pagination from '@/components/Pagination'
+import filterHelper from '@/utils/filterHelper'
+import ElementUI from 'element-ui'
+
+export default {
+  name: 'BonusBalanceList',
+  components: { FilterUser, Pagination },
+  data() {
+    return {
+      tableHeaders: null,
+      tableData: null,
+      tableHeight: window.innerHeight - 310,
+      loading: true,
+      multipleSelection: [],
+      currentPage: 1,
+      totalPages: 1,
+      totalCount: 1,
+      pageSize: 20,
+      tool: tool,
+      permission: permission,
+      baseDecLevels: baseInfo.decLevels(),
+      baseEmpLevels: baseInfo.empLevels(),
+      filterTypes: null,
+      filterModel: {},
+      dialogVisible: false,
+      dialogLoading: false,
+      statuses: null,
+      applyTypes: [
+        { 'ID': 'all', 'NAME': 'All' }, // 全部
+        { 'ID': 'cf', 'NAME': 'Garage endowment' }, // 车房养老
+        { 'ID': 'lx', 'NAME': 'Leader bonus' }// 领袖分红
+      ],
+      form: {
+        selectedIds: [],
+        statusValue: [],
+        sendType: null,
+        remark: null
+      }
+    }
+  },
+  mounted() {
+    fetchGetUserStatus().then(response => {
+      this.statuses = response.data.statuses
+      return this.getData()
+      // Just to simulate the time of the request
+    })
+  },
+  methods: {
+    handleSelectionChange(val) {
+      this.multipleSelection = val
+    },
+    handleCurrentChange(page) {
+      this.getData(page, this.pageSize)
+    },
+    handleSizeChange(pageSize) {
+      this.getData(this.currentPage, pageSize)
+    },
+    handleFilterUser(filterData) {
+      filterHelper.handleFilterUser(this, filterData)
+    },
+    getData(page, pageSize) {
+      const filterData = this.filterModel
+      this.loading = true
+      const paramsData = Object.assign({
+        page: (page === null || page === undefined) ? 1 : page,
+        pageSize: (pageSize === null || pageSize === undefined) ? this.pageSize : pageSize
+      }, filterData)
+      fetchBalanceList(paramsData).then(response => {
+        console.log(response)
+        this.filterTypes = response.data.filterTypes
+        this.tableData = response.data.list
+        this.tableHeaders = response.data.columnsShow ? response.data.columnsShow : []
+        this.loading = false
+        this.currentPage = page
+        this.totalPages = parseInt(response.data.totalPages)
+        this.totalCount = parseInt(response.data.totalCount)
+        this.pageSize = pageSize
+        this.sumData = response.data.sumData
+        this.loading = false
+      })
+    },
+    // handleSendShow() {
+    //   if (this.multipleSelection.length < 1) {
+    //     this.$message({
+    //       message: 'Please check the member to apply for distribution', // 请勾选要申请发放的会员
+    //       type: 'warning'
+    //     })
+    //     return false
+    //   }
+    //   this.dialogVisible = true
+    // },
+    // handleSend() {
+    //   this.dialogLoading = true
+    //   this.$message({
+    //     message: 'Applying for distribution, please wait', // 正在申请发放请稍后
+    //     type: 'info'
+    //   })
+    //   for (const val of this.multipleSelection) {
+    //     this.form.selectedIds.push(val.USER_ID)
+    //   }
+    //   network.postData(`bonus/cf-lx-apply`,
+    //     this.form
+    //   ).then(response => {
+    //     this.$message({
+    //       message: response,
+    //       type: 'success'
+    //     })
+    //     this.dialogVisible = false
+    //     this.dialogLoading = false
+    //     this.form = {
+    //       selectedIds: [],
+    //       year: null,
+    //       sendType: null,
+    //       remark: null
+    //     }
+    //     this.getData()
+    //   }).catch(response => {
+    //     this.dialogLoading = false
+    //   })
+    // },
+    getSummaries(param) {
+      const { columns, data } = param
+      const sums = []
+      if (columns && data && columns.length > 0 && data.length > 0) {
+        columns.forEach((column, index) => {
+          if (index === 0) {
+            sums[index] = 'sub-total' + '\n' + 'Total' // '小计' + "\n" + '合计'
+            return
+          }
+          const values = data.map(item => {
+            if (typeof item[column.property] === 'object') {
+              return Number(item[column.property].value)
+            } else {
+              return Number(undefined)
+            }
+          })
+          if (!values.every(value => isNaN(value))) {
+            sums[index] = values.reduce((prev, curr) => {
+              const value = Number(curr)
+              if (!isNaN(value)) {
+                return prev + curr
+              } else {
+                return prev
+              }
+            }, 0)
+            const field = 'SUM_' + column.property
+            if (typeof this.sumData[field] !== 'undefined') {
+              sums[index] = tool.formatPrice(sums[index]) + '\n' + tool.formatPrice(this.sumData[field])
+            } else {
+              sums[index] = tool.formatPrice(sums[index])
+            }
+          } else {
+            sums[index] = '-'
+          }
+        })
+      }
+      return sums
+    },
+    handleExport() {
+     this.$confirm(this.$t('common.exportCurrentData'), this.$t('common.notice'), {  // `确定要导出当前数据吗?`, '提示',
+     confirmButtonText: this.$t('common.confirm'), // 确定
+     cancelButtonText: this.$t('common.cancel'), // 取消
+        type: 'warning'
+      }).then(() => {
+        return fetchBalanceExport(this.filterModel)
+      }).then(response => {
+        this.$message({
+          message: response.data,
+          type: 'success'
+        })
+     }).catch((error) => {
+         if(error !== 'cancel'){
+             ElementUI.Message({type: 'error', message: error.message, showClose: true, duration: 0})
+         }
+     })
+    }
+  }
+}
+
+</script>
+
+<style scoped>
+</style>

+ 123 - 0
src/views/bonus/flow-bonus.vue

@@ -0,0 +1,123 @@
+<template>
+  <div v-loading="loading">
+    <div class="white-box">
+      <div class="filter-box">
+        <filter-user :filter-types="filterTypes" :filter-btn-name="$t('common.screen')" @select-value="handleFilterUser" />
+      </div>
+      <el-table ref="multipleTable" class="table-box" :data="tableData" stripe style="width: 100%;" :height="tool.getTableHeight()">
+        <el-table-column v-for="(tableHeader, key) in tableHeaders" :key="key" :label="tableHeader.header" :width="tableHeader.other.width ? tableHeader.other.width : ''" :prop="tableHeader.other.prop ? tableHeader.other.prop : null">
+          <template slot-scope="scope">
+            <template v-if="scope.row[tableHeader.index].other.tag">
+              <el-tag :type="scope.row[tableHeader.index].other.tag.type ? scope.row[tableHeader.index].other.tag.type : null" :size="scope.row[tableHeader.index].other.tag.size ? scope.row[tableHeader.index].other.tag.size : null" :class="scope.row[tableHeader.index].other.tag.class ? scope.row[tableHeader.index].other.tag.class : null">{{ scope.row[tableHeader.index].value }}</el-tag>
+            </template>
+            <template v-else>
+              <div v-html="scope.row[tableHeader.index].value" />
+            </template>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="white-box-footer">
+        <el-button v-show="permission.hasPermission(`bonus/flow-bonus-export`)" type="success" size="small" @click="handleExport">{{$t('common.exportExcel')}}<!-- 导出Excel --></el-button>
+        <pagination :total="totalCount" :page_size="pageSize" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { fetchFlowBonus, fetchFlowBonusExport } from '@/api/bonus'
+import tool from '@/utils/tool'
+import baseInfo from '@/utils/baseInfo'
+import FilterUser from '../../components/FilterUser'
+import permission from '@/utils/permission'
+import Pagination from '@/components/Pagination'
+import filterHelper from '@/utils/filterHelper'
+import ElementUI from 'element-ui'
+
+export default {
+  name: 'BonusFlowBonus',
+  components: { FilterUser, Pagination },
+  data() {
+    return {
+      tableHeaders: null,
+      tableData: null,
+      loading: true,
+      multipleSelection: [],
+      currentPage: 1,
+      totalPages: 1,
+      totalCount: 1,
+      pageSize: 20,
+      tool: tool,
+      permission: permission,
+      baseDecLevels: baseInfo.decLevels(),
+      baseEmpLevels: baseInfo.empLevels(),
+      filterTypes: null,
+      filterModel: {}
+    }
+  },
+  mounted() {
+    this.getData()
+  },
+  methods: {
+    handleCurrentChange(page) {
+      this.getData(page, this.pageSize)
+    },
+    handleSizeChange(pageSize) {
+      this.getData(this.currentPage, pageSize)
+    },
+    handleFilterUser(filterData) {
+      filterHelper.handleFilterUser(this, filterData)
+    },
+    getData(page, pageSize) {
+      const filterData = this.filterModel
+      this.loading = true
+      const paramsData = Object.assign({
+        page: (page === null || page === undefined) ? 1 : page,
+        pageSize: (pageSize === null || pageSize === undefined) ? this.pageSize : pageSize
+      }, filterData)
+      fetchFlowBonus(paramsData).then(response => {
+        this.filterTypes = response.data.filterTypes
+        this.tableData = response.data.list
+        this.tableHeaders = response.data.columnsShow ? response.data.columnsShow : []
+        this.loading = false
+        this.currentPage = page
+        this.totalPages = parseInt(response.data.totalPages)
+        this.totalCount = parseInt(response.data.totalCount)
+        this.pageSize = pageSize
+        // vueObj.sumData = response.sumData
+      })
+    },
+    handleExport() {
+    this.$confirm(this.$t('common.exportCurrentData'), this.$t('common.notice'), {  // `确定要导出当前数据吗?`, '提示',
+        confirmButtonText: this.$t('common.confirm'), // 确定
+        cancelButtonText: this.$t('common.cancel'), // 取消
+      }).then(() => {
+        return fetchFlowBonusExport(this.filterModel)
+      }).then(response => {
+        this.$message({
+          message: response.data,
+          type: 'success'
+        })
+     }).catch((error) => {
+         if(error !== 'cancel'){
+             ElementUI.Message({type: 'error', message: error.message, showClose: true, duration: 0})
+         }
+     })
+    }
+  }
+}
+
+</script>
+
+<style scoped>
+  .table-box .el-form-item__label {
+    width: 100px;
+    color: #99a9bf;
+  }
+
+  .table-box .el-form-item {
+    width: 30%;
+    margin-right: 0;
+    margin-bottom: 0;
+  }
+</style>

+ 178 - 0
src/views/bonus/other-period-bonus.vue

@@ -0,0 +1,178 @@
+<template>
+  <div v-loading="loading">
+    <div class="white-box">
+      <div class="filter-box">
+        <filter-user :filter-types.sync="filterTypes" :filter-btn-name="$t('common.screen')" @select-value="handleFilterUser" />
+      </div>
+      <el-table ref="multipleTable" class="table-box" :data="tableData" stripe style="width: 100%;" :height="tool.getTableHeight()">
+        <el-table-column v-for="(tableHeader, key) in tableHeaders" :key="key" :label="tableHeader.header" :width="tableHeader.other.width ? tableHeader.other.width : ''" :prop="tableHeader.other.prop ? tableHeader.other.prop : null">
+          <template slot-scope="scope">
+            <template v-if="scope.row[tableHeader.index].other.tag">
+              <el-tag :type="scope.row[tableHeader.index].other.tag.type ? scope.row[tableHeader.index].other.tag.type : null" :size="scope.row[tableHeader.index].other.tag.size ? scope.row[tableHeader.index].other.tag.size : null" :class="scope.row[tableHeader.index].other.tag.class ? scope.row[tableHeader.index].other.tag.class : null">{{ scope.row[tableHeader.index].value }}</el-tag>
+            </template>
+            <template v-else>
+              <div v-html="scope.row[tableHeader.index].value" />
+            </template>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="white-box-footer">
+        <el-button v-show="permission.hasPermission(`bonus/new-period-bonus-export`)" type="success" size="small" @click="handleExport">{{$t('common.exportExcel')}}<!-- 导出Excel --></el-button>
+        <pagination :total="totalCount" :page_size="pageSize" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { fetchOtherPeriodBonusFilterTypes, fetchOtherPeriodBonus, fetchOtherPeriodBonusExport } from '@/api/bonus'
+import tool from '@/utils/tool'
+import FilterUser from '@/components/FilterUser'
+import permission from '@/utils/permission'
+import baseInfo from '@/utils/baseInfo'
+import Pagination from '@/components/Pagination'
+import filterHelper from '../../utils/filterHelper'
+import ElementUI from 'element-ui'
+
+export default {
+  name: 'BonusOtherPeriodBonus',
+  components: { FilterUser, Pagination },
+  data() {
+    return {
+      tableHeaders: null,
+      tableData: null,
+      sumData: {
+        'SUM_PV_1L': null
+      },
+      loading: true,
+      multipleSelection: [],
+      currentPage: 1,
+      totalPages: 1,
+      totalCount: 1,
+      pageSize: 20,
+      tool: tool,
+      permission: permission,
+      filterTypes: null,
+      filterModel: {},
+      baseDecLevels: baseInfo.decLevels(),
+      baseEmpLevels: baseInfo.empLevels()
+    }
+  },
+  mounted() {
+    this.loading = false
+    this.getData()
+  },
+  methods: {
+    handleCurrentChange(page) {
+      this.getData(page, this.pageSize)
+    },
+    handleSizeChange(pageSize) {
+      this.getData(this.currentPage, pageSize)
+    },
+    handleFilterUser(filterData) {
+      filterHelper.handleFilterUser(this, filterData)
+    },
+    handleFilter() {
+      this.getData()
+    },
+    getFilterTypes() {
+      fetchOtherPeriodBonusFilterTypes.then(response => {
+        this.filterTypes = response.data
+        // 如果地址栏不为空则执行getData()
+        // if(window.location.href.match(/filter=/) !== null){
+        this.getData()
+        // }
+      })
+    },
+    getData(page, pageSize) {
+      const filterData = this.filterModel
+      this.loading = true
+      const paramsData = Object.assign({
+        page: (page === null || page === undefined) ? 1 : page,
+        pageSize: (pageSize === null || pageSize === undefined) ? this.pageSize : pageSize
+      }, filterData)
+      fetchOtherPeriodBonus(paramsData).then(response => {
+        this.filterTypes = response.data.filterTypes
+        this.tableData = response.data.list
+        this.tableHeaders = response.data.columnsShow ? response.data.columnsShow : []
+        this.loading = false
+        this.currentPage = page
+        this.totalPages = parseInt(response.data.totalPages)
+        this.totalCount = parseInt(response.data.totalCount)
+        this.pageSize = pageSize
+        this.loading = false
+        // vueObj.sumData = response.sumData
+      })
+    },
+    getSummaries(param) {
+      const { columns, data } = param
+      const sums = []
+      if (columns && data && columns.length > 0 && data.length > 0) {
+        columns.forEach((column, index) => {
+          if (index === 0) {
+            sums[index] = 'sub-total' + '\n' + 'Total' // '小计' + "\n" + '合计'
+            return
+          }
+          const values = data.map(item => {
+            if (typeof item[column.property] === 'object') {
+              return Number(item[column.property].value)
+            } else {
+              return Number(undefined)
+            }
+          })
+          if (!values.every(value => isNaN(value))) {
+            sums[index] = values.reduce((prev, curr) => {
+              const value = Number(curr)
+              if (!isNaN(value)) {
+                return prev + curr
+              } else {
+                return prev
+              }
+            }, 0)
+            const field = 'SUM_' + column.property
+            if (typeof this.sumData[field] !== 'undefined') {
+              sums[index] = tool.formatPrice(sums[index]) + '\n' + tool.formatPrice(this.sumData[field])
+            } else {
+              sums[index] = tool.formatPrice(sums[index])
+            }
+          } else {
+            sums[index] = '-'
+          }
+        })
+      }
+      return sums
+    },
+    handleExport() {
+    this.$confirm(this.$t('common.exportCurrentData'), this.$t('common.notice'), {  // `确定要导出当前数据吗?`, '提示',
+        confirmButtonText: this.$t('common.confirm'), // 确定
+        cancelButtonText: this.$t('common.cancel'), // 取消
+      }).then(() => {
+        return fetchOtherPeriodBonusExport(this.filterModel)
+      }).then(response => {
+        this.$message({
+          message: response.data,
+          type: 'success'
+        })
+    }).catch((error) => {
+        if(error !== 'cancel'){
+            ElementUI.Message({type: 'error', message: error.message, showClose: true, duration: 0})
+        }
+    })
+    }
+  }
+}
+
+</script>
+
+<style scoped>
+  .table-box .el-form-item__label {
+    width: 100px;
+    color: #99a9bf;
+  }
+
+  .table-box .el-form-item {
+    width: 30%;
+    margin-right: 0;
+    margin-bottom: 0;
+  }
+</style>

+ 150 - 0
src/views/bonus/perf-adjustment.vue

@@ -0,0 +1,150 @@
+<template>
+  <div v-loading="loading">
+    <div class="white-box">
+      <div class="filter-user" @keyup.enter="getData()">
+        <el-input v-model="memberCode" size="small" style="width:400px;">
+          <template slot="prepend">{{$t('bonus.memberCode')}}</template>
+        </el-input>
+        <el-button type="primary" icon="el-icon-search" size="small" @click="getData()">{{$t('common.confirm')}}<!-- 确定 --></el-button>
+      </div>
+
+      <div v-show="show" style="margin-top: 25px;">
+        <el-row>
+          <el-col :span="16">
+            <div class="grid-content bg-purple" style="width: 100%">
+              <el-card class="box-card" shadow="hover">
+                <el-form ref="perfForm" :model="perfForm" status-icon label-width="250px" width="100%" class="demo-ruleForm">
+                  <el-form-item v-show="false" label="Member Code" prop="USER_NAME">
+                    <el-input v-model="perfForm.USER_ID" type="text" size="small" />
+                    <el-input v-model="perfForm.USER_NAME" type="text" size="small" />
+                  </el-form-item>
+
+                  <el-divider><span style="font-weight: bold;">{{$t('bonus.LMarketBalancePerformance')}}</span></el-divider>
+                  <el-form-item :label="$t('bonus.memberCode')" prop="SURPLUS_1L_USER_NAME"><!--会员编号-->
+                    <el-input v-model="perfForm.SURPLUS_1L_USER_NAME" type="text" size="small" autocomplete="off" readonly />
+                  </el-form-item>
+                  <el-form-item :label="$t('bonus.balancePerformance')" prop="SURPLUS_1L"><!--综合结余业绩-->
+                    <el-input v-model="perfForm.SURPLUS_1L" type="text" size="small" autocomplete="off" />
+                  </el-form-item>
+                  <el-form-item :label="$t('bonus.entryBalancePerformance')" prop="SURPLUS_1L_ZC"><!--首单结余业绩-->
+                    <el-input v-model="perfForm.SURPLUS_1L_ZC" type="text" size="small" autocomplete="off" />
+                  </el-form-item>
+                  <el-form-item :label="$t('bonus.reconditioningBalancePerformance')" prop="SURPLUS_1L_FX"><!--复消结余业绩-->
+                    <el-input v-model="perfForm.SURPLUS_1L_FX" type="text" size="small" autocomplete="off" />
+                  </el-form-item>
+
+                  <el-divider><span style="font-weight: bold;">{{$t('bonus.RMarketBalancePerformance')}}</span></el-divider>
+                  <el-form-item :label="$t('bonus.memberCode')" prop="SURPLUS_2L_USER_NAME"><!--会员编号-->
+                    <el-input v-model="perfForm.SURPLUS_2L_USER_NAME" type="text" size="small" autocomplete="off" readonly />
+                  </el-form-item>
+                  <el-form-item :label="$t('bonus.balancePerformance')" prop="SURPLUS_2L"><!--综合结余业绩-->
+                    <el-input v-model="perfForm.SURPLUS_2L" type="text" size="small" autocomplete="off" />
+                  </el-form-item>
+                  <el-form-item :label="$t('bonus.entryBalancePerformance')" prop="SURPLUS_2L_ZC">
+                    <el-input v-model="perfForm.SURPLUS_2L_ZC" type="text" size="small" autocomplete="off" />
+                  </el-form-item>
+                  <el-form-item :label="$t('bonus.reconditioningBalancePerformance')" prop="SURPLUS_2L_FX"><!--复消结余业绩-->
+                    <el-input v-model="perfForm.SURPLUS_2L_FX" type="text" size="small" autocomplete="off" />
+                  </el-form-item>
+
+                  <el-form-item>
+                    <el-button type="primary" size="small" @click="handlePerfAdjustment('perfForm')">{{$t('common.save')}}</el-button>
+                  </el-form-item>
+                </el-form>
+              </el-card>
+            </div>
+          </el-col>
+        </el-row>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+
+import { fetchPerfAdjustment, fetchPerfAdjustmentPost } from '@/api/bonus'
+
+export default {
+  name: 'BonusPerfAdjustment',
+  data() {
+    return {
+      loading: false,
+      memberCode: '',
+      show: false,
+      perfForm: {
+        USER_ID: '',
+        USER_NAME: '',
+        SURPLUS_1L: '',
+        SURPLUS_1L_ZC: '',
+        SURPLUS_1L_FX: '',
+        SURPLUS_21L_USER_NAME: '',
+        SURPLUS_2L: '',
+        SURPLUS_2L_ZC: '',
+        SURPLUS_2L_FX: '',
+        SURPLUS_2L_USER_NAME: ''
+      }
+    }
+  },
+  methods: {
+    // 查询安置网的下级会员和业绩
+    getData() {
+      if (!this.memberCode.length) {
+        this.$message({
+          message: 'Please enter member code',
+          type: 'info'
+        })
+        return false
+      }
+
+      // 清除上一次的填充结果
+      this.$refs['perfForm'].resetFields()
+      this.show = false
+
+      fetchPerfAdjustment({ memberCode: this.memberCode }).then(response => {
+        this.perfForm = response.data.allData
+        this.show = true
+        this.loading = false
+        // vueObj.sumData = response.sumData
+      }).catch(error => {
+        this.$message({
+          message: error,
+          type: 'warning'
+        })
+
+        this.loading = false
+      })
+    },
+    // 修改会员业绩
+    handlePerfAdjustment(formName) {
+      this.$confirm(this.$t('bonus.confirmAndReviseMemberPerformance'), this.$t('common.hint'), { // 确认修改会员业绩
+        confirmButtonText: this.$t('common.confirm'), // 确定
+        cancelButtonText: this.$t('common.cancel'), // 取消
+        type: 'warning'
+      }).then(() => {
+        this.loading = true
+        return fetchPerfAdjustmentPost(this.perfForm).then(response => {
+          this.$message({
+            message: response.data,
+            type: 'success'
+          })
+          this.loading = false
+
+          // 刷新数据
+          this.getData()
+        }).catch(error => {
+          this.$message({
+            message: error,
+            type: 'warning'
+          })
+          this.loading = false
+        })
+      })
+    }
+  }
+}
+</script>
+
+<style>
+  .filter-user { font-size: 14px; margin-bottom: 20px; }
+  .filter-user:after { content: ''; display: table;  clear: both; }
+</style>

+ 143 - 0
src/views/bonus/perf-month.vue

@@ -0,0 +1,143 @@
+<template>
+  <div v-loading="loading">
+    <div class="white-box">
+      <div class="filter-box">
+        <filter-user ref="filterUser" :filter-btn-name="$t('common.screen')" :filter-types="filterTypes" @select-value="handleFilterUser" />
+      </div>
+      <el-table
+        :data="tableData"
+        stripe
+        style="width: 100%;"
+        :height="tool.getTableHeight(true)"
+        @selection-change="handleSelectionChange"
+      >
+        <el-table-column v-if="tableHeaders" type="selection" width="55" />
+        <el-table-column v-for="(tableHeader, key) in tableHeaders" :key="key" :label="tableHeader.header" :width="tableHeader.other.width ? tableHeader.other.width : ''" :prop="tableHeader.other.prop ? tableHeader.other.prop : null">
+          <template slot-scope="scope">
+            <template v-if="scope.row[tableHeader.index].other.tag">
+              <el-tag :type="scope.row[tableHeader.index].other.tag.type ? scope.row[tableHeader.index].other.tag.type : null" :size="scope.row[tableHeader.index].other.tag.size ? scope.row[tableHeader.index].other.tag.size : null" :class="scope.row[tableHeader.index].other.tag.class ? scope.row[tableHeader.index].other.tag.class : null">{{ scope.row[tableHeader.index].value }}</el-tag>
+            </template>
+            <template v-else>
+              <div v-html="scope.row[tableHeader.index].value" />
+            </template>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="white-box-footer">
+        <el-button v-show="permission.hasPermission(`bonus/perf-month-export`)" type="success" size="small" @click="handleExport">{{$t('common.exportExcel')}}<!-- 导出Excel --></el-button>
+        <pagination :total="totalCount" :page_size="pageSize" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { fetchPerfMonth, fetchPerfMonthExport } from '@/api/bonus'
+import tool from '@/utils/tool'
+import baseInfo from '@/utils/baseInfo'
+import FilterUser from '@/components/FilterUser'
+import permission from '@/utils/permission'
+import Pagination from '@/components/Pagination'
+import filterHelper from '@/utils/filterHelper'
+import ElementUI from 'element-ui'
+
+export default {
+  name: 'LeoPerfMonthTable',
+  components: { FilterUser, Pagination },
+  data() {
+    return {
+      tableHeaders: null,
+      tableData: null,
+      loading: true,
+      multipleSelection: [],
+      currentPage: 1,
+      totalPages: 1,
+      totalCount: 1,
+      pageSize: 20,
+      tool: tool,
+      permission: permission,
+      baseDecLevels: baseInfo.decLevels(),
+      baseEmpLevels: baseInfo.empLevels(),
+      filterTypes: null,
+      filterModel: {},
+      filterStatus: 'ALL'
+    }
+  },
+  mounted() {
+    this.getData()
+  },
+  methods: {
+    handleSelectionChange(val) {
+      this.multipleSelection = val
+    },
+    handleCurrentChange(page) {
+      this.getData(page, this.pageSize)
+    },
+    handleSizeChange(pageSize) {
+      this.getData(this.currentPage, pageSize)
+    },
+
+    handleFilterUser(filterData) {
+      filterHelper.handleFilterUser(this, filterData)
+    },
+    getData(page, pageSize) {
+      const filterData = this.filterModel
+      if (window.location.href.indexOf('filter') === -1) {
+        filterData.filterType = this.filterStatus !== 'ALL' ? `=,${this.filterStatus}` : ''
+      }
+
+      this.loading = true
+      const paramsData = Object.assign({
+        page: (page === null || page === undefined) ? 1 : page,
+        pageSize: (pageSize === null || pageSize === undefined) ? this.pageSize : pageSize
+      }, filterData)
+      fetchPerfMonth(paramsData).then(response => {
+        this.filterTypes = response.data.filterTypes
+        this.tableData = response.data.list
+        this.tableHeaders = response.data.columnsShow ? response.data.columnsShow : []
+        this.loading = false
+        this.currentPage = page
+        this.totalPages = parseInt(response.data.totalPages)
+        this.totalCount = parseInt(response.data.totalCount)
+        this.pageSize = pageSize
+        // vueObj.sumData = response.sumData
+      })
+    },
+    handleExport() {
+      const filterData = this.filterModel
+      if (window.location.href.indexOf('filter') === -1) {
+        filterData.filterType = this.filterStatus !== 'ALL' ? `=,${this.filterStatus}` : ''
+      }
+     this.$confirm(this.$t('common.exportCurrentData'), this.$t('common.notice'), { // '确定要导出当前表格中的数据吗?', '提示',
+       confirmButtonText: this.$t('common.confirm'), // 确定
+       cancelButtonText: this.$t('common.cancel'), // 取消
+        type: 'warning'
+      }).then(() => {
+        return fetchPerfMonthExport(this.filterModel)
+      }).then(response => {
+        this.$message({
+          message: response.data,
+          type: 'success'
+        })
+    }).catch((error) => {
+        if(error !== 'cancel'){
+            ElementUI.Message({type: 'error', message: error.message, showClose: true, duration: 0})
+        }
+    })
+    }
+  }
+}
+</script>
+
+<style>
+  .leo-withdrawTable .el-form-item__label {
+    width: 100px;
+    color: #99a9bf;
+  }
+
+  .leo-withdrawTable .el-form-item {
+    width: 40%;
+    margin-right: 0;
+    margin-bottom: 0;
+  }
+</style>

+ 150 - 0
src/views/bonus/perf-order.vue

@@ -0,0 +1,150 @@
+<template>
+  <div v-loading="loading">
+    <div class="white-box">
+      <el-tabs v-model="filterStatus" @tab-click="handleFilterStatusClick">
+        <el-tab-pane :label="$t('common.all')" name="ALL" :lazy="true" /><!-- 全部 -->
+        <el-tab-pane :label="$t('bonus.welcomePackOrder')" name="ZC" :lazy="true" /><!-- 首购单 -->
+      </el-tabs>
+      <div class="filter-box">
+        <filter-user ref="filterUser" :filter-btn-name="$t('common.screen')" :filter-types="filterTypes" @select-value="handleFilterUser" />
+      </div>
+      <el-table
+        :data="tableData"
+        stripe
+        style="width: 100%;"
+        :height="tool.getTableHeight(true)"
+        @selection-change="handleSelectionChange"
+      >
+        <el-table-column v-if="tableHeaders" type="selection" width="55" />
+        <el-table-column v-for="(tableHeader, key) in tableHeaders" :key="key" :label="tableHeader.header" :width="tableHeader.other.width ? tableHeader.other.width : ''" :prop="tableHeader.other.prop ? tableHeader.other.prop : null">
+          <template slot-scope="scope">
+            <template v-if="scope.row[tableHeader.index].other.tag">
+              <el-tag :type="scope.row[tableHeader.index].other.tag.type ? scope.row[tableHeader.index].other.tag.type : null" :size="scope.row[tableHeader.index].other.tag.size ? scope.row[tableHeader.index].other.tag.size : null" :class="scope.row[tableHeader.index].other.tag.class ? scope.row[tableHeader.index].other.tag.class : null">{{ scope.row[tableHeader.index].value }}</el-tag>
+            </template>
+            <template v-else>
+              <div v-html="scope.row[tableHeader.index].value" />
+            </template>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="white-box-footer">
+        <el-button v-show="permission.hasPermission(`bonus/perf-order-export`)" type="success" size="small" @click="handleExport">{{$t('common.exportExcel')}}<!-- 导出Excel --></el-button>
+        <pagination :total="totalCount" :page_size="pageSize" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { fetchPerfOrder, fetchPerfOrderExport } from '@/api/bonus'
+import tool from '@/utils/tool'
+import baseInfo from '@/utils/baseInfo'
+import FilterUser from '@/components/FilterUser'
+import permission from '@/utils/permission'
+import Pagination from '@/components/Pagination'
+import filterHelper from '@/utils/filterHelper'
+import ElementUI from 'element-ui'
+
+export default {
+  name: 'LeoPerfOrderTable',
+  components: { FilterUser, Pagination },
+  data() {
+    return {
+      tableHeaders: null,
+      tableData: null,
+      loading: true,
+      multipleSelection: [],
+      currentPage: 1,
+      totalPages: 1,
+      totalCount: 1,
+      pageSize: 20,
+      tool: tool,
+      permission: permission,
+      baseDecLevels: baseInfo.decLevels(),
+      baseEmpLevels: baseInfo.empLevels(),
+      filterTypes: null,
+      filterModel: {},
+      filterStatus: 'ALL'
+    }
+  },
+  mounted() {
+    this.getData()
+  },
+  methods: {
+    handleSelectionChange(val) {
+      this.multipleSelection = val
+    },
+    handleCurrentChange(page) {
+      this.getData(page, this.pageSize)
+    },
+    handleSizeChange(pageSize) {
+      this.getData(this.currentPage, pageSize)
+    },
+    handleFilterStatusClick(tab, event) {
+      filterHelper.clearFilterOption(this)
+      this.getData()
+    },
+    handleFilterUser(filterData) {
+      filterHelper.handleFilterUser(this, filterData)
+    },
+    getData(page, pageSize) {
+      const filterData = this.filterModel
+      if (window.location.href.indexOf('filter') === -1) {
+        filterData.filterType = this.filterStatus !== 'ALL' ? `=,${this.filterStatus}` : ''
+      }
+
+      this.loading = true
+      const paramsData = Object.assign({
+        page: (page === null || page === undefined) ? 1 : page,
+        pageSize: (pageSize === null || pageSize === undefined) ? this.pageSize : pageSize
+      }, filterData)
+      fetchPerfOrder(paramsData).then(response => {
+        this.filterTypes = response.data.filterTypes
+        this.tableData = response.data.list
+        this.tableHeaders = response.data.columnsShow ? response.data.columnsShow : []
+        this.loading = false
+        this.currentPage = page
+        this.totalPages = parseInt(response.data.totalPages)
+        this.totalCount = parseInt(response.data.totalCount)
+        this.pageSize = pageSize
+        // vueObj.sumData = response.sumData
+      })
+    },
+    handleExport() {
+      const filterData = this.filterModel
+      if (window.location.href.indexOf('filter') === -1) {
+        filterData.filterType = this.filterStatus !== 'ALL' ? `=,${this.filterStatus}` : ''
+      }
+      this.$confirm(this.$t('common.exportCurrentData'), this.$t('common.notice'), { // '确定要导出当前表格中的数据吗?', '提示'
+      confirmButtonText: this.$t('common.confirm'), // 确定
+      cancelButtonText: this.$t('common.cancel'), // 取消
+        type: 'warning'
+      }).then(() => {
+        return fetchPerfOrderExport(this.filterModel)
+      }).then(response => {
+        this.$message({
+          message: response.data,
+          type: 'success'
+        })
+     }).catch((error) => {
+         if(error !== 'cancel'){
+             ElementUI.Message({type: 'error', message: error.message, showClose: true, duration: 0})
+         }
+     })
+    }
+  }
+}
+</script>
+
+<style>
+  .leo-withdrawTable .el-form-item__label {
+    width: 100px;
+    color: #99a9bf;
+  }
+
+  .leo-withdrawTable .el-form-item {
+    width: 40%;
+    margin-right: 0;
+    margin-bottom: 0;
+  }
+</style>

+ 143 - 0
src/views/bonus/perf-period-list.vue

@@ -0,0 +1,143 @@
+<template>
+  <div v-loading="loading">
+    <div class="white-box">
+      <div class="filter-box">
+        <filter-user ref="filterUser" :filter-btn-name="$t('common.screen')" :filter-types="filterTypes" @select-value="handleFilterUser" />
+      </div>
+      <el-table
+        :data="tableData"
+        stripe
+        style="width: 100%;"
+        :height="tool.getTableHeight(true)"
+        @selection-change="handleSelectionChange"
+      >
+        <el-table-column v-if="tableHeaders" type="selection" width="55" />
+        <el-table-column v-for="(tableHeader, key) in tableHeaders" :key="key" :label="tableHeader.header" :width="tableHeader.other.width ? tableHeader.other.width : ''" :prop="tableHeader.other.prop ? tableHeader.other.prop : null">
+          <template slot-scope="scope">
+            <template v-if="scope.row[tableHeader.index].other.tag">
+              <el-tag :type="scope.row[tableHeader.index].other.tag.type ? scope.row[tableHeader.index].other.tag.type : null" :size="scope.row[tableHeader.index].other.tag.size ? scope.row[tableHeader.index].other.tag.size : null" :class="scope.row[tableHeader.index].other.tag.class ? scope.row[tableHeader.index].other.tag.class : null">{{ scope.row[tableHeader.index].value }}</el-tag>
+            </template>
+            <template v-else>
+              <div v-html="scope.row[tableHeader.index].value" />
+            </template>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="white-box-footer">
+        <el-button v-show="permission.hasPermission(`bonus/perf-period-list-export`)" type="success" size="small" @click="handleExport">{{$t('common.exportExcel')}}<!-- 导出Excel --></el-button>
+        <pagination :total="totalCount" :page_size="pageSize" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { fetchPerfPeriodList, fetchPerfPeriodListExport } from '@/api/bonus'
+import tool from '@/utils/tool'
+import baseInfo from '@/utils/baseInfo'
+import FilterUser from '@/components/FilterUser'
+import permission from '@/utils/permission'
+import Pagination from '@/components/Pagination'
+import filterHelper from '@/utils/filterHelper'
+import ElementUI from 'element-ui'
+
+export default {
+  name: 'LeoPerfPeriodListTable',
+  components: { FilterUser, Pagination },
+  data() {
+    return {
+      tableHeaders: null,
+      tableData: null,
+      loading: true,
+      multipleSelection: [],
+      currentPage: 1,
+      totalPages: 1,
+      totalCount: 1,
+      pageSize: 20,
+      tool: tool,
+      permission: permission,
+      baseDecLevels: baseInfo.decLevels(),
+      baseEmpLevels: baseInfo.empLevels(),
+      filterTypes: null,
+      filterModel: {},
+      filterStatus: 'ALL'
+    }
+  },
+  mounted() {
+    this.getData()
+  },
+  methods: {
+    handleSelectionChange(val) {
+      this.multipleSelection = val
+    },
+    handleCurrentChange(page) {
+      this.getData(page, this.pageSize)
+    },
+    handleSizeChange(pageSize) {
+      this.getData(this.currentPage, pageSize)
+    },
+
+    handleFilterUser(filterData) {
+      filterHelper.handleFilterUser(this, filterData)
+    },
+    getData(page, pageSize) {
+      const filterData = this.filterModel
+      if (window.location.href.indexOf('filter') === -1) {
+        filterData.filterType = this.filterStatus !== 'ALL' ? `=,${this.filterStatus}` : ''
+      }
+
+      this.loading = true
+      const paramsData = Object.assign({
+        page: (page === null || page === undefined) ? 1 : page,
+        pageSize: (pageSize === null || pageSize === undefined) ? this.pageSize : pageSize
+      }, filterData)
+      fetchPerfPeriodList(paramsData).then(response => {
+        this.filterTypes = response.data.filterTypes
+        this.tableData = response.data.list
+        this.tableHeaders = response.data.columnsShow ? response.data.columnsShow : []
+        this.loading = false
+        this.currentPage = page
+        this.totalPages = parseInt(response.data.totalPages)
+        this.totalCount = parseInt(response.data.totalCount)
+        this.pageSize = pageSize
+        // vueObj.sumData = response.sumData
+      })
+    },
+    handleExport() {
+      const filterData = this.filterModel
+      if (window.location.href.indexOf('filter') === -1) {
+        filterData.filterType = this.filterStatus !== 'ALL' ? `=,${this.filterStatus}` : ''
+      }
+       this.$confirm(this.$t('common.exportCurrentData'), this.$t('common.notice'),  { // '确定要导出当前表格中的数据吗?', '提示',
+       confirmButtonText: this.$t('common.confirm'), // 确定
+       cancelButtonText: this.$t('common.cancel'), // 取消
+        type: 'warning'
+      }).then(() => {
+        return fetchPerfPeriodListExport(this.filterModel)
+      }).then(response => {
+        this.$message({
+          message: response.data,
+          type: 'success'
+        })
+     }).catch((error) => {
+         if(error !== 'cancel'){
+             ElementUI.Message({type: 'error', message: error.message, showClose: true, duration: 0})
+         }
+     })
+    }
+  }
+}
+</script>
+
+<style>
+  .leo-withdrawTable .el-form-item__label {
+    width: 100px;
+    color: #99a9bf;
+  }
+
+  .leo-withdrawTable .el-form-item {
+    width: 40%;
+    margin-right: 0;
+    margin-bottom: 0;
+  }
+</style>

+ 141 - 0
src/views/bonus/user-perf.vue

@@ -0,0 +1,141 @@
+<template>
+  <div v-loading="loading">
+    <div class="white-box">
+      <div class="filter-box">
+        <filter-user ref="filterUser" :filter-btn-name="$t('common.screen')" :filter-types="filterTypes" @select-value="handleFilterUser" />
+      </div>
+      <el-table
+        :data="tableData"
+        stripe
+        style="width: 100%;"
+        :height="tool.getTableHeight(true)"
+        @selection-change="handleSelectionChange"
+      >
+        <el-table-column v-for="(tableHeader, key) in tableHeaders" :key="key" :label="tableHeader.header" :width="tableHeader.other.width ? tableHeader.other.width : ''" :prop="tableHeader.other.prop ? tableHeader.other.prop : null">
+          <template slot-scope="scope">
+            <template v-if="scope.row[tableHeader.index].other.tag">
+              <el-tag :type="scope.row[tableHeader.index].other.tag.type ? scope.row[tableHeader.index].other.tag.type : null" :size="scope.row[tableHeader.index].other.tag.size ? scope.row[tableHeader.index].other.tag.size : null" :class="scope.row[tableHeader.index].other.tag.class ? scope.row[tableHeader.index].other.tag.class : null">{{ scope.row[tableHeader.index].value }}</el-tag>
+            </template>
+            <template v-else>
+              <div v-html="scope.row[tableHeader.index].value" />
+            </template>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="white-box-footer">
+        <el-button v-show="permission.hasPermission(`bonus/user-perf-export`)" type="success" size="small" @click="handleExport">{{$t('common.exportExcel')}}<!-- 导出Excel --></el-button>
+        <pagination :total="totalCount" :page_size="pageSize" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { fetchUserPerf, fetchUserPerfExport } from '@/api/bonus'
+import tool from '@/utils/tool'
+import baseInfo from '@/utils/baseInfo'
+import FilterUser from '@/components/FilterUser'
+import permission from '@/utils/permission'
+import Pagination from '@/components/Pagination'
+import filterHelper from '@/utils/filterHelper'
+import ElementUI from 'element-ui'
+
+export default {
+  name: 'LeoUserPerfTable',
+  components: { FilterUser, Pagination },
+  data() {
+    return {
+      tableHeaders: null,
+      tableData: null,
+      loading: true,
+      multipleSelection: [],
+      currentPage: 1,
+      totalPages: 1,
+      totalCount: 1,
+      pageSize: 20,
+      tool: tool,
+      permission: permission,
+      baseDecLevels: baseInfo.decLevels(),
+      baseEmpLevels: baseInfo.empLevels(),
+      filterTypes: null,
+      filterModel: {},
+      filterStatus: 'ALL'
+    }
+  },
+  mounted() {
+    this.getData()
+  },
+  methods: {
+    handleSelectionChange(val) {
+      this.multipleSelection = val
+    },
+    handleCurrentChange(page) {
+      this.getData(page, this.pageSize)
+    },
+    handleSizeChange(pageSize) {
+      this.getData(this.currentPage, pageSize)
+    },
+
+    handleFilterUser(filterData) {
+      filterHelper.handleFilterUser(this, filterData)
+    },
+    getData(page, pageSize) {
+      const filterData = this.filterModel
+      if (window.location.href.indexOf('filter') === -1) {
+        filterData.filterType = this.filterStatus !== 'ALL' ? `=,${this.filterStatus}` : ''
+      }
+
+      this.loading = true
+      const paramsData = Object.assign({
+        page: (page === null || page === undefined) ? 1 : page,
+        pageSize: (pageSize === null || pageSize === undefined) ? this.pageSize : pageSize
+      }, filterData)
+      fetchUserPerf(paramsData).then(response => {
+        this.filterTypes = response.data.filterTypes
+        this.tableData = response.data.list
+        this.tableHeaders = response.data.columnsShow ? response.data.columnsShow : []
+        this.loading = false
+        this.currentPage = page
+        this.totalPages = parseInt(response.data.totalPages)
+        this.totalCount = parseInt(response.data.totalCount)
+        this.pageSize = pageSize
+      })
+    },
+    handleExport() {
+      const filterData = this.filterModel
+      if (window.location.href.indexOf('filter') === -1) {
+        filterData.filterType = this.filterStatus !== 'ALL' ? `=,${this.filterStatus}` : ''
+      }
+      this.$confirm(this.$t('common.exportCurrentData'), this.$t('common.notice'), { // '确定要导出当前表格中的数据吗?', '提示',
+       confirmButtonText: this.$t('common.confirm'), // 确定
+       cancelButtonText: this.$t('common.cancel'), // 取消
+        type: 'warning'
+      }).then(() => {
+        return fetchUserPerfExport(this.filterModel)
+      }).then(response => {
+        this.$message({
+          message: response.data,
+          type: 'success'
+        })
+     }).catch((error) => {
+         if(error !== 'cancel'){
+             ElementUI.Message({type: 'error', message: error.message, showClose: true, duration: 0})
+         }
+     })
+    }
+  }
+}
+</script>
+
+<style>
+  .leo-withdrawTable .el-form-item__label {
+    width: 100px;
+    color: #99a9bf;
+  }
+
+  .leo-withdrawTable .el-form-item {
+    width: 40%;
+    margin-right: 0;
+    margin-bottom: 0;
+  }
+</style>

+ 301 - 0
src/views/file/export.vue

@@ -0,0 +1,301 @@
+<template>
+  <div v-loading="loading">
+    <div class="white-box">
+      <el-tabs v-model="moduleName" @tab-click="handleFilterStatusClick">
+        <el-tab-pane :label="$t('file.all')" name="all" :lazy="true" /><!-- 全部 -->
+        <el-tab-pane
+          v-for="(item,key) in allModuleName"
+          :key="key"
+          :label="item.label"
+          :name="item.value"
+          :lazy="true"
+        />
+      </el-tabs>
+      <div class="filter-box">
+        <filter-user :filter-types.sync="filterTypes" :filter-btn-name="$t('common.screen')" @select-value="handleFilterUser" />
+      </div>
+      <el-table
+        ref="multipleTable"
+        class="table-box"
+        :data="tableData"
+        stripe
+        style="width: 100%;"
+        :height="tool.getTableHeight(true)"
+        @selection-change="handleSelectionChange"
+      >
+        <!--        <el-table-column type="selection" width="55"></el-table-column>-->
+        <!-- <el-table-column
+          :label="$t('file.exportName')"
+          prop="EXPORT_NAME"
+          :width="flexWidth('EXPORT_NAME',tableData,$t('file.exportName'))"
+        > --><!-- 导出名称 -->
+        <el-table-column
+          :label="$t('file.exportName')"
+          prop="EXPORT_NAME"
+          :width="flexWidth('EXPORT_NAME',tableData,$t('file.exportName'))"
+        >
+          <!-- <template slot-scope="scope">
+            {{ scope.row.EXPORT_NAME }}
+          </template> -->
+
+        </el-table-column>
+        <el-table-column
+          :label="$t('file.route')"
+          prop="EXPORT_PERCENT"
+          :width="flexWidth('EXPORT_PERCENT',tableData,$t('file.download'))"
+        ><!-- 路径 -->
+          <template slot-scope="scope">
+            <el-button
+              v-if="Number(scope.row.EXPORT_PERCENT)===100"
+              type="success"
+              size="small"
+              @click="singleDownload(scope.row)"
+            >{{ $t('file.download') }}
+            </el-button>
+          </template>
+        </el-table-column>
+        <el-table-column
+          :label="$t('file.operationAdministrator')"
+          prop="ADMIN_NAME"
+          :width="flexWidth('ADMIN_NAME',tableData,$t('file.operationAdministrator'))"
+        ><!-- 操作管理员 -->
+          <!-- <template slot-scope="scope">
+            {{ scope.row.ADMIN_NAME }}
+          </template> -->
+        </el-table-column>
+        <el-table-column
+          :label="$t('file.exportProgress')"
+          prop="EXPORT_PERCENT"
+          :width="flexWidth('EXPORT_PERCENT',tableData,$t('file.exportProgress'))"
+        ><!-- 导出进度 -->
+          <template slot-scope="scope">
+            <el-progress
+              type="circle"
+              :percentage="Number.parseInt(percentList['EXPORT_PERCENT'][scope.row.ID])"
+              :width="50"
+              :stroke-width="3"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column :label="$t('file.exportStart')" width="180"><!-- 导出开始 -->
+          <template slot-scope="scope">
+            {{ tool.formatDate(scope.row.STARTED_AT) }}
+          </template>
+        </el-table-column>
+        <el-table-column :label="$t('file.exportComplete')" width="180"><!-- 导出完成 -->
+          <template slot-scope="scope">
+            {{ tool.formatDate(scope.row.ENDED_AT) }}
+          </template>
+        </el-table-column>
+        <el-table-column :label="$t('file.createTime')" width="180"><!-- 创建时间 -->
+          <template slot-scope="scope">
+            {{ tool.formatDate(scope.row.CREATED_AT) }}
+          </template>
+        </el-table-column>
+          <!--        <el-table-column fixed="right" label="操作" width="180">-->
+          <!--          <template slot-scope="scope">-->
+          <!--            <el-dropdown size="small" trigger="click" v-if="permission.hasPermission(`file/export-delete`)">-->
+          <!--              <el-button type="primary" size="small" @click.stop="">-->
+          <!--                操作该数据<i class="el-icon-arrow-down el-icon&#45;&#45;right"></i>-->
+          <!--              </el-button>-->
+          <!--              <el-dropdown-menu slot="dropdown">-->
+          <!--                <el-dropdown-item command="delete" @click.native="handleDelete(scope.row)">删除</el-dropdown-item>-->
+          <!--              </el-dropdown-menu>-->
+          <!--            </el-dropdown>-->
+          <!--          </template>-->
+          <!--        </el-table-column>-->
+        </el-table-column>
+      </el-table>
+      <!--      <div class="white-box-footer"
+      >-->
+      <!--        <el-dropdown size="small" trigger="click" v-if="permission.hasPermission(`file/export-delete`)">-->
+      <!--          <el-button type="primary" size="small">-->
+      <!--            所选数据<i class="el-icon-arrow-down el-icon&#45;&#45;right"></i>-->
+      <!--          </el-button>-->
+      <!--          <el-dropdown-menu slot="dropdown">-->
+      <!--            <el-dropdown-item command="delete" @click.native="handleDelete()">删除</el-dropdown-item>-->
+      <!--          </el-dropdown-menu>-->
+      <!--        </el-dropdown>-->
+      <!--        <pagination :total="totalCount" :page_size="pageSize" @size-change="handleSizeChange"-->
+      <!--                    @current-change="handleCurrentChange"></pagination>-->
+      <!--      </div>-->
+    </div>
+  </div>
+</template>
+
+<script>
+import tool from '@/utils/tool'
+import FilterUser from '@/components/FilterUser'
+import permission from '@/utils/permission'
+import filterHelper from '../../utils/filterHelper'
+import { fetchExport } from '@/api/file'
+import store from '@/utils/vuexStore'
+
+export default {
+  name: 'FileExport',
+  components: { FilterUser },
+  data() {
+    return {
+      tableData: null,
+      multipleSelection: [],
+      loading: true,
+      currentPage: 1,
+      totalPages: 1,
+      totalCount: 1,
+      pageSize: 20,
+      tool: tool,
+      EXPORT_NAME: '',
+      permission: permission,
+      filterTypes: {
+        'EXPORT_NAME': { isUserTable: false, name: this.$t('file.exportName') }, // 导出名称
+        'STARTED_AT': { isUserTable: false, name: this.$t('file.exportStartTime'), other: 'date' }, // 导出开始时间
+        'ENDED_AT': { isUserTable: false, name: this.$t('file.exportEndTime'), other: 'date' }, // 导出结束时间
+        'createdAt': { isUserTable: false, name: this.$t('file.creationTime'), other: 'date' }// 创建时间
+      },
+      filterModel: {},
+      filterStatus: '0',
+      auditStatus: ['not approved', 'approved', 'rejected'], // '未审核', '已审核', '已拒绝'
+      allModuleName: null,
+      moduleName: 'all',
+      percentList: {
+        'EXPORT_PERCENT': {}
+      }
+    }
+  },
+  mounted() {
+    this.getData()
+    store.state.socket.onMessageCallback = this.onMessageCallback
+  },
+  methods: {
+    singleDownload(row) {
+      const url = (row.REMOTE_URL) ? row.REMOTE_URL : process.env.VUE_APP_CDN_API + '/' + 'upload/excel_export' + '/' + row.FILE_NAME
+      window.open(url)
+    },
+    handleSelectionChange(val) {
+      this.multipleSelection = val
+    },
+    handleCurrentChange(page) {
+      this.getData(page, this.pageSize)
+    },
+    handleSizeChange(pageSize) {
+      this.getData(this.currentPage, pageSize)
+    },
+    handleDownload(url) {
+      window.open(url)
+    },
+    handleFilterStatusClick(tab, event) {
+      this.getData()
+    },
+    handleFilterUser(filterData) {
+      filterHelper.handleFilterUser(this, filterData)
+    },
+    handleFilter() {
+      this.getData()
+    },
+    getData(page, pageSize) {
+      if (page === undefined) page = 1
+      if (pageSize === undefined) pageSize = 20
+      const filterData = this.filterModel
+      filterData.moduleName = this.moduleName !== 'all' ? `=,${this.moduleName}` : ''
+      let paramsData = {
+        page: page,
+        pageSize: pageSize
+      }
+      paramsData = Object.assign(paramsData, filterData)
+      console.log(paramsData)
+      fetchExport(paramsData).then(response => {
+        this.allModuleName = response.data.allModuleName
+        this.tableData = response.data.list
+        console.log(this.tableData)
+        this.currentPage = page
+        this.totalPages = parseInt(response.data.totalPages)
+        this.totalCount = parseInt(response.data.totalCount)
+        this.pageSize = pageSize
+        this.loading = false
+        const EXPORT_PERCENT = ['EXPORT_PERCENT']
+        if (EXPORT_PERCENT !== null) {
+          if (EXPORT_PERCENT.length > 0) {
+            for (const i in this.tableData) {
+              for (const j in EXPORT_PERCENT) {
+                this.$set(this.percentList[EXPORT_PERCENT[j]], this.tableData[i].ID, this.tableData[i][EXPORT_PERCENT[j]])
+              }
+            }
+          }
+        }
+      }, null, ['EXPORT_PERCENT'])
+    },
+    onMessageCallback(data) {
+      console.log(data)
+      if (data) {
+        if (data.other && data.other.MODEL === 'EXPORT' && data.other.ID) {
+          this.$set(this.percentList[data.other.FIELD], data.other.ID, data.percent)
+        }
+        if (data.percent && data.percent === 100) {
+          this.getData(this.currentPage, this.pageSize)
+        }
+      }
+    },
+    /**
+     * flexWidth
+     * @param prop 每列的prop 可传''
+     * @param tableData 表格数据
+     * @param title 标题长内容短的,传标题  可不传
+     * @param num 列中有标签等加的富余量
+     * @returns 列的宽度
+     * 注:prop,title有一个必传
+     */
+    flexWidth(prop, tableData = '', title, num = 0) {
+      if (tableData === undefined || tableData === null) {
+        return
+      }
+      let flexWidth = 0// 初始化表格列宽
+      let columnContent = ''// 占位最宽的内容
+      const canvas = document.createElement('canvas')
+      const context = canvas.getContext('2d')
+      context.font = '14px Microsoft YaHei'
+      if ((prop === '') && title) { // 标题长内容少的,取标题的值,
+        columnContent = title
+      } else { // 获取该列中占位最宽的内容
+        let index = 0
+        for (let i = 0; i < Object.values(tableData).length; i++) {
+          const now_temp = tableData[i][prop] + ''
+          const max_temp = tableData[index][prop] + ''
+          const now_temp_w = context.measureText(now_temp).width
+          const max_temp_w = context.measureText(max_temp).width
+          if (now_temp_w > max_temp_w) {
+            index = i
+          }
+        }
+        if (tableData[index] === undefined || tableData[index] === null) {
+          return
+        }
+        columnContent = tableData[index][prop]
+        // 比较占位最宽的值跟标题、标题为空的留出四个位置
+        const column_w = context.measureText(columnContent).width
+        const title_w = context.measureText(title).width
+        if (column_w < title_w) {
+          columnContent = title || '留四个字'
+        }
+      }
+      // 计算最宽内容的列宽
+      const width = context.measureText(columnContent)
+      flexWidth = width.width + 40 + num
+      return flexWidth + 'px'
+    }
+  }
+}
+
+</script>
+
+<style scoped>
+  .table-box .el-form-item__label {
+    width: 100px;
+    color: #99a9bf;
+  }
+
+  .table-box .el-form-item {
+    width: 30%;
+    margin-right: 0;
+    margin-bottom: 0;
+  }
+</style>

+ 474 - 0
src/views/finance/balance-audit-list.vue

@@ -0,0 +1,474 @@
+<template>
+    <div v-loading="loading">
+      <div class="white-box">
+        <el-tabs v-model="filterStatus" @tab-click="handleFilterStatusClick">
+          <el-tab-pane :label="$t('financial.all')" name="-1" :lazy="true"></el-tab-pane><!-- 全部 -->
+          <el-tab-pane :label="$t('financial.toBeReviewed')" name="0" :lazy="true"></el-tab-pane><!-- 待审核 -->
+          <el-tab-pane :label="$t('financial.approved')" name="1" :lazy="true"></el-tab-pane><!-- 审核通过 -->
+          <el-tab-pane :label="$t('financial.auditReject')" name="3" :lazy="true"></el-tab-pane><!-- 审核拒绝 -->
+        </el-tabs>
+        <div class="filter-box">
+          <filter-user ref="filterUser" :filter-types="filterTypes" @select-value="handleFilterUser"></filter-user>
+        </div>
+        <el-table :data="tableData" stripe style="width: 100%;" @selection-change="handleSelectionChange"
+                  :height="tool.getTableHeight(true)">
+          <el-table-column type="selection" width="55" v-if="tableHeaders"></el-table-column>
+          <el-table-column v-for="(tableHeader, key) in tableHeaders" :key="key" :label="tableHeader.header" :width="tableHeader.other.width ? tableHeader.other.width : ''">
+            <template slot-scope="scope">
+              <template v-if="scope.row[tableHeader.index].other.tag" >
+                <el-tag :type="scope.row[tableHeader.index].other.tag.type ? scope.row[tableHeader.index].other.tag.type : null" :size="scope.row[tableHeader.index].other.tag.size ? scope.row[tableHeader.index].other.tag.size : null" :class="scope.row[tableHeader.index].other.tag.class ? scope.row[tableHeader.index].other.tag.class : null" >{{scope.row[tableHeader.index].value}}</el-tag>
+              </template>
+              <template v-else-if="scope.row[tableHeader.index].other.progress" >
+                <el-progress type="circle" :percentage="Number.parseInt(percentList['MOVE_PERCENT'][scope.row.ID])"
+                             :width="50"
+                             :stroke-width="3"></el-progress>
+              </template>
+              <template v-else>
+                <div v-html="scope.row[tableHeader.index].value"></div>
+              </template>
+            </template>
+          </el-table-column>
+          <el-table-column :fixed="fixedColumn" :label="$t('financial.action')" width="180" v-if="tableHeaders"><!-- 操作 -->
+            <template slot-scope="scope"
+                      v-if="scope.row.AUDIT_STATUS==='0' && (permission.hasPermission(`finance/balance-audit-pass`) || permission.hasPermission(`finance/balance-audit`) || permission.hasPermission(`finance/balance-audit-delete`))">
+              <el-dropdown size="small" trigger="click">
+                <el-button type="primary" size="small" @click.stop="">
+                  <!-- 操作该数据 -->{{ $t('financial.action') }}<i class="el-icon-arrow-down el-icon--right"></i>
+                </el-button>
+                <el-dropdown-menu slot="dropdown">
+                  <el-dropdown-item command="pass" @click.native="handleAuditShow(scope.row)"
+                                    v-show="permission.hasPermission(`finance/balance-audit-pass`)">{{ $t('financial.approved') }}<!-- 审核通过 -->
+                  </el-dropdown-item>
+                  <el-dropdown-item command="refuse" @click.native="handleAudit(scope.row, 'reject')"
+                                    v-show="permission.hasPermission(`finance/balance-audit`)">{{ $t('financial.auditReject') }}<!-- 审核拒绝 -->
+                  </el-dropdown-item>
+                  <el-dropdown-item command="del" @click.native="handleDel(scope.row.ID)"
+                                    v-show="permission.hasPermission(`finance/balance-audit-delete`)">{{ $t('financial.delData') }}<!-- 删除数据 -->
+                  </el-dropdown-item>
+                </el-dropdown-menu>
+              </el-dropdown>
+            </template>
+          </el-table-column>
+        </el-table>
+        <div class="white-box-footer">
+          <el-dropdown style="margin-right:10px;" size="small" trigger="click" @command="handleMuli"
+                       v-if="filterStatus==='0' && (permission.hasPermission(`finance/balance-audit`)||permission.hasPermission(`finance/balance-audit-delete`))">
+            <el-button type="primary" size="small">
+              <!-- 所选数据 -->{{ $t('financial.selectedData') }}<i class="el-icon-arrow-down el-icon--right"></i>
+            </el-button>
+            <el-dropdown-menu slot="dropdown">
+              <el-dropdown-item command="passMinus" v-if="permission.hasPermission(`finance/balance-audit`)">{{ $t('financial.negativeAllowedBatchApproval') }}<!-- 批量审核允许为负数 --></el-dropdown-item>
+              <el-dropdown-item command="pass" v-if="permission.hasPermission(`finance/balance-audit`)">{{ $t('financial.cannotNegativeBatch') }}<!-- 批量审核不允许为负数 --></el-dropdown-item>
+              <el-dropdown-item command="reject" v-if="permission.hasPermission(`finance/balance-audit`)">{{ $t('financial.batchReject') }}<!-- 批量拒审 --></el-dropdown-item>
+              <el-dropdown-item command="del" @click.native="handleDel()" v-if="permission.hasPermission(`finance/balance-audit-delete`)">{{ $t('financial.batchDel') }}<!-- 批量删除 --></el-dropdown-item>
+            </el-dropdown-menu>
+          </el-dropdown>
+          <el-button style="margin-right:10px;" type="primary" size="small" @click="handleAdd" icon="el-icon-plus"
+                     v-show="permission.hasPermission(`finance/change-balance-opt`)">{{ $t('financial.applyChangeEcoin') }}<!-- 申请变动会员余额 -->
+          </el-button>
+          <el-button type="success" size="small" @click="handleExport"
+                     v-show="permission.hasPermission(`finance/balance-audit-list-export`)">{{ $t('common.exportExcel') }}<!-- 导出Excel -->
+          </el-button>
+          <pagination :total="totalCount" :page_size="pageSize" @size-change="handleSizeChange" @current-change="handleCurrentChange"></pagination>
+        </div>
+        <el-dialog :title="$t('financial.modifyEcoinChangeInfo')" :visible.sync="dialogEditFormVisible"><!-- 修改会员余额变动信息 -->
+          <el-form :model="form" label-width="150px" class="form-dialog" v-loading="dialogEditLoading">
+            <el-form-item :label="$t('financial.memberCode')"><!-- 会员编号 -->
+              <el-input v-model="form.baseInfo.USER_NAME" :disabled="true"></el-input>
+            </el-form-item>
+            <el-form-item :label="$t('financial.memberName')"><!-- 会员姓名 -->
+              <el-input v-model="form.baseInfo.REAL_NAME" :disabled="true"></el-input>
+            </el-form-item>
+            <el-form-item :label="$t('financial.accountType')"><!-- 账户类型 -->
+              <el-select v-model="form.type" :placeholder="$t('financial.pleaseSelectAccountType')"><!-- 请选择账户类型 -->
+                <el-option v-for="(item,key) in type" :label="item.label" :value="key" :key="key"></el-option>
+              </el-select>
+            </el-form-item>
+            <el-form-item :label="$t('financial.adjustmentAmount')"><!-- 调整金额 -->
+              <el-input v-model="form.amount"></el-input>
+            </el-form-item>
+            <el-form-item :label="$t('financial.transactionType')"><!-- 交易类型 -->
+              <el-select v-model="form.dealType" :placeholder="$t('financial.pleaseSelectTranserType')"><!-- 请选择交易类型 -->
+                <el-option v-for="(item,key) in dealTypes" :label="item.TYPE_NAME" :value="item.ID"
+                           :key="item.ID"></el-option>
+              </el-select>
+            </el-form-item>
+            <el-form-item :label="$t('table.remark')"><!-- 备注 -->
+              <el-input v-model="form.remark"></el-input>
+            </el-form-item>
+            <el-form-item :label="$t('financial.forgeDisplayRemark')"><!-- 备注前台显示 -->
+              <el-switch v-model="form.isShow" active-value="1" inactive-value="0">
+              </el-switch>
+            </el-form-item>
+          </el-form>
+          <div slot="footer" class="dialog-footer">
+            <el-button @click="dialogEditFormVisible = false">{{ $t('table.cancel') }}<!-- 取 消 --></el-button>
+            <el-button type="primary" @click.native="handleEdit">{{ $t('table.edit') }}<!-- 修 改 --></el-button>
+          </div>
+        </el-dialog>
+        <el-dialog :title="$t('financial.reviewRemberEcoinInfo')" :visible.sync="dialogAuditFormVisible"><!-- 审核会员余额变动信息 -->
+          <el-form :model="form" label-width="250px" class="form-dialog" v-loading="dialogAuditLoading">
+            <el-form-item :label="$t('financial.memberCode')"><!-- 会员编号 -->
+              <el-input v-model="form.baseInfo.USER_NAME" :disabled="true"></el-input>
+            </el-form-item>
+            <el-form-item :label="$t('financial.memberName')"><!-- 会员姓名 -->
+              <el-input v-model="form.baseInfo.REAL_NAME" :disabled="true"></el-input>
+            </el-form-item>
+            <el-form-item :label="$t('financial.accountType')"><!-- 账户类型 -->
+              <el-select v-model="form.type" :placeholder="$t('financial.pleaseSelectAccountType')"><!-- 请选择账户类型 -->
+                <el-option v-for="(item,key) in type" :label="item.label" :value="key" :key="key"></el-option>
+              </el-select>
+            </el-form-item>
+            <el-form-item :label="item.label" v-show="form.baseInfo.REAL_NAME!==null && item.name===form.type"
+                          v-for="(item,key) in type" :key="key">
+              <el-input :value="form.baseInfo[item.name.toUpperCase()]" :disabled="true"></el-input>
+            </el-form-item>
+            <el-form-item :label="$t('financial.adjustmentAmount')"><!-- 调整金额 -->
+              <el-input v-model="form.amount"></el-input>
+            </el-form-item>
+            <el-form-item :label="$t('financial.transactionType')"><!-- 交易类型 -->
+              <el-select v-model="form.dealType" :placeholder="$t('financial.pleaseSelectTranserType')"><!-- 请选择交易类型 -->
+                <el-option v-for="(item,key) in dealTypes" :label="item.TYPE_NAME" :value="item.ID"
+                           :key="item.ID"></el-option>
+              </el-select>
+            </el-form-item>
+            <el-form-item :label="$t('financial.forgeDisplayRemark')"><!-- 备注前台显示 -->
+              <el-switch v-model="form.isShow" active-value="1" inactive-value="0">
+              </el-switch>
+            </el-form-item>
+            <el-form-item :label="$t('table.remark')"><!-- 备注 -->
+              <el-input v-model="form.remark"></el-input>
+            </el-form-item>
+          </el-form>
+          <div slot="footer" class="dialog-footer">
+            <el-button @click="dialogAuditFormVisible = false">{{ $t('table.cancel') }}<!-- 取 消 --></el-button>
+            <el-button type="primary" @click.native="handleAuditPass" :disabled="auditPassButtonStat">{{ $t('table.adopted') }}<!-- 通 过 --></el-button>
+          </div>
+        </el-dialog>
+      </div>
+    </div>
+  </template>
+  
+  <script>
+    import tool from '@/utils/tool'
+    import {getOperatingSystem} from "@/utils"
+    import FilterUser from '@/components/FilterUser'
+    import baseInfo from '@/utils/baseInfo'
+    import permission from '@/utils/permission'
+    import Pagination from '@/components/Pagination'
+    import filterHelper from '@/utils/filterHelper'
+    import { getChangeBalanceType, balanceAuditList, balanceAuditListExport, balanceAuditDelete, multPoint, balanceAudit, balanceAuditGet, balanceAuditPass } from '@/api/finance'
+  
+    export default {
+      name: 'leo-balance-audit-table',
+      components: {FilterUser,Pagination},
+      mounted() {
+        getChangeBalanceType().then(response => {
+          this.type = response.data.type
+          this.dealTypes = response.data.dealTypes
+          this.getData()
+        })
+        let system =  getOperatingSystem()
+        if (system == "Android" || system == 'ios') {
+          this.fixedColumn = false
+        } else {
+          this.fixedColumn = 'right'
+        }
+        
+      },
+      data() {
+        return {
+          fixedColumn:false, // 固定,当手机端不固定,pc固定
+          tableHeaders: null,
+          tableData: null,
+          loading: true,
+          multipleSelection: [],
+          currentPage: 1,
+          totalPages: 1,
+          totalCount: 1,
+          pageSize: 20,
+          tool: tool,
+          permission: permission,
+          baseDecLevels: baseInfo.decLevels(),
+          filterTypes: {},
+          filterModel: {},
+          filterStatus: '0',
+          type: null,
+          dealTypes: null,
+          dialogEditLoading: false,
+          dialogAuditLoading: false,
+          dialogEditFormVisible: false,
+          dialogAuditFormVisible: false,
+          auditPassButtonStat: true,
+          auditId: null,
+          form: {
+            id: null,
+            baseInfo: {USER_NAME: null},
+            type: null,
+            dealType: null,
+            amount: 0,
+            createRemark: '',
+            remark: '',
+            auditStatus: null,
+            balanceCode:''
+          },
+        }
+      },
+      methods: {
+        handleMuli(command) {
+          if (this.multipleSelection.length < 1) {
+            this.$message({
+              message: this.$t('financial.selectRecordOperateNotice'),//请选择要操作的记录
+              type: 'warning'
+            })
+            return;
+          }
+          if (command === 'pass') {
+            this.handleAudit(null, 'true')
+          } else if (command === 'reject') {
+            this.handleAudit(null, 'reject')
+          } else if (command === 'passMinus') {
+            this.handleAudit(null, 'true', true)
+          }
+        },
+        handleAdd() {
+          this.$router.push({path: `/finance/change-balance-opt`})
+        },
+        handleEditShow(row) {
+          this.dialogEditLoading = true
+          this.auditId = row.ID
+          this.dialogEditFormVisible = true
+          let vueObj = this
+          network.getData('finance/balance-audit-get', {id: this.auditId}).then(response => {
+            vueObj.dialogEditLoading = false
+            vueObj.form = response
+            vueObj.form.type = String(response.type)
+            vueObj.form.createRemark = vueObj.form.remark
+          })
+        },
+        handleEdit() {
+          this.dialogEditFormVisible = false
+          this.$message({
+            message: this.$t('financial.modifyData'),//正在修改数据
+            type: 'info'
+          })
+          let path = 'finance/balance-audit-edit'
+          network.postData(path, this.form).then(response => {
+            this.$message({
+              message: response,
+              type: 'success'
+            })
+            this.getData(this.currentPage, this.pageSize)
+          }).catch(response => {
+          })
+        },
+        handleAuditShow(row) {
+          this.dialogAuditLoading = true
+          this.auditId = row.ID
+          this.dialogAuditFormVisible = true
+          let vueObj = this
+          balanceAuditGet({id: this.auditId}).then(response => {
+            vueObj.dialogAuditLoading = false
+            vueObj.form.id = response.data.id
+            vueObj.form.baseInfo = response.data.baseInfo
+            vueObj.form.dealType = response.data.dealType
+            vueObj.form.amount = response.data.amount
+            vueObj.form.remark = response.data.remark
+            vueObj.form.auditStatus = response.data.auditStatus
+            vueObj.form.type = String(response.data.type)
+            vueObj.form.createRemark = vueObj.form.remark
+          }).catch(err => {
+            vueObj.dialogAuditLoading = false
+          })
+          multPoint({opType: 1}).then(response => {
+            this.form.balanceCode = response.data.balanceCode
+            this.auditPassButtonStat = false
+          }).catch(err => {
+            this.$message({
+              message: err,
+              type: 'error'
+            })
+          })
+        },
+        handleAuditPass() {
+            if (this.form.type === 'bonus') {
+              if ((Number.parseFloat(this.form.baseInfo['BONUS']) + Number.parseFloat(this.form.amount)) < 0) {
+                this.$confirm(this.$t('financial.balanceInsufficientSubmitNotice'), this.$t('common.hint'), {//`会员账户余额不足,是否继续提交`, '提示'
+                  confirmButtonText: this.$t('common.confirm'),//确定
+                  cancelButtonText: this.$t('common.cancel'),//取消
+                  type: 'warning'
+                }).then(() => {
+                  this._handleAuditPass()
+                }).catch(() => {
+                  this.submitButtonStat = false
+                  return false
+                })
+              } else {
+                this._handleAuditPass()
+              }
+            } else {
+              this._handleAuditPass()
+            }
+        },
+        _handleAuditPass() {
+          this.dialogAuditFormVisible = false
+          this.$message({
+            message: this.$t('financial.passingAudit'),//正在通过审核
+            type: 'info'
+          })
+          this.form.auditStatus = 'true'
+          balanceAuditPass(this.form).then(response => {
+            this.$message({
+              message: response.data,
+              type: 'success'
+            })
+            this.getData(this.currentPage, this.pageSize)
+          }).catch(err => {
+            this.$message({
+              message: err,
+              type: 'error'
+            })
+          })
+        },
+        // 审核拒绝
+        handleAudit(row = null, status, minus = false) {
+          let obj = this  
+          let title = this.$t('financial.handleAuditDefaultNotice')  //确定要通过审核(会员账户不允许为负数)?备注:
+          if (status === 'reject') {
+            title = this.$t('financial.handleAuditRejectNotice') //确定要拒绝审核?备注
+          }else if(minus){
+            title = this.$t('financial.handleAuditPassNotice') //确定要通过审核(会员账户允许为负数)?备注
+          }
+          multPoint({opType: 1}).then(response => {
+            this.form.balanceCode = response.data.balanceCode
+            this.$prompt(title, this.$t('common.hint'), {//提示
+              confirmButtonText: this.$t('common.confirm'),//确定
+              cancelButtonText: this.$t('common.cancel'),//取消
+              inputValue: row ? row.REMARK : '',
+                  //type: 'warning',
+            }).then(({value}) => {
+              let selectedIds = []
+              if (row === null) {
+                for (let val of obj.multipleSelection) {
+                  selectedIds.push(val.ID)
+                }
+              } else {
+                selectedIds.push(row.ID)
+              }
+              let requestParams = {
+                selected: selectedIds,
+                remark: value,
+                allowMinus: minus,
+                auditStatus: status,
+                balanceCode: this.form.balanceCode
+              }
+              balanceAudit(requestParams).then(response => {
+                this.$message({
+                  message: response.data,
+                  type: 'success'
+                })
+                this.getData(this.currentPage, this.pageSize)
+              }).catch(err => {
+                this.$message({
+                  message: err,
+                  type: 'error'
+                })
+              })
+            })
+          })
+        },
+        handleDel(id = null) {
+          let obj = this
+          this.$confirm(this.$t('financial.okDelData'), this.$t('common.hint'), {//'确定删除选定的数据?', '提示'
+            confirmButtonText: this.$t('common.confirm'),//确定
+            cancelButtonText: this.$t('common.cancel'),//取消
+            type: 'warning'
+          }).then(() => {
+            let selectedIds = []
+            if (id === null) {
+              for (let val of obj.multipleSelection) {
+                selectedIds.push(val.ID)
+              }
+            } else {
+              selectedIds.push(id)
+            }
+            balanceAuditDelete({selected: selectedIds}).then(response => {
+              this.$message({
+                message: response.data,
+                type: 'success'
+              })
+              obj.getData(obj.currentPage, obj.pageSize)
+            }).catch(err => {
+              this.$message({
+                message: err,
+                type: 'error'
+              })
+            })  
+            
+          })
+        },
+        handleSelectionChange(val) {
+          this.multipleSelection = val
+        },
+        handleCurrentChange(page) {
+          this.getData(page, this.pageSize)
+        },
+        handleSizeChange(pageSize) {
+          this.getData(this.currentPage, pageSize)
+        },
+        handleFilterStatusClick(tab, event) {
+          filterHelper.clearFilterOption(this)
+          this.getData()
+        },
+        handleFilterUser(filterData) {
+          filterHelper.handleFilterUser(this, filterData)
+        },
+        getData(page, pageSize) {
+          let filterData = this.filterModel
+          let vueObj=this
+          filterData.filterStatus = this.filterStatus != -1 ? `=,${this.filterStatus}` : ''
+          const paramsData = Object.assign({
+            page: (page === null || page == undefined) ? 1 : page,
+            pageSize: (pageSize === null || pageSize == undefined) ? vueObj.pageSize : pageSize
+          }, filterData)
+          balanceAuditList(paramsData).then(response => {
+            vueObj.tableHeaders = response.data.columnsShow ? response.data.columnsShow : []
+            vueObj.tableData = response.data.list
+            vueObj.filterTypes = response.data.filterTypes
+            vueObj.currentPage = page
+            vueObj.totalPages = parseInt(response.data.totalPages)
+            vueObj.totalCount = parseInt(response.data.totalCount)
+            vueObj.pageSize = pageSize
+            this.loading = false
+          }).catch(err => {
+            console.log('err=============' + err)
+            this.loading = false
+          })
+        },
+        handleExport(){
+          this.$confirm(this.$t('financial.exportNotice'), this.$t('common.hint'), {//`确定要导出当前数据吗?`, '提示',
+            confirmButtonText: this.$t('common.confirm'),//确定
+            cancelButtonText: this.$t('common.cancel'),//取消
+            type: 'warning'
+          }).then(() => {
+            balanceAuditListExport(this.filterModel).then(response => {
+              this.$message({
+                message: response.data,
+                type: 'success'
+              })
+            }).catch(error => {
+              this.$message({
+                message: error,
+                type: 'error'
+              })
+            })
+          })
+        },
+      }
+    }
+  </script>
+  
+  <style scoped>
+  
+  </style>
+  

+ 224 - 0
src/views/finance/change-balance-opt.vue

@@ -0,0 +1,224 @@
+<template>
+    <div v-loading="loading">
+      <div class="white-box">
+        <el-tabs v-model="tabActiveName">
+          <el-tab-pane :label="$t('financial.manuallyAdd')" name="first" v-if="permission.hasPermission(`finance/change-balance`)"><!--手动添加-->
+            <el-form ref="form" :model="form" label-width="250px" class="bkele-form-page">
+              <el-form-item :label="$t('financial.memberCode')"><!--会员编号-->
+                <el-input v-model="form.userName" @change="handleChange"></el-input>
+              </el-form-item>
+              <el-form-item :label="$t('financial.memberName')" v-show="userInfo.REAL_NAME!==null"><!--会员姓名-->
+                <el-input :value="userInfo.REAL_NAME" :disabled="true"></el-input>
+              </el-form-item>
+              <el-form-item :label="$t('financial.memberLevel')" v-show="userInfo.REAL_NAME!==null"><!--会员级别-->
+                <el-input :value="userInfo.LEVEL_NAME" :disabled="true"></el-input>
+              </el-form-item>
+              <!--<el-form-item label="报单中心级别" v-show="userInfo.DEC_ROLE_NAME!=='无'">-->
+                <!--<el-input :value="userInfo.DEC_ROLE_NAME" :disabled="true"></el-input>-->
+              <!--</el-form-item>-->
+  
+              <el-form-item :label="item.label" v-show="userInfo.REAL_NAME!==null" v-for="(item,key) in type" :key="key">
+                <el-input :value="userInfo[item.name.toUpperCase()]" :disabled="true"></el-input>
+              </el-form-item>
+              
+              <el-form-item :label="$t('financial.accountType')"><!--账户类型-->
+                <el-select v-model="form.type" :placeholder="$t('financial.pleaseSelectAccountType')"><!--请选择账户类型-->
+                  <el-option v-for="(item,key) in type" :label="item.label" :value="key" :key="key"></el-option>
+                </el-select>
+              </el-form-item>
+              <el-form-item :label="$t('financial.adjustAmount')"><!--调整金额-->
+                <el-input v-model="form.amount"></el-input>
+              </el-form-item>
+              <el-form-item :label="$t('financial.transactionType')"><!--交易类型-->
+                <el-select v-model="form.dealType" :placeholder="$t('financial.pleaseSelectTranserType')"><!--请选择交易类型-->
+                  <el-option v-for="(item,key) in dealTypes" :label="item.TYPE_NAME" :value="item.ID"
+                             :key="item.ID"></el-option>
+                </el-select>
+              </el-form-item>
+              <el-form-item :label="$t('common.note')"><!--备注-->
+                <el-input v-model="form.remark"></el-input>
+              </el-form-item>
+              <el-form-item :label="$t('financial.forgeDisplayRemark')"><!--备注前台显示-->
+                <el-switch v-model="form.isShow" active-value="1" inactive-value="0">
+                </el-switch>
+              </el-form-item>
+              <el-form-item>
+                <el-button type="primary" :loading="submitButtonStat" :disabled="getCodeStat" @click="onSubmit">{{ $t('common.confirm') }}<!-- 提交 --></el-button>
+              </el-form-item>
+            </el-form>
+          </el-tab-pane>
+          <!--<el-tab-pane label="批量导入" name="second"-->
+                       <!--v-if="permission.hasPermission(`finance/import-change-balance-to-excel-table`)&&permission.hasPermission(`finance/import-change-balance`)">-->
+            <!--<el-form ref="form" :model="form" label-width="250px" class="form-page">-->
+              <!--<el-form-item label="Excel文件总行数">-->
+                <!--<el-input v-model="excelForm.rowCount"></el-input>-->
+              <!--</el-form-item>-->
+              <!--<el-form-item label="">-->
+                <!--<el-tag type="info">表格中账户类型要求英文:bonus(会员账户余额)、reconsume_points(复消积分)</el-tag>-->
+              <!--</el-form-item>-->
+              <!--<el-form-item>-->
+                <!--<leo-excel-uploader-->
+                    <!--:request-upload-route="`file/upload-excel`"-->
+                    <!--:request-import-to-excel-table-route="`finance/import-change-balance-to-excel-table`"-->
+                    <!--:request-import-excel-table-to-data-route="`finance/import-change-balance`"-->
+                    <!--:import-row-count="excelForm.rowCount"-->
+                    <!--excel-option="changeBalance"-->
+                    <!--upload-btn-title="Excel导入"-->
+                    <!--style="float: left;"-->
+                <!--&gt;</leo-excel-uploader>-->
+                <!--<el-button type="primary" @click="handleExcel" style="float: left; margin-left: 10px;">下载模板</el-button>-->
+              <!--</el-form-item>-->
+            <!--</el-form>-->
+          <!--</el-tab-pane>-->
+        </el-tabs>
+      </div>
+    </div>
+  </template>
+  
+  <script>
+    import tool from '@/utils/tool'
+    import baseInfo from '@/utils/baseInfo'
+    import { getChangeBalanceType, multPoint, changeBalance, userFullInfo } from '@/api/finance'
+    // import {CDN_BASE_URL} from '@/utils/config'
+    import permission from '@/utils/permission'
+  
+    export default {
+      name: 'finance_change-balance-opt',
+      mounted() {
+        getChangeBalanceType().then(response => {
+          this.type = response.data.type
+          this.dealTypes = response.data.dealTypes
+          this.loading = false
+          if (permission.hasPermission(`finance/import-change-balance-to-excel-table`) && permission.hasPermission(`finance/import-change-balance`)) {
+            this.tabActiveName = 'second'
+          }
+          if (permission.hasPermission(`finance/change-balance`)) {
+            this.tabActiveName = 'first'
+          }
+        }).catch(err => {
+            console.log(err)
+            this.loading = false
+        })
+        multPoint({opType: 1}).then(response => {
+            this.form.balanceCode = response.data.balanceCode
+            this.getCodeStat = false
+        })
+      },
+      data() {
+        return {
+          form: {
+            userName: null,
+            type: null,
+            amount: 0,
+            remark: '',
+            isShow: '1',
+            dealType: null,
+            balanceCode: '',
+          },
+          userInfo: {
+            REAL_NAME: null,
+            DEC_ROLE_NAME: '',
+            BONUS: 0,
+            BONUS_FREEZE: 0,
+            DEC_LV: 0,
+            DEC_DEC_LV: 0,
+          },
+          baseDecLevels: baseInfo.decLevels(),
+          type: null,
+          dealTypes: null,
+          loading: true,
+          submitButtonStat: false,
+          getCodeStat: true,
+          tool: tool,
+          tabActiveName: 'first',
+          excelForm: {
+            rowCount: 0,
+          },
+          permission: permission,
+        }
+      },
+      methods: {
+        handleChange() {
+          this.loading = true
+          userFullInfo({userName: this.form.userName}).then(response => {
+            this.userInfo = response.data
+            this.loading = false
+          }).catch(err => {
+            this.loading = false
+            this.$message({
+              message: err,
+              type: 'error'
+            })
+          })
+        },
+        onSubmit() {
+              if (this.form.type === 'bonus') {
+                if ((Number.parseFloat(this.userInfo['BONUS']) + Number.parseFloat(this.form.amount)) < 0) {
+                  this.$confirm(this.$t('financial.ecoinInsufficientNotice'), this.$t('common.hint'), {// 会员账户余额不足,是否继续提交
+                    confirmButtonText: this.$t('common.confirm'), // 确定
+                    cancelButtonText: this.$t('common.cancel'), // 取消
+                    type: 'warning'
+                  }).then(() => {
+                    this._handleSubmit()
+                  }).catch(() => {
+                    this.submitButtonStat = false
+                    return false
+                  })
+                } else {
+                  this._handleSubmit()
+                }
+              } else {
+                this._handleSubmit()
+              }
+        },
+        _handleSubmit() {
+          this.submitButtonStat = true
+          changeBalance(this.form).then(response => {
+            this.submitButtonStat = false
+            this.$message({
+              message: response.data,
+              type: 'success'
+            })
+            this.$router.go(-1)
+          }).catch(err => {
+            this.submitButtonStat = false
+            this.$message({
+              message: err,
+              type: 'error'
+            })
+          })
+        },
+        handleExcel() {
+        //   window.open(CDN_BASE_URL + `/files/bonus_change_balance.xlsx`)
+        },
+      }
+    }
+  </script>
+  
+  <style scoped>
+  @media (min-width: 761px) {
+    /deep/ .el-input__inner {
+      width: 500px;
+    }
+  }
+  @media (max-width:760px) {
+    /deep/ .white-box {
+    padding: 0px 0px;
+    }
+    /deep/ .el-form-item__content {
+      margin-left:150px !important;
+    }
+    /deep/ .el-form-item__label {
+      width:150px !important;
+    }
+    /deep/ .el-input__inner { 
+      width: 150px;
+    }
+    /* .el-input {
+      width: 90%;
+    } */
+
+  }
+
+  </style>
+  

+ 117 - 0
src/views/finance/recharge-status.vue

@@ -0,0 +1,117 @@
+<template>
+    <div v-loading="loading">
+        <div class="white-box">
+            <el-form ref="form"  label-width="250px" class="bkele-form-page">
+                <el-form-item :label="$t('financial.rechargeStatusState')"> <!-- 充值状态 -->
+                    <el-select v-model="form.auditStatus" :placeholder="$t('financial.rechargeStatusState')"> <!-- 充值状态 -->
+                        <el-option v-for="(item,index) in statusArray" :key="index" :label="item"
+                                   :value="index"></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item :label="$t('table.remark')"> <!-- 备注 -->
+                    <el-input v-model="form.createRemark"></el-input>
+                </el-form-item>
+                <el-form-item>
+                    <el-button type="primary" @click="onSubmit" :loading="submitButtonStat">{{  $t('common.modify')  }}</el-button> <!-- 修改 -->
+                </el-form-item>
+            </el-form>
+        </div>
+    </div>
+</template>
+
+<script>
+    import { getRechargeStatus, postRechargeStatus } from '@/api/finance'
+    export default {
+        name: "recharge-status",
+        created(){
+            this.getParams()
+        },
+        mounted() {
+            this.getData();
+        },
+
+        data(){
+            return{
+                loading: false,
+                form:{
+                    auditStatus:'',
+                    createRemark:'',
+                    selectedIds:'',
+                },
+                submitButtonStat: false,
+                statusArray: null,
+            }
+        },
+        methods: {
+            getParams(){
+                // 取到路由带过来的参数
+                this.form.selectedIds = this.$route.query.mallCode.ID
+                // 将数据放在当前组件的数据内
+                //this.form.selectedIds = routerParams;
+
+            },
+            getData() {
+                getRechargeStatus().then(response => {
+                    this.statusArray = response.data.statusArray;
+                    this.loading = false;
+                }).catch(err => {
+                    this.loading = false;
+                })
+            },
+            onSubmit() {
+                this.submitButtonStat = true
+                let postData = {
+                    auditStatus: this.form.auditStatus,
+                    createRemark: this.form.createRemark,
+                    selectedIds: this.form.selectedIds,
+                }
+                postRechargeStatus(postData).then(response => {
+                    this.$message({
+                        message: response.data,
+                        type: 'success'
+                    })
+                    this.submitButtonStat = false
+                    this.$router.go(-1)
+                }).catch(err => {
+                    this.$message({
+                        message: err,
+                        type: 'error'
+                    })
+                    this.submitButtonStat = false
+                })
+            },
+        },
+        watch: {
+            '$route': 'getParams'
+        }
+    }
+</script>
+
+<style scoped>
+    .el-form-item{
+        margin-top: 35px;
+    }
+    @media (min-width: 761px) {
+    /deep/ .el-input__inner {
+      width: 500px;
+    }
+  }
+  @media (max-width:760px) {
+    /deep/ .white-box {
+    padding: 0px 0px;
+    }
+    /deep/ .el-form-item__content {
+      margin-left:150px !important;
+    }
+    /deep/ .el-form-item__label {
+      width:150px !important;
+    }
+    /deep/ .el-input__inner { 
+      width: 150px;
+    }
+    /* .el-input {
+      width: 90%;
+    } */
+
+  }
+</style>

+ 215 - 0
src/views/finance/recharge.vue

@@ -0,0 +1,215 @@
+<template>
+    <div v-loading="loading">
+        <div class="white-box">
+            <div class="filter-box">
+                <filter-user :filter-types="filterTypes" @select-value="handleFilterUser"></filter-user>
+            </div>
+            <el-table class="table-box" ref="multipleTable" :data="tableData" stripe style="width: 100%;" :height="tool.getTableHeight()" @selection-change="handleSelectionChange">
+                <!-- <el-table-column fixed type="selection" width="55" v-if="tableHeaders" :selectable="checkSelectable"></el-table-column>-->
+                <el-table-column v-for="(tableHeader, key) in tableHeaders" :key="key" :label="tableHeader.header" :width="tableHeader.other.width ? tableHeader.other.width : ''" :prop="tableHeader.other.prop ? tableHeader.other.prop : null">
+                    <template slot-scope="scope">
+                        <template v-if="scope.row[tableHeader.index].other.tag" >
+                            <el-tag :type="scope.row[tableHeader.index].other.tag.type ? scope.row[tableHeader.index].other.tag.type : null" :size="scope.row[tableHeader.index].other.tag.size ? scope.row[tableHeader.index].other.tag.size : null" :class="scope.row[tableHeader.index].other.tag.class ? scope.row[tableHeader.index].other.tag.class : null" >{{scope.row[tableHeader.index].value}}</el-tag>
+                        </template>
+                        <template v-else>
+                            <div v-html="scope.row[tableHeader.index].value"></div>
+                        </template>
+                    </template>
+                </el-table-column>
+                <el-table-column :label="$t('common.action')"> <!-- 操作 -->
+                    <template slot-scope="scope">
+                    <el-button type="success" size="small" @click="handleGroupManage(scope.row)" >
+                        {{  $t('financial.statusManagement')  }}<!-- 状态管理 -->
+                    </el-button>
+                </template></el-table-column>
+                <el-table-column :label="$t('financial.viewVoucher')"><!-- 查看凭证 -->
+                    <template slot-scope="scope">
+                        <el-button type="success" size="small" @click="handleInvoiceShow(scope.row)"
+                           v-if="scope.row.AUDIT_STATUS!=='0'">{{  $t('financial.viewVoucher')  }}<!-- 查看凭证 -->
+                        </el-button>
+                    </template>
+                </el-table-column>
+
+            </el-table>
+            <div class="white-box-footer">
+                <el-button type="success" size="small" @click="handleExport"
+                     v-show="permission.hasPermission(`finance/recharge-export`)">{{ $t('common.exportExcel') }}
+                </el-button>
+                <pagination :total="totalCount" :page_size="pageSize" @size-change="handleSizeChange" @current-change="handleCurrentChange"></pagination>
+            </div>
+            <el-dialog :title="$t('financial.checkRechargeVoucher')" :visible.sync="dialogInvoiceVisible"> <!-- 查看充值凭证 -->
+                <div v-loading="dialogInvoiceLoading">
+                    <a :href="invoiceUrl" target="_blank"><img :src="urlimg" alt="" style="max-width: 100%"></a>
+                </div>
+                <div slot="footer" class="dialog-footer">
+                    <el-button @click="dialogInvoiceVisible = false">{{ $t('common.confirm') }}</el-button> <!-- 确 定 -->
+                </div>
+            </el-dialog>
+        </div>
+    </div>
+</template>
+
+<script>
+    import tool from '@/utils/tool'
+    import FilterUser from '@/components/FilterUser'
+    import permission from '@/utils/permission'
+    import Pagination from '@/components/Pagination'
+    import filterHelper from '@/utils/filterHelper'
+    import { rechargeList, rechargeExport } from '@/api/finance'
+
+    export default {
+        name: 'recharge',
+        components: {FilterUser,Pagination},
+        mounted () {
+            this.getData()
+        },
+
+        data () {
+            return {
+                tableHeaders: null,
+                tableData: null,
+                loading: true,
+                currentPage: 1,
+                totalPages: 1,
+                totalCount: 1,
+                pageSize: 20,
+                multipleSelection: [],
+                tool: tool,
+                permission: permission,
+                filterTypes: {},
+                filterModel: {},
+                value:[],
+                selectedIds:'',
+                dialogInvoiceVisible: false,
+                dialogInvoiceLoading: false,
+                invoiceUrl:'',
+                urlimg:''
+            }
+        },
+        methods: {
+            handleSelectionChange(val) {
+                this.multipleSelection = val
+            },
+            handleCurrentChange (page) {
+                this.getData(page, this.pageSize)
+            },
+            handleSizeChange (pageSize) {
+                this.getData(this.currentPage, pageSize)
+            },
+            handleFilterUser(filterData){
+                filterHelper.handleFilterUser(this, filterData)
+            },
+            handleFilter() {
+                this.getData()
+            },
+            checkSelectable(row) {
+                return row.DONT_DEL !== '1'
+            },
+            getData (page, pageSize) {
+                let filterData = this.filterModel
+                let vueObj = this
+                const paramsData = Object.assign({
+                    page: (page === null || page == undefined) ? 1 : page,
+                    pageSize: (pageSize === null || pageSize == undefined) ? vueObj.pageSize : pageSize
+                }, filterData)
+                rechargeList(paramsData).then(response => {
+                    vueObj.tableHeaders = response.data.columnsShow ? response.data.columnsShow : []
+                    vueObj.tableData = response.data.list
+                    vueObj.filterTypes = response.data.filterTypes
+                    vueObj.currentPage = page
+                    vueObj.totalPages = parseInt(response.data.totalPages)
+                    vueObj.totalCount = parseInt(response.data.totalCount)
+                    vueObj.pageSize = pageSize
+                    // vueObj.selectedIds = vueObj.tableData.ID;
+                    let settingObj=vueObj.tableData;
+                    let settingArr = Object.keys(settingObj).map(key => {
+                        //console.log(key); //为每个键名
+                        return settingObj[key];  //把每个对象返回出去生成一个新的数组中相当于0:{id:1}
+                    } );
+                    this.tableData=settingArr;
+                    this.loading = false
+                }).catch(err => {
+                    this.$message({
+                        message: err,
+                        type: 'error'
+                    })
+                    this.loading = false
+                })
+            },
+            handleExport(){
+                this.$confirm(this.$t('financial.exportNotice'), this.$t('common.hint'), {
+                    confirmButtonText: this.$t('common.confirm'), // 确定
+                    cancelButtonText: this.$t('common.cancel'), // 取消
+                    type: 'warning'
+                }).then(() => {
+                    rechargeExport(this.filterModel).then(response => {
+                        this.$message({
+                                message: response.data,
+                                type: 'success'
+                        })
+                    }).catch(error => {
+                        this.$message({
+                            message: error,
+                            type: 'error'
+                        })
+                    })
+                })
+            },
+            handleInvoiceShow(row) {
+                this.dialogInvoiceLoading = true
+                this.uploadId = row.ID
+                this.dialogInvoiceVisible = true
+                this.dialogInvoiceLoading = false
+                this.urlimg = tool.getArImage(row.BANK_PROVE, '/files/');
+            },
+
+       /* handlestate(){
+            this.$router.push({path: `/finance/recharge-status`})
+        },*/
+
+            handleGroupManage(row) {
+
+               /* if (this.multipleSelection.length < 1) {
+                    this.$message({
+                        message: '请勾选要操作的会员',
+                        type: 'warning'
+                    })
+                    return
+                }else{
+                    if(this.multipleSelection.length > 1){
+                        this.$message({
+                            message: '只能选择一个',
+                            type: 'warning'
+                        })
+                        return
+                    }
+                }*/
+
+                    this.$router.push({
+                        path: `/finance/recharge-status`,
+                        query: {
+                            mallCode: row
+                        }
+                    })
+
+
+
+            },
+        },
+    }
+</script>
+<style scoped>
+    .table-box .el-form-item__label {
+        width: 100px;
+        color: #99a9bf;
+    }
+
+    .table-box .el-form-item {
+        width: 30%;
+        margin-right: 0;
+        margin-bottom: 0;
+    }
+    .el-button--small, .el-button--small.is-round {
+        padding: 9px 5px;
+    }
+</style>

+ 124 - 0
src/views/finance/transfer-list.vue

@@ -0,0 +1,124 @@
+<template>
+    <div v-loading="loading">
+      <div class="white-box">
+        <div class="filter-box">
+          <filter-user :filter-types.sync="filterTypes" @select-value="handleFilterUser"></filter-user>
+        </div>
+        <el-table :data="tableData" stripe style="width: 100%;" :height="tool.getTableHeight()">
+          <el-table-column v-for="(tableHeader, key) in tableHeaders" :key="key" :label="tableHeader.header" :width="tableHeader.other.width ? tableHeader.other.width : ''">
+            <template slot-scope="scope">
+              <template v-if="scope.row[tableHeader.index].other.tag" >
+                <el-tag :type="scope.row[tableHeader.index].other.tag.type ? scope.row[tableHeader.index].other.tag.type : null" :size="scope.row[tableHeader.index].other.tag.size ? scope.row[tableHeader.index].other.tag.size : null" :class="scope.row[tableHeader.index].other.tag.class ? scope.row[tableHeader.index].other.tag.class : null" >{{scope.row[tableHeader.index].value}}</el-tag>
+              </template>
+              <template v-else-if="scope.row[tableHeader.index].other.progress" >
+                <el-progress type="circle" :percentage="Number.parseInt(percentList['MOVE_PERCENT'][scope.row.ID])"
+                             :width="50"
+                             :stroke-width="3"></el-progress>
+              </template>
+              <template v-else>
+                <div v-html="scope.row[tableHeader.index].value"></div>
+              </template>
+            </template>
+          </el-table-column>
+        </el-table>
+        <div class="white-box-footer">
+          <el-button type="success" size="small" @click="handleExport"
+                     v-show="permission.hasPermission(`finance/transfer-list-export`)">{{ $t('common.exportExcel') }}<!-- 导出Excel -->
+          </el-button>
+          <pagination :total="totalCount" :page_size="pageSize" @size-change="handleSizeChange"
+                      @current-change="handleCurrentChange"></pagination>
+        </div>
+      </div>
+    </div>
+  </template>
+  
+  <script>
+    import tool from '@/utils/tool'
+    import FilterUser from '@/components/FilterUser'
+    import baseInfo from '@/utils/baseInfo'
+    import permission from '@/utils/permission'
+    import Pagination from '@/components/Pagination'
+    import filterHelper from '@/utils/filterHelper'
+    import { transferList, transferListExport } from '@/api/finance'
+  
+    export default {
+      name: 'finance_transfer-list',
+      components: {FilterUser, Pagination},
+      mounted() {
+        this.getData()
+      },
+      data() {
+        return {
+          tableHeaders: null,
+          tableData: null,
+          loading: true,
+          currentPage: 1,
+          totalPages: 1,
+          totalCount: 1,
+          pageSize: 20,
+          tool: tool,
+          permission: permission,
+          baseDecLevels: baseInfo.decLevels(),
+          filterTypes: {},
+          filterModel: {},
+        }
+      },
+      methods: {
+        handleCurrentChange(page) {
+          this.getData(page, this.pageSize)
+        },
+        handleSizeChange(pageSize) {
+          this.getData(this.currentPage, pageSize)
+        },
+        handleFilterUser(filterData) {
+          filterHelper.handleFilterUser(this, filterData)
+        },
+        handleFilter() {
+          this.getData()
+        },
+        getData(page, pageSize) {
+          let filterData = this.filterModel
+          let vueObj = this
+          const paramsData = Object.assign({
+            page: (page === null || page == undefined) ? 1 : page,
+            pageSize: (pageSize === null || pageSize == undefined) ? vueObj.pageSize : pageSize
+          }, filterData)
+          transferList(paramsData).then(response => {
+            vueObj.tableHeaders = response.data.columnsShow ? response.data.columnsShow : []
+            vueObj.tableData = response.data.list
+            vueObj.filterTypes = response.data.filterTypes
+            vueObj.currentPage = page
+            vueObj.totalPages = parseInt(response.data.totalPages)
+            vueObj.totalCount = parseInt(response.data.totalCount)
+            vueObj.pageSize = pageSize
+        
+            this.loading = false
+          })
+        },
+        handleExport(){
+          this.$confirm(this.$t('financial.exportNotice'), this.$t('common.hint'), {//`确定要导出当前数据吗?`, '提示'
+            confirmButtonText: this.$t('common.confirm'),//确定
+            cancelButtonText: this.$t('common.cancel'),//取消
+            type: 'warning'
+          }).then(() => {
+            transferListExport(this.filterModel).then(response => {
+              this.$message({
+                message: response.data,
+                type: 'success'
+              })
+            }).catch(error => {
+              this.$message({
+                message: error,
+                type: 'error'
+              })
+            })
+          })
+        },
+      }
+    }
+  </script>
+  
+  <style scoped>
+  
+  </style>
+  

+ 549 - 0
src/views/finance/withdraw.vue

@@ -0,0 +1,549 @@
+<template>
+    <div v-loading="loading">
+      <div class="white-box">
+        <el-tabs v-model="filterStatus" @tab-click="handleFilterStatusClick">
+          <el-tab-pane :label="$t('financial.all')" name="-1" :lazy="true"></el-tab-pane> <!-- 全部 -->
+          <el-tab-pane :label="$t('financial.toBeReviewed')" name="0" :lazy="true"></el-tab-pane> <!-- 待审核 -->
+          <el-tab-pane :label="$t('financial.reviewed')" name="2" :lazy="true"></el-tab-pane> <!-- 已审核 -->
+          <el-tab-pane :label="$t('financial.toBePaid')" name="3" :lazy="true"></el-tab-pane> <!-- 待付款 -->
+          <el-tab-pane :label="$t('financial.paid')" name="6" :lazy="true"></el-tab-pane> <!-- 已付款 -->
+          <el-tab-pane :label="$t('financial.paymentFailed')" name="4" :lazy="true"></el-tab-pane> <!-- 付款失败 -->
+          <el-tab-pane :label="$t('financial.returned')" name="7" :lazy="true"></el-tab-pane> <!-- 已退回 -->
+        </el-tabs>
+        <div class="filter-box">
+          <filter-user :filter-types.sync="filterTypes" @select-value="handleFilterUser"></filter-user>
+        </div>
+        <el-table :data="tableData" stripe style="width: 100%;" @selection-change="handleSelectionChange" :height="tool.getTableHeight(true)">
+          <el-table-column type="selection" width="55" v-if="tableHeaders"></el-table-column>
+          <el-table-column v-for="(tableHeader, key) in tableHeaders" :key="key" :label="tableHeader.header" :width="tableHeader.other.width ? tableHeader.other.width : ''">
+            <template slot-scope="scope">
+              <template v-if="scope.row[tableHeader.index].other.tag" >
+                <el-tag :type="scope.row[tableHeader.index].other.tag.type ? scope.row[tableHeader.index].other.tag.type : null" :size="scope.row[tableHeader.index].other.tag.size ? scope.row[tableHeader.index].other.tag.size : null" :class="scope.row[tableHeader.index].other.tag.class ? scope.row[tableHeader.index].other.tag.class : null" >{{scope.row[tableHeader.index].value}}</el-tag>
+              </template>
+              <template v-else-if="scope.row[tableHeader.index].other.progress" >
+                <el-progress type="circle" :percentage="Number.parseInt(percentList['MOVE_PERCENT'][scope.row.ID])"
+                             :width="50"
+                             :stroke-width="3"></el-progress>
+              </template>
+              <template v-else>
+                <div v-html="scope.row[tableHeader.index].value"></div>
+              </template>
+            </template>
+          </el-table-column>
+          <el-table-column :fixed="fixedColumn" :label="$t('financial.action')" width="180"> <!-- 操作 -->
+            <template slot-scope="scope">
+              <el-dropdown size="small" trigger="click"
+                           v-if="scope.row.AUDIT_STATUS!=='7' && (permission.hasPermission(`finance/withdraw-status`))">
+                <el-button type="primary" size="small" @click.stop="">
+                  {{ $t('financial.action') }}<i class="el-icon-arrow-down el-icon--right"></i>
+                </el-button>
+                <el-dropdown-menu slot="dropdown">
+                  <!--<el-dropdown-item command="add"-->
+                  <!--@click.native="handleAddInvoiceShow(scope.row)"-->
+                  <!--v-show="(scope.row.AUDIT_STATUS==='0'||scope.row.AUDIT_STATUS==='1') && (permission.hasPermission(`finance/invoice-audit-add`)||permission.hasPermission(`finance/invoice-audit-edit`))">-->
+                  <!--补录发票信息-->
+                  <!--</el-dropdown-item>-->
+                  <el-dropdown-item command="status"
+                                    @click.native="handleStatusShow(scope.row, 2, $t('financial.approveWithdrawalNotice'))"
+                                    v-show="scope.row.AUDIT_STATUS==='0' && permission.hasPermission(`finance/withdraw-status`)"> <!-- 确定对当前提现进行审核通过操作? -->
+                                    {{ $t('financial.approve') }} <!-- 审核通过 -->
+                  </el-dropdown-item>
+                  <el-dropdown-item command="status"
+                                    @click.native="handleStatusShow(scope.row, 3, $t('financial.setWithdrawalPaymentAction'))"
+                                    v-show="scope.row.AUDIT_STATUS === '2' && permission.hasPermission(`finance/withdraw-status`)"> <!-- 确定对当前提现进行设为待付款操作? -->
+                          {{ $t('financial.toBePaid') }}<!-- 设为待付款 -->
+                  </el-dropdown-item>
+                  <el-dropdown-item command="status"
+                                    @click.native="handleStatusShow(scope.row, 6, $t('financial.setWithdrawalPaidNotice'))"
+                                    v-show="scope.row.AUDIT_STATUS === '3' && permission.hasPermission(`finance/withdraw-status`)"> <!-- 确定对当前提现进行设为已付款操作 -->
+                          {{ $t('financial.paid') }}<!--设为已付款-->
+                  </el-dropdown-item>
+                  <el-dropdown-item command="status"
+                                    @click.native="handleStatusShow(scope.row, 3, $t('financial.setWithdrawalPaymentAction'))"
+                                    v-show="scope.row.AUDIT_STATUS === '4' && permission.hasPermission(`finance/withdraw-status`)"> <!-- 确定对当前提现进行设为待付款操作? -->
+                          {{ $t('financial.toBePaid') }}<!-- 设为待付款 -->
+                  </el-dropdown-item>
+                  <el-dropdown-item command="status"
+                                    @click.native="handleStatusShow(scope.row, 4, $t('financial.setPayFailedWithdrawal'), $t('common.note'))"
+                                    v-show="scope.row.AUDIT_STATUS === '6' && permission.hasPermission(`finance/withdraw-status`)"> <!-- 付款失败备注 --> <!-- 确定对当前提现进行设为付款失败操作? -->
+                          {{ $t('financial.withdrawSetFailed') }}<!-- 设为付款失败 -->
+                  </el-dropdown-item>
+                  <el-dropdown-item command="status"
+                                    @click.native="handleStatusShow(scope.row, 7, $t('financial.setWithdrawalReturnNotice'), $t('financial.noteWithdrawalReturn'))"
+                                    v-show="scope.row.AUDIT_STATUS === '0' && permission.hasPermission(`finance/withdraw-status`)"> <!-- 确定对当前提现进行设为提现退回操作? --> <!-- 提现退回备注 -->
+                                    {{ $t('financial.withdrawSetReturn') }} <!-- 设为提现退回 -->
+                  </el-dropdown-item>
+                  <el-dropdown-item command="status"
+                                    @click.native="handleStatusShow(scope.row, 7, $t('financial.memberInvoiceWithdrawalReturnNotice'), $t('financial.noteWithdrawalReturn'))"
+                                    v-show="(scope.row.AUDIT_STATUS === '1'||scope.row.AUDIT_STATUS === '2'||scope.row.AUDIT_STATUS === '3') && permission.hasPermission(`finance/withdraw-status`)"><!-- 提现退回备注 -->
+                                    {{ $t('financial.withdrawSetReturn') }} <!-- 该会员已提供发票,请确认是否处理提现退回 --> <!-- 设为提现退回 -->
+                  </el-dropdown-item>
+                </el-dropdown-menu>
+              </el-dropdown>
+            </template>
+          </el-table-column>
+        </el-table>
+        <div class="white-box-footer">
+          <el-dropdown  style="margin-right:10px;" size="small" trigger="click" @command="handleMuli"
+                       v-if="filterStatus!=='-1' && filterStatus!=='7' && (permission.hasPermission(`finance/withdraw-status`))">
+            <el-button type="primary" size="small">
+                {{ $t('financial.selectedData') }}<!--所选数据--><i class="el-icon-arrow-down el-icon--right"></i>
+            </el-button>
+            <el-dropdown-menu v-if="filterStatus==='0'" slot="dropdown">
+              <el-dropdown-item command="2">{{ $t('financial.batchAuditPassed') }}</el-dropdown-item> <!-- 批量审核通过-->
+              <el-dropdown-item command="7">{{ $t('financial.batchReturn') }}</el-dropdown-item> <!-- 批量退回 -->
+            </el-dropdown-menu>
+            <el-dropdown-menu v-else-if="filterStatus==='2'" slot="dropdown">
+              <el-dropdown-item command="3">{{ $t('financial.batchSetToBePaid') }}</el-dropdown-item><!-- 批量设为待付款 -->
+            </el-dropdown-menu>
+            <el-dropdown-menu v-else-if="filterStatus==='3'" slot="dropdown">
+              <el-dropdown-item command="6">{{ $t('financial.batchSetPaid') }}</el-dropdown-item><!--批量设为已付款-->
+              <el-dropdown-item command="7">{{ $t('financial.batchReturn') }}</el-dropdown-item><!--批量退回-->
+            </el-dropdown-menu>
+            <el-dropdown-menu v-else-if="filterStatus==='6'" slot="dropdown">
+              <el-dropdown-item command="4">{{ $t('financial.batchSetPaymentFailure') }}</el-dropdown-item><!--批量设为付款失败-->
+            </el-dropdown-menu>
+            <el-dropdown-menu v-else-if="filterStatus==='4'" slot="dropdown">
+              <el-dropdown-item command="3">{{ $t('financial.batchSetToBePaid') }}</el-dropdown-item><!-- 批量设为待付款 -->
+            </el-dropdown-menu>
+          </el-dropdown>
+  
+          <el-button type="success" size="small" @click="handleExport" style="margin-right:10px;"
+                     v-show="permission.hasPermission(`finance/transfer-list-export`)">{{ $t('common.exportExcel') }}
+          </el-button>
+          <pagination :total="totalCount" :page_size="pageSize" :page_sizes="pageSizes" @size-change="handleSizeChange"
+                      @current-change="handleCurrentChange"></pagination>
+          <el-dialog :title="$t('financial.modifyWithdrawalInfo')" :visible.sync="dialogEditFormVisible">
+            <el-form :model="form" label-width="150px"  v-loading="dialogEditLoading">
+              <el-form-item :label="$t('financial.memberCode')">
+                <el-input v-model="form.baseInfo.USER_NAME" :disabled="true"></el-input>
+              </el-form-item>
+              <el-form-item :label="$t('financial.memberName')">
+                <el-input v-model="form.baseInfo.REAL_NAME" :disabled="true"></el-input>
+              </el-form-item>
+              <el-form-item :label="$t('financial.idCardNumber')">
+                <el-input v-model="form.baseInfo.ID_CARD" :disabled="true"></el-input>
+              </el-form-item>
+              <el-form-item :label="$t('financial.registerType')">
+                <el-select v-model="form.baseInfo.REG_TYPE" :placeholder="$t('financial.pleaseSelectRegisterType')" :disabled="true">
+                  <el-option v-for="(item,key) in regTypes" :label="item.TYPE_NAME" :value="item.ID"
+                             :key="item.ID"></el-option>
+                </el-select>
+              </el-form-item>
+              <el-form-item :label="$t('financial.withdrawAmount')">
+                <el-input v-model="form.amount" :disabled="true"></el-input>
+              </el-form-item>
+              <el-form-item :label="$t('financial.estimatedDatePayment')" label-width="180"> <!-- 预计付款日期 -->
+                <el-date-picker
+                        v-model="form.planPaidAt"
+                        type="date"
+                        :placeholder="$t('financial.selectDate')"
+                        value-format="yyyy-MM-dd"
+                        :picker-options="pickerOptions0"
+                >
+                </el-date-picker>
+              </el-form-item>
+              <el-form-item :label="$t('table.remark')"> <!-- 备注 -->
+                <el-input v-model="form.createRemark"></el-input>
+              </el-form-item>
+            </el-form>
+            <div slot="footer" class="dialog-footer">
+              <el-button @click="dialogEditFormVisible = false">{{ $t('common.cancel') }}<!-- 取 消 --></el-button>
+              <el-button type="primary" @click.native="handleEdit">{{ $t('common.edit') }}<!-- 修 改 --></el-button>
+            </div>
+          </el-dialog><!--修改提现信息-->
+          <el-dialog :title="$t('financial.reviewWithdrawalInfoNotice')" :visible.sync="dialogAuditFormVisible"> <!-- 审核提现信息 -->
+            <el-alert
+                    :title="auditForm.auditTips"
+                    type="warning" :closable="false">
+            </el-alert>
+            <el-form :model="auditForm"  v-loading="dialogAuditLoading">
+              <el-form-item :label="$t('financial.estimatedDatePayment')" v-show="filterStatus==='2' || filterStatus==='4'"> <!-- 预计付款日期 -->
+                <el-date-picker
+                        v-model="auditForm.planPaidAt"
+                        type="date"
+                        :placeholder="$t('financial.selectDate')"
+                        value-format="yyyy-MM-dd"
+                        :picker-options="pickerOptions0"
+                >
+                </el-date-picker>
+              </el-form-item>
+              <el-form-item :label="$t('financial.datePayment')" v-show="filterStatus==='3'"><!-- 付款日期 -->
+                <el-date-picker
+                        v-model="auditForm.paidAt"
+                        type="date"
+                        :placeholder="$t('financial.selectDate')"
+                        value-format="yyyy-MM-dd"
+                        :picker-options="pickerOptions1"
+                >
+                </el-date-picker>
+              </el-form-item>
+              <el-form-item :label="auditRemark">
+                <el-input v-model="auditForm.createRemark"></el-input>
+              </el-form-item>
+            </el-form>
+            <div slot="footer" class="dialog-footer">
+              <el-button @click="dialogAuditFormVisible = false">{{ $t('common.cancel') }}<!-- 取 消 --></el-button>
+              <el-button type="primary" @click.native="handleStatus">{{ $t('common.submit') }}<!-- 提 交 --></el-button>
+            </div>
+          </el-dialog>
+        </div>
+      </div>
+    </div>
+  </template>
+  
+  <script>
+  import permission from '@/utils/permission'
+  import tool from '@/utils/tool'
+  import FilterUser from '@/components/FilterUser'
+  import baseInfo from '@/utils/baseInfo'
+  import Pagination from '@/components/Pagination'
+  import filterHelper from '@/utils/filterHelper'
+  import { withdrawList, withdrawExport, multPoint, postWithdrawStatus } from '@/api/finance'
+  import {getOperatingSystem} from "@/utils"
+
+  export default {
+    name: 'finance_withdraw',
+    components: {FilterUser, Pagination},
+  
+    data () {
+      return {
+        fixedColumn:false, // 固定,当手机端不固定,pc固定
+        activeName: 'all',
+        tableHeaders: null,
+        baseDecLevels: baseInfo.decLevels(),
+        allData: null,
+        tableData: null,
+        loading: true,
+        multipleSelection: [],
+        currentPage: 1,
+        totalPages: 1,
+        totalCount: 1,
+        pageSize: 20,
+        pageSizes:  [1, 2, 5, 10, 20, 50, 100],
+        tool: tool,
+        permission: permission,
+        regTypes: baseInfo.regTypes(),
+        dialogEditFormVisible: false,
+        dialogEditLoading: false,
+        dialogAuditFormVisible: false,
+        dialogAuditLoading: false,
+        dialogAddInvoiceVisible: false,
+        dialogAddInvoiceLoading: false,
+        auditId: null,
+        form: {
+          id: null,
+          baseInfo: {USER_NAME: null, REG_TYPE: null},
+          amount: null,
+          planPaidAt: null,
+          paidAt: new Date(),
+          createRemark: null,
+        },
+        invoiceForm: {
+          id: null,
+          withdrawId: null,
+          withdrawSn: null,
+          invoiceCode: null,
+          invoiceNum: null,
+          invoiceDate: null,
+          amount: null,
+          taxRate: null,
+          purchaserName: null,
+          purchaserRegisterNum: null,
+          purchaserAddress: null,
+          purchaserBank: null,
+          sellerName: null,
+          sellerRegisterNum: null,
+          sellerAddress: null,
+          sellerBank: null,
+          itemName: null,
+          invoiceRemark: null,
+          createRemark: null,
+        },
+        pickerOptions0: {
+          disabledDate(time) {
+            return time.getTime() < Date.now();
+          }
+        },
+        pickerOptions1: {
+          disabledDate(time) {
+            return time.getTime() < Date.now() - 8.64e7;
+          }
+        },
+        auditRemark: '',
+        auditForm: {
+          auditTips: '',
+          auditStatus: null,
+          selectedIds: [],
+          planPaidAt: null,
+          createRemark: null,
+          withdrawAudit: '',
+        },
+        auditTips: '',
+        filterTypes: {},
+        filterModel: {},
+        excelForm: {
+          rowCount: '',
+        },
+        filterStatus: '0',
+      }
+    },
+    mounted () {
+      this.getData();
+      let system =  getOperatingSystem()
+        if (system == "Android" || system == 'ios') {
+            this.fixedColumn = false
+        } else {
+            this.fixedColumn = 'right'
+        }
+      // if (permission.hasPermission(`finance/withdraw-7`)) {
+      //   this.activeName = 'seven'
+      // }
+      // if (permission.hasPermission(`finance/withdraw-4`)) {
+      //   this.activeName = 'four'
+      // }
+      // if (permission.hasPermission(`finance/withdraw-6`)) {
+      //   this.activeName = 'six'
+      // }
+      // if (permission.hasPermission(`finance/withdraw-3`)) {
+      //   this.activeName = 'three'
+      // }
+      // if (permission.hasPermission(`finance/withdraw-2`)) {
+      //   this.activeName = 'two'
+      // }
+      // if (permission.hasPermission(`finance/withdraw-1`)) {
+      //   this.activeName = 'one'
+      // }
+      // if (permission.hasPermission(`finance/withdraw-0`)) {
+      //   this.activeName = 'zero'
+      // }
+      // if (permission.hasPermission(`finance/withdraw-0`) && permission.hasPermission(`finance/withdraw-1`) && permission.hasPermission(`finance/withdraw-2`) && permission.hasPermission(`finance/withdraw-3`) && permission.hasPermission(`finance/withdraw-6`) && permission.hasPermission(`finance/withdraw-4`) && permission.hasPermission(`finance/withdraw-7`)) {
+      //   this.activeName = 'all'
+      // }
+    },
+  
+    methods: {
+      handleMuli (command) {
+        if (this.multipleSelection.length < 1) {
+          this.$message({
+            message: this.$t('financial.selectRecordOperateNotice'), // 请选择要操作的记录
+            type: 'warning'
+          })
+          return;
+        }
+        this.handleAudit(null, command)
+      },
+      handleAudit (row = null, status) {
+        let title = ''
+        if (status === '2') {
+          title = this.$t('financial.surePassReviewNoteNotice') // 确定要通过审核?备注:
+        }else if(status === '3') {
+          title = this.$t('financial.sureUnpaidReviewNotice') // 确定要设为待付款?备注:
+        }else if(status === '4') {
+          title = this.$t('financial.surePaymentFailureReview')// 确定要设为付款失败?备注:
+        }else if(status === '6') {
+          title = this.$t('financial.surePaidReviewNotice')// 确定要设为已付款?备注:
+        }else if(status === '7') {
+          title = this.$t('financial.sureReturnReviewNotice')//确定要设为已退回?备注:
+        }
+        this.handleStatusShow(row,status,title);
+      },
+      handleExpand (row, event, column) {
+        this.$refs.multipleTable.toggleRowExpansion(row)
+      },
+      handleExport () {
+        let filterData = this.filterModel
+        // 如果有选中,导出选中ID,否则导出全部
+        if (this.multipleSelection.length > 0) {
+          let selectedIds = []
+          for (let val of this.multipleSelection) {
+            selectedIds.push(val.ID)
+          }
+          filterData.selectedIds = selectedIds
+        }
+        this.$confirm(this.$t('financial.exportNotice'), this.$t('common.hint'), {
+          confirmButtonText:  this.$t('common.confirm'), // 确定
+          cancelButtonText: this.$t('common.cancel'), // 取消
+          type: 'warning'
+        }).then(() => {
+            withdrawExport(filterData).then(response => {
+                this.$message({
+                    message: response.data,
+                    type: 'success'
+                })
+            }).catch(err => {
+                this.$message({
+                    message: err,
+                    type: 'error'
+                })
+            })
+        })
+      },
+      handleAdd () {
+        this.$router.push({path: `/finance/withdraw-add`})
+      },
+      handleExcel () {
+      },
+      handleExcelPaidFalse () {
+        window.open(CDN_BASE_URL + `/files/bonus_withdraw_paid_false.xlsx`)
+      },
+      handleEditShow (row) {
+        this.dialogEditLoading = true
+        this.auditId = row.ID
+        this.dialogEditFormVisible = true
+        let vueObj = this
+        network.getData('finance/withdraw-get', {id: this.auditId}).then(response => {
+          vueObj.dialogEditLoading = false
+          vueObj.form = response
+        })
+      },
+      handleEdit () {
+        this.dialogEditFormVisible = false
+        this.$message({
+          message: this.$t('financial.modifyData'),//正在修改数据
+          type: 'info'
+        })
+        this.loading = true
+        let path = 'finance/withdraw-edit'
+        network.postData(path, this.form).then(response => {
+          this.$message({
+            message: response,
+            type: 'success'
+          })
+          this.getData(this.currentPage, this.pageSize)
+        }).catch(response => {
+        })
+      },
+      handleStatusShow(row, status, title, remark = this.$t('table.remark')) { // 备注
+        this.auditForm = {
+          auditTips: '',
+          auditStatus: null,
+          selectedIds: [],
+          planPaidAt: null,
+          paidAt: new Date(),
+          remark: null,
+        }
+        if (row === null) {
+          for (let val of this.multipleSelection) {
+            this.auditForm.selectedIds.push(val.ID)
+          }
+        } else {
+          this.auditForm.selectedIds.push(row.ID)
+        }
+        if (this.auditForm.selectedIds.length === 0) {
+          this.$message({
+            message: this.$t('financial.selectRecordOperateNotice'),// 请选择数据
+            type: 'warning'
+          })
+          return
+        }
+        this.auditRemark = remark
+        this.dialogAuditFormVisible = true
+        this.auditForm.auditTips = title
+        this.auditForm.auditStatus = status
+      },
+      handleStatus () {
+        multPoint({opType: 2}).then(response => {
+            this.auditForm.withdrawAudit = response.data.withdrawAudit
+            this.$confirm(this.$t('financial.changeStateSelectedDataNotice'), this.$t('common.hint'), {
+                confirmButtonText: this.$t('common.confirm'),
+                cancelButtonText: this.$t('common.cancel'),
+                type: 'warning'
+            }).then(() => {
+                postWithdrawStatus(this.auditForm).then(response => {
+                    this.dialogAuditFormVisible = false
+                    this.$message({
+                        message: response.data,
+                        type: 'success'
+                    })
+                    this.getData(this.currentPage, this.pageSize)
+                }).catch(err => {
+                    this.dialogAuditFormVisible = false
+                    this.$message({
+                        message: err,
+                        type: 'error'
+                    })
+                })
+          })
+        })
+      },
+      handleAddInvoiceShow (row) {
+        this.dialogAddInvoiceVisible = true
+        this.auditId = row.INVOICE_ID
+        this.dialogAddInvoiceLoading = true
+        let vueObj = this
+        network.getData('finance/invoice-audit-get', {id: this.auditId}).then(response => {
+          vueObj.dialogAddInvoiceLoading = false
+          vueObj.invoiceForm = response
+          this.invoiceForm.withdrawSn = row.SN
+          this.invoiceForm.withdrawId = row.ID
+        })
+      },
+      handleAddInvoice () {
+        let path = 'finance/invoice-audit-add'
+        if (this.invoiceForm.id) path = 'finance/invoice-audit-edit'
+        network.postData(path, this.invoiceForm).then(response => {
+          this.$message({
+            message: response,
+            type: 'success'
+          })
+          this.dialogAddInvoiceVisible = false
+          this.getData(this.currentPage, this.pageSize)
+        }).catch(response => {
+        })
+      },
+      handleSelectionChange(val) {
+        this.multipleSelection = val
+      },
+      handleCurrentChange(page) {
+        this.getData(page, this.pageSize)
+      },
+      handleSizeChange(pageSize) {
+        this.getData(this.currentPage, pageSize)
+      },
+      handleFilterStatusClick(tab, event) {
+        filterHelper.clearFilterOption(this)
+        this.getData()
+      },
+      handleFilterUser(filterData) {
+        filterHelper.handleFilterUser(this, filterData)
+      },
+      handleFilter() {
+        this.getData()
+      },
+      getData(page, pageSize) {
+        let filterData = this.filterModel
+        filterData.filterStatus = this.filterStatus != '-1' ? `=,${this.filterStatus}` : ''
+        let vueObj = this
+        const paramsData = Object.assign({
+        page: (page === null || page == undefined) ? 1 : page,
+        pageSize: (pageSize === null || pageSize == undefined) ? vueObj.pageSize : pageSize
+        }, filterData)
+        withdrawList(paramsData).then(response => {
+            vueObj.tableHeaders = response.data.columnsShow ? response.data.columnsShow : []
+            vueObj.tableData = response.data.list
+            vueObj.filterTypes = response.data.filterTypes
+            vueObj.currentPage = page
+            vueObj.totalPages = parseInt(response.data.totalPages)
+            vueObj.totalCount = parseInt(response.data.totalCount)
+            vueObj.pageSize = pageSize
+            this.loading = false
+        }).catch(err => {
+            console.log('err=============' + err)
+            this.loading = false
+        })
+      },
+      onMessageCallback() {
+        this.getData(this.currentPage, this.pageSize)
+      },
+    }
+  }
+  </script>
+  
+  <style scoped>
+  /deep/ .el-date-editor.el-input {
+    width:100% !important;
+  }
+ 
+  </style>
+  

+ 8 - 7
src/views/log/user-login.vue

@@ -20,7 +20,7 @@
       </el-table-column>
     </el-table>
     <div class="white-box-footer">
-      <el-button v-show="permission.hasPermission(`v1/log/user-login-export`)" type="success" size="small" @click="handleExport">Export Excel<!-- 导出Excel --></el-button>
+      <el-button v-show="permission.hasPermission(`v1/log/user-login-export`)" type="success" size="small" @click="handleExport">{{$t('common.exportExcel')}}<!-- 导出Excel --></el-button>
       <pagination
         :total="totalCount"
         :page_size="pageSize"
@@ -38,6 +38,7 @@ import { fetchUserLoginList, fetchUserLoginExport } from '@/api/log'
 import filterHelper from '@/utils/filterHelper'
 import FilterUser from '@/components/FilterUser'
 import Pagination from '@/components/Pagination'
+import ElementUI from 'element-ui'
 
 export default {
   name: 'LogAdminLogin',
@@ -94,19 +95,19 @@ export default {
       this.getData()
     },
     handleExport() {
-      this.$confirm(`Are you sure you want to export the current data?`, 'Hint', { // `确定要导出当前数据吗?`, '提示',
-        confirmButtonText: 'confirm', // 确定
-        cancelButtonText: 'cancel', // 取消
+       this.$confirm(this.$t('common.exportCurrentData'), this.$t('common.notice'), {  // `确定要导出当前数据吗?`, '提示',
+      confirmButtonText: this.$t('common.confirm'), // 确定
+      cancelButtonText: this.$t('common.cancel'), // 取消
         type: 'warning'
       }).then(() => {
         return fetchUserLoginExport(this.filterModel)
       }).then(response => {
         this.$message({
-          message: response,
+          message: response.data,
           type: 'success'
         })
-      }).catch(response => {
-
+      }).catch((error) => {
+          ElementUI.Message({type: 'error', message: error.message, showClose: true, duration: 0})
       })
     }
   }