前一篇文章《用 AirPower4J ,我们来写个后端服务吧》 是来水一篇,主要是顺带给前端项目写个后端的 api 服务, 略简单,入门级。后续再丰富吧:)
前端主要使用的是 Vue3 TypeScript Element Plus 等技术栈,行,开整。
老规矩,先新建个目录 frontend,再把宿主项目和依赖项目都拉下来,还是在 Github :)
我们直接使用 宿主项目 提供的一键脚本吧:)
我不知道你是不是习惯 ssh 方式,反正我挺喜欢:)
git clone git@github.com:HammCn/AirPowerWebDemo.git &&
cd AirPowerWebDemo/src &&
git clone git@github.com:HammCn/AirPower4T.git airpower && cd ../ &&
yarn && cp .env.dev .env && yarn s
不出意外应该会装完依赖启动项目,直接跑起来了。
这一套前后端是配套设计的,所以环境变量默认配置的就是上一篇后端服务文章里的本地服务。
先创建个菜单吧:)
好,依然是先来创建一下 Service Entity View 部分:
@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
}
export enum SupplierLevel {
GOLD = 1,
SILVER = 2,
COPPER = 3
}
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,
},
])
上面我们按需求配置了一些表单、表格以及一些验证,还提供了一个供应商级别的枚举以及字典。
export class SupplierService extends AbstractBaseService<SupplierEntity> {
entityClass = SupplierEntity
baseUrl = 'supplier'
}
我们创建了 edit.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>
实现的效果如下图
关键词搜索、高级筛选,这些基本都可以直接在装饰器中配置,后续再讲。
<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>
实现了创建和修改两个需求,接下来试试配置的验证是否生效:)
好,搞定,看起来没什么问题。
That's all ,今天的水文又有了。
上面所有的代码都在 Github 欢迎食用。
文中提到几个开源地址:
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.