jiangping
2024-01-26 4a34ae32407330c6600d24b065c7de2ad9a51d6b
开发业务接口
已添加22个文件
已修改27个文件
2536 ■■■■ 文件已修改
company/src/App.vue 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/assets/avatar/man.png 补丁 | 查看 | 原始文档 | blame | 历史
company/src/assets/avatar/woman.png 补丁 | 查看 | 原始文档 | blame | 历史
company/src/assets/images/login_bg.png 补丁 | 查看 | 原始文档 | blame | 历史
company/src/assets/images/login_img.jpg 补丁 | 查看 | 原始文档 | blame | 历史
company/src/assets/images/login_img.png 补丁 | 查看 | 原始文档 | blame | 历史
company/src/assets/images/man.png 补丁 | 查看 | 原始文档 | blame | 历史
company/src/assets/images/top_ic_bolang@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
company/src/assets/images/top_ic_chilun@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
company/src/assets/images/woman.png 补丁 | 查看 | 原始文档 | blame | 历史
company/src/assets/images/zan.png 补丁 | 查看 | 原始文档 | blame | 历史
company/src/assets/logo.png 补丁 | 查看 | 原始文档 | blame | 历史
company/src/assets/style/alertstyle.scss 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/assets/style/element-variables.scss 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/assets/style/lib.css 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/assets/style/style.scss 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/assets/style/variables.scss 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/base/BaseOpera.vue 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/base/BaseTable.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/common/CommonHeader.vue 220 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/common/DepartmentSelect.vue 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/common/GlobalAlertWindow.vue 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/common/GlobalQuestionWindow.vue 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/common/GlobalRigthWindow.vue 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/common/GlobalWindow.vue 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/common/Header.vue 193 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/common/ImportButton.vue 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/common/ImportWindow.vue 204 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/common/Light.vue 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/common/Menu.vue 58 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/common/Pagination.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/common/PositionSelect.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/common/RichEditor.vue 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/common/SearchFormCollapse.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/common/ShowRich.vue 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/common/Tree.vue 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/common/TreeSelect.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/common/UploadAvatarImage.vue 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/common/UploadImage.vue 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/common/myImage.vue 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/components/common/tagsview.vue 261 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/layouts/AppLayout.vue 112 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/layouts/TableLayout.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/plugins/download.js 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/plugins/messagebox.js 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/router/index.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/store/index.js 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/platform/src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/service/src/main/java/com/doumee/service/business/impl/CompanyServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
company/src/App.vue
@@ -3,10 +3,20 @@
</template>
<style lang="scss">
@import "assets/style/lib.css";
// å¼•入全局样式
@import "assets/style/style";
// å¼•入系统内置图标
@import "assets/icons/system/index";
// å¼•入自定义图标
@import "assets/icons/ext/index";
.long-title-style {
  white-space: nowrap;
  text-overflow: ellipsis;
  -webkit-text-overflow: ellipsis;
  overflow: hidden;
}
.el-tooltip__popper.is-dark {
  max-width: 400px;
}
</style>
company/src/assets/avatar/man.png
company/src/assets/avatar/woman.png
company/src/assets/images/login_bg.png
company/src/assets/images/login_img.jpg
company/src/assets/images/login_img.png
company/src/assets/images/man.png

company/src/assets/images/top_ic_bolang@2x.png
company/src/assets/images/top_ic_chilun@2x.png
company/src/assets/images/woman.png

company/src/assets/images/zan.png
company/src/assets/logo.png

