V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Hamm
V2EX  ›  TypeScript

用 AirPower4T,我们来写个前端管理后台吧:)

  •  
  •   Hamm · 2023-08-14 22:42:28 +08:00 · 966 次点击
    这是一个创建于 466 天前的主题,其中的信息可能已经有所发展或是发生改变。

    一、写在前面

    前一篇文章《用 AirPower4J ,我们来写个后端服务吧》 是来水一篇,主要是顺带给前端项目写个后端的 api 服务, 略简单,入门级。后续再丰富吧:)

    前端主要使用的是 Vue3 TypeScript Element Plus 等技术栈,行,开整。

    二、初始化项目

    老规矩,先新建个目录 frontend,再把宿主项目和依赖项目都拉下来,还是在 Github :)

    我们直接使用 宿主项目 提供的一键脚本吧:)

    我不知道你是不是习惯 ssh 方式,反正我挺喜欢:)

    git clone [email protected]:HammCn/AirPowerWebDemo.git &&
    cd AirPowerWebDemo/src && 
    git clone [email protected]:HammCn/AirPower4T.git airpower && cd ../ &&
    yarn && cp .env.dev .env && yarn s
    

    不出意外应该会装完依赖启动项目,直接跑起来了。

    截屏 2023-08-07 22.43.11.png

    这一套前后端是配套设计的,所以环境变量默认配置的就是上一篇后端服务文章里的本地服务。

    三、开始写代码

    先创建个菜单吧:)

    截屏 2023-08-07 22.54.08.png

    好,依然是先来创建一下 Service Entity View 部分:

    SupplierEntity 实体

    @ClassName('供应商')
    export class SupplierEntity extends BaseEntity {
      @TableField({
        copyField: true,
        forceShow: true,
      })
      @FormField({
        requiredString: true,
      })
      @FieldName('供应商编码') code!: string
    
      @TableField()
      @FormField({
        requiredString: true,
      })
      @FieldName('供应商名称') name!: string
    
      @Dictionary(SupplierLevelDictionary)
      @TableField({
        showColor: true,
      })
      @FormField({
        requiredNumber: true,
        defaultValue: SupplierLevel.GOLD,
      })
      @FieldName('供应商级别') level!: SupplierLevel
    
      @TableField()
      @FormField({
        mobilePhone: true,
      })
      @FieldName('联系电话') phone!: string
    }
    
    

    SupplierLevel 枚举

    export enum SupplierLevel {
      GOLD = 1,
      SILVER = 2,
      COPPER = 3
    }
    

    SupplierLevelDictionary 枚举翻译字典

    export const SupplierLevelDictionary = AirDictionaryArray.create([
      {
        key: SupplierLevel.GOLD, label: '金牌', color: AirColor.SUCCESS,
      }, {
        key: SupplierLevel.SILVER, label: '银牌', color: AirColor.WARNING,
      }, {
        key: SupplierLevel.COPPER, label: '铜牌', color: AirColor.NORMAL,
      },
    ])
    
    

    上面我们按需求配置了一些表单、表格以及一些验证,还提供了一个供应商级别的枚举以及字典。

    SupplierService 接口请求服务

    export class SupplierService extends AbstractBaseService<SupplierEntity> {
      entityClass = SupplierEntity
    
      baseUrl = 'supplier'
    }
    

    View 层

    我们创建了 edit.vue list.vue 这些视图:)

    list.vue

    <template>
      <APanel>
        <AToolBar
          :loading="isLoading"
          :entity="SupplierEntity"
          :service="SupplierService"
          @on-add="onAdd"
          @on-search="onSearch"
        >
          <template #afterButton>
            <AButton
              v-if="selectList.length>0"
              type="DELETE_LIST"
              danger
              @click="AirNotification.warning('就是玩');selectList=[]"
            >
              批量删除
            </AButton>
          </template>
        </AToolBar>
        <ATable
          v-loading="isLoading"
          :data-list="response.list"
          :entity="SupplierEntity"
          :select-list="selectList"
          show-select
          @on-edit="onEdit"
          @on-delete="onDelete"
          @on-sort-change="onSortChanged"
          @on-select="onSelected"
        />
        <template #footerLeft>
          <APage
            :response="response"
            @on-change="onPageChanged"
          />
        </template>
      </APanel>
    </template>
    
    <script lang="ts" setup>
    import {
      APanel, APage, ATable, AToolBar, AButton,
    } from '@/airpower/component'
    import { useAirTable } from '@/airpower/hook/useAirTable'
    import { SupplierEntity } from '@/model/supplier/SupplierEntity'
    import { SupplierService } from '@/model/supplier/SupplierService'
    import { SupplierEditor } from './component'
    import { AirRequest } from '@/airpower/model/AirRequest'
    import { AirNotification } from '@/airpower/feedback/AirNotification'
    
    const {
      isLoading,
      response,
      selectList,
      onSearch, onAdd, onDelete, onEdit, onPageChanged, onSortChanged, onSelected,
    } = useAirTable(SupplierEntity, SupplierService, {
      editor: SupplierEditor,
    })
    </script>
    

    实现的效果如下图

    截屏 2023-08-07 23.21.44.png

    关键词搜索、高级筛选,这些基本都可以直接在装饰器中配置,后续再讲。

    edit.vue

    <template>
      <ADialog
        :title="title"
        :form-ref="formRef"
        :loading="isLoading"
        @on-confirm="onSubmit()"
        @on-cancel="onCancel()"
      >
        <el-form
          ref="formRef"
          :model="formData"
          label-width="120px"
          :rules="rules"
          @submit.prevent
        >
          <el-form-item
            :label="SupplierEntity.getFormFieldLabel('code')"
            prop="code"
          >
            <AInput
              v-model.code="formData.code"
              :entity="SupplierEntity"
            />
          </el-form-item>
          <el-form-item
            :label="SupplierEntity.getFormFieldLabel('name')"
            prop="name"
          >
            <AInput
              v-model.name="formData.name"
              :entity="SupplierEntity"
            />
          </el-form-item>
          <el-form-item
            :label="SupplierEntity.getFormFieldLabel('level')"
            prop="level"
          >
            <AInput
              v-model.level="formData.level"
              :entity="SupplierEntity"
            />
          </el-form-item>
          <el-form-item
            :label="SupplierEntity.getFormFieldLabel('phone')"
            prop="phone"
          >
            <AInput
              v-model.phone="formData.phone"
              :entity="SupplierEntity"
            />
          </el-form-item>
        </el-form>
      </ADialog>
    </template>
    
    <script lang="ts" setup>
    import { ADialog, AInput } from '@/airpower/component'
    import { airPropsParam } from '@/airpower/config/AirProps'
    import { useAirEditor } from '@/airpower/hook/useAirEditor'
    import { SupplierEntity } from '@/model/supplier/SupplierEntity'
    import { SupplierService } from '@/model/supplier/SupplierService'
    
    const props = defineProps(airPropsParam(new SupplierEntity()))
    
    const {
      title,
      formData,
      rules,
      onSubmit,
      formRef,
      isLoading,
    } = useAirEditor(props, SupplierEntity, SupplierService)
    
    </script>
    
    

    截屏 2023-08-07 23.18.47.png

    实现了创建和修改两个需求,接下来试试配置的验证是否生效:)

    image.png

    好,搞定,看起来没什么问题。

    四、就这样

    That's all ,今天的水文又有了。

    上面所有的代码都在 Github 欢迎食用。

    文中提到几个开源地址:

    依赖仓库: https://github.com/HammCn/AirPower4T

    宿主项目: https://github.com/HammCn/AirPowerWebDemo

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2600 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 04:43 · PVG 12:43 · LAX 20:43 · JFK 23:43
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.