feat: 优化打印机和报警器管理功能 - 新增打印机管理功能,优化报警器表单,更新API接口,补充开发文档

This commit is contained in:
Asoka 2025-06-09 14:14:26 +08:00
parent 1280c11bbc
commit 4018936bf7
6 changed files with 1050 additions and 14 deletions

View File

@ -0,0 +1,156 @@
/* eslint-disable */
/* tslint:disable */
/*
* ---------------------------------------------------------------
* ## THIS FILE WAS GENERATED VIA SWAGGER-TYPESCRIPT-API ##
* ## ##
* ## AUTHOR: adademo / https://github.com/adademo/swagger-typescript-api ##
* ## SOURCE: https://github.com/adademo/swagger-typescript-api ##
* ---------------------------------------------------------------
*/
import {
EquPrinter,
EquPrinterAddInput,
EquPrinterUpdateInput,
PageInputEquPrinterGetPageInput,
ResultOutputEquPrinter,
ResultOutputPageOutputEquPrinter,
ResultOutputInt64,
} from './data-contracts'
import { ContentType, HttpClient, RequestParams } from './http-client'
import { AxiosResponse } from 'axios'
export class EquPrinterApi<SecurityDataType = unknown> extends HttpClient<SecurityDataType> {
/**
* No description
*
* @tags equ-printer
* @name Get
* @summary
* @request GET:/api/admin/equ-printer/get
* @secure
*/
get = (
query?: {
/** @format int64 */
id?: number
},
params: RequestParams = {}
) =>
this.request<ResultOutputEquPrinter, any>({
path: `/api/admin/equ-printer/get`,
method: 'GET',
query: query,
secure: true,
format: 'json',
...params,
})
/**
* No description
*
* @tags equ-printer
* @name GetPage
* @summary
* @request POST:/api/admin/equ-printer/get-page
* @secure
*/
getPage = (data: PageInputEquPrinterGetPageInput, params: RequestParams = {}) =>
this.request<ResultOutputPageOutputEquPrinter, any>({
path: `/api/admin/equ-printer/get-page`,
method: 'POST',
body: data,
secure: true,
type: ContentType.Json,
format: 'json',
...params,
})
/**
* No description
*
* @tags equ-printer
* @name Add
* @summary
* @request POST:/api/admin/equ-printer/add
* @secure
*/
add = (data: EquPrinterAddInput, params: RequestParams = {}) =>
this.request<ResultOutputInt64, any>({
path: `/api/admin/equ-printer/add`,
method: 'POST',
body: data,
secure: true,
type: ContentType.Json,
format: 'json',
...params,
})
/**
* No description
*
* @tags equ-printer
* @name Update
* @summary
* @request PUT:/api/admin/equ-printer/update
* @secure
*/
update = (data: EquPrinterUpdateInput, params: RequestParams = {}) =>
this.request<AxiosResponse, any>({
path: `/api/admin/equ-printer/update`,
method: 'PUT',
body: data,
secure: true,
type: ContentType.Json,
...params,
})
/**
* No description
*
* @tags equ-printer
* @name Delete
* @summary
* @request DELETE:/api/admin/equ-printer/delete
* @secure
*/
delete = (
query?: {
/** @format int64 */
id?: number
},
params: RequestParams = {}
) =>
this.request<AxiosResponse, any>({
path: `/api/admin/equ-printer/delete`,
method: 'DELETE',
query: query,
secure: true,
...params,
})
/**
* No description
*
* @tags equ-printer
* @name SoftDelete
* @summary
* @request DELETE:/api/admin/equ-printer/soft-delete
* @secure
*/
softDelete = (
query?: {
/** @format int64 */
id?: number
},
params: RequestParams = {}
) =>
this.request<AxiosResponse, any>({
path: `/api/admin/equ-printer/soft-delete`,
method: 'DELETE',
query: query,
secure: true,
...params,
})
}

View File

