lisiyan 9 місяців тому
батько
коміт
a13fdbc8db

+ 1 - 1
src/assets/scss/common.scss

@@ -201,7 +201,7 @@ input:-ms-input-placeholder {
     text-decoration: underline;
   }
 }
-@media screen and (max-width: 429px) {
+@media screen and (max-width: 930px) {
   h1 {
     font-size: 20px;
     line-height: 24px;

+ 23 - 1
src/assets/scss/element-variables.scss

@@ -51,7 +51,13 @@ $--font-path: '~element-ui/lib/theme-chalk/fonts';
 }
 // 按钮
 .el-button--primary {
+  border-color: #1665FF;
   background: #1665FF;
+  &.is-disabled {
+    opacity: 0.4;
+    background-color: #396FFA;
+    border-color: #396FFA;
+  }
 }
 // 勾选框
 .el-checkbox {
@@ -212,6 +218,12 @@ $--font-path: '~element-ui/lib/theme-chalk/fonts';
         }
         &:last-child {
           margin-left: 12px;
+          border-color: #1665FF !important;
+          background-color: #1665FF !important;
+          &:hover {
+            background: #66b1ff !important;
+            border-color: #66b1ff !important;
+          }
         }
       }
     }
@@ -226,8 +238,18 @@ $--font-path: '~element-ui/lib/theme-chalk/fonts';
       }
     }
   }
+  .el-table__header-wrapper {
+    .el-table__header {
+      .el-table__cell {
+        .cell {
+          word-break: normal;
+          white-space: normal;
+        }
+      }
+    }
+  }
   th.el-table__cell {
-    padding: 16px 0;
+    padding: 16px;
     font-size: 14px;
     font-weight: 600;
     line-height: 20px;

+ 6 - 6
src/components/calendar/calendar.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="calender-wrap">
+  <div class="calender-wrap" @click.stop>
     <div class="calender">
       <div class="top">
         <img src="@/assets/images/dashboard/calendar_icon.svg" alt="calendar_icon">
@@ -9,9 +9,9 @@
       </div>
 
       <div class="title">
-        <div class="btn btn-left" @click="last()"><img src="@/assets/images/dashboard/calendar_arrow.svg" alt="calendar_arrow"></div>
+        <div class="btn btn-left" @click.stop="last()"><img src="@/assets/images/dashboard/calendar_arrow.svg" alt="calendar_arrow"></div>
         <div class="text">{{ dataTime }}</div>
-        <div class="btn btn-right" @click="next()"><img src="@/assets/images/dashboard/calendar_arrow.svg" alt="calendar_arrow"></div>
+        <div class="btn btn-right" @click.stop="next()"><img src="@/assets/images/dashboard/calendar_arrow.svg" alt="calendar_arrow"></div>
       </div>
 
       <div class="head">
@@ -24,7 +24,7 @@
             $t('calendar.week.Wed'),
             $t('calendar.week.Thur'),
             $t('calendar.week.Fri'),
-            $t('calendar.week.Sat'),
+            $t('calendar.week.Sat')
           ]"
           :key="index"
         >
@@ -42,7 +42,7 @@
             >
           <div
             class="span"
-            @click="click(item.count)"
+            @click.stop="click(item.count)"
             :class="
               item.count == ''
                 ? 'empty'
@@ -63,7 +63,7 @@
       </div>
 
       <div class="bottom-btn">
-        <button class="sure-btn" :class="{'disabled': startTime === '' || endTime === ''}" @click="firm()">{{ $t('dashboard.customDate') }}</button>
+        <button class="sure-btn" :class="{'disabled': startTime === '' || endTime === ''}" @click.stop="firm()">{{ $t('dashboard.customDate') }}</button>
       </div>
     </div>
   </div>

+ 11 - 5
src/components/common/Aside.vue

@@ -48,7 +48,7 @@
           </el-submenu>
         </el-menu>
       </div>
-      <div @click.stop="changeLangEvent" class="switch">
+      <div @click.stop="languageActive = !languageActive" class="switch">
         <div class="choose" :class="languageActive && 'chooseActive'">
           <p  @click.stop="changeLangEvent('en')">English</p>
           <p @click.stop="changeLangEvent('zh-cn')">简体中文</p>
@@ -158,7 +158,6 @@ export default class Aside extends Vue {
   }
 
   changeLangEvent (val: string) {
-    this.languageActive = !this.languageActive
     if (val === 'en') {
       i18n.locale = 'en'
       localStorage.setItem('locale', 'en')
@@ -166,6 +165,8 @@ export default class Aside extends Vue {
       i18n.locale = 'zh-cn'
       localStorage.setItem('locale', 'zh-cn')
     }
+    this.languageActive = false
+    this.$router.go(0)
   }
 }
 </script>
