Browse Source

feat: 一些调整

master
wangqi 6 months ago
parent
commit
e7cc105641
  1. 2
      .env
  2. 4
      .env.production
  3. 3
      components.d.ts
  4. 90
      src/api/module/eam/device/fileConfig.ts
  5. 5
      src/api/module/eam/device/firmware.ts
  6. 3
      src/api/module/index.ts
  7. 4
      src/api/server/config.ts
  8. 2
      src/pages/Profile/components/ProfileUser.vue
  9. 1
      src/pages/deviceInfo/components/DeliveryInfo.vue
  10. 1
      src/pages/deviceInfo/components/MaintainInfo.vue
  11. 52
      src/pages/deviceInfo/index.vue
  12. 2
      src/pages/deviceInfo/utils.ts
  13. 2
      src/pages/deviceStorage/index.vue
  14. 4
      src/pages/deviceStorage/utils.ts
  15. 2
      src/pages/deviceTest/testPlan/index.vue
  16. 40
      src/pages/ota/firmware/components/create-firmware-dlg.vue
  17. 8
      src/pages/ota/firmware/index.vue
  18. 150
      src/pages/system/config/index.vue
  19. 6
      src/pages/system/deviceField/index.vue

2
.env

@ -1,3 +1,5 @@ @@ -1,3 +1,5 @@
VITE_BASE_API_SYSTEM = '/remote/admin-api/system'
VITE_BASE_API_EAM = '/remote/admin-api/eam'
VITE_BASE_API_INFRA = '/remote/admin-api/infra'
VITE_DEVICE_INFO_INTERVAL = 35000

4
.env.production

@ -1,2 +1,2 @@ @@ -1,2 +1,2 @@
VITE_BASE_URL = 'http://62.234.18.176:7080'
VITE_SOCKET_SERVER = 'http://62.234.18.176:7080'
VITE_BASE_URL = 'http://192.168.1.3:48080'
VITE_SOCKET_SERVER = 'http://192.168.1.3:48080'

3
components.d.ts vendored