@ -7472,3 +7472,168 @@ export interface PageOutputAlarmGetPageOutput {
/** 数据 */
list?: AlarmGetPageOutput[] | null;
}
/** 打印机实体 */
export type EquPrinter = {
/** 主键 */
id?: number;
/** 设备编号 */
deviceNo?: string;
/** 资产编号 */
assetNo?: string;
/** IP地址 */
ip?: string;
/** 端口号 */
port?: string;
/** 打印机IP */
printerIP?: string;
/** 打印机端口 */
printerPort?: string;
/** 打印高度(主) */
printerHeight?: string;
/** 打印高度1 */
printerHeightOne?: string;
/** 打印高度2 */
printerHeightTwo?: string;
/** 打印高度3 */
printerHeightThree?: string;
/** 打印宽度(主) */
printerWidth?: string;
/** 打印宽度1 */
printerWidthOne?: string;
/** 打印宽度2 */
printerWidthTwo?: string;
/** 打印宽度3 */
printerWidthThree?: string;
/** 打印字体(主) */
printerFont?: string;
/** 打印字体1 */
printerFontOne?: string;
/** 打印字体2 */
printerFontTwo?: string;
/** 打印字体3 */
printerFontThree?: string;
/** 创建时间 */
createdTime?: string;
/** 创建者 */
createdBy?: number;
/** 创建者名称 */
createdUserName?: string;
/** 更新时间 */
updatedTime?: string;
/** 更新者 */
updatedBy?: number;
/** 更新者名称 */
updatedUserName?: string;
/** 是否删除 */
isDeleted?: boolean;
};
/** 打印机分页查询参数 */
export type EquPrinterPageQuery = {
/** 关键词 */
keyWord?: string;
/** 开始时间 */
stDate?: string;
/** 结束时间 */
edDate?: string;
/** 页码 */
pageNum?: number;
/** 每页条数 */
pageSize?: number;
};
/** 结果输出 */
export type ResultOutputEquPrinter = {
/** 是否成功标记 */
success?: boolean;
/** 编码 */
code?: string;
/** 消息 */
msg?: string;
/** 数据 */
data?: EquPrinter;
};
/** 分页信息输出 */
export type PageOutputEquPrinter = {
/** 数据总数 */
total?: number;
/** 数据 */
list?: EquPrinter[];
};
/** 结果输出 */
export type ResultOutputPageOutputEquPrinter = {
/** 是否成功标记 */
success?: boolean;
/** 编码 */
code?: string;
/** 消息 */
msg?: string;
/** 分页信息输出 */
data?: PageOutputEquPrinter;
};
export type EquPrinterAddInput = {
/** 设备编号 */
deviceNo?: string
/** 资产编号 */
assetNo?: string
/** IP地址 */
ip?: string
/** 端口号 */
port?: number
/** 打印机IP */
printerIP?: string
/** 打印机端口 */
printerPort?: string
/** 打印高度(主) */
printerHeight?: string
/** 打印高度1 */
printerHeightOne?: string
/** 打印高度2 */
printerHeightTwo?: string
/** 打印高度3 */
printerHeightThree?: string
/** 打印宽度(主) */
printerWidth?: string
/** 打印宽度1 */
printerWidthOne?: string
/** 打印宽度2 */
printerWidthTwo?: string
/** 打印宽度3 */
printerWidthThree?: string
/** 打印字体(主) */
printerFont?: string
/** 打印字体1 */
printerFontOne?: string
/** 打印字体2 */
printerFontTwo?: string
/** 打印字体3 */
printerFontThree?: string
/** 打印数量 */
printerNumber?: number
/** 是否启用 */
isEnabled?: boolean
/** 备注 */
remark?: string
}
export type EquPrinterUpdateInput = EquPrinterAddInput & {
/** 主键 */
id?: number
}
export type PageInputEquPrinterGetPageInput = {
/** 关键字 */
keyWord?: string
/** 开始时间 */
stDate?: string
/** 结束时间 */
edDate?: string
/** 页码 */
pageNum?: number
/** 每页条数 */
pageSize?: number
}