company/src/assets/style/alertstyle.scss
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,32 @@
::v-deep .el-form-item {
  display: flex;
}
::v-deep .el-form-item__content {
  margin-left: 0 !important;
  flex: 1;
}
.address-plus {
  display: flex;
  justify-content: space-between;
  ::v-deep .el-select {
    width: 31%;
    .el-input__inner {
      width: 100%;
    }
  }
}
.address {
  display: flex;
  justify-content: space-between;
  ::v-deep .el-select {
    width: 47%;
    .el-input__inner {
      width: 100%;
    }
  }
}
::v-deep input {
  text-align: left !important;
}
company/src/assets/style/element-variables.scss
@@ -6,3 +6,4 @@
$--font-path: '~element-ui/lib/theme-chalk/fonts';
@import "~element-ui/packages/theme-chalk/src/index";
company/src/assets/style/lib.css
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,117 @@
/*-----------------[初始化]--------------*/
*{ font-family: PingFang SC;}
/* æ¸…理浮动 */
.cle:after {visibility:hidden;display:block;font-size:0;content:" ";clear:both;height:0;}
.cle:after{zoom:1;}
.clear{clear: both;}
.tc{text-align:center;}
.tl{text-align:left}
.tr{text-align:right}
.fl{float: left;}
.fr{float: right;}
.wp{ width: 94%; margin: 0 auto;}
.w30{ width: 30%;}.w40{ width: 40%;}.w47{ width: 47%;}.w48{ width: 48%;}.w49{ width: 49%;}.w50{ width: 50%;}.w60{ width: 60%;}.w80{ width: 80%;}.w90{ width: 90%;}
.bg_fa{ background-color: #fafafa;}.bg_f2{ background-color: #f2f2f2;}.bg_f1{ background-color: #f1f1f1;}.bg_f5{ background-color: #f5f5f5;}.bg_f6{ background-color: #f6f6f6;}.bg_f7{ background-color: #f7f7f7;}.bg_f8{ background-color: #f8f8f8;}.bg_e{ background-color: #eee;}.bg_d{ background-color: #ddd;}.bg_w{ background-color: #fff;}.bg_3{ background-color: #333;}.bcf{ color: #fff;}.bc3{ color: #333;}.bcc{ color: #ccc;}.bc9{ color: #999;}.bc6{ color: #666;}
.rd4{border-radius: 4px;}.rd5{border-radius: 5px;}.rd6{border-radius: 6px;}.rd8{border-radius: 8px;}.rd10{border-radius: 10px;}.rd15{border-radius: 15px;}.rd20{border-radius: 20px;}.rd30{border-radius: 30px;}.rd40{border-radius: 40px;}.rd50{border-radius: 50px;}.rd60{border-radius: 60px;}.rd70{border-radius: 70px;}.rd80{border-radius: 80px;}.rd90{border-radius: 90px;}.rd100{border-radius: 100px;}.rd120{border-radius: 120px;}.rdhalf{  border-radius:50%}
.ml5{ margin-left: 5px;}.ml10{ margin-left: 10px;}.ml15{ margin-left: 15px;}.ml20{ margin-left: 20px;}.ml25{ margin-left: 25px;}.ml30{ margin-left: 30px;}.ml40{ margin-left: 40px;}.ml50{ margin-left: 50px;}.ml60{ margin-left: 60px;}
.mt5{ margin-top: 5px;}.mt10{ margin-top: 10px;}.mt15{ margin-top: 15px;}.mt20{ margin-top: 20px;}.mt25{ margin-top: 25px;}.mt30{ margin-top: 30px;}.mt35{ margin-top: 35px;}.mt40{ margin-top: 40px;}.mt45{ margin-top: 45px;}.mt50{ margin-top: 50px;}.mt60{ margin-top: 60px;}.mt70{ margin-top: 70px;}.mt80{ margin-top: 80px;}.mt90{ margin-top: 90px;}.mt100{ margin-top:100px;}.mt150{ margin-top:150px;}.mt200{ margin-top:200px;}.mt-20{ margin-top: -20px;}.mt-30{ margin-top: -30px;}.mt-40{ margin-top: -40px;}
.mb5{ margin-bottom: 5px;}.mb10{ margin-bottom: 10px;}.mb15{ margin-bottom: 15px;}.mb20{ margin-bottom: 20px;}.mb25{ margin-bottom: 25px;}.mb30{ margin-bottom: 30px;}.mb40{ margin-bottom: 40px;}.mb50{ margin-bottom: 50px;}.mb60{ margin-bottom: 60px;}.mb80{ margin-bottom: 80px;}
.mr5{ margin-right: 5px;}.mr10{ margin-right: 10px;}.mr15{ margin-right: 15px;}.mr20{ margin-right: 20px;}.mr25{ margin-right: 25px;}.mr30{ margin-right: 30px;}.mr40{ margin-right: 40px;}.mr60{ margin-right: 60px;}.mr80{ margin-right: 80px;}.mr100{ margin-right: 100px;}
.pl10{ padding-left: 10px;}.pl20{ padding-left: 20px;}.pl25{ padding-left: 25px;}.pl30{ padding-left: 30px;}.pl40{ padding-left: 40px;}.pl50{ padding-left: 50px;}.pl60{ padding-left: 60px;}.pl80{ padding-left: 80px;}.pl100{ padding-left: 100px;}
.pr10{ padding-right: 10px;}.pr20{ padding-right: 20px;}.pr25{ padding-right: 25px;}.pr30{ padding-right: 30px;}.pr40{ padding-right: 40px;}.pr50{ padding-right: 50px;}.pr60{ padding-right: 60px;}.pr80{ padding-right: 80px;}.pr100{ padding-right: 100px;}
.pb10{ padding-bottom: 10px;}.pb20{ padding-bottom: 20px;}.pb25{ padding-bottom: 25px;}.pb30{ padding-bottom: 30px;}.pb40{ padding-bottom: 40px;}.pb50{ padding-bottom: 50px;}.pb100{ padding-bottom: 100px;}
.pt10{ padding-top: 10px;}.pt20{ padding-top: 20px;}.pt25{ padding-top: 25px;}.pt30{ padding-top: 30px;}.pt40{ padding-top: 40px;}.pt50{ padding-top: 50px;}.pt100{ padding-top: 100px;}
.plr{ padding-left: 30px; padding-right: 30px;}.plr20{ padding-left: 20px; padding-right: 20px;}.plr25{ padding-left: 25px; padding-right: 25px;}.plr30{ padding-left: 30px; padding-right: 30px;}.plr40{ padding-left: 40px; padding-right: 40px;}.plr50{ padding-left: 50px; padding-right: 50px;}.plr60{ padding-left: 60px; padding-right: 60px;}
.ptb10{padding-bottom: 10px; padding-top: 10px;} .ptb15{padding-bottom: 15px; padding-top: 15px;} .ptb20{padding-bottom: 20px; padding-top: 20px;}.ptb25{padding-bottom: 25px; padding-top: 25px;}.ptb30{padding-bottom: 30px; padding-top: 30px;}.ptb35{padding-bottom: 35px; padding-top: 35px;}.ptb40{padding-bottom: 40px; padding-top: 40px;}.ptb50{padding-bottom: 50px; padding-top: 50px;}.ptb60{padding-bottom: 60px; padding-top: 60px;}.ptb80{padding-bottom: 80px; padding-top: 80px;}.ptb100{padding-bottom: 100px; padding-top: 100px;}.ptb150{padding-bottom: 150px; padding-top: 150px;}.ptb200{padding-bottom: 200px; padding-top: 200px;}
.p5{ padding:5px}.p10{ padding:10px} .p20{ padding:20px}.p30{ padding:30px}.p2030{ padding:20px 30px}.p40{ padding:40px}.p3040{ padding:30px 40px}
.f0{ font-size: 0px;}.f20{ font-size: 20px;}.f22{ font-size: 22px;}.f24{ font-size: 24px;}.f26{ font-size: 26px;}.f28{ font-size: 28px;}.f30{ font-size: 30px;}.f32{ font-size: 32px;}.f34{ font-size: 34px;}.f36{ font-size: 36px;} .f38{ font-size: 38px;}.f40{ font-size: 40px;} .f42{ font-size: 42px;}.f44{ font-size: 44px;}.f48{ font-size: 48px;}.f50{ font-size: 50px;}.f60{ font-size: 60px;}.f64{ font-size: 64px;}.f70{ font-size: 70px;}.f80{ font-size: 80px;}.f90{ font-size: 90px;}.f100{ font-size: 100px;}
.img16{ width: 16px; height: 16px;}
.img20{ width: 20px; height: 20px;}
.img24{ width: 24px; height: 24px;}
.img26{ width: 26px; height: 26px;}
.img30{ width: 30px; height: 30px;}
.img32{ width: 32px; height: 32px;}
.img36{ width: 36px; height: 36px;}
.img40{ width: 40px; height: 40px;}
.img48{ width: 48px; height: 48px;}
.img60{ width: 60px; height: 60px;}
.img66{ width: 66px; height: 66px;}
.img80{ width: 80px; height: 80px;}
.img86{ width: 86px; height: 86px;}
.img90{ width: 90px; height: 90px;}
.img100{ width: 100px; height: 100px;}
.img110{ width: 110px; height: 110px;}
.img120{ width: 120px; height: 120px;}
.img150{ width: 150px; height: 150px;}
.img180{ width: 180px; height: 180px;}
.img200{ width: 200px; height: 200px;}
.imgfull{ width: 100%;}
.rimb{ border-bottom: 1px solid #F1F1F1;}
.rimt{ border-top: 1px solid #F1F1F1;}
.bcover{  background-size: cover; background-position: center center; background-repeat:  no-repeat;}
.bfull{ background-size: 100% 100%; background-position: center center; background-repeat:  no-repeat;}
.b{ font-weight: bold;}
.ibm{ display: inline-block; vertical-align: middle;}
.bbox{ box-sizing: border-box;}
.rauto{ margin-left:auto; margin-right:auto}
.fixedBottom{position: fixed;        left: 0;        bottom: 0;        width: 100%;}
.lh1-6{line-height: 1.6;}
.lh1-6{line-height: 1.6;}
.lh1-8{line-height: 1.8;}
.lh2{line-height: 2;}
.sbtn{ display: inline-block; padding: 0.7em 2em;  border: 1px solid transparent; box-sizing: border-box; text-align: center;}
.mini{ font-size: 18px;}
.med{ font-size: 26px;}
.def{ font-size: 34px;}
.sbtn_w100{ width: 100%; padding-left: 0; padding-right: 0;}
.sbtn_green{ color: #fff; background:#65C35D; }
.sbtn_green_rim{ color: #65C35D; border-color:#65C35D; }
.sbtn_black{ color: #fff; background:#333; }
.sbtn_gray{ color: #333; background:#F7F7F7; }
.sbtn_black_rim{ color: #333; border-color:#eee; }
.sbtn_gray_rim{ color: #999; border-color:#ccc; }
/* flex */
.flex{ display: flex; flex-wrap: wrap; justify-content: space-between;}
.cXY{ display: flex;  align-items: center;justify-content: center;}
.cY{ display: flex; align-items: center;}
.cX{display: flex; justify-content: center}
.rowW{ display: flex; flex-wrap: wrap;}
.bX{ display: flex;   flex-direction: row; justify-content: space-between;}
.bY{ display: flex;   flex-direction:column; justify-content: space-between;}
.bcX{ display: flex; justify-content: space-between; align-items: center;}
.fx1{ flex: 1; overflow: hidden; }
.cAXY{ position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);}
.shadowA{box-shadow: 0 0 5px 0 #ddd;}
.shadowB{ position: relative;}
.shadowB::after{ content: ""; display: block; width: 100%; height: 8px; box-shadow: 0 6px 12px rgba(0,0,0,.08); top: -8px; left: 0; position: absolute; }
.orange{ color: #EA531B;}
.green{ color: #65C35D;}
.blue{ color: #3C77DA;}
.red{ color: #f00;}
/* /deep/ .uicon-close .u-icon--right{ position: absolute; right: 30px; top: 30px; z-index: 999;} */
.popCloseBtn{ position: absolute; width:50px; height:50px; right: 20px; top: 20px;}
.fixedHeader{ position: absolute; left: 0; top: 0;}
company/src/assets/style/style.scss
@@ -5,13 +5,26 @@
  padding: 0;
  margin: 0;
  color: $font-color;
  // overflow: hidden;
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  scrollbar-width: none; /* firefox */
  -ms-overflow-style: none; /* IE 10+ */
  &::-webkit-scrollbar {
    display: none; /* Chrome Safari */
  }
  body {
    height: 100%;
    padding: 0;
    margin: 0;
    overflow: scroll;
    overflow: hidden;
    scrollbar-width: none; /* firefox */
    -ms-overflow-style: none; /* IE 10+ */
    &::-webkit-scrollbar {
      display: none; /* Chrome Safari */
    }
  }
  h1,h2,h3,h4,h5,h6,ul {
    margin: 0;
@@ -23,10 +36,44 @@
  #app {
    height: 100%;
    min-width: $page-min-width;
    // overflow: hidden;
  }
}
.bg {
  z-index: 9990 !important;
}
.windows {
  z-index: 9991 !important;
}
// ç©¿æ¢­æ¡†çš„æŒ‰é’®
.el-transfer__buttons {
  padding: 0 16px !important;
}
.table-header {
  background-color: #F5F6F8!important;
  th {
    background-color: #F5F6F8!important;
    color: #3F4F69 !important;
    font-size: 14px;
  }
}
.doumee-element-table {
  border-color: #DFE2E8;
  tr, th, td {
    border-color: #DFE2E8;
  }
}
::v-deep .el-table__fixed {
  height: 100% !important;
}
::v-deep .el-table__fixed-right {
  height: 100% !important;
}
::v-deep .el-table__cell {
  height: 100% !important;
}
company/src/assets/style/variables.scss
@@ -1,5 +1,12 @@
// ä¸»è‰²è°ƒ
$primary-color: #2E68EC;
$primary-color: #216EEE;
$primary-title-start-color: #3582ff;
$primary-title-color: #216EcE;
$primary-color-sel: #0046c6;
$primary-color-hover: #1562e2;
$icon-background-color: #0d5ada;
//菜单悬浮色:
$menu-hover-color: rgba(33, 110, 238, 0.10);
// å¤´éƒ¨é«˜åº¦
$header-height: 60px;
// èœå•宽度
company/src/components/base/BaseOpera.vue
@@ -14,6 +14,16 @@
      }
    }
  },
  // watch: {
  //   visible() {
  //     console.log(this.visible);
  //   }
  // },
  watch: {
    $route (to, from) {
      this.close()
    }
  },
  methods: {
    // é…ç½®
    config (extParams = {}) {
@@ -49,6 +59,9 @@
        }
      })
    },
    close () {
      this.visible = false
    },
    // ç¡®è®¤æ–°å»º/修改
    confirm () {
      if (this.form.id == null || this.form.id === '') {
@@ -60,9 +73,12 @@
    // ç¡®è®¤æ–°å»º
    __confirmCreate () {
      this.$refs.form.validate((valid) => {
        // debugger
        if (!valid) {
          return
        }
        // console.log(this.form);
        // debugger
        // è°ƒç”¨æ–°å»ºæŽ¥å£
        this.isWorking = true
        this.api.create(this.form)
company/src/components/base/BaseTable.vue
@@ -135,9 +135,11 @@
    // åˆ é™¤
    deleteById (row, childConfirm = true) {
      this.__checkApi()
      let message = `确认删除${this.module}【${row[this.configData['field.main']]}】吗?`
      // let message = `确认删除${this.module}【${row[this.configData['field.main']]}】吗?`
      let message = `确认删除该记录吗?`
      if (childConfirm && row.children != null && row.children.length > 0) {
        message = `确认删除${this.module}【${row[this.configData['field.main']]}】及其子${this.module}吗?`
        // message = `确认删除${this.module}【${row[this.configData['field.main']]}】及其子${this.module}吗?`
        message = `确认删除该记录及其子数据吗?`
      }
      this.$dialog.deleteConfirm(message)
        .then(() => {
@@ -175,7 +177,7 @@
          }
        }
        if (containChildrenRows.length > 0) {
          message = `本次将删除${this.module}【${containChildrenRows.join('、')}】及其子${this.module}记录,确认删除吗?`
          message = '本次将删除该数据及其子数据,确认删除吗?'
        }
      }
      this.$dialog.deleteConfirm(message)
company/src/components/common/CommonHeader.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,220 @@
<template>
  <div class="common-header">
    <div class="header">
      <div class="logo">
        <div>云易保客户服务系统</div>
        <!-- <div class="title-en">Diagnosis of Intelligent Manufacturing Integrated Service Platfrom</div> -->
      </div>
      <div class="user">
        <el-dropdown v-if="isLogined" trigger="click">
          <span class="el-dropdown-link">
            <!-- <img v-if="userInfo != null" :src="userInfo.avatar == null ? `${require('@/assets/avatar/man.png')}` : userInfo.avatar" alt="">{{userInfo | displayName}}<i class="el-icon-arrow-down el-icon--right"></i> -->
            <img v-if="userInfo != null" style="width: 30px !important;" src="@/assets/avatar/man.png" alt="">{{userInfo | displayName}}<i class="el-icon-arrow-down el-icon--right"></i>
          </span>
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item @click.native="changePwd">修改密码</el-dropdown-item>
            <el-dropdown-item @click.native="logout">退出登录</el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
      </div>
    </div>
    <!-- ä¿®æ”¹å¯†ç  -->
    <GlobalAlertWindow
      title="修改密码"
      :visible.sync="visible.changePwd"
      @confirm="confirmChangePwd"
      @close="visible.changePwd = false"
    >
      <el-form :model="changePwdData.form" ref="changePwdDataForm" :rules="changePwdData.rules">
        <el-form-item label="原始密码" prop="oldPwd" required>
          <el-input v-model="changePwdData.form.oldPwd" type="password" placeholder="请输入原始密码" maxlength="30" show-password></el-input>
        </el-form-item>
        <el-form-item label="新密码" prop="newPwd" required>
          <el-input v-model="changePwdData.form.newPwd" type="password" placeholder="请输入新密码" maxlength="30" show-password></el-input>
        </el-form-item>
        <el-form-item label="确认新密码" prop="confirmPwd" required>
          <el-input v-model="changePwdData.form.confirmPwd" type="password" placeholder="请再次输入新密码" maxlength="30" show-password></el-input>
        </el-form-item>
      </el-form>
    </GlobalAlertWindow>
  </div>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
import GlobalAlertWindow from './GlobalAlertWindow'
import { logout, updatePwd } from '@/api/system/common'
export default {
  name: 'CommonHeader',
  components: { GlobalAlertWindow },
  props: {
    isLogined: {
      type: Boolean,
      default: true
    }
  },
  data () {
    return {
      visible: {
        // ä¿®æ”¹å¯†ç 
        changePwd: false
      },
      isWorking: {
        // ä¿®æ”¹å¯†ç 
        changePwd: false
      },
      username: 'bob', // ç”¨æˆ·å
      // ä¿®æ”¹å¯†ç å¼¹æ¡†
      changePwdData: {
        form: {
          oldPwd: '',
          newPwd: '',
          confirmPwd: ''
        },
        rules: {
          oldPwd: [
            { required: true, message: '请输入原始密码' }
          ],
          newPwd: [
            { required: true, message: '请输入新密码' }
          ],
          confirmPwd: [
            { required: true, message: '请再次输入新密码' }
          ]
        }
      }
    }
  },
  computed: {
    ...mapState(['menuData', 'userInfo']),
    title () {
      return this.$route.meta.title
    }
  },
  filters: {
    // å±•示名称
    displayName (userInfo) {
      if (userInfo == null) {
        return ''
      }
      if (userInfo.realname != null && userInfo.realname.trim().length > 0) {
        return userInfo.realname
      }
      return userInfo.username
    }
  },
  methods: {
    ...mapMutations(['setUserInfo', 'switchCollapseMenu']),
    // ä¿®æ”¹å¯†ç 
    changePwd () {
      this.visible.changePwd = true
      this.$nextTick(() => {
        this.$refs.changePwdDataForm.resetFields()
      })
    },
    // ç¡®å®šä¿®æ”¹å¯†ç 
    confirmChangePwd () {
      if (this.isWorking.changePwd) {
        return
      }
      this.$refs.changePwdDataForm.validate((valid) => {
        if (!valid) {
          return
        }
        // éªŒè¯ä¸¤æ¬¡å¯†ç è¾“入是否一致
        if (this.changePwdData.form.newPwd !== this.changePwdData.form.confirmPwd) {
          this.$tip.warning('两次密码输入不一致')
          return
        }
        // æ‰§è¡Œä¿®æ”¹
        this.isWorking.changePwd = true
        updatePwd({
          oldPwd: this.changePwdData.form.oldPwd,
          newPwd: this.changePwdData.form.newPwd
        })
          .then(() => {
            this.$tip.apiSuccess('修改成功')
            this.visible.changePwd = false
          })
          .catch(e => {
            this.$tip.apiFailed(e)
          })
          .finally(() => {
            this.isWorking.changePwd = false
          })
      })
    },
    // é€€å‡ºç™»å½•
    logout () {
      logout()
        .then(() => {
          this.setUserInfo(null)
          this.$router.push({ name: 'login' })
        })
        .catch(e => {
          this.$tip.apiFailed(e)
        })
    }
  }
}
</script>
<style scoped lang="scss">
@import "@/assets/style/variables.scss";
.common-header {
  background-color: #1457C7;
}
.header {
  overflow: hidden;
  // background: #fff;
  height: 100%;
  display: flex;
  justify-content: space-between;
  .logo {
    background: url('../../assets/images/top_ic_chilun@2x.png') no-repeat;
    box-sizing: border-box;
    min-width: 280px;
    height: 70px;
    padding: 17px 30px;
    // flex-shrink: 0;
    line-height: 36px;
    font-size: 22px;
    font-weight: 600;
    color: #fff;
    // display: inline;
    .title-en {
      font-size: 11px;
      font-weight: 500;
      color: rgb(202, 214, 238);
    }
  }
  .user {
    width: 712px;
    box-sizing: border-box;
    height: 70px;
    padding-right: 25px;
    background: url('../../assets/images/top_ic_bolang@2x.png') no-repeat;
    flex-shrink: 0;
    text-align: right;
    .el-dropdown {
      top: 10px;
      color: #fff;
    }
    img {
      width: 32px;
      position: relative;
      top: 10px;
      margin-right: 10px;
    }
  }
}
// ä¸‹æ‹‰èœå•框
.el-dropdown-menu {
  width: 140px;
  .el-dropdown-menu__item:hover {
    background: #E3EDFB;
    color: $primary-color;
  }
}
</style>
company/src/components/common/DepartmentSelect.vue
@@ -45,7 +45,7 @@
    }
  },
  watch: {
    excludeId () {
    value () {
      this.fetchData()
    }
  },
@@ -54,6 +54,7 @@
    fetchData () {
      fetchTree()
        .then(records => {
          // debugger
          this.data = []
          this.__fillData(this.data, records)
        })
company/src/components/common/GlobalAlertWindow.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,120 @@
<template>
  <el-dialog
    class="global-window"
    title="title"
    :visible="visible"
    :with-header="true"
    :width="width"
    :close-on-press-escape="false"
    :wrapper-closable="false"
    :append-to-body="true"
    @close="close"
  >
    <div slot="title" class="window__header">
      {{title}}
    </div>
    <div class="window__body">
      <slot></slot>
    </div>
    <div v-if="withFooter" class="window__footer">
      <slot name="footer">
        <el-button @click="confirm" :loading="confirmWorking" type="primary">确定</el-button>
        <el-button @click="close">取消</el-button>
      </slot>
    </div>
  </el-dialog>
</template>
<script>
export default {
  name: 'GlobalAlertWindow',
  props: {
    width: {
      type: String,
      default: '50%'
    },
    // æ˜¯å¦åŒ…含底部操作
    withFooter: {
      type: Boolean,
      default: true
    },
    // ç¡®è®¤æŒ‰é’®loading状态
    confirmWorking: {
      type: Boolean,
      default: false
    },
    // æ ‡é¢˜
    title: {
      type: String,
      default: ''
    },
    // æ˜¯å¦å±•示
    visible: {
      type: Boolean,
      required: true
    }
  },
  methods: {
    confirm () {
      // console.log(this.title);
      // debugger
      this.$emit('confirm')
    },
    close () {
      // console.log(this.title);
      // debugger
      this.$emit('update:visible', false)
    }
  }
}
</script>
<style scoped lang="scss">
@import "@/assets/style/variables.scss";
// è¾“入框高度
$input-height: 32px;
::v-deep .el-dialog__header {
  background-color: #f7f7f7;
  font-weight: 500;
  color: #222;
}
::v-deep .el-dialog__body {
  padding: 20px 20px 0;
  box-sizing: border-box;
}
.global-window {
  // top: 80px !important;
  // left: 218px !important;
  // å¤´éƒ¨æ ‡é¢˜
  ::v-deep .el-dialog__header {
    padding: 19px 24px;
    height: 56px;
    line-height: 18px;
    box-sizing: border-box;
    border-bottom: 1px solid #eee;
    // text-align: center;
    .el-dialog__headerbtn {
      width: 18px;
      height: 18px;
      .el-dialog__close {
        width: 18px;
        height: 18px;
        font-size: 19px;
        line-height: 18px;
      }
    }
  }
  // ä¸»ä½“
  .window__body {
    min-height: 200px;
  }
  .window__footer {
      user-select: none;
      border-top: 1px solid #eee;
      height: 60px;
      line-height: 60px;
      text-align: center;
    }
}
</style>
company/src/components/common/GlobalQuestionWindow.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,137 @@
<template>
  <el-dialog
    class="global-window"
    title="title"
    :visible="visible"
    :with-header="true"
    :top="top"
    :width="width"
    :close-on-press-escape="false"
    :wrapper-closable="false"
    :append-to-body="true"
    @close="close"
  >
    <div slot="title" style="min-height: 10px;" class="window__header">
      {{title}}
    </div>
    <div class="window__body">
      <slot></slot>
    </div>
    <div v-if="withFooter" class="window__footer">
      <slot name="footer">
        <el-button @click="confirm" :loading="confirmWorking" type="primary">确定</el-button>
        <el-button @click="close">返回</el-button>
      </slot>
    </div>
  </el-dialog>
</template>
<script>
export default {
  name: 'GlobalQuestionWindow',
  props: {
    width: {
      type: String,
      default: '40%'
    },
    top: {
      type: String,
      default: '15vh'
    },
    // æ˜¯å¦åŒ…含底部操作
    withFooter: {
      type: Boolean,
      default: true
    },
    // ç¡®è®¤æŒ‰é’®loading状态
    confirmWorking: {
      type: Boolean,
      default: false
    },
    // æ ‡é¢˜
    title: {
      type: String,
      default: ''
    },
    // æ˜¯å¦å±•示
    visible: {
      type: Boolean,
      required: true
    }
  },
  methods: {
    confirm () {
      // console.log(this.title);
      // debugger
      this.$emit('confirm')
    },
    close () {
      // console.log(this.title);
      // debugger
      this.$emit('update:visible', false)
    }
  }
}
</script>
<style scoped lang="scss">
@import "@/assets/style/variables.scss";
// è¾“入框高度
$input-height: 32px;
::v-deep .el-dialog__header {
  background-color: #f7f7f7;
  font-weight: 500;
  color: #222;
}
::v-deep .el-dialog__body {
  padding: 30px 20px 0;
  box-sizing: border-box;
}
.global-window {
  // top: 80px !important;
  // left: 218px !important;
  // å¤´éƒ¨æ ‡é¢˜
  ::v-deep .el-drawer__header {
    padding: 0 10px 0 0;
    line-height: 40px;
    border-bottom: 1px solid #eee;
    text-align: center;
    width: 100%;
  }
  // ä¸»ä½“
  ::v-deep .el-dialog__body {
    display: flex;
    flex-direction: column;
    position: absolute;
    top: 40px;
    bottom: 0;
    width: 100%;
    height: calc(90vh - 52px);
    overflow: hidden;
    background-color: #f7f7f7;
    // å†…容
    .window__body {
      width: 100%;
      height: 100%;
      overflow-y: auto;
      // æ ‡ç­¾
      .el-form-item__label {
        float: none;
      }
      // å…ƒç´ å®½åº¦ä¸º100%
      .el-form-item__content > *{
        width: 100%;
      }
    }
    // å°¾éƒ¨
    .window__footer {
      user-select: none;
      border-top: 1px solid #eee;
      height: 60px;
      line-height: 60px;
      text-align: center;
    }
  }
}
</style>
company/src/components/common/GlobalRigthWindow.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,137 @@
<template>
  <el-drawer
    class="global-window"
    title="title"
    :visible="visible"
    :with-header="true"
    :size="width"
    :close-on-press-escape="false"
    :wrapper-closable="false"
    :append-to-body="true"
    :modal="false"
    @close="close"
  >
    <div slot="title" class="window__header">
      <span class="header__btn-back" @click="close"><i class="el-icon-arrow-left"></i></span>{{title}}
      <!-- {{title}} -->
    </div>
    <div class="window__body">
      <slot></slot>
    </div>
    <div v-if="withFooter" class="window__footer">
      <slot name="footer">
        <el-button @click="confirm" :loading="confirmWorking" type="primary">确定</el-button>
        <el-button @click="close">返回</el-button>
      </slot>
    </div>
  </el-drawer>
</template>
<script>
export default {
  name: 'GlobalWindow',
  props: {
    width: {
      type: String,
      default: '100%'
    },
    // æ˜¯å¦åŒ…含底部操作
    withFooter: {
      type: Boolean,
      default: true
    },
    // ç¡®è®¤æŒ‰é’®loading状态
    confirmWorking: {
      type: Boolean,
      default: false
    },
    // æ ‡é¢˜
    title: {
      type: String,
      default: ''
    },
    // æ˜¯å¦å±•示
    visible: {
      type: Boolean,
      required: true
    }
  },
  methods: {
    confirm () {
      this.$emit('confirm')
    },
    close () {
      this.$emit('update:visible', false)
    }
  }
}
</script>
<style scoped lang="scss">
@import "@/assets/style/variables.scss";
// è¾“入框高度
$input-height: 32px;
.global-window {
  top: 80px !important;
  left: 218px !important;
  // å¤´éƒ¨æ ‡é¢˜
  ::v-deep .el-drawer__header {
    padding: 0 10px 0 0;
    line-height: 40px;
    border-bottom: 1px solid #eee;
    // text-align: center;
    font-weight: 500;
    color: #222;
    // è¿”回按钮
    .header__btn-back {
      display: inline-block;
      width: 30px;
      background: $primary-color;
      color: #fff;
      text-align: center;
      margin-right: 12px;
      border-right: 1px solid #eee;
    }
    .el-drawer__close-btn:focus {
      outline: none;
    }
  }
  // ä¸»ä½“
  ::v-deep .el-drawer__body {
    display: flex;
    flex-direction: column;
    position: absolute;
    top: 40px;
    bottom: 0;
    width: 100%;
    overflow: hidden;
    // background-color: #f7f7f7;
    // å†…容
    .window__body {
      // width: 1100px;
      // margin: 0 auto;
      // background-color: #fff;
      width: 100%;
      height: 100%;
      overflow-y: auto;
      padding: 0;
      // æ ‡ç­¾
      .el-form-item__label {
        float: none;
      }
      // å…ƒç´ å®½åº¦ä¸º100%
      .el-form-item__content > *{
        width: 100%;
      }
    }
    // å°¾éƒ¨
    .window__footer {
      user-select: none;
      border-top: 1px solid #eee;
      height: 60px;
      line-height: 60px;
      text-align: center;
    }
  }
}
</style>
company/src/components/common/GlobalWindow.vue
@@ -8,18 +8,20 @@
    :close-on-press-escape="false"
    :wrapper-closable="false"
    :append-to-body="true"
    :modal="false"
    @close="close"
  >
    <div slot="title" class="window__header">
      <span class="header__btn-back" @click="close"><i class="el-icon-arrow-left"></i></span>{{title}}
      <!-- {{title}} -->
    </div>
    <div class="window__body">
      <slot></slot>
    </div>
    <div v-if="withFooter" class="window__footer">
      <slot name="footer">
        <el-button @click="confirm" :loading="confirmWorking" type="primary">{{submitText}}</el-button>
        <el-button @click="close">取消</el-button>
        <el-button @click="confirm" :loading="confirmWorking" type="primary">确定</el-button>
        <el-button @click="close">返回</el-button>
      </slot>
    </div>
  </el-drawer>
@@ -31,7 +33,7 @@
  props: {
    width: {
      type: String,
      default: '36%'
      default: '100%'
    },
    // æ˜¯å¦åŒ…含底部操作
    withFooter: {
@@ -52,11 +54,6 @@
    visible: {
      type: Boolean,
      required: true
    },
    // ç¡®è®¤æŒ‰é’®æ–‡å­—
    submitText: {
      type: String,
      default: '确定'
    }
  },
  methods: {
@@ -75,11 +72,16 @@
// è¾“入框高度
$input-height: 32px;
.global-window {
  top: 80px !important;
  left: 218px !important;
  // å¤´éƒ¨æ ‡é¢˜
  /deep/ .el-drawer__header {
  ::v-deep .el-drawer__header {
    padding: 0 10px 0 0;
    line-height: 40px;
    border-bottom: 1px solid #eee;
    // text-align: center;
    font-weight: 500;
    color: #222;
    // è¿”回按钮
    .header__btn-back {
      display: inline-block;
@@ -95,7 +97,7 @@
    }
  }
  // ä¸»ä½“
  /deep/ .el-drawer__body {
  ::v-deep .el-drawer__body {
    display: flex;
    flex-direction: column;
    position: absolute;
@@ -103,15 +105,20 @@
    bottom: 0;
    width: 100%;
    overflow: hidden;
    // background-color: #f7f7f7;
    // å†…容
    .window__body {
      // width: 1100px;
      // margin: 0 auto;
      // background-color: #fff;
      width: 100%;
      height: 100%;
      overflow-y: auto;
      padding: 12px 16px;
      // æ ‡ç­¾
      .el-form-item__label {
        float: none;
      }
      // .el-form-item__label {
      //   float: none;
      // }
      // å…ƒç´ å®½åº¦ä¸º100%
      .el-form-item__content > *{
        width: 100%;
company/src/components/common/Header.vue
@@ -1,156 +1,30 @@
<template>
  <div class="main-header">
    <div class="header">
<!--      <h2>-->
<!--        <i class="el-icon-s-unfold" v-if="menuData.collapse" @click="switchCollapseMenu(null)"></i>-->
<!--        <i class="el-icon-s-fold" v-else @click="switchCollapseMenu(null)"></i>-->
<!--        {{title}}-->
<!--      </h2>-->
      <div class="user">
<!--        <span style="font-size: 13px">{{ userInfo.company.name }}</span>-->
        <el-dropdown trigger="click">
          <span class="el-dropdown-link">
            <img v-if="userInfo != null" :src="userInfo.avatar == null ? '@/assets/images/avatar/man.png' : userInfo.avatar" alt="">{{userInfo | displayName}}<i class="el-icon-arrow-down el-icon--right"></i>
          </span>
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item @click.native="changePwd">修改密码</el-dropdown-item>
            <el-dropdown-item @click.native="logout">退出登录</el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
      </div>
      <h2>
        <i class="el-icon-s-unfold" v-if="menuData.collapse" @click="switchCollapseMenu(null)"></i>
        <i class="el-icon-s-fold" v-else @click="switchCollapseMenu(null)"></i>
        {{title}}
      </h2>
      <tagsview class="tags"></tagsview>
    </div>
    <!-- ä¿®æ”¹å¯†ç  -->
    <GlobalWindow
      title="修改密码"
      :visible.sync="visible.changePwd"
      @confirm="confirmChangePwd"
      @close="visible.changePwd = false"
    >
      <el-form :model="changePwdData.form" ref="changePwdDataForm" :rules="changePwdData.rules">
        <el-form-item label="原始密码" prop="oldPwd" required>
          <el-input v-model="changePwdData.form.oldPwd" type="password" placeholder="请输入原始密码" maxlength="30" show-password></el-input>
        </el-form-item>
        <el-form-item label="新密码" prop="newPwd" required>
          <el-input v-model="changePwdData.form.newPwd" type="password" placeholder="请输入新密码" maxlength="30" show-password></el-input>
        </el-form-item>
        <el-form-item label="确认新密码" prop="confirmPwd" required>
          <el-input v-model="changePwdData.form.confirmPwd" type="password" placeholder="请再次输入新密码" maxlength="30" show-password></el-input>
        </el-form-item>
      </el-form>
    </GlobalWindow>
  </div>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
import GlobalWindow from './GlobalWindow'
import { logout, updatePwd } from '@/api/system/common'
import tagsview from "./tagsview.vue"
export default {
  name: 'Header',
  components: { GlobalWindow },
  data () {
    return {
      visible: {
        // ä¿®æ”¹å¯†ç 
        changePwd: false
      },
      isWorking: {
        // ä¿®æ”¹å¯†ç 
        changePwd: false
      },
      username: 'bob', // ç”¨æˆ·å
      // ä¿®æ”¹å¯†ç å¼¹æ¡†
      changePwdData: {
        form: {
          oldPwd: '',
          newPwd: '',
          confirmPwd: ''
        },
        rules: {
          oldPwd: [
            { required: true, message: '请输入原始密码' }
          ],
          newPwd: [
            { required: true, message: '请输入新密码' }
          ],
          confirmPwd: [
            { required: true, message: '请再次输入新密码' }
          ]
        }
      }
    }
  },
  components: { tagsview },
  computed: {
    ...mapState(['menuData', 'userInfo']),
    ...mapState(['menuData']),
    title () {
      return this.$route.meta.title
    }
  },
  filters: {
    // å±•示名称
    displayName (userInfo) {
      if (userInfo == null) {
        return ''
      }
      // if (userInfo.realname != null && userInfo.realname.trim().length > 0) {
      //   return userInfo.realname
      // }
      return userInfo.username
    }
  },
  methods: {
    ...mapMutations(['setUserInfo', 'switchCollapseMenu']),
    // ä¿®æ”¹å¯†ç 
    changePwd () {
      this.visible.changePwd = true
      this.$nextTick(() => {
        this.$refs.changePwdDataForm.resetFields()
      })
    },
    // ç¡®å®šä¿®æ”¹å¯†ç 
    confirmChangePwd () {
      if (this.isWorking.changePwd) {
        return
      }
      this.$refs.changePwdDataForm.validate((valid) => {
        if (!valid) {
          return
        }
        // éªŒè¯ä¸¤æ¬¡å¯†ç è¾“入是否一致
        if (this.changePwdData.form.newPwd !== this.changePwdData.form.confirmPwd) {
          this.$tip.warning('两次密码输入不一致')
          return
        }
        // æ‰§è¡Œä¿®æ”¹
        this.isWorking.changePwd = true
        updatePwd({
          oldPwd: this.changePwdData.form.oldPwd,
          newPwd: this.changePwdData.form.newPwd
        })
          .then(() => {
            this.$tip.apiSuccess('修改成功')
            this.visible.changePwd = false
          })
          .catch(e => {
            this.$tip.apiFailed(e)
          })
          .finally(() => {
            this.isWorking.changePwd = false
          })
      })
    },
    // é€€å‡ºç™»å½•
    logout () {
      logout()
        .then(() => {
          this.setUserInfo(null)
          location.reload()
          // this.$router.push({ name: 'login' })
        })
        .catch(e => {
          this.$tip.apiFailed(e)
        })
    }
    ...mapMutations(['switchCollapseMenu']),
  }
}
</script>
@@ -163,54 +37,23 @@
  background: #fff;
  height: 100%;
  display: flex;
  overflow: hidden;
  h2 {
    width: 50%;
    flex-shrink: 0;
    line-height: $header-height;
    line-height: 48px;
    width: 200px;
    font-size: 19px;
    font-weight: 600;
    color: #606263;
    font-weight: normal;
    display: inline;
    & > i {
      font-size: 20px;
      margin-right: 12px;
    }
  }
  .user {
    width: 50%;
    flex-shrink: 0;
    text-align: right;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    text {
      font-size: 18px !important;
      color: #222222;
    }
    .el-dropdown-link {
      height: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    .el-dropdown {
      top: 2px;
      height: 100%;
    }
    img {
      width: 32px;
      position: relative;
      // top: 10px;
      margin-right: 10px;
    }
  }
}
// ä¸‹æ‹‰èœå•框
.el-dropdown-menu {
  width: 140px;
  .el-dropdown-menu__item:hover {
    background: #E3EDFB;
    color: $primary-color;
  }
}
// .tags {
//     padding-bottom: 16px;
//   }
</style>
company/src/components/common/ImportButton.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,37 @@
<template>
  <div class="import-button">
    <el-button type="primary" @click="$refs.importWindow.open(text)">{{text}}</el-button>
    <ImportWindow :action="action" :template-path="templatePath" :template-name="templateName" ref="importWindow" @download="$emit('download')" @success="handleSuccess"/>
  </div>
</template>
<script>
import ImportWindow from './ImportWindow'
export default {
  name: 'ImportButton',
  components: { ImportWindow },
  props: {
    // æŒ‰é’®æ–‡æ¡ˆ
    text: {
      default: '导入'
    },
    // æ¨¡ç‰ˆåœ°å€
    templatePath: {
      required: true
    },
    // ä¸‹è½½åŽçš„æ¨¡ç‰ˆæ–‡ä»¶åç§°
    templateName: {
      required: true
    },
    // å¯¼å…¥æŽ¥å£åœ°å€
    action: {
      required: true
    }
  },
  methods: {
    handleSuccess () {
      this.$emit('success')
    }
  }
}
</script>
company/src/components/common/ImportWindow.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,204 @@
<template>
  <el-dialog
    width="500px"
    :title="title"
    :visible.sync="visible"
    append-to-body
    custom-class="eva-dialog import-window"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    :show-close="false"
  >
    <el-form>
      <el-form-item>
        <el-upload
          drag
          :show-file-list="false"
          action="none"
          accept=".xlsx, .xls"
          :before-upload="handleBeforeUpload"
        >
          <template v-if="form.file == null">
            <i class="el-icon-upload"></i>
            <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
          </template>
          <template v-else>
            <i class="el-icon-files"></i>
            <div class="el-upload__text">{{form.file.name}}<em></em></div>
          </template>
        </el-upload>
      </el-form-item>
    </el-form>
    <div slot="footer" class="import-window__footer">
      <!-- <div class="sync-exists">
        <el-checkbox v-model="form.sync"/><span>同步已存在的数据</span>
      </div> -->
      <div class="opera">
        <a href=""></a>
        <el-button type="text" icon="el-icon-download" @click="downloadTemplate">下载模版</el-button>
        <el-button @click="cancel">{{cancelText}}</el-button>
        <el-button type="primary" @click="confirm" :loading="isWorking">{{confirmText}}</el-button>
      </div>
    </div>
  </el-dialog>
</template>
<script>
import request from '@/utils/request'
export default {
  name: 'ImportWindow',
  props: {
    // å¯¼å…¥æŽ¥å£åœ°å€
    action: {
      required: true
    },
    // ç¡®è®¤æŒ‰é’®æ–‡æ¡ˆ
    confirmText: {
      type: String,
      default: '导入'
    },
    // å–消按钮文案
    cancelText: {
      type: String,
      default: '取消'
    },
    // æ¨¡ç‰ˆåœ°å€
    templatePath: {
      required: true
    },
    // ä¸‹è½½åŽçš„æ¨¡ç‰ˆæ–‡ä»¶åç§°
    templateName: {
      required: true
    }
  },
  data () {
    return {
      visible: false,
      isWorking: false,
      title: '导入数据',
      form: {
        sync: false,
        file: false,
        categoryId: ''
      }
    }
  },
  methods: {
    /**
     * æ‰“开窗口
     *
     * @param title çª—口标题
     */
    open (title) {
      this.visible = true
      this.title = title
      this.form.sync = false
      this.form.file = null
    },
    /**
     * ç¡®å®šå¯¼å…¥
     */
    confirm () {
      if (this.form.file == null) {
        this.$tip.warning('请选择文件')
        return
      }
      this.isWorking = true
      const param = new FormData()
      param.set('file', this.form.file)
      request.post(this.action, param, {
        headers: {
          'Content-Type': 'multipart/form-data;charset=UTF-8'
        }
      })
        .then(() => {
          this.$tip.success('导入成功')
          this.visible = false
          this.$emit('success')
        })
        .catch(e => {
          this.$tip.apiFailed(e)
        })
        .finally(() => {
          this.isWorking = false
        })
    },
    /**
     * å–消
     */
    cancel () {
      this.visible = false
    },
    /**
     * ä¸‹è½½æ¨¡ç‰ˆ
     */
    downloadTemplate () {
      const link = document.createElement('a')
      link.setAttribute('download', this.templateName) //下载的文件名
      console.log(`${window.location.origin}${process.env.VUE_APP_CONTEXT_PATH}${this.templatePath}`);
      link.href = `${window.location.origin}${process.env.VUE_APP_CONTEXT_PATH}${this.templatePath}`  //文件url
      link.click()
      // this.$emit('download')
    },
    /**
     * æ–‡ä»¶ä¸Šä¼ å‰å­˜å‚¨ä¸Šä¼ çš„æ–‡ä»¶
     *
     * @param file éœ€å¯¼å…¥çš„æ–‡ä»¶
     */
    handleBeforeUpload (file) {
      this.form.file = file
      return false
    }
  }
}
</script>
<style lang="scss">
@import "../../assets/style/variables";
.import-window {
  .el-upload {
    width: 100%;
    .el-upload-dragger {
      width: 100%;
      .el-icon-upload, .el-icon-files {
        font-size: 67px;
        color: #C0C4CC;
        margin: 40px 0 16px;
        line-height: 50px;
      }
    }
  }
  .import-window__footer {
    display: flex;
    .sync-exists {
      width: 200px;
      flex-shrink: 0;
      text-align: left;
      font-size: 13px;
      display: flex;
      align-items: center;
      .el-checkbox {
        margin-right: 10px;
      }
      & > * {
        vertical-align: middle;
      }
    }
    .opera {
      flex-grow: 1;
      a {
        font-size: 12px;
        margin-right: 10px;
        text-decoration: none;
        .el-icon-download {
          font-size: 15px;
          position: relative;
          top: 2px;
        }
      }
    }
  }
}
</style>
company/src/components/common/Light.vue
@@ -28,13 +28,16 @@
$cycle-size01: 16px;
$cycle-size02: 6px;
$normal-color: #00CC99;
$shadow-color: #00CCa9;
$warn-color: #FFCC33;
$warn-shadow-color: #FFCbe3;
$danger-color: #FF3300;
$dange-shadowr-color: #FF3310;
@mixin light-status ($cycle-bg) {
  em {
    background: $cycle-bg;
    i {
      background: $cycle-bg - 30;
      background: mix($cycle-bg,  #000030, 0.5);
    }
  }
}
@@ -79,44 +82,44 @@
}
@keyframes shine-normal {
  0% {
    box-shadow: 0 0 5px $normal-color + 10;
    box-shadow: 0 0 5px $shadow-color;
  }
  25% {
    box-shadow: 0 0 10px $normal-color + 10;
    box-shadow: 0 0 10px $shadow-color;
  }
  50% {
    box-shadow: 0 0 15px $normal-color + 10;
    box-shadow: 0 0 15px $shadow-color;
  }
  100% {
    box-shadow: 0 0 20px $normal-color + 10;
    box-shadow: 0 0 20px $shadow-color;
  }
}
@keyframes shine-warn {
  0% {
    box-shadow: 0 0 5px $warn-color - 50;
    box-shadow: 0 0 5px $warn-shadow-color;
  }
  25% {
    box-shadow: 0 0 10px $warn-color - 50;
    box-shadow: 0 0 10px $warn-shadow-color;
  }
  50% {
    box-shadow: 0 0 15px $warn-color - 50;
    box-shadow: 0 0 15px $warn-shadow-color;
  }
  100% {
    box-shadow: 0 0 20px $warn-color - 50;
    box-shadow: 0 0 20px $warn-shadow-color;
  }
}
@keyframes shine-danger {
  0% {
    box-shadow: 0 0 5px $danger-color + 10;
    box-shadow: 0 0 5px $dange-shadowr-color;
  }
  25% {
    box-shadow: 0 0 10px $danger-color + 10;
    box-shadow: 0 0 10px $dange-shadowr-color;
  }
  50% {
    box-shadow: 0 0 15px $danger-color + 10;
    box-shadow: 0 0 15px $dange-shadowr-color;
  }
  100% {
    box-shadow: 0 0 20px $danger-color + 10;
    box-shadow: 0 0 20px $dange-shadowr-color;
  }
}
</style>
company/src/components/common/Menu.vue
@@ -1,19 +1,15 @@
<template>
  <div class="menu" :class="{collapse: menuData.collapse}">
    <div class="logo">
      <div><img src="@/assets/logo.png"></div>
      <h1 :class="{ hidden: menuData.collapse }">云易保</h1>
    </div>
    <scrollbar>
<!--      :default-openeds="defaultOpeneds"-->
      <el-menu
        ref="menu"
        :unique-opened="true"
        :default-active="activeIndex"
        text-color="#fff"
        active-text-color="#fff"
        :collapse="menuData.collapse"
        :default-openeds="defaultOpeneds"
        :collapse-transition="false"
        unique-opened
        @select="handleSelect"
      >
        <MenuItems v-for="menu in menuData.list" :key="menu.index" :menu="menu" :is-root-menu="true"/>
@@ -40,12 +36,17 @@
      const menuConfig = this.__getMenuConfig(path, 'url', this.menuData.list)
      if (menuConfig == null) {
        return null
      } else {
        this.$store.commit("pushtags", menuConfig)
      }
      // console.log(menuConfig.index);
      return menuConfig.index
    },
    // é»˜è®¤å±•开的菜单index
    defaultOpeneds () {
      return this.menuData.list.map(menu => menu.index)
      // return this.menuData.list.map(menu => menu.index)
      return [this.menuData.list[0].index]
    }
  },
  methods: {
@@ -65,7 +66,9 @@
      if (menuConfig.url == null || menuConfig.url.trim().length === 0) {
        return
      }
      this.$router.push(menuConfig.url)
      this.$store.commit("pushtags", menuConfig)
    },
    // èŽ·å–èœå•é…ç½®
    __getMenuConfig (value, key, menus) {
@@ -92,37 +95,6 @@
  height: 100%;
  display: flex;
  flex-direction: column;
  // LOGO
  .logo {
    height: 60px;
    flex-shrink: 0;
    line-height: 60px;
    overflow: hidden;
    display: flex;
    background: $primary-color - 20;
    padding: 0 16px;
    & > div {
      width: 32px;
      flex-shrink: 0;
      margin-right: 12px;
      img {
        width: 100%;
        flex-shrink: 0;
        vertical-align: middle;
        position: relative;
        top: -2px;
      }
    }
    h1 {
      font-size: 16px;
      font-weight: 500;
      transition: opacity ease .3s;
      overflow: hidden;
      &.hidden {
        opacity: 0;
      }
    }
  }
}
</style>
<style lang="scss">
@@ -136,11 +108,11 @@
    background: $primary-color;
    // é€‰ä¸­çŠ¶æ€
    &.is-active {
      background: $primary-color - 40 !important;
      background: $primary-color-sel !important;
    }
    // æ‚¬æµ®
    &:hover {
      background-color: $primary-color - 12;
      background-color: $primary-color-hover;
    }
    &:focus {
      background: $primary-color;
@@ -153,13 +125,13 @@
    }
    &.is-active {
      .el-submenu__title{
        background-color: $primary-color - 20;
        background-color: $icon-background-color;
      }
      .el-menu .el-menu-item{
        background-color: $primary-color - 20;
        background-color: $icon-background-color;
        // æ‚¬æµ®
        &:hover {
          background-color: $primary-color - 30;
          background-color: $icon-background-color;
        }
      }
    }
company/src/components/common/Pagination.vue
@@ -2,7 +2,7 @@
  <div class="table-pagination">
    <el-pagination
      :current-page="pagination.pageIndex"
      :page-sizes="[10, 20, 30, 40]"
      :page-sizes="pagination.pageSizes||[10, 20, 30, 40]"
      :page-size="pagination.pageSize"
      layout="total, sizes, prev, pager, next, jumper"
      :total="pagination.total"
company/src/components/common/PositionSelect.vue
@@ -93,7 +93,7 @@
}
.vue-treeselect {
  line-height: 30px;
  /deep/ .vue-treeselect__control {
  ::deep .vue-treeselect__control {
    height: 32px;
    .vue-treeselect__single-value {
      line-height: 30px;
company/src/components/common/RichEditor.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,158 @@
<template>
  <div style="border: 1px solid #ccc;">
    <Toolbar
      style="border-bottom: 1px solid #ccc"
      :editor="editor"
      :defaultConfig="toolbarConfig"
      :mode="mode"
    />
    <Editor
      style="height: 300px; overflow-y: hidden;"
      :value="content.content"
      :mode="mode"
      :defaultConfig="editorConfig"
      @onCreated="onCreated"
      @onChange="onChange"
      @input="html=$event"
    />
  </div>
</template>
<script>
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
export default {
  name: 'RichEditor',
  components: { Editor, Toolbar },
  props: {
    content: {
      type: Object,
      default: () => {}
    }
  },
  data() {
    return {
      editor: null,
      html: '<p><br></p>',
      toolbarConfig: {
        toolbarKeys: [
          "headerSelect",
          "blockquote",
          "|",
          "bold",
          "underline",
          "italic",
          {
              "key": "group-more-style",
              "title": "更多",
              "iconSvg": "<svg viewBox=\"0 0 1024 1024\"><path d=\"M204.8 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z\"></path><path d=\"M505.6 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z\"></path><path d=\"M806.4 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z\"></path></svg>",
              "menuKeys": [
                  "through",
                  "code",
                  "sup",
                  "sub",
                  "clearStyle"
              ]
          },
          "color",
          "bgColor",
          "|",
          "fontSize",
          "fontFamily",
          "lineHeight",
          "|",
          "bulletedList",
          "numberedList",
          "todo",
          {
              "key": "group-justify",
              "title": "对齐",
              "iconSvg": "<svg viewBox=\"0 0 1024 1024\"><path d=\"M768 793.6v102.4H51.2v-102.4h716.8z m204.8-230.4v102.4H51.2v-102.4h921.6z m-204.8-230.4v102.4H51.2v-102.4h716.8zM972.8 102.4v102.4H51.2V102.4h921.6z\"></path></svg>",
              "menuKeys": [
                  "justifyLeft",
                  "justifyRight",
                  "justifyCenter",
                  "justifyJustify"
              ]
          },
          {
              "key": "group-indent",
              "title": "缩进",
              "iconSvg": "<svg viewBox=\"0 0 1024 1024\"><path d=\"M0 64h1024v128H0z m384 192h640v128H384z m0 192h640v128H384z m0 192h640v128H384zM0 832h1024v128H0z m0-128V320l256 192z\"></path></svg>",
              "menuKeys": [
                  "indent",
                  "delIndent"
              ]
          },
          // "|",
          "emotion",
          "insertLink",
          {
              "key": "group-image",
              "title": "图片",
              "iconSvg": "<svg viewBox=\"0 0 1024 1024\"><path d=\"M959.877 128l0.123 0.123v767.775l-0.123 0.122H64.102l-0.122-0.122V128.123l0.122-0.123h895.775zM960 64H64C28.795 64 0 92.795 0 128v768c0 35.205 28.795 64 64 64h896c35.205 0 64-28.795 64-64V128c0-35.205-28.795-64-64-64zM832 288.01c0 53.023-42.988 96.01-96.01 96.01s-96.01-42.987-96.01-96.01S682.967 192 735.99 192 832 234.988 832 288.01zM896 832H128V704l224.01-384 256 320h64l224.01-192z\"></path></svg>",
              "menuKeys": [
                  "insertImage",
                  "uploadImage"
              ]
          },
          "insertTable",
          "codeBlock",
          "divider",
          "|",
          "undo",
          "redo",
          "|",
          "fullScreen"
        ]
      },
      editorConfig: {
        placeholder: '请输入内容...',
        MENU_CONF: {
          uploadImage: {
            // server: '/api/upload',
            name: 'file',
            server: process.env.VUE_APP_API_PREFIX + '/public/uploadLocal',
            meta: {
              folder: 'shop'
            },
            onBeforeUpload(file) {    // JS è¯­æ³•
              // file é€‰ä¸­çš„æ–‡ä»¶ï¼Œæ ¼å¼å¦‚ { key: file }
              // debugger
              return file
            },
            onSuccess(file, res) {
                console.log(`${file.name} ä¸Šä¼ æˆåŠŸ`, res)
            },
            onError(file, err, res) {
              console.log(`${file.name} ä¸Šä¼ å‡ºé”™`, err, res)
            },
          },
        }
      },
      mode: 'default', // or 'simple'
    }
  },
  beforeDestroy() {
    const editor = this.editor
    if (editor == null) return
    editor.destroy() // ç»„件销毁时,及时销毁编辑器
  },
  methods: {
    onCreated (editor) {
      this.editor = Object.seal(editor)
    },
    onChange (editor) {
      console.log(this.html);
      // debugger
      if (!this.html||this.content.content==this.html) {
        return
      }
      this.$emit('edit', this.html)
    },
  },
}
</script>
<style src="@wangeditor/editor/dist/css/style.css"></style>
company/src/components/common/SearchFormCollapse.vue
@@ -31,7 +31,7 @@
    height: 50px;
    overflow: hidden;
    padding-right: 250px;
    /deep/ section {
    ::v-deep section {
      position: absolute;
      top: 0;
      right: 100px;
company/src/components/common/ShowRich.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,42 @@
<template>
  <GlobalAlertWindow
    :title="title"
    :visible.sync="visible"
    :confirm-working="isWorking"
    @confirm="confirm"
  >
    <Editor v-if="form.content" v-model="form.content" :defaultConfig="{ readOnly : true }" />
    <div slot="footer"></div>
  </GlobalAlertWindow>
</template>
<script>
import BaseOpera from '@/components/base/BaseOpera'
import GlobalAlertWindow from '@/components/common/GlobalAlertWindow'
import { Editor } from '@wangeditor/editor-for-vue'
export default {
  name: 'ShowRich',
  extends: BaseOpera,
  components: { GlobalAlertWindow, Editor },
  data () {
    return {
      // è¡¨å•数据
      form: {
        content: ''
      },
      // éªŒè¯è§„则
      rules: {
      }
    }
  },
  created () {
    this.config({
      api: '/business/areas',
      'field.id': 'id'
    })
  },
  methods: {
  },
}
</script>
company/src/components/common/Tree.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,135 @@
<template>
    <div class="tree">
        <div v-for="(item, index) of list" :key="index" @click.stop="clickIten(item)">
            <div class="tree_item">
                <i class="el-icon-caret-bottom" :class="{ 'activeColor': item[defaultProps.status] }" v-show="item[defaultProps.status] && item[defaultProps.children]"></i>
                <i class="el-icon-caret-right color" v-show="item[defaultProps.children] && !item[defaultProps.status]"></i>
                <div class="tree_item_label long-title-style" :title="item[defaultProps.name]" :class="{ 'activeColor': item[defaultProps.status] && !item[defaultProps.children] }">{{ item[defaultProps.name] }}</div>
            </div>
            <div class="tree_childern" v-show="item[defaultProps.status]">
                <tree
                  :list="item[defaultProps.children]"
                  :defaultProps="defaultProps"
                  @callback="callback"
                />
                 <!-- @callback="callback" -->
            </div>
        </div>
    </div>
</template>
<script>
// import Bus from '@/utils/eventBus'
export default {
  name: 'tree',
  props: {
    list: {
      type: Array,
      required: false,
      default: () => []
    },
    defaultProps: {
      type: Object,
      require: false,
      default: () => {
        return {
          name: 'name',
          status: 'status',
          children: 'children',
          id: 'id'
        }
      }
    }
  },
  data() {
    return {
      tempItem: {
        id: null,
        name: null
      }
    }
  },
  methods: {
    // ç‚¹å‡»å½“前项
    clickIten (item) {
      item[this.defaultProps.status] = !item[this.defaultProps.status]
      this.list.forEach(subItem => {
        if ((subItem[this.defaultProps.id] !== item[this.defaultProps.id] && subItem[this.defaultProps.status]) || (this.list.length === 1 && subItem[this.defaultProps.status] === false)) {
          subItem[this.defaultProps.status] = false
          if (subItem[this.defaultProps.children]) {
            this.recursion(subItem[this.defaultProps.children])
          }
        }
      })
      if (this.tempItem['id'] === item[this.defaultProps.id]) {
        this.tempItem = {
          id: null,
          name: null
        }
      } else {
        this.tempItem.id = item[this.defaultProps.id]
        this.tempItem.name = item[this.defaultProps.name]
      }
      this.$emit('callback', this.tempItem, item)
    },
    // é€’归方法
    recursion (children) {
      children.forEach(item => {
        item[this.defaultProps.status] = false
        if (item[this.defaultProps.children]) {
          this.recursion(item[this.defaultProps.children])
        }
      })
    },
    callback (data, item) {
      if (this.tempItem.id === data.id) {
        this.tempItem = {}
      } else {
        this.tempItem.id = data.id
        this.tempItem.name = data.name
      }
      this.$emit('callback', this.tempItem, item)
    }
  }
}
</script>
<style lang="scss" scoped>
.tree {
    /*width: 100%;*/
    /*height: auto;*/
    /*border-radius: 5px;*/
    /*overflow: hidden;*/
    /*border: 1px solid #eeeeee;*/
    /*box-sizing: border-box;*/
    .tree_childern {
        margin-left: 20px;
    }
    .activeItem {
        background: #F4F7FC;
    }
    .tree_item {
        display: flex;
        align-items: center;
        height: 48px;
        cursor: pointer;
        padding-left: 10px;
        .tree_item_label {
            font-size: 14px;
            font-weight: 400;
            color: #333333;
            white-space: nowrap;
        }
        i {
            margin-right: 5px;
        }
        .color {
            color: #999999 !important;
        }
        .activeColor {
            color: #305ED5 !important;
        }
    }
}
</style>
company/src/components/common/TreeSelect.vue
@@ -57,7 +57,7 @@
  }
  .vue-treeselect {
    line-height: 30px;
    /deep/ .vue-treeselect__control {
    ::v-deep .vue-treeselect__control {
      height: 32px;
      .vue-treeselect__single-value {
        line-height: 30px;
company/src/components/common/UploadAvatarImage.vue
@@ -1,18 +1,18 @@
<template>
  <div>
    <el-upload
      :style="customStyle"
      class="avatar-uploader"
      accept=".png,.jpg"
      :action="uploadImgUrl"
      :data="uploadData"
      :show-file-list="false"
      :on-success="handleAvatarSuccess"
      :on-error="uploadError"
      :before-upload="beforeAvatarUpload">
      <img v-if="file.imgurlfull" :src="file.imgurlfull" :style="customStyle" class="avatar">
      <div v-else :style="customStyle">
        <i class="el-icon-plus avatar-uploader-icon"></i>
        <div class="tips-style">{{ tipsLabel }}</div>
      </div>
      <template v-if="file.imgurlfull">
        <img :src="file.imgurlfull" class="avatar">
      </template>
      <i v-else class="el-icon-plus avatar-uploader-icon"></i>
    </el-upload>
  </div>
@@ -25,16 +25,16 @@
      type: Object,
      default: () => {}
    },
    uploadData: Object,
    tipsLabel: '',
    customStyle: {
      type: String,
      default: 'width: 90px; height: 90px;'
    }
    uploadData: Object
  },
  data() {
    return {
      uploadImgUrl: process.env.VUE_APP_API_PREFIX + '/public/upload'
      uploadImgUrl: process.env.VUE_APP_API_PREFIX + '/public/uploadLocal',
      // uploadData: {
      //   folder: 'upload',
      //   type: 'image'
      // },
      imgurlfull: ''
    }
  },
@@ -42,36 +42,41 @@
    // ä¸Šä¼ å›¾ç‰‡
    handleAvatarSuccess(res, file) {
      if (res.code == 200) {
        let { data } = res
        this.file.imgurl = data.imgaddr;
        this.file.imgurlfull = data.url;
        this.$message.success('上传成功')
        this.$emit('uploadSuccess', { imgurl: data.imgaddr, imgurlfull: data.url, name: data.originname })
        this.file.imgurl = res.data.imgaddr;
        this.file.imgurlfull = res.data.url;
        this.$tip.apiSuccess('上传成功')
        this.$emit('uploadSuccess', { imgurl: res.data.imgaddr, imgurlfull: res.data.url })
      } else {
        this.$message.error('上传失败')
        this.$tip.apiFailed('上传失败')
      }
      this.$emit('uploadEnd')
    },
    uploadError() {
      this.$message.error('上传失败')
      this.$tip.apiFailed('上传失败')
      this.$emit('endUpload')
    },
    // // æ‹¦æˆª
    beforeAvatarUpload(file) {
      this.$emit('uploadBegin')
      return true;
    },
  },
      return true
    }
  }
}
</script>
<style lang="scss" scoped>
$image-width: 100px;
.avatar-uploader {
  width: $image-width;
  height: $image-width;
}
::v-deep .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  width: $image-width;
  height: $image-width;
  overflow: hidden;
}
.avatar-uploader .el-upload:hover {
@@ -80,18 +85,34 @@
.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  line-height: 90px;
  width: $image-width;
  height: $image-width;
  line-height: $image-width;
  text-align: center;
}
.avatar {
  width: $image-width;
  height: $image-width;
  display: block;
}
.tips-style {
  height: 13px;
  font-size: 13px;
  font-weight: 400;
  color: #999999;
  line-height: 13px;
</style>
<style lang="scss" scoped>
::v-deep .el-upload--picture-card{
  width: 90px !important;
  height: 90px !important;
}
::v-deep .el-upload-list__item {
  width: 90px !important;
  height: 90px !important;
}
.icon {
  -webkit-transform: translate(-50%,-50%);
  -ms-transform: translate(-50%,-50%);
  transform: translate(0%, -85%);
}
::v-deep .el-upload-list__item {
  width: 90px !important;
  height: 90px !important;
}
</style>
company/src/components/common/UploadImage.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,155 @@
<template>
  <div>
    <el-upload
      :action="uploadImgUrl"
      :data="uploadData"
      list-type="picture-card"
      :file-list="fileList"
      accept=".jpg,.png"
      :before-upload="beforeUpload"
      :on-success="uploadSuccess"
      :on-error="fail"
    >
      <i class="el-icon-plus icon"></i>
      <div slot="file" slot-scope="{file}">
        <img
          class="el-upload-list__item-thumbnail"
          :src="file.url" alt=""
          style="width: 100px;height: 100px;"
        >
        <span class="el-upload-list__item-actions">
          <span
            class="el-upload-list__item-preview"
            @click="handlePictureCardPreview(file)"
          >
            <i class="el-icon-zoom-in"></i>
          </span>
          <span
            class="el-upload-list__item-delete"
            @click="handleRemove(file)"
          >
            <i class="el-icon-delete"></i>
          </span>
        </span>
      </div>
    </el-upload>
    <el-image-viewer
      v-if="showViewer"
      :on-close="closeViewer"
      :initialIndex="tempIndex"
      :url-list="srcList"
      :z-index="3000"
    />
  </div>
</template>
<script>
import ElImageViewer from 'element-ui/packages/image/src/image-viewer'
export default {
  components: {
    ElImageViewer
  },
  props: {
    fileList: {
      type: Array,
      default: () => []
    },
    uploadData: Object,
  },
  data() {
    return {
      uploadImgUrl: process.env.VUE_APP_API_PREFIX + '/public/uploadLocal',
      realList: [],
      srcList: [],
      tempIndex: 0,
      showViewer: false,
    }
  },
  watch: {
    fileList: {
      handler(val) {
        console.log(val);
        if (val.length==0) {
          this.realList = []
          this.srcList = []
        }
      }
    }
  },
  methods: {
    beforeUpload(file) {
      this.$emit('beginUpload')
      return true
    },
     // ä¸Šä¼ å›¾ç‰‡æˆåŠŸ
     uploadSuccess (res, file, fileList) {
      // console.log('this.fileList', this.fileList);
      // console.log('fileList', fileList);
      this.$emit('endUpload')
      this.realList = fileList
      this.srcList.push(res.data.url)
      // console.log('file', file);
      if (res.code === 200) {
        this.fileList.push(
          {
            fileurl: res.data.imgaddr,
            name: res.data.originname,
            url: res.data.url
          }
        )
      } else {
        this.$message.error(res.msg || '上传失败')
      }
    },
    fail (err, file, fileList) {
      this.$emit('endUpload')
      this.$message.error('上传失败')
    },
    handlePictureCardPreview(file) {
      // this.tempIndex = this.srcList.findIndex(item => item == file.response.data.url )
      // console.log(file);
      this.tempIndex = this.fileList.findIndex(item => item.url == file.url )
      // console.log( this.tempIndex);
      this.srcList = this.fileList.map(item => item.url)
      this.showViewer = true
    },
    closeViewer() {
      this.showViewer = false
    },
    handleRemove(file) {
      console.log(this.fileList);
      let tempIndex = this.realList.findIndex(item => item.url === file.url)
      // debugger
      this.realList.splice(tempIndex, 1)
      this.fileList.splice(tempIndex, 1)
      this.srcList.splice(tempIndex, 1)
    },
  },
}
</script>
<style lang="scss" scoped>
::v-deep .el-upload--picture-card{
  width: 90px !important;
  height: 90px !important;
}
::v-deep .el-upload-list__item {
  width: 90px !important;
  height: 90px !important;
}
.icon {
  -webkit-transform: translate(-50%,-50%);
  -ms-transform: translate(-50%,-50%);
  transform: translate(0%, -85%);
}
::v-deep .el-upload-list__item {
  width: 90px !important;
  height: 90px !important;
}
</style>
company/src/components/common/myImage.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,84 @@
<template>
  <div>
    {{ src }}
    <img
      class="el-upload-list__item-thumbnail"
      :src="src" alt=""
      :style="`width: ${width}px;height: ${height}px;`"
      @click="handlePictureCardPreview()"
    >
    <el-image-viewer
      v-if="showViewer"
      :on-close="closeViewer"
      :initialIndex="tempIndex"
      :url-list="previewSrcList"
      :z-index="3000"
    />
  </div>
</template>
<script>
import ElImageViewer from 'element-ui/packages/image/src/image-viewer'
export default {
  components: {
    ElImageViewer
  },
  props: {
    src: {
      type: String,
      default: ''
    },
    width: {
      type: Number,
      default: 100
    },
    height: {
      type: Number,
      default: 100
    },
    previewSrcList: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      tempIndex: 0,
      showViewer: false,
    }
  },
  methods: {
    handlePictureCardPreview() {
      console.log(this.src);
      this.tempIndex = this.srcList.findIndex(item => item == this.src )
      this.showViewer = true
    },
    closeViewer() {
      this.showViewer = false
    },
  },
}
</script>
<style lang="scss" scoped>
::v-deep .el-upload--picture-card{
  width: 90px !important;
  height: 90px !important;
}
::v-deep .el-upload-list__item {
  width: 90px !important;
  height: 90px !important;
}
.icon {
  -webkit-transform: translate(-50%,-50%);
  -ms-transform: translate(-50%,-50%);
  transform: translate(0%, -85%);
}
::v-deep .el-upload-list__item {
  width: 90px !important;
  height: 90px !important;
}
</style>
company/src/components/common/tagsview.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,261 @@
<template>
  <div class="tags-view-style" style="display:flex; overflow-x: scroll;">
    <i class="el-icon-arrow-left btn" v-if="leftStatus" :class="leftStatus?'nor-btn':'ban-btn'" @click="scrollToStart()"></i>
    <div id="tags-box" ref="tags">
      <div
        v-for="(item, index) in tags"
        :key="index"
        :id="'tags-box-' + index"
        @contextmenu.prevent="openMenu(item,$event)"
        :class="isActive(item.url,index)?'active':''"
        class="tagsview"
        @click="tagsmenu(item, index)"
      >
        {{ item.label }}
        <!-- è¿™ä¸ªåœ°æ–¹ä¸€å®šè¦click加个stop阻止,不然会因为事件冒泡一直触发父元素的点击事件,无法跳转另一个路由 -->
        <span v-if="tags.length > 1" class="el-icon-close tagsicon" @click.stop="handleClose(item,index)"></span>
        <!-- <ul v-show="visible" class="contextmenu" :style="{left:left+'px',top:top+'px'}">
          <li @click.stop="rightClose()">关闭</li>
          <li @click.stop="cleartags($route.path)">关闭其他</li>
        </ul> -->
      </div>
    </div>
    <i class="el-icon-arrow-right btn" v-if="rightStatus"  :class="rightStatus?'nor-btn':'ban-btn'" @click="scrollToEnd()"></i>
  </div>
</template>
<script>
//这个就是导入vuex的数据,配合下面...map用
import { mapState, mapMutations } from "vuex";
export default {
  data() {
    return {
      //右键菜单隐藏对应布尔值
      visible: false,
      //右键菜单对应位置
      top: 0,
      left: 0,
      leftStatus: false,
      rightStatus: false,
    }
  },
  computed: {
    //引入vuex中state中的tags数据,一样this调用就行
    ...mapState(["tags"]),
  },
  watch:{
    //监听右键菜单的值是否为true,如果是就创建全局监听点击事件,触发closeMenu事件隐藏菜单,如果是false就删除监听
    visible(value) {
      if (value) {
        document.body.addEventListener('click', this.closeMenu)
      } else {
        document.body.removeEventListener('click', this.closeMenu)
      }
    },
    $route(to,from){
      this.tags.forEach((item, index) => {
        if (item.url === to.path) {
          let tagsDiv = document.getElementById('tags-box')
          if (index) {
            tagsDiv.scrollTo(index * 110, 0)
          } else {
            tagsDiv.scrollTo(0, 0)
          }
        }
      })
    }
  },
  mounted() {
    this.$refs.tags.addEventListener('scroll', e => {
      if (this.$refs.tags.scrollLeft > 0) {
        this.leftStatus = true
      } else {
        this.leftStatus = false
      }
      if (this.$refs.tags.scrollLeft + this.$refs.tags.clientWidth < this.$refs.tags.scrollWidth) {
       this.rightStatus = true
      } else {
        this.rightStatus = false
      }
    }, false)
  },
  methods: {
    //引入vuex中mutation方法,可以直接this.xxx调用他
    ...mapMutations(["closeTab", "cleartagsview"]),
    //点击叉叉删除的事件
    rightClose() {
      this.visible = false
      if (this.tags.length == 1) {
        return
      }
      let index = this.tags.indexOf(this.selectedTag)
      this.handleClose(this.selectedTag, index)
    },
    handleClose(item, index) {
      if (this.tags.length == 1) {
        return
      }
      //先把长度保存下来后面用来比较做判断条件
      let length = this.tags.length - 1;
      //vuex调方法,上面...map引入的vuex方法,不会这种方法的看vue官网文档
      this.closeTab(item);
      // å¦‚果关闭的标签不是当前路由的话,就不跳转
      if (item.url !== this.$route.path) {
        return;
      }
      // åˆ¤æ–­ï¼šå¦‚æžœindex和length是一样的,那就代表都是一样的长度,就是最后一位,那就往左跳转一个
      if (index === length) {
        //再判断:如果length=0,也就是说你删完了所有标签
        if (length === 0) {
          //那么再判断:如果当前路由不等于index,也就是我首页的路由
          if (this.$route.path !== "/index") {
            //那么就跳转首页。这一步的意思是:如果删除的最后一个标签不是首页就统一跳转首页,如果你删除的最后一个标签是首页标签,已经在这个首页路由上了,你还跳个什么呢。这不重复操作了吗。
            this.$router.push({ path: "/index" });
          }
        } else {
          //那么,如果上面的条件都不成立,没有length=0.也就是说你还有好几个标签,并且你删除的是最后一位标签,那么就往左边挪一位跳转路由
          this.$router.push({ path: this.tags[index - 1].url });
        }
      } else {
        // å¦‚果你点击不是最后一位标签,点的前面的,那就往右边跳转
        this.$router.push({ path: this.tags[index].url });
      }
    },
    //点击跳转路由
    tagsmenu(item, index) {
      console.log('tagsmenu');
      //判断:当前路由不等于当前选中项的url,也就代表你点击的不是现在选中的标签,是另一个标签就跳转过去,如果你点击的是现在已经选中的标签就不用跳转了,因为你已经在这个路由了还跳什么呢。
      if (this.$route.path !== item.url) {
        //用path的跳转方法把当前项的url当作地址跳转。
        this.$router.push({ path: item.url });
        let tagsDiv = document.getElementById('tags-box')
        if (index) {
          tagsDiv.scrollTo(index * 110, 0)
        }
      }
    },
    //通过判断路由一致返回布尔值添加class,添加高亮效果
    isActive(route, index) {
      let res = route === this.$route.path
      return res
    },
    scrollToStart() {
      let tagsDiv = document.getElementById('tags-box')
      tagsDiv.scrollTo(0, 0)
    },
    scrollToEnd() {
      let tagsDiv = document.getElementById('tags-box')
      tagsDiv.scrollTo(tagsDiv.scrollWidth, 0)
    },
    //右键事件,显示右键菜单,并固定好位置。
    openMenu(tag, e) {
      this.visible = true
      this.selectedTag = tag
      const offsetLeft = this.$el.getBoundingClientRect().left
      console.log(tag, e);
      this.left = e.clientX - offsetLeft + 60  //右键菜单距离左边的距离
      this.top = e.clientY +20  //右键菜单距离上面的距离           è¿™ä¸¤ä¸ªå¯ä»¥æ›´æ”¹ï¼Œçœ‹çœ‹è‡ªå·±çš„右键菜单在什么位置,自己调
    },
    //隐藏右键菜单
    closeMenu() {
      this.visible = false
    },
    //右键菜单关闭所有选项,触发vuex中的方法,把当前路由当参数传过去用于判断
    cleartags(val){
      this.visible = false
      this.cleartagsview(val)
    }
  },
};
</script>
<style lang="scss" scoped>
.btn {
  font-size: 20px;
  line-height: 48px;
  height: 48px;
}
.nor-btn {
  color: #666;
  cursor: pointer;
  &:hover {
    color: #2E68EC;
  }
}
.ban-btn {
  color: #999;
  cursor:not-allowed
}
#tags-box {
  overflow-x: hidden;
  white-space: nowrap;
  flex: 1;
  // width: 240px;
  scrollbar-width: none; /* firefox */
  -ms-overflow-style: none; /* IE 10+ */
  &::-webkit-scrollbar {
      display: none; /* Chrome Safari */
    }
}
#tags-box::-webkit-scrollbar {
    display: none; /* Chrome Safari */
}
//标签导航样式
.tagsview {
  cursor: pointer;
  // margin-left: 4px;
  height: 48px;
  line-height: 48px;
  padding: 0 8px 0 24px;
  // border: 1px solid #d8dce5;
  // border-radius: 5px;
  color: #000;
  font-size: 14px;
  display: inline-block;
}
//叉号鼠标经过样式
.tagsicon:hover{
  color: #f56c6c;
}
//标签高亮
.active{
  color: #2E68EC;
  border-bottom: 2px solid #2E68EC;
}
//右键菜单样式
.contextmenu {
  margin: 0;
  background: #fff;
  z-index: 100;
  position: absolute;
  list-style-type: none;
  padding: 5px 0;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 400;
  color: #333;
  box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3);
  li {
    margin: 0;
    padding: 7px 16px;
    cursor: pointer;
    &:hover {
      background: #eee;
    }
  }
}
.tags-view-style {
  scrollbar-width: none; /* firefox */
  -ms-overflow-style: none; /* IE 10+ */
  &::-webkit-scrollbar {
    display: none; /* Chrome Safari */
  }
}
</style>
company/src/layouts/AppLayout.vue
@@ -1,31 +1,49 @@
<template>
  <el-container class="app-layout">
    <el-aside :class="{collapse:menuData.collapse}">
      <Menu/>
    </el-aside>
    <el-main>
      <header>
        <AppHeader/>
      </header>
      <main>
        <transition name="fade">
          <router-view></router-view>
        </transition>
      </main>
    </el-main>
  </el-container>
  <div>
    <CommonHeader />
    <div style="height:10px; background: #fff"></div>
    <el-container class="app-layout">
      <el-aside :class="{collapse:menuData.collapse}">
        <Menu/>
      </el-aside>
      <el-main>
        <header>
          <AppHeader/>
        </header>
        <div style="height:10px;"></div>
        <main>
          <transition name="fade">
            <keep-alive>
              <router-view></router-view>
            </keep-alive>
          </transition>
        </main>
      </el-main>
    </el-container>
  </div>
</template>
<script>
import { mapState } from 'vuex'
import Header from '@/components/common/Header'
import CommonHeader from '@/components/common/CommonHeader'
import Menu from '@/components/common/Menu'
export default {
  name: 'DefaultLayout',
  components: { AppHeader: Header, Menu },
  components: { AppHeader: Header, Menu, CommonHeader },
  data() {
    return {
      isFinishData: false
    }
  },
  computed: {
    ...mapState(['menuData'])
  }
    ...mapState(['menuData', 'userInfo'])
  },
  methods: {
  },
}
</script>
@@ -34,17 +52,27 @@
.el-container {
  background: #F7F8F9;
  height: 100%;
  display: flex;
  overflow: hidden;
  // overflow: hidden;
  overflow: scroll;
  // å·¦è¾¹èœå•
  .el-aside {
    width: $menu-width !important;
    flex-shrink: 0;
    height: 100%;
    overflow-y: auto;
    // height: 100%;
    // height: 900px;
    height: calc(100vh - 80px);
    overflow-y: scroll;
    overflow-x: hidden;
    background: $primary-color;
    color: #fff;
    transition: width ease .3s;
    scrollbar-width: none; /* firefox */
    -ms-overflow-style: none; /* IE 10+ */
    &::-webkit-scrollbar {
      display: none; /* Chrome Safari */
    }
    &.collapse {
      width: 64px !important;
    }
@@ -52,14 +80,21 @@
  // å³è¾¹å†…容
  .el-main {
    width: 100%;
    height: 100%;
    // height: 100%;
    height: calc(100vh - 90px);
    padding: 0;
    position: relative;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    overflow-y: scroll;
    overflow-x: hidden;
    scrollbar-width: none; /* firefox */
    -ms-overflow-style: none; /* IE 10+ */
    &::-webkit-scrollbar {
      display: none; /* Chrome Safari */
    }
    & > header {
      height: $header-height;
      height: 48px;
      flex-shrink: 0;
    }
    & > main {
@@ -81,4 +116,33 @@
  transition: all .5s;
  position: absolute;
}
.comfirm {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.3);
  z-index: 1000;
  .container {
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    margin: auto;
    background-color: #fff;
    width: 500px;
    height: 120px;
    padding: 30px;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    .complete {
      display: flex;
      flex-direction: row-reverse;
    }
  }
}
</style>
company/src/layouts/TableLayout.vue
@@ -1,11 +1,11 @@
<template>
  <div class="table-layout">
    <!-- å¤´éƒ¨ -->
    <div v-if="withBreadcrumb" class="table-header">
<!--    <div v-if="withBreadcrumb" class="table-header">
      <el-breadcrumb separator="/">
        <el-breadcrumb-item v-for="path in paths" :key="path">{{path}}</el-breadcrumb-item>
      </el-breadcrumb>
    </div>
    </div>-->
    <Profile :roles="roles" :permissions="permissions">
      <!-- æœç´¢è¡¨å•部分 -->
      <div class="table-search-form">
company/src/plugins/download.js
@@ -2,12 +2,11 @@
import message from './message'
export default function (response, decode = true, mime = 'application/octet-stream') {
  // debugger
  // å½“下载接口没有成功返回流并且接口返回的是JSON时需要对响应流进行解析并提示错误。(处理下载接口出现未知异常的情况)
  if (response.headers['content-type'] === 'application/json') {
    const blob = new Blob([response.data])
    const fileReader = new FileReader()
    fileReader.readAsText(blob, 'UTF-8')
    fileReader.readAsText(blob, 'utf-8')
    fileReader.onload = function () {
      message.apiFailed(JSON.parse(fileReader.result))
    }
company/src/plugins/messagebox.js
@@ -10,6 +10,13 @@
      type: 'warning'
    })
  },
  resetConfirm (message) {
    return MessageBox.confirm(message, '重置提醒', {
      confirmButtonText: '确认重置',
      cancelButtonText: '取消',
      type: 'warning'
    })
  },
  // ç¦ç”¨äºŒæ¬¡ç¡®è®¤
  disableConfirm (message) {
    return MessageBox.confirm(message, '禁用提醒', {
@@ -25,5 +32,29 @@
      cancelButtonText: '取消',
      type: 'warning'
    })
  },
  // å®Œå–„提醒
  messageApprove (message) {
    return MessageBox.confirm(message, '审核提醒', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
  },
    // é—®å·ç¡®å®žæé†’
  messageWaring (message, title, confirmText='确定', cancelText='取消') {
    return MessageBox.confirm(message, title, {
      confirmButtonText: confirmText,
      cancelButtonText: cancelText,
      type: 'warning'
    })
  },
  // ç¡®è®¤æ˜¯å¦æœåŠ¡è¯¥ä¼ä¸š
  cancelOrder (message) {
    return MessageBox.confirm(message, '取消提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
  }
}
company/src/router/index.js
@@ -3,6 +3,7 @@
import AppLayout from '@/layouts/AppLayout'
import { getUserInfo } from '@/api/system/common'
const Login = () => import('@/views/login')
const ErrorNoPermissions = () => import('@/views/no-permissions')
const Error404 = () => import('@/views/not-found')
@@ -18,6 +19,7 @@
      path: '/login',
      component: Login
    },
    // æ— æƒé™
    {
      name: 'no-permissions',
@@ -52,7 +54,6 @@
  }
  // éªŒè¯ç”¨æˆ·æ˜¯å¦ç™»å½•
  const userInfo = router.app.$options.store.state.userInfo
  // console.log(userInfo)
  if (userInfo != null) {
    // å¦‚果用户不存在权限
    if (userInfo.permissions.length === 0) {
@@ -67,7 +68,6 @@
    next()
    return
  }
  // debugger
  getUserInfo()
    .then(userInfo => {
      // å¦‚果用户不存在权限
company/src/store/index.js
@@ -13,7 +13,11 @@
    list: [],
    // æ˜¯å¦æ”¶èµ·
    collapse: false
  }
  },
  //tags数组
  tags:[],
  //tagsview标签显示隐藏
  isCollapse:false
}
const mutations = {
@@ -28,8 +32,12 @@
  },
  // è®¾ç½®å·²ç™»å½•的用户信息
  setUserInfo: (state, data) => {
    state.userInfo = data
    state.userInfo = {
      ...state.userInfo,
      ...data
    }
  },
  // è®¾ç½®é¦–页路由信息
  setHomePage (state, homePage) {
    state.homePage = homePage
@@ -37,6 +45,37 @@
  // é‡ç½®èœå•
  resetMenus: (state) => {
    state.menuData.list = []
  },
  //  tags
  pushtags(state,val){
    //如果等于-1说明tabs不存在那么插入,否则什么都不做
    //findindex找角标,循环判断一下,如果等于那么就代表有相同的,就不必添加,如果找不到那就是-1.就添加
    let result = state.tags.findIndex(item => item.label === val.label)
    if (result === -1) {
      state.tags.push({...val, keepAlive: false})
    } else {
      state.tags[result]= {...val, keepAlive: true}
    }
    // result === -1 ? state.tags.push(val) : (state.tags[result]==val)
  },
  //关闭标签
  closeTab(state, val) {
    //同上,找角标,然后用角标的位置对应删除一位。splice:这是数组的删除方法
    let result = state.tags.findIndex(item => item.label === val.label)
    state.tags.splice(result, 1)
  },
  //关闭所有tagsview标签
  cleartagsview(state,val){
    //清空数组
    state.tags=[]
    //跳转到首页,val接受传过来的当前路由
    if(val !== "/index"){
      router.push({path:"/index"})
    }
  },
  //改变tagsview显示隐藏
  changeisshow(state){
    state.isCollapse=!state.isCollapse
  }
}
const actions = {}
server/platform/src/main/resources/application.yml
@@ -55,7 +55,7 @@
# dao层的日志设置为debug,方便查看sql
logging:
  level:
    doumeemes.dao: debug
    com.doumee.dao: debug
knife4j:
  enable: true
server/service/src/main/java/com/doumee/service/business/impl/CompanyServiceImpl.java
@@ -462,7 +462,7 @@
    @Override
    public Company findById(Integer id) {
        Company model = findById(id);
        Company model = companyMapper.selectById(id);
        if(model == null ||Constants.equalsInteger(model.getIsdeleted(),Constants.ONE)){
            throw  new BusinessException(ResponseStatus.DATA_EMPTY);
        }