Commit f4377883 authored by 陈浩玮's avatar 陈浩玮

设备管理

parent 1b45a3e4
...@@ -14,7 +14,7 @@ function delOceanusTreeApi(data) { ...@@ -14,7 +14,7 @@ function delOceanusTreeApi(data) {
} }
function getAttributesApi(data) { function getAttributesApi(data) {
return getReq('/oceanus/api/v1/categories/attributes', data); return getReq('/oceanus/api/v1/categories/attributes', data);
} }
function addAttributesApi(data) { function addAttributesApi(data) {
...@@ -45,31 +45,38 @@ function getEquipmentsInfoApi(data) { ...@@ -45,31 +45,38 @@ function getEquipmentsInfoApi(data) {
return getReq(`/oceanus/api/v1/equipments/${data.catalogValue}`); return getReq(`/oceanus/api/v1/equipments/${data.catalogValue}`);
} }
function getEquipmentsAttributesApi(data) { function getEquipmentsAttributesApi(data) {
return getReq('/oceanus/api/v1/equipments/attributes', data); return getReq('/oceanus/api/v1/equipments/attributes', data);
} }
function addEquipmentsAttributesApi(data) { function addEquipmentsAttributesApi(data) {
return postReq('/oceanus/api/v1/equipments/attributes', data); return postReq('/oceanus/api/v1/equipments/attributes', data);
} }
function updateEquipmentsAttributesApi(data) { function updateEquipmentsAttributesApi(data) {
return putReq('/oceanus/api/v1/equipments/attributes', data); return putReq('/oceanus/api/v1/equipments/attributes', data);
} }
function topEquipmentsAttributesApi(data) { function topEquipmentsAttributesApi(data) {
return putReq(`/oceanus/api/v1/equipments/attributes/top/${data.instanceId}`,{}); return putReq(`/oceanus/api/v1/equipments/attributes/top/${data.instanceId}`, {});
} }
function bottomEquipmentsAttributesApi(data) { function bottomEquipmentsAttributesApi(data) {
return putReq(`/oceanus/api/v1/equipments/attributes/bottom/${data.instanceId}`,{}); return putReq(`/oceanus/api/v1/equipments/attributes/bottom/${data.instanceId}`, {});
}
function getEquipmentsEventsApi(data) {
return getReq('/oceanus/api/v1/equipments/events', data);
}
function addEquipmentsEventsApi(data) {
return postReq('/oceanus/api/v1/equipments/events', data);
}
function updateEquipmentsEventsApi(data) {
return putReq('/oceanus/api/v1/equipments/events', data);
} }
export default { export default {
getOceanusTree: getOceanusTreeApi, getOceanusTree: getOceanusTreeApi,
addOceanusTree: addOceanusTreeApi, addOceanusTree: addOceanusTreeApi,
updateOceanusTree: updateOceanusTreeApi, updateOceanusTree: updateOceanusTreeApi,
delOceanusTree: delOceanusTreeApi, delOceanusTree: delOceanusTreeApi,
getAttributes:getAttributesApi, getAttributes: getAttributesApi,
addAttributes: addAttributesApi, addAttributes: addAttributesApi,
updateAttributes: updateAttributesApi, updateAttributes: updateAttributesApi,
movementAttributes: movementAttributesApi, movementAttributes: movementAttributesApi,
...@@ -78,9 +85,12 @@ export default { ...@@ -78,9 +85,12 @@ export default {
updateEquipmentsTree: updateEquipmentsTreeApi, updateEquipmentsTree: updateEquipmentsTreeApi,
delEquipmentsTree: delEquipmentsTreeApi, delEquipmentsTree: delEquipmentsTreeApi,
getEquipmentsInfo: getEquipmentsInfoApi, getEquipmentsInfo: getEquipmentsInfoApi,
getEquipmentsAttributes:getEquipmentsAttributesApi, getEquipmentsAttributes: getEquipmentsAttributesApi,
addEquipmentsAttributes:addEquipmentsAttributesApi, addEquipmentsAttributes: addEquipmentsAttributesApi,
updateEquipmentsAttributes:updateEquipmentsAttributesApi, updateEquipmentsAttributes: updateEquipmentsAttributesApi,
topEquipmentsAttributes:topEquipmentsAttributesApi, topEquipmentsAttributes: topEquipmentsAttributesApi,
bottomEquipmentsAttributes:bottomEquipmentsAttributesApi, bottomEquipmentsAttributes: bottomEquipmentsAttributesApi,
getEquipmentsEvents: getEquipmentsEventsApi,
addEquipmentsEvents: addEquipmentsEventsApi,
updateEquipmentsEvents: updateEquipmentsEventsApi,
}; };
...@@ -24,6 +24,7 @@ export default { ...@@ -24,6 +24,7 @@ export default {
request: Function, request: Function,
formatData: { type: Object, default: undefined }, formatData: { type: Object, default: undefined },
getName: Function, getName: Function,
param: { type: Object, default: () => ({}) },
labelFiled: String, // 和 formatData 一样 传一种就行了 labelFiled: String, // 和 formatData 一样 传一种就行了
valueFiled: String, valueFiled: String,
}, },
...@@ -34,7 +35,7 @@ export default { ...@@ -34,7 +35,7 @@ export default {
}, },
async mounted() { async mounted() {
if (this.request) { if (this.request) {
const newArr = await this.request(); const newArr = await this.request(this.param);
this.data = this.formatData ? await formatObj(newArr, this.formatData) : newArr; this.data = this.formatData ? await formatObj(newArr, this.formatData) : newArr;
this.data = this.labelFiled this.data = this.labelFiled
? formatObj(newArr, { label: this.labelFiled, value: this.valueFiled, key: this.valueFiled }) ? formatObj(newArr, { label: this.labelFiled, value: this.valueFiled, key: this.valueFiled })
......
...@@ -167,6 +167,7 @@ export default { ...@@ -167,6 +167,7 @@ export default {
...data, ...data,
catalogId: curData.catalogId, catalogId: curData.catalogId,
catalogType: curData.catalogType, catalogType: curData.catalogType,
catalogName: curData.catalogName,
}; };
this.treeData = [...this.treeData]; this.treeData = [...this.treeData];
} }
...@@ -220,13 +221,13 @@ export default { ...@@ -220,13 +221,13 @@ export default {
if (type === 1) { if (type === 1) {
const { equipmentForm, catalogForm } = data; const { equipmentForm, catalogForm } = data;
const { equipmentName } = equipmentForm; const { equipmentName } = equipmentForm;
const { catalogId, catalogType } = catalogForm; const { catalogId, catalogType, catalogName } = catalogForm;
console.log(this.treeNode);
this.treeNode.dataRef.catalogName = equipmentName; this.treeNode.dataRef.catalogName = equipmentName;
const newData = { const newData = {
...equipmentForm, ...equipmentForm,
catalogId, catalogId,
catalogType, catalogType,
catalogName,
}; };
this.treeData = [...this.treeData]; this.treeData = [...this.treeData];
this.$emit('change', newData); this.$emit('change', newData);
......
...@@ -126,11 +126,12 @@ export default { ...@@ -126,11 +126,12 @@ export default {
return Api.updateEquipmentsTree(data); return Api.updateEquipmentsTree(data);
}, },
colesAfter() { colesAfter() {
const { catalogId, catalogType, installTime, runTime, ...rest } = this.form; const { catalogId, catalogType, installTime, runTime, catalogName, ...rest } = this.form;
const data = { const data = {
catalogForm: { catalogForm: {
catalogId, catalogId,
catalogType, catalogType,
catalogName,
}, },
equipmentForm: { equipmentForm: {
installTime: installTime && installTime.format('YYYY-MM-DD hh:mm:ss'), installTime: installTime && installTime.format('YYYY-MM-DD hh:mm:ss'),
......
<template>
<Drawer ref="drawerRef" v-model="visible" :title="title" :onOk="submit" :colesAfter="colesAfter">
<a-form-model layout="vertical" :model="form" :rules="rules" ref="DrawerForm">
<a-form-model-item label="设备编码" prop="equipmentId">
<a-select v-model="form.equipmentId" :disabled="true" :options="options" />
</a-form-model-item>
<a-form-model-item label="事件类型" prop="eventType">
<MySelect
v-model="form.eventType"
:request="getStaticDataApi"
:param="{ paramModule: 'oceanus_equipment_event', paramCode: 'event_type' }"
:disabled="isView"
/>
</a-form-model-item>
<a-form-model-item label="发生日期" prop="occurTime">
<a-date-picker
v-model="form.occurTime"
style="width: 100%"
placeholder="Select date"
:disabled="isView"
/>
</a-form-model-item>
<a-form-model-item label="设备编码" prop="eventDescription">
<a-textarea
:rows="4"
v-model="form.eventDescription"
style="width: 100%"
placeholder="Select date"
:disabled="isView"
/>
</a-form-model-item>
</a-form-model>
</Drawer>
</template>
<script>
import { getStaticDataApi } from '@/api';
import Drawer from '@/components/table/drawer.vue';
import FormMixin from '@/components/FormMixin';
import Api from '@/api/oceanus';
import MySelect from '@/components/MySelect/RequestSelect.vue';
export default {
components: { Drawer, MySelect },
props: {
dataInfo: {
type: Object,
default: () => ({}),
},
refresh: Function,
},
mixins: [FormMixin],
watch: {
dataInfo: {
handler(val) {
console.log(val);
const { catalogName, equipmentId } = val;
this.options = [{ value: equipmentId, label: catalogName, key: equipmentId }];
},
deep: true,
immediate: true,
},
},
data() {
return {
visible: false,
form: {},
rules: {
equipmentId: [{ required: true, message: 'Please select Activity zone', trigger: 'change' }],
eventType: [{ required: true, message: 'Please select Activity zone', trigger: 'change' }],
occurTime: [{ required: true, message: 'Please select Activity zone', trigger: 'change' }],
eventDescription: [
{ required: true, message: 'Please select Activity zone', trigger: 'change' },
],
},
options: [],
getStaticDataApi,
Api,
};
},
async mounted() {},
methods: {
open() {
this.form = {};
this.visible = true;
},
add() {
const data = {
...this.form,
occurTime: this.form.occurTime && this.form.occurTime.format('YYYY-MM-DD hh:mm:ss'),
};
return Api.addEquipmentsEvents(data);
},
edit() {
const data = {
...this.form,
occurTime: this.form.occurTime && this.form.occurTime.format('YYYY-MM-DD hh:mm:ss'),
};
return Api.updateEquipmentsEvents(data);
},
colesAfter() {
this.refresh();
},
},
};
</script>
...@@ -7,16 +7,19 @@ ...@@ -7,16 +7,19 @@
<a-tab-pane key="2" tab="属性" :forceRender="true"> <a-tab-pane key="2" tab="属性" :forceRender="true">
<TabTwo v-if="key === '2'" :dataInfo="dataInfo" /> <TabTwo v-if="key === '2'" :dataInfo="dataInfo" />
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="3" tab="事件" :forceRender="true"> Content of Tab Pane 3 </a-tab-pane> <a-tab-pane key="3" tab="事件" :forceRender="true">
<TabThree v-if="key === '3'" :dataInfo="dataInfo" />
</a-tab-pane>
</a-tabs> </a-tabs>
</my-card> </my-card>
</template> </template>
<script> <script>
import TabOne from './TabOne.vue'; import TabOne from './TabOne.vue';
import TabTwo from './TabTwo.vue'; import TabTwo from './TabTwo.vue';
import TabThree from './TabThree.vue';
export default { export default {
components: { TabOne, TabTwo }, components: { TabOne, TabTwo, TabThree },
props: { props: {
info: { info: {
type: Object, type: Object,
......
<template>
<my-table
:style="{ marginTop: 0 }"
url="/oceanus/api/v1/categories/attributes"
:tableParam="{ categoryId: tableParam.categoryId }"
rowKey="key"
ref="table"
:formatData="formatData"
>
<template v-if="tableParam.categoryId !== 1" #search="{ query }">
<my-form-item label="账号" :colAttr="{ span: 12 }">
<a-input placeholder="Basic usage" v-model="query.attributeName" />
</my-form-item>
</template>
<template v-if="tableParam.categoryId !== 1" #buttons>
<a-button type="primary" @click="onAddTableRow">新增</a-button>
</template>
<a-table-column title="属性名称">
<template #default="row">
<a-input v-if="row.editable" v-model="row.attributeName" />
<span v-else>
{{ row.attributeName }}
</span>
</template>
</a-table-column>
<a-table-column title="操作" :width="180">
<template #default="row">
<ActionButton v-if="row.editable" :buttons="editButtons" :row="row" />
<ActionButton v-else :buttons="buttons" :row="row" />
</template>
</a-table-column>
</my-table>
</template>
<script>
import Api from '@/api/oceanus';
import { formatObj } from '@/utils';
import ActionButton from '@/components/action_button/index.vue';
export default {
components: { ActionButton },
props: {
param: Object,
},
watch: {
param(val) {
this.tableParam = val;
},
},
data() {
return {
buttons: [
{
label: '编辑',
click: this.onEditTableRow,
},
{
type: 'confirm',
url: (row) => `/oceanus/api/v1/categories/attributes/${row.attributeId}`,
after: () => this.refreshTable(),
},
{
label: '置顶',
click: async (row) => {
const { attributeId, categoryId } = row;
try {
await Api.movementAttributes({ attributeId, categoryId, moveType: 'TOP' });
this.refreshTable();
this.$message.success('置顶成功!');
} catch (e) {
this.$message.warning('置顶失败!');
}
},
},
{
label: '置底',
click: async (row) => {
const { attributeId, categoryId } = row;
try {
await Api.movementAttributes({ attributeId, categoryId, moveType: 'BOTTOM' });
this.refreshTable();
this.$message.success('置顶成功!');
} catch (e) {
this.$message.warning('置顶失败!');
}
},
},
],
editButtons: [
{
label: '确定',
click: this.onSubmitTableRow,
},
{
type: 'confirm',
label: '取消',
title: '确认是否取消?',
onOk: this.onCancelTableRow,
},
],
tableParam: {},
};
},
methods: {
async formatData(data) {
const newData = await formatObj(data.records, { key: 'attributeId' });
return newData;
},
onAddTableRow() {
const data = this.$refs['table']?.getTableData();
const isEdit = data.find((i) => i.action === 'add');
if (isEdit) return;
const obj = {
editable: true,
key: +new Date(),
attributeName: '',
action: 'add',
categoryId: this.tableParam.categoryId,
viewIndex: 1,
};
this.$refs['table']?.setTableData([obj, ...data]);
},
onCancelTableRow(row) {
const data = this.$refs['table']?.getTableData();
if (row.action === 'add') {
const newData = data.filter((i) => i.key !== row.key);
this.$refs['table']?.setTableData(newData);
}
if (row.action === 'edit') {
const newData = data.map((i) => {
const data = { ...i };
if (i.key === row.key) {
data.editable = false;
delete data.action;
}
return data;
});
this.$refs['table']?.setTableData(newData);
}
},
async onSubmitTableRow(row) {
if (row.attributeName === '') {
return this.$message.warning('请输入属性名称!');
} else {
try {
if (row.action === 'add') {
await Api.addAttributes(row);
}
if (row.action === 'edit') {
await Api.updateAttributes(row);
}
this.refreshTable();
this.$message.success('提交成功!');
} catch (e) {
this.$message.warning('保存失败!');
}
}
},
onEditTableRow(row) {
const data = this.$refs['table']?.getTableData();
const newData = data.map((i) => {
const oData = { ...i };
if (i.key === row.key) {
oData.editable = true;
oData.action = 'edit';
}
return oData;
});
this.$refs['table']?.setTableData(newData);
},
refreshTable() {
this.$refs['table']?.reset();
},
},
};
</script>
<style scoped>
</style>
<template>
<a-popover v-model="visible" placement="leftTop" trigger="click" v-bind="$attrs">
<template slot="content">
<div :style="{ width: '400px' }">
<a-form-model :model="form" :labelCol="{ span: 6 }" :wrapperCol="{ span: 18 }">
<a-form-model-item :style="{ marginBottom: 0 }" label="开始时间">
<a-date-picker
v-model="form.startTime"
style="width: 100%"
placeholder="Select date"
/>
</a-form-model-item>
<a-form-model-item :style="{ marginBottom: 0 }" label="结束时间">
<a-date-picker v-model="form.endTime" style="width: 100%" placeholder="Select date" />
</a-form-model-item>
<a-form-model-item :style="{ marginBottom: 0 }" label="设备">
<a-tree-select
v-model="form.equipmentId"
style="width: 100%"
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
:tree-data="treeData"
placeholder="Please select"
treeDataSimpleMode
:load-data="onLoadData"
/>
</a-form-model-item>
<a-form-model-item :style="{ marginBottom: 0 }" label="时间类型">
<MySelect
v-model="form.eventType"
:request="getStaticDataApi"
:param="{ paramModule: 'oceanus_equipment_event', paramCode: 'event_type' }"
/>
</a-form-model-item>
</a-form-model>
<a-row>
<a-col :span="24" class="tw-text-right tw-mt-4">
<a-space>
<a-button type="default" @click="hide">取消</a-button>
<a-button type="default" @click="rest">重置</a-button>
<a-button type="primary" @click="submit">确定</a-button>
</a-space>
</a-col>
</a-row>
</div>
</template>
<slot name="btn">
<a-button type="link">搜索</a-button>
</slot>
</a-popover>
</template>
<script>
import Api from '@/api/oceanus';
import { getStaticDataApi } from '@/api';
import MySelect from '@/components/MySelect/RequestSelect.vue';
export default {
components: { MySelect },
props: {
dataInfo: {
type: Object,
default: () => ({}),
},
},
watch: {
dataInfo: {
handler(val) {
this.init(val);
},
deep: true,
immediate: true,
},
},
data() {
return {
Api,
visible: false,
form: {},
treeData: [],
getStaticDataApi,
};
},
methods: {
init(data) {
const { catalogId, catalogName, equipmentId } = data;
this.treeData = [{ value: equipmentId, id: catalogId, title: catalogName, pId: 0 }];
this.form = {
...this.form,
equipmentId,
};
},
rest() {
const { equipmentId } = this.dataInfo;
this.form = {
equipmentId,
};
},
hide() {
this.visible = false;
},
onLoadData(treeNode) {
return new Promise((resolve) => {
Api.getEquipmentsTree({ catalogId: treeNode.dataRef.id }).then((resp) => {
const newData = resp.map((i) => {
return {
value: i.catalogValue,
id: i.catalogId,
title: i.catalogName,
pId: i.parentCatalogId,
};
});
this.treeData = this.treeData.concat([...newData]);
resolve();
});
});
},
submit() {
const data = {
...this.form,
startTime: this.form.startTime && this.form.startTime.format('YYYY-MM-DD hh:mm:ss'),
starendTimetTime: this.form.endTime && this.form.endTime.format('YYYY-MM-DD hh:mm:ss'),
};
this.$emit('submit', data);
this.hide();
},
},
};
</script>
<template>
<a-row :gutter="[16, 24]">
<a-col :span="12">
<a-button type="link" @click="onAdd">新增</a-button>
<a-divider type="vertical" />
<a-dropdown>
<a-button type="link"> 记录数 <a-icon type="down" /> </a-button>
<a-menu slot="overlay">
<a-menu-item>
<a @click="() => setPage(10)">10</a>
</a-menu-item>
<a-menu-item>
<a @click="() => setPage(20)">20</a>
</a-menu-item>
<a-menu-item>
<a @click="() => setPage(30)">30</a>
</a-menu-item>
<a-menu-item>
<a @click="() => setPage(50)">50</a>
</a-menu-item>
<a-menu-item>
<a @click="() => setPage(100)">100</a>
</a-menu-item>
</a-menu>
</a-dropdown>
</a-col>
<a-col :span="12" class="tw-text-right">
<SearchPopover :dataInfo="dataInfo" title="事件过滤" @submit="onScreen" />
</a-col>
<a-col :span="24">
<a-timeline mode="alternate">
<a-timeline-item v-for="item in list" :key="item.eventId">
<div class="tw-font-bold tw-leading-4 tw-mb-2">
{{ item.equipmentName }} [{{ item.equipmentCode }}]
</div>
<a-space>
<a-icon
v-if="item.eventType === 'MAINTAIN'"
type="tool"
style="color: rgb(245, 158, 11)"
/>
<a-icon v-else type="warning" style="color: rgb(190, 24, 93)" />
<div>{{ item.eventTypeName }}</div>
<div>{{ item.occurTime }}</div>
</a-space>
<div class="tw-mb-2 tw-mt-2">{{ item.eventDescription }}</div>
<a-space>
<a @click="() => onEdit(item)">编辑</a>
<PopconfirmDelete
:url="`/oceanus/api/v1/equipments/events/${item.eventId}`"
:cb="refresh"
/>
</a-space>
</a-timeline-item>
</a-timeline>
</a-col>
<EventDrawer ref="EventDrawer" :dataInfo="dataInfo" :refresh="refresh" />
</a-row>
</template>
<script>
import moment from 'moment';
import Api from '@/api/oceanus';
import PopconfirmDelete from '@/components/popconfirm_delete/index.vue';
import SearchPopover from './SearchPopover.vue';
import EventDrawer from './EventDrawer.vue';
export default {
components: { SearchPopover, EventDrawer, PopconfirmDelete },
props: {
dataInfo: {
type: Object,
default: () => ({}),
},
},
watch: {
dataInfo: {
handler(val) {
const { equipmentId } = val;
this.form = {
equipmentId,
};
this.size = 10;
},
deep: true,
immediate: true,
},
},
data() {
return {
Api,
size: 10,
form: {},
list: [],
};
},
mounted() {
this.onSearch();
},
methods: {
onScreen(data) {
this.form = data;
this.onSearch();
},
setPage(val) {
this.size = val;
this.onSearch();
},
onAdd() {
const { equipmentId } = this.dataInfo;
this.view({ equipmentId });
},
onEdit(row) {
const data = {
...row,
occurTime: row.occurTime && moment(row.occurTime, 'YYYY-MM-DD'),
};
delete data.eventTypeName;
delete data.equipmentName;
delete data.equipmentCode;
this.view(data, 1);
},
async onSearch() {
const data = {
...this.form,
size: this.size,
};
const resp = await Api.getEquipmentsEvents(data);
this.list = resp;
},
async view(data = {}, type = 0) {
this.$refs['EventDrawer']?.open();
this.$nextTick(() => {
this.$refs['EventDrawer'].setData({ ...data }, type);
});
},
refresh() {
this.onSearch();
},
},
};
</script>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment