index.vue 9.32 KB
<template>
  <div>
    <el-row
      v-for="row in appRowCount"
      :key="row"
      :gutter="32"
      style="margin-bottom: 32px"
    >
      <el-col
        v-for="app in apps.filter(
          (a, index) => index >= (row - 1) * 4 && index < row * 4
        )"
        :key="app.id"
        :span="6"
      >
        <div class="app-box" @click="click(app)">
          <div style="padding: 24px; display: flex">
            <div
              class="app-left__wrap"
              :style="{
                background: getIconBkColor(app.iconColor),
              }"
            >
              <el-image
                v-if="app.icon && app.icon.indexOf('icon') < 0"
                :src="app.icon"
                :style="{
                  background: getIconBkColor(app.iconColor),
                }"
                style="height: 40px; width: 40px"
              ></el-image>
              <i
                v-else
                :class="app.icon ? app.icon : 'el-icon-house'"
                class="app-icon"
              ></i>
            </div>
            <div class="app-right__wrap">
              <div class="card-title" :title="app.name">{{ app.name }}</div>
              <el-popover
                placement="bottom"
                width="320"
                trigger="hover"
                :content="app.desc"
              >
                <div slot="reference" class="card-desc">
                  {{ app.desc }}
                </div>
              </el-popover>
            </div>
          </div>
        </div>
      </el-col>
    </el-row>
    <el-dialog
      title="应用说明"
      width="70%"
      :visible="dialogVisible"
      :before-close="beforeClose"
    >
      <el-form>
        <div v-for="(item, index) in appParamList" :key="index">
          <ht-form-item :label="item.name">
            <!--<ht-input v-model="item.value" v-if="item.controlType == 'textarea'" :disabled="true"></ht-input>-->
            <div>
              <span
                v-if="
                  item.controlType === 'textarea' ||
                  item.controlType === 'number' ||
                  item.controlType === 'date' ||
                  item.controlType === 'dateTime'
                "
                v-text="item.value"
              ></span>
            </div>
            <!--<ht-input v-model="item.value" v-if="item.controlType == 'number'" type="number" :disabled="true"></ht-input>
                <ht-date v-model="item.value" v-if="item.controlType == 'date'" format="yyyy-MM-dd" :disabled="true"></ht-date>
            <ht-date v-model="item.value" v-if="item.controlType == 'dateTime'" format="yyyy-MM-dd HH:mm:ss" :disabled="true"></ht-date>-->
            <div v-if="item.controlType === 'attachment'">
              <el-tag
                v-for="file in JSON.parse(item.value)"
                :key="file.id"
                type="primary"
                @click="downloadFile(file.id)"
              >
                {{ file.name }}
              </el-tag>
            </div>
            <div>
              <span
                v-if="item.controlType === 'richText'"
                v-html="item.value"
              ></span>
            </div>
          </ht-form-item>
        </div>
      </el-form>
    </el-dialog>
  </div>
</template>

