소스 검색

标养室监测

zhuangyunsheng 3 달 전
부모
커밋
e0387b28eb

+ 5 - 5
src/api/model/carwash.js

@@ -54,11 +54,11 @@ export default {
     //     }
     // },
 
-    copyData: {
-        url: `${config.API_URL}/ops/carRinse/copyData`,
-        name: "数据模拟-复制",
-        add: async function (data = {}) {
-            return await http.post(this.url, data);
+    dataMock: {
+        url: `${config.API_URL}/ops/carRinse`,
+        name: "数据模拟-参数/复制",
+        copyData: async function (data = {}) {
+            return await http.post(`${this.url}/copyData`, data);
         }
     }
 }

+ 36 - 6
src/api/model/scc.js

@@ -2,19 +2,49 @@ import config from "@/config"
 import http from "@/utils/request"
 
 export default {
-    gate: {
-        url: `${config.API_URL}/api/scc/mounted/fetch`,
+    mounted: {
+        url: `${config.API_URL}/ops/scc/getMountedList`,
         name: "安装点查询",
         get: async function (data = {}) {
             return await http.post(this.url, data);
         }
     },
 
-    records: {
-        url: `${config.API_URL}/api/scc/records/fetch`,
-        name: "监测记录",
+    record: {
+        name: "预警记录",
+        url: `${config.API_URL}/ops/scc`,
         get: async function (data = {}) {
-            return await http.post(this.url, data);
+            return await http.post(`${this.url}/getPage`, data);
+        },
+
+        add: async function (data = {}) {
+            return await http.post(`${this.url}/save`, data);
+        },
+
+        edit: async function (data = {}) {
+            return await http.post(`${this.url}/update`, data);
+        },
+
+        del: async function (data = {}) {
+            return await http.post(`${this.url}/remove`, data);
+        },
+
+        batchDel: async function (data = {}) {
+            return await http.post(`${this.url}/batchRemove`, data);
+        }
+    },
+
+    dataMock: {
+        makeData: {
+            url: `${config.API_URL}/ops/scc`,
+            name: "数据模拟-参数",
+            normal: async function (data = {}) {
+                return await http.post(`${this.url}/makeData`, data);
+            },
+
+            alarm: async function (data = {}) {
+                return await http.post(`${this.url}/makeWarningData`, data);
+            }
         }
     }
 }

+ 5 - 5
src/api/model/ugliAi.js

@@ -34,11 +34,11 @@ export default {
         }
     },
 
-    copyData: {
-        url: `${config.API_URL}/ops/aihazard/copyData`,
-        name: "数据模拟-复制",
-        add: async function (data = {}) {
-            return await http.post(this.url, data);
+    dataMock: {
+        url: `${config.API_URL}/ops/aihazard`,
+        name: "数据模拟-参数/复制",
+        copyData: async function (data = {}) {
+            return await http.post(`${this.url}/copyData`, data);
         }
     }
 }

+ 10 - 5
src/utils/basicDic.js

@@ -20,11 +20,6 @@ export const towerWarningDic = {
     WARNING_XIANWEI: "限位告警"
 }
 
-export const sccRecordTypeDic = {
-    SCC_RECORD_VTYPE_C: { label: "温度", unit: "℃" },
-    SCC_RECORD_VTYPE_RH: { label: "湿度", unit: "%rh" }
-}
-
 /* ************************************************************************* */ 
 export const taskDic = {
     option: {
@@ -61,6 +56,16 @@ export const aiTypeDic = {
     AIHAZARD_REC_VEHICLE_NOT_CLEANED: "车辆未清洗"
 }
 
+export const sccTypeDic = {
+    SCC_RECORD_VTYPE_C: "温度",
+    SCC_RECORD_VTYPE_RH: "湿度"
+}
+
+export const sccTypeUnitDic = {
+    SCC_RECORD_VTYPE_C: "℃",
+    SCC_RECORD_VTYPE_RH: "%rh"
+}
+
 export function objectToArray(obj) {
     return XEUtils.map(XEUtils.keys(obj), value => ({ label: XEUtils.get(obj, value), value }))
 }

+ 3 - 3
src/utils/shortcuts.js

@@ -6,8 +6,8 @@ export function rangeShortcuts(format = "YYYY-MM-DD HH:mm:ss") {
         { text: "本月", value: () => [moment().startOf("month").format(format), moment().format(format)] },
         { text: "本季度", value: () => [moment().startOf("quarter").format(format), moment().format(format)] },
         { text: "今年", value: () => [moment().startOf("year").format(format), moment().format(format)] },
-        { text: "近7天", value: () => [moment().subtract(1, "week").format(format), moment().format(format)] },
-        { text: "近1月", value: () => [moment().subtract(1, "month").format(format), moment().format(format)] },
-        { text: "近1年", value: () => [moment().subtract(1, "year").format(format), moment().format(format)] },
     ]
+    // { text: "近7天", value: () => [moment().subtract(1, "week").format(format), moment().format(format)] },
+    // { text: "近1月", value: () => [moment().subtract(1, "month").format(format), moment().format(format)] },
+    // { text: "近1年", value: () => [moment().subtract(1, "year").format(format), moment().format(format)] },
 }

+ 8 - 2
src/views/dataMock/carwash/detail.vue

@@ -1,5 +1,10 @@
 <template>
     <el-dialog v-model="visible" title="数据模拟" fullscreen :close-on-click-modal="false" @closed="$emit('closed')">
+        <el-tabs v-model="apiKey">
+            <el-tab-pane label="参数配置" name="makeData" disabled></el-tab-pane>
+            <el-tab-pane label="数据复制" name="copyData"></el-tab-pane>
+        </el-tabs>
+        
         <el-form ref="formRef" :model="form" :rules="rules" label-width="110">
             <el-row>
                 <el-col :md="12" :xs="24">
@@ -82,6 +87,7 @@ import dataTable from "./components/record";
 
 const route = useRoute();
 const $emit = defineEmits(["success", "closed"]);
+const apiKey = ref("copyData");
 const visible = ref(false);
 const isSaving = ref(false);
 
@@ -149,7 +155,7 @@ const submit = key => {
             key == "template" && XEUtils.set(data, "targetProjectId", 1);
 
             isSaving.value = true;
-            API.carwash.copyData.add(data).then(() => {
+            API.carwash.dataMock[apiKey.value](data).then(() => {
                 isSaving.value = false;
                 ElMessage.success("操作成功");
                 visible.value = false;
@@ -167,7 +173,7 @@ defineExpose({
 </script>
 
 <style lang="scss" scoped>
-.el-form {padding-right: var(--el-message-close-size, 16px);}
+.el-form {margin-top: 5px;padding-right: var(--el-message-close-size, 16px);}
 .el-form-item .el-radio-group {flex-wrap: nowrap;}
 .el-form :deep(.el-main) {padding-right: 0;padding-bottom: 0;}
 </style>

+ 0 - 1
src/views/dataMock/carwash/index.vue

@@ -39,7 +39,6 @@ const mock_add = () => {
 
 const refreshState = () => {
     if (activeName.value == "monos") setTimeout(() => componentRef.value.refreshTable(), 2000);
-    activeName.value = "monos";
 }
 </script>
 

+ 8 - 3
src/views/dataMock/standard/components/index.js

@@ -1,12 +1,17 @@
+import XEUtils from "xe-utils"
+
 const resultComps = {}
 let requireComponent = require.context(
     "./", // 在当前目录下查找
-    false, // 不遍历子文件夹
+    true, // 遍历子文件夹
     /\.vue$/ // 正则匹配 以 .vue结尾的文件
 )
 requireComponent.keys().forEach(fileName => {
-    let comp = requireComponent(fileName)
-    resultComps[fileName.replace(/^\.\/(.*)\.\w+$/, "$1")] = comp.default
+    const compName = fileName.replace(/^\.\/(.*)\.\w+$/, "$1")
+    const comp = requireComponent(fileName)
+    if (compName.includes("/")) {
+        if (XEUtils.last(compName.split("/")) == "index") resultComps[XEUtils.first(compName.split("/"))] = comp.default
+    } else resultComps[compName] = comp.default
 })
 
 export default resultComps

+ 0 - 116
src/views/dataMock/standard/components/monos.vue

@@ -1,116 +0,0 @@
-<template>
-    <el-main>
-        <el-card>
-            <template #header>Group任务池配置<el-button type="primary" @click="mono_detail">任务列表</el-button></template>
-
-            <el-form>
-                <el-row :gutter="15">
-                    <el-col :span="8">
-                        <el-form-item label="最大组任务数:">{{ XEUtils.get(defaultGroups, "configs.maxGroupQueues") }}</el-form-item>
-                    </el-col>
-                    <el-col :span="8">
-                        <el-form-item label="队列最大任务数:">{{ XEUtils.get(defaultGroups, "configs.maxQueueLimit") }}</el-form-item>
-                    </el-col>
-                    <el-col :span="8">
-                        <el-form-item label="最大并发队列数:">{{ XEUtils.get(defaultGroups, "configs.maxQueues") }}</el-form-item>
-                    </el-col>
-                    <el-col :span="8">
-                        <el-form-item label="队列任务间隔(秒):">{{ XEUtils.get(defaultGroups, "configs.taskIntervalSeconds") }}</el-form-item>
-                    </el-col>
-                    <el-col :span="8">
-                        <el-form-item label="重试任务间隔(秒):">{{ XEUtils.get(defaultGroups, "configs.taskRetryInterval") }}</el-form-item>
-                    </el-col>
-                    <el-col :span="8">
-                        <el-form-item label="任务最大重试次数(秒):">{{ XEUtils.get(defaultGroups, "configs.taskRetryTimes") }}</el-form-item>
-                    </el-col>
-                    <el-col :span="8">
-                        <el-form-item label="任务最大等待时间(秒):">{{ XEUtils.get(defaultGroups, "configs.taskWaitSeconds") }}</el-form-item>
-                    </el-col>
-                </el-row>
-            </el-form>
-        </el-card>
-
-        <el-card>
-            <el-form>
-                <el-form-item label="workers忙碌数量:">0</el-form-item>
-                <el-form-item label="workers空闲数量:">50</el-form-item>
-                <el-form-item label="Groups忙碌数量:">0</el-form-item>
-                <el-form-item label="Groups队列数量:">0</el-form-item>
-                <el-form-item label="mono总数:">0</el-form-item>
-            </el-form>
-        </el-card>
-        <div class="echart-bar">
-            <sc-echarts :option="option" @chartClick="chart_click"></sc-echarts>
-        </div>
-    </el-main>
-
-    <mono-detail v-if="dialog" ref="monoRef" @closed="dialog = false"></mono-detail>
-</template>
-
-<script setup>
-import XEUtils from "xe-utils"
-import { defaultGroups } from "../../main";
-import monoDetail from "../mono/index"
-
-const $emit = defineEmits(["closed"]);
-
-const option = ref({
-    grid: { left: "5%", right: "10%", bottom: 60 },
-    dataZoom: [
-        { type: "inside", endValue: 15, zoomLock: true }, { 
-        type: "slider",
-        showDetail: false,
-        moveHandleIcon: "none", // 移动手柄
-        moveHandleStyle: { opacity: 0 }
-    }],
-    xAxis: {
-        name: "workers",
-        nameTextStyle: { fontSize: 14, color: "#606266" },
-        axisLabel: { color: '#5d5d5d', rotate: -30 },
-        data: XEUtils.keys(XEUtils.get(defaultGroups, "workers"))
-    },
-    yAxis: {
-        name: "mono",
-        type: "value",
-        min: 0,
-        max: XEUtils.max([8, 5]),
-        nameTextStyle: { fontSize: 14, color: "#606266" },
-        minInterval: 1,
-        axisLabel: { color: '#5d5d5d' },
-        axisLine: { show: true, lineStyle: { color: "#d3d2d3" } },
-        splitLine: { show: false }
-    },
-    series: [{
-        type: "bar",
-        data: [8, 5],
-        animationDuration: 2500,
-        animationDurationUpdate: 2500
-    }]
-})
-
-const dialog = ref(false);
-const monoRef = ref();
-const chart_click = ({ name }) => {
-    dialog.value = true;
-    nextTick(() => monoRef.value.open(XEUtils.get(defaultGroups, `groups.${name}.monos`)));
-}
-
-const mono_detail = () => {
-    dialog.value = true;
-    nextTick(() => monoRef.value.open());
-}
-</script>
-
-<style lang="scss" scoped>
-.el-main {padding: 0 12px 12px;background: #fff;}
-.el-card :deep(.el-card__header) {display: flex;justify-content: space-between;align-items: center;padding-left: 20px;background: #f9fdff;font-weight: 700;}
-.el-card :deep(.el-card__body) {padding: 10px var(--el-card-padding);}
-.el-card + .el-card {margin-top: 10px;}
-
-.el-form .el-form-item {margin-bottom: 0;}
-.el-form :deep(.el-form-item__content) {font: 22px calculator-all;color: #1890ff;letter-spacing: 2px;}
-
-.el-card + .el-card .el-form {display: flex;justify-content: space-evenly;}
-
-.echart-bar {width: 100%;height: 400px;}
-</style>

+ 0 - 68
src/views/dataMock/standard/components/record.vue

@@ -1,68 +0,0 @@
-<template>
-    <scTable ref="xGridTable" :apiObj="$API.scc.records" framework="zeroLiteOld" :toolbarConfig="toolbarConfig" :formConfig="formConfig" :paramsColums="paramsColums" :columns="columns"></scTable>
-</template>
-
-<script setup>
-import moment from "moment";
-import XEUtils from "xe-utils";
-import TOOL from "@/utils/tool";
-import { sccRecordTypeDic } from "@/utils/basicDic";
-import { mapFormItemSelect, mapFormItemDatePicker } from "@/components/scTable/helper";
-
-const route = useRoute();
-
-const proConfig = reactive({
-    storageKey: "PROJECT",
-    resetValue: XEUtils.toNumber(XEUtils.get(route, "query.projectId", 288)),
-    optionProps: { label: "projectName", value: "fpiId" },
-    events: {
-        change: data => XEUtils.assign(formConfig.data, data)
-    }
-})
-
-const daterangeConfig = reactive({
-    span: 9,
-    resetValue: () => [moment().startOf("day").format("YYYY-MM-DD HH:mm:ss"), moment().format("YYYY-MM-DD HH:mm:ss")],
-    props: {
-        type: "datetimerange",
-        clearable: false,
-        startPlaceholder: "开始时间",
-        endPlaceholder: "结束时间",
-        format: "YYYY-MM-DD HH:mm"
-    }
-})
-
-const toolbarConfig = reactive({
-    enabled: true,
-    print: false
-})
-
-const formConfig = reactive({
-    data: {
-        projectID: XEUtils.toNumber(XEUtils.get(route, "query.projectId", 288)),
-        createTime: [moment().startOf("day").format("YYYY-MM-DD HH:mm:ss"), moment().format("YYYY-MM-DD HH:mm:ss")]
-    },
-    items: [
-        mapFormItemSelect("projectID", "所属项目", proConfig),
-        mapFormItemDatePicker("createTime", "监测时间", daterangeConfig)
-    ]
-})
-
-const paramsColums = reactive([
-    { type: "relation", column: "createTime", symbol: "eqgt", field: "createTime[0]", formatValue: value => moment(value).format("YYYY-MM-DDTHH:mm:ss[Z]") },
-    { type: "relation", column: "createTime", symbol: "eqlt", field: "createTime[1]", formatValue: value => moment(value).format("YYYY-MM-DDTHH:mm:ss[Z]") },
-    { type: "orderby", column: "createTime", symbol: "desc" },
-    { type: "expands", column: "projectID", symbol: "eq" }
-]);
-
-const columns = reactive([
-    { type: "seq", fixed: "left", width: 60 },
-    { type: "html", field: "device.device_num", title: "设备唯一标识", fixed: "left", minWidth: 150, sortable: true },
-    { type: "html", field: "projectName", title: "所属项目", minWidth: 200, sortable: true, formatter: ({ cellValue, row }) => cellValue || XEUtils.get(XEUtils.find(TOOL.data.get("PROJECT"), item => item.fpiId === XEUtils.get(row, "device.project_id")), "projectName") },
-    { type: "html", field: "mounted.ground.groundName", title: "工地场区", minWidth: 150, sortable: true },
-    { type: "html", field: "mounted.mountedName", title: "安装点名称", minWidth: 150, sortable: true },
-    { type: "html", field: "taskTime", title: "监测时间", minWidth: 160, sortable: true, formatter: ({ cellValue, row }) => cellValue || TOOL.dateFormat(row.createTime) },
-    { type: "html", field: "taskType", title: "监测类型", minWidth: 100, sortable: true, formatter: ({ cellValue, row }) => cellValue || XEUtils.get(sccRecordTypeDic, `${XEUtils.get(row, "vtype")}.label`) },
-    { type: "html", field: "taskValue", title: "监测数值", minWidth: 100, sortable: true, formatter: ({ cellValue, row }) => cellValue || XEUtils.divide(XEUtils.get(row, "value"), 100) + XEUtils.get(sccRecordTypeDic, `${XEUtils.get(row, "vtype")}.unit`) }
-])
-</script>

+ 131 - 0
src/views/dataMock/standard/components/record/detail.vue

@@ -0,0 +1,131 @@
+<template>
+    <el-dialog v-model="visible" :title="titleMap[mode]" :width="480" :close-on-click-modal="false" @closed="$emit('closed', isDel)">
+        <el-form ref="formRef" :model="form" :rules="rules" label-width="120">
+            <template v-if="props.projectId != 1">
+                <el-form-item label="所属项目" prop="projectId">
+                    <el-select v-model="form.projectId" filterable placeholder="请选择所属项目" @change="form.mountedId = null">
+                        <el-option v-for="item in $TOOL.data.get('PROJECT')" :key="item.fpiId" :label="item.projectName" :value="item.fpiId"></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="设备安装点" prop="mountedId">
+                    <el-select v-model="form.mountedId" filterable placeholder="请选择设备安装点">
+                        <el-option v-for="item in filterMounteds" :key="item.id" :label="item.mountedName" :value="item.id"></el-option>
+                    </el-select>
+                </el-form-item>
+            </template>
+            <el-form-item label="监测类型" prop="vtype">
+                <el-select v-model="form.vtype" placeholder="请选择监测类型" @change="form.value = null">
+                    <el-option v-for="(label, key) in sccTypeDic" :key="key" :label="label" :value="key"></el-option>
+                </el-select>
+            </el-form-item>
+            <el-form-item label="监测数值" prop="value">
+                <el-input-number v-model="form.value" :readonly="!form.vtype" :precision="2" :controls="false" placeholder="请输入监测数值">
+                    <template v-if="form.vtype" #suffix>{{ XEUtils.get(sccTypeUnitDic, form.vtype) }}</template>
+                </el-input-number>
+            </el-form-item>
+            <el-form-item label="监测时间" prop="createTime">
+                <el-date-picker v-model="form.createTime" type="datetime" :clearable="false" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择监测时间"></el-date-picker>
+            </el-form-item>
+        </el-form>
+
+        <template #footer>
+            <el-button :loading="isSaving" type="primary" auto-insert-space @click="submit">保存</el-button>
+            <el-button auto-insert-space @click="visible = false">取消</el-button>
+        </template>
+    </el-dialog>
+</template>
+
+<script setup>
+import XEUtils from "xe-utils";
+import API from "@/api";
+import TOOL from "@/utils/tool";
+import { sccTypeDic, sccTypeUnitDic } from "@/utils/basicDic";
+
+const $emit = defineEmits(["success", "closed"]);
+const props = defineProps({
+    projectId: { type: Number, default: TOOL.data.get("PROJECT_ID") }
+});
+
+const visible = ref(false);
+const isSaving = ref(false);
+const isDel = ref(false);
+
+const mode = ref("add");
+const titleMap = reactive({
+    add: "数据录入",
+    edit: "修改"
+});
+
+const form = ref({
+    id: null,
+    projectId: props.projectId,
+    mountedId: null,
+    vtype: null,
+    value: null,
+    createTime: null,
+    features: "{}"
+});
+const rules = reactive({
+    projectId: [{ required: true, message: "请选择所属项目" }],
+    mountedId: [{ required: true, message: "请选择设备安装点" }],
+    createTime: [{ required: true, message: "请选择监测时间" }],
+    vtype: [{ required: true, message: "请选择监测类型" }],
+    value: [{ required: true, message: "请输入监测数值" }]
+})
+
+const mounteds = ref([]);
+const filterMounteds = computed(() => form.value.projectId ? XEUtils.filter(mounteds.value, item => item.projectId == form.value.projectId) : []);
+const fetchMounted = async () => {
+    const res = await API.scc.mounted.get();
+    mounteds.value = res || [];
+    if (props.projectId == 1) form.value.mountedId = XEUtils.get(XEUtils.find(res, item => item.projectId == 1), "id");
+}
+
+const open = () => {
+    visible.value = true;
+    fetchMounted();
+}
+const setData = data => {
+    open();
+    mode.value = "edit";
+    XEUtils.objectEach(form.value, (_, key) => {
+        if (key == "value") XEUtils.set(form.value, key, XEUtils.divide(XEUtils.get(data, key), 100));
+        else XEUtils.set(form.value, key, XEUtils.get(data, key));
+    });
+}
+
+const formRef = ref();
+const submit = () => {
+    formRef.value.validate(valid => {
+        if (valid) {
+            const data = XEUtils.omit(form.value, "value");
+            XEUtils.set(data, "value", XEUtils.multiply(XEUtils.get(form.value, "value"), 100));
+
+            isSaving.value = true;
+            API.scc.record[mode.value](data).then(() => {
+                isSaving.value = false;
+                ElMessage.success("操作成功");
+                visible.value = false;
+                $emit("success", mode.value);
+            }).catch(() => isSaving.value = false);
+        } else {
+            return false;
+        }
+    });
+}
+
+defineExpose({
+    open,
+    setData
+})
+</script>
+
+<style lang="scss" scoped>
+.el-form {
+    padding-right: calc(var(--el-dialog-padding-primary) + var(--el-message-close-size, 16px));
+
+    .el-input-number {width: 100%;}
+    .el-input-number :deep(.el-input__inner) {text-align: unset;}
+    .el-input-number :deep(.el-input__suffix) {font-size: 12px;}
+}
+</style>

+ 184 - 0
src/views/dataMock/standard/components/record/index.vue

@@ -0,0 +1,184 @@
+<template>
+    <scTable ref="xGridTable" batchDel :apiObj="$API.scc.record" :formConfig="formConfig" :paramsColums="paramsColums" :toolbarConfig="toolbarConfig" :columns="columns" v-bind="props.options">
+        <template #default_imgUrl="{ row }">
+            <template v-if="XEUtils.get(XEUtils.toStringJSON(row.features), 'bigImage.image')">
+                <vxe-image style="cursor: pointer;" :src="'/minio' + XEUtils.get(XEUtils.toStringJSON(row.features), 'bigImage.image')" width="40" height="40" :toolbar-config="imageToolbar"></vxe-image>
+            </template>
+        </template>
+        
+        <template #action="{ row }">
+            <el-button type="primary" link @click="table_edit(row)">
+                <template #icon><sc-iconify icon="ant-design:edit-outlined"></sc-iconify></template>修改
+            </el-button>
+            <el-button type="primary" link @click="table_del(row)">
+                <template #icon><sc-iconify icon="ant-design:delete-outlined"></sc-iconify></template>删除
+            </el-button>
+        </template>
+    </scTable>
+
+    <record-detail v-if="dialog" ref="recordRef" :projectId="props.isTemp ? 1 : TOOL.data.get('PROJECT_ID')" @success="refreshTable" @closed="dialog = false"></record-detail>
+</template>
+
+<script setup>
+import moment from "moment";
+import XEUtils from "xe-utils";
+import API from "@/api";
+import TOOL from "@/utils/tool";
+import { mapFormItemSelect, mapFormItemDatePicker } from "@/components/scTable/helper";
+import { dataSource, sccTypeDic, sccTypeUnitDic, objectToArray } from "@/utils/basicDic";
+import recordDetail from "./detail";
+
+const props = defineProps({
+    options: { type: Object, default: () => {} },
+    isTemp: { type: Boolean, default: false },
+    hideHandler: { type: Boolean, default: false }
+})
+const visible = computed(() => !props.isTemp);
+
+const radioConfig = reactive({
+    span: props.isTemp ? 5 : 6,
+    resetValue: 0,
+    options: [{ label: "全部", value: 0 }, { label: "报警数据", value: 1 }],
+    props: { filterable: false, clearable: false },
+    events: {
+        change: data => XEUtils.merge(formConfig.data, data)
+    }
+})
+
+const proConfig = reactive({
+    visible,
+    storageKey: "PROJECT",
+    resetValue: TOOL.data.get("PROJECT_ID"),
+    optionProps: { label: "projectName", value: "fpiId" },
+    events: {
+        change: data => XEUtils.assign(formConfig.data, { ...data, mountedId: null })
+    }
+})
+
+const mountedConfig = reactive({
+    visible,
+    api: {
+        key: "scc.mounted",
+        query: {
+            projectId: computed(() => formConfig.data.projectId),
+            projectIdNot: 1
+        }
+    },
+    slot: {
+        style: { float: "right", paddingLeft: "6px", color: "#8492a6" }
+    },
+    optionProps: { label: "mountedName", value: "id", slot: ({ data }) => XEUtils.get(XEUtils.find(TOOL.data.get("PROJECT"), item => item.fpiId === data.projectId), "projectName") },
+    events: {
+        change: data => XEUtils.assign(formConfig.data, data)
+    }
+})
+
+const selectConfig = reactive({
+    options: objectToArray(sccTypeDic),
+    events: {
+        change: data => XEUtils.merge(formConfig.data, data)
+    }
+})
+
+const datetimerangeConfig = reactive({
+    span: 7,
+    resetValue: () => [moment().startOf("month").format("YYYY-MM-DD HH:mm:ss"), moment().format("YYYY-MM-DD HH:mm:ss")],
+    props: {
+        type: "datetimerange",
+        startPlaceholder: "开始时间",
+        endPlaceholder: "结束时间",
+        format: "YYYY-MM-DD HH:mm"
+    }
+})
+
+const toolbarConfig = reactive({
+    enabled: true,
+    print: false
+})
+
+const formConfig = reactive({
+    data: {
+        projectId: TOOL.data.get("PROJECT_ID"),
+        projectIdNot: 1,
+        isWarning: 0,
+        createTime: [moment().startOf("month").format("YYYY-MM-DD HH:mm:ss"), moment().format("YYYY-MM-DD HH:mm:ss")]
+    },
+    items: [
+        mapFormItemSelect("isWarning", "数据类型", radioConfig),
+        mapFormItemSelect("projectId", "所属项目", proConfig),
+        mapFormItemSelect("mountedId", "设备安装点", mountedConfig),
+        mapFormItemSelect("vtype", "监测类型", selectConfig),
+        mapFormItemDatePicker("createTime", "监测时间", datetimerangeConfig)
+    ]
+})
+
+const paramsColums = reactive([
+    { column: "projectId", field: visible.value ? "" : "projectIdNot" },
+    visible.value ? { column: "projectIdNot" } : {},
+    { column: "mountedId" },
+    { column: "isWarning" },
+    { column: "vtype" },
+    { column: "createTimeBegin", field: "createTime[0]" },
+    { column: "createTimeEnd", field: "createTime[1]" }
+])
+
+const columns = reactive([
+    { visible: !props.hideHandler, type: "checkbox", fixed: "left", width: 40 },
+    { type: "seq", fixed: "left", width: 60 },
+    { visible, type: "html", field: "projectName", title: "项目名称", minWidth: 160, sortable: true, formatter: ({ cellValue, row }) => cellValue || XEUtils.get(XEUtils.find(TOOL.data.get("PROJECT"), item => item.fpiId == row.projectId), "projectName") },
+    { visible, type: "html", field: "groundName", title: "工地场区", minWidth: 160, sortable: true },
+    { visible, type: "html", field: "mountedName", title: "设备安装点", minWidth: 160, sortable: true },
+    { type: "html", field: "vtype", title: "监测类型", minWidth: 100, sortable: true, formatter: ({ cellValue }) => XEUtils.get(sccTypeDic, cellValue, cellValue) },
+    { type: "html", field: "taskValue", title: "监测数值", minWidth: 100, sortable: true, formatter: ({ cellValue, row }) => cellValue || XEUtils.divide(XEUtils.get(row, "value"), 100) + XEUtils.get(sccTypeUnitDic, XEUtils.get(row, "vtype")) },
+    { type: "html", field: "createTime", title: "监测时间", minWidth: 160, sortable: true },
+    { visible, type: "html", field: "dataSource", title: "数据来源", fixed: "right", minWidth: 100, sortable: true, formatter: ({ cellValue }) => XEUtils.get(dataSource, cellValue, cellValue) },
+    { visible: !props.hideHandler, title: "操作", fixed: "right", width: 140, align: "center", slots: { default: "action" } }
+])
+
+const imageToolbar = reactive({
+    print: false,
+    download: true
+})
+
+// 显示隐藏 筛选表单
+const xGridTable = ref();
+const toggleFormEnabled = () => xGridTable.value.toggleFormEnabled();
+const getTableTotal = () => xGridTable.value.getTableData().tableData.length;
+
+const refreshTable = () => {
+    xGridTable.value.reloadColumn(columns);
+    xGridTable.value.searchData();
+}
+
+const recordRef = ref();
+const dialog = ref(false);
+
+const table_add = () => {
+    dialog.value = true;
+    nextTick(() => recordRef.value?.open());
+}
+
+const table_edit = row => {
+    dialog.value = true;
+    nextTick(() => recordRef.value?.setData(row));
+}
+
+const table_del = ({ id }) => {
+    ElMessageBox.confirm("是否确认删除该监测记录?", "删除警告", {
+        type: "warning",
+        confirmButtonText: "确定",
+        cancelButtonText: "取消"
+    }).then(() => {
+        API.scc.record.del({ id }).then(() => {
+            ElMessage.success("操作成功");
+            refreshTable();
+        });
+    });
+}
+
+defineExpose({
+    table_add,
+    refreshTable,
+    getTableTotal
+})
+</script>

+ 148 - 80
src/views/dataMock/standard/detail.vue

@@ -1,114 +1,187 @@
 <template>
-    <el-dialog v-model="visible" title="数据模拟" width="870" :close-on-click-modal="false" @closed="$emit('closed')">
-        <el-form ref="formRef" :model="form" :rules="rules" label-width="110px">
+    <el-dialog v-model="visible" title="数据模拟" fullscreen :close-on-click-modal="false" @closed="$emit('closed')">
+        <el-tabs v-model="apiKey">
+            <el-tab-pane label="参数配置" name="makeData"></el-tab-pane>
+            <el-tab-pane label="数据复制" name="copyData" disabled></el-tab-pane>
+        </el-tabs>
+
+        <el-form ref="formRef" :model="form" :rules="rules" label-width="126">
             <el-row>
                 <el-col :md="12" :xs="24">
-                    <el-form-item label="时间范围" prop="dateRange">
-                        <el-date-picker v-model="form.dateRange" type="daterange" :clearable="false" :shortcuts="shortcuts" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
+                    <el-form-item label="模拟项目" prop="targetProjectId">
+                        <el-select v-model="form.targetProjectId" filterable placeholder="请选择模拟项目" @change="form.targetMountedId = null, dataTimeRange()">
+                            <el-option v-for="item in $TOOL.data.get('PROJECT')" :key="item.fpiId" :label="item.projectName" :value="item.fpiId"></el-option>
+                        </el-select>
+                    </el-form-item>
+                </el-col>
+                <el-col v-if="form.targetProjectId" :md="12" :xs="24">
+                    <el-form-item label="数据时间范围">
+                        <template v-if="XEUtils.isEmpty(acceptItem)">该项目未配置验收清单,<el-button type="primary" link @click="$router.push('/basic/acceptItems')">去配置</el-button></template>
+                        <template v-else-if="acceptItem.beginTime">{{ $TOOL.dateFormat(acceptItem.beginTime, "YY.M.D") }}<span>-{{ acceptItem.endTime && $TOOL.dateFormat(acceptItem.endTime, "YY.M.D") || "至今" }}</span></template>
+                        <template v-else>该项目未配置数据时间范围,<el-button type="primary" link @click="$router.push('/basic/project')">去配置</el-button></template>
                     </el-form-item>
                 </el-col>
                 <el-col :md="12" :xs="24">
-                    <el-form-item class="step-item" label="时间步长" prop="timeStep">
-                        <el-input-number v-model="form.timeStep" :min="0"
-                            :max="['second', 'minute'].includes(form.timeStepType) ? 60 : form.timeStepType == 'hour' ? 12 : Infinity" 
-                            :controls="false" placeholder="时间步长">
-                        </el-input-number>
-                        <el-form-item>
-                            <el-select v-model="form.timeStepType">
-                                <el-option label="秒" value="second"></el-option>
-                                <el-option label="分钟" value="minute"></el-option>
-                                <el-option label="小时" value="hour"></el-option>
-                                <el-option label="天" value="day"></el-option>
-                            </el-select>
-                        </el-form-item>
+                    <el-form-item label="模拟项目安装点" prop="targetMountedId">
+                        <el-select v-model="form.targetMountedId" filterable placeholder="请选择模拟项目安装点">
+                            <el-option v-for="item in filterTargetM" :key="item.id" :label="item.mountedName" :value="item.id"></el-option>
+                        </el-select>
                     </el-form-item>
                 </el-col>
                 <el-col :md="12" :xs="24">
-                    <el-form-item label="精度偏差" prop="precision">
-                        <el-input-number v-model="form.precision" :min="0" :max="2" :precision="2" :controls="false" placeholder="请输入精度偏差">
-                            <template #prefix>±</template>
-                        </el-input-number>
+                    <el-form-item label="模拟时间范围" prop="targetTime">
+                        <el-date-picker v-model="form.targetTime" type="datetimerange" :clearable="false" value-format="YYYY-MM-DD HH:mm:ss" :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]" :shortcuts="shortcuts" range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间"></el-date-picker>
                     </el-form-item>
                 </el-col>
+
                 <el-col :md="12" :xs="24">
-                    <el-form-item label="数据处理" prop="handler">
-                        <el-radio-group v-model="form.handler">
-                            <el-radio value="copy">重复新增</el-radio>
-                            <el-radio value="cover">数据覆盖</el-radio>
-                            <el-radio value="partly">部分覆盖</el-radio>
+                    <el-form-item label="数据类型" prop="dataSouce">
+                        <el-radio-group v-model="form.dataSouce">
+                            <el-radio value="normal">标准数据</el-radio>
+                            <el-radio value="alarm">报警数据</el-radio>
                         </el-radio-group>
                     </el-form-item>
                 </el-col>
-            </el-row>
+                <el-col :md="12" :xs="24">
+                    <el-form-item label="数据处理" prop="isCover">
+                        <el-radio-group v-model="form.isCover">
+                            <el-radio :value="false">重复新增</el-radio>
+                            <el-radio :value="true">数据覆盖</el-radio>
+                        </el-radio-group>
+                    </el-form-item>
+                </el-col>
+
+                <template v-if="form.dataSouce == 'normal'">
+                    <el-col :md="12" :xs="24">
+                        <el-form-item class="step-item" label="时间步长" prop="timeStepSec">
+                            <el-input-number v-model="form.timeStepSec" :min="0" :controls="false" placeholder="时间步长"></el-input-number>
 
-            <el-form-item label="数据设置">
-                <sc-form-table v-model="form.warnList" hideSeq>
-                    <el-table-column label="报警类型" prop="field" width="100" align="center"></el-table-column>
-                    <el-table-column class-name="threshold-cell" label="阈值" prop="threshold">
-                        <template #default="scope">
-                            <el-input-number v-model="scope.row.min" :min="0" :max="scope.row.max" :precision="2" :controls="false" placeholder="最小值"></el-input-number>
-                            <div class="symbol">至</div>
-                            <el-input-number v-model="scope.row.max" :min="scope.row.min" :precision="2" :controls="false" placeholder="最大值"></el-input-number>
-                        </template>
-                    </el-table-column>
-                    <el-table-column label="报警条数" prop="count" width="120" align="center">
-                        <template #default="scope">
-                            <el-input-number v-model="scope.row.count" :min="0" :controls="false" placeholder="请输入报警条数"></el-input-number>
-                        </template>
-                    </el-table-column>
-                </sc-form-table>
-            </el-form-item>
+                            <el-radio-group v-model="form.timeStepType" @change="stepTypeChange">
+                                <el-radio value="second">秒</el-radio>
+                                <el-radio value="minute">分钟</el-radio>
+                            </el-radio-group>
+                        </el-form-item>
+                    </el-col>
+                    <el-col :md="12" :xs="24">
+                        <el-form-item label="数据波动" prop="floatNumber">
+                            <el-input-number v-model="form.floatNumber" :min="0" :precision="2" :controls="false" placeholder="请输入数据波动">
+                                <template #prefix>±</template>
+                            </el-input-number>
+                        </el-form-item>
+                    </el-col>
+                </template>
+                <template v-if="form.dataSouce == 'alarm'">
+                    <el-col :md="12" :xs="24">
+                        <el-form-item label="温度报警数" prop="temWarnNum">
+                            <el-input-number v-model="form.temWarnNum" :min="0" :controls="false" placeholder="请输入温度报警数"></el-input-number>
+                        </el-form-item>
+                    </el-col>
+                    <el-col :md="12" :xs="24">
+                        <el-form-item label="湿度报警数" prop="humWarnNum">
+                            <el-input-number v-model="form.humWarnNum" :min="0" :controls="false" placeholder="请输入湿度报警数"></el-input-number>
+                        </el-form-item>
+                    </el-col>
+                </template>
+            </el-row>
         </el-form>
 
         <template #footer>
-            <el-button :loading="isSaving" type="primary" auto-insert-space @click="submit">保存</el-button>
+            <el-button :loading="isSaving" type="primary" auto-insert-space @click="submit()">提交</el-button>
+            <el-button v-if="form.source == 'other'" :loading="isSaving" type="primary" auto-insert-space @click="submit('template')">保存为模版</el-button>
             <el-button auto-insert-space @click="visible = false">取消</el-button>
         </template>
     </el-dialog>
 </template>
 
 <script setup>
-import moment from "moment";
 import XEUtils from "xe-utils";
+import API from "@/api";
+import TOOL from "@/utils/tool";
+import { rangeShortcuts } from "@/utils/shortcuts";
 
+const route = useRoute();
 const $emit = defineEmits(["success", "closed"]);
+const apiKey = ref("makeData");
 const visible = ref(false);
 const isSaving = ref(false);
 
-const shortcuts = [
-    { text: "上周", value: () => [moment().subtract(1, "week"), moment()] },
-    { text: "上月", value: () => [moment().subtract(1, "month"), moment()] },
-    { text: "去年", value: () => [moment().subtract(1, "year"), moment()] }
-]
-
+const shortcuts = rangeShortcuts();
 const form = ref({
-    id: null,
-    dateRange: null,
+    targetProjectId: TOOL.data.get("PROJECT_ID"),
+    targetMountedId: null,
+    targetTime: ["2025-08-28 00:00:00", "2025-08-28 00:59:59"],
+    dataSouce: "normal",
+    isCover: false,
+    timeStepSec: 3,
     timeStepType: "minute",
-    timeStep: 3,
-    precision: null,
-    handler: "copy",
-    warnList: [
-        { field: "温度 (℃)", min: 18, max: 22, count: 0 },
-        { field: "湿度 (%rh)", min: 95, max: 100, count: 0 }
-    ]
+    floatNumber: 1,
+    temWarnNum: null,
+    humWarnNum: null
 });
 
 const rules = reactive({
-    dateRange: [{ required: true, message: "请选择时间范围" }],
-    timeStep: [{ required: true, message: "请输入时间步长" }],
-    precision: [{ required: true, message: "请输入精度偏差" }],
-    warnList: [{ required: true, validator: (rule, value, callback) => {
-        callback();
-    }}]
-})
+    targetProjectId: [{ required: true, message: "请选择模拟项目" }],
+    targetMountedId: [{ required: true, message: "请选择模拟项目安装点" }],
+    targetTime: [{ required: true, message: "请选择模拟时间范围" }],
+    dataSouce: [{ required: true }],
+    isCover: [{ required: true }],
+    timeStepSec: [{ required: true, message: "请输入时间步长" }],
+    floatNumber: [{ required: true, message: "请输入数据波动" }],
+    temWarnNum: [{ required: true, message: "请输入温度报警数" }],
+    humWarnNum: [{ required: true, message: "请输入湿度报警数" }]
+});
 
-const open = () => visible.value = true;
-const formRef = ref();
+const acceptItem = ref({});
+const dataTimeRange = async () => {
+    const query = {
+        projectId: form.value.targetProjectId,
+        itemName: XEUtils.last(route.meta.title.split("-"))
+    }
+    const res = await API.system.project.bindItem.judgment(query);
+    acceptItem.value = res || {};
+}
 
-const submit = () => {
+const mounteds = ref([]);
+const filterTargetM = computed(() => form.value.targetProjectId ? XEUtils.filter(mounteds.value, item => item.projectId == form.value.targetProjectId) : []);
+const fetchMounted = async () => {
+    const res = await API.scc.mounted.get();
+    mounteds.value = res || [];
+}
+
+const open = () => {
+    visible.value = true;
+    TOOL.data.get("PROJECT_ID") && dataTimeRange();
+    fetchMounted();
+}
+
+const stepTypeChange = e => {
+    if (e == "minute") XEUtils.set(form.value, "timeStepSec", XEUtils.floor(XEUtils.divide(form.value.timeStepSec, 60)));
+    if (e == "second") XEUtils.set(form.value, "timeStepSec", XEUtils.multiply(form.value.timeStepSec, 60));
+}
+
+const formRef = ref();
+const submit = key => {
     formRef.value.validate(valid => {
         if (valid) {
+            const data = XEUtils.pick(form.value, "targetProjectId", "targetMountedId", "isCover");
+            XEUtils.set(data, "targetBeginTime", XEUtils.first(form.value.targetTime));
+            XEUtils.set(data, "targetEndTime", XEUtils.last(form.value.targetTime));
+            
+            if (form.value.dataSouce == "normal") {
+                XEUtils.set(data, "floatNumber", XEUtils.multiply(form.value.floatNumber, 100));
+                XEUtils.set(data, "timeStepSec", form.value.timeStepType == "minute" ? XEUtils.multiply(form.value.timeStepSec, 60) : form.value.timeStepSec);
+            } else {
+                XEUtils.set(data, "temWarnNum", form.value.temWarnNum);
+                XEUtils.set(data, "humWarnNum", form.value.humWarnNum);
+            }
+
+            isSaving.value = true;
+            API.scc.dataMock[apiKey.value][form.value.dataSouce](data).then(() => {
+                isSaving.value = false;
+                ElMessage.success("操作成功");
+                visible.value = false;
+                $emit("success");
+            }).catch(() => isSaving.value = false);
         } else {
             return false;
         }
@@ -121,20 +194,15 @@ defineExpose({
 </script>
 
 <style lang="scss" scoped>
-.el-form {padding-right: calc(var(--el-dialog-padding-primary) + var(--el-message-close-size, 16px));}
+.el-form {margin-top: 5px;padding-right: var(--el-message-close-size, 16px);}
+.el-form-item .el-radio-group {flex-wrap: nowrap;}
 
 .el-form-item .el-input-number {width: 100%;}
 .el-form-item .el-input-number :deep(.el-input__prefix) {margin-right: 8px;}
 .el-form-item .el-input-number :deep(.el-input__inner) {text-align: unset;}
-.el-form-item .el-input-number + .el-form-item {margin-left: 20px;}
-    
+
 .el-form-item.step-item {
     .el-input-number {flex: 1;}
-    .el-form-item {width: 100px;}
+    .el-radio-group {margin-left: 20px;}
 }
-
-.el-form-item .el-radio-group {flex-wrap: nowrap;}
-
-.el-form-item :deep(.el-table) .threshold-cell .cell {display: flex;justify-content: center;align-items: center;}
-.el-form-item :deep(.el-table) .threshold-cell .cell .symbol {margin: 0 10px;}
 </style>

+ 20 - 9
src/views/dataMock/standard/index.vue

@@ -1,33 +1,44 @@
 <template>
 	<el-container class="is-vertical">
-        <sc-page-header @add="dock_add"></sc-page-header>
+        <sc-page-header addText="数据模拟" @add="mock_add">
+            <template #extra-right>
+                <el-button v-if="activeName == 'record' || activeName == 'template'" type="primary" @click="table_add">数据录入</el-button>
+            </template>
+        </sc-page-header>
 
         <el-tabs v-model="activeName">
-            <el-tab-pane v-for="(label, key) in XEUtils.omit(workerStates, 'calendar')" :key="key" :label="label" :name="key"></el-tab-pane>
+            <el-tab-pane v-for="(label, key) in workerStates" :key="key" :label="label" :name="key"></el-tab-pane>
         </el-tabs>
 
-        <component :is="allcomp[activeName]" />
+        <component ref="componentRef" :is="allcomp[activeName]" taskType="scc" />
 	</el-container>
 
     <mock-detail v-if="dialog" ref="mockRef" @success="refreshState" @closed="dialog = false"></mock-detail>
 </template>
 
 <script setup>
-import XEUtils from "xe-utils";
-import { workerStates } from "../main";
-import allcomp from "./components";
+import { workerStates } from "./main";
+import comp from "./components";
+import monos from "@/views/dataMock/tasks/monos";
 import mockDetail from "./detail";
 
-const activeName = ref("monos");
-const refreshState = () => {}
+const allcomp = { ...comp, monos };
+const activeName = ref("record");
 
+const componentRef = ref();
 const mockRef = ref();
 const dialog = ref(false);
 
-const dock_add = () => {
+const table_add = () => componentRef.value.table_add();
+
+const mock_add = () => {
     dialog.value = true;
     nextTick(() => mockRef.value?.open());
 }
+
+const refreshState = () => {
+    if (activeName.value == "monos") setTimeout(() => componentRef.value.refreshTable(), 2000);
+}
 </script>
 
 <style lang="scss" scoped>

+ 5 - 0
src/views/dataMock/standard/main.js

@@ -0,0 +1,5 @@
+export const workerStates = {
+    record: "设备监控",
+    monos: "任务中心",
+    threshold: "阈值设置"
+}

+ 0 - 47
src/views/dataMock/standard/mono/index.vue

@@ -1,47 +0,0 @@
-<template>
-    <el-dialog v-model="visible" title="任务详情" width="80%" @closed="$emit('closed')">
-        <!-- <scTable :apiObj="formConfig.data.deviceCode && $API.passqrcode.online" min-height="108" max-height="600" framework="zeroLite" :formConfig="formConfig" :paramsColums="paramsColums" :columns="columns"></scTable> -->
-        <scTable :maxHeight="600" :options="options">
-            <template #expand_content="{ row }">
-                <table-expand :rowData="row.monos"></table-expand>
-            </template>
-            <template #progress_content="{ row }">
-                <el-progress text-inside :stroke-width="16" :status="row.status == '已完成' ? 'success' : row.status == '执行失败' ? 'exception' : ''" :percentage="row.progress" />
-            </template>
-        </scTable>
-    </el-dialog>
-</template>
-
-<script setup>
-import XEUtils from "xe-utils";
-import TOOL from "@/utils/tool";
-import { defaultGroups } from "../../main";
-
-import tableExpand from "./tableExpand";
-
-const visible = ref(false);
-const open = data => {
-    visible.value = true;
-    options.data = data ? [XEUtils.first(XEUtils.get(defaultGroups, "groups.000.monos"))] : XEUtils.get(defaultGroups, "groups.000.monos")
-}
-
-const options = reactive({
-    minHeight: 108,
-    data: [],
-    formConfig: { enabled: false },
-    pagerConfig: { enabled: false },
-    columns: [
-        { type: "expand", fixed: "left", width: 50, align: "center", slots: { content: "expand_content" } },
-        { field: "option", title: "任务类型", minWidth: 100 },
-        { field: "createTime", title: "触发时间", minWidth: 160, formatter: ({ cellValue }) => TOOL.dateFormat(cellValue) },
-        { field: "status", title: "任务状态", minWidth: 100 },
-        { field: "executeTimes", title: "执行次数", minWidth: 80 },
-        { field: "progress", title: "执行进度", minWidth: 250, slots: { default: 'progress_content' } },
-        { field: "reason", title: "失败原因", minWidth: 160 }
-    ]
-})
-
-defineExpose({
-    open
-})
-</script>

+ 0 - 33
src/views/dataMock/standard/mono/tableExpand.vue

@@ -1,33 +0,0 @@
-<template>
-    <scTable :maxHeight="192" :options="options">
-        <template #progress_content="{ row }">
-            <el-progress text-inside :stroke-width="16" :status="row.status == '已完成' ? 'success' : row.status == '执行失败' ? 'exception' : ''" :percentage="row.progress" />
-        </template>
-    </scTable>
-</template>
-
-<script setup>
-import TOOL from "@/utils/tool";
-
-const options = reactive({
-    minHeight: 108,
-    data: useAttrs().rowData,
-    formConfig: { enabled: false },
-    pagerConfig: { enabled: false },
-    columns: [
-        { field: "dateRange", title: "时间范围", minWidth: 160 },
-        { field: "timeStep", title: "时间步长", minWidth: 100 },
-        { field: "precision", title: "精度偏差", minWidth: 100 },
-        { field: "handler", title: "数据处理", minWidth: 80 },
-        { field: "createTime", title: "触发时间", minWidth: 160, formatter: ({ cellValue }) => TOOL.dateFormat(cellValue) },
-        { field: "status", title: "任务状态", minWidth: 100 },
-        { field: "executeTimes", title: "执行次数", minWidth: 80 },
-        { field: "progress", title: "执行进度", minWidth: 250, slots: { default: 'progress_content' } },
-        { field: "reason", title: "失败原因", minWidth: 160 }
-    ]
-})
-</script>
-
-<style scoped>
-    .el-main {padding: 0;}
-</style>

+ 8 - 2
src/views/dataMock/ugliAi/detail.vue

@@ -1,5 +1,10 @@
 <template>
     <el-dialog v-model="visible" title="数据模拟" fullscreen :close-on-click-modal="false" @closed="$emit('closed')">
+        <el-tabs v-model="apiKey">
+            <el-tab-pane label="参数配置" name="makeData" disabled></el-tab-pane>
+            <el-tab-pane label="数据复制" name="copyData"></el-tab-pane>
+        </el-tabs>
+
         <el-form ref="formRef" :model="form" :rules="rules" label-width="126">
             <el-row>
                 <el-col :md="12" :xs="24">
@@ -99,6 +104,7 @@ import dataTable from "./components/record";
 
 const route = useRoute();
 const $emit = defineEmits(["success", "closed"]);
+const apiKey = ref("copyData");
 const visible = ref(false);
 const isSaving = ref(false);
 
@@ -183,7 +189,7 @@ const submit = key => {
             }
 
             isSaving.value = true;
-            API.ugliAi.copyData.add(data).then(() => {
+            API.ugliAi.dataMock[apiKey.value](data).then(() => {
                 isSaving.value = false;
                 ElMessage.success("操作成功");
                 visible.value = false;
@@ -201,7 +207,7 @@ defineExpose({
 </script>
 
 <style lang="scss" scoped>
-.el-form {padding-right: var(--el-message-close-size, 16px);}
+.el-form {margin-top: 5px;padding-right: var(--el-message-close-size, 16px);}
 .el-form-item .el-radio-group {flex-wrap: nowrap;}
 .el-form :deep(.el-main) {padding-right: 0;padding-bottom: 0;}
 </style>

+ 0 - 1
src/views/dataMock/ugliAi/index.vue

@@ -38,7 +38,6 @@ const mock_add = () => {
 
 const refreshState = () => {
     if (activeName.value == "monos") setTimeout(() => componentRef.value.refreshTable(), 2000);
-    activeName.value = "monos";
 }
 </script>