当前位置: 首页 > article >正文

arco-design 自定义table和for循环自定义form-item并添加自定义校验

代码

<template>
  <div class="list-container">
    <Breadcrumb
      :items="['menu.generateRecords', 'menu.generateRecordsDetail']"
      :needBack="true"
    />
    <a-card class="general-card">
      <PageQuery
        ref="pageQuery"
        :show-add="true"
        :provider-list="state.providerList"
        :telecom-status-list="state.telecomStatusList"
        :telecom-list="state.telecomList"
        :sim-status-list="state.simStatusList"
        @fetch-list-query="fetchListQuery"
        @fetch-list-reset="fetchListReset"
        @add-data="addData"
        @upload="handleUpload"
        @import="handleImport"
      ></PageQuery>
    </a-card>
    <a-card class="general-card" style="margin-top: 20px">
      <a-table
        :loading="state.tableLoading"
        :columns="state.columnsList"
        :data="state.tableData"
        :pagination="state.basePagination"
        :bordered="{ cell: true }"
        @page-change="onPageChange($event)"
        @page-size-change="onPageSizeChange($event)"
      >
        <template #imei="{ rowIndex, record }">
          <a-input
            v-model="state.tableData[rowIndex].imei"
            @blur="imeiBlur(record)"
          />
        </template>
        <template #iotCardNo="{ rowIndex, record }">
          <a-input
            v-model="state.tableData[rowIndex].iotCardNo"
            @blur="iotCardBlur(record)"
          />
        </template>
        <template
          v-for="(TabItem, index) in state.addColumnsList"
          v-slot:[TabItem.slotName]="{ rowIndex, record }"
          :key="index"
        >
          <a-input
            v-model="state.tableData[rowIndex][TabItem.slotName]"
            @blur="otherBlur(record, TabItem.slotName)"
          />
        </template>
        <template #optional="{ record }">
          <a-button type="text" @click="handleClickDetail(record)">
            详情
          </a-button>
          <a-button type="text" @click="handleClickDetail(record)">
            导出
          </a-button>
        </template>
      </a-table>
    </a-card>
    <!-- 详情组件 -->
    <DetailModal
      ref="DetailModalRef"
      :current-detail="state.currentDetail"
    ></DetailModal>
    <!-- 新增弹窗 -->
    <a-modal
      v-model:visible="insertVisible"
      :footer="false"
      @cancel="closeAddModal"
    >
      <template #title>
        <div class="modal-title">新增桩码</div>
      </template>
      <a-form
        ref="formRef"
        :model="state.form"
        :style="{ width: '100%' }"
        auto-label-width
        @submit="handleAddSubmit"
      >
        <a-form-item
          v-for="(labelItem, indexs) in state.form.formList"
          :key="indexs"
          :field="labelItem.dataIndex"
          :label="labelItem.title"
          :rules="[
            {
              required: true,
              message: `${labelItem.title}不能为空`,
            },
            {
              validator:
                labelItem.dataIndex === 'iotCardNo' ? customValidator : '',
            },
          ]"
          :validate-trigger="['blur', 'change']"
        >
          <a-input
            v-model="state.form[labelItem.dataIndex]"
            :disabled="labelItem.dataIndex === 'orderNo'"
            :placeholder="`请输入${labelItem.title}`"
          />
        </a-form-item>
        <a-form-item>
          <a-space>
            <a-button @click="closeAddModal">取 消</a-button>
            <a-button type="primary" html-type="submit">确 定</a-button>
          </a-space>
        </a-form-item>
      </a-form>
    </a-modal>
    <!-- 导入 -->
    <input
      ref="fileInput"
      type="file"
      style="display: none"
      accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
      @change="handleFileChange"
    />
  </div>
</template>

