---
title: IMES-Cloud前端项目
keywords: IMES, Vue, 前端
desc: IMES-Cloud前端项目
author: devin
date: 2023-07-20
tags: VUE, IMES, Cloud前端项目
---



## IMES-Cloud前端项目

## 一、代码模块介绍

### 1、`在项目文件夹src=>Views=>admin 文件下进行新增业务文件夹，例如Product  业务模块文件夹`

###  2、VUE 内容页面分三个模块 

######  定义页面的样式：

 调整当前页面的内容和样式，都是在 <u>template</u> 节点中进行处理

```vue
   <template>
      .....具体的页面样式
   <template>
       

```

 例如

```vue
 <template>
    <div class="my-layout">
      <el-card class="mt8" shadow="never" :body-style="{ paddingBottom: '0' }">
        <el-form :model="bomModel.filterModel" :inline="true" @submit.stop.prevent>
          <el-form-item prop="name">
            <el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="mb20">
            <el-form-item label="物料号">
              <el-input v-model="bomModel.filterModel.bomMateNo" placeholder="物料号" clearable></el-input>
            </el-form-item>
          </el-col>
          <el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="mb20">
            <el-form-item label="生产编码">
              <el-input v-model="bomModel.filterModel.bomProNo" placeholder="生产编码" clearable></el-input>
            </el-form-item>
          </el-col>
          <el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="mb20">
            <el-form-item label="部件名称">
              <el-input v-model="bomModel.filterModel.bomName" placeholder="部件名称" clearable></el-input>
            </el-form-item>
          </el-col>
          <el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="mb20">
            <el-form-item label="部件类型">
              <el-select v-model="bomModel.filterModel.bomType" placeholder="请选择部件类型" clearable class="w100">
                <el-option label="计税主板" value="1"></el-option>
                <el-option label="油气回收" value="2"></el-option>
                <el-option label="计量主板" value="3"></el-option>
              </el-select>
            </el-form-item>
          </el-col>
                   </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="ele-Search" @click="onQuery"> 查询 </el-button>
        <el-button v-auth="'api:admin:file:upload-file'" type="primary" icon="ele-Upload" @click="onUpload"> 上传 </el-button>
      </el-form-item>
    </el-form>
  </el-card>
  
  <el-card class="my-fill mt8" shadow="never">
    <el-table v-loading="bomModel.loading" :data="bomModel.bomListData" row-key="id" style="width: 100%">
      <el-table-column prop="guid" label="序号" width="120" />
      <el-table-column prop="bomName" label="部件名称" width="120" />
      <el-table-column prop="bomNo" label="物料号" width="120" />
      <el-table-column prop="bomProNo" label="生产编号" width="120" />
      <el-table-column prop="cpuId" label="CPUID" width="120" />
      <el-table-column prop="software_v" label="软件版本" width="120" />
      <el-table-column prop="status" label="状态" width="120" />
      <el-table-column prop="key_name" label="密钥状态" width="120" />
      <el-table-column prop="stand_name" label="团标状态" width="120" />
      <el-table-column prop="createTime" label="创建时间" width="120" />
      <el-table-column prop="remark" label="备注" min-width="120">
      </el-table-column>
   
      <el-table-column prop="createdTime" label="更新时间" width="100">
        <template #default="{ row }">
          {{ formatterTime(row.modifiedTime || row.createdTime || '') }}
        </template>
      </el-table-column>
      <el-table-column label="操作" width="180" fixed="right" header-align="center" align="center">
        <template #default="{ row }">
         
          <el-link
            class="my-el-link mr12 ml12"
            :href="row.guid"
            type="primary"
            icon="ele-edit"
            size="small"
            :underline="false"
            target="_blank"
            >详情</el-link>
        </template>
      </el-table-column>
    </el-table>
    <div class="my-flex my-flex-end" style="margin-top: 20px">
      <el-pagination
        v-model:currentPage="bomModel.pageInput.currentPage"
        v-model:page-size="bomModel.pageInput.pageSize"
        :total="bomModel.total"
        :page-sizes="[10, 20, 50, 100]"
        small
        background
        @size-change="onSizeChange"
        @current-change="onCurrentChange"
        layout="total, sizes, prev, pager, next, jumper"
      />
    </div>
  </el-card>
  </div>  </template>

```



###### 页面需要引用的模块和对象结构


```vue
 <script lang="ts" setup name="admin/Component">
  import { ref, reactive, onMounted, onBeforeMount} from 'vue'  //computed, getCurrentInstance 
  import { PageInputFileGetPageDto, ComponentGetPageOutPut } from '/@/api/admin/data-contracts'
  import { ComponentApi } from '/@/api/admin/Component'
  import dayjs from 'dayjs'
  import eventBus from '/@/utils/mitt' 
```



###### 页面的绑定对象和事件定义处理

```typescript
  const fileUploadRef = ref()

  //部件的页面对象
  const bomModel = reactive({
    loading: false,
    fileFormTitle: '',
    filterModel: {
      fileName: '',
      bomType: '',
      bomName: '',
      bomProNo: '',
      bomMateNo: '',
    },
    total: 0,
    pageInput: {
      currentPage: 1,
      pageSize: 20,
    } as PageInputFileGetPageDto,
    bomListData: [] as Array<ComponentGetPageOutPut>,
    bomLogsTitle: '',
  })



  onMounted(() => {
    onQuery()
    eventBus.off('refreshFile')
    eventBus.on('refreshFile', async () => {
      onQuery()
    })
  })

  onBeforeMount(() => {
    eventBus.off('refreshFile')
  })

  const formatterTime = (cellValue: any) => {
    return dayjs(cellValue).format('YYYY-MM-DD HH:mm:ss')
  }



  const onQuery = async () => {
    bomModel.loading = true
    const res = await new ComponentApi().getPage({ ...bomModel.pageInput, filter: bomModel.filterModel }).catch(() => {
        bomModel.loading = false
    })

    bomModel.bomListData = res?.data?.list ?? []
    bomModel.total = res?.data?.total ?? 0
    bomModel.loading = false

  }

  const onSizeChange = (val: number) => {
    bomModel.pageInput.pageSize = val
    onQuery()
  }

  const onCurrentChange = (val: number) => {
    bomModel.pageInput.currentPage = val
    onQuery()
  }

  const onUpload = () => {
    fileUploadRef.value.open()
  }

  //const onDelete = (row: FileGetPageOutput) => {
    //proxy.$modal
      //.confirmDelete(`确定要删除文件【${row.fileName}${row.extension}】?`)
      //.then(async () => {
        //await new BomApi().delete({ id: row.id as number }, { loading: true, showSuccessMessage: true })
       // onQuery()
    //  })
    //  .catch(() => {})
 // }
  </script>

  <style scoped lang="scss">
  .my-el-link {
    font-size: 12px;
  }
  </style>


​        
```



### 3、当前页面需要接口和页面对象定义

   定义当前页面需要的后端接口

```vue
import { ComponentApi } from '/@/api/admin/Component'
```

######   定义当前页面的API 文件

   在文件夹 src=>api=>admin 下 新建typescript 文件 例如：Component.ts

   该文件用于后端接口请求交互和转换前端页面对象处理。

######   Component.ts 代码结构如下

```typescript
import { AxiosResponse } from 'axios'
import {
  FileDeleteInput,
  PageInputComponentGetPageDto,
  ResultOutputFileEntity,
  ResultOutputListFileEntity,
  ResultOutputPageComponentGetPageOutPut,
} from './data-contracts'
import { ContentType, HttpClient, RequestParams } from './http-client'

export class ComponentApi<SecurityDataType = unknown> extends HttpClient<SecurityDataType> {
  /**
   * No description
   *
   * @tags file
   * @name GetPage
   * @summary 查询分页
   * @request POST:/api/app/CompoentService/GetPageAsync
   * @secure
   */
  getPage = (data: PageInputComponentGetPageDto, params: RequestParams = {}) =>
    this.request<ResultOutputPageComponentGetPageOutPut, any>({
      path: `/api/app/compoent/get-page`,
      method: 'POST',
      body: data,
      secure: true,
      type: ContentType.Json,
      format: 'json',
      ...params,
    })
  /**
   * No description
   *
   * @tags file
   * @name Delete
   * @summary 删除
   * @request POST:/api/admin/file/delete
   * @secure
   */
  delete = (data: FileDeleteInput, params: RequestParams = {}) =>
    this.request<AxiosResponse, any>({
      path: `/api/admin/file/delete`,
      method: 'POST',
      body: data,
      secure: true,
      type: ContentType.Json,
      ...params,
    })
  /**
   * No description
   *
   * @tags file
   * @name UploadFile
   * @summary 上传文件
   * @request POST:/api/admin/file/upload-file
   * @secure
   */
  uploadFile = (
    data: {
      /** @format binary */
      file: File
    },
    query?: {
      /**
       * 文件目录
       * @default ""
       */
      fileDirectory?: string
      /**
       * 文件重命名
       * @default true
       */
      fileReName?: boolean
    },
    params: RequestParams = {}
  ) =>
    this.request<ResultOutputFileEntity, any>({
      path: `/api/admin/file/upload-file`,
      method: 'POST',
      query: query,
      body: data,
      secure: true,
      type: ContentType.FormData,
      format: 'json',
      ...params,
    })
  /**
   * No description
   *
   * @tags file
   * @name UploadFiles
   * @summary 上传多文件
   * @request POST:/api/admin/file/upload-files
   * @secure
   */
  uploadFiles = (
    data: {
      files: File[]
    },
    query?: {
      /**
       * 文件目录
       * @default ""
       */
      fileDirectory?: string
      /**
       * 文件重命名
       * @default true
       */
      fileReName?: boolean
    },
    params: RequestParams = {}
  ) =>
    this.request<ResultOutputListFileEntity, any>({
      path: `/api/admin/file/upload-files`,
      method: 'POST',
      query: query,
      body: data,
      secure: true,
      type: ContentType.FormData,
      format: 'json',
      ...params,
    })
}

```



###### 页面前端传输对象定义

当前业务api 涉及到哪些页面参数对象和DTO ，统一定义在 ，在文件夹 src=>api=>admin 中的  data-contracts。

也可以单独定义个 data-component.ts  作为传输对象

```typescript
import {
  FileDeleteInput,
  PageInputComponentGetPageDto,
  ResultOutputFileEntity,
  ResultOutputListFileEntity,
  ResultOutputPageComponentGetPageOutPut,
} from './data-contracts'
```



`接口搜索条件对象`

```typescript
/** 分页信息输入 */
export interface PageInputComponentGetPageDto {
  /**
   * 当前页标
   * @format int32
   */
  currentPage?: number
  /**
   * 每页大小
   * @format int32
   */
  pageSize?: number
  dynamicFilter?: DynamicFilterInfo
  filter?: ComponentGetPageDto
}


/**部件列表对象 */
export interface ComponentGetPageDto{

   /**部件名称 */
   bomName:string | null
   /**部件编号 */
   bomNo:string | null
   bomProNo: string | null
   bomMateNo:string | null
   bomType: number
   status: number

}
```

`接口列表返回对象`

```typescript

/** 结果输出 */
export interface ResultOutputPageComponentGetPageOutPut {
  /** 是否成功标记 */
  success?: boolean
  /** 编码 */
  code?: string | null
  /** 消息 */
  msg?: string | null
  /** 分页信息输出 */
  data?: PageOutputPageComponentGetPage
}

export interface PageOutputPageComponentGetPage{
    /**
   * 数据总数
   * @format int64
   */
    total?: number
    /** 数据 */
    list?: ComponentGetPageOutPut[] | null
}

/**部件列表对象 */
export interface ComponentGetPageOutPut{
  /**序号 */
   guid: number
   
   /**部件名称 */
   bomName:string | null

   /**部件编号 */
   bomNo:string | null
   bomProNo: string | null
   cpuId:string | null
   software_v: string | null
   status: number
   key_name: number
   stand_name:number
   createTime: Date
   remark:string |null
}
```

## 二、新页面的开发

### 1、新增视图

![img](file:///C:/Users/11047158/AppData/Local/Temp/msohtmlclip1/01/clip_image002.gif)

### 2、视图配置

![img](file:///C:/Users/11047158/AppData/Local/Temp/msohtmlclip1/01/clip_image004.gif)

### 3、新增分组

![img](file:///C:/Users/11047158/AppData/Local/Temp/msohtmlclip1/01/clip_image006.gif)

### 4、配置分组

![img](file:///C:/Users/11047158/AppData/Local/Temp/msohtmlclip1/01/clip_image008.gif)

### 5、新增菜单

![img](file:///C:/Users/11047158/AppData/Local/Temp/msohtmlclip1/01/clip_image010.gif)

### 6、配置菜单

![img](file:///C:/Users/11047158/AppData/Local/Temp/msohtmlclip1/01/clip_image012.gif)

### 7、数据字典

![img](file:///C:/Users/11047158/AppData/Local/Temp/msohtmlclip1/01/clip_image014.gif)

 

数据字典使用到pinia管理，代码文件在 src - stores - globalCacheStore.ts



 

Tip:

1、添加页面时

![img](file:///C:/Users/11047158/AppData/Local/Temp/msohtmlclip1/01/clip_image016.gif)

在添加页面的时候如果需要将components放在fuelingsdk目录里，则在注册视图的时候，视图地址需要指定到具体的index页面

![img](file:///C:/Users/11047158/AppData/Local/Temp/msohtmlclip1/01/clip_image018.gif)



 

![img](file:///C:/Users/11047158/AppData/Local/Temp/msohtmlclip1/01/clip_image020.gif)

如果goodInfo里面只有index，视图地址则不需要指定到具体的index

![img](file:///C:/Users/11047158/AppData/Local/Temp/msohtmlclip1/01/clip_image022.gif)