View File

@ -1,18 +1,18 @@
<template>
<div>
<el-dialog v-model="state.showDialog" destroy-on-close :title="title" draggable :close-on-click-modal="false"
:close-on-press-escape="false" width="700px">
<el-form :model="form" ref="formRef" size="default" label-width="100px">
:close-on-press-escape="false" width="900px">
<el-form :model="form" ref="formRef" size="default" label-width="120px">
<div class="form-section">
<div class="section-title">基本信息</div>
<el-row :gutter="25">
<el-col :span="12">
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
<el-form-item label="设备编号" prop="deviceNo"
:rules="[{ required: true, message: '请输入设备编号', trigger: ['blur', 'change'] }]">
<el-input v-model="form.deviceNo" clearable placeholder="请输入设备编号" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
<el-form-item label="资产编号" prop="assetNo">
<el-input v-model="form.assetNo" clearable placeholder="请输入资产编号" />
</el-form-item>
@ -22,23 +22,37 @@
<div class="form-section">
<div class="section-title">网络配置</div>
<el-row :gutter="25">
<el-col :span="12">
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
<el-form-item label="IP地址" prop="ip" :rules="[{ required: true, message: '请输入IP地址', trigger: 'blur' }]">
<el-input v-model="form.ip" clearable placeholder="请输入IP地址" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
<el-form-item label="端口" prop="port" :rules="[{ required: true, message: '请输入端口', trigger: 'blur' }]">
<el-input v-model="form.port" clearable placeholder="请输入端口" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
<el-form-item label="服务名称" prop="serviceName">
<el-input v-model="form.serviceName" clearable placeholder="请输入服务名称" />
</el-form-item>
</el-col>
</el-row>
</div>
<div class="form-section">
<div class="section-title">设备配置</div>
<el-row :gutter="25">
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
<el-form-item label="启用状态">
<el-switch
v-model="form.status"
active-text="启用"
inactive-text="禁用"
/>
</el-form-item>
</el-col>
</el-row>
</div>
</el-form>
<template #footer>
<span class="dialog-footer">
@ -138,14 +152,38 @@ defineExpose({
<style lang="scss" scoped>
.form-section {
margin-bottom: 20px;
margin-bottom: 24px;
.section-title {
font-size: 16px;
font-weight: bold;
margin-bottom: 15px;
padding-left: 10px;
border-left: 4px solid var(--el-color-primary);
&:last-child {
margin-bottom: 0;
}
}
.section-title {
font-size: 16px;
font-weight: 600;
color: #303133;
margin-bottom: 16px;
padding-bottom: 8px;
border-bottom: 2px solid #f0f0f0;
position: relative;
&:before {
content: '';
position: absolute;
left: 0;
bottom: -2px;
width: 40px;
height: 2px;
background: #409eff;
}
}
:deep(.el-form-item) {
margin-bottom: 18px;
}
:deep(.el-switch__label) {
font-size: 13px;
}
</style>

View File

@ -0,0 +1,342 @@
<script setup lang="ts">
import { ref, reactive, watch } from 'vue'
import type { FormInstance, FormRules } from 'element-plus'
import { ElMessage } from 'element-plus'
import { EquPrinterApi } from '/@/api/admin/EquPrinterApi'
import type { EquPrinterAddInput, EquPrinterUpdateInput } from '/@/api/admin/data-contracts'
const props = defineProps<{
modelValue: boolean
title: string
formData: Partial<EquPrinterAddInput> & { id?: number }
}>()
const emit = defineEmits<{
(e: 'update:modelValue', value: boolean): void
(e: 'success'): void
}>()
// ref
const formRef = ref<FormInstance>()
//
const form = reactive<EquPrinterAddInput & { id?: number }>({
deviceNo: '',
assetNo: '',
ip: '',
port: 9100,
printerIP: '',
printerPort: '',
printerHeight: '',
printerHeightOne: '',
printerHeightTwo: '',
printerHeightThree: '',
printerWidth: '',
printerWidthOne: '',
printerWidthTwo: '',
printerWidthThree: '',
printerFont: '',
printerFontOne: '',
printerFontTwo: '',
printerFontThree: '',
printerNumber: 1,
isEnabled: true
})
//
const rules = {
deviceNo: [{ required: true, message: '请输入设备编号', trigger: 'blur' }],
assetNo: [{ required: true, message: '请输入资产编号', trigger: 'blur' }],
ip: [{ required: true, message: '请输入IP地址', trigger: 'blur' }],
port: [{ required: true, message: '请输入端口号', trigger: 'blur' }],
printerIP: [{ required: true, message: '请输入打印机IP', trigger: 'blur' }],
printerPort: [{ required: true, message: '请输入打印机端口', trigger: 'blur' }],
printerHeight: [{ required: true, message: '请输入打印高度', trigger: 'blur' }],
printerWidth: [{ required: true, message: '请输入打印宽度', trigger: 'blur' }],
printerFont: [{ required: true, message: '请输入打印字体', trigger: 'blur' }],
printerNumber: [{ required: true, message: '请输入打印数量', trigger: 'blur' }]
}
//
const dialogVisible = ref(false)
// modelValue
watch(() => props.modelValue, (val) => {
dialogVisible.value = val
})
//
watch(() => dialogVisible.value, (val) => {
emit('update:modelValue', val)
if (!val) {
resetForm()
}
})
//
watch(() => props.formData, (val) => {
if (val) {
Object.assign(form, val)
}
}, { deep: true, immediate: true })
//
const resetForm = () => {
if (formRef.value) {
formRef.value.resetFields()
}
Object.assign(form, {
deviceNo: '',
assetNo: '',
ip: '',
port: 9100,
printerIP: '',
printerPort: '',
printerHeight: '',
printerHeightOne: '',
printerHeightTwo: '',
printerHeightThree: '',
printerWidth: '',
printerWidthOne: '',
printerWidthTwo: '',
printerWidthThree: '',
printerFont: '',
printerFontOne: '',
printerFontTwo: '',
printerFontThree: '',
printerNumber: 1,
isEnabled: true
})
}
//
const submitForm = async () => {
if (!formRef.value) return
await formRef.value.validate(async (valid: boolean) => {
if (valid) {
try {
const api = new EquPrinterApi()
if (form.id) {
const res = await api.update(form)
if (res.success) {
ElMessage.success('修改成功')
dialogVisible.value = false
emit('success')
}
} else {
const res = await api.add(form)
if (res.success) {
ElMessage.success('添加成功')
dialogVisible.value = false
emit('success')
}
}
} catch (error) {
console.error('提交表单失败:', error)
}
}
})
}
</script>
<template>
<el-dialog
v-model="dialogVisible"
:title="title"
width="900px"
append-to-body
destroy-on-close
:close-on-click-modal="false"
:close-on-press-escape="false"
draggable
>
<el-form
ref="formRef"
:model="form"
:rules="rules"
label-width="120px"
size="default"
class="printer-form"
>
<!-- 基本信息 -->
<div class="form-section">
<div class="section-title">基本信息</div>
<el-row :gutter="25">
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
<el-form-item label="设备编号" prop="deviceNo">
<el-input v-model="form.deviceNo" clearable placeholder="请输入设备编号" />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
<el-form-item label="资产编号" prop="assetNo">
<el-input v-model="form.assetNo" clearable placeholder="请输入资产编号" />
</el-form-item>
</el-col>
</el-row>
</div>
<!-- 网络配置 -->
<div class="form-section">
<div class="section-title">网络配置</div>
<el-row :gutter="25">
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
<el-form-item label="IP地址" prop="ip">
<el-input v-model="form.ip" clearable placeholder="请输入IP地址" />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
<el-form-item label="端口号" prop="port">
<el-input-number v-model="form.port" :min="1" :max="65535" style="width: 100%" placeholder="请输入端口号" />
</el-form-item>
</el-col>
</el-row>
</div>
<!-- 参数配置 -->
<div class="form-section">
<div class="section-title">参数配置</div>
<el-row :gutter="25">
<el-col :xs="24" :sm="8" :md="8" :lg="8" :xl="8">
<el-form-item label="第一行宽度" prop="printerWidth">
<el-input v-model="form.printerWidth" clearable placeholder="请输入第一行宽度" />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="8" :md="8" :lg="8" :xl="8">
<el-form-item label="第一行高度" prop="printerHeight">
<el-input v-model="form.printerHeight" clearable placeholder="请输入第一行高度" />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="8" :md="8" :lg="8" :xl="8">
<el-form-item label="第一行字体" prop="printerFont">
<el-input v-model="form.printerFont" clearable placeholder="请输入第一行字体" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="25">
<el-col :xs="24" :sm="8" :md="8" :lg="8" :xl="8">
<el-form-item label="第二行宽度" prop="printerWidthOne">
<el-input v-model="form.printerWidthOne" clearable placeholder="请输入第二行宽度" />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="8" :md="8" :lg="8" :xl="8">
<el-form-item label="第二行高度" prop="printerHeightOne">
<el-input v-model="form.printerHeightOne" clearable placeholder="请输入第二行高度" />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="8" :md="8" :lg="8" :xl="8">
<el-form-item label="第二行字体" prop="printerFontOne">
<el-input v-model="form.printerFontOne" clearable placeholder="请输入第二行字体" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="25">
<el-col :xs="24" :sm="8" :md="8" :lg="8" :xl="8">
<el-form-item label="第三行宽度" prop="printerWidthTwo">
<el-input v-model="form.printerWidthTwo" clearable placeholder="请输入第三行宽度" />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="8" :md="8" :lg="8" :xl="8">
<el-form-item label="第三行高度" prop="printerHeightTwo">
<el-input v-model="form.printerHeightTwo" clearable placeholder="请输入第三行高度" />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="8" :md="8" :lg="8" :xl="8">
<el-form-item label="第三行字体" prop="printerFontTwo">
<el-input v-model="form.printerFontTwo" clearable placeholder="请输入第三行字体" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="25">
<el-col :xs="24" :sm="8" :md="8" :lg="8" :xl="8">
<el-form-item label="第四行宽度" prop="printerWidthThree">
<el-input v-model="form.printerWidthThree" clearable placeholder="请输入第四行宽度" />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="8" :md="8" :lg="8" :xl="8">
<el-form-item label="第四行高度" prop="printerHeightThree">
<el-input v-model="form.printerHeightThree" clearable placeholder="请输入第四行高度" />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="8" :md="8" :lg="8" :xl="8">
<el-form-item label="第四行字体" prop="printerFontThree">
<el-input v-model="form.printerFontThree" clearable placeholder="请输入第四行字体" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="25">
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
<el-form-item label="打印数量" prop="printerNumber">
<el-input-number v-model="form.printerNumber" :min="1" :max="999" style="width: 100%" placeholder="请输入打印数量" />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
<el-form-item label="启用状态" prop="isEnabled">
<el-switch
v-model="form.isEnabled"
active-text="启用"
inactive-text="禁用"
/>
</el-form-item>
</el-col>
</el-row>
</div>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false" size="default"> </el-button>
<el-button type="primary" @click="submitForm" size="default"> </el-button>
</span>
</template>
</el-dialog>
</template>
<style lang="scss" scoped>
.form-section {
margin-bottom: 24px;
&:last-child {
margin-bottom: 0;
}
}
.section-title {
font-size: 16px;
font-weight: 600;
color: #303133;
margin-bottom: 16px;
padding-bottom: 8px;
border-bottom: 2px solid #f0f0f0;
position: relative;
&:before {
content: '';
position: absolute;
left: 0;
bottom: -2px;
width: 40px;
height: 2px;
background: #409eff;
}
}
:deep(.el-form-item) {
margin-bottom: 18px;
}
:deep(.el-switch__label) {
font-size: 13px;
}
.dialog-footer {
display: flex;
justify-content: flex-end;
gap: 10px;
padding: 10px 20px;
border-top: 1px solid var(--el-border-color-lighter);
}
</style>

View File

@ -0,0 +1,193 @@
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { EquPrinterApi } from '/@/api/admin/EquPrinterApi'
import type { EquPrinterAddInput } from '/@/api/admin/data-contracts'
import PrinterForm from './components/printer-form.vue'
//
const queryParams = reactive({
keyWord: '',
pageNum: 1,
pageSize: 10,
stDate: '',
edDate: ''
})
//
const loading = ref(false)
//
const printerList = ref<any[]>([])
//
const total = ref(0)
//
const dialogVisible = ref(false)
//
const dialogTitle = ref('')
//
const formData = ref<Partial<EquPrinterAddInput>>({})
//
const getList = async () => {
loading.value = true
try {
const res = await new EquPrinterApi().getPage({
keyWord: queryParams.keyWord,
stDate: queryParams.stDate,
edDate: queryParams.edDate,
pageNum: queryParams.pageNum,
pageSize: queryParams.pageSize
})
if (res.success) {
printerList.value = res.data?.list || []
total.value = res.data?.total || 0
}
} catch (error) {
console.error('获取打印机列表失败:', error)
} finally {
loading.value = false
}
}
//
const handleQuery = () => {
queryParams.pageNum = 1
getList()
}
//
const resetQuery = () => {
queryParams.keyWord = ''
queryParams.stDate = ''
queryParams.edDate = ''
handleQuery()
}
//
const handleAdd = () => {
dialogTitle.value = '新增打印机'
formData.value = {}
dialogVisible.value = true
}
//
const handleUpdate = (row: any) => {
dialogTitle.value = '修改打印机'
formData.value = { ...row }
dialogVisible.value = true
}
//
const handleDelete = (row: any) => {
ElMessageBox.confirm('确认要删除该打印机吗?', '警告', {
type: 'warning'
}).then(async () => {
try {
const res = await new EquPrinterApi().softDelete({ id: row.id })
if (res.success) {
ElMessage.success('删除成功')
getList()
}
} catch (error) {
console.error('删除打印机失败:', error)
}
})
}
//
const handleSizeChange = (val: number) => {
queryParams.pageSize = val
getList()
}
//
const handleCurrentChange = (val: number) => {
queryParams.pageNum = val
getList()
}
//
onMounted(() => {
getList()
})
</script>
<template>
<my-layout>
<el-card class="my-query-box mt8" shadow="never" :body-style="{ paddingBottom: '0' }">
<el-form :inline="true" @submit.stop.prevent>
<el-form-item label="关键词">
<el-input v-model="queryParams.keyWord" placeholder="请输入关键词" clearable />
</el-form-item>
<el-form-item label="开始时间">
<el-date-picker
v-model="queryParams.stDate"
type="datetime"
placeholder="选择开始时间"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
style="width: 180px"
/>
</el-form-item>
<el-form-item label="结束时间">
<el-date-picker
v-model="queryParams.edDate"
type="datetime"
placeholder="选择结束时间"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
style="width: 180px"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="ele-Search" @click="handleQuery"> 查询 </el-button>
<el-button type="primary" icon="ele-Plus" @click="handleAdd"> 新增 </el-button>
</el-form-item>
</el-form>
</el-card>
<el-card class="my-fill mt8" shadow="never">
<el-table v-loading="loading" :data="printerList" style="width: 100%" border>
<el-table-column label="设备编号" prop="deviceNo" min-width="120" show-overflow-tooltip />
<el-table-column label="资产编号" prop="assetNo" min-width="120" show-overflow-tooltip />
<el-table-column label="IP地址" prop="ip" min-width="120" show-overflow-tooltip />
<el-table-column label="端口号" prop="port" width="100" show-overflow-tooltip />
<el-table-column label="操作" width="180" fixed="right" header-align="center" align="center">
<template #default="{ row }">
<el-button icon="ele-EditPen" size="small" text type="primary" @click="handleUpdate(row)">编辑</el-button>
<el-button icon="ele-Delete" size="small" text type="danger" @click="handleDelete(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="my-flex my-flex-end" style="margin-top: 10px">
<el-pagination
v-model:current-page="queryParams.pageNum"
v-model:page-size="queryParams.pageSize"
:page-sizes="[10, 20, 50, 100]"
:total="total"
size="small"
background
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</el-card>
<!-- 添加或修改对话框 -->
<printer-form
v-model="dialogVisible"
:title="dialogTitle"
:form-data="formData"
@success="getList"
/>
</my-layout>
</template>
<style scoped lang="scss"></style>

142
页面开发指南.md Normal file
View File

@ -0,0 +1,142 @@
# 页面开发指南
## 页面结构
1. 列表页面
- 搜索区域:关键词搜索
- 操作按钮:新增、查询
- 表格区域:基础字段展示
- 分页区域:标准分页组件
2. 编辑页面
- 基本信息模块
- 网络配置模块
- 设备配置模块
## 样式规范
1. 对话框配置
```html
<el-dialog
v-model="state.showDialog"
destroy-on-close
:title="title"
draggable
:close-on-click-modal="false"
:close-on-press-escape="false"
width="900px"
>
```
2. 表单布局
```html
<el-form :model="form" ref="formRef" size="default" label-width="120px">
<div class="form-section">
<div class="section-title">模块标题</div>
<el-row :gutter="25">
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
<el-form-item label="字段名称" prop="fieldName">
<el-input v-model="form.fieldName" clearable placeholder="请输入" />
</el-form-item>
</el-col>
</el-row>
</div>
</el-form>
```
3. 样式定义
```scss
.form-section {
margin-bottom: 24px;
&:last-child { margin-bottom: 0; }
}
.section-title {
font-size: 16px;
font-weight: 600;
color: #303133;
margin-bottom: 16px;
padding-bottom: 8px;
border-bottom: 2px solid #f0f0f0;
position: relative;
&:before {
content: '';
position: absolute;
left: 0;
bottom: -2px;
width: 40px;
height: 2px;
background: #409eff;
}
}
```
## 开发规范
1. 组件命名
- 目录:小写字母,用横线分隔
- 组件PascalCase
- 组合函数camelCase
2. 代码组织
```typescript
// 1. 导入声明
import { reactive, ref } from 'vue'
// 2. 类型定义
interface State {
showDialog: boolean
form: FormData
}
// 3. 组件定义
const props = defineProps({
title: String
})
// 4. 状态定义
const state = reactive<State>({
showDialog: false,
form: {}
})
// 5. 方法定义
const handleSubmit = async () => {
// 处理逻辑
}
```
3. 表单验证
```typescript
const rules = {
fieldName: [
{ required: true, message: '请输入', trigger: ['blur', 'change'] }
]
}
```
4. API 调用
```typescript
const handleSave = async () => {
try {
const res = await api.save(state.form)
if (res.success) {
ElMessage.success('保存成功')
emit('refresh')
state.showDialog = false
}
} catch (error) {
console.error(error)
}
}
```
## 注意事项
1. 保持与 uspscale 页面风格一致
2. 使用响应式布局适配不同屏幕
3. 统一表单验证规则和错误提示
4. 优化用户交互体验
5. 保持代码风格统一
6. 注意性能优化
7. 遵循 TypeScript 类型规范
---
**注意**:此模板基于 Vue 3 + TypeScript + Element Plus + Pinia 技术栈,使用时请根据实际项目技术栈进行调整。