<script lang="ts" setup>
  // @ts-nocheck
  import { ref, reactive, onMounted, getCurrentInstance } from 'vue';
  import type { TableColumnData } from '@arco-design/web-vue/es/table/interface';
  import { Message } from '@arco-design/web-vue';
  import {
    generateEquipmentEncodeQuery,
    updateEquipmentEncodeRecordDetailBySortNum,
    addEquipmentEncodeRecordDetail,
    template,
    importImei,
  } from '@/api/purchasing';
  import { useRouter } from 'vue-router';
  import AddModal from '@/views/iotcard/all-card/components/add-modal.vue';
  import PageQuery from './components/PageQuery.vue';
  import DetailModal from './components/detail-modal.vue';
  import { pagination, columnsList } from './config';

  const proxy = getCurrentInstance()?.proxy as any;
  const { currentRoute } = useRouter();
  const route = currentRoute.value;
  const DetailModalRef = ref();
  const fileInput = ref(); // 导入
  const insertVisible = ref(false);
  const state = reactive({
    formQuery: {},
    tableLoading: false,
    tableData: [],
    currentDetail: {},
    basePagination: {
      ...pagination,
    },

    telecomList: [], // 运营商字典
    providerList: [], // 供应商字典
    telecomStatusList: [], // 卡状态(运营商)
    simStatusList: [], // 管理状态
    isFirst: true,
    columnsList: [],
    imei: 'imei',
    addColumnsList: [],
    form: {
      formList: [],
    },
  });
  const fetchData = async (
    params = {
      accessType: 'Web',
      data: {
        ...state.formQuery,
        encodeRecordId: route.query.encodeRecordId,
      },
      page: {
        pageIndex: state.basePagination.current,
        pageSize: state.basePagination.pageSize,
      },
    }
  ) => {
    state.tableLoading = true;
    try {
      const resData = await generateEquipmentEncodeQuery(params);
      state.columnsList = resData.data.ruleNames.map((item) => {
        return {
          title: item.ruleName,
          dataIndex: item.ruleCode,
          slotName: item.ruleCode,
        };
      });
      state.addColumnsList = resData.data.ruleNames.map((item) => {
        return {
          title: item.ruleName,
          dataIndex: item.ruleCode,
          slotName: item.ruleCode,
        };
      });
      state.columnsList.unshift(
        { title: '订单号', dataIndex: 'orderNo' },
        {
          title: 'imei',
          dataIndex: 'imei',
          slotName: 'imei',
        },
        {
          title: '物联网卡编号',
          dataIndex: 'iotCardNo',
          slotName: 'iotCardNo',
        }
      );
      // 表单item数组
      state.form.formList = [];
      state.columnsList.forEach((item) => {
        state.form.formList.push(item);
      });
      // 表单对象
      state.columnsList.forEach((item) => {
        if (item.dataIndex === 'orderNo') {
          state.form[item.dataIndex] = route.query.orderNo;
        } else {
          state.form[item.dataIndex] = '';
        }
      });
      console.log(state.form);
      state.tableData = resData.data.ruleCodes;
      state.basePagination.current = params.page.pageIndex;
      state.basePagination.total = resData.page.total;
    } catch (err) {
      // you can report use errorHandler or other
    } finally {
      state.tableLoading = false;
      state.isFirst = false;
    }
  };
  // imei修改
  // eslint-disable-next-line consistent-return
  const imeiBlur = async (e) => {
    console.log('保存了imei号');
    console.log(e);
    if (e.imei === '' || e.imei === null) {
      return false;
    }
    e.recordId = route.query.encodeRecordId;
    const params = {
      accessType: 'Web',
      data: {
        sortNum: e.sortNum,
        recordId: e.recordId,
        imei: e.imei,
      },
    };
    try {
      const res = await updateEquipmentEncodeRecordDetailBySortNum(params);
      proxy.$message.success('imei修改成功');
    } catch (err) {
      // you can report use errorHandler or other
      console.log(err);
      console.log('请求失败');
    } finally {
      state.tableLoading = false;
    }
  };

  // 物联网卡号修改
  // eslint-disable-next-line consistent-return
  const iotCardBlur = async (e) => {
    console.log('保存了物联网卡号');
    console.log(e);
    if (e.iotCardNo === '' || e.iotCardNo === null) {
      return false;
    }
    const flag: boolean = /^\d{13}$/.test(e.iotCardNo);
    if (!flag) {
      proxy.$message.error('请输入13位纯数字物联卡号');
      return false;
    }

    e.recordId = route.query.encodeRecordId;
    const params = {
      accessType: 'Web',
      data: {
        sortNum: e.sortNum,
        recordId: e.recordId,
        iotCardNo: e.iotCardNo,
      },
    };

    try {
      const res = await updateEquipmentEncodeRecordDetailBySortNum(params);
      proxy.$message.success('物联网卡编号修改成功');
    } catch (err) {
      // you can report use errorHandler or other
      console.log(err);
      console.log('请求失败');
    } finally {
      state.tableLoading = false;
    }
  };
  // 其他字段修改
  // eslint-disable-next-line consistent-return
  const otherBlur = async (e, className) => {
    console.log('修改了其他字段');
    console.log(e);
    console.log(className);
    const key = className;
    console.log(e[className]);

    e.recordId = route.query.encodeRecordId;
    const datas = {
      sortNum: e.sortNum,
      recordId: e.recordId,
      productCode: e[className],
      ruleCode: className,
    };
    const params = {
      accessType: 'Web',
      data: datas,
    };

    try {
      const res = await updateEquipmentEncodeRecordDetailBySortNum(params);
      proxy.$message.success('物联网卡编号修改成功');
    } catch (err) {
      // you can report use errorHandler or other
      console.log(err);
      console.log('请求失败');
    } finally {
      state.tableLoading = false;
    }
  };
  // 新增数据
  const addData = () => {
    console.log('点击了增加');
    console.log(state.form);
    insertVisible.value = true;
  };
  // 取消新增
  const closeAddModal = () => {
    insertVisible.value = false;
    state.form.formList.forEach((item) => {
      item.value = '';
    });
    proxy.$refs.formRef.resetFields();
  };
  // 新增
  const handleAddSubmit = async ({ errors, values }) => {
    if (errors !== undefined) {
      return;
    }

    const list = [];
    console.log(state.form);
    console.log(state.addColumnsList);
    state.addColumnsList.forEach((item) => {
      const obj = {
        imei: state.form.imei,
        iotCardNo: state.form.iotCardNo,
        productCode: '', // value
        recordId: route.query.encodeRecordId,
        ruleCode: '', // key
      };
      obj.ruleCode = item.dataIndex;
      obj.productCode = state.form[item.dataIndex];
      list.push(obj);
    });
    console.log(list);
    const params = {
      accessType: 'Web',
      data: list,
    };
    console.log(params);

    try {
      const resData = await addEquipmentEncodeRecordDetail(params);
      console.log('resData', resData);
      if (resData.code === '0000') {
        Message.success('新增成功');
        closeAddModal();
      }
      fetchData();
    } catch (err) {
      // you can report use errorHandler or other
    } finally {
      state.tableLoading = false;
    }
  };
  // 物联网卡号校验
  const customValidator = (value, callback) => {
    // Your custom validation logic here
    const isValid = /^\d{13}$/.test(value);

    // Call the callback with an error message if validation fails
    if (!isValid) {
      callback('请输入13位纯数字物联卡号');
    } else {
      // Call the callback with no error if validation passes
      callback();
    }
  };

  // 查询
  const fetchListQuery = (e: any) => {
    state.formQuery = e;
    state.basePagination.current = 1;
    fetchData();
  };
  // 重置
  const fetchListReset = (e: any) => {
    state.formQuery = e;
    state.basePagination.current = 1;
    fetchData();
  };
  // 下载
  const handleClickDownload = async () => {
    state.tableLoading = true;
    try {
      const params = {
        accessType: 'Web',
        data: {
          ...state.formQuery,
          pageIndex: state.basePagination.current,
          pageSize: state.basePagination.pageSize,
        },
      };
      const res: any = await exportInstallCard(params);
      if (res.code === '0000') {
        proxy.$message.success('下载成功,请点击传输管理按钮查看下载记录!');
      }
    } catch (err) {
      // you can report use errorHandler or other
    } finally {
      state.tableLoading = false;
    }
  };
  // 模板下载
  const handleUpload = async () => {
    console.log('模板下载');
    state.tableLoading = true;
    try {
      const params = {
        accessType: 'Web',
        data: {},
      };
      const res: any = await template(params);
      const elink = document.createElement('a');
      const blob = new Blob([res], { type: 'application/vnd.ms-excel' });
      elink.style.display = 'none';
      elink.download = `生成记录下载文件.xlsx`;
      elink.href = window.URL.createObjectURL(blob);
      document.body.appendChild(elink);
      elink.click();
      document.body.removeChild(elink);
      proxy.$message.success('下载成功!');
    } catch (err) {
      // you can report use errorHandler or other
    } finally {
      state.tableLoading = false;
    }
  };
  // 导入
  const handleImport = () => {
    console.log('导入');
    fileInput.value.click();
  };
  // 批量导入 - 文件上传
  const handleFileChange = async (event: any) => {
    const file = event.target.files[0];
    if (!file) {
      return;
    }
    if (file.name.split('.')[1] !== 'xlsx') {
      proxy.$message.error('请上传格式为 .xlsx 的文件');
      // 上传完成后重置input
      fileInput.value = document.createElement('input');
      fileInput.value.type = 'file';
      fileInput.value.accept =
        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
      fileInput.value.onchange = handleFileChange;
      return;
    }
    const fd = new FormData();
    fd.append('file', file);
    fd.append('recordId', route.query.encodeRecordId);
    const res: any = await importImei(fd);
    // 上传完成后重置input
    fileInput.value = document.createElement('input');
    fileInput.value.type = 'file';
    fileInput.value.accept =
      'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
    fileInput.value.onchange = handleFileChange;

    if (res.code === '0000') {
      proxy.$message.success('导入成功');
    }
  };

  // 页码切换
  const onPageChange = (current: number) => {
    state.basePagination.current = current;
    fetchData();
  };
  // 条数切换
  const onPageSizeChange = (pageSize: number) => {
    state.basePagination.pageSize = pageSize;
    fetchData();
  };
  // 详情
  const handleClickDetail = async (e: any) => {
    state.tableLoading = true;
    try {
      const params = {
        accessType: 'Web',
        data: {
          msisdn: e.msisdn,
          deviceNo: e.deviceNo,
        },
      };
      const res: any = await getInstallCardDetail(params);
      state.currentDetail = res.data || {};
      DetailModalRef.value.showModel(true, e.msisdn);
    } catch (err) {
      // you can report use errorHandler or other
    } finally {
      state.tableLoading = false;
    }
  };

  // 获取字典
  const fetchDict = async () => {
    try {
      const telecomRes: any = await getDict('telecom'); // 运营商
      state.telecomList = telecomRes.data || [];

      const providerRes: any = await getDict('provider'); // 供应商
      state.providerList = providerRes.data || [];

      const telecomStatusRes: any = await getDict('telecom_status'); // 卡状态(运营商状态)
      state.telecomStatusList = telecomStatusRes.data || [];

      const simStatusRes: any = await getDict('sim_status'); // 卡状态(sim卡状态)
      state.simStatusList = simStatusRes.data || [];
    } catch (err) {
      // you can report use errorHandler or other
    }
  };

  const pageQuery = ref(null);

  // 页面初始化信息
  onMounted(() => {
    fetchData();
    // fetchListQuery(pageQuery.value.formQuery);
    // fetchDict();
  });
