Files
2023-03-29 11:11:06 +08:00

697 lines
21 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="app-container">
<el-form
v-show="showSearch"
ref="queryRef"
:inline="true"
:model="queryParams"
label-position="left"
label-width="100px"
>
<el-form-item label="物模型名称" prop="templateName">
<el-input
v-model="queryParams.templateName"
clearable
placeholder="请输入物模型名称"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="租户ID" prop="tenantId">
<el-input
v-model="queryParams.tenantId"
clearable
placeholder="请输入租户ID"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="标识符,产品下唯一" prop="identifier">
<el-input
v-model="queryParams.identifier"
clearable
placeholder="请输入标识符,产品下唯一"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="是否系统通用" prop="isSys">
<el-input
v-model="queryParams.isSys"
clearable
placeholder="请输入是否系统通用"
@keyup.enter="handleQuery"
/>
</el-form-item>
<!-- <el-form-item label="是否首页显示" prop="isTop">-->
<!-- <el-input-->
<!-- v-model="queryParams.isTop"-->
<!-- clearable-->
<!-- placeholder="请输入是否首页显示"-->
<!-- @keyup.enter="handleQuery"-->
<!-- />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="是否实时监测" prop="isMonitor">-->
<!-- <el-input-->
<!-- v-model="queryParams.isMonitor"-->
<!-- clearable-->
<!-- placeholder="请输入是否实时监测"-->
<!-- @keyup.enter="handleQuery"-->
<!-- />-->
<!-- </el-form-item>-->
<el-form-item>
<el-button icon="Search" type="primary" @click="handleQuery"
>搜索
</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-hasPermi="['thingsmodel:template:add']"
icon="Plus"
plain
type="primary"
@click="handleAdd"
>新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-hasPermi="['thingsmodel:template:edit']"
:disabled="single"
icon="Edit"
plain
type="success"
@click="handleUpdate"
>修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-hasPermi="['thingsmodel:template:remove']"
:disabled="multiple"
icon="Delete"
plain
type="danger"
@click="handleDelete"
>删除
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-hasPermi="['thingsmodel:template:export']"
icon="Download"
plain
type="warning"
@click="handleExport"
>导出
</el-button>
</el-col>
<right-toolbar
v-model:showSearch="showSearch"
@queryTable="getList"
></right-toolbar>
</el-row>
<el-table
v-loading="loading"
:data="templateList"
border
@selection-change="handleSelectionChange"
>
<el-table-column align="center" type="selection" width="55" />
<el-table-column align="center" label="物模型ID" prop="templateId" />
<el-table-column align="center" label="物模型名称" prop="templateName" />
<el-table-column align="center" label="租户ID" prop="tenantId" />
<el-table-column
align="center"
label="标识符,产品下唯一"
prop="identifier"
/>
<el-table-column align="center" label="模型类别" prop="type">
<template #default="{ row }">
<dict-tag
:options="modelTypeDict"
:value="[row.type]"
effect="dark"
size="small"
/>
<!-- <el-tag size="small">-->
<!-- {{ modelType.get(row.type) ?? "未知" }}-->
<!-- </el-tag>-->
</template>
</el-table-column>
<el-table-column align="center" label="数据类型">
<template #default="{ row }">
<!-- {{ dataTypeMap.get(row.datatype) ?? "未知" }}-->
<dict-tag :options="dataTypeDict" :value="[row.datatype]" />
</template>
</el-table-column>
<el-table-column
align="center"
header-align="center"
label="数据定义"
min-width="150"
prop="specs"
>
<template #default="{ row }">
<div v-html="formatSpecsDisplay(row.specs)"></div>
</template>
</el-table-column>
<el-table-column align="center" label="是否系统通用" prop="isSys">
<template #default="{ row }">
<dict-tag :options="isSysDict" :value="[row.isSys]" />
</template>
</el-table-column>
<!-- <el-table-column align="center" label="是否首页显示" prop="isTop" />-->
<!-- <el-table-column align="center" label="是否实时监测" prop="isMonitor" />-->
<el-table-column align="center" label="备注" prop="remark" />
<el-table-column align="center" label="状态" prop="status" />
<el-table-column
align="center"
class-name="small-padding fixed-width"
label="操作"
>
<template #default="scope">
<el-button
v-hasPermi="['thingsmodel:template:edit']"
icon="Edit"
link
type="primary"
@click="handleUpdate(scope.row)"
>修改
</el-button>
<el-button
v-hasPermi="['thingsmodel:template:remove']"
icon="Delete"
link
type="primary"
@click="handleDelete(scope.row)"
>删除
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
v-model:limit="queryParams.pageSize"
v-model:page="queryParams.pageNum"
:total="total"
@pagination="getList"
/>
<!-- 添加或修改物模型模板对话框 -->
<el-dialog v-model="open" :title="title" append-to-body width="500px">
<el-form
ref="templateRef"
:model="form"
:rules="rules"
label-position="left"
label-width="120px"
>
<el-form-item label="物模型名称" prop="templateName">
<el-input
v-model="form.templateName"
placeholder="请输入物模型名称"
/>
</el-form-item>
<el-form-item label="租户ID" prop="tenantId">
<el-input v-model="form.tenantId" placeholder="请输入租户ID" />
</el-form-item>
<el-form-item label="标识符,产品下唯一" prop="identifier">
<el-input
v-model="form.identifier"
placeholder="请输入标识符,产品下唯一"
/>
</el-form-item>
<el-form-item label="是否系统通用" prop="isSys">
<!-- <el-input v-model="form.isSys" placeholder="请输入是否系统通用" />-->
<el-switch
v-model="form.isSys"
:active-value="1"
:inactive-value="0"
></el-switch>
</el-form-item>
<el-form-item label="模型类别" prop="type">
<el-radio-group v-model="form.type" @change="typeChange(form.type)">
<el-radio-button :label="1">属性</el-radio-button>
<el-radio-button :label="2">功能</el-radio-button>
<el-radio-button :label="3">事件</el-radio-button>
</el-radio-group>
</el-form-item>
<!-- <el-form-item label="是否首页显示" prop="isTop">-->
<!-- <el-input v-model="form.isTop" placeholder="请输入是否首页显示" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="是否实时监测" prop="isMonitor">-->
<!-- <el-input v-model="form.isMonitor" placeholder="请输入是否实时监测" />-->
<!-- </el-form-item>-->
<el-form-item label="备注" prop="remark">
<el-input
v-model="form.remark"
placeholder="请输入内容"
type="textarea"
/>
</el-form-item>
<el-divider />
<el-form-item label="数据类型" prop="datatype">
<el-select
v-model="form.datatype"
placeholder="请选择数据类型"
style="width: 175px"
@change="dataTypeChange"
>
<el-option key="integer" label="整数" value="integer"></el-option>
<el-option key="decimal" label="小数" value="decimal"></el-option>
<el-option
key="bool"
:disabled="form.type === 1"
label="布尔"
value="bool"
></el-option>
<el-option
key="enum"
:disabled="form.type === 1"
label="枚举"
value="enum"
></el-option>
<el-option
key="string"
:disabled="form.type === 1"
label="字符串"
value="string"
></el-option>
<el-option
key="array"
:disabled="form.type === 1"
label="数组"
value="array"
></el-option>
</el-select>
</el-form-item>
<div v-if="form.datatype === 'integer' || form.datatype === 'decimal'">
<el-form-item label="取值范围">
<el-row>
<el-col :span="9">
<el-input
v-model="form.specs.min"
placeholder="最小值"
type="number"
/>
</el-col>
<el-col :span="2" align="center">到</el-col>
<el-col :span="9">
<el-input
v-model="form.specs.max"
placeholder="最大值"
type="number"
/>
</el-col>
</el-row>
</el-form-item>
<el-form-item label="单位">
<el-input
v-model="form.specs.unit"
placeholder="请输入单位,例如:℃"
style="width: 385px"
/>
</el-form-item>
<el-form-item label="步长">
<el-input
v-model="form.specs.step"
placeholder="请输入步长例如1"
style="width: 385px"
type="number"
/>
</el-form-item>
</div>
<div v-if="form.datatype === 'bool'">
<el-form-item label="布尔值" prop="">
<el-row style="margin-bottom: 10px">
<el-col :span="9">
<el-input
v-model="form.specs.falseText"
placeholder="例如:关闭"
/>
</el-col>
<el-col :offset="1" :span="10"> 0 值对应文本)</el-col>
</el-row>
<el-row>
<el-col :span="9">
<el-input
v-model="form.specs.trueText"
placeholder="例如:打开"
/>
</el-col>
<el-col :offset="1" :span="10"> 1 值对应文本)</el-col>
</el-row>
</el-form-item>
</div>
<div v-if="form.datatype === 'enum'">
<el-form-item label="枚举项" prop="">
<el-row
v-for="(item, index) in form.specs.enumList"
:key="'enum' + index"
style="margin-bottom: 10px"
>
<el-col :span="9">
<el-input
v-model="item.value"
placeholder="参数值例如0"
type="number"
/>
</el-col>
<el-col :offset="1" :span="11">
<el-input
v-model="item.text"
placeholder="参数描述,例如:中速档位"
/>
</el-col>
<el-col v-if="index !== 0" :offset="1" :span="2"
><a style="color: #f56c6c" @click="removeEnumItem(index)"
>删除</a
></el-col
>
</el-row>
<div>
+ <a style="color: #409eff" @click="addEnumItem()">添加枚举项</a>
</div>
</el-form-item>
</div>
<div v-if="form.datatype === 'string'">
<el-form-item label="最大长度" prop="">
<el-row>
<el-col :span="9">
<el-input
v-model="form.specs.maxLength"
placeholder="例如1024"
type="number"
/>
</el-col>
<el-col :offset="1" :span="14">字符串的最大长度</el-col>
</el-row>
</el-form-item>
</div>
<div v-if="form.datatype === 'array'">
<el-form-item label="数组类型" prop="">
<el-radio-group v-model="form.specs.arrayType">
<el-radio label="int">int整数</el-radio>
<el-radio label="double">double小数</el-radio>
<el-radio label="string">string字符串</el-radio>
</el-radio-group>
</el-form-item>
</div>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script name="Template" setup>
import {
addTemplate,
delTemplate,
getTemplate,
listTemplate,
updateTemplate,
} from "@/api/thingsmodel/template";
import { getCurrentInstance, reactive, ref, toRefs } from "vue";
import { dataTypeDict, isSysDict, modelTypeDict } from "@/constant/dict";
import { formatSpecsDisplay } from "@/utils/thingsmodel";
import { listTenant } from "@/api/system/tenant";
import DictTag from "@/components/DictTag/index.vue";
const { proxy } = getCurrentInstance();
const templateList = ref([]);
const open = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");
const tenantOptions = ref([]);
const data = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
templateName: null,
tenantId: null,
identifier: null,
type: null,
datatype: null,
specs: null,
isSys: null,
isTop: null,
isMonitor: null,
status: null,
},
rules: {
templateName: [
{ required: true, message: "物模型名称不能为空", trigger: "blur" },
],
tenantId: [{ required: true, message: "租户ID不能为空", trigger: "blur" }],
identifier: [
{
required: true,
message: "标识符,产品下唯一不能为空",
trigger: "blur",
},
],
type: [{ required: true, message: "模型类别不能为空", trigger: "change" }],
datatype: [
{ required: true, message: "数据类型不能为空", trigger: "change" },
],
specs: [{ required: true, message: "数据定义不能为空", trigger: "blur" }],
isSys: [
{ required: true, message: "是否系统通用不能为空", trigger: "blur" },
],
isTop: [
{ required: true, message: "是否首页显示不能为空", trigger: "blur" },
],
isMonitor: [
{ required: true, message: "是否实时监测不能为空", trigger: "blur" },
],
},
});
const { queryParams, form, rules } = toRefs(data);
/** 查询物模型模板列表 */
function getList() {
loading.value = true;
listTemplate(queryParams.value).then((response) => {
templateList.value = response.rows;
total.value = response.total;
loading.value = false;
});
}
// 取消按钮
function cancel() {
open.value = false;
reset();
}
// 表单重置
function reset() {
form.value = {
templateId: null,
templateName: null,
tenantId: null,
identifier: null,
type: 1,
datatype: "integer",
specs: {
enumList: [
{
value: "",
text: "",
},
],
arrayType: "int",
},
isSys: null,
isTop: null,
isMonitor: null,
createBy: null,
createTime: null,
remark: null,
status: null,
};
proxy.resetForm("templateRef");
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1;
getList();
}
/** 重置按钮操作 */
function resetQuery() {
proxy.resetForm("queryRef");
handleQuery();
}
// 多选框选中数据
function handleSelectionChange(selection) {
ids.value = selection.map((item) => item.templateId);
single.value = selection.length !== 1;
multiple.value = !selection.length;
}
/** 新增按钮操作 */
function handleAdd() {
reset();
open.value = true;
title.value = "添加物模型模板";
}
/** 修改按钮操作 */
function handleUpdate(row) {
reset();
const _templateId = row.templateId || ids.value;
getTemplate(_templateId).then((response) => {
const tempForm = response.data;
open.value = true;
title.value = "修改物模型模板";
// Json转对象
tempForm.specs = JSON.parse(tempForm.specs);
if (!tempForm.specs.enumList) {
tempForm.specs.enumList = [
{
value: "",
text: "",
},
];
}
if (!tempForm.specs.arrayType) {
tempForm.specs.arrayType = "int";
}
form.value = tempForm;
});
}
/** 提交按钮 */
function submitForm() {
proxy.$refs["templateRef"].validate((valid) => {
if (valid) {
if (form.value.templateId != null) {
// 格式化specs
form.value.specs = formatThingsSpecs();
updateTemplate(form.value).then((response) => {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
});
} else {
// 格式化specs
form.value.specs = formatThingsSpecs();
addTemplate(form.value).then((response) => {
proxy.$modal.msgSuccess("新增成功");
open.value = false;
getList();
});
}
}
});
}
/** 删除按钮操作 */
function handleDelete(row) {
const _templateIds = row.templateId || ids.value;
proxy.$modal
.confirm('是否确认删除物模型模板编号为"' + _templateIds + '"的数据项?')
.then(function () {
return delTemplate(_templateIds);
})
.then(() => {
getList();
proxy.$modal.msgSuccess("删除成功");
})
.catch(() => {});
}
/** 导出按钮操作 */
function handleExport() {
proxy.download(
"thingsmodel/template/export",
{
...queryParams.value,
},
`template_${new Date().getTime()}.xlsx`
);
}
// 类型改变
const typeChange = (label) => {
// if (label === 2 || label === 3) {
// form.value.isMonitor = 0;
// }
if (
label === 1 &&
form.value.datatype !== "integer" &&
form.value.datatype !== "decimal"
) {
console.log(form.value);
form.value.datatype = "integer";
}
};
const dataTypeChange = () => {};
/** 添加枚举项 */
const addEnumItem = () => {
form.value.specs.enumList.push({
value: "",
text: "",
});
};
/** 删除枚举项 */
const removeEnumItem = (index) => {
form.value.specs.enumList.splice(index, 1);
};
// 格式化物模型
const formatThingsSpecs = () => {
const data = {};
data.type = form.value.datatype;
if (form.value.datatype === "integer" || form.value.datatype === "decimal") {
data.min = Number(form.value.specs.min);
data.max = Number(form.value.specs.max);
data.unit = form.value.specs.unit;
data.step = Number(form.value.specs.step);
} else if (form.value.datatype === "string") {
data.maxLength = Number(form.value.specs.maxLength);
} else if (form.value.datatype === "bool") {
data.falseText = form.value.specs.falseText;
data.trueText = form.value.specs.trueText;
} else if (form.value.datatype === "array") {
data.arrayType = form.value.specs.arrayType;
} else if (form.value.datatype === "enum") {
data.enumList = form.value.specs.enumList;
}
return JSON.stringify(data);
};
const getTenantList = async (keyword) => {
const response = await listTenant({
pageNum: 1,
pageSize: 20,
tenantName: keyword,
});
tenantOptions.value = response.rows;
};
getList();
getTenantList();
</script>