<script>
  import store from '@/store'
  import {
    getAppByAppId,
    isAppHasDesc,
    downloadFile,
    getMainByDefKey,
    isSinglePage,
  } from '@/api/appCenter.js'
  export default {
    name: 'AppMain',
    props: {
      apps: {
        type: Array,
        default: () => {
          return []
        },
      },
    },
    data() {
      return {
        dialogVisible: false,
        appParamList: [],
        visibleTag: [],
        appRightMap: {},
        closingWait: false,
      }
    },
    computed: {
      appRowCount: function () {
        return this.apps && Math.ceil(this.apps.length / 4)
        return 0
      },
    },
    methods: {
      //获取图标背景色
      getIconBkColor(iconColor) {
        if (iconColor) {
          return iconColor
        }
        return store.getters['settings/themeColor'] || '#1339E0'
      },
      //取颜色的反色
      colorReverse(oldColor) {
        var oldColor = '0x' + oldColor.replace(/#/g, '')
        var str = '000000' + (0xffffff - oldColor).toString(16)
        return '#' + str.substring(str.length - 6, str.length)
      },
      //点击应用
      async click(app) {
        let data = await isSinglePage(app.id)
        if (!data.value) {
          if (data.message === 'success') {
            window.open(`${window.context.front}/app/${app.id}`)
            return
          }
          this.$message.warning(data.message)
        }
        this.jump(data.value)
      },
      async jump(app) {
        //1常规应用 2数据报表 3自定义视图 4图表 6表单 7模块 8启动流程
        ///appContent/:type/:id/:otherId/:appName
        let url = ''
        if (app.type === 4) {
          let content = JSON.parse(app.content)
          url = `/appContent?type=${app.type}&id=${content.id}&appName=${app.name}`
        } else if (app.type === 2) {
          let content = JSON.parse(app.content)
          url = `/appContent?type=${app.type}&id=${content.alias}&appName=${app.name}`
        } else if (app.type === 3) {
          let content = JSON.parse(app.content)
          url = `/appContent?type=${app.type}&id=${content.id}&appName=${app.name}`
        } else if (app.type === 6) {
          let content = JSON.parse(app.content)
          url = `/appContent?type=${app.type}&id=${content.id}&appName=${app.name}`
        } else if (app.type === 7) {
          let content = JSON.parse(app.content)
          url = `/appContent?type=${app.type}&id=${content.id}&appName=${app.name}`
        } else if (app.type === 8) {
          let content = JSON.parse(app.content)
          let resp = {}
          if (content.key) {
            resp = await getMainByDefKey(content.key)
            url = `/matter/startProcess?from=applicationModule&defId=${resp.id}&name=${content.name}`
          } else {
            url = `/matter/startProcess?from=applicationModule&defId=${content.id}&name=${content.name}`
          }
        } else if (app.type === 9) {
          let content = JSON.parse(app.content)
          url = `/appContent?type=${app.type}&id=${content.id}&appName=${app.name}&alias=${content.alias}`
        } else if (app.type === 5) {
          url = app.content
        } else if (app.type === 1) {
          let content = JSON.parse(app.content)
          url = `/appContent?type=${app.type}&id=${content.alias}&appName=${app.name}`
        }
        if (url) {
          window.open(this.getUrl(url), '_blank')
        }
      },
      getUrl(url) {
        if (url.startsWith('http') || url.startsWith('https')) {
          return url
        } else return `${window.context.front}${url}&__isFull__=true`
      },
      appDescClick(appId) {
        getAppByAppId(appId).then((resp) => {
          this.appParamList = resp.value
          this.dialogVisible = true
        })
      },
      mouseEnter(index) {
        let this_ = this
        let appId = this.apps[index].id
        let timeWait = 0
        if (this_.appRightMap.hasOwnProperty(appId)) {
          if (this_.appRightMap[appId]) {
            if (this_.closingWait) {
              timeWait = 200
            }
            setTimeout(() => {
              this_.visibleTag[index] = true
              this_.$forceUpdate()
            }, timeWait)
          }
          return
        }
        isAppHasDesc(appId).then((resp) => {
          if (resp.state) {
            this_.appRightMap[appId] = resp.value
            if (resp.value) {
              if (this_.closingWait) {
                timeWait = 200
              }
              setTimeout(() => {
                this_.visibleTag[index] = true
                this_.$forceUpdate()
              }, timeWait)
            }
          }
        })
      },
      mouseLeave(index) {
        this.closingWait = true
        setTimeout(() => {
          this.visibleTag[index] = false
          this.closingWait = true
          this.$forceUpdate()
        }, 200)
      },
      beforeClose() {
        this.appParamList = []
        this.dialogVisible = false
      },
      //附件下载
      downloadFile(fileId) {
        //"${portal}/system/file/v1/downloadFile?fileId=" + this.fileRow.id
        downloadFile(fileId)
      },
    },
  }
</script>

<style lang="scss" scoped>
  .app-box {
    background-color: #f5f5f5;
    border-radius: 2px;
    border: 1px solid transparent;
    width: 100%;
    height: 88px;
    cursor: pointer;
    .app-left__wrap {
      width: 40px;
      height: 40px;
      display: flex;
      justify-content: center;
      align-items: center;
      border-radius: $base-border-radius;
    }
    .app-right__wrap {
      width: calc(100% - 52px);
      padding-left: 12px;
    }
  }
  .app-box:hover {
    border-color: var(--themeColor);
    box-shadow: 0px 0px 4px rgba(var(--themeColorRgb), 0.65);
  }
  .app-icon {
    font-size: 28px;
    color: #fff;
  }
  .card-title {
    width: 60%;
    font-size: 16px;
    font-weight: bold;
    color: #333333;
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
  }
  .card-desc {
    width: 80%;
    font-size: 12px;
    font-weight: 400;
    line-height: 22px;
    color: #999999;
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
  }
</style>