@ -22,8 +22,6 @@ declare module 'vue' { @@ -22,8 +22,6 @@ declare module 'vue' {
EdfsWrap: typeof import('./src/components/dashboard/Edfs-wrap.vue')['default']
Editor: typeof import('./src/components/dashboard/Editor/src/Editor.vue')['default']
ElAvatar: typeof import('element-plus/es')['ElAvatar']
ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb']
ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem']
ElButton: typeof import('element-plus/es')['ElButton']
ElCard: typeof import('element-plus/es')['ElCard']
ElCascader: typeof import('element-plus/es')['ElCascader']
@ -67,7 +65,6 @@ declare module 'vue' { @@ -67,7 +65,6 @@ declare module 'vue' {
ElTabPane: typeof import('element-plus/es')['ElTabPane']
ElTabs: typeof import('element-plus/es')['ElTabs']
ElTag: typeof import('element-plus/es')['ElTag']
ElTextarea: typeof import('element-plus/es')['ElTextarea']
ElTooltip: typeof import('element-plus/es')['ElTooltip']
ElTree: typeof import('element-plus/es')['ElTree']
ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']

90
src/api/module/eam/device/fileConfig.ts

@ -0,0 +1,90 @@ @@ -0,0 +1,90 @@
import { infraServer } from '../../index'
export interface FileClientConfig {
basePath: string
host?: string
port?: number
username?: string
password?: string
mode?: string
endpoint?: string
bucket?: string
accessKey?: string
accessSecret?: string
domain: string
}
export interface FileConfigVO {
id: number
name: string
storage?: number
master: boolean
visible: boolean
config: FileClientConfig
remark: string
createTime: Date
}
// 查询文件配置列表
export const getFileConfigPage = (params: PageParam) => {
return infraServer({
url: '/file-config/page',
method: 'get',
params,
})
}
// 查询文件配置详情
export const getFileConfig = (id: number) => {
return infraServer({
url: '/file-config/get',
method: 'get',
params: { id },
})
}
// 更新文件配置为主配置
export const updateFileConfigMaster = (id: number) => {
return infraServer({
url: '/file-config/update-master',
method: 'put',
params: { id },
})
}
// 新增文件配置
export const createFileConfig = (data: FileConfigVO) => {
return infraServer({
url: '/file-config/create',
method: 'post',
data,
})
}
// 修改文件配置
export const updateFileConfig = (data: FileConfigVO) => {
return infraServer({
url: '/file-config/update',
method: 'put',
data,
})
}
// 删除文件配置
export const deleteFileConfig = (id: number) => {
return infraServer({
url: '/file-config/delete',
method: 'delete',
params: { id },
})
}
// 测试文件配置
export const testFileConfig = (id: number) => {
return infraServer({
url: '/file-config/test',
method: 'get',
params: { id },
})
}

5
src/api/module/eam/device/firmware.ts

@ -11,8 +11,8 @@ export function getFirmwareList(params: PageParam) { @@ -11,8 +11,8 @@ export function getFirmwareList(params: PageParam) {
export function deleteFirmware(id: string) {
return eamServer({
url: '/firmware/delete',
method: 'post',
data: { id },
method: 'delete',
params: { id },
})
}
@ -22,6 +22,7 @@ export function createFirmware(data: any) { @@ -22,6 +22,7 @@ export function createFirmware(data: any) {
method: 'post',
data,
headers: { 'Content-Type': 'multipart/form-data' },
timeout: 20000,
})
}

3
src/api/module/index.ts

@ -3,5 +3,6 @@ import { API_Config } from '@/api/server/config' @@ -3,5 +3,6 @@ import { API_Config } from '@/api/server/config'
const systemServer = axiosInstance('system', API_Config.system)
const eamServer = axiosInstance('eam', API_Config.eam)
const infraServer = axiosInstance('infra', API_Config.infra)
export { systemServer, eamServer }
export { systemServer, eamServer, infraServer }

4
src/api/server/config.ts

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
export interface APIConfig {
system: Config
eam: Config
infra: Config
}
interface Config {
@ -15,6 +16,9 @@ const API_Config: APIConfig = { @@ -15,6 +16,9 @@ const API_Config: APIConfig = {
eam: {
baseAPI: import.meta.env.VITE_BASE_API_EAM,
},
infra: {
baseAPI: import.meta.env.VITE_BASE_API_INFRA,
},
}
export type APIConfigKeys = keyof typeof API_Config

2
src/pages/Profile/components/ProfileUser.vue

@ -54,7 +54,7 @@ import { getUserProfile, type ProfileVO } from '@/api/module/system/user/profile @@ -54,7 +54,7 @@ import { getUserProfile, type ProfileVO } from '@/api/module/system/user/profile
import { isResError } from '@/hooks/useMessage'
import Icon from '@/components/dashboard/Icon/src/Icon.vue'
import { useI18n } from 'vue-i18n'
import Avatar from '../../../avatar.png'
import Avatar from '../../avatar.png'
defineOptions({ name: 'ProfileUser' })
const { t } = useI18n()

1
src/pages/deviceInfo/components/DeliveryInfo.vue

@ -109,7 +109,6 @@ async function loadDeviceStorageInfo() { @@ -109,7 +109,6 @@ async function loadDeviceStorageInfo() {
if (!props.deviceId) return
const res = await getStorageOutByDeviceId(props.deviceId)
if (isResError(res)) return
debugger
for (const key of Object.keys(params.value)) {
params.value[key] = res.data[key] ?? ''
}

1
src/pages/deviceInfo/components/MaintainInfo.vue

@ -180,7 +180,6 @@ function oncancel(index: number) { @@ -180,7 +180,6 @@ function oncancel(index: number) {
}
async function onSave(row: any) {
debugger
for (const key of Object.keys(dataParams)) {
if (isEmpty(row[key]) && key !== 'description') {
msg.error(`请填写${tableCol.find(item => item.prop === key)?.label}`)

52
src/pages/deviceInfo/index.vue

@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
<div class="from-row">
<div class="label">设备序列:</div>
<el-input
v-model="queryParams.number"
v-model="queryParams.serialNo"
placeholder="请输入设备序列号"
clearable
@keyup.enter="handleQuery"
@ -15,7 +15,7 @@ @@ -15,7 +15,7 @@
<div class="from-row">
<div class="label">设备名称:</div>
<el-input
v-model="queryParams.deviceName"
v-model="queryParams.name"
placeholder="请输入设备名称"
clearable
@keyup.enter="handleQuery"
@ -34,14 +34,16 @@ @@ -34,14 +34,16 @@
</div>
<div class="from-row">
<div class="label">设备类别:</div>
<el-select v-model="queryParams.status" placeholder="" clearable>
<!-- <el-option
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/> -->
</el-select>
<el-cascader
class="input"
v-model="queryParams.categoryId"
:options="categoryTreeData"
:props="{
checkStrictly: true,
value: 'id',
label: 'name',
}"
/>
</div>
<div class="btn-group">
@ -148,6 +150,7 @@ import type { TableColumnCtx } from 'element-plus' @@ -148,6 +150,7 @@ import type { TableColumnCtx } from 'element-plus'
import { useRouter } from 'vue-router'
import { getDevicePage, type IDevice } from '@/api/module/eam/device'
import { deviceTableCol, DeviceStatus } from './utils'
import { getCategoryTree, type ICategoryTree } from '@/api/module/eam/device/category'
const loading = ref(true)
const total = ref(0)
@ -155,17 +158,22 @@ const list = ref<IDevice[]>([]) @@ -155,17 +158,22 @@ const list = ref<IDevice[]>([])
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
number: undefined,
deviceName: undefined,
serialNo: undefined,
name: undefined,
status: undefined,
code: undefined,
categoryId: [],
createTime: [],
})
const getList = async () => {
loading.value = true
const res = await getDevicePage(queryParams)
const options = {
...queryParams,
categoryId: queryParams.categoryId?.[queryParams.categoryId.length - 1],
}
const res = await getDevicePage(options)
if (!isResError(res)) {
list.value = res.data.list
@ -185,14 +193,22 @@ function handleJump(page: number) { @@ -185,14 +193,22 @@ function handleJump(page: number) {
}
function resetQuery() {
queryParams.number = undefined
queryParams.deviceName = undefined
queryParams.serialNo = undefined
queryParams.name = undefined
queryParams.status = undefined
queryParams.code = undefined
queryParams.categoryId = []
queryParams.createTime = []
handleQuery()
}
const categoryTreeData = ref<ICategoryTree[]>([])
async function loadDeviceTypeTree() {
const res = await getCategoryTree()
if (!isResError(res)) {
categoryTreeData.value = res.data
}
}
interface SpanMethodProps {
row: any
column: TableColumnCtx<any>
@ -204,6 +220,7 @@ const formRef = ref() @@ -204,6 +220,7 @@ const formRef = ref()
const openForm = (type: string, id?: number) => {}
onMounted(() => {
getList()
loadDeviceTypeTree()
})
const router = useRouter()
@ -220,6 +237,7 @@ function addDevice() { @@ -220,6 +237,7 @@ function addDevice() {
function onView(row: any) {
router.push({ path: '/device/deviceOperation', query: { action: 'view', id: row.id } })
}
</script>
<style lang="scss" scoped>

2
src/pages/deviceInfo/utils.ts

@ -7,7 +7,7 @@ export enum DeviceStatus { @@ -7,7 +7,7 @@ export enum DeviceStatus {
export const deviceTableCol = [
{ label: '设备编号', prop: 'serialNo', minWidth: '16%' },
{ label: '设备名称', prop: 'name', minWidth: '10%' },
{ label: '设备类型', prop: 'categoryId', minWidth: '10%' },
{ label: '设备类型', prop: 'categoryName', minWidth: '10%' },
{ label: '设备状态', prop: 'status', minWidth: '10%' },
{ label: '设备sn', prop: 'sn', minWidth: '10%' },
{ label: '创建时间', prop: 'createTime', minWidth: '10%' },

2
src/pages/deviceStorage/index.vue

@ -42,7 +42,7 @@ @@ -42,7 +42,7 @@
</div>
</div>
</EdfsWrap> -->
<EdfsWrap title="设备信息列表" class="storage-info-table">
<EdfsWrap title="出库设备列表" class="storage-info-table">
<EdfsTable
class="table"
v-loading="loading"

4
src/pages/deviceStorage/utils.ts

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
export const tableCol = [
{ label: '出库设备', prop: 'deviceId', minWidth: '12%' },
{ label: '客户', prop: 'customerId', minWidth: '10%' },
{ label: '出库设备', prop: 'deviceName', minWidth: '12%' },
{ label: '客户', prop: 'customerName', minWidth: '10%' },
{ label: '出库价格', prop: 'price', minWidth: '10%' },
// { label: '出库单名称', prop: 'name', minWidth: '10%' },
{ label: '描述', prop: 'description', minWidth: '16%' },

2
src/pages/deviceTest/testPlan/index.vue

@ -146,7 +146,7 @@ import { CommonStatusEnum } from '@/utils/constants' @@ -146,7 +146,7 @@ import { CommonStatusEnum } from '@/utils/constants'
const tableCol = [
{ label: '模板名称', prop: 'name', minWidth: '10%' },
{ label: '模板所属设备类型', prop: 'categoryId', minWidth: '12%' },
{ label: '模板所属设备类型', prop: 'categoryName', minWidth: '12%' },
{ label: '模板启用状态', prop: 'enabled', minWidth: '10%' },
{ label: '创建时间', prop: 'createTime', minWidth: '10%' },
{ label: '描述', prop: 'description', minWidth: '15%' },

40
src/pages/ota/firmware/components/create-firmware-dlg.vue

@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
@on-save="onSave"
title="新建固件"
:is-show="isShow"
:btn-loading="loading"
width="44%"
class="create-firmware-dlg"
>
@ -15,14 +16,19 @@ @@ -15,14 +16,19 @@
<FormItemInput label="固件版本" v-model="formData.version" require />
</el-row>
<el-row>
<FormItemSelect
label="固件类型"
<span class="label">
<span data-v-fbd7b238="" class="require">*</span>设备类别:
</span>
<el-cascader
class="input"
v-model="formData.type"
require
:options="getIntDictOptions('device_entity_type')"
keyTag="value"
valueTag="value"
labelTag="label"
:options="categoryTreeData"
style="flex: 1;"
:props="{
checkStrictly: true,
value: 'id',
label: 'name',
}"
/>
</el-row>
<!-- 固件文件 -->
@ -75,6 +81,7 @@ import type { @@ -75,6 +81,7 @@ import type {
UploadUserFile,
} from 'element-plus'
import { cloneDeep } from 'lodash'
import { getCategoryTree, type ICategoryTree } from '@/api/module/eam/device/category'
interface Props {
isShow: boolean
@ -115,7 +122,7 @@ function validate() { @@ -115,7 +122,7 @@ function validate() {
return true
}
if (!formData.value.type) {
if (formData.value.type.length < 1) {
message.error('请选择固件类型')
return true
}
@ -127,16 +134,19 @@ function validate() { @@ -127,16 +134,19 @@ function validate() {
return false
}
const loading = ref(false)
async function onSave() {
if (validate()) return
loading.value = true
const data = new FormData()
data.append('path', getTenantId())
data.append('file', fileList.value[0].raw as File)
data.append('name', formData.value.name)
data.append('version', formData.value.version)
data.append('type', formData.value.type)
data.append('type', formData.value.type[formData.value.type.length - 1])
data.append('description', formData.value.description)
const res = await createFirmware(data)
loading.value = false
if (isResError(res)) return
emits('on-save')
clearData()
@ -150,6 +160,17 @@ function onClone() { @@ -150,6 +160,17 @@ function onClone() {
clearData()
emits('on-close')
}
const categoryTreeData = ref<ICategoryTree[]>([])
async function loadDeviceTypeTree() {
const res = await getCategoryTree()
if (!isResError(res)) {
categoryTreeData.value = res.data
}
}
onMounted(() => {
loadDeviceTypeTree()
})
</script>
<style scoped lang="scss">
@ -163,6 +184,7 @@ function onClone() { @@ -163,6 +184,7 @@ function onClone() {
:deep(.label) {
margin-right: 10px;
}
span {
width: 110px;
height: 32px;

8
src/pages/ota/firmware/index.vue

@ -60,14 +60,14 @@ @@ -60,14 +60,14 @@
/>
</template>
<el-table-column label="操作" min-width="14%">
<!-- <el-table-column label="操作" min-width="14%">
<template #default="scope">
<!-- <EdfsButton
<EdfsButton
type="success"
link
inner-text="下载固件"
@click="onDownload(scope.row)"
/> -->
/>
<EdfsButton
type="danger"
link
@ -75,7 +75,7 @@ @@ -75,7 +75,7 @@
@click="onDelete(scope.row.id)"
/>
</template>
</el-table-column>
</el-table-column>-->
</edfs-table>
</EdfsWrap>
<createFirmwareDlg :is-show="isShowDlg" @on-close="onClose" @on-save="onSave" />

150
src/pages/system/config/index.vue

@ -19,13 +19,159 @@ @@ -19,13 +19,159 @@
</div>
</div>
</EdfsWrap>
<EdfsWrap title="文件存储接入配置" class="file" v-if="isEnableFileStorage"></EdfsWrap>
<EdfsWrap title="文件存储接入配置" class="file" v-if="isEnableFileStorage">
<el-form
ref="formRef"
v-loading="formLoading"
:model="formData"
:rules="formRules"
label-width="120px"
>
<el-form-item label="配置名" prop="name">
<el-input v-model="formData.name" placeholder="请输入配置名" />
</el-form-item>
<el-form-item label="存储器" prop="storage">
<el-select
v-model="formData.storage"
:disabled="formData.id !== undefined"
placeholder="请选择存储器"
>
<el-option
v-for="dict in [{ label: 'S3本地存储', value: 20 }]"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item
v-if="formData.storage === 20"
label="存储 bucket"
prop="config.bucket"
>
<el-input v-model="formData.config.bucket" placeholder="请输入 bucket" />
</el-form-item>
<el-form-item
v-if="formData.storage === 20"
label="accessKey"
prop="config.accessKey"
>
<el-input v-model="formData.config.accessKey" placeholder="请输入 accessKey" />
</el-form-item>
<el-form-item
v-if="formData.storage === 20"
label="accessSecret"
prop="config.accessSecret"
>
<el-input
v-model="formData.config.accessSecret"
placeholder="请输入 accessSecret"
/>
</el-form-item>
<!-- 通用 -->
<el-form-item v-if="formData.storage === 20" label="自定义域名">
<!-- 无需参数校验所以去掉 prop -->
<el-input v-model="formData.config.domain" placeholder="请输入自定义域名" />
</el-form-item>
<el-form-item
v-else-if="formData.storage"
label="自定义域名"
prop="config.domain"
>
<el-input v-model="formData.config.domain" placeholder="请输入自定义域名" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="formData.remark" placeholder="请输入备注" />
</el-form-item>
</el-form>
<div style="display: flex; justify-content: center; margin-top: 20px">
<el-button :disabled="formLoading" type="primary" @click="submitForm"
> </el-button
>
</div>
</EdfsWrap>
</div>
</template>
<script setup lang="ts">
import {
createFileConfig,
getFileConfig,
updateFileConfig,
type FileClientConfig,
type FileConfigVO,
} from '@/api/module/eam/device/fileConfig'
import EdfsWrap from '@/components/dashboard/Edfs-wrap.vue'
const isEnableFileStorage = ref(false)
const isEnableFileStorage = ref(true)
import { useI18n } from 'vue-i18n'
import { useMessage } from '@/hooks/useMessage'
import { type FormRules } from 'element-plus'
defineOptions({ name: 'InfraFileConfigForm' })
const { t } = useI18n() //
const message = useMessage() //
const formLoading = ref(false) // 12
const formType = ref('update') // create - update -
const formData = ref({
id: undefined,
name: '',
storage: 20,
remark: '',
config: {} as FileClientConfig,
})
const formRules = reactive<FormRules>({
name: [{ required: true, message: '配置名不能为空', trigger: 'blur' }],
storage: [{ required: true, message: '存储器不能为空', trigger: 'change' }],
config: {
basePath: [{ required: true, message: '基础路径不能为空', trigger: 'blur' }],
host: [{ required: true, message: '主机地址不能为空', trigger: 'blur' }],
port: [{ required: true, message: '主机端口不能为空', trigger: 'blur' }],
username: [{ required: true, message: '用户名不能为空', trigger: 'blur' }],
password: [{ required: true, message: '密码不能为空', trigger: 'blur' }],
mode: [{ required: true, message: '连接模式不能为空', trigger: 'change' }],
endpoint: [{ required: true, message: '节点地址不能为空', trigger: 'blur' }],
bucket: [{ required: true, message: '存储 bucket 不能为空', trigger: 'blur' }],
accessKey: [{ required: true, message: 'accessKey 不能为空', trigger: 'blur' }],
accessSecret: [{ required: true, message: 'accessSecret 不能为空', trigger: 'blur' }],
domain: [{ required: true, message: '自定义域名不能为空', trigger: 'blur' }],
} as FormRules,
})
const formRef = ref() // Ref
async function loadFileConfig() {
const res = await getFileConfig(23)
formData.value = res.data
}
const submitForm = async () => {
//
if (!formRef) return
const valid = await formRef.value.validate()
if (!valid) return
//
formLoading.value = true
try {
const data = formData.value as unknown as FileConfigVO
if (formType.value === 'create') {
await createFileConfig(data)
message.success(t('common.createSuccess'))
} else {
await updateFileConfig(data)
message.success(t('common.updateSuccess'))
}
} finally {
formLoading.value = false
}
}
onMounted(() => {
loadFileConfig()
})
</script>
<style scoped lang="scss">

6
src/pages/system/deviceField/index.vue

@ -15,7 +15,7 @@ @@ -15,7 +15,7 @@
@on-delete="onDeleteCategory"
/>
</EdfsWrap>
<EdfsWrap title="设备处置/报废/故障 常用原因管理" class="cause-box">
<!-- <EdfsWrap title="设备处置/报废/故障 常用原因管理" class="cause-box">
<template #title-right>
<EdfsButton
type="success"
@ -25,7 +25,7 @@ @@ -25,7 +25,7 @@
</template>
<Dispose />
</EdfsWrap>
<EdfsWrap title="设备信息字段管理" class="info-box"></EdfsWrap>
<EdfsWrap title="设备信息字段管理" class="info-box"></EdfsWrap> -->
</div>
<CategoryDlg
:action="categoryAction"
@ -106,7 +106,7 @@ onMounted(() => { @@ -106,7 +106,7 @@ onMounted(() => {
height: 100%;
column-gap: 10px;
.category-box {
flex: 0.6;
// flex: 0.6;
}
.cause-box {
flex: 0.6;

Loading…
Cancel
Save