feat(iot): 新增设备管理卡片展示功能
- 添加设备列表页面,支持查询、重置功能 - 实现设备详情页面,展示设备信息和扩展属性 - 新增设备编辑组件,支持创建和修改设备 - 重构公告卡片组件,改为设备卡片样式
This commit is contained in:
parent
dfd9d165ca
commit
a45b8985b6
@ -36,6 +36,17 @@ const IOT: AppRouteRecordRaw = {
|
|||||||
permissions: ['iot:device'],
|
permissions: ['iot:device'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'deviceCard',
|
||||||
|
name: 'DeviceCard',
|
||||||
|
component: () => import('@/views/iot/deviceCard/index.vue'),
|
||||||
|
meta: {
|
||||||
|
locale: '设备管理(卡片)',
|
||||||
|
title: '设备管理(卡片)',
|
||||||
|
requiresAuth: true,
|
||||||
|
permissions: ['iot:device'],
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'product/:id',
|
path: 'product/:id',
|
||||||
name: 'productDetail',
|
name: 'productDetail',
|
||||||
|
@ -43,7 +43,7 @@ const NOTIFICATION: AppRouteRecordRaw = {
|
|||||||
title: '公告详情',
|
title: '公告详情',
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
showInMenu: false,
|
showInMenu: false,
|
||||||
permissions: ['message:bulletin:query'],
|
permissions: ['message:bulletin'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -44,17 +44,6 @@ const USER: AppRouteRecordRaw = {
|
|||||||
permissions: ['*'],
|
permissions: ['*'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: 'bulletinCard',
|
|
||||||
name: 'BulletinCard',
|
|
||||||
component: () => import('@/views/user/bulletin-card/index.vue'),
|
|
||||||
meta: {
|
|
||||||
locale: '公告通知(卡片)',
|
|
||||||
title: '公告通知(卡片)',
|
|
||||||
requiresAuth: true,
|
|
||||||
permissions: ['*'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: 'messages',
|
path: 'messages',
|
||||||
name: 'Messages',
|
name: 'Messages',
|
||||||
|
@ -20,11 +20,11 @@
|
|||||||
{{ createBy }}
|
{{ createBy }}
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
<a-descriptions-item label="创建时间">
|
<a-descriptions-item label="创建时间">
|
||||||
{{ dayjs(publishTime).format('YYYY-MM-DD HH:mm:ss') }}
|
{{ dayjs(createTime).format('YYYY-MM-DD HH:mm:ss') }}
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="备注">
|
|
||||||
{{ remark }}
|
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
|
<!-- <a-descriptions-item label="备注">-->
|
||||||
|
<!-- {{ remark }}-->
|
||||||
|
<!-- </a-descriptions-item>-->
|
||||||
</a-descriptions>
|
</a-descriptions>
|
||||||
</template>
|
</template>
|
||||||
</a-card-meta>
|
</a-card-meta>
|
||||||
@ -32,9 +32,17 @@
|
|||||||
<template #actions>
|
<template #actions>
|
||||||
<div>
|
<div>
|
||||||
<a-space>
|
<a-space>
|
||||||
<a-button type="outline" @click="handleDetail(id)">
|
<a-button type="outline" status="success" @click="openDetail(id)">
|
||||||
详情
|
详情
|
||||||
</a-button>
|
</a-button>
|
||||||
|
<DeviceEdit
|
||||||
|
ref="editUserRef"
|
||||||
|
:id="id"
|
||||||
|
:is-create="false"
|
||||||
|
/>
|
||||||
|
<a-button type="outline" status="danger" @click="handleDelete(id)">
|
||||||
|
删除
|
||||||
|
</a-button>
|
||||||
</a-space>
|
</a-space>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -46,6 +54,9 @@
|
|||||||
|
|
||||||
import router from '@/router';
|
import router from '@/router';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
import { deleteDevice } from '@/api/device';
|
||||||
|
import { Message } from '@arco-design/web-vue';
|
||||||
|
import DeviceEdit from '@/views/iot/deviceCard/components/device-edit.vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
loading: {
|
loading: {
|
||||||
@ -72,14 +83,28 @@
|
|||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
publishTime: {
|
createTime: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
// 详情
|
// 打开详情
|
||||||
const handleDetail = async (id: number) => {
|
function openDetail(id:number): void{
|
||||||
await router.push({ name: 'Details', params: { id } });
|
const url = router.resolve({
|
||||||
|
name: 'deviceDetail',
|
||||||
|
params: {id}
|
||||||
|
}).href;
|
||||||
|
router.push(url);
|
||||||
|
}
|
||||||
|
// 删除
|
||||||
|
const handleDelete = async (id: number) => {
|
||||||
|
const res = await deleteDevice(id);
|
||||||
|
if (res.status === 200) {
|
||||||
|
Message.success({
|
||||||
|
content: '删除成功',
|
||||||
|
duration: 5 * 1000,
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
102
src/views/iot/deviceCard/components/device-detail.vue
Normal file
102
src/views/iot/deviceCard/components/device-detail.vue
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<Breadcrumb :items="['物联网管理', '设备管理', '设备详情']" />
|
||||||
|
<a-card class="general-card" title=" ">
|
||||||
|
<a-descriptions v-model="renderData" size="large">
|
||||||
|
<template #title><h3 style="margin-top: -15px">设备详情</h3></template>
|
||||||
|
<a-descriptions-item label="设备名称">{{renderData.name }}</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="硬件版本">{{renderData.hardwareVersion }}</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="固件版本">{{renderData.firmwareVersion }}</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="所属产品">{{renderData.productId }}</a-descriptions-item>
|
||||||
|
<!-- <a-descriptions-item label="备注">{{renderData.remark }}</a-descriptions-item>-->
|
||||||
|
<a-descriptions-item label="创建时间">{{dayjs(renderData.createTime).format('YYYY-MM-DD HH:mm:ss') }}</a-descriptions-item>
|
||||||
|
</a-descriptions>
|
||||||
|
</a-card>
|
||||||
|
<a-card class="general-card" style="margin-top: 10px">
|
||||||
|
<a-tabs :active-key="activeKey" @tab-click="handleMenuClick" style="padding-top: 20px">
|
||||||
|
<a-tab-pane key="1" tab="参数" title="扩展属性">
|
||||||
|
<a-table :columns="columns" :data="renderData.extendParams" />
|
||||||
|
</a-tab-pane>
|
||||||
|
<a-tab-pane key="2" tab="基本信息" title="基本信息">
|
||||||
|
基本信息
|
||||||
|
</a-tab-pane>
|
||||||
|
<a-tab-pane key="3" tab="执行服务" title="执行服务"> 执行服务内容 </a-tab-pane>
|
||||||
|
</a-tabs>
|
||||||
|
</a-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
import { onMounted, ref } from 'vue';
|
||||||
|
import { queryDeviceDetail } from '@/api/device';
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
const id = Number(route.params.id);
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: '参数名称',
|
||||||
|
dataIndex: 'name',
|
||||||
|
slotName: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '参数标识',
|
||||||
|
dataIndex: 'identifier',
|
||||||
|
slotName: 'identifier',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '数据类型',
|
||||||
|
dataIndex: 'dataType',
|
||||||
|
slotName: 'dataType',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '参数类型',
|
||||||
|
dataIndex: 'type',
|
||||||
|
slotName: 'type',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const activeKey = ref('1');
|
||||||
|
const renderData = ref([]);
|
||||||
|
const fetchData = async (Id: number) => {
|
||||||
|
const res = await queryDeviceDetail(Id);
|
||||||
|
renderData.value = res.data;
|
||||||
|
};
|
||||||
|
const handleMenuClick = (e: any) => {
|
||||||
|
activeKey.value = e;
|
||||||
|
};
|
||||||
|
onMounted(() => {
|
||||||
|
fetchData(id);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
padding: 0 20px 20px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 24px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meta span {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.attachments li {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.attachments a {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #1890ff;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.attachments a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
</style>
|
415
src/views/iot/deviceCard/components/device-edit.vue
Normal file
415
src/views/iot/deviceCard/components/device-edit.vue
Normal file
@ -0,0 +1,415 @@
|
|||||||
|
<template>
|
||||||
|
<!-- <a-button v-permission="['iot:device:create']" v-if="props.isCreate" type="primary" @click="handleClick">-->
|
||||||
|
<!-- <template #icon>-->
|
||||||
|
<!-- <icon-plus />-->
|
||||||
|
<!-- </template>-->
|
||||||
|
<!-- 新建-->
|
||||||
|
<!-- </a-button>-->
|
||||||
|
<a-col
|
||||||
|
v-permission="['iot:device:create']"
|
||||||
|
v-if="props.isCreate"
|
||||||
|
@click="handleClick"
|
||||||
|
:xs="12"
|
||||||
|
:sm="12"
|
||||||
|
:md="12"
|
||||||
|
:lg="6"
|
||||||
|
:xl="6"
|
||||||
|
:xxl="6"
|
||||||
|
class="list-col"
|
||||||
|
>
|
||||||
|
<div class="card-wrap empty-wrap">
|
||||||
|
<a-card :bordered="false" hoverable>
|
||||||
|
<a-result :status="null" title="点击创建设备">
|
||||||
|
<template #icon>
|
||||||
|
<icon-plus style="font-size: 20px" />
|
||||||
|
</template>
|
||||||
|
</a-result>
|
||||||
|
</a-card>
|
||||||
|
</div>
|
||||||
|
</a-col>
|
||||||
|
<a-button
|
||||||
|
v-permission="['iot:device:update']"
|
||||||
|
v-if="!props.isCreate"
|
||||||
|
type="outline"
|
||||||
|
size="small"
|
||||||
|
@click="handleClick"
|
||||||
|
>
|
||||||
|
<!-- <template #icon><icon-edit /></template>-->
|
||||||
|
修改
|
||||||
|
</a-button>
|
||||||
|
|
||||||
|
<a-modal
|
||||||
|
width="900px"
|
||||||
|
height="500px"
|
||||||
|
:visible="visible"
|
||||||
|
@cancel="handleCancel"
|
||||||
|
>
|
||||||
|
<template #title>{{ modalTitle }}</template>
|
||||||
|
<a-form
|
||||||
|
ref="CreateRef"
|
||||||
|
:model="formData"
|
||||||
|
:style="{ width: '800px', height: '420px' }"
|
||||||
|
>
|
||||||
|
<!-- 产品id -->
|
||||||
|
<a-form-item
|
||||||
|
field="productName"
|
||||||
|
label="产品名称"
|
||||||
|
:rules="[{ required: true, message: '产品名称不能为空' }]"
|
||||||
|
:validate-trigger="['change']"
|
||||||
|
>
|
||||||
|
<a-select
|
||||||
|
v-model="formData.productName"
|
||||||
|
placeholder="请选择产品名称"
|
||||||
|
:loading="loading"
|
||||||
|
:filter-option="false"
|
||||||
|
allow-search
|
||||||
|
@search="handleSearch"
|
||||||
|
>
|
||||||
|
<a-option v-for="item of options" :key="item.id" :value="item.name">{{
|
||||||
|
item.name
|
||||||
|
}}</a-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
<!-- 设备名称 -->
|
||||||
|
<a-form-item
|
||||||
|
field="name"
|
||||||
|
label="设备名称"
|
||||||
|
:rules="[{ required: true, message: '设备名称不能为空' }]"
|
||||||
|
:validate-trigger="['change']"
|
||||||
|
>
|
||||||
|
<a-input v-model="formData.name" placeholder="请输入设备名称" />
|
||||||
|
</a-form-item>
|
||||||
|
<!-- 硬件版本 -->
|
||||||
|
<a-form-item
|
||||||
|
field="hardwareVersion"
|
||||||
|
label="硬件版本"
|
||||||
|
:rules="[{ required: true, message: '硬件版本不能为空' }]"
|
||||||
|
:validate-trigger="['change']"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model="formData.hardwareVersion"
|
||||||
|
placeholder="请输入硬件版本"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<!-- 固件版本 -->
|
||||||
|
<a-form-item
|
||||||
|
field="firmwareVersion"
|
||||||
|
label="固件版本"
|
||||||
|
:rules="[{ required: true, message: '固件版本不能为空' }]"
|
||||||
|
:validate-trigger="['change']"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model="formData.firmwareVersion"
|
||||||
|
placeholder="请输入固件版本"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
field="remark"
|
||||||
|
label="备注"
|
||||||
|
>
|
||||||
|
<a-textarea
|
||||||
|
v-model="formData.remark"
|
||||||
|
placeholder="请输入描述"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<!-- 扩展属性 -->
|
||||||
|
<a-form-item field="extendParams" label="扩展属性">
|
||||||
|
<!-- <a-input-->
|
||||||
|
<!-- v-model="formData.extendParams"-->
|
||||||
|
<!-- placeholder='请输入扩展属性'-->
|
||||||
|
<!-- />-->
|
||||||
|
<div style="width: 100%">
|
||||||
|
<div style="width: 100%; margin-bottom: 5px">
|
||||||
|
<a-space
|
||||||
|
v-for="(param, index) in paramsData"
|
||||||
|
:key="index"
|
||||||
|
style="margin-bottom: 5px"
|
||||||
|
>
|
||||||
|
<a-input v-model="param.name" placeholder="名称" allow-clear />
|
||||||
|
<a-input
|
||||||
|
v-model="param.identifier"
|
||||||
|
placeholder="标识"
|
||||||
|
allow-clear
|
||||||
|
/>
|
||||||
|
<a-select
|
||||||
|
v-model="param.dataType"
|
||||||
|
:options="dataTypeOptions"
|
||||||
|
allow-search
|
||||||
|
placeholder="数据类型"
|
||||||
|
style="width: 140px"
|
||||||
|
/>
|
||||||
|
<a-select
|
||||||
|
v-model="param.type"
|
||||||
|
:options="typeOptions"
|
||||||
|
allow-search
|
||||||
|
placeholder="类型"
|
||||||
|
style="width: 140px"
|
||||||
|
/>
|
||||||
|
<a-button type="text" @click="handleDeleteParams(index)"
|
||||||
|
><icon-minus-circle
|
||||||
|
/></a-button>
|
||||||
|
</a-space>
|
||||||
|
</div>
|
||||||
|
<a-button type="outline" @click="handleAddParams" style="width: 100%">
|
||||||
|
<icon-plus />
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<a-button class="editor-button" @click="handleCancel">取消</a-button>
|
||||||
|
<a-button class="editor-button" type="primary" @click="handleSubmit"
|
||||||
|
>确定</a-button
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import useVisible from '@/hooks/visible';
|
||||||
|
import {
|
||||||
|
computed,
|
||||||
|
defineEmits,
|
||||||
|
PropType,
|
||||||
|
ref,
|
||||||
|
shallowRef,
|
||||||
|
onBeforeUnmount,
|
||||||
|
} from 'vue';
|
||||||
|
import { CreateRecord } from '@/api/user';
|
||||||
|
import { FormInstance } from '@arco-design/web-vue/es/form';
|
||||||
|
import { Message } from '@arco-design/web-vue';
|
||||||
|
import '@wangeditor/editor/dist/css/style.css';
|
||||||
|
import { createDevice, queryDeviceByName, queryDeviceDetail, updateDevice } from '@/api/device';
|
||||||
|
import type { SelectOptionData } from '@arco-design/web-vue/es/select/interface';
|
||||||
|
import { queryProductDetail } from '@/api/product';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
id: {
|
||||||
|
type: Number,
|
||||||
|
default: -1,
|
||||||
|
},
|
||||||
|
isCreate: Boolean,
|
||||||
|
});
|
||||||
|
const paramsData = ref([
|
||||||
|
{
|
||||||
|
name: '',
|
||||||
|
identifier: '',
|
||||||
|
dataType: '',
|
||||||
|
type: '',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
const dataTypeOptions = computed<SelectOptionData[]>(() => [
|
||||||
|
{
|
||||||
|
label: '整型',
|
||||||
|
value: 'INT',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '单精度浮点型',
|
||||||
|
value: 'FLOAT',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '双精度浮点型',
|
||||||
|
value: 'DOUBLE',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '布尔型',
|
||||||
|
value: 'BOOLEAN',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '字符串',
|
||||||
|
value: 'STRING',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '日期型',
|
||||||
|
value: 'DATE',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '透传',
|
||||||
|
value: 'RAW',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
const typeOptions = computed<SelectOptionData[]>(() => [
|
||||||
|
{
|
||||||
|
label: '输入',
|
||||||
|
value: 'INPUT',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '输出',
|
||||||
|
value: 'OUTPUT',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '读写属性',
|
||||||
|
value: 'RW',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
const emit = defineEmits(['refresh']);
|
||||||
|
const modalTitle = computed(() => {
|
||||||
|
return props.isCreate ? '创建设备' : '编辑设备';
|
||||||
|
});
|
||||||
|
const { visible, setVisible } = useVisible(false);
|
||||||
|
const checkKeys = ref<number[]>([]);
|
||||||
|
|
||||||
|
const CreateRef = ref<FormInstance>();
|
||||||
|
const formData = ref<any>({});
|
||||||
|
const editorRef = shallowRef();
|
||||||
|
const options = ref();
|
||||||
|
const loading = ref(false);
|
||||||
|
|
||||||
|
// 搜索
|
||||||
|
const handleSearch = (value: any) => {
|
||||||
|
if (value) {
|
||||||
|
loading.value = true;
|
||||||
|
options.value = [];
|
||||||
|
window.setTimeout(async () => {
|
||||||
|
const res = await queryDeviceByName({
|
||||||
|
name: value,
|
||||||
|
page:1,
|
||||||
|
size: 10,
|
||||||
|
});
|
||||||
|
options.value = res.data.records.map((item: any) => {
|
||||||
|
return {
|
||||||
|
id: item.id,
|
||||||
|
name: item.name,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
loading.value = false;
|
||||||
|
}, 1000);
|
||||||
|
} else {
|
||||||
|
options.value = [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 点击添加参数
|
||||||
|
const handleAddParams = () => {
|
||||||
|
// paramsVisible.value = true;
|
||||||
|
paramsData.value.push({
|
||||||
|
name: '',
|
||||||
|
identifier: '',
|
||||||
|
dataType: '',
|
||||||
|
type: '',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// 删除参数
|
||||||
|
const handleDeleteParams = (record: number) => {
|
||||||
|
if (record !== -1) {
|
||||||
|
paramsData.value.splice(record, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 组件被点击
|
||||||
|
const handleClick = async () => {
|
||||||
|
setVisible(true);
|
||||||
|
|
||||||
|
if (!props.isCreate) {
|
||||||
|
queryDeviceDetail(props.id).then((res) => {
|
||||||
|
formData.value = res.data;
|
||||||
|
paramsData.value = res.data.extendParams;
|
||||||
|
console.log('formData:', formData.value);
|
||||||
|
|
||||||
|
const ID = formData.value.productId;
|
||||||
|
return queryProductDetail(ID);
|
||||||
|
}).then((res) => {
|
||||||
|
formData.value.productName = res.data.name;
|
||||||
|
}).catch((error) => {
|
||||||
|
console.error('Error fetching data:', error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 提交
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
const valid = await CreateRef.value?.validate();
|
||||||
|
// formData.value.productId = formData.value.productId.id;
|
||||||
|
if (!valid) {
|
||||||
|
// 新增
|
||||||
|
formData.value.extendParams = paramsData.value;
|
||||||
|
const productId = await queryDeviceByName(formData.value.productName);
|
||||||
|
formData.value.productId = productId.data.records[0].id;
|
||||||
|
|
||||||
|
if (props.isCreate) {
|
||||||
|
// formData.value.username = formData.value.email;
|
||||||
|
const res = await createDevice(formData.value);
|
||||||
|
if (res.status === 200) {
|
||||||
|
Message.success({
|
||||||
|
content: '新建成功',
|
||||||
|
duration: 5 * 1000,
|
||||||
|
});
|
||||||
|
emit('refresh');
|
||||||
|
setVisible(false);
|
||||||
|
}
|
||||||
|
CreateRef.value?.resetFields();
|
||||||
|
} else {
|
||||||
|
// 编辑
|
||||||
|
const res = await updateDevice(formData.value);
|
||||||
|
if (res.status === 200) {
|
||||||
|
Message.success({
|
||||||
|
content: '修改成功',
|
||||||
|
duration: 5 * 1000,
|
||||||
|
});
|
||||||
|
emit('refresh');
|
||||||
|
setVisible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 组件销毁时,也及时销毁编辑器
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
const editor = editorRef.value;
|
||||||
|
if (editor == null) return;
|
||||||
|
editor.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 关闭
|
||||||
|
const handleCancel = async () => {
|
||||||
|
checkKeys.value = [];
|
||||||
|
setVisible(false);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
.editor-button {
|
||||||
|
position: static;
|
||||||
|
}
|
||||||
|
.card-wrap {
|
||||||
|
height: 100%;
|
||||||
|
transition: all 0.3s;
|
||||||
|
border: 1px solid var(--color-neutral-3);
|
||||||
|
&:hover {
|
||||||
|
transform: translateY(-4px);
|
||||||
|
}
|
||||||
|
:deep(.arco-card-meta-description) {
|
||||||
|
color: rgb(var(--gray-6));
|
||||||
|
.arco-descriptions-item-label-inline {
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 12px;
|
||||||
|
color: rgb(var(--gray-6));
|
||||||
|
}
|
||||||
|
.arco-descriptions-item-value-inline {
|
||||||
|
color: rgb(var(--gray-8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.empty-wrap {
|
||||||
|
height: 210px;
|
||||||
|
border-radius: 4px;
|
||||||
|
:deep(.arco-card) {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 4px;
|
||||||
|
.arco-result-title {
|
||||||
|
color: rgb(var(--gray-6));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
:deep(.list-wrap) {
|
||||||
|
.list-row {
|
||||||
|
align-items: stretch;
|
||||||
|
.list-col {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<Breadcrumb :items="['个人中心', '公告通知']" />
|
<Breadcrumb :items="['系统管理', '公告设置']" />
|
||||||
<a-card class="general-card" title=" ">
|
<a-card class="general-card" title=" ">
|
||||||
<a-row>
|
<a-row>
|
||||||
<a-col :flex="1">
|
<a-col :flex="1">
|
||||||
@ -12,39 +12,48 @@
|
|||||||
>
|
>
|
||||||
<a-row :gutter="18">
|
<a-row :gutter="18">
|
||||||
<a-col :span="9">
|
<a-col :span="9">
|
||||||
<a-form-item field="title" label="标题">
|
<a-form-item
|
||||||
|
field="name"
|
||||||
|
label='名称'
|
||||||
|
>
|
||||||
<a-input
|
<a-input
|
||||||
v-model="formModel.title"
|
v-model="formModel.name"
|
||||||
style="width: 360px"
|
style="width: 360px"
|
||||||
placeholder="请输入标题"
|
placeholder='请输入设备名称'
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="10">
|
<a-col :span="10">
|
||||||
<a-form-item field="Time" label="时间">
|
<a-form-item field="status" label='状态'>
|
||||||
<a-range-picker
|
<a-input
|
||||||
show-time
|
v-model="formModel.status"
|
||||||
format="YYYY-MM-DD HH:mm"
|
style="width: 360px"
|
||||||
@ok="timeRangs"
|
placeholder='请输入设备状态'
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<!-- <a-col :span="9">-->
|
<a-col :span="9">
|
||||||
<!-- <a-form-item field="isRead" label="状态">-->
|
<a-form-item
|
||||||
<!-- <a-select-->
|
field="isOnline"
|
||||||
<!-- v-model="formModel.isRead"-->
|
label='在线'
|
||||||
<!-- style="width: 360px"-->
|
>
|
||||||
<!-- placeholder="请选择状态"-->
|
<a-select
|
||||||
<!-- :options="statusOptions"-->
|
v-model="formModel.isOnline"
|
||||||
<!-- />-->
|
style="width: 360px"
|
||||||
<!-- </a-form-item>-->
|
placeholder='请选择是否在线'
|
||||||
<!-- </a-col>-->
|
:options="statusOptions"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</a-row>
|
</a-row>
|
||||||
</a-form>
|
</a-form>
|
||||||
</a-col>
|
</a-col>
|
||||||
<!-- <a-divider style="height: 84px" direction="vertical" />-->
|
<a-divider style="height: 84px" direction="vertical" />
|
||||||
<a-col :flex="'46px'" style="text-align: right">
|
<a-col :flex="'86px'" style="text-align: right">
|
||||||
<a-space :size="18">
|
<a-space direction="vertical" :size="18">
|
||||||
<a-button type="primary" @click="search">
|
<a-button type="primary" @click="search">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<icon-search />
|
<icon-search />
|
||||||
@ -77,10 +86,9 @@
|
|||||||
<CardWrap
|
<CardWrap
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
:id="item.id"
|
:id="item.id"
|
||||||
:title="item.title"
|
:title="item.name"
|
||||||
:remark="item.remark"
|
|
||||||
:createBy="item.createBy"
|
:createBy="item.createBy"
|
||||||
:publishTime="item.publishTime"
|
:createTime="item.createTime"
|
||||||
open-txt="详情"
|
open-txt="详情"
|
||||||
>
|
>
|
||||||
<template #skeleton>
|
<template #skeleton>
|
||||||
@ -94,29 +102,30 @@
|
|||||||
</template>
|
</template>
|
||||||
</CardWrap>
|
</CardWrap>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col
|
<DeviceEdit ref="createUserRef" :is-create="true" />
|
||||||
:xs="12"
|
<!-- <a-col-->
|
||||||
:sm="12"
|
<!-- :xs="12"-->
|
||||||
:md="12"
|
<!-- :sm="12"-->
|
||||||
:lg="6"
|
<!-- :md="12"-->
|
||||||
:xl="6"
|
<!-- :lg="6"-->
|
||||||
:xxl="6"
|
<!-- :xl="6"-->
|
||||||
class="list-col"
|
<!-- :xxl="6"-->
|
||||||
>
|
<!-- class="list-col"-->
|
||||||
<div class="card-wrap empty-wrap">
|
<!-- >-->
|
||||||
<a-card :bordered="false" hoverable>
|
<!-- <div class="card-wrap empty-wrap">-->
|
||||||
<a-result :status="null" title="点击创建设备">
|
<!-- <a-card :bordered="false" hoverable>-->
|
||||||
<template #icon>
|
<!-- <a-result :status="null" title="点击创建设备">-->
|
||||||
<icon-plus style="font-size: 20px" />
|
<!-- <template #icon>-->
|
||||||
</template>
|
<!-- <icon-plus style="font-size: 20px" />-->
|
||||||
</a-result>
|
<!-- </template>-->
|
||||||
</a-card>
|
<!-- </a-result>-->
|
||||||
</div>
|
<!-- </a-card>-->
|
||||||
</a-col>
|
<!-- </div>-->
|
||||||
|
<!-- </a-col>-->
|
||||||
</a-row>
|
</a-row>
|
||||||
</div>
|
</div>
|
||||||
<a-pagination
|
<a-pagination
|
||||||
style="float: right; position: relative; right: 1px; bottom: 25px"
|
style="float: right; position: relative; right: 1px; bottom: 25px; margin-top: 10px"
|
||||||
:total="pagination.total"
|
:total="pagination.total"
|
||||||
show-total
|
show-total
|
||||||
show-jumper
|
show-jumper
|
||||||
@ -129,41 +138,48 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, ref } from 'vue';
|
import { computed, onMounted, ref } from 'vue';
|
||||||
import useLoading from '@/hooks/loading';
|
import useLoading from '@/hooks/loading';
|
||||||
import { useBulletinsStore } from '@/store';
|
|
||||||
import usePagination from '@/hooks/pagination';
|
import usePagination from '@/hooks/pagination';
|
||||||
import { BulletinsList, BulletinsRecord } from '@/api/bulletins';
|
import type { SelectOptionData } from '@arco-design/web-vue/es/select/interface';
|
||||||
|
import { DeviceRecord, queryDeviceList } from '@/api/device';
|
||||||
|
import DeviceEdit from '@/views/iot/deviceCard/components/device-edit.vue';
|
||||||
import CardWrap from './components/card-wrap.vue';
|
import CardWrap from './components/card-wrap.vue';
|
||||||
|
|
||||||
const generateFormModel = () => {
|
const generateFormModel = () => {
|
||||||
return {
|
return {
|
||||||
title: '',
|
name:'',
|
||||||
state: '',
|
status:'',
|
||||||
publishTimeBegin: '',
|
isOnline:'',
|
||||||
publishTimeEnd: '',
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const { loading, setLoading } = useLoading(true);
|
const { loading, setLoading } = useLoading(true);
|
||||||
const renderData = ref<BulletinsList[]>([]);
|
const { pagination,setPagination } = usePagination();
|
||||||
|
const renderData = ref<[]>([]);
|
||||||
const formModel = ref(generateFormModel());
|
const formModel = ref(generateFormModel());
|
||||||
const { pagination, setPagination} = usePagination();
|
|
||||||
|
|
||||||
|
|
||||||
const bulletinsStore = useBulletinsStore();
|
const statusOptions = computed<SelectOptionData[]>(() => [
|
||||||
|
{
|
||||||
|
label: '是',
|
||||||
|
value: 'true',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '否',
|
||||||
|
value: 'false',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 获取设备列表
|
||||||
// 获取公告列表
|
|
||||||
const fetchData = async (
|
const fetchData = async (
|
||||||
params: BulletinsRecord = { size: 8, current: 1 }
|
params = { size: 10, current: 1 }
|
||||||
) => {
|
) => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
const res = await bulletinsStore.getBulletinsList(params);
|
const res: any = await queryDeviceList(params);
|
||||||
renderData.value = res.data.records;
|
renderData.value = res.data.records;
|
||||||
setPagination(res.data);
|
setPagination(res.data);
|
||||||
console.log(pagination.value.total);
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// you can report use errorHandler or other
|
// you can report use errorHandler or other
|
||||||
} finally {
|
} finally {
|
||||||
@ -171,45 +187,56 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// 时间范围
|
|
||||||
const timeRangs = (dateString: string[]) => {
|
|
||||||
// eslint-disable-next-line prefer-destructuring
|
|
||||||
formModel.value.publishTimeBegin = dateString[0];
|
|
||||||
// eslint-disable-next-line prefer-destructuring
|
|
||||||
formModel.value.publishTimeEnd = dateString[1];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// 查询
|
// 查询
|
||||||
const search = () => {
|
const search = () => {
|
||||||
fetchData({
|
fetchData({
|
||||||
...pagination.value,
|
...pagination.value,
|
||||||
...formModel.value,
|
...formModel.value,
|
||||||
} as unknown as BulletinsRecord);
|
} as unknown as DeviceRecord);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 分页发生改变
|
// 分页发生改变
|
||||||
const onPageChange = (current: number) => {
|
const onPageChange = (current: number) => {
|
||||||
|
pagination.value.page = current;
|
||||||
pagination.value.current = current;
|
pagination.value.current = current;
|
||||||
search();
|
search();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 数据条数改变
|
// 数据条数改变
|
||||||
const onSizeChange = (total: number) => {
|
const onSizeChange = (Size: number) => {
|
||||||
pagination.value.total = total;
|
pagination.value.size = Size;
|
||||||
console.log(pagination.value.total);
|
|
||||||
search();
|
search();
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
search();
|
|
||||||
})
|
|
||||||
|
|
||||||
// 重置
|
// 重置
|
||||||
const reset = () => {
|
const reset = () => {
|
||||||
formModel.value = generateFormModel();
|
formModel.value = generateFormModel();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// // 打开详情
|
||||||
|
// function openDetail(id:number): void{
|
||||||
|
// const url = router.resolve({
|
||||||
|
// name: 'deviceDetail',
|
||||||
|
// params: {id}
|
||||||
|
// }).href;
|
||||||
|
// router.push(url);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // 删除
|
||||||
|
// const handleDelete = async (id: number) => {
|
||||||
|
// const res = await deleteDevice(id);
|
||||||
|
// if (res.status === 200) {
|
||||||
|
// Message.success({
|
||||||
|
// content: '删除成功',
|
||||||
|
// duration: 5 * 1000,
|
||||||
|
// });
|
||||||
|
// search();
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
onMounted(() => {
|
||||||
|
search();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
@ -257,4 +284,38 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
</style>
|
||||||
|
<style scoped lang="less">
|
||||||
|
.container {
|
||||||
|
padding: 0 20px 20px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.arco-table-th) {
|
||||||
|
&:last-child {
|
||||||
|
.arco-table-th-item-title {
|
||||||
|
margin-left: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-icon {
|
||||||
|
margin-left: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active {
|
||||||
|
color: #0960bd;
|
||||||
|
background-color: #e3f4fc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 200px;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
margin-left: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
@ -1,208 +0,0 @@
|
|||||||
<template>
|
|
||||||
<a-button v-if="props.isCreate" type="primary">
|
|
||||||
<template #icon><icon-plus /></template>
|
|
||||||
新建
|
|
||||||
</a-button>
|
|
||||||
<a-button
|
|
||||||
v-if="!props.isCreate"
|
|
||||||
type="outline"
|
|
||||||
size="small"
|
|
||||||
:style="{ marginRight: '10px', padding: '7px' }"
|
|
||||||
>
|
|
||||||
<template #icon><icon-edit /></template>
|
|
||||||
修改
|
|
||||||
</a-button>
|
|
||||||
|
|
||||||
<a-modal
|
|
||||||
width="700px"
|
|
||||||
:visible="visible"
|
|
||||||
@ok="handleSubmit"
|
|
||||||
@cancel="handleCancel"
|
|
||||||
>
|
|
||||||
<template #title>{{ modalTitle }}</template>
|
|
||||||
<a-form ref="CreateRef" :model="formData" :style="{ width: '650px' }">
|
|
||||||
<a-form-item
|
|
||||||
field="title"
|
|
||||||
:label="$t('标题')"
|
|
||||||
:validate-trigger="['change', 'input']"
|
|
||||||
:rules="[
|
|
||||||
{ required: true, message: '' },
|
|
||||||
{
|
|
||||||
match: /^[a-zA-Z0-9\u4e00-\u9fa5]{1,20}$/,
|
|
||||||
message: '',
|
|
||||||
},
|
|
||||||
]"
|
|
||||||
>
|
|
||||||
<a-input v-model="formData.title" :placeholder="$t('请输入公告标题')" />
|
|
||||||
<!-- v-if="props.isCreate"-->
|
|
||||||
<!-- <div v-else>{{ formData.title }}</div>-->
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item
|
|
||||||
field="email"
|
|
||||||
:label="$t('作者')"
|
|
||||||
:rules="[
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
type: 'email',
|
|
||||||
message: t('user.info.email.required'),
|
|
||||||
},
|
|
||||||
]"
|
|
||||||
:validate-trigger="['change', 'input']"
|
|
||||||
>
|
|
||||||
<a-input v-model="formData.email" :placeholder="$t('请输入作者')" />
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item
|
|
||||||
field="phone"
|
|
||||||
:label="$t('发布范围')"
|
|
||||||
:rules="[
|
|
||||||
{ required: true, message: t('user.info.phone.required') },
|
|
||||||
{ match: /^1[3-9]\d{9}$/, message: t('user.info.phone.format') },
|
|
||||||
]"
|
|
||||||
:validate-trigger="['change', 'input']"
|
|
||||||
>
|
|
||||||
<a-input v-model="formData.phone" :placeholder="$t('请选择范围')" />
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item
|
|
||||||
field="password"
|
|
||||||
:label="$t('发布时间')"
|
|
||||||
:validate-trigger="['change', 'input']"
|
|
||||||
:rules="[{ required: true, message: t('user.info.password.required') }]"
|
|
||||||
>
|
|
||||||
<!-- v-if="isCreate"-->
|
|
||||||
<a-input
|
|
||||||
v-model="formData.password"
|
|
||||||
:placeholder="$t('请选择发布时间')"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item field="nickName" :label="$t('公告内容')">
|
|
||||||
<a-textarea
|
|
||||||
default-value="请输入内容"
|
|
||||||
:auto-size="{
|
|
||||||
minRows: 2,
|
|
||||||
maxRows: 5,
|
|
||||||
}"
|
|
||||||
style="margin-top: 20px"
|
|
||||||
v-model="formData.content"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-form>
|
|
||||||
</a-modal>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { useI18n } from 'vue-i18n';
|
|
||||||
import useVisible from '@/hooks/visible';
|
|
||||||
import { computed, PropType, ref } from 'vue';
|
|
||||||
import { CreateRecord } from '@/api/user';
|
|
||||||
import { FormInstance } from '@arco-design/web-vue/es/form';
|
|
||||||
import { deptList } from '@/api/dept';
|
|
||||||
import { Message } from '@arco-design/web-vue';
|
|
||||||
import { useUserStore } from '@/store';
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
prem: {
|
|
||||||
type: Object as PropType<CreateRecord>,
|
|
||||||
},
|
|
||||||
isCreate: Boolean,
|
|
||||||
});
|
|
||||||
const { t } = useI18n();
|
|
||||||
const modalTitle = computed(() => {
|
|
||||||
return props.isCreate ? t('新增公告') : t('编辑公告');
|
|
||||||
});
|
|
||||||
const { visible, setVisible } = useVisible(false);
|
|
||||||
const checkKeys = ref<number[]>([]);
|
|
||||||
|
|
||||||
const CreateRef = ref<FormInstance>();
|
|
||||||
|
|
||||||
const formData = ref<any>({});
|
|
||||||
|
|
||||||
let formDifer = {};
|
|
||||||
const userStore = useUserStore();
|
|
||||||
|
|
||||||
// 部门数据
|
|
||||||
const deptOptions = ref();
|
|
||||||
const getDeptData = async () => {
|
|
||||||
const res = await deptList();
|
|
||||||
deptOptions.value = res.data.records;
|
|
||||||
};
|
|
||||||
// 角色数据
|
|
||||||
// const roleOptions = ref();
|
|
||||||
// const getRoleData = async () => {
|
|
||||||
// const res = await queryRoleList('');
|
|
||||||
// roleOptions.value = res.data.records.filter((item: any) => {
|
|
||||||
// return item.enabled !== false;
|
|
||||||
// });
|
|
||||||
// };
|
|
||||||
|
|
||||||
// 组件被点击
|
|
||||||
// const handleClick = () => {
|
|
||||||
// getDeptData();
|
|
||||||
// // getRoleData();
|
|
||||||
// const userId = props.prem?.id;
|
|
||||||
// // 编辑
|
|
||||||
// if (!props.isCreate && userId) {
|
|
||||||
// formData.value = props.prem;
|
|
||||||
// formDifer = { ...props.prem };
|
|
||||||
// }
|
|
||||||
// setVisible(true);
|
|
||||||
// };
|
|
||||||
|
|
||||||
// 做出只修改的部分
|
|
||||||
const diffDataForm = (newData: any, oldData: any) => {
|
|
||||||
const result = {}; // 报错修改的字段内容
|
|
||||||
Object.keys(oldData).forEach((key) => {
|
|
||||||
if (oldData[key] !== newData[key]) {
|
|
||||||
result[key] = newData[key];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 提交
|
|
||||||
const handleSubmit = async () => {
|
|
||||||
const valid = await CreateRef.value?.validate();
|
|
||||||
if (!valid) {
|
|
||||||
formData.value.permissionIds = checkKeys.value;
|
|
||||||
// 新增
|
|
||||||
if (props.isCreate) {
|
|
||||||
// formData.value.username = formData.value.email;
|
|
||||||
const res = await userStore.createUser(formData.value);
|
|
||||||
if (res.status === 200) {
|
|
||||||
Message.success({
|
|
||||||
content: t('create.sucess'),
|
|
||||||
duration: 5 * 1000,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
CreateRef.value?.resetFields();
|
|
||||||
} else {
|
|
||||||
// 编辑
|
|
||||||
formDifer = diffDataForm(formData.value, formDifer);
|
|
||||||
if (Object.keys(formDifer).length === 0) {
|
|
||||||
Message.success({
|
|
||||||
content: t('unmodified'),
|
|
||||||
duration: 3 * 1000,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
formDifer.id = formData.value.id;
|
|
||||||
const res = await userStore.updateUser(formDifer);
|
|
||||||
if (res.status === 200) {
|
|
||||||
Message.success({
|
|
||||||
content: t('modify.sucess'),
|
|
||||||
duration: 5 * 1000,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
checkKeys.value = [];
|
|
||||||
setVisible(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 关闭
|
|
||||||
const handleCancel = async () => {
|
|
||||||
checkKeys.value = [];
|
|
||||||
setVisible(false);
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
@ -1,445 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="container">
|
|
||||||
<Breadcrumb :items="['系统管理', '公告设置']" />
|
|
||||||
<a-card class="general-card" title=" ">
|
|
||||||
<a-row>
|
|
||||||
<a-col :flex="1">
|
|
||||||
<a-form
|
|
||||||
:model="formModel"
|
|
||||||
:label-col-props="{ span: 6 }"
|
|
||||||
:wrapper-col-props="{ span: 18 }"
|
|
||||||
label-align="right"
|
|
||||||
>
|
|
||||||
<a-row :gutter="18">
|
|
||||||
<a-col :span="9">
|
|
||||||
<a-form-item field="title" :label="$t('标题')">
|
|
||||||
<a-input
|
|
||||||
v-model="formModel.title"
|
|
||||||
style="width: 360px"
|
|
||||||
:placeholder="$t('请输入标题')"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="9">
|
|
||||||
<a-form-item field="enable" :label="$t('状态')">
|
|
||||||
<a-select
|
|
||||||
v-model="formModel.states"
|
|
||||||
style="width: 360px"
|
|
||||||
:placeholder="$t('请选择状态')"
|
|
||||||
:options="statusOptions"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
|
|
||||||
<a-col :span="9">
|
|
||||||
<a-form-item field="publishTimeBegin" :label="$t('开始时间')">
|
|
||||||
<a-date-picker
|
|
||||||
v-model="formModel.publishTimeBegin"
|
|
||||||
style="width: 360px"
|
|
||||||
show-time
|
|
||||||
:time-picker-props="{ defaultValue: '09:09:06' }"
|
|
||||||
format="YYYY-MM-DD HH:mm"
|
|
||||||
:allow-clear="false"
|
|
||||||
@select="onSelect"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="9">
|
|
||||||
<a-form-item field="publishTimeEnd" :label="$t('结束时间')">
|
|
||||||
<a-date-picker
|
|
||||||
v-model="formModel.publishTimeEnd"
|
|
||||||
style="width: 360px"
|
|
||||||
show-time
|
|
||||||
:time-picker-props="{ defaultValue: '09:09:06' }"
|
|
||||||
format="YYYY-MM-DD HH:mm"
|
|
||||||
:allow-clear="false"
|
|
||||||
@select="onSelect"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
|
||||||
</a-form>
|
|
||||||
</a-col>
|
|
||||||
<a-divider style="height: 84px" direction="vertical" />
|
|
||||||
<a-col :flex="'86px'" style="text-align: right">
|
|
||||||
<a-space direction="vertical" :size="18">
|
|
||||||
<a-button type="primary" @click="search">
|
|
||||||
<template #icon>
|
|
||||||
<icon-search />
|
|
||||||
</template>
|
|
||||||
查询
|
|
||||||
</a-button>
|
|
||||||
<a-button @click="reset">
|
|
||||||
<template #icon>
|
|
||||||
<icon-refresh />
|
|
||||||
</template>
|
|
||||||
重置
|
|
||||||
</a-button>
|
|
||||||
</a-space>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
|
||||||
|
|
||||||
<a-divider style="margin-top: 0" />
|
|
||||||
<a-row>
|
|
||||||
<a-col :span="12">
|
|
||||||
<a-space>
|
|
||||||
<NoticeEdit
|
|
||||||
ref="createUserRef"
|
|
||||||
:is-create="true"
|
|
||||||
@refresh="search"
|
|
||||||
/>
|
|
||||||
</a-space>
|
|
||||||
<a-button style="margin-left: 20px" @click="generateExcel">
|
|
||||||
<template #icon>
|
|
||||||
<icon-download size="18" />
|
|
||||||
</template>
|
|
||||||
导出
|
|
||||||
</a-button>
|
|
||||||
</a-col>
|
|
||||||
<a-col
|
|
||||||
:span="12"
|
|
||||||
style="
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: end;
|
|
||||||
padding-bottom: 20px;
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<a-tooltip :content="$t('刷新')">
|
|
||||||
<div class="action-icon" @click="search">
|
|
||||||
<icon-refresh size="18" />
|
|
||||||
</div>
|
|
||||||
</a-tooltip>
|
|
||||||
|
|
||||||
<a-dropdown @select="handleSelectDensity">
|
|
||||||
<a-tooltip :content="$t('密度')">
|
|
||||||
<div class="action-icon"><icon-line-height size="18" /></div>
|
|
||||||
</a-tooltip>
|
|
||||||
<template #content>
|
|
||||||
<a-doption
|
|
||||||
v-for="item in densityList"
|
|
||||||
:key="item.value"
|
|
||||||
:value="item.value"
|
|
||||||
:class="{ active: item.value === sizeof }"
|
|
||||||
>
|
|
||||||
<span>{{ item.name }}</span>
|
|
||||||
</a-doption>
|
|
||||||
</template>
|
|
||||||
</a-dropdown>
|
|
||||||
|
|
||||||
<a-tooltip :content="$t('列设置')">
|
|
||||||
<a-popover
|
|
||||||
trigger="click"
|
|
||||||
position="bl"
|
|
||||||
@popup-visible-change="popupVisibleChange"
|
|
||||||
>
|
|
||||||
<div class="action-icon"><icon-settings size="18" /></div>
|
|
||||||
<template #content>
|
|
||||||
<div id="tableSetting">
|
|
||||||
<div
|
|
||||||
v-for="(item, index) in showColumns"
|
|
||||||
:key="item.dataIndex"
|
|
||||||
class="setting"
|
|
||||||
>
|
|
||||||
<div style="margin-right: 4px; cursor: move">
|
|
||||||
<icon-drag-arrow />
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<a-checkbox
|
|
||||||
v-model="item.checked"
|
|
||||||
@change="
|
|
||||||
handleChange($event, item as TableColumnData, index)
|
|
||||||
"
|
|
||||||
>
|
|
||||||
</a-checkbox>
|
|
||||||
</div>
|
|
||||||
<div class="title">
|
|
||||||
{{ item.title === '#' ? '序列号' : item.title }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</a-popover>
|
|
||||||
</a-tooltip>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
|
||||||
|
|
||||||
<a-table
|
|
||||||
row-key="id"
|
|
||||||
:loading="loading"
|
|
||||||
:pagination="false"
|
|
||||||
:columns="(cloneColumns as TableColumnData[])"
|
|
||||||
:data="renderData"
|
|
||||||
:bordered="false"
|
|
||||||
:size="size"
|
|
||||||
style="margin-bottom: 40px"
|
|
||||||
:filter-icon-align-left="alignLeft"
|
|
||||||
@change="handleSortChange"
|
|
||||||
@page-change="onPageChange"
|
|
||||||
>
|
|
||||||
<template #index="{ rowIndex }">
|
|
||||||
{{ rowIndex + 1 + (pagination.current - 1) * pagination.size }}
|
|
||||||
</template>
|
|
||||||
<template #enabled="{ record }">
|
|
||||||
<a-switch
|
|
||||||
:model-value="record.enabled"
|
|
||||||
:checked-value="true"
|
|
||||||
:unchecked-value="false"
|
|
||||||
@change="enabledStatus(record)"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
<template #operations="{ record }">
|
|
||||||
<a-button
|
|
||||||
type="outline"
|
|
||||||
size="small"
|
|
||||||
status="success"
|
|
||||||
style="padding: 7px; margin-right: 10px"
|
|
||||||
>
|
|
||||||
<template #icon><icon-list /></template>
|
|
||||||
详情
|
|
||||||
</a-button>
|
|
||||||
|
|
||||||
<NoticeEdit
|
|
||||||
ref="editUserRef"
|
|
||||||
:prem="record"
|
|
||||||
:is-create="false"
|
|
||||||
@refresh="fetchData"
|
|
||||||
/>
|
|
||||||
<a-button
|
|
||||||
type="outline"
|
|
||||||
size="small"
|
|
||||||
status="danger"
|
|
||||||
style="padding: 7px"
|
|
||||||
>
|
|
||||||
<template #icon><icon-delete /></template>
|
|
||||||
删除
|
|
||||||
</a-button>
|
|
||||||
</template>
|
|
||||||
</a-table>
|
|
||||||
<a-pagination
|
|
||||||
style="float: right; position: relative; right: 1px; bottom: 25px"
|
|
||||||
:total="pagination.total"
|
|
||||||
:size="size"
|
|
||||||
show-total
|
|
||||||
show-jumper
|
|
||||||
show-page-size
|
|
||||||
@page-size-change="onSizeChange"
|
|
||||||
@change="onPageChange"
|
|
||||||
/>
|
|
||||||
</a-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { computed, ref, watch } from 'vue';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
|
||||||
import useLoading from '@/hooks/loading';
|
|
||||||
import { UserRecord, UserParams } from '@/api/user';
|
|
||||||
import { Pagination } from '@/types/global';
|
|
||||||
import type { SelectOptionData } from '@arco-design/web-vue/es/select/interface';
|
|
||||||
import type { TableColumnData } from '@arco-design/web-vue/es/table/interface';
|
|
||||||
import { useUserStore } from '@/store';
|
|
||||||
import { Message } from '@arco-design/web-vue';
|
|
||||||
import useTableOption from '@/hooks/table-option';
|
|
||||||
import NoticeEdit from './components/notice-edit.vue';
|
|
||||||
|
|
||||||
const generateFormModel = () => {
|
|
||||||
return {
|
|
||||||
title: '',
|
|
||||||
states: '',
|
|
||||||
publishTimeBegin: '',
|
|
||||||
publishTimeEnd: '',
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const { loading, setLoading } = useLoading(true);
|
|
||||||
const { t } = useI18n();
|
|
||||||
const renderData = ref<UserRecord[]>([]);
|
|
||||||
const formModel = ref(generateFormModel());
|
|
||||||
|
|
||||||
const {
|
|
||||||
cloneColumns,
|
|
||||||
showColumns,
|
|
||||||
densityList,
|
|
||||||
handleSelectDensity,
|
|
||||||
handleChange,
|
|
||||||
popupVisibleChange,
|
|
||||||
deepClone,
|
|
||||||
} = useTableOption();
|
|
||||||
const sizeof = useTableOption().size;
|
|
||||||
|
|
||||||
const userStore = useUserStore();
|
|
||||||
|
|
||||||
const pagination: Pagination = {
|
|
||||||
page: 1,
|
|
||||||
size: 10,
|
|
||||||
current: 1,
|
|
||||||
total: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
const columns = computed<TableColumnData[]>(() => [
|
|
||||||
{
|
|
||||||
title: '序号',
|
|
||||||
dataIndex: 'index',
|
|
||||||
slotName: 'index',
|
|
||||||
width: 60,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '标题',
|
|
||||||
dataIndex: 'title',
|
|
||||||
sortable: {
|
|
||||||
sortDirections: ['ascend', 'descend'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t('时间'),
|
|
||||||
dataIndex: 'publishTimeBegin',
|
|
||||||
sortable: {
|
|
||||||
sortDirections: ['ascend', 'descend'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t('状态'),
|
|
||||||
dataIndex: 'states',
|
|
||||||
sortable: {
|
|
||||||
sortDirections: ['ascend', 'descend'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '操作',
|
|
||||||
dataIndex: 'operations',
|
|
||||||
slotName: 'operations',
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
const statusOptions = computed<SelectOptionData[]>(() => [
|
|
||||||
{
|
|
||||||
label: t('已发布'),
|
|
||||||
value: 'true',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: t('未发布'),
|
|
||||||
value: 'false',
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
// 获取公告列表
|
|
||||||
const fetchData = async (
|
|
||||||
params: UserParams = { page: 1, size: 10, current: 1 }
|
|
||||||
) => {
|
|
||||||
setLoading(true);
|
|
||||||
try {
|
|
||||||
const res = await userStore.getUserList(params);
|
|
||||||
renderData.value = res.data.records;
|
|
||||||
pagination.page = res.data.page;
|
|
||||||
pagination.current = res.data.current;
|
|
||||||
pagination.total = res.data.total;
|
|
||||||
pagination.size = res.data.size;
|
|
||||||
} catch (err) {
|
|
||||||
// you can report use errorHandler or other
|
|
||||||
} finally {
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 查询
|
|
||||||
const search = () => {
|
|
||||||
fetchData({
|
|
||||||
...pagination,
|
|
||||||
...formModel.value,
|
|
||||||
} as unknown as UserParams);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 分页发生改变
|
|
||||||
const onPageChange = (current: number) => {
|
|
||||||
pagination.page = current;
|
|
||||||
pagination.current = current;
|
|
||||||
search();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 数据条数改变
|
|
||||||
const onSizeChange = (size: number) => {
|
|
||||||
pagination.size = size;
|
|
||||||
search();
|
|
||||||
};
|
|
||||||
|
|
||||||
search();
|
|
||||||
|
|
||||||
// 重置
|
|
||||||
const reset = () => {
|
|
||||||
formModel.value = generateFormModel();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 表格内部排序
|
|
||||||
const alignLeft = ref(false);
|
|
||||||
const handleSortChange = (
|
|
||||||
data: any,
|
|
||||||
extra: any,
|
|
||||||
currentDataSource: any
|
|
||||||
) => {};
|
|
||||||
|
|
||||||
// 是否启用
|
|
||||||
const enabledStatus = async (record: string) => {
|
|
||||||
record.enabled = !record.enabled;
|
|
||||||
const res = await userStore.enabledUser(record.id);
|
|
||||||
if (res.status === 200) {
|
|
||||||
Message.success({
|
|
||||||
content: t('modify.status.sucess'),
|
|
||||||
duration: 3 * 1000,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
Message.error({
|
|
||||||
content: t('modify.status.fail'),
|
|
||||||
duration: 3 * 1000,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 删除
|
|
||||||
// const handleDelete = async (record: UserRecord) => {
|
|
||||||
// const res = await userStore.removeUser(record.id);
|
|
||||||
// if (res.status === 200) {
|
|
||||||
// Message.success({
|
|
||||||
// content: '删除成功',
|
|
||||||
// duration: 5 * 1000,
|
|
||||||
// });
|
|
||||||
// search();
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
watch(() => columns.value, deepClone, { deep: true, immediate: true });
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="less">
|
|
||||||
.container {
|
|
||||||
padding: 0 20px 20px 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.arco-table-th) {
|
|
||||||
&:last-child {
|
|
||||||
.arco-table-th-item-title {
|
|
||||||
margin-left: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.action-icon {
|
|
||||||
margin-left: 12px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.active {
|
|
||||||
color: #0960bd;
|
|
||||||
background-color: #e3f4fc;
|
|
||||||
}
|
|
||||||
|
|
||||||
.setting {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
width: 200px;
|
|
||||||
|
|
||||||
.title {
|
|
||||||
margin-left: 12px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,148 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="container">
|
|
||||||
<Breadcrumb :items="['个人中心', '公告通知','公告详情']" />
|
|
||||||
<a-card class="general-card" title=" ">
|
|
||||||
<div class="announcement-detail">
|
|
||||||
<div class="header">
|
|
||||||
<h1>{{ renderData.title }}</h1>
|
|
||||||
<div class="meta">
|
|
||||||
<span>作者: {{ renderData.createBy }}</span>
|
|
||||||
<span
|
|
||||||
>时间: {{ dayjs(renderData.publishTime).format('YYYY-MM-DD') }}</span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<a-divider style="margin-top: 0" />
|
|
||||||
<div v-html="renderData.content" class="content"></div>
|
|
||||||
<div>
|
|
||||||
<ul class="attachments">
|
|
||||||
<li v-for="(item, index) in renderData.attachments" :key="index">
|
|
||||||
<a
|
|
||||||
:href="item.url"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
<icon-download />
|
|
||||||
{{ item.fileName }}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import dayjs from 'dayjs';
|
|
||||||
import { useBulletinStore } from '@/store';
|
|
||||||
import { useRoute } from 'vue-router';
|
|
||||||
import { onMounted, ref } from 'vue';
|
|
||||||
|
|
||||||
const bulletinStore = useBulletinStore();
|
|
||||||
const route = useRoute();
|
|
||||||
const id = Number(route.params.id);
|
|
||||||
const renderData = ref<any>([]);
|
|
||||||
// const attachmentList = ref<any>([]);
|
|
||||||
const fetchData = async (Id: number) => {
|
|
||||||
const res = await bulletinStore.queryBulletinDetail(Id);
|
|
||||||
// attachmentList.value = await bulletinStore.queryAttachmentInfo(
|
|
||||||
// '28452d83420650425d45110c6417bf693b966b29'
|
|
||||||
// );
|
|
||||||
// eslint-disable-next-line prefer-destructuring
|
|
||||||
renderData.value = res.data;
|
|
||||||
};
|
|
||||||
onMounted(() => {
|
|
||||||
fetchData(id);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.container {
|
|
||||||
padding: 0 20px 20px 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.announcement-detail {
|
|
||||||
min-width: 800px;
|
|
||||||
max-width: 800px;
|
|
||||||
margin: auto;
|
|
||||||
padding: 20px;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
background-color: #fff; /* 白色背景,与淡蓝色背景区分开来 */
|
|
||||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
h1 {
|
|
||||||
font-size: 24px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.meta {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
color: #777;
|
|
||||||
}
|
|
||||||
|
|
||||||
.meta span {
|
|
||||||
margin-right: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
line-height: 1.6;
|
|
||||||
}
|
|
||||||
.attachments li {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attachments a {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
font-size: 14px;
|
|
||||||
color: #1890ff;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attachments a:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attachments .arco-icon {
|
|
||||||
margin-right: 8px;
|
|
||||||
color: #1890ff;
|
|
||||||
}
|
|
||||||
.layout-demo :deep(.arco-layout-header),
|
|
||||||
.layout-demo :deep(.arco-layout-footer),
|
|
||||||
.layout-demo :deep(.arco-layout-sider-children),
|
|
||||||
.layout-demo :deep(.arco-layout-content) {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
color: var(--color-white);
|
|
||||||
font-size: 16px;
|
|
||||||
font-stretch: condensed;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.layout-demo :deep(.arco-layout-header),
|
|
||||||
.layout-demo :deep(.arco-layout-footer) {
|
|
||||||
height: 64px;
|
|
||||||
background-color: var(--color-primary-light-4);
|
|
||||||
}
|
|
||||||
|
|
||||||
.layout-demo :deep(.arco-layout-sider) {
|
|
||||||
width: 206px;
|
|
||||||
background-color: var(--color-primary-light-3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.layout-demo :deep(.arco-layout-content) {
|
|
||||||
background-color: rgb(var(--arcoblue-6));
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user