feat: 添加基于pywebview的图形界面支持
新增图形界面模块webui,使用Vue 3 + Quasar + TypeScript + Tailwind CSS开发 扩展README文档说明图形界面使用方法 更新.gitignore忽略前端相关文件 添加Python版本配置文件
This commit is contained in:
149
webui/README.md
Normal file
149
webui/README.md
Normal file
@@ -0,0 +1,149 @@
|
||||
# EGM Web 界面
|
||||
|
||||
基于 pywebview 的输电线路绕击跳闸率计算程序图形界面。
|
||||
|
||||
## 技术栈
|
||||
|
||||
- **后端**: Python + pywebview
|
||||
- **前端**: Vue 3 + Quasar + TypeScript + Tailwind CSS
|
||||
- **构建工具**: Vite
|
||||
|
||||
## 安装步骤
|
||||
|
||||
### 1. 安装 Python 依赖
|
||||
|
||||
```bash
|
||||
# 在项目根目录
|
||||
uv sync
|
||||
# 或
|
||||
pip install pywebview
|
||||
```
|
||||
|
||||
### 2. 安装前端依赖
|
||||
|
||||
```bash
|
||||
cd webui
|
||||
npm install
|
||||
```
|
||||
|
||||
## 运行方式
|
||||
|
||||
### 开发模式
|
||||
|
||||
1. 启动前端开发服务器:
|
||||
|
||||
```bash
|
||||
cd webui
|
||||
npm run dev
|
||||
```
|
||||
|
||||
2. 在另一个终端启动 pywebview:
|
||||
|
||||
```bash
|
||||
cd ..
|
||||
python webview_app.py
|
||||
```
|
||||
|
||||
### 生产模式
|
||||
|
||||
1. 构建前端:
|
||||
|
||||
```bash
|
||||
cd webui
|
||||
npm run build
|
||||
```
|
||||
|
||||
2. 启动 pywebview:
|
||||
|
||||
```bash
|
||||
cd ..
|
||||
python webview_app.py
|
||||
```
|
||||
|
||||
## 项目结构
|
||||
|
||||
```
|
||||
webui/
|
||||
├── src/
|
||||
│ ├── components/
|
||||
│ │ └── ParameterForm.vue # 参数表单组件
|
||||
│ ├── types/
|
||||
│ │ └── index.ts # TypeScript 类型定义
|
||||
│ ├── App.vue # 主应用组件
|
||||
│ ├── main.ts # 应用入口
|
||||
│ └── style.css # 全局样式
|
||||
├── package.json # 前端依赖配置
|
||||
├── vite.config.ts # Vite 配置
|
||||
├── tsconfig.json # TypeScript 配置
|
||||
├── tailwind.config.js # Tailwind CSS 配置
|
||||
└── index.html # HTML 入口
|
||||
```
|
||||
|
||||
## 功能说明
|
||||
|
||||
### 参数配置
|
||||
|
||||
界面提供三个参数分组:
|
||||
|
||||
1. **基本参数**:
|
||||
- 额定电压等级 (kV)
|
||||
- 导线弧垂 (m)
|
||||
- 地线弧垂 (m)
|
||||
- 导线串子绝缘长度 (m)
|
||||
- 导线串长 (m)
|
||||
- 地线串长 (m)
|
||||
- 导、地线挂点垂直距离 (m)
|
||||
- 导、地线水平坐标 (m)
|
||||
- 地面倾角 (°)
|
||||
- 海拔高度 (m)
|
||||
- 雷暴日 (d)
|
||||
|
||||
2. **高级参数**:
|
||||
- 地闪密度 (次/(km²·a))
|
||||
- 雷电流概率密度曲线系数 a
|
||||
- 雷电流概率密度曲线系数 b
|
||||
|
||||
3. **可选参数**:
|
||||
- 计算时电压分成多少份
|
||||
- 最大尝试雷电流 (kA)
|
||||
|
||||
### 操作功能
|
||||
|
||||
- **开始计算**: 执行 EGM 计算
|
||||
- **重置参数**: 恢复默认参数值
|
||||
- **导出配置**: 将当前配置导出为 JSON 文件
|
||||
|
||||
## 开发说明
|
||||
|
||||
### 添加新功能
|
||||
|
||||
1. 在 `src/types/index.ts` 中添加类型定义
|
||||
2. 在 `src/components/ParameterForm.vue` 中添加 UI 组件
|
||||
3. 在 `webview_app.py` 中添加后端 API 方法
|
||||
|
||||
### 样式定制
|
||||
|
||||
- 使用 Tailwind CSS 类名进行样式定制
|
||||
- Quasar 组件自带 Material Design 风格
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q: pywebview 窗口无法打开?
|
||||
|
||||
A: 请确保已安装 pywebview:`pip install pywebview`
|
||||
|
||||
### Q: 前端开发服务器无法连接?
|
||||
|
||||
A: 请确保先运行 `npm run dev`,然后再启动 `python webview_app.py`
|
||||
|
||||
### Q: 计算功能不工作?
|
||||
|
||||
A: 当前版本仅提供界面框架,需要进一步集成 core.py 中的计算逻辑。
|
||||
|
||||
## 后续开发
|
||||
|
||||
- [ ] 集成 core.py 中的实际计算函数
|
||||
- [ ] 添加计算结果可视化
|
||||
- [ ] 支持导入/导出 TOML 配置文件
|
||||
- [ ] 添加批量计算功能
|
||||
- [ ] 添加结果导出(DXF、PDF 等)
|
||||
13
webui/index.html
Normal file
13
webui/index.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>EGM 输电线路绕击跳闸率计算</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
3290
webui/package-lock.json
generated
Normal file
3290
webui/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
1
webui/package.json
Normal file
1
webui/package.json
Normal file
@@ -0,0 +1 @@
|
||||
{"name":"egm-webui","version":"0.1.0","type":"module","scripts":{"dev":"vite","build":"vue-tsc && vite build","preview":"vite preview"},"dependencies":{"@quasar/extras":"^1.17.0","@quasar/vite-plugin":"^1.10.0","quasar":"^2.14.0","vue":"^3.4.0"},"devDependencies":{"@vitejs/plugin-vue":"^5.0.0","autoprefixer":"^10.4.0","postcss":"^8.4.0","sass-embedded":"^1.97.3","tailwindcss":"^3.4.0","typescript":"^5.3.0","vite":"^5.0.0","vue-tsc":"^1.8.0"}}
|
||||
6
webui/postcss.config.js
Normal file
6
webui/postcss.config.js
Normal file
@@ -0,0 +1,6 @@
|
||||
export default {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
7
webui/src/App.vue
Normal file
7
webui/src/App.vue
Normal file
@@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<ParameterForm />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import ParameterForm from '@/components/ParameterForm.vue'
|
||||
</script>
|
||||
432
webui/src/components/ParameterForm.vue
Normal file
432
webui/src/components/ParameterForm.vue
Normal file
@@ -0,0 +1,432 @@
|
||||
<template>
|
||||
<q-layout view="lHh lpr lFf">
|
||||
<q-header elevated class="bg-indigo-600 text-white">
|
||||
<q-toolbar>
|
||||
<q-toolbar-title>
|
||||
<div class="flex items-center gap-2">
|
||||
<q-icon name="flash_on" size="md" />
|
||||
<span class="text-xl font-bold">EGM 输电线路绕击跳闸率计算</span>
|
||||
</div>
|
||||
</q-toolbar-title>
|
||||
</q-toolbar>
|
||||
</q-header>
|
||||
|
||||
<q-page-container>
|
||||
<q-page class="q-pa-md">
|
||||
<div class="max-w-4xl mx-auto">
|
||||
<!-- 基本参数 -->
|
||||
<q-card class="q-mb-md shadow-2">
|
||||
<q-card-section class="bg-indigo-50">
|
||||
<div class="text-h6 text-indigo-900 flex items-center gap-2">
|
||||
<q-icon name="settings" />
|
||||
基本参数
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section>
|
||||
<div class="row q-col-gutter-md">
|
||||
<div class="col-12 col-md-6">
|
||||
<q-input
|
||||
v-model="params.parameter.rated_voltage"
|
||||
type="number"
|
||||
label="额定电压等级 (kV)"
|
||||
hint="输电线路的额定电压"
|
||||
:rules="[val => val > 0 || '必须大于0']"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<q-input
|
||||
v-model="params.parameter.h_c_sag"
|
||||
type="number"
|
||||
step="0.01"
|
||||
label="导线弧垂 (m)"
|
||||
hint="导线的平均弧垂"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<q-input
|
||||
v-model="params.parameter.h_g_sag"
|
||||
type="number"
|
||||
step="0.01"
|
||||
label="地线弧垂 (m)"
|
||||
hint="地线的平均弧垂"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<q-input
|
||||
v-model="params.parameter.insulator_c_len"
|
||||
type="number"
|
||||
step="0.01"
|
||||
label="导线串子绝缘长度 (m)"
|
||||
hint="绝缘子的有效绝缘距离"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<q-input
|
||||
v-model="params.parameter.string_c_len"
|
||||
type="number"
|
||||
step="0.1"
|
||||
label="导线串长 (m)"
|
||||
hint="导线串的总长度"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<q-input
|
||||
v-model="params.parameter.string_g_len"
|
||||
type="number"
|
||||
step="0.1"
|
||||
label="地线串长 (m)"
|
||||
hint="地线串的总长度"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<q-input
|
||||
v-model="params.parameter.altitude"
|
||||
type="number"
|
||||
label="海拔高度 (m)"
|
||||
hint="线路所在地的海拔"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<q-input
|
||||
v-model="params.parameter.td"
|
||||
type="number"
|
||||
label="雷暴日 (d)"
|
||||
hint="年雷暴日数"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 导、地线挂点高度 -->
|
||||
<div class="q-mt-md">
|
||||
<div class="text-subtitle2 q-mb-sm">
|
||||
导、地线挂点垂直距离 (m) - 第一个值为地线挂点高度
|
||||
</div>
|
||||
<div class="row q-col-gutter-sm">
|
||||
<div class="col" v-for="(h, index) in params.parameter.h_arm" :key="index">
|
||||
<q-input
|
||||
v-model="params.parameter.h_arm[index]"
|
||||
type="number"
|
||||
step="0.1"
|
||||
:label="index === 0 ? '地线' : `导线 ${index}`"
|
||||
dense
|
||||
/>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<q-btn flat round color="primary" icon="add" @click="addHArm" />
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<q-btn flat round color="negative" icon="remove" @click="removeHArm" :disable="params.parameter.h_arm.length <= 1" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 导、地线水平坐标 -->
|
||||
<div class="q-mt-md">
|
||||
<div class="text-subtitle2 q-mb-sm">
|
||||
导、地线水平坐标 (m)
|
||||
</div>
|
||||
<div class="row q-col-gutter-sm">
|
||||
<div class="col" v-for="(x, index) in params.parameter.gc_x" :key="index">
|
||||
<q-input
|
||||
v-model="params.parameter.gc_x[index]"
|
||||
type="number"
|
||||
step="0.1"
|
||||
:label="index === 0 ? '地线' : `导线 ${index}`"
|
||||
dense
|
||||
/>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<q-btn flat round color="primary" icon="add" @click="addGcX" />
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<q-btn flat round color="negative" icon="remove" @click="removeGcX" :disable="params.parameter.gc_x.length <= 1" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 地面倾角 -->
|
||||
<div class="q-mt-md">
|
||||
<div class="text-subtitle2 q-mb-sm">
|
||||
地面倾角 (°) - 向下为正
|
||||
</div>
|
||||
<div class="row q-col-gutter-sm">
|
||||
<div class="col" v-for="(angle, index) in params.parameter.ground_angels" :key="index">
|
||||
<q-input
|
||||
v-model="params.parameter.ground_angels[index]"
|
||||
type="number"
|
||||
step="1"
|
||||
:label="`角度 ${index + 1}`"
|
||||
dense
|
||||
/>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<q-btn flat round color="primary" icon="add" @click="addGroundAngel" />
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<q-btn flat round color="negative" icon="remove" @click="removeGroundAngel" :disable="params.parameter.ground_angels.length <= 1" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
|
||||
<!-- 高级参数 -->
|
||||
<q-card class="q-mb-md shadow-2">
|
||||
<q-card-section class="bg-indigo-50">
|
||||
<div class="text-h6 text-indigo-900 flex items-center gap-2">
|
||||
<q-icon name="tune" />
|
||||
高级参数
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section>
|
||||
<div class="row q-col-gutter-md">
|
||||
<div class="col-12 col-md-6">
|
||||
<q-input
|
||||
v-model="params.advance.ng"
|
||||
type="number"
|
||||
step="0.01"
|
||||
label="地闪密度 (次/(km²·a))"
|
||||
hint="大于0时使用此值,否则通过雷暴日计算"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<q-input
|
||||
v-model="params.advance.Ip_a"
|
||||
type="number"
|
||||
step="0.01"
|
||||
label="雷电流概率密度曲线系数 a"
|
||||
hint="大于0时使用此值"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<q-input
|
||||
v-model="params.advance.Ip_b"
|
||||
type="number"
|
||||
step="0.01"
|
||||
label="雷电流概率密度曲线系数 b"
|
||||
hint="大于0时使用此值"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
|
||||
<!-- 可选参数 -->
|
||||
<q-card class="q-mb-md shadow-2">
|
||||
<q-card-section class="bg-indigo-50">
|
||||
<div class="text-h6 text-indigo-900 flex items-center gap-2">
|
||||
<q-icon name="more_horiz" />
|
||||
可选参数
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section>
|
||||
<div class="row q-col-gutter-md">
|
||||
<div class="col-12 col-md-6">
|
||||
<q-input
|
||||
v-model="params.optional.voltage_n"
|
||||
type="number"
|
||||
label="计算时电压分成多少份"
|
||||
hint="考虑电压波动影响"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<q-input
|
||||
v-model="params.optional.max_i"
|
||||
type="number"
|
||||
label="最大尝试雷电流 (kA)"
|
||||
hint="迭代计算的最大电流"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<div class="row q-gutter-md justify-center q-mt-lg">
|
||||
<q-btn
|
||||
color="primary"
|
||||
size="lg"
|
||||
label="开始计算"
|
||||
icon="calculate"
|
||||
@click="calculate"
|
||||
:loading="calculating"
|
||||
class="px-8"
|
||||
/>
|
||||
<q-btn
|
||||
color="grey-7"
|
||||
size="lg"
|
||||
label="重置参数"
|
||||
icon="refresh"
|
||||
@click="resetParams"
|
||||
class="px-8"
|
||||
/>
|
||||
<q-btn
|
||||
color="positive"
|
||||
size="lg"
|
||||
label="导出配置"
|
||||
icon="download"
|
||||
@click="exportConfig"
|
||||
class="px-8"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 计算结果 -->
|
||||
<q-card v-if="result" class="q-mt-md shadow-2 bg-green-50">
|
||||
<q-card-section class="bg-green-100">
|
||||
<div class="text-h6 text-green-900 flex items-center gap-2">
|
||||
<q-icon name="check_circle" />
|
||||
计算结果
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<pre class="text-caption bg-white q-pa-md rounded">{{ result }}</pre>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
|
||||
<!-- 错误信息 -->
|
||||
<q-card v-if="error" class="q-mt-md shadow-2 bg-red-50">
|
||||
<q-card-section>
|
||||
<div class="text-negative q-mb-sm flex items-center gap-2">
|
||||
<q-icon name="error" />
|
||||
错误信息
|
||||
</div>
|
||||
<p class="text-negative">{{ error }}</p>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</div>
|
||||
</q-page>
|
||||
</q-page-container>
|
||||
</q-layout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import type { AllParameters } from '@/types'
|
||||
|
||||
// 默认参数
|
||||
const defaultParams: AllParameters = {
|
||||
parameter: {
|
||||
rated_voltage: 750,
|
||||
h_c_sag: 14.43,
|
||||
h_g_sag: 11.67,
|
||||
insulator_c_len: 7.02,
|
||||
string_c_len: 9.2,
|
||||
string_g_len: 0.5,
|
||||
h_arm: [150, 130],
|
||||
gc_x: [17.9, 17],
|
||||
ground_angels: [0],
|
||||
altitude: 1000,
|
||||
td: 20
|
||||
},
|
||||
advance: {
|
||||
ng: -1,
|
||||
Ip_a: -1,
|
||||
Ip_b: -1
|
||||
},
|
||||
optional: {
|
||||
voltage_n: 3,
|
||||
max_i: 200
|
||||
}
|
||||
}
|
||||
|
||||
const params = reactive<AllParameters>(JSON.parse(JSON.stringify(defaultParams)))
|
||||
const calculating = ref(false)
|
||||
const result = ref<string | null>(null)
|
||||
const error = ref<string | null>(null)
|
||||
|
||||
// 数组操作函数
|
||||
const addHArm = () => {
|
||||
const last = params.parameter.h_arm[params.parameter.h_arm.length - 1] || 100
|
||||
params.parameter.h_arm.push(last - 20)
|
||||
}
|
||||
|
||||
const removeHArm = () => {
|
||||
if (params.parameter.h_arm.length > 1) {
|
||||
params.parameter.h_arm.pop()
|
||||
}
|
||||
}
|
||||
|
||||
const addGcX = () => {
|
||||
const last = params.parameter.gc_x[params.parameter.gc_x.length - 1] || 10
|
||||
params.parameter.gc_x.push(last)
|
||||
}
|
||||
|
||||
const removeGcX = () => {
|
||||
if (params.parameter.gc_x.length > 1) {
|
||||
params.parameter.gc_x.pop()
|
||||
}
|
||||
}
|
||||
|
||||
const addGroundAngel = () => {
|
||||
params.parameter.ground_angels.push(0)
|
||||
}
|
||||
|
||||
const removeGroundAngel = () => {
|
||||
if (params.parameter.ground_angels.length > 1) {
|
||||
params.parameter.ground_angels.pop()
|
||||
}
|
||||
}
|
||||
|
||||
// 计算函数
|
||||
const calculate = async () => {
|
||||
calculating.value = true
|
||||
result.value = null
|
||||
error.value = null
|
||||
|
||||
try {
|
||||
// 调用 pywebview 的 Python 函数
|
||||
if (window.pywebview) {
|
||||
const response = await window.pywebview.api.calculate(params)
|
||||
result.value = JSON.stringify(response, null, 2)
|
||||
} else {
|
||||
// 开发模式下的模拟
|
||||
await new Promise(resolve => setTimeout(resolve, 1000))
|
||||
result.value = JSON.stringify({
|
||||
success: true,
|
||||
message: '计算完成(开发模式)',
|
||||
data: {
|
||||
tripping_rate: '0.0581 次/(100km·a)',
|
||||
parameters: params
|
||||
}
|
||||
}, null, 2)
|
||||
}
|
||||
} catch (e: any) {
|
||||
error.value = e.message || '计算失败'
|
||||
} finally {
|
||||
calculating.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 重置参数
|
||||
const resetParams = () => {
|
||||
Object.assign(params, JSON.parse(JSON.stringify(defaultParams)))
|
||||
result.value = null
|
||||
error.value = null
|
||||
}
|
||||
|
||||
// 导出配置
|
||||
const exportConfig = () => {
|
||||
const config = JSON.stringify(params, null, 2)
|
||||
const blob = new Blob([config], { type: 'application/json' })
|
||||
const url = URL.createObjectURL(blob)
|
||||
const a = document.createElement('a')
|
||||
a.href = url
|
||||
a.download = 'egm_config.json'
|
||||
a.click()
|
||||
URL.revokeObjectURL(url)
|
||||
}
|
||||
|
||||
// 声明 pywebview API 类型
|
||||
declare global {
|
||||
interface Window {
|
||||
pywebview?: {
|
||||
api: {
|
||||
calculate: (params: AllParameters) => Promise<any>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
14
webui/src/main.ts
Normal file
14
webui/src/main.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { createApp } from 'vue'
|
||||
import { Quasar } from 'quasar'
|
||||
import '@quasar/extras/material-icons/material-icons.css'
|
||||
import 'quasar/src/css/index.sass'
|
||||
import './style.css'
|
||||
import App from './App.vue'
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
app.use(Quasar, {
|
||||
plugins: {}
|
||||
})
|
||||
|
||||
app.mount('#app')
|
||||
9
webui/src/quasar-variables.sass
Normal file
9
webui/src/quasar-variables.sass
Normal file
@@ -0,0 +1,9 @@
|
||||
// Quasar SCSS Variables
|
||||
$primary : #1976D2
|
||||
$secondary : #26A69A
|
||||
$accent : #9C27B0
|
||||
$dark : #1D1D1D
|
||||
$positive : #21BA45
|
||||
$negative : #C10015
|
||||
$info : #31CCEC
|
||||
$warning : #F2C037
|
||||
19
webui/src/style.css
Normal file
19
webui/src/style.css
Normal file
@@ -0,0 +1,19 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
#app {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
overflow: auto;
|
||||
}
|
||||
39
webui/src/types/index.ts
Normal file
39
webui/src/types/index.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
// EGM 计算参数类型定义
|
||||
|
||||
export interface Parameter {
|
||||
// 基本参数
|
||||
rated_voltage: number // 额定电压等级 (kV)
|
||||
h_c_sag: number // 导线弧垂 (m)
|
||||
h_g_sag: number // 地线弧垂 (m)
|
||||
insulator_c_len: number // 导线串子绝缘长度 (m)
|
||||
string_c_len: number // 导线串长 (m)
|
||||
string_g_len: number // 地线串长 (m)
|
||||
h_arm: number[] // 导、地线挂点垂直距离 (m)
|
||||
gc_x: number[] // 导、地线水平坐标 (m)
|
||||
ground_angels: number[] // 地面倾角 (°)
|
||||
altitude: number // 海拔高度 (m)
|
||||
td: number // 雷暴日 (d)
|
||||
}
|
||||
|
||||
export interface AdvanceParameter {
|
||||
ng: number // 地闪密度 (次/(km²·a))
|
||||
Ip_a: number // 雷电流概率密度曲线系数a
|
||||
Ip_b: number // 雷电流概率密度曲线系数b
|
||||
}
|
||||
|
||||
export interface OptionalParameter {
|
||||
voltage_n: number // 计算时电压分成多少份
|
||||
max_i: number // 最大尝试雷电流 (kA)
|
||||
}
|
||||
|
||||
export interface AllParameters {
|
||||
parameter: Parameter
|
||||
advance: AdvanceParameter
|
||||
optional: OptionalParameter
|
||||
}
|
||||
|
||||
export interface CalculationResult {
|
||||
success: boolean
|
||||
message?: string
|
||||
data?: any
|
||||
}
|
||||
11
webui/tailwind.config.js
Normal file
11
webui/tailwind.config.js
Normal file
@@ -0,0 +1,11 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
content: [
|
||||
"./index.html",
|
||||
"./src/**/*.{vue,js,ts,jsx,tsx}",
|
||||
],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
1
webui/tsconfig.json
Normal file
1
webui/tsconfig.json
Normal file
@@ -0,0 +1 @@
|
||||
{"compilerOptions": {"target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], "skipLibCheck": true, "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "preserve", "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true}, "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"], "references": [{"path": "./tsconfig.node.json"}]}
|
||||
1
webui/tsconfig.node.json
Normal file
1
webui/tsconfig.node.json
Normal file
@@ -0,0 +1 @@
|
||||
{"compilerOptions": {"composite": true, "skipLibCheck": true, "module": "ESNext", "moduleResolution": "bundler", "allowSyntheticDefaultImports": true}, "include": ["vite.config.ts"]}
|
||||
22
webui/vite.config.ts
Normal file
22
webui/vite.config.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import { quasar, transformAssetUrls } from '@quasar/vite-plugin'
|
||||
import { fileURLToPath, URL } from 'node:url'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
vue({
|
||||
template: { transformAssetUrls }
|
||||
}),
|
||||
quasar()
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||||
}
|
||||
},
|
||||
server: {
|
||||
port: 5173,
|
||||
host: true
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user