AppView.vue 9.4 KB
<template>
  <div class="app-view">
    <el-row
      v-for="row in appRowCount"
      :key="row"
      style="margin-bottom: 24px"
      :gutter="24"
    >
      <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 class="app-box-content">
            <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: 48px; width: 48px"
              ></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-container" :title="app.name">
                <div class="card-title">{{ app.name }}</div>
                <el-tooltip
                  v-if="app.fileInfo"
                  class="item"
                  effect="dark"
                  content="应用说明"
                  placement="top"
                >
                  <i
                    class="icon-shujushitu1 info"
                    @click.stop="viewInfo(app)"
                  ></i>
                </el-tooltip>
              </div>
              <el-popover
                v-if="app.desc"
                placement="bottom"
                width="320"
                trigger="hover"
                :content="app.desc"
              >
                <div slot="reference" class="card-desc">
                  {{ app.desc }}
                </div>
              </el-popover>
              <div v-else class="card-desc">暂无描述</div>
            </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">
            <div>
              <span
                v-if="
                  item.controlType === 'textarea' ||
                  item.controlType === 'number' ||
                  item.controlType === 'date' ||
                  item.controlType === 'dateTime'
                "
                v-text="item.value"
              ></span>
            </div>
            <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>

    <app-info ref="appInfo" />
  </div>
</template>

<script>
  import store from '@/store'
  import {
    downloadFile,
    getMainByDefKey,
    isSinglePage,
  } from '@/api/appCenter.js'
  import AppInfo from './AppInfo.vue'
  export default {
    name: 'AppView',
    components: { AppInfo },
    props: {
      apps: {
        type: Array,
        default: () => {
          return []
        },
      },
      openType: {
        type: String,
        default: 'window',
      },
    },
    data() {
      return {
        dialogVisible: false,
        appParamList: [],
        visibleTag: [],
        appRightMap: {},
        closingWait: false,
      }
    },
    computed: {
      appRowCount: function () {
        return this.apps && Math.ceil(this.apps.length / 4)
      },
    },
    methods: {
      //获取图标背景色
      getIconBkColor(iconColor) {
        if (iconColor) {
          return iconColor
        }
        return store.getters['settings/themeColor'] || '#1339E0'
      },
      //点击应用
      async click(app) {
        let data = await isSinglePage(app.id)

        if (!data.value) {
          if (data.message === 'success') {
            this.open(`/app/${app.id}`, false)
            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}&alias=${content.key}`
        } 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) {
          this.open(url, true)
        }
      },
      open(url, isFull) {
        if (this.openType === 'window') {
          window.open(this.getUrl(url, isFull), '_blank')
        } else if (this.openType === 'router') {
          if (url.startsWith('/app/')) {
            this.$router.push(url + this.handlerWinUrl(url, isFull))
          } else {
            window.location.href = this.getUrl(url, isFull)
          }
        }
        this.$emit('after-select')
      },
      handlerWinUrl(url, isFull) {
        if (!isFull) {
          return ''
        }
        if (url.includes('?')) {
          return `&__isFull__=true`
        } else {
          return `?__isFull__=true`
        }
      },
      getUrl(url, isFull) {
        if (url.startsWith('http') || url.startsWith('https')) {
          return url
        } else {
          return `${window.context.front}${url}${this.handlerWinUrl(
            url,
            isFull
          )}`
        }
      },
      viewInfo(app) {
        if (app.fileInfo) {
          let appInfo = JSON.parse(app.fileInfo)
          this.$refs.appInfo.open(appInfo)
        }
      },
      beforeClose() {
        this.appParamList = []
        this.dialogVisible = false
      },
      //附件下载
      downloadFile(fileId) {
        downloadFile(fileId)
      },
    },
  }
</script>

<style lang="scss" scoped>
  .app-view {
    height: calc(100% - 84px);
    overflow-y: auto;
  }
  .app-box {
    background-color: #f9f9f9;
    border-radius: 4px;
    border: 1px solid transparent;
    width: 228px;
    height: 88px;
    cursor: pointer;

    .app-box-content {
      padding: 20px 16px;
      display: flex;

      .app-left__wrap {
        width: 48px;
        height: 48px;
        display: flex;
        justify-content: center;
        align-items: center;
        border-radius: 8px;
        flex-shrink: 0;
      }
      .app-right__wrap {
        width: calc(100% - 52px);
        padding-left: 8px;
        display: flex;
        flex-direction: column;
        justify-content: space-between;
      }
    }
  }
  .app-box:hover {
    border-color: var(--themeColor);
    box-shadow: 0 0 4px rgba(var(--themeColorRgb), 0.65);
    .info {
      display: flex;
      font-size: 18px;
    }
  }
  .app-icon {
    font-size: 28px;
    color: #fff;
  }
  .card-title-container {
    width: 140px;
    display: flex;
    align-items: center;
    justify-content: space-between;

    .card-title {
      width: 120px;
      font-size: 16px;
      font-weight: bold;
      color: #333333;
      white-space: nowrap;
      text-overflow: ellipsis;
      overflow: hidden;
      line-height: 24px;
    }

    .info {
      display: none;
      &:hover {
        color: #409eff;
      }
    }
  }
  .card-desc {
    width: 100%;
    font-size: 12px;
    font-weight: 400;

    color: #999999;
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
  }

  .el-row {
    margin-right: 0 !important;
  }
</style>