@@ -173,6 +174,7 @@ export default class Aside extends Vue {
 <style lang="scss" scoped>
 .aside .max {
   display: block;
+  padding: 40px 20px 0;
 }
 .aside .min {
   display: none;
@@ -184,14 +186,16 @@ export default class Aside extends Vue {
     flex-direction: column;
     justify-content: space-between;
     .switch {
+      bottom: 0;
       left: 70px;
-      bottom: 36px;
       display: flex;
       cursor: pointer;
       position: sticky;
+      padding: 12px 0;
       align-items: center;
-      margin-bottom: 36px;
+      background: white;
       justify-content: center;
+      border-top: 1px solid #E1E3E8;
       .sideBox {
         display: flex;
         max-width: 120px;
@@ -240,7 +244,6 @@ export default class Aside extends Vue {
   min-width: 260px;
   max-width: 260px;
   min-height: 100%;
-  padding: 40px 20px 0;
   background-color: #fff;
   ::v-deep .el-submenu {
     .el-submenu__title {
@@ -294,6 +297,9 @@ export default class Aside extends Vue {
   width: 100%;
   display: inline-block;
   color: rgb(102, 102, 102);
+  &:hover {
+    color: #396FFA;
+  }
 }
 @media screen and (max-width: 767px) {
   .aside {

+ 1 - 1
src/components/common/Header.vue

@@ -84,7 +84,7 @@ export default Vue.extend({
       this.dropdownShow = false
     },
     loginOut () {
-      apiLoginOut({}).then(res => {
+      apiLoginOut({}).then(() => {
         loginStore().setAuth(false)
         Cookie.remove('access_token')
         window.location.href = this.apiDomain

+ 7 - 7
src/crypto/crypto.js

@@ -7,11 +7,11 @@ export default { // 加密
    * @param {*} keyStr
    */
   set (word) {
-    var keyStr = 'abcdef0123456789' // 16位的密钥,自己定义,和下面的密钥要相同
-    var srcs = CryptoJS.enc.Utf8.parse(word) // 字符串到数组转换,解析明文
-    var key = CryptoJS.enc.Utf8.parse(keyStr) // 字符串到数组转换,解析秘钥
+    const keyStr = 'abcdef0123456789' // 16位的密钥,自己定义,和下面的密钥要相同
+    const srcs = CryptoJS.enc.Utf8.parse(word) // 字符串到数组转换,解析明文
+    const key = CryptoJS.enc.Utf8.parse(keyStr) // 字符串到数组转换,解析秘钥
     // mode:加密方式;padding:填充方式;iv便宜向量(可选)
-    var encrypted = CryptoJS.AES.encrypt(srcs, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 })
+    const encrypted = CryptoJS.AES.encrypt(srcs, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 })
     return encrypted.toString() // 加密后的结果是对象,要转换为文本
   },
 
@@ -21,9 +21,9 @@ export default { // 加密
    * @param {*} keyStr
    */
   get (word) {
-    var keyStr = 'abcdef0123456789'
-    var key = CryptoJS.enc.Utf8.parse(keyStr) // 字符串到数组转换
-    var decrypt = CryptoJS.AES.decrypt(word, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 })
+    const keyStr = 'abcdef0123456789'
+    const key = CryptoJS.enc.Utf8.parse(keyStr) // 字符串到数组转换
+    const decrypt = CryptoJS.AES.decrypt(word, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 })
     return CryptoJS.enc.Utf8.stringify(decrypt).toString() // 数组到字符串转换
   }
 }

+ 24 - 14
src/locales/en.ts

@@ -55,17 +55,24 @@ export default {
       'HTML to PDF': 'HTML to PDF',
       'RTF to PDF': 'RTF to PDF',
       'CSV to PDF': 'CSV to PDF',
-      'PDF to Split': 'PDF to Split',
-      'PDF to Merge': 'PDF to Merge',
-      'PDF Delete': 'PDF Delete',
-      'PDF Extract': 'PDF Extract',
-      'PDF Rotation': 'PDF Rotation',
-      'PDF Compress': 'PDF Compress',
-      'PDF Insert': 'PDF Insert',
-      'PDF AddWatermark': 'PDF AddWatermark',
-      'PDF DelWatermark': 'PDF DelWatermark',
+      'PDF to Split': 'Split PDF',
+      'PDF to Merge': 'Merge PDF',
+      'PDF Insert': 'Insert PDF',
+      'PDF Delete': 'Delete PDF',
+      'PDF Extract': 'Extract PDF',
+      'PDF Rotation': 'Rotate PDF',
+      'PDF Compress': 'Compress PDF',
+      'PDF AddWatermark': 'PDF Overlay Comparison',
+      'PDF DelWatermark': 'PDF Content Comparison',
       'PDF CoverCompare': 'PDF CoverCompare',
-      'PDF ContentCompare': 'PDF ContentCompare'
+      'PDF ContentCompare': 'PDF ContentCompare',
+      'PDF to Json': 'PDF to Json',
+      'DocumentAI OCR': 'OCR',
+      'DocumentAI MagicColor': 'Image Processing',
+      'DocumentAI TableRec': 'Form Recognizer',
+      'DocumentAI LayoutAnalysis': 'Layout Analysis',
+      'DocumentAI Dewarp': 'Trim Correction',
+      'DocumentAI DetectionStamp': 'Stamp Inspection'
     }
   },
   calendar: {
@@ -97,6 +104,8 @@ export default {
     title: 'API Keys',
     projectsKeys: 'Projects and Keys',
     projectName: 'Project Name',
+    'Default Project': 'Default Project',
+    projectBlank: 'Project name cannot be blank',
     publicKey: 'Public Key',
     secretKey: 'Secret Key',
     creationDate: 'Creation Date',
@@ -215,6 +224,7 @@ export default {
     'Package Files': 'Package Files',
     'Files Expired': 'Files Expired',
     'Files consumed': 'Files consumed',
+    'Files Consumed': 'Files consumed',
     previous: 'Previous',
     next: 'Next'
   },
@@ -227,7 +237,7 @@ export default {
     lastName: 'Last Name',
     lastNameTip: 'Please enter your last name',
     lastNameErr: 'Ensure your last name is under 255 characters in length.',
-    company: 'Company Name',
+    company: 'Company',
     companyTip: 'Please enter your company name',
     companyErr: 'Ensure your company name is under 255 characters in length.',
     address: 'Company Address',
@@ -235,14 +245,14 @@ export default {
     addressErr: 'Ensure your company address is under 255 characters in length.',
     country: 'Country',
     countryTip: 'Scroll down to select country',
-    province: 'State/Province',
+    province: 'State / Province',
     provinceTip: 'Please enter your state/province',
     provinceErr: 'Ensure your state/province is under 255 characters in length.',
-    zip: 'Postal Code',
+    zip: 'ZIP / Postal Code',
     zipTip: 'Please enter your postal code',
     update: 'Update',
     mail: 'Billing Mail Address',
-    email: '* E-Mail Address',
+    email: 'E-Mail Address',
     emailTip: 'Please enter your email address',
     emailFormatErr: 'Email format is incorrect. Please enter a valid email address.',
     emailContact: ['This billing email address is only used for receiving invoices. If you need a paper invoice, please ', 'contact us'],

+ 17 - 7
src/locales/zh.ts

@@ -43,10 +43,10 @@ export default {
     },
     allTools: '所有工具',
     tools: {
-      'Office to PDF': 'Office to PDF',
+      'Office to PDF': 'Office  PDF',
       'PNG to PDF': 'PNG 转 PDF',
       'TXT to PDF': 'TXT 转 PDF',
-      'PDF to Image': 'PDF 转 Image',
+      'PDF to Image': 'PDF 转 图片',
       'PDF to Office': 'PDF 转 Office',
       'PDF to TXT': 'PDF 转 TXT',
       'PDF to HTML': 'PDF 转 HTML',
@@ -65,7 +65,14 @@ export default {
       'PDF AddWatermark': '添加水印',
       'PDF DelWatermark': '删除水印',
       'PDF CoverCompare': '覆盖对比',
-      'PDF ContentCompare': '内容对比'
+      'PDF ContentCompare': '内容对比',
+      'PDF to Json': 'PDF 转 Json',
+      'DocumentAI OCR': 'OCR',
+      'DocumentAI MagicColor': '图像处理',
+      'DocumentAI TableRec': '表格识别',
+      'DocumentAI LayoutAnalysis': '版面分析',
+      'DocumentAI Dewarp': '修边校正',
+      'DocumentAI DetectionStamp': '印章检测'
     }
   },
   calendar: {
@@ -97,6 +104,8 @@ export default {
     title: 'API 密钥',
     projectsKeys: '项目和密钥',
     projectName: '项目名称',
+    'Default Project': '默认项目',
+    projectBlank: '项目名称不能为空',
     publicKey: '公钥',
     secretKey: '密钥',
     creationDate: '创建日期',
@@ -210,11 +219,12 @@ export default {
     'Free Files': '免费文档数',
     'Free files': '免费文档数',
     'Free 100 Files(Validity: 30 days)': '免费文档数',
-    'Monthly Subscription Files': '按月订购文档',
-    'Annually Subscription Files': '按年订购文档',
+    'Monthly Subscription Files': '月订阅文档数',
+    'Annually Subscription Files': '年订阅文档数',
     'Package Files': '套餐包文档数',
-    'Files Expired': '文档数已过期',
+    'Files Expired': '过期文档数',
     'Files consumed': '已消耗文档数',
+    'Files Consumed': '已消耗文档数',
     previous: '上一页',
     next: '下一页'
   },
@@ -227,7 +237,7 @@ export default {
     lastName: '名',
     lastNameTip: '请输入您的名字',
     lastNameErr: '请确保输入内容长度不超过255个字符。',
-    company: '公司',
+    company: '公司',
     companyTip: '请输入您的公司名',
     companyErr: '请确保输入内容长度不超过255个字符。',
     address: '公司地址',

+ 2 - 2
src/request/http.ts

@@ -4,11 +4,11 @@
  */
 import Vue from 'vue'
 import axios from 'axios'
-import QS from 'qs'
+// import QS from 'qs'
 import pinia from '@/store/index'
 import { loginStore } from '@/store/loginStore'
 // import { Message } from 'element-ui'
-import router from '../router'
+// import router from '../router'
 
 const store = loginStore(pinia)
 

+ 0 - 1
src/router/index.ts

@@ -1,7 +1,6 @@
 import Vue from 'vue'
 import VueRouter, { RouteConfig } from 'vue-router'
 import { loginStore } from '@/store/loginStore'
-import pinia from '@/store/index'
 import dashboard from '@/views/projects/dashboard.vue'
 import login from '@/views/login.vue'
 import security from '@/views/accountSettings/security.vue'

+ 1 - 1
src/utils/country.js

@@ -1,5 +1,5 @@
 export function country () {
-  var country =
+  const country =
     [
       { name: 'Afghanistan', code: 'AF' },
       { name: 'Åland Islands', code: 'AX' },

+ 13 - 5
src/views/accountSettings/security.vue

@@ -80,6 +80,12 @@ interface isUserNameRuleForm{
 }
 @Component
 export default class Security extends Vue {
+  created () {
+    this.$watch('$i18n.locale', () => {
+      this.$router.go(0)
+    })
+  }
+
   ruleForm:isRuleForm = {
     oldPassword: '',
     newPassword: '',
@@ -133,17 +139,17 @@ export default class Security extends Vue {
 
   // 监视属性
   @Watch('ruleFormOld')
-  noValue1change (newVal:string, oldVal:string) {
+  noValue1change () {
     this.showErrTipOld = false
   }
 
   @Watch('ruleFormNew')
-  noValue2change (newVal:string, oldVal:string) {
+  noValue2change () {
     this.showErrTipNotMatch = false
   }
 
   @Watch('ruleFormConfirm')
-  noValue3change (newVal:string, oldVal:string) {
+  noValue3change () {
     this.showErrTipNotMatch = false
   }
 
@@ -162,7 +168,8 @@ export default class Security extends Vue {
             password_confirm: this.ruleForm.confirmPassword
           }, {}).then((res: any) => {
             if (res.code === 200) {
-              this.changedSuccessBox()
+              const url = window.location.href
+              window.location.href = process.env.VUE_APP_PDFSdk_DOMAIN + '/login?from=api&redirect=' + url
             } else if (res.code === 500) {
               if (res.message === 'Incorrect Old Password.' || res.message === 'Cannot Match Old Password.') {
                 this.showErrTipOld = true
@@ -254,9 +261,10 @@ export default class Security extends Vue {
 
   // 校验密码是否与确认密码相同
   validPassword () {
+    const fail: any = this.$t('security.changedFail')
     if (this.ruleForm.newPassword !== this.ruleForm.confirmPassword) {
       this.showErrTipNotMatch = true
-      this.$message.error('Changed Failed!')
+      this.$message.error(fail)
     }
   }
 

+ 18 - 15
src/views/billing/information.vue

@@ -4,20 +4,24 @@
     <div class="password-form block">
       <h2>{{ $t('information.billing') }}</h2>
       <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-position="top" label-width="100px" inline-message>
-        <el-form-item prop="lastName" :label="$t('information.lastName')">
-          <el-input @input="submitBtnState('ruleForm')" @focus="clear('ruleForm', 'lastName')" v-model.trim="ruleForm.lastName" auto-complete="off" :placeholder="$t('information.lastNameTip')"
-          ></el-input>
-        </el-form-item>
         <el-form-item prop="firstName" :label="$t('information.firstName')">
           <el-input @input="submitBtnState('ruleForm')" @focus="clear('ruleForm', 'firstName')" v-model.trim="ruleForm.firstName" auto-complete="off" :placeholder="$t('information.firstNameTip')"
           ></el-input>
         </el-form-item>
+        <el-form-item prop="lastName" :label="$t('information.lastName')">
+          <el-input @input="submitBtnState('ruleForm')" @focus="clear('ruleForm', 'lastName')" v-model.trim="ruleForm.lastName" auto-complete="off" :placeholder="$t('information.lastNameTip')"
+          ></el-input>
+        </el-form-item>
         <el-form-item prop="company" :label="$t('information.company')">
           <el-input @input="submitBtnState('ruleForm')" @focus="clear('ruleForm', 'company')" v-model.trim="ruleForm.company" auto-complete="off" :placeholder="$t('information.companyTip')"
           ></el-input>
         </el-form-item>
+        <el-form-item prop="address" :label="$t('information.address')">
+          <el-input @input="submitBtnState('ruleForm')" @focus="clear('ruleForm', 'address')" v-model.trim="ruleForm.address" auto-complete="off" :placeholder="$t('information.addressTip')"
+          ></el-input>
+        </el-form-item>
         <el-form-item :label="$t('information.country')">
-          <el-select v-model="ruleForm.country" :placeholder="$t('information.countryTip')" class="w-full">
+          <el-select v-model="ruleForm.country" filterable :placeholder="$t('information.countryTip')" @change="submitBtnState('ruleForm')" class="w-full">
             <el-option v-for="item in countryList" :key="item.value" :label="item.name" :value="item.name"></el-option>
           </el-select>
         </el-form-item>
@@ -25,10 +29,6 @@
           <el-input @input="submitBtnState('ruleForm')" @focus="clear('ruleForm', 'province')" v-model.trim="ruleForm.province" auto-complete="off" :placeholder="$t('information.provinceTip')"
           ></el-input>
         </el-form-item>
-        <el-form-item prop="address" :label="$t('information.address')">
-          <el-input @input="submitBtnState('ruleForm')" @focus="clear('ruleForm', 'address')" v-model.trim="ruleForm.address" auto-complete="off" :placeholder="$t('information.addressTip')"
-          ></el-input>
-        </el-form-item>
         <el-form-item :label="$t('information.zip')">
           <el-input @input="submitBtnState('ruleForm')" v-model.trim="ruleForm.zip" auto-complete="off" :placeholder="$t('information.zipTip')"
           ></el-input>
@@ -72,6 +72,13 @@ interface isEmailRuleForm{
 }
 @Component
 export default class Security extends Vue {
+  created () {
+    this.getBillingInfo()
+    this.$watch('$i18n.locale', () => {
+      this.$router.go(0)
+    })
+  }
+
   ruleForm:isRuleForm = {
     firstName: '',
     lastName: '',
@@ -113,20 +120,16 @@ export default class Security extends Vue {
       {
         required: true,
         message: this.$t('information.emailTip'),
-        trigger: ['']
+        trigger: 'blur'
       },
       {
         type: 'email',
         message: this.$t('information.emailFormatErr'),
-        trigger: ['']
+        trigger: 'blur'
       }
     ]
   }
 
-  created () {
-    this.getBillingInfo()
-  }
-
   pdfSDKDomain = process.env.VUE_APP_PDFSdk_DOMAIN
 
   // 方法

+ 34 - 37
src/views/billing/invoices.vue

@@ -7,13 +7,13 @@
       </div>
       <div class="plan-table">
         <el-table :data="tableData" style="width: 100%" :default-sort = "{prop: 'date', order: 'descending'}">
-          <el-table-column prop="payTime" :label="$t('invoices.date')" min-width="120"></el-table-column>
-          <el-table-column prop="orderNo" :label="$t('invoices.order')" min-width="240"></el-table-column>
-          <el-table-column prop="price" :label="$t('invoices.amount') " min-width="60"></el-table-column>
-          <el-table-column prop="billNo" :label="$t('invoices.number')" min-width="120">
+          <el-table-column prop="payTime" :label="$t('invoices.date')" min-width="170"></el-table-column>
+          <el-table-column prop="orderNo" :label="$t('invoices.order')" min-width="360"></el-table-column>
+          <el-table-column prop="price" :label="$t('invoices.amount') " min-width="90"></el-table-column>
+          <el-table-column prop="billNo" :label="$t('invoices.number')" min-width="180">
             <template slot-scope="scope">{{scope.row.billNo ? scope.row.billNo : '-' }}</template>
           </el-table-column>
-          <el-table-column prop="remainingFiles" :label="$t('invoices.operation') " min-width="180">
+          <el-table-column prop="remainingFiles" :label="$t('invoices.operation') " min-width="220">
             <template slot-scope="scope">
               <div class="opera">
                 <template v-if="scope.row.billNo">
@@ -69,17 +69,19 @@ export default class Plan extends Vue {
     const failedConnect: any = this.$t('failedConnect')
     getInvoices().then((res:any) => {
       if (res.code === '200') {
-        const array = this.paginateArray(res.data, this.pageSize)[this.currentPage - 1]
-        this.tableData = []
-        this.totalNum = res.data.length
-        this.totalPageNum = Math.ceil(res.data.length / 8)
-        for (let i = 0; i < array.length; i++) {
-          this.tableData.push(array[i])
-          if (this.currentPage <= 1) {
-            this.disabledPrevBtn = true
-          }
-          if (this.currentPage >= this.totalPageNum) {
-            this.disabledNextBtn = true
+        if (res.data.length !== 0) {
+          const array = this.paginateArray(res.data, this.pageSize)[this.currentPage - 1]
+          this.tableData = []
+          this.totalNum = res.data.length
+          this.totalPageNum = Math.ceil(res.data.length / 8)
+          for (let i = 0; i < array.length; i++) {
+            this.tableData.push(array[i])
+            if (this.currentPage <= 1) {
+              this.disabledPrevBtn = true
+            }
+            if (this.currentPage >= this.totalPageNum) {
+              this.disabledNextBtn = true
+            }
           }
         }
       } else {
@@ -140,9 +142,10 @@ export default class Plan extends Vue {
     // 用户信息完整申请开票
     if (valid) {
       this.loading = true
+      const cn = this.$i18n.locale === 'zh-cn'
       const emailFail: any = this.$t('invoices.fail')
       const emailSuccess: any = this.$t('invoices.success')
-      const data: any = await apiApplyInvoice({ orderId: val.id }, {})
+      const data: any = await apiApplyInvoice({ orderId: val.id, isCN: cn }, {})
       if (data.code === '200') {
         this.loading = false
         this.$message({
@@ -200,7 +203,6 @@ export default class Plan extends Vue {
         } else {
           this.$message.error(emailFail)
         }
-        console.log(res)
       }).catch((err) => {
         if (err === 'cancel') {
           this.$router.push('/billing/information')
@@ -335,7 +337,7 @@ export default class Plan extends Vue {
 }
 ::v-deep .el-table {
   .el-table__header {
-    @media screen and (max-width: 429px) {
+    @media screen and (max-width: 576px) {
       width: 1020px !important;
     }
     .is-leaf {
@@ -344,7 +346,7 @@ export default class Plan extends Vue {
     }
   }
   .el-table__body {
-    @media screen and (max-width: 429px) {
+    @media screen and (max-width: 576px) {
       width: 1020px !important;
     }
   }
@@ -389,20 +391,20 @@ export default class Plan extends Vue {
 // 未录入收件邮箱
 .el-message-box.infoBox.el-message-box--center {
   width: 474px;
-  @media screen and (max-width: 429px) {
+  @media screen and (max-width: 576px) {
     width: calc(100% - 60px);
   }
   .el-message-box__btns {
     display: flex;
     justify-content: space-between;
-    @media screen and (max-width: 429px) {
+    @media screen and (max-width: 576px) {
       flex-direction: column;
     }
     & button:nth-child(1) {
       width: 151px;
       color: #396FFA;
       border-color: #396FFA;
-      @media screen and (max-width: 429px) {
+      @media screen and (max-width: 576px) {
         width: 100%;
       }
       &:hover {
@@ -412,7 +414,7 @@ export default class Plan extends Vue {
     }
     & button:nth-child(2) {
       width: calc(100% - 167px);
-      @media screen and (max-width: 429px) {
+      @media screen and (max-width: 576px) {
         width: 100%;
         margin-left: 0;
         margin-top: 12px;
@@ -427,14 +429,9 @@ export default class Plan extends Vue {
 // 邮件发送确认
 .el-message-box.emailBox.el-message-box--center {
   width: 454px;
-  @media screen and (max-width: 429px) {
+  @media screen and (max-width: 576px) {
     width: calc(100% - 60px);
   }
-  @media screen and (max-width: 429px){
-    .el-message-box {
-        width: calc(100% - 60px);
-    }
-  }
   .el-message-box__header {
     display: none;
   }
@@ -446,14 +443,14 @@ export default class Plan extends Vue {
     padding: 32px;
     padding-bottom: 40px;
     justify-content: flex-end;
-    @media screen and (max-width: 429px) {
+    @media screen and (max-width: 576px) {
       flex-direction: column;
       justify-content: inherit;
     }
     & button:nth-child(1) {
       color: #396FFA;
       border-color: #396FFA;
-      @media screen and (max-width: 429px) {
+      @media screen and (max-width: 576px) {
         width: 100%;
       }
       &:hover {
@@ -462,7 +459,7 @@ export default class Plan extends Vue {
       }
     }
     & button:nth-child(2) {
-      @media screen and (max-width: 429px) {
+      @media screen and (max-width: 576px) {
         width: 100%;
         margin-left: 0;
         margin-top: 12px;
@@ -478,7 +475,7 @@ export default class Plan extends Vue {
 // 未录入收件邮箱
 .el-message-box.emailErrBox.el-message-box--center {
   width: 464px;
-  @media screen and (max-width: 429px) {
+  @media screen and (max-width: 576px) {
     width: calc(100% - 60px);
   }
   .el-message-box__header {
@@ -492,14 +489,14 @@ export default class Plan extends Vue {
     padding: 32px;
     padding-bottom: 40px;
     justify-content: space-between;
-    @media screen and (max-width: 429px) {
+    @media screen and (max-width: 576px) {
       flex-direction: column;
       justify-content: inherit;
     }
     & button:nth-child(1) {
       color: #396FFA;
       border-color: #396FFA;
-      @media screen and (max-width: 429px) {
+      @media screen and (max-width: 576px) {
         width: 100%;
       }
       &:hover {
@@ -508,7 +505,7 @@ export default class Plan extends Vue {
       }
     }
     & button:nth-child(2) {
-      @media screen and (max-width: 429px) {
+      @media screen and (max-width: 576px) {
         width: 100%;
         margin-left: 0;
         margin-top: 12px;

+ 10 - 1
src/views/billing/plan.vue

@@ -156,7 +156,7 @@ export default class Plan extends Vue {
       const downloadElement = document.createElement('a') // 创建a标签
       const href = window.URL.createObjectURL(blob) // 创建下载的链接
       downloadElement.href = href
-      downloadElement.download = 'plan.xlsx' // 下载后文件名
+      downloadElement.download = this.$i18n.locale === 'en' ? 'plan.xlsx' : '套餐.xlsx' // 下载后文件名
       document.body.appendChild(downloadElement)
       downloadElement.click() // 点击下载
       document.body.removeChild(downloadElement) // 下载完成移除元素
@@ -220,6 +220,15 @@ export default class Plan extends Vue {
   }
   :deep .el-table--enable-row-hover .el-table__body tr:hover > td.el-table__cell {
     background-color: #fff;
+    .cell {
+      text-align: center;
+    }
+  }
+  :deep .el-table tr > td.el-table__cell .cell {
+    text-align: center;
+  }
+  :deep .el-table th.el-table__cell > .cell {
+    text-align: center;
   }
   .pagination {
     margin-top: 40px;

+ 2 - 2
src/views/login.vue

@@ -87,12 +87,12 @@ export default class Login extends Vue {
 
   // 监视属性
   @Watch('ruleFormEmail')
-  noValue1change (newVal:string, oldVal:string) {
+  noValue1change () {
     this.showErrTipEmailBlank = false
   }
 
   @Watch('ruleFormPwd')
-  noValue2change (newVal:string, oldVal:string) {
+  noValue2change () {
     this.showErrTipPwdBlank = false
     this.showErrTip = false
   }

+ 8 - 2
src/views/projects/api/add.vue

@@ -20,13 +20,19 @@ import { apiAddNewProject } from '@/request/api'
 
 @Component
 export default class apiAdd extends Vue {
+  created () {
+    this.$watch('$i18n.locale', () => {
+      this.$router.go(0)
+    })
+  }
+
   ruleForm = {
     projectName: ''
   }
 
   rules = {
     projectName: [
-      { required: true, message: 'Project name cannot be blank', trigger: 'change' }
+      { required: true, message: this.$t('apiKey.projectBlank'), trigger: 'change' }
     ]
   }
 
@@ -37,7 +43,7 @@ export default class apiAdd extends Vue {
   }
 
   @Watch('ruleFormName')
-  onVal1Change (newVal: boolean, oldVal: boolean) {
+  onVal1Change () {
     this.showErrTip = false
   }
 

+ 18 - 8
src/views/projects/api/apiKeys.vue

@@ -14,9 +14,9 @@
       </div>
       <div class="keys-table" v-show="showFather">
         <el-table :data="tableData" style="width: 100%">
-          <el-table-column prop="projectName" :label="$t('apiKey.projectName')" min-width="130">
+          <el-table-column prop="projectName" :label="$t('apiKey.projectName')" min-width="120">
             <template slot-scope="scope">
-              <div class="key-projectName" :title="scope.row.projectName">{{ scope.row.projectName }}</div>
+              <div class="key-projectName" :title="scope.row.projectName">{{ scope.row.projectName === 'Default Project' ? $t('webhooks')[scope.row.projectName] : scope.row.projectName }}</div>
             </template>
           </el-table-column>
           <el-table-column :label="$t('apiKey.publicKey')" min-width="200">
@@ -59,14 +59,14 @@
                   @click="copy('#secret' + scope.$index)"
                   :id="'secret' + scope.$index"
                 >
-                  {{ showEye === scope.$index ? scope.row.secretKey : formatterKey(scope.row.secretKey) }}
+                  <p>{{ showEye === scope.$index ? scope.row.secretKey : formatterKey(scope.row.secretKey) }}</p>
                   <span v-show="scope.row.secretKey" class="show-password" :class="showEye === scope.$index ? 'eye-open' : 'eye-close'" @click.stop="toggleShowEye(scope.$index)"></span>
                 </div>
               </el-tooltip>
             </template>
           </el-table-column>
           <el-table-column prop="createDate" :label="$t('apiKey.creationDate')" :formatter="formatterDate" min-width="140"></el-table-column>
-          <el-table-column :label="$t('apiKey.actions')" min-width="80">
+          <el-table-column :label="$t('apiKey.actions')" min-width="90" class-name="actions">
             <template slot-scope="scope">
               <router-link :to="{name: 'editApiKeys', params: {'id': scope.row.id}, query: {'projectName': scope.row.projectName}}"><img src="@/assets/images/apiKey/edit.svg" alt="edit" class="edit-icon" /></router-link>
               <img src="@/assets/images/apiKey/delete.svg" alt="delete" @click="handleDelete(scope.$index, scope.row)" class="delete-icon" />
@@ -327,11 +327,21 @@ export default class apiKeys extends Vue {
       padding: 0 10px 0 8px;
       text-overflow: ellipsis;
     }
-    .secret-key-input .el-input__inner {
-      padding: 0 25px 0 8px;
+    .secret-key-input {
+      p {
+        overflow: hidden;
+      }
+      .el-input__inner {
+        padding: 0 25px 0 8px;
+      }
+      .el-input__inner[type=''] {
+        text-overflow: ellipsis;
+      }
     }
-    .secret-key-input .el-input__inner[type=''] {
-      text-overflow: ellipsis;
+    .actions {
+      .cell {
+        white-space: nowrap;
+      }
     }
     .el-table__body {
       // 使表格兼容safari,不错位

+ 12 - 9
src/views/projects/api/edit.vue

@@ -24,30 +24,33 @@ interface isRuleForm{
 
 @Component
 export default class apiEdit extends Vue {
+  created () {
+    this.$watch('$i18n.locale', () => {
+      this.$router.go(0)
+    })
+    this.id = this.$route.params.id
+    this.ruleForm.projectName = this.$route.query.projectName
+  }
+
   id = ''
+  showErrTip = false
+
   ruleForm: isRuleForm = {
     projectName: ''
   }
 
   rules = {
     projectName: [
-      { required: true, message: 'Project name cannot be blank', trigger: 'change' }
+      { required: true, message: this.$t('apiKey.projectBlank'), trigger: 'change' }
     ]
   }
 
-  showErrTip = false
-
-  created () {
-    this.id = this.$route.params.id
-    this.ruleForm.projectName = this.$route.query.projectName
-  }
-
   get ruleFormName () {
     return this.ruleForm.projectName
   }
 
   @Watch('ruleFormName')
-  watchRuleFormName (newVal: string, oldVal: string) {
+  watchRuleFormName () {
     this.showErrTip = false
   }
 

+ 18 - 10
src/views/projects/dashboard.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="dashboard container" @click="showCalender = false, timeSelected = oldTimeSelectVal">
+  <div class="dashboard container" @click="close">
     <h1>{{ $t('dashboard.title') }}</h1>
     <Progress ref="progress" class="process" :init="false" />
     <div class="board block">
@@ -18,9 +18,9 @@
             <span class="max">{{ $t('dashboard.view') }}</span>
             <select v-model="projectValue" :placeholder="$t('dashboard.project')['All Projects']" name="projects">
               <option value="">{{ $t('dashboard.project')['All Projects'] }}</option>
-              <option v-for="item in projects" :key="item.projectId" :value="item.projectId">{{ $t('dashboard.project')[item.projectName] }}</option>
+              <option v-for="item in projects" :key="item.projectId" :value="item.projectId">{{ item.projectName === 'Default Project' ? $t('dashboard.project')[item.projectName] : item.projectName }}</option>
             </select>
-            <select v-model="toolValue" :placeholder="$t('dashboard.project.allTools')" name="tools">
+            <select v-model="toolValue" :placeholder="$t('dashboard.allTools')" name="tools">
               <option value="">{{ $t('dashboard.allTools') }}</option>
               <option v-for="item in tools" :key="item.id" :value="item.id">{{ $t('dashboard.tools')[item.toolName] }}</option>
             </select>
@@ -156,13 +156,13 @@ export default class dashBoard extends Vue {
     const el = this.$refs.progress as any
     el && el.getFileAmount()
     this.getFirstLoginTime()
-    this.$watch('$i18n.locale', (newVal: string, oldVal: string) => {
+    this.$watch('$i18n.locale', () => {
       this.selectData(this.dataSelected, true)
     })
   }
 
   @Watch('datePickerValue')
-  onDatePickerValue (newVal: Array<string>, oldVal: Array<string>) {
+  onDatePickerValue (newVal: Array<string>) {
     if (newVal.length === 2) {
       this.getFourAnalysisData()
       this.getChartsData(this.dataSelected)
@@ -170,13 +170,13 @@ export default class dashBoard extends Vue {
   }
 
   @Watch('projectValue')
-  onProjectValue (newVal: string, oldVal: string) {
+  onProjectValue () {
     this.getFourAnalysisData()
     this.getChartsData(this.dataSelected)
   }
 
   @Watch('toolValue')
-  onToolValue (newVal: string, oldVal:string) {
+  onToolValue () {
     this.getFourAnalysisData()
     this.getChartsData(this.dataSelected)
   }
@@ -186,6 +186,13 @@ export default class dashBoard extends Vue {
     return day
   }
 
+  close () {
+    this.showCalender = false
+    if (this.timeSelected === 4) {
+      this.timeSelected = this.oldTimeSelectVal
+    }
+  }
+
   // 选择时间段
   selectTime (val: number) {
     if (this.timeSelected !== 4) {
@@ -689,6 +696,7 @@ export default class dashBoard extends Vue {
             margin-right: 0;
           }
           &.time-selected {
+            font-weight: 700;
             color: #1460F3;
             background: rgba(20, 96, 243, 0.1);
             border-radius: 4px;
@@ -809,7 +817,7 @@ export default class dashBoard extends Vue {
   width: 100%;
   height: 320px;
 }
-@media screen and (max-width: 1407px) {
+@media screen and (max-width: 1520px) {
   .max {
     display: none;
   }
@@ -866,14 +874,14 @@ export default class dashBoard extends Vue {
     color: #43474D;
   }
 }
-@media screen and (min-width: 1408px) {
+@media screen and (min-width: 1520px) {
   .dashboard .board .detail-data {
     .data-box {
       margin-right: 25px;
     }
   }
 }
-@media screen and (max-width: 1407px) and (min-width: 930px) {
+@media screen and (max-width: 1520px) and (min-width: 930px) {
   .dashboard .board .detail-data {
     flex-wrap: wrap;
     margin-bottom: 40px;

+ 11 - 8
src/views/projects/user/add.vue

@@ -24,7 +24,7 @@
       <el-form-item :label="$t('webhooks.project')" class="select-project">
         <select v-model="ruleForm.projectId" :placeholder="$t('webhooks.allProjects')" name="projects">
           <option value="">{{ $t('webhooks.allProjects') }}</option>
-          <option v-for="item in projects" :key="item.projectId" :value="item.projectId">{{ $t('webhooks')[item.projectName] }}</option>
+          <option v-for="item in projects" :key="item.projectId" :value="item.projectId">{{ item.projectName === 'Default Project' ? $t('webhooks')[item.projectName] : item.projectName }}</option>
         </select>
       </el-form-item>
       <el-form-item class="btn-group">
@@ -59,6 +59,14 @@ export default class userAdd extends Vue {
     events: []
   }
 
+  created () {
+    this.$watch('$i18n.locale', () => {
+      this.$router.go(0)
+    })
+    this.getEvents()
+    this.getProjectsList()
+  }
+
   rules = {
     url: [
       { required: true, message: this.$t('webhooks.urlErr'), trigger: 'change' }
@@ -72,17 +80,12 @@ export default class userAdd extends Vue {
   projects: Array<isProjects> = []
   showErrTipUrl = false
 
-  created () {
-    this.getEvents()
-    this.getProjectsList()
-  }
-
   get ruleFormUrl () {
     return this.ruleForm.url
   }
 
   @Watch('ruleFormUrl')
-  function (newVal: string, oldVal: string) {
+  function () {
     this.showErrTipUrl = false
   }
 
@@ -91,7 +94,7 @@ export default class userAdd extends Vue {
     this.validUrl()
     const msg: any = this.$t('webhooks.createInvalid')
     if (this.showErrTipUrl) {
-      this.$message.error('Create Invalid!')
+      this.$message.error(msg)
     } else {
       this.createNewWebhook()
     }

+ 17 - 14
src/views/projects/user/edit.vue

@@ -25,7 +25,7 @@
       <el-form-item :label="$t('webhooks.project')" class="select-project">
         <select v-model="ruleForm.projectId" :placeholder="$t('webhooks.allProjects')" name="projects">
           <option value="">{{ $t('webhooks.allProjects') }}</option>
-          <option v-for="item in projects" :key="item.projectId" :value="item.projectId">{{ $t('webhooks')[item.projectName] }}</option>
+          <option v-for="item in projects" :key="item.projectId" :value="item.projectId">{{ item.projectName === 'Default Project' ? $t('webhooks')[item.projectName] : item.projectName }}</option>
         </select>
       </el-form-item>
       <el-form-item class="btn-group">
@@ -64,6 +64,21 @@ interface isRuleForm{
 @Component
 export default class userEdit extends Vue {
   id = ''
+  eventsList: Array<isEventsList> = []
+  projects: Array<isProjects> = []
+  showErrTipUrl = false
+
+  created () {
+    this.$watch('$i18n.locale', () => {
+      this.$router.go(0)
+    })
+    this.id = this.$route.params.id
+    this.getEvents()
+    this.getWebhookInfo()
+    this.getProjectsList()
+    this.getCheckedEvents()
+  }
+
   ruleForm: isRuleForm= {
     url: '',
     projectId: '',
@@ -79,24 +94,12 @@ export default class userEdit extends Vue {
     ]
   }
 
-  eventsList: Array<isEventsList> = []
-  projects: Array<isProjects> = []
-  showErrTipUrl = false
-
-  created () {
-    this.id = this.$route.params.id
-    this.getEvents()
-    this.getWebhookInfo()
-    this.getProjectsList()
-    this.getCheckedEvents()
-  }
-
   get ruleFormUrl () {
     return this.ruleForm.url
   }
 
   @Watch('ruleFormUrl')
-  function (newVal: string, oldVal: string) {
+  function () {
     this.showErrTipUrl = false
   }
 

+ 20 - 11
src/views/projects/user/webhooks.vue

@@ -45,7 +45,7 @@
           <el-table-column prop="secretToken" class-name="header-with-info" min-width="200">
             <template slot="header">
               <span>{{ $t('webhooks.secretToken') }}</span>
-              <el-tooltip class="item" effect="dark" :content="$t('webhooks.tokenTip')" placement="bottom">
+              <el-tooltip class="item" effect="dark" :content="$t('webhooks.tokenTip')" placement="bottom" :hide-after="3000">
                 <img src="@/assets/images/common/info_white.svg" alt="info">
               </el-tooltip>
             </template>
@@ -66,7 +66,7 @@
                   :data-clipboard-text="scope.row.secretToken"
                   @click="copy('#secretToken' + scope.$index)"
                   :id="'secretToken' + scope.$index"
-                >{{ showEye === scope.$index ? scope.row.secretToken : formatterKey(scope.row.secretToken) }}
+                ><p>{{ showEye === scope.$index ? scope.row.secretToken : formatterKey(scope.row.secretToken) }}</p>
                   <span v-show="scope.row.secretToken" class="show-password" :class="showEye === scope.$index ? 'eye-open' : 'eye-close'" @click="toggleShowEye(scope.$index)"></span>
                 </div>
               </el-tooltip>
@@ -75,10 +75,11 @@
           <el-table-column prop="responseTime" class-name="header-with-info" :formatter="formatterDate" min-width="180">
             <template slot="header">
               <span>{{ $t('webhooks.lastResponse') }}</span>
-              <el-tooltip class="item" effect="dark" :content="$t('webhooks.responseTip')" placement="bottom">
+              <el-tooltip class="item" effect="dark" :content="$t('webhooks.responseTip')" placement="bottom" :hide-after="3000">
                 <img src="@/assets/images/common/info_white.svg" alt="info">
               </el-tooltip>
-            </template></el-table-column>
+            </template>
+          </el-table-column>
           <el-table-column :label="$t('webhooks.actions')" min-width="90" class-name="actions">
             <template slot-scope="scope">
               <router-link :to="{name: 'editWebhook', params: {id: scope.row.id}}"><img src="@/assets/images/apiKey/edit.svg" alt="edit" class="edit-icon" /></router-link>
@@ -183,7 +184,7 @@ export default class webhooks extends Vue {
   // 点击复制input中的内容
   copy (id: string) {
     const copiedFail: any = this.$t('webhooks.copiedFail')
-    var clipboard = new Clipboard(id)
+    const clipboard = new Clipboard(id)
     clipboard.on('success', () => {
       this.showTooltip = id
       this.isCopyActive = id
@@ -247,8 +248,8 @@ export default class webhooks extends Vue {
 .webhooks {
   .top {
     display: flex;
-    justify-content: space-between;
     align-items: flex-start;
+    justify-content: space-between;
     margin-bottom: 2px;
     h2 {
       display: flex;
@@ -333,6 +334,9 @@ export default class webhooks extends Vue {
     display: none !important;
   }
   .webhooks {
+    h2 {
+      white-space: nowrap;
+    }
     .top {
       ::v-deep .el-button {
         width: 24px;
@@ -408,11 +412,16 @@ export default class webhooks extends Vue {
       padding: 0 10px 0 8px;
       text-overflow: ellipsis;
     }
-    .secret-key-input .el-input__inner {
-      padding: 0 25px 0 8px;
-    }
-    .secret-key-input .el-input__inner[type=''] {
-      text-overflow: ellipsis;
+    .secret-key-input {
+      p {
+        overflow: hidden;
+      }
+      .el-input__inner {
+        padding: 0 25px 0 8px;
+      }
+      .el-input__inner[type=''] {
+        text-overflow: ellipsis;
+      }
     }
     .header-with-info .cell {
       display: flex;