gaoluyang
2 天以前 1159f2e96a1a1c95c6f8b478f8353357831458de
新疆马铃薯
1.代码更新
已修改5个文件
1756 ■■■■■ 文件已修改
src/views/equipmentManagement/inspectionManagement/components/formDia.vue 626 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/ledger/Form.vue 205 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/measurementEquipment/components/formDia.vue 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/measurementEquipment/filesDia.vue 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/upkeep/Form/formDia.vue 781 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/inspectionManagement/components/formDia.vue
@@ -1,48 +1,89 @@
<template>
  <div>
    <el-dialog :title="operationType === 'add' ? '新增巡检任务' : '编辑巡检任务'"
               v-model="dialogVisitable" width="800px" @close="cancel">
    <el-dialog
      v-model="dialogVisitable"
      :title="operationType === 'add' ? '新增巡检任务' : '编辑巡检任务'"
      width="800px"
      @close="cancel"
    >
      <el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
        <el-row>
          <el-col :span="12">
            <el-form-item label="设备名称" prop="taskId">
              <el-select v-model="form.taskId" @change="setDeviceModel">
            <el-form-item label="所属区域" prop="areaId">
              <el-tree-select
                v-model="form.areaId"
                :data="areaOptions"
                :props="areaTreeProps"
                node-key="id"
                value-key="id"
                check-strictly
                clearable
                filterable
                placeholder="请选择所属区域"
                style="width: 100%"
                @change="handleAreaChange"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="设备名称" prop="deviceLedgerIds">
              <el-select
                v-model="form.deviceLedgerIds"
                multiple
                collapse-tags
                collapse-tags-tooltip
                clearable
                filterable
                placeholder="请选择设备"
                style="width: 100%"
                @change="setDeviceModels"
              >
                <el-option
                  v-for="(item, index) in deviceOptions"
                  :key="index"
                  v-for="item in deviceOptions"
                  :key="item.id"
                  :label="item.deviceName"
                  :value="item.id"
                ></el-option>
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="巡检人" prop="inspector">
              <el-select v-model="form.inspector" placeholder="请选择" multiple clearable>
                <el-option v-for="item in userList" :label="item.nickName" :value="item.userId" :key="item.userId"/>
                <el-option
                  v-for="item in userList"
                  :key="item.userId"
                  :label="item.nickName"
                  :value="item.userId"
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="巡检项目" prop="inspectionProject">
              <el-input v-model="form.inspectionProject" placeholder="请输入巡检项目" type="textarea" :autosize="{ minRows: 2, maxRows: 6 }" />
            <el-form-item label="规格型号">
              <el-input
                v-model="form.deviceModel"
                placeholder="自动带出规格型号"
                disabled
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="备注" prop="remarks">
              <el-input v-model="form.remarks" placeholder="请输入备注" type="textarea" :autosize="{ minRows: 2, maxRows: 6 }" />
              <el-input v-model="form.remarks" placeholder="请输入备注" type="textarea" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="是否启用" prop="isEnabled">
              <el-radio-group v-model="form.isEnabled">
                <el-radio :value="1">是</el-radio>
                <el-radio :value="0">否</el-radio>
              </el-radio-group>
              <el-switch
                v-model="form.isEnabled"
                :active-value="1"
                :inactive-value="0"
              />
            </el-form-item>
          </el-col>
        </el-row>
@@ -50,55 +91,64 @@
          <el-col :span="12">
            <el-form-item label="任务频率" prop="frequencyType">
              <el-select v-model="form.frequencyType" placeholder="请选择" clearable>
                <el-option label="每日" value="DAILY"/>
                <el-option label="每周" value="WEEKLY"/>
                <el-option label="每月" value="MONTHLY"/>
                <!-- <el-option label="季度" value="QUARTERLY"/> -->
                <el-option label="每日" value="DAILY" />
                <el-option label="每周" value="WEEKLY" />
                <el-option label="每月" value="MONTHLY" />
                <el-option label="每年" value="YEARLY" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12" v-if="form.frequencyType === 'DAILY' && form.frequencyType">
          <el-col :span="12" v-if="form.frequencyType === 'DAILY'">
            <el-form-item label="日期" prop="frequencyDetail">
              <el-time-picker v-model="form.frequencyDetail" placeholder="选择时间" format="HH:mm"
                              value-format="HH:mm" />
            </el-form-item>
          </el-col>
          <el-col :span="12" v-if="form.frequencyType === 'WEEKLY' && form.frequencyType">
            <el-form-item label="日期" prop="frequencyDetail">
              <el-select v-model="form.week" placeholder="请选择" clearable style="width: 50%">
                <el-option label="周一" value="MON"/>
                <el-option label="周二" value="TUE"/>
                <el-option label="周三" value="WED"/>
                <el-option label="周四" value="THU"/>
                <el-option label="周五" value="FRI"/>
                <el-option label="周六" value="SAT"/>
                <el-option label="周日" value="SUN"/>
              </el-select>
              <el-time-picker v-model="form.time" placeholder="选择时间" format="HH:mm"
                              value-format="HH:mm"  style="width: 50%"/>
            </el-form-item>
          </el-col>
          <el-col :span="12" v-if="form.frequencyType === 'MONTHLY' && form.frequencyType">
            <el-form-item label="日期" prop="frequencyDetail">
              <el-date-picker
                  v-model="form.frequencyDetail"
                  type="datetime"
                  clearable
                  placeholder="选择开始日期"
                  format="DD,HH:mm"
                  value-format="DD,HH:mm"
              <el-time-picker
                v-model="form.frequencyDetail"
                placeholder="选择时间"
                format="HH:mm"
                value-format="HH:mm"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12" v-if="form.frequencyType === 'QUARTERLY' && form.frequencyType">
          <el-col :span="12" v-if="form.frequencyType === 'WEEKLY'">
            <el-form-item label="日期" prop="frequencyDetail">
              <el-select v-model="form.week" placeholder="请选择" clearable style="width: 50%">
                <el-option label="周一" value="MON" />
                <el-option label="周二" value="TUE" />
                <el-option label="周三" value="WED" />
                <el-option label="周四" value="THU" />
                <el-option label="周五" value="FRI" />
                <el-option label="周六" value="SAT" />
                <el-option label="周日" value="SUN" />
              </el-select>
              <el-time-picker
                v-model="form.time"
                placeholder="选择时间"
                format="HH:mm"
                value-format="HH:mm"
                style="width: 50%"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12" v-if="form.frequencyType === 'MONTHLY'">
            <el-form-item label="日期" prop="frequencyDetail">
              <el-date-picker
                  v-model="form.frequencyDetail"
                  type="datetime"
                  clearable
                  placeholder="选择开始日期"
                  format="MM,DD,HH:mm"
                  value-format="MM,DD,HH:mm"
                v-model="form.frequencyDetail"
                type="datetime"
                clearable
                placeholder="选择开始日期"
                format="DD,HH:mm"
                value-format="DD,HH:mm"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12" v-if="form.frequencyType === 'YEARLY'">
            <el-form-item label="日期" prop="frequencyDetail">
              <el-date-picker
                v-model="form.frequencyDetail"
                type="datetime"
                clearable
                placeholder="选择开始日期"
                format="MM,DD,HH:mm"
                value-format="MM,DD,HH:mm"
              />
            </el-form-item>
          </el-col>