</script>

<script lang="ts">
  export default {
    name: 'Recording',
  };
</script>

<style lang="less" scoped>
  .btn {
    text-align: center;
    color: white;
    line-height: 24px;
    width: 68px;
    border-radius: 4px;
    margin: auto;
  }
</style>


展示效果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

后台返回的数据
在这里插入图片描述


http://www.kler.cn/news/366152.html

相关文章:

  • day3:管道,解压缩,vim
  • 华为ICT题库-AI 人工智能部分
  • 【linux】服务器Ubuntu20.04安装cuda11.8教程
  • C语言运算符——[]下标运算符
  • Docker 部署 EMQX 一分钟极速部署
  • 实现可扩展人工智能的便捷之路:英特尔 Tiber 开发者云 + MinIO 对象存储
  • 912.排序数组(桶排序)
  • 文件下载漏洞
  • 中小企业设备管理流程优化:Spring Boot系统实现
  • react项目因eslint检测未通过而Failed to compile编译失败
  • 线性可分支持向量机的原理推导 9-18基于拉格朗日函数L(w,b,α) 对w求偏导 公式解析
  • 【设计模式-我的思考】套餐模式
  • 【有啥问啥】CLIP Adapter:提升视觉语言模型性能的利器
  • LeetCode 每周算法 10(多维动态规划、技巧)
  • 银行客户贷款行为数据挖掘与分析
  • 入侵检测算法平台部署LiteAIServer视频智能分析平台行人入侵检测算法
  • 分布式光伏发电系统电气一次部分设计(开题报告3)
  • GFF: Gated Fully Fusion for Semantic Segmentation门控融合语义分割-论文阅读笔记
  • ChainLink 预言机学习
  • 华为OD机试真题-矩形绘制-2024年OD统一考试(E卷)
  • 依赖关系是危险的
  • 深入探讨 HTTP 请求方法:GET、POST、PUT、DELETE 的实用指南
  • 泛型的特点
  • C++《vector》
  • 【实战案例】Django框架使用模板渲染视图页面及异常处理
  • Vscode连接WSL2(Ubuntu20.04)