@@ -115,192 +165,312 @@
</template>
<script setup>
import {reactive, ref, getCurrentInstance, toRefs} from "vue";
import useUserStore from '@/store/modules/user'
import {addOrEditTimingTask} from "@/api/inspectionManagement/index.js";
import {userListNoPageByTenantId} from "@/api/system/user.js";
import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
import { getCurrentInstance, reactive, ref, toRefs } from "vue";
import useUserStore from "@/store/modules/user";
import { addOrEditTimingTask } from "@/api/inspectionManagement/index.js";
import { userListNoPageByTenantId } from "@/api/system/user.js";
import {
  getDeviceAreaTree,
  getDeviceAreaTreeWithDevices,
} from "@/api/equipmentManagement/deviceArea";
const { proxy } = getCurrentInstance()
const emit = defineEmits()
const userStore = useUserStore()
const { proxy } = getCurrentInstance();
const emit = defineEmits(["closeDia"]);
const userStore = useUserStore();
const dialogVisitable = ref(false);
const operationType = ref('add');
const operationType = ref("add");
const areaOptions = ref([]);
const deviceOptions = ref([]);
const data = reactive({
  form: {
    taskId: undefined,
    taskName: undefined,
    inspector: '',
    inspectorIds: '',
    inspectionProject: '',
    isEnabled: 1,
    remarks: '',
    frequencyType: '',
    frequencyDetail: '',
    week: '',
    time: ''
  },
    rules: {
        taskId: [{ required: true, message: "请选择设备", trigger: "change" },],
        inspector: [{ required: true, message: "请输入巡检人", trigger: "blur" },],
        dateStr: [{ required: true, message: "请选择登记时间", trigger: "change" }],
        frequencyType: [{ required: true, message: "请选择任务频率", trigger: "change" }],
        frequencyDetail: [
            {
                required: true,
                message: "请选择日期",
                trigger: "change",
                validator: (rule, value, callback) => {
                    if (!form.value.frequencyType) {
                        callback()
                        return
                    }
                    if (form.value.frequencyType === 'WEEKLY') {
                        if (!form.value.week || !form.value.time) {
                            callback(new Error("请选择日期和时间"))
                        } else {
                            callback()
                        }
                    } else {
                        if (!value) {
                            callback(new Error("请选择日期"))
                        } else {
                            callback()
                        }
                    }
                }
            }
        ],
        week: [
            {
                required: true,
                message: "请选择星期",
                trigger: "change",
                validator: (rule, value, callback) => {
                    if (form.value.frequencyType === 'WEEKLY' && !value) {
                        callback(new Error("请选择星期"))
                    } else {
                        callback()
                    }
                }
            }
        ],
        time: [
            {
                required: true,
                message: "请选择时间",
                trigger: "change",
                validator: (rule, value, callback) => {
                    if (form.value.frequencyType === 'WEEKLY' && !value) {
                        callback(new Error("请选择时间"))
                    } else {
                        callback()
                    }
                }
            }
        ]
    }
})
const { form, rules } = toRefs(data)
const userList = ref([])
const loadDeviceName = async () => {
  const { data } = await getDeviceLedger();
  deviceOptions.value = data;
const userList = ref([]);
const areaTreeProps = {
  label: "areaName",
  children: "children",
};
const setDeviceModel = (id) => {
  const option = deviceOptions.value.find((item) => item.id === id);
  if (option) {
    form.value.taskName = option.deviceName;
  }
}
const data = reactive({
  form: {
    areaId: undefined,
    taskId: undefined,
    taskIds: [],
    taskIdsStr: undefined,
    deviceLedgerIds: [],
    deviceLedgerIdsStr: undefined,
    taskName: undefined,
    deviceModel: undefined,
    inspector: [],
    inspectorIds: "",
    remarks: "",
    isEnabled: 1,
    frequencyType: "",
    frequencyDetail: "",
    week: "",
    time: "",
  },
  rules: {
    areaId: [{ required: true, message: "请选择所属区域", trigger: "change" }],
    deviceLedgerIds: [{ required: true, message: "请选择设备", trigger: "change" }],
    inspector: [{ required: true, message: "请选择巡检人", trigger: "change" }],
    frequencyType: [{ required: true, message: "请选择任务频率", trigger: "change" }],
    frequencyDetail: [
      {
        required: true,
        trigger: "change",
        validator: (rule, value, callback) => {
          if (!form.value.frequencyType) {
            callback();
            return;
          }
          if (form.value.frequencyType === "WEEKLY") {
            if (!form.value.week || !form.value.time) {
              callback(new Error("请选择日期和时间"));
            } else {
              callback();
            }
            return;
          }
          if (!value) {
            callback(new Error("请选择日期"));
            return;
          }
          callback();
        },
      },
    ],
  },
});
// 打开弹框
const { form, rules } = toRefs(data);
const loadAreaTree = async () => {
  const { data } = await getDeviceAreaTree();
  areaOptions.value = Array.isArray(data) ? data : [];
};
const normalizeIdList = (value) => {
  if (Array.isArray(value)) {
    return value
      .map((item) => Number(item))
      .filter((item) => Number.isFinite(item));
  }
  if (typeof value === "string") {
    return value
      .split(",")
      .map((item) => Number(item.trim()))
      .filter((item) => Number.isFinite(item));
  }
  if (value !== undefined && value !== null && value !== "") {
    const numericValue = Number(value);
    return Number.isFinite(numericValue) ? [numericValue] : [];
  }
  return [];
};
const getNodeDevices = (node) => {
  const candidates = [
    node?.deviceList,
    node?.devices,
    node?.deviceLedgerList,
    node?.deviceLedgers,
    node?.ledgerList,
    node?.ledgers,
  ];
  return candidates.find((item) => Array.isArray(item)) || [];
};
const normalizeDevice = (item) => ({
  ...item,
  id: item.id ?? item.deviceLedgerId,
  deviceName: item.deviceName ?? item.name,
  deviceModel: item.deviceModel ?? item.model,
});
const collectDevices = (node) => {
  const currentDevices = getNodeDevices(node).map(normalizeDevice);
  const childDevices = (node?.children || []).flatMap((child) =>
    collectDevices(child)
  );
  const deviceMap = new Map();
  [...currentDevices, ...childDevices].forEach((item) => {
    if (item?.id !== undefined && item?.id !== null) {
      deviceMap.set(Number(item.id), item);
    }
  });
  return Array.from(deviceMap.values());
};
const findAreaNode = (nodes, areaId) => {
  for (const node of nodes || []) {
    if (Number(node.id) === Number(areaId)) {
      return node;
    }
    const target = findAreaNode(node.children, areaId);
    if (target) {
      return target;
    }
  }
  return null;
};
const loadDevicesByArea = async (areaId) => {
  if (!areaId) {
    deviceOptions.value = [];
    return;
  }
  const { data } = await getDeviceAreaTreeWithDevices();
  const treeData = Array.isArray(data) ? data : [];
  const currentNode = findAreaNode(treeData, areaId);
  deviceOptions.value = currentNode ? collectDevices(currentNode) : [];
};
const syncDeviceFields = (deviceIds) => {
  const selectedIds = normalizeIdList(deviceIds);
  const selectedDevices = selectedIds
    .map((deviceId) =>
      deviceOptions.value.find((item) => Number(item.id) === Number(deviceId))
    )
    .filter(Boolean);
  form.value.deviceLedgerIds = selectedIds;
  form.value.deviceLedgerIdsStr = selectedIds.join(",");
  form.value.taskIds = [...selectedIds];
  form.value.taskIdsStr = selectedIds.join(",");
  form.value.taskId = selectedIds[0];
  form.value.taskName = selectedDevices
    .map((item) => item.deviceName)
    .filter(Boolean)
    .join(",");
  form.value.deviceModel = selectedDevices
    .map((item) => item.deviceModel || "-")
    .join(",");
};
const setDeviceModels = (deviceIds) => {
  syncDeviceFields(deviceIds);
};
const handleAreaChange = async (areaId) => {
  form.value.taskId = undefined;
  form.value.taskIds = [];
  form.value.taskIdsStr = undefined;
  form.value.deviceLedgerIds = [];
  form.value.deviceLedgerIdsStr = undefined;
  form.value.taskName = undefined;
  form.value.deviceModel = undefined;
  await loadDevicesByArea(areaId);
};
const resetForm = () => {
  if (proxy.$refs.formRef) {
    proxy.$refs.formRef.resetFields();
  }
  form.value = {
    areaId: undefined,
    taskId: undefined,
    taskIds: [],
    taskIdsStr: undefined,
    deviceLedgerIds: [],
    deviceLedgerIdsStr: undefined,
    taskName: undefined,
    deviceModel: undefined,
    inspector: [],
    inspectorIds: "",
    remarks: "",
    isEnabled: 1,
    frequencyType: "",
    frequencyDetail: "",
    week: "",
    time: "",
  };
};
const openDialog = async (type, row) => {
  dialogVisitable.value = true
  operationType.value = type
  // 重置表单
  dialogVisitable.value = true;
  operationType.value = type;
  resetForm();
  // 加载用户列表
  userListNoPageByTenantId().then((res) => {
    userList.value = res.data;
  });
  // 加载设备列表
  await loadDeviceName();
  if (type === 'edit' && row) {
    form.value = {...row}
    form.value.inspector = form.value.inspectorIds.split(',').map(Number)
    // 如果有设备ID,自动设置设备信息
    if (form.value.taskId) {
      setDeviceModel(form.value.taskId);
  await loadAreaTree();
  if (type === "edit" && row) {
    form.value = {
      ...form.value,
      ...row,
      isEnabled: Number(row.isEnabled ?? row.status ?? 1),
      inspector: row.inspectorIds
        ? String(row.inspectorIds)
            .split(",")
            .map((item) => Number(item))
            .filter((item) => Number.isFinite(item))
        : [],
    };
    form.value.deviceLedgerIds = normalizeIdList(
      row.deviceLedgerIds ??
        row.deviceLedgerIdsStr ??
        row.taskIds ??
        row.taskIdsStr ??
        row.taskId
    );
    form.value.deviceLedgerIdsStr = form.value.deviceLedgerIds.join(",");
    form.value.taskIds = [...form.value.deviceLedgerIds];
    form.value.taskIdsStr = form.value.deviceLedgerIds.join(",");
    form.value.taskId = form.value.deviceLedgerIds[0];
    if (form.value.areaId) {
      await loadDevicesByArea(form.value.areaId);
      syncDeviceFields(form.value.deviceLedgerIds);
    }
  }
}
};
// 关闭对话框
const cancel = () => {
  resetForm()
  dialogVisitable.value = false
  emit('closeDia')
}
  resetForm();
  dialogVisitable.value = false;
  emit("closeDia");
};
// 重置表单函数
const resetForm = () => {
  if (proxy.$refs.formRef) {
    proxy.$refs.formRef.resetFields()
  }
  // 重置表单数据确保设备信息正确重置
  form.value = {
    taskId: undefined,
    taskName: undefined,
    inspector: '',
    inspectorIds: '',
    inspectionProject: '',
    isEnabled: 1,
    remarks: '',
    frequencyType: '',
    frequencyDetail: '',
    week: '',
    time: ''
  }
}
// 提交表单
const submitForm = () => {
  proxy.$refs["formRef"].validate(async valid => {
    if (valid) {
      try {
        form.value.inspectorIds = form.value.inspector.join(',')
        delete form.value.inspector
        if (form.value.frequencyType === 'WEEKLY') {
          let frequencyDetail = ''
          frequencyDetail = form.value.week + ',' + form.value.time
          form.value.frequencyDetail = frequencyDetail
        }
        let res = await userStore.getInfo()
        form.value.registrantId = res.user.userId
        await addOrEditTimingTask(form.value)
        cancel()
        proxy.$modal.msgSuccess('提交成功')
      } catch (error) {
        proxy.$modal.msgError('提交失败,请重试')
      }
  proxy.$refs.formRef.validate(async (valid) => {
    if (!valid) {
      return;
    }
  })
}
defineExpose({ openDialog })
    try {
      syncDeviceFields(form.value.deviceLedgerIds);
      const payload = { ...form.value };
      payload.inspectorIds = Array.isArray(form.value.inspector)
        ? form.value.inspector.join(",")
        : "";
      delete payload.inspector;
      if (payload.frequencyType === "WEEKLY") {
        payload.frequencyDetail = `${payload.week},${payload.time}`;
      }
      const userInfo = await userStore.getInfo();
      payload.registrantId = userInfo.user.userId;
      payload.taskId = form.value.deviceLedgerIds[0];
      payload.taskIds = [...form.value.deviceLedgerIds];
      payload.taskIdsStr = form.value.deviceLedgerIds.join(",");
      payload.deviceLedgerIds = [...form.value.deviceLedgerIds];
      payload.deviceLedgerIdsStr = form.value.deviceLedgerIds.join(",");
      payload.taskName = form.value.taskName;
      payload.deviceModel = form.value.deviceModel || "-";
      payload.isEnabled = Number(form.value.isEnabled ?? 1);
      await addOrEditTimingTask(payload);
      cancel();
      proxy.$modal.msgSuccess("提交成功");
    } catch (error) {
      proxy.$modal.msgError("提交失败,请重试");
    }
  });
};
defineExpose({ openDialog });
</script>
<style scoped>
</style>
<style scoped></style>
src/views/equipmentManagement/ledger/Form.vue
@@ -2,6 +2,22 @@
  <el-form :model="form" label-width="120px" :rules="formRules" ref="formRef">
    <el-row :gutter="20">
      <el-col :span="12">
        <el-form-item label="所属区域" prop="areaId">
          <el-tree-select
            v-model="form.areaId"
            :data="areaOptions"
            :props="areaTreeProps"
            node-key="id"
            value-key="id"
            check-strictly
            clearable
            filterable
            placeholder="请选择所属区域"
            style="width: 100%"
          />
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="设备名称" prop="deviceName">
          <el-input v-model="form.deviceName" placeholder="请输入设备名称" />
        </el-form-item>
@@ -11,11 +27,11 @@
          <el-input v-model="form.deviceModel" placeholder="请输入规格型号" />
        </el-form-item>
      </el-col>
      <el-col :span="12">
      <!-- <el-col :span="12">
        <el-form-item label="设备品牌" prop="deviceBrand">
          <el-input v-model="form.deviceBrand" placeholder="请输入设备品牌" />
        </el-form-item>
      </el-col>
      </el-col> -->
      <el-col :span="12">
        <el-form-item label="设备类型" prop="type">
          <el-select
@@ -72,59 +88,62 @@
        <el-form-item label="数量" prop="number">
          <el-input-number :min="1" style="width: 100%"
            v-model="form.number"
                                                     disabled
            placeholder="请输入数量"
            @change="mathNum"
          />
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="含税单价" prop="taxIncludingPriceUnit">
          <el-input-number :step="0.01" :min="0" style="width: 100%"
            v-model="form.taxIncludingPriceUnit"
            placeholder="请输入含税单价"
            maxlength="10"
            @change="mathNum"
          />
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="含税总价" prop="taxIncludingPriceTotal">
          <el-input
            v-model="form.taxIncludingPriceTotal"
            placeholder="自动生成"
            type="number"
            disabled
          />
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="税率(%)" prop="taxRate">
          <el-select
            v-model="form.taxRate"
            placeholder="请选择"
            clearable
            @change="mathNum"
          >
            <el-option
              v-for="dict in tax_rate"
              :key="dict.value"
              :label="dict.label"
              :value="Number(dict.value)"
            />
          </el-select>
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="不含税总价" prop="unTaxIncludingPriceTotal">
          <el-input
            v-model="form.unTaxIncludingPriceTotal"
            placeholder="自动生成"
            type="number"
            disabled
          />
        </el-form-item>
      </el-col>
<!--      <el-col :span="12">-->
<!--        <el-form-item label="含税单价" prop="taxIncludingPriceUnit">-->
<!--          <el-input-number :step="0.01" :min="0" style="width: 100%"-->
<!--            v-model="form.taxIncludingPriceUnit"-->
<!--            placeholder="请输入含税单价"-->
<!--            maxlength="10"-->
<!--            @change="mathNum"-->
<!--          />-->
<!--        </el-form-item>-->
<!--      </el-col>-->
<!--      <el-col :span="12">-->
<!--        <el-form-item label="含税总价" prop="taxIncludingPriceTotal">-->
<!--          <el-input-->
<!--            v-model="form.taxIncludingPriceTotal"-->
<!--            placeholder="自动生成"-->
<!--            type="number"-->
<!--            disabled-->
<!--          />-->
<!--        </el-form-item>-->
<!--      </el-col>-->
<!--      <el-col :span="12">-->
<!--        <el-form-item label="税率(%)" prop="taxRate">-->
<!--          &lt;!&ndash; <el-input-->
<!--            v-model="form.taxRate"-->
<!--            placeholder="请输入税率"-->
<!--            type="number"-->
<!--          >-->
<!--            <template #append> % </template>-->
<!--          </el-input> &ndash;&gt;-->
<!--          <el-select-->
<!--            v-model="form.taxRate"-->
<!--            placeholder="请选择"-->
<!--            clearable-->
<!--            @change="mathNum"-->
<!--          >-->
<!--            <el-option label="1" :value="1" />-->
<!--            <el-option label="6" :value="6" />-->
<!--            <el-option label="13" :value="13" />-->
<!--          </el-select>-->
<!--        </el-form-item>-->
<!--      </el-col>-->
<!--      <el-col :span="12">-->
<!--        <el-form-item label="不含税总价" prop="unTaxIncludingPriceTotal">-->
<!--          <el-input-->
<!--            v-model="form.unTaxIncludingPriceTotal"-->
<!--            placeholder="自动生成"-->
<!--            type="number"-->
<!--            disabled-->
<!--          />-->
<!--        </el-form-item>-->
<!--      </el-col>-->
      <!-- <el-col :span="12">
        <el-form-item label="录入人" prop="createUser">
          <el-input v-model="form.createUser" placeholder="请输入录入人" />
@@ -156,16 +175,16 @@
                    />
                </el-form-item>
            </el-col>
      <el-col :span="24">
        <el-form-item label="设备图片" prop="storageBlobDTOs">
          <AttachmentUploadImage
            v-model:fileList="fileList"
            :limit="20"
            :fileSize="5"
            :buttonText="'上传图片'"
          />
        </el-form-item>
      </el-col>
            <el-col :span="12">
                <el-form-item label="物联设备" prop="isIotDevice">
                    <el-switch v-model="form.isIotDevice" :active-value="1" :inactive-value="0" />
                </el-form-item>
            </el-col>
            <el-col :span="12" v-if="form.isIotDevice === 1">
                <el-form-item label="外部编码" prop="externalCode">
                    <el-input v-model="form.externalCode" placeholder="请输入外部编码" />
                </el-form-item>
            </el-col>
    </el-row>
  </el-form>
</template>
@@ -174,23 +193,25 @@
import useFormData from "@/hooks/useFormData";
// import useUserStore from "@/store/modules/user";
import { getLedgerById } from "@/api/equipmentManagement/ledger";
import { getDeviceAreaTree } from "@/api/equipmentManagement/deviceArea";
import dayjs from "dayjs";
import {
  calculateTaxIncludeTotalPrice,
  calculateTaxExclusiveTotalPrice,
} from "@/utils/summarizeTable";
import { ElMessage } from "element-plus";
import { ref, getCurrentInstance, computed } from "vue";
import AttachmentUploadImage from '@/components/AttachmentUpload/image/index.vue';
const { proxy } = getCurrentInstance();
const { tax_rate } = proxy.useDict("tax_rate");
import { ref, onMounted } from "vue";
defineOptions({
  name: "设备台账表单",
});
const formRef = ref(null);
const operationType = ref('');
const areaOptions = ref([]);
const areaTreeProps = {
  label: "areaName",
  children: "children",
};
// 设备类型固定选项
const deviceTypeOptions = ref([
  '生产设备',
@@ -200,6 +221,7 @@
  '其他设备'
]);
const formRules = {
    areaId: [{ required: true, trigger: "change", message: "请选择所属区域" }],
    deviceName: [{ required: true, trigger: "blur", message: "请输入" }],
    deviceModel: [{ required: true, trigger: "blur", message: "请输入" }],
    type: [{ required: true, trigger: "change", message: "请选择或输入设备类型" }],
@@ -221,12 +243,25 @@
            trigger: "blur" 
        }
    ],
    externalCode: [
        {
            validator: (rule, value, callback) => {
                if (form.isIotDevice === 1 && !value) {
                    callback(new Error('物联设备为是时,请输入外部编码'));
                } else {
                    callback();
                }
            },
            trigger: "blur"
        }
    ],
}
const { form, resetForm } = useFormData({
  areaId: undefined, // 区域ID
  deviceName: undefined, // 设备名称
  deviceModel: undefined, // 规格型号
  deviceBrand: undefined, // 设备品牌
  // deviceBrand: undefined, // 设备品牌
  type: undefined, // 设备类型
  supplierName: undefined, // 供应商
  storageLocation: undefined, // 存放位置
@@ -240,19 +275,9 @@
  unTaxIncludingPriceTotal: undefined, // 不含税总价
  // createUser: useUserStore().nickName, // 录入人
  createTime: dayjs().format("YYYY-MM-DD HH:mm:ss"), // 录入日期
    planRuntimeTime: dayjs().format("YYYY-MM-DD"), // 录入日期
  storageBlobDTOs: undefined, // 设备图片提交
  storageBlobVOs: undefined, // 设备图片展示
});
const fileList = computed({
  get() {
    return form.storageBlobVOs || [];
  },
  set(val) {
    form.storageBlobDTOs = val;
    form.storageBlobVOs = val;
  }
  planRuntimeTime: dayjs().format("YYYY-MM-DD"), // 预计运行时间
  isIotDevice: 0, // 是否为物联设备 0-否 1-是
  externalCode: undefined, // 外部编码
});
const loadForm = async (id) => {
@@ -261,9 +286,10 @@
    }
  const { code, data } = await getLedgerById(id);
  if (code == 200) {
    form.areaId = data.areaId;
    form.deviceName = data.deviceName;
    form.deviceModel = data.deviceModel;
    form.deviceBrand = data.deviceBrand;
    // form.deviceBrand = data.deviceBrand;
    form.type = data.type;
    form.supplierName = data.supplierName;
    form.storageLocation = data.storageLocation;
@@ -282,9 +308,19 @@
    } else {
      form.planRuntimeTime = undefined;
    }
    form.storageBlobVOs = data.storageBlobVOs;
    form.storageBlobDTOs = data.storageBlobVOs;
    // 物联设备和外部编码
    form.isIotDevice = data.isIotDevice ?? 0;
    form.externalCode = data.externalCode;
  }
};
const setAreaId = (areaId) => {
  form.areaId = areaId;
};
const loadAreaOptions = async () => {
  const res = await getDeviceAreaTree();
  areaOptions.value = Array.isArray(res?.data) ? res.data : Array.isArray(res) ? res : [];
};
const handleDeviceTypeChange = (value) => {
@@ -322,9 +358,14 @@
  clearValidate();
};
onMounted(() => {
  loadAreaOptions();
});
defineExpose({
  form,
  loadForm,
  setAreaId,
  resetForm,
  clearValidate,
  resetFormAndValidate,
src/views/equipmentManagement/measurementEquipment/components/formDia.vue
@@ -36,6 +36,15 @@
                </el-row>
                <el-row :gutter="30">
                    <el-col :span="12">
                        <el-form-item label="安装位置:" prop="instationLocation">
                            <el-input
                                v-model="form.instationLocation"
                                placeholder="请输入"
                                clearable
                            />
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="检定单位:" prop="unit">
              <el-input
                  v-model="form.unit"
@@ -44,17 +53,17 @@
              />
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="证书编号:" prop="model">
                </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="证书编号:" prop="model">
              <el-input
                  v-model="form.model"
                  placeholder="请输入"
                  clearable
              />
            </el-form-item>
                    </el-col>
                </el-row>
        <el-row :gutter="30">
          </el-col>
          <el-col :span="12">
            <el-form-item label="最新鉴定日期:" prop="mostDate">
              <el-date-picker
@@ -68,6 +77,8 @@
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="有效日期(天):" prop="valid">
              <el-input
@@ -80,6 +91,15 @@
              >
              <template #append>日</template>
              </el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="检定周期:" prop="cycle">
              <el-input
                  v-model="form.cycle"
                  placeholder="请输入检定周期"
                  clearable
              />
            </el-form-item>
          </el-col>
        </el-row>
@@ -164,8 +184,10 @@
    form: {
        code: "",
    name: "",
    instationLocation: "",
    mostDate:"",
        model: "",
    cycle:"",
        validDate: "",
        nextDate: "",
        userId: "",
@@ -181,7 +203,9 @@
        nextDate: [{required: true, message: "请选择", trigger: "change"}],
        userId: [{required: true, message: "请选择", trigger: "change"}],
        recordDate: [{required: true, message: "请选择", trigger: "change"}],
    instationLocation: [{required: true, message: "请输入", trigger: "blur"}],
    mostDate: [{required: true, message: "请选择", trigger: "change"}],
    cycle: [{required: true, message: "请选择", trigger: "blur"}],
    valid: [
      {required: true, message: "请输入", trigger: "blur"},
      {
src/views/equipmentManagement/measurementEquipment/filesDia.vue
@@ -1,16 +1,38 @@
<template>
  <div>
    <el-dialog v-model="dialogFormVisible" title="上传附件" width="50%" @close="closeDia">
    <el-dialog
        v-model="dialogFormVisible"
        title="上传附件"
        width="50%"
        @close="closeDia"
    >
      <div style="margin-bottom: 10px;text-align: right">
        <el-upload v-model:file-list="fileList" class="upload-demo" :action="uploadUrl"
          :on-success="handleUploadSuccess" :on-error="handleUploadError" name="files" :show-file-list="false"
          :headers="headers" style="display: inline;margin-right: 10px">
        <el-upload
            v-model:file-list="fileList"
            class="upload-demo"
            :action="uploadUrl"
            :on-success="handleUploadSuccess"
            :on-error="handleUploadError"
            name="file"
            :show-file-list="false"
            :headers="headers"
            style="display: inline;margin-right: 10px"
        >
          <el-button type="primary">上传附件</el-button>
        </el-upload>
        <el-button type="danger" plain @click="handleDelete">删除</el-button>
      </div>
      <PIMTable rowKey="id" :column="tableColumn" :tableData="tableData" :page="page" :tableLoading="tableLoading"
        :isSelection="true" @selection-change="handleSelectionChange" @pagination="paginationSearch" height="500">
      <PIMTable
          rowKey="id"
          :column="tableColumn"
          :tableData="tableData"
          :page="page"
          :tableLoading="tableLoading"
          :isSelection="true"
          @selection-change="handleSelectionChange"
          @pagination="paginationSearch"
          height="500"
      >
      </PIMTable>
      <template #footer>
        <div class="dialog-footer">
@@ -23,16 +45,16 @@
</template>
<script setup>
import { ref, reactive, getCurrentInstance } from "vue";
import { ElMessageBox } from "element-plus";
import { getToken } from "@/utils/auth.js";
import {ref, reactive, getCurrentInstance} from "vue";
import {ElMessageBox} from "element-plus";
import {getToken} from "@/utils/auth.js";
import filePreview from '@/components/filePreview/index.vue'
import PIMTable from "@/components/PIMTable/PIMTable.vue";
import {
  addStorageAttachment,
  delStorageAttachment,
  getStorageAttachmentList
} from "@/api/equipmentManagement/measurementEquipment.js";
  fileAdd,
  fileDel,
  fileListPage
} from "@/api/financialManagement/revenueManagement.js";
const { proxy } = getCurrentInstance()
const emit = defineEmits(['close'])
@@ -68,9 +90,9 @@
  },
]);
const page = reactive({
  current: 1,
  size: 100,
  total: 0,
    current: 1,
    size: 100,
    total: 0,
});
const tableData = ref([]);
const fileList = ref([]);
@@ -79,25 +101,24 @@
const headers = ref({
  Authorization: "Bearer " + getToken(),
});
const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/upload"); // 上传的服务器地址
const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/file/upload"); // 上传的图片服务器地址
// 打开弹框
const openDialog = (row, type) => {
const openDialog = (row,type) => {
  accountType.value = type;
  dialogFormVisible.value = true;
  currentId.value = row.id;
  getList()
}
const paginationSearch = (obj) => {
  page.current = obj.page;
  page.size = obj.limit;
  // 前端分页暂不处理,直接调用获取全量列表
  getList();
    page.current = obj.page;
    page.size = obj.limit;
    getList();
};
const getList = () => {
  getStorageAttachmentList({ recordId: currentId.value, recordType: accountType.value }).then(res => {
    tableData.value = res.data;
    page.total = res.data ? res.data.length : 0;
  fileListPage({accountId: currentId.value,accountType:accountType.value, ...page}).then(res => {
    tableData.value = res.data.records;
        page.total = res.data.total;
  })
}
// 表格选择数据
@@ -113,25 +134,22 @@
// 上传成功处理
function handleUploadSuccess(res, file) {
  // 如果上传成功
  if (res.code == 200 && res.data && res.data.length > 0) {
    const newFiles = res.data.map(item => ({
      ...item,
      name: item.originalFilename || item.name
    }));
    const mergedFiles = [...(tableData.value || []), ...newFiles];
    const storageAttachmentDTO = {
      recordType: accountType.value,
      recordId: currentId.value,
      application: "file",
      storageBlobDTOs: mergedFiles
    };
    addStorageAttachment(storageAttachmentDTO).then(r => {
      proxy.$modal.msgSuccess("文件上传成功");
      getList()
    })
  if (res.code == 200) {
    const fileRow = {}
    fileRow.name = res.data.originalName
    fileRow.url = res.data.tempPath
    uploadFile(fileRow)
  } else {
    proxy.$modal.msgError("文件上传失败");
  }
}
function uploadFile(file) {
  file.accountId = currentId.value;
  file.accountType = accountType.value;
  fileAdd(file).then(res => {
    proxy.$modal.msgSuccess("文件上传成功");
    getList()
  })
}
// 上传失败处理
function handleUploadError() {
@@ -139,13 +157,13 @@
}
// 下载附件
const downLoadFile = (row) => {
  proxy.$download.byUrl(row.url, row.originalFilename);
  proxy.$download.name(row.url);
}
// 删除
const handleDelete = () => {
  let ids = [];
  if (selectedRows.value.length > 0) {
    ids = selectedRows.value.map((item) => item.storageAttachmentId);
    ids = selectedRows.value.map((item) => item.id);
  } else {
    proxy.$modal.msgWarning("请选择数据");
    return;
@@ -155,7 +173,7 @@
    cancelButtonText: "取消",
    type: "warning",
  }).then(() => {
    delStorageAttachment(ids).then((res) => {
    fileDel(ids).then((res) => {
      proxy.$modal.msgSuccess("删除成功");
      getList();
    });
@@ -173,4 +191,6 @@
});
</script>
<style scoped></style>
<style scoped>
</style>
src/views/equipmentManagement/upkeep/Form/formDia.vue
@@ -1,330 +1,497 @@
<template>
    <FormDialog
        v-model="dialogVisitable"
        :title="operationType === 'add' ? '新增保养任务' : '编辑保养任务'"
        width="800px"
        :operation-type="operationType"
        @confirm="submitForm"
        @cancel="cancel"
        @close="cancel"
    >
        <el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
            <el-row>
                <el-col :span="12">
                    <el-form-item label="设备名称" prop="taskId">
                        <el-select v-model="form.taskId" @change="setDeviceModel" filterable>
                            <el-option
                                v-for="(item, index) in deviceOptions"
                                :key="index"
                                :label="item.deviceName"
                                :value="item.id"
                            ></el-option>
                        </el-select>
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="规格型号">
                        <el-input
                            v-model="form.deviceModel"
                            placeholder="请输入规格型号"
                            disabled
                        />
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row>
                <el-col :span="12">
                    <el-form-item label="录入人" prop="inspector">
                        <el-select
                            v-model="form.inspector"
                            filterable
                            default-first-option
                            :reserve-keyword="false"
                            placeholder="请选择"
                            clearable
                        >
                            <el-option
                                v-for="item in userList"
                                :label="item.nickName"
                                :value="item.userId"
                                :key="item.userId"
                            />
                        </el-select>
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="登记时间" prop="registrationDate">
                        <el-date-picker
                            v-model="form.registrationDate"
                            type="date"
                            placeholder="选择登记日期"
                            format="YYYY-MM-DD"
                            value-format="YYYY-MM-DD"
                            style="width: 100%"
                        />
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row>
                <el-col :span="12">
                    <el-form-item label="保养项目" prop="machineryCategory">
                        <el-input
                            v-model.trim="form.machineryCategory"
                            placeholder="请输入保养项目"
                            maxlength="100"
                            clearable
                        />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="保养人" prop="maintenancePerson">
                        <el-input
                            v-model.trim="form.maintenancePerson"
                            placeholder="请输入保养人姓名"
                            maxlength="100"
                            clearable
                        />
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row>
                <el-col :span="12">
                    <el-form-item label="任务频率" prop="frequencyType">
                        <el-select v-model="form.frequencyType" placeholder="请选择" clearable>
                            <el-option label="每日" value="DAILY"/>
                            <el-option label="每周" value="WEEKLY"/>
                            <el-option label="每月" value="MONTHLY"/>
                            <el-option label="季度" value="QUARTERLY"/>
                        </el-select>
                    </el-form-item>
                </el-col>
                <el-col :span="12" v-if="form.frequencyType === 'DAILY' && form.frequencyType">
                    <el-form-item label="日期" prop="frequencyDetail">
                        <el-time-picker v-model="form.frequencyDetail" placeholder="选择时间" format="HH:mm"
                                                        value-format="HH:mm" />
                    </el-form-item>
                </el-col>
                <el-col :span="12" v-if="form.frequencyType === 'WEEKLY' && form.frequencyType">
                    <el-form-item label="日期" prop="frequencyDetail">
                        <el-select v-model="form.week" placeholder="请选择" clearable style="width: 50%">
                            <el-option label="周一" value="MON"/>
                            <el-option label="周二" value="TUE"/>
                            <el-option label="周三" value="WED"/>
                            <el-option label="周四" value="THU"/>
                            <el-option label="周五" value="FRI"/>
                            <el-option label="周六" value="SAT"/>
                            <el-option label="周日" value="SUN"/>
                        </el-select>
                        <el-time-picker v-model="form.time" placeholder="选择时间" format="HH:mm"
                                                        value-format="HH:mm"  style="width: 50%"/>
                    </el-form-item>
                </el-col>
                <el-col :span="12" v-if="form.frequencyType === 'MONTHLY' && form.frequencyType">
                    <el-form-item label="日期" prop="frequencyDetail">
                        <el-date-picker
                            v-model="form.frequencyDetail"
                            type="datetime"
                            clearable
                            placeholder="选择开始日期"
                            format="DD,HH:mm"
                            value-format="DD,HH:mm"
                        />
                    </el-form-item>
                </el-col>
                <el-col :span="12" v-if="form.frequencyType === 'QUARTERLY' && form.frequencyType">
                    <el-form-item label="日期" prop="frequencyDetail">
                        <el-date-picker
                            v-model="form.frequencyDetail"
                            type="datetime"
                            clearable
                            placeholder="选择开始日期"
                            format="MM,DD,HH:mm"
                            value-format="MM,DD,HH:mm"
                        />
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row>
                <el-col :span="12">
                    <el-form-item label="备注" prop="remarks">
                        <el-input v-model="form.remarks" placeholder="请输入备注" type="textarea" />
                    </el-form-item>
                </el-col>
            </el-row>
        </el-form>
    </FormDialog>
  <FormDialog
    v-model="dialogVisitable"
    :title="operationType === 'add' ? '新增保养任务' : '编辑保养任务'"
    width="800px"
    :operation-type="operationType"
    @confirm="submitForm"
    @cancel="cancel"
    @close="cancel"
  >
    <el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
      <el-row>
        <el-col :span="12">
          <el-form-item label="所属区域" prop="areaId">
            <el-tree-select
              v-model="form.areaId"
              :data="areaOptions"
              :props="areaTreeProps"
              node-key="id"
              value-key="id"
              check-strictly
              clearable
              filterable
              placeholder="请选择所属区域"
              style="width: 100%"
              @change="handleAreaChange"
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="设备名称" prop="deviceLedgerIds">
            <el-select
              v-model="form.deviceLedgerIds"
              filterable
              clearable
              multiple
              collapse-tags
              collapse-tags-tooltip
              placeholder="请选择设备"
              style="width: 100%"
              @change="setDeviceModels"
            >
              <el-option
                v-for="item in deviceOptions"
                :key="item.id"
                :label="item.deviceName"
                :value="item.id"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="规格型号">
            <el-input
              v-model="form.deviceModel"
              placeholder="自动带出规格型号"
              disabled
            />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="12">
          <el-form-item label="录入人" prop="inspector">
            <el-select
              v-model="form.inspector"
              filterable
              default-first-option
              :reserve-keyword="false"
              placeholder="请选择"
              clearable
            >
              <el-option
                v-for="item in userList"
                :key="item.userId"
                :label="item.nickName"
                :value="item.userId"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="登记时间" prop="registrationDate">
            <el-date-picker
              v-model="form.registrationDate"
              type="date"
              placeholder="选择登记日期"
              format="YYYY-MM-DD"
              value-format="YYYY-MM-DD"
              style="width: 100%"
            />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="12">
          <el-form-item label="任务频率" prop="frequencyType">
            <el-select v-model="form.frequencyType" placeholder="请选择" clearable>
              <el-option label="每日" value="DAILY" />
              <el-option label="每周" value="WEEKLY" />
              <el-option label="每月" value="MONTHLY" />
              <el-option label="季度" value="QUARTERLY" />
              <el-option label="每年" value="YEARLY" />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12" v-if="form.frequencyType === 'DAILY'">
          <el-form-item label="日期" prop="frequencyDetail">
            <el-time-picker
              v-model="form.frequencyDetail"
              placeholder="选择时间"
              format="HH:mm"
              value-format="HH:mm"
            />
          </el-form-item>
        </el-col>
        <el-col :span="12" v-if="form.frequencyType === 'WEEKLY'">
          <el-form-item label="日期" prop="frequencyDetail">
            <el-select v-model="form.week" placeholder="请选择" clearable style="width: 50%">
              <el-option label="周一" value="MON" />
              <el-option label="周二" value="TUE" />
              <el-option label="周三" value="WED" />
              <el-option label="周四" value="THU" />
              <el-option label="周五" value="FRI" />
              <el-option label="周六" value="SAT" />
              <el-option label="周日" value="SUN" />
            </el-select>
            <el-time-picker
              v-model="form.time"
              placeholder="选择时间"
              format="HH:mm"
              value-format="HH:mm"
              style="width: 50%"
            />
          </el-form-item>
        </el-col>
        <el-col :span="12" v-if="form.frequencyType === 'MONTHLY'">
          <el-form-item label="日期" prop="frequencyDetail">
            <el-date-picker
              v-model="form.frequencyDetail"
              type="datetime"
              clearable
              placeholder="选择开始日期"
              format="DD,HH:mm"
              value-format="DD,HH:mm"
            />
          </el-form-item>
        </el-col>
        <el-col :span="12" v-if="form.frequencyType === 'QUARTERLY'">
          <el-form-item label="日期" prop="frequencyDetail">
            <el-date-picker
              v-model="form.frequencyDetail"
              type="datetime"
              clearable
              placeholder="选择开始日期"
              format="MM,DD,HH:mm"
              value-format="MM,DD,HH:mm"
            />
          </el-form-item>
        </el-col>
        <el-col :span="12" v-if="form.frequencyType === 'YEARLY'">
          <el-form-item label="日期" prop="frequencyDetail">
            <el-date-picker
              v-model="form.frequencyDetail"
              type="datetime"
              clearable
              placeholder="选择开始日期"
              format="MM,DD,HH:mm"
              value-format="MM,DD,HH:mm"
            />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="12">
          <el-form-item label="是否启用" prop="isEnabled">
            <el-switch
              v-model="form.isEnabled"
              :active-value="1"
              :inactive-value="0"
            />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="12">
          <el-form-item label="备注" prop="remarks">
            <el-input v-model="form.remarks" placeholder="请输入备注" type="textarea" />
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
  </FormDialog>
</template>
<script setup>
import { getCurrentInstance, reactive, ref, toRefs } from "vue";
import FormDialog from "@/components/Dialog/FormDialog.vue";
import { reactive, ref, getCurrentInstance, toRefs } from "vue";
import {userListNoPageByTenantId} from "@/api/system/user.js";
import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
import { deviceMaintenanceTaskAdd, deviceMaintenanceTaskEdit } from "@/api/equipmentManagement/upkeep";
import { userListNoPageByTenantId } from "@/api/system/user.js";
import {
  getDeviceAreaTree,
  getDeviceAreaTreeWithDevices,
} from "@/api/equipmentManagement/deviceArea";
import {
  deviceMaintenanceTaskAdd,
  deviceMaintenanceTaskEdit,
} from "@/api/equipmentManagement/upkeep";
import { getCurrentDate } from "@/utils/index.js";
import useUserStore from "@/store/modules/user.js";
const { proxy } = getCurrentInstance()
const emit = defineEmits()
const { proxy } = getCurrentInstance();
const emit = defineEmits(["closeDia"]);
const dialogVisitable = ref(false);
const operationType = ref('add');
const operationType = ref("add");
const areaOptions = ref([]);
const deviceOptions = ref([]);
const userList = ref([]);
const areaTreeProps = {
  label: "areaName",
  children: "children",
};
const userStore = useUserStore();
const data = reactive({
    form: {
        taskId: undefined,
        taskName: undefined,
        // 录入人:单选一个用户 id
        inspector: undefined,
        machineryCategory: "",
        remarks: '',
        frequencyType: '',
        frequencyDetail: '',
        week: '',
        time: '',
        deviceModel: undefined, // 规格型号
        registrationDate: '',
        maintenancePerson: '' // 保养人
    },
    rules: {
        taskId: [{ required: true, message: "请选择设备", trigger: "change" },],
        inspector: [{ required: true, message: "请选择录入人", trigger: "blur" },],
        registrationDate: [{ required: true, message: "请选择登记时间", trigger: "change" }],
        machineryCategory: [{ required: true, message: "请输入保养项目", trigger: "blur" }]
    }
})
const { form, rules } = toRefs(data)
const userList = ref([])
const loadDeviceName = async () => {
    const { data } = await getDeviceLedger();
    deviceOptions.value = data;
const data = reactive({
  form: {
    areaId: undefined,
    taskId: undefined,
    taskIds: [],
    taskIdsStr: undefined,
    deviceLedgerIds: [],
    deviceLedgerIdsStr: undefined,
    taskName: undefined,
    isEnabled: 1,
    inspector: undefined,
    remarks: "",
    frequencyType: "",
    frequencyDetail: "",
    week: "",
    time: "",
    deviceModel: undefined,
    registrationDate: "",
  },
  rules: {
    areaId: [{ required: true, message: "请选择所属区域", trigger: "change" }],
    deviceLedgerIds: [{ required: true, message: "请选择设备", trigger: "change" }],
    inspector: [{ required: true, message: "请选择录入人", trigger: "change" }],
    registrationDate: [{ required: true, message: "请选择登记时间", trigger: "change" }],
  },
});
const { form, rules } = toRefs(data);
const loadAreaTree = async () => {
  const { data } = await getDeviceAreaTree();
  areaOptions.value = Array.isArray(data) ? data : [];
};
// 选择设备时,回填设备名称(taskName)和规格型号(deviceModel)
const setDeviceModel = (id) => {
    const option = deviceOptions.value.find((item) => item.id === id);
    if (option) {
        form.value.taskId = option.id;
        form.value.taskName = option.deviceName;
        form.value.deviceModel = option.deviceModel;
    }
}
const normalizeIdList = (value) => {
  if (Array.isArray(value)) {
    return value
      .map((item) => Number(item))
      .filter((item) => Number.isFinite(item));
  }
  if (typeof value === "string") {
    return value
      .split(",")
      .map((item) => Number(item.trim()))
      .filter((item) => Number.isFinite(item));
  }
  if (value !== undefined && value !== null && value !== "") {
    const numericValue = Number(value);
    return Number.isFinite(numericValue) ? [numericValue] : [];
  }
  return [];
};
// 打开弹框
const openDialog = async (type, row) => {
    dialogVisitable.value = true
    operationType.value = type
    // 重置表单
    resetForm();
    // 加载用户列表
    userListNoPageByTenantId().then((res) => {
        userList.value = res.data;
    });
    // 加载设备列表
    await loadDeviceName();
    if (type === 'edit' && row) {
        form.value = { ...row }
        // 编辑时用接口返回的 registrantId 回显录入人
        if (row.registrantId) {
            form.value.inspector = row.registrantId
        }
const getNodeDevices = (node) => {
  const candidates = [
    node?.deviceList,
    node?.devices,
    node?.deviceLedgerList,
    node?.deviceLedgers,
    node?.ledgerList,
    node?.ledgers,
  ];
  return candidates.find((item) => Array.isArray(item)) || [];
};
        // 如果有设备ID,自动设置设备信息
        if (form.value.taskId) {
            setDeviceModel(form.value.taskId);
        }
    } else if (type === 'add') {
        // 新增时设置登记日期为当天
        form.value.registrationDate = getCurrentDate();
        // 新增时设置录入人为当前登录账户
        form.value.inspector = userStore.id;
    }
}
const normalizeDevice = (item) => ({
  ...item,
  id: item.id ?? item.deviceLedgerId,
  deviceName: item.deviceName ?? item.name,
  deviceModel: item.deviceModel ?? item.model,
});
// 关闭对话框
const cancel = () => {
    resetForm()
    dialogVisitable.value = false
    emit('closeDia')
}
const collectDevices = (node) => {
  const currentDevices = getNodeDevices(node).map(normalizeDevice);
  const childDevices = (node?.children || []).flatMap((child) =>
    collectDevices(child)
  );
  const deviceMap = new Map();
  [...currentDevices, ...childDevices].forEach((item) => {
    if (item?.id !== undefined && item?.id !== null) {
      deviceMap.set(Number(item.id), item);
    }
  });
  return Array.from(deviceMap.values());
};
// 重置表单函数
const findAreaNode = (nodes, areaId) => {
  for (const node of nodes || []) {
    if (Number(node.id) === Number(areaId)) {
      return node;
    }
    const target = findAreaNode(node.children, areaId);
    if (target) {
      return target;
    }
  }
  return null;
};
const loadDevicesByArea = async (areaId) => {
  if (!areaId) {
    deviceOptions.value = [];
    return;
  }
  const { data } = await getDeviceAreaTreeWithDevices();
  const treeData = Array.isArray(data) ? data : [];
  const currentNode = findAreaNode(treeData, areaId);
  deviceOptions.value = currentNode ? collectDevices(currentNode) : [];
};
const syncDeviceFields = (deviceIds) => {
  const selectedIds = normalizeIdList(deviceIds);
  const selectedDevices = selectedIds
    .map((deviceId) =>
      deviceOptions.value.find((item) => Number(item.id) === Number(deviceId))
    )
    .filter(Boolean);
  form.value.deviceLedgerIds = selectedIds;
  form.value.deviceLedgerIdsStr = selectedIds.join(",");
  form.value.taskIds = [...selectedIds];
  form.value.taskIdsStr = selectedIds.join(",");
  form.value.taskId = selectedIds[0];
  form.value.taskName = selectedDevices
    .map((item) => item.deviceName)
    .filter(Boolean)
    .join(",");
  form.value.deviceModel = selectedDevices
    .map((item) => item.deviceModel || "-")
    .join(",");
};
const setDeviceModels = (deviceIds) => {
  syncDeviceFields(deviceIds);
};
const handleAreaChange = async (areaId) => {
  form.value.taskId = undefined;
  form.value.taskIds = [];
  form.value.taskIdsStr = undefined;
  form.value.deviceLedgerIds = [];
  form.value.deviceLedgerIdsStr = undefined;
  form.value.taskName = undefined;
  form.value.deviceModel = undefined;
  await loadDevicesByArea(areaId);
};
const resetForm = () => {
    if (proxy.$refs.formRef) {
        proxy.$refs.formRef.resetFields()
    }
    // 重置表单数据确保设备信息正确重置
    form.value = {
        taskId: undefined,
        taskName: undefined,
        inspector: undefined,
        machineryCategory: "",
        remarks: '',
        frequencyType: '',
        frequencyDetail: '',
        week: '',
        time: '',
        deviceModel: undefined,
        registrationDate: '',
        maintenancePerson: ''
    }
}
  if (proxy.$refs.formRef) {
    proxy.$refs.formRef.resetFields();
  }
  form.value = {
    areaId: undefined,
    taskId: undefined,
    taskIds: [],
    taskIdsStr: undefined,
    deviceLedgerIds: [],
    deviceLedgerIdsStr: undefined,
    taskName: undefined,
    isEnabled: 1,
    inspector: undefined,
    remarks: "",
    frequencyType: "",
    frequencyDetail: "",
    week: "",
    time: "",
    deviceModel: undefined,
    registrationDate: "",
  };
};
// 提交表单
const openDialog = async (type, row) => {
  dialogVisitable.value = true;
  operationType.value = type;
  resetForm();
  userListNoPageByTenantId().then((res) => {
    userList.value = res.data;
  });
  await loadAreaTree();
  if (type === "edit" && row) {
    form.value = {
      ...form.value,
      ...row,
      isEnabled: Number(row.isEnabled ?? row.status ?? 1),
      inspector: row.registrantId || row.inspector,
    };
    form.value.deviceLedgerIds = normalizeIdList(
      row.deviceLedgerIds ??
        row.deviceLedgerIdsStr ??
        row.taskIds ??
        row.taskIdsStr ??
        row.taskId
    );
    form.value.deviceLedgerIdsStr = form.value.deviceLedgerIds.join(",");
    form.value.taskIds = [...form.value.deviceLedgerIds];
    form.value.taskIdsStr = form.value.deviceLedgerIds.join(",");
    form.value.taskId = form.value.deviceLedgerIds[0];
    if (form.value.areaId) {
      await loadDevicesByArea(form.value.areaId);
      syncDeviceFields(form.value.deviceLedgerIds);
    }
  } else {
    form.value.registrationDate = getCurrentDate();
    form.value.inspector = userStore.id;
    deviceOptions.value = [];
  }
};
const cancel = () => {
  resetForm();
  dialogVisitable.value = false;
  emit("closeDia");
};
const submitForm = () => {
    proxy.$refs["formRef"].validate(async valid => {
        if (valid) {
            try {
                const payload = { ...form.value }
                // 不再向后端传保养人字段,仅使用接口要求的 registrant / registrantId
                // 根据选择的"录入人"设置 registrant / registrantId
                if (payload.inspector) {
                    const selectedUser = userList.value.find(
                        (u) => String(u.userId) === String(payload.inspector)
                    )
                    if (selectedUser) {
                        payload.registrantId = selectedUser.userId
                        payload.registrant = selectedUser.nickName
                    }
                }
                delete payload.inspector
                delete payload.inspectorIds
                if (payload.frequencyType === 'WEEKLY') {
                    let frequencyDetail = ''
                    frequencyDetail = payload.week + ',' + payload.time
                    payload.frequencyDetail = frequencyDetail
                }
                // 录入日期:直接使用表单里的 registrationDate 字段
                // 一些默认状态字段
                if (payload.status === undefined || payload.status === null || payload.status === '') {
                    payload.status = '0' // 默认状态,可按实际枚举调整
                }
                payload.active = true
                payload.deleted = 0
                if (operationType.value === 'edit') {
                    await deviceMaintenanceTaskEdit(payload)
                } else {
                    await deviceMaintenanceTaskAdd(payload)
                }
                cancel()
                proxy.$modal.msgSuccess('提交成功')
            } catch (error) {
                proxy.$modal.msgError('提交失败,请重试')
            }
        }
    })
}
defineExpose({ openDialog })
  proxy.$refs.formRef.validate(async (valid) => {
    if (!valid) {
      return;
    }
    try {
      syncDeviceFields(form.value.deviceLedgerIds);
      const payload = { ...form.value };
      if (payload.inspector) {
        const selectedUser = userList.value.find(
          (item) => String(item.userId) === String(payload.inspector)
        );
        if (selectedUser) {
          payload.registrantId = selectedUser.userId;
          payload.registrant = selectedUser.nickName;
        }
      }
      delete payload.inspector;
      delete payload.inspectorIds;
      if (payload.frequencyType === "WEEKLY") {
        payload.frequencyDetail = `${payload.week},${payload.time}`;
      }
      payload.isEnabled = Number(form.value.isEnabled ?? 1);
      payload.deviceLedgerIds = [...form.value.deviceLedgerIds];
      payload.deviceLedgerIdsStr = form.value.deviceLedgerIds.join(",");
      payload.taskIds = [...form.value.deviceLedgerIds];
      payload.taskIdsStr = form.value.deviceLedgerIds.join(",");
      payload.taskId = form.value.deviceLedgerIds[0];
      payload.taskName = form.value.taskName;
      payload.deviceModel = form.value.deviceModel || "-";
      payload.active = true;
      payload.deleted = 0;
      if (operationType.value === "edit") {
        await deviceMaintenanceTaskEdit(payload);
      } else {
        await deviceMaintenanceTaskAdd(payload);
      }
      cancel();
      proxy.$modal.msgSuccess("提交成功");
    } catch (error) {
      proxy.$modal.msgError("提交失败,请重试");
    }
  });
};
defineExpose({ openDialog });
</script>
<style scoped>
</style>
<style scoped></style>