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

vue3+ts+element-plus 开发一个页面模块的详细过程

目录、文件名均使用kebab-case(短横线分隔式)命名规范

子组件目录:./progress-ctrl/comps

1、新建页面文件 progress-ctrl.vue

<script setup lang="ts" name="progress-ctrl">

</script>

<template></template>

<style scoped lang="scss"></style>

运行效果: 

2、 页面布局

<script setup lang="ts" name="progress-ctrl">

</script>

<template>
  <el-container class="layout-container">
    <el-aside class="aside">
      <!-- 左侧受理类别节点树 -->
      受理类别节点树
    </el-aside>
    <el-container class="container">
      <el-header class="header">
        <!-- 查询栏 -->
        查询栏
      </el-header>
      <el-main class="main">
        <!-- main -->
        主项数据区域
      </el-main>
      <el-footer class="footer">
        <!-- 选项卡 -->
        选项卡
        <!-- 分页 -->
        分页
      </el-footer>
    </el-container>
  </el-container>
</template>

<style scoped lang="scss">
* {
  margin: 0;
  padding: 0;
}
.layout-container {
  height: 100%;
  border: 1px solid #ddd;
  .aside {
    width: 150px;
  }
  .container {
    border-left: 1px solid #ddd;
    .header {
      height: auto;
      min-height: 40px;
      border-bottom: 1px solid #ddd;
    }
    .main {
      min-height: 100px;
    }
    .footer {
      height: auto;
      min-height: 40px;
      border-top: 1px solid #ddd;
    }
  }
}
</style>

运行效果:

3、新建子组件

3.1、子组件-左侧树

./progress-ctrl/comps/progress-ctrl-tree.vue

<script setup lang="ts" name="progress-ctrl-tree">

</script>

<template>
  <div class="tree">
    <el-scrollbar>
      <el-tree
        :default-expand-all="true"
        :highlight-current="true"
        :expand-on-click-node="false"
        :indent="0">
      </el-tree>
    </el-scrollbar>
  </div>
</template>

<style scoped lang="scss"></style>

3.2、子组件-查询栏

./progress-ctrl/comps/progress-ctrl-search.vue

<script setup lang="ts" name="progress-ctrl-search">

</script>

<template>
  <div class="search">
    <el-form class="header-form" :inline="true" :label-width="90">
      <el-form-item class="header-form-item-330" label="受理编号:">
        <el-input clearable />
      </el-form-item>
      <el-form-item class="header-form-item-auto">
        <el-button class="btn-same-width" type="primary" plain @click="">查询</el-button>
        <el-button class="btn-same-width" type="primary" plain @click="">重置</el-button>
        <el-button class="btn-same-width" type="primary" plain @click="">更多筛选</el-button>
      </el-form-item>
    </el-form>
    <el-form class="header-form" :inline="true" :label-width="90" v-show="">
      <el-form-item class="header-form-item-330" label="受理日期:">
        <el-date-picker
          type="daterange"
          start-placeholder="开始日期"
          range-separator="至"
          end-placeholder="结束日期"
          format="YYYY-MM-DD"
          value-format="YYYY-MM-DD">
        </el-date-picker>
      </el-form-item>
      <el-form-item class="header-form-item-330" label="受检单位:">
        <el-input clearable />
      </el-form-item>
    </el-form>
  </div>
</template>

<style scoped lang="scss"></style>

3.3、子组件-主项数据

./progress-ctrl/comps/progress-ctrl-main.vue

<script setup lang="ts" name="progress-ctrl-main">

</script>

<template>
  <div class="main">
    <el-table
      ref="table"
      :border="true"
      highlight-current-row
      style="width: 100%; height: 100%">
      <el-table-column
        prop="outerApplyId"
        label="受理编号"
        width="120"
        fixed="left"
        header-align="center"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="stateDescription"
        label="状态"
        width="150"
        fixed="left"
        header-align="center"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="acceptDate"
        label="受理日期"
        width="110"
        header-align="center"
        :align="`center`"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="reportDate"
        label="报告限期"
        width="110"
        header-align="center"
        :align="`center`"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="verifyTypeName"
        label="检验类别"
        width="120"
        header-align="center"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="acceptTypeName"
        label="受理类别"
        width="150"
        header-align="center"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="acceptGroupName"
        label="受理组别"
        width="150"
        header-align="center"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="sjdwName"
        label="受检单位"
        width="300"
        header-align="center"
        sortable
        show-overflow-tooltip />
    </el-table>
  </div>
</template>

<style scoped lang="scss"></style>

3.4、子组件-选项卡

./progress-ctrl/comps/progress-ctrl-tabs.vue

<script setup lang="ts" name="progress-ctrl-tabs">

</script>

<template>
  <div class="tabs">
    <el-tabs type="border-card" @tab-click="">
      <el-tab-pane label="受理信息" name="apply">
        
      </el-tab-pane>
      <el-tab-pane label="交接信息" name="jjd">
        
      </el-tab-pane>
      <el-tab-pane label="检测信息" name="test">
       
      </el-tab-pane>
      <el-tab-pane label="报告信息" name="report">
        
      </el-tab-pane>
    </el-tabs>
  </div>
</template>

<style scoped lang="scss"></style>

3.5、子组件-分页

./progress-ctrl/comps/progress-ctrl-pagination.vue 

<script setup lang="ts" name="progress-ctrl-pagination">

</script>

<template>
  <div class="pagination">
    <el-pagination
      :page-sizes="[5]"
      background
      layout="total, prev, pager, next"
      :small="true" />
  </div>
</template>

<style scoped lang="scss"></style>

4、新建选项卡组件的子组件

4.1、孙组件-受理信息

./progress-ctrl/comps/progress-ctrl-tabs-apply.vue

<script setup lang="ts" name="progress-ctrl-tabs-apply">

</script>

<template>
  <div class="tabs-apply">
    <el-table
      ref="applyTable"
      :border="true"
      highlight-current-row
      style="width: 100%; height: 100%">
      <el-table-column
        prop="applyId"
        label="子受理编号"
        width="120"
        fixed="left"
        header-align="center"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="acceptDate"
        label="受理日期"
        width="110"
        header-align="center"
        :align="`center`"
        show-overflow-tooltip />
      <el-table-column
        prop="acceptSmallTypeName"
        label="受理小类"
        width="150"
        header-align="center"
        show-overflow-tooltip />
      <el-table-column prop="sampleKind" label="检材类别" width="150" header-align="center" show-overflow-tooltip />
      <el-table-column
        prop="keepCondition"
        label="描述信息"
        width="150"
        header-align="center"
        show-overflow-tooltip />
      <el-table-column
        prop="acceptPersonName"
        label="受理人"
        width="100"
        header-align="center"
        :align="`center`"
        show-overflow-tooltip />
      <el-table-column
        prop="state"
        label="状态"
        width="100"
        header-align="center"
        :align="`center`"
        fixed="right"
        show-overflow-tooltip />
    </el-table>
  </div>
</template>

<style scoped lang="scss"></style>

4.2、孙组件-交接信息

 ./progress-ctrl/comps/progress-ctrl-tabs-jjd.vue

<script setup lang="ts" name="progress-ctrl-tabs-jjd">

</script>

<template>
  <div class="tabs-jjd">
    <el-table
      ref="jjdTable"
      :border="true"
      highlight-current-row
      style="width: 100%; height: 100%">
      <el-table-column
        prop="blPersonName"
        label="派样人"
        width="100"
        header-align="center"
        :align="`center`"
        show-overflow-tooltip />
      <el-table-column prop="submitTime" label="派样时间" width="200" header-align="center" show-overflow-tooltip />
      <el-table-column
        prop="checkGroupName"
        label="检验组别"
        width="150"
        header-align="center"
        :align="`center`"
        show-overflow-tooltip />
      <el-table-column
        prop="receivePersonName"
        label="接样人"
        width="100"
        header-align="center"
        :align="`center`"
        show-overflow-tooltip />
      <el-table-column
        prop="receiveTime"
        label="接样时间"
        width="200"
        header-align="center"
        show-overflow-tooltip />
      <el-table-column
        prop="deadlineTime"
        label="交接限期"
        width="110"
        header-align="center"
        :align="`center`"
        show-overflow-tooltip />
      <el-table-column
        prop="state"
        label="状态"
        width="100"
        header-align="center"
        :align="`center`"
        fixed="right"
        show-overflow-tooltip />
    </el-table>
  </div>
</template>

<style scoped lang="scss"></style>

 4.3、孙组件-检测信息

 ./progress-ctrl/comps/progress-ctrl-tabs-test.vue

<script setup lang="ts" name="progress-ctrl-tabs-test">

</script>

<template>
  <div class="tabs-test">
    <el-table
      ref="sampleItemResultTable"
      :border="true"
      highlight-current-row
      style="width: 100%; height: 100%">
      <el-table-column
        prop="sampleNo"
        label="样品编号"
        width="120"
        header-align="center"
        fixed
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="sampleName"
        label="样品名称"
        width="150"
        header-align="center"
        fixed
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="itemName"
        label="检验项目"
        width="150"
        header-align="center"
        fixed
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="result"
        label="结果"
        width="120"
        header-align="center"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="conclusion"
        label="结论"
        width="80"
        header-align="center"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="state"
        label="状态"
        width="100"
        header-align="center"
        :align="`center`"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="standardScript"
        label="标准值"
        width="120"
        header-align="center"
        sortable
        show-overflow-tooltip />
      <el-table-column prop="unit" label="单位" width="100" header-align="center" sortable show-overflow-tooltip />
      <el-table-column
        prop="ffbzId"
        label="检测标准编号"
        width="200"
        header-align="center"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="ffbzName"
        label="检测标准名称"
        width="300"
        header-align="center"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="verifyMethod"
        label="检验方法"
        width="150"
        header-align="center"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="person"
        label="检验员"
        width="100"
        header-align="center"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="allotTime"
        label="分派时间"
        width="200"
        header-align="center"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="submitTime"
        label="检测时间"
        width="200"
        header-align="center"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="deadlineDate"
        label="检测限期"
        width="110"
        header-align="center"
        :align="`center`"
        sortable
        show-overflow-tooltip />
    </el-table>
  </div>
</template>

<style scoped lang="scss"></style>

4.4、孙组件-报告信息

  ./progress-ctrl/comps/progress-ctrl-tabs-report.vue

<script setup lang="ts" name="progress-ctrl-tabs-report">

</script>

<template>
  <div class="tabs-report">
    <el-table
      ref="reportTable"
      :border="true"
      highlight-current-row
      style="width: 100%; height: 100%">
      <el-table-column
        prop="deptName"
        label="所属部门"
        width="150"
        header-align="center"
        fixed="left"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="type"
        label="类型"
        width="100"
        header-align="center"
        :align="`center`"
        fixed="left"
        sortable
        show-overflow-tooltip
        :formatter="(row: any) => { return row.type === 1 ? `检验报告` : `评价报告` }" />
      <el-table-column
        prop="reportTypeName"
        label="报告类型"
        width="200"
        header-align="center"
        fixed="left"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="hbPerson"
        label="编制人"
        width="100"
        header-align="center"
        :align="`center`"
        show-overflow-tooltip />
      <el-table-column
        prop="hbDate"
        label="编制日期"
        width="110"
        header-align="center"
        :align="`center`"
        show-overflow-tooltip />
      <el-table-column
        prop="hdPerson"
        label="核对人"
        width="100"
        header-align="center"
        :align="`center`"
        show-overflow-tooltip />
      <el-table-column
        prop="hdDate"
        label="核对日期"
        width="110"
        header-align="center"
        :align="`center`"
        show-overflow-tooltip />
      <el-table-column
        prop="hfPerson"
        label="签发人"
        width="100"
        header-align="center"
        :align="`center`"
        show-overflow-tooltip />
      <el-table-column
        prop="hfDate"
        label="签发日期"
        width="110"
        header-align="center"
        :align="`center`"
        show-overflow-tooltip />
      <el-table-column
        prop="reportDate"
        label="报告限期"
        width="110"
        header-align="center"
        :align="`center`"
        show-overflow-tooltip />
      <el-table-column
        prop="state"
        label="状态"
        width="100"
        header-align="center"
        :align="`center`"
        fixed="right"
        show-overflow-tooltip />
    </el-table>
  </div>
</template>

<style scoped lang="scss"></style>

5、选项卡子组件导入使用子组件

<script setup lang="ts" name="progress-ctrl-tabs">
import ProgressCtrlTabsApply from './progress-ctrl-tabs-apply.vue';
import ProgressCtrlTabsJJD from './progress-ctrl-tabs-jjd.vue';
import ProgressCtrlTabsTest from './progress-ctrl-tabs-test.vue';
import ProgressCtrlTabsReport from './progress-ctrl-tabs-report.vue';

</script>

<template>
  <div class="tabs">
    <el-tabs type="border-card" @tab-click="">
      <el-tab-pane label="受理信息" name="apply">
        <ProgressCtrlTabsApply />
      </el-tab-pane>
      <el-tab-pane label="交接信息" name="jjd">
        <ProgressCtrlTabsJJD />
      </el-tab-pane>
      <el-tab-pane label="检测信息" name="test">
        <ProgressCtrlTabsTest />
      </el-tab-pane>
      <el-tab-pane label="报告信息" name="report">
        <ProgressCtrlTabsReport />
      </el-tab-pane>
    </el-tabs>
  </div>
</template>

<style scoped lang="scss"></style>

6、父组件导入使用子组件

<script setup lang="ts" name="progress-ctrl">
import ProgressCtrlTree from './progress-ctrl/comps/progress-ctrl-tree.vue';
import ProgressCtrlSearch from './progress-ctrl/comps/progress-ctrl-search.vue';
import ProgressCtrlMain from './progress-ctrl/comps/progress-ctrl-main.vue';
import ProgressCtrlTabs from './progress-ctrl/comps/progress-ctrl-tabs.vue';
import ProgressCtrlPagination from './progress-ctrl/comps/progress-ctrl-pagination.vue';

</script>

<template>
  <el-container class="layout-container">
    <el-aside class="aside">
      <!-- 左侧受理类别节点树 -->
      <ProgressCtrlTree />
    </el-aside>
    <el-container class="container">
      <el-header class="header">
        <!-- 查询栏 -->
        <ProgressCtrlSearch />
      </el-header>
      <el-main class="main">
        <!-- main -->
        <ProgressCtrlMain />
      </el-main>
      <el-footer class="footer">
        <!-- 选项卡 -->
        <ProgressCtrlTabs />
        <!-- 分页 -->
        <ProgressCtrlPagination />
      </el-footer>
    </el-container>
  </el-container>
</template>

<style scoped lang="scss">
* {
  margin: 0;
  padding: 0;
}
.layout-container {
  height: 100%;
  border: 1px solid #ddd;
  .aside {
    width: 150px;
  }
  .container {
    border-left: 1px solid #ddd;
    .header {
      height: auto;
      min-height: 40px;
      border-bottom: 1px solid #ddd;
    }
    .main {
      min-height: 100px;
    }
    .footer {
      height: auto;
      min-height: 40px;
      border-top: 1px solid #ddd;
    }
  }
}
</style>

运行效果:

7、数据模型业务逻辑处理

7.1、数据定义

import type { Component } from "vue";

export interface ITree {
  // 树节点的label,受理类别名称
  label: string;
  // 树节点的value,受理类别代码
  value: string;
  // 树节点的图标
  icon?: Component;
  // 图标颜色
  iconColor?: string;
  // 子节点
  children?: ITree[];
}

// 分页对象
interface IPage {
  // 当前页码
  page: number
  // 每页显示数量                   
  size: number                   
}

// 查询对象
export interface IQueryObj {
  // 分页器
  pageHelper: IPage
  // 受理编号
  outerApplyId?: string  
  // 受检单位        
  sjdwName?: string  
  // 受理类别            
  acceptType?: string  
  // 受理开始日期          
  acceptDateBegin?: string      
  // 受理结束日期 
  acceptDateEnd?: string         
}

export interface IApplyBasicInfo {
  // 受理编号
  outerApplyId: string
  // 状态
  stateDescription: string
  // 受理日期
  acceptDate: string
  // 报告限期
  reportDate: string
  // 检验类别
  verifyTypeName: string
  // 受理类别
  acceptTypeName: string
  // 受理组别
  acceptGroupName: string
  // 受检单位
  sjdwName: string
}

// 结构继承使用 extends
// import type { Apply, JJD, SampleItemResult, ReportSimpleVO } from "@/interface";
// export interface IApply extends Apply {
// }
// export interface IJJD extends JJD {
// }
// export interface ITest extends SampleItemResult {
// }
// export interface IReport extends ReportSimpleVO {
// }

7.2、数据处理

import { defineStore } from "pinia";
import { ref } from "vue";
import { acceptTypeOptionsByUserNameService } from "@/api/selectOptions";
import type { IApplyBasicInfo, IQueryObj, ITree } from "../types";
import {
  applyBasicInfoSjkByQueryDTOService,
  applyBasicInfoYztByQueryDTOService,
  applyBasicInfoSjkAllService,
  applyBasicInfoSjkTodayService,
  applyBasicInfoSjk3DayService,
  applyBasicInfoSjkRecentService,
  applyBasicInfoSjkOverdueService
} from "@/api/applyBasicInfo";
// 使用 as 重命名导出的类型
import type { Apply as IApply, JJD as IJJD, SampleItemResult as ITest, ReportSimpleVO as IReport } from "@/interface";
import { applyDataByOuterApplyIdService } from "@/api/apply";
import { jjdDataByOuterApplyIdService } from "@/api/jjd";
// 使用 as 重命名导出的方法
import { sampleItemResultByOuterApplyIdService as testDataByOuterApplyIdService } from "@/api/sampleItemResult";
import { reportDataByOuterApplyIdService } from "@/api/report";

const useProgressCtrlStore = defineStore("progressCtrl", () => {
  // 页面实例数据
  // 受理类别列表数据
  const acceptTypeListData = ref<{ label: string; value: string }[]>([]);
  // 树数据
  const treeData = ref<ITree[]>([]);
  // 受理列表数据
  const applyBasicInfoListData = ref<IApplyBasicInfo[]>([]);
  // 查询对象
  const queryObj = ref<IQueryObj>({
    pageHelper: {
      page: 1,
      size: 5
    },
    acceptType: "",
    outerApplyId: "",
    sjdwName: "",
    acceptDateBegin: "",
    acceptDateEnd: ""
  });
  // 当前点击选择的树节点
  const currentNode = ref<ITree>();
  // 当前表格选择行
  const currentTableRow = ref<IApplyBasicInfo>();
  // 当前选中的选项卡名称
  const activeTabName = ref("test");
  // 子受理列表数据
  const applyListData = ref<IApply[]>([]);
  // 交接单列表数据
  const jjdListData = ref<IJJD[]>([]);
  // 检验列表数据
  const testListData = ref<ITest[]>([]);
  // 报告列表数据
  const reportListData = ref<IReport[]>([]);

  // 发送网络请求,获取受理类别列表数据
  const postAcceptTypeListDataService = async () => {
    let result = await acceptTypeOptionsByUserNameService();
    acceptTypeListData.value = result.data;
  };
  // 发送网络请求,获取受理列表数据
  const postApplyBasicInfoListDataService = async () => {
    // 前置处理,清空数据
    clearData();

    let result;
    // 通过树节点数据,获取受理列表数据
    if (
      !queryObj.value.outerApplyId &&
      !queryObj.value.sjdwName &&
      !queryObj.value.acceptDateBegin &&
      !queryObj.value.acceptDateEnd
    ) {
      queryObj.value.acceptType = currentNode.value?.value;
      switch (currentNode.value?.value) {
        case "#ALL#":
          // 发送网络请求,获取受监控的受理列表数据(所有)
          result = await applyBasicInfoSjkAllService(queryObj.value);
          break;
        case "#today#":
          // 发送网络请求,获取受监控的受理列表数据(今天内到期)
          result = await applyBasicInfoSjkTodayService(queryObj.value);
        case "#3day#":
          // 发送网络请求,获取受监控的受理单(三天内到期)
          result = await applyBasicInfoSjk3DayService(queryObj.value);
          break;
        case "#recent#":
          // 发送网络请求,获取受监控的受理单(最近30天)
          result = await applyBasicInfoSjkRecentService(queryObj.value);
          break;
        case "#overdue#":
          // 发送网络请求,获取受监控的受理单(已超期)
          result = await applyBasicInfoSjkOverdueService(queryObj.value);
          break;
        default:
          // 发送网络请求,获取受监控的受理单(树节点)
          result = await applyBasicInfoSjkByQueryDTOService(queryObj.value);
          break;
      }
    }
    // 通过查询数据,获取受理列表数据
    else {
      queryObj.value.acceptType = currentNode.value?.value;
      // 发送网络请求,获取受监控的受理列表数据(有状态描述)
      result = await applyBasicInfoYztByQueryDTOService(queryObj.value);
    }
    applyBasicInfoListData.value = result.data.rows;
  };

  function clearData() {
    applyBasicInfoListData.value = [];
    applyListData.value = [];
    jjdListData.value = [];
    testListData.value = [];
    reportListData.value = [];
  }

  // 发送网络请求,获取子受理列表数据
  const postApplyListDataService = async () => {
    if (!currentTableRow.value) return;
    let result = await applyDataByOuterApplyIdService(currentTableRow.value?.outerApplyId);
    applyListData.value = result.data;
  };

  // 发送网络请求,获取交接单列表数据
  const postJJDListDataService = async () => {
    if (!currentTableRow.value) return;
    let result = await jjdDataByOuterApplyIdService(currentTableRow.value?.outerApplyId);
    jjdListData.value = result.data;
  };

  // 发送网络请求,获取检验列表数据
  const postTestListDataService = async () => {
    if (!currentTableRow.value) return;
    let result = await testDataByOuterApplyIdService(currentTableRow.value?.outerApplyId);
    testListData.value = result.data;
  };

  // 发送网络请求,获取报告列表数据
  const postReportListDataService = async () => {
    if (!currentTableRow.value) return;
    let result = await reportDataByOuterApplyIdService(currentTableRow.value?.outerApplyId);
    reportListData.value = result.data;
  };

  // 暴露供给外部访问的属性和方法
  return {
    acceptTypeListData,
    treeData,
    applyBasicInfoListData,
    queryObj,
    currentTableRow,
    currentNode,
    activeTabName,
    applyListData,
    jjdListData,
    testListData,
    reportListData,
    postAcceptTypeListDataService,
    postApplyBasicInfoListDataService,
    postApplyListDataService,
    postJJDListDataService,
    postTestListDataService,
    postReportListDataService,
    clearData
  };
});

// 默认导出 store 实例
export default useProgressCtrlStore;

8、数据邦定(VM:视图+数据模型)

8.1、实例组件(父组件) progress-ctrl.vue

<script setup lang="ts" name="progress-ctrl">
import ProgressCtrlTree from './progress-ctrl/comps/progress-ctrl-tree.vue';
import ProgressCtrlSearch from './progress-ctrl/comps/progress-ctrl-search.vue';
import ProgressCtrlMain from './progress-ctrl/comps/progress-ctrl-main.vue';
import ProgressCtrlTabs from './progress-ctrl/comps/progress-ctrl-tabs.vue';
import ProgressCtrlPagination from './progress-ctrl/comps/progress-ctrl-pagination.vue';

</script>

<template>
  <el-container class="layout-container">
    <el-aside class="aside">
      <!-- 左侧受理类别节点树 -->
      <ProgressCtrlTree />
    </el-aside>
    <el-container class="container">
      <el-header class="header">
        <!-- 查询栏 -->
        <ProgressCtrlSearch />
      </el-header>
      <el-main class="main">
        <!-- main -->
        <ProgressCtrlMain />
      </el-main>
      <el-footer class="footer">
        <!-- 选项卡 -->
        <ProgressCtrlTabs />
        <!-- 分页 -->
        <ProgressCtrlPagination />
      </el-footer>
    </el-container>
  </el-container>
</template>

<style scoped lang="scss">
* {
  margin: 0;
  padding: 0;
}
.layout-container {
  height: 100%;
  border: 1px solid #ddd;
  .aside {
    width: 150px;
  }
  .container {
    border-left: 1px solid #ddd;
    .header {
      height: auto;
      min-height: 40px;
      border-bottom: 1px solid #ddd;
    }
    .main {
      min-height: 100px;
    }
    .footer {
      height: auto;
      min-height: 40px;
      border-top: 1px solid #ddd;
    }
  }
}
</style>

8.2、子组件(左侧树) progress-ctrl-tree.vue

<script setup lang="ts" name="progress-ctrl-tree">
import { onMounted, ref, type Component, markRaw } from "vue";
import type { ITree } from "@/views/query/progress-ctrl/types";
import useProgressCtrlStore from "@/views/query/progress-ctrl/stores";
import { Clock } from "@element-plus/icons-vue";

const progressCtrlStore = useProgressCtrlStore();

onMounted(async () => {
  // 获取受理类别列表数据
  await progressCtrlStore.postAcceptTypeListDataService();
  // 创建树形结构数据
  createTreeData(progressCtrlStore.acceptTypeListData);
});

// 创建树形结构数据
function createTreeData(data: any[]) {
  let childrenData = data.map((item) => {
    let { label = "", value = "" } = { ...item };
    return {
      label: label as string,
      value: value as string
    };
  });

  progressCtrlStore.treeData.push({
    label: "受理类别",
    value: "#ALL#",
    children: childrenData
  });
  progressCtrlStore.treeData.push({
    label: "今天内到期",
    // 组件本身不需要响应式处理,使用 markRaw 包裹组件,标记组件为非响应式
    icon: markRaw(Clock),
    iconColor: "blue",
    value: "#today#"
  });
  progressCtrlStore.treeData.push({
    label: "三天内到期",
    // 组件本身不需要响应式处理,使用 markRaw 包裹组件,标记组件为非响应式
    icon: markRaw(Clock),
    iconColor: "orange",
    value: "#3day#"
  });
  progressCtrlStore.treeData.push({
    label: "最近30天",
    // 组件本身不需要响应式处理,使用 markRaw 包裹组件,标记组件为非响应式
    icon: markRaw(Clock),
    iconColor: "green",
    value: "#recent#"
  });
  progressCtrlStore.treeData.push({
    label: "已超期",
    // 组件本身不需要响应式处理,使用 markRaw 包裹组件,标记组件为非响应式
    icon: markRaw(Clock),
    iconColor: "red",
    value: "#overdue#"
  });
}

// 点击树节点
const onTreeNodeClick = async (node: ITree) => {
  // 防止在同一树节点上点击多次,产生多次请求
  if (progressCtrlStore.currentNode && progressCtrlStore.currentNode.value === node.value) {
    return;
  }
  progressCtrlStore.currentNode = node;

  // 获取受监控的受理单
  await progressCtrlStore.postApplyBasicInfoListDataService();
};
</script>

<template>
  <div class="tree">
    <el-scrollbar>
      <el-tree
        :data="progressCtrlStore.treeData"
        :default-expand-all="true"
        :highlight-current="true"
        :expand-on-click-node="false"
        :indent="0"
        @node-click="onTreeNodeClick">
      </el-tree>
    </el-scrollbar>
  </div>
</template>

<style scoped lang="scss"></style>

8.3、子组件(查询栏) progress-ctrl-search.vue

<script setup lang="ts" name="progress-ctrl-search">
import useProgressCtrlStore from "@/views/query/progress-ctrl/stores";
import { ref } from "vue";

const progressCtrlStore = useProgressCtrlStore();
// 更多筛选
const moreFilterVisible = ref(false);
// 受理日期范围
const acceptDate = ref<string[]>([]);

// 查询
import { ElMessage } from "element-plus";
const onQueryClick = async () => {
  progressCtrlStore.queryObj.acceptDateBegin = "";
  progressCtrlStore.queryObj.acceptDateEnd = "";
  // 从范围日期组件中,获取开始日期和结束日期
  if (acceptDate.value.length) {
    progressCtrlStore.queryObj.acceptDateBegin = acceptDate.value[0];
    progressCtrlStore.queryObj.acceptDateEnd = acceptDate.value[1];
  }

  // 检查查询参数
  if (
    !progressCtrlStore.queryObj.acceptDateBegin &&
    !progressCtrlStore.queryObj.acceptDateEnd &&
    !progressCtrlStore.queryObj.outerApplyId &&
    !progressCtrlStore.queryObj.sjdwName
  ) {
    ElMessage.warning("请输入查询条件!");
    return;
  }

  // 获取受监控的受理列表数据
  await progressCtrlStore.postApplyBasicInfoListDataService();
};

// 重置
const onResetClick = () => {
  // 清空日期选择器
  acceptDate.value.length = 0;
  // 清空查询条件
  progressCtrlStore.queryObj.outerApplyId = "";
  progressCtrlStore.queryObj.sjdwName = "";
  progressCtrlStore.queryObj.acceptDateBegin = "";
  progressCtrlStore.queryObj.acceptDateEnd = "";
  // 清空数据
  progressCtrlStore.clearData();
};

// 更多筛选
const onMoreFilterClick = () => {
  moreFilterVisible.value = !moreFilterVisible.value;
};
</script>

<template>
  <div class="search">
    <el-form class="header-form" v-model="progressCtrlStore.queryObj" :inline="true" :label-width="90">
      <el-form-item class="header-form-item-330" label="受理编号:">
        <el-input v-model="progressCtrlStore.queryObj.outerApplyId" clearable />
      </el-form-item>
      <el-form-item class="header-form-item-auto">
        <el-button class="btn-same-width" type="primary" plain @click="onQueryClick">查询</el-button>
        <el-button class="btn-same-width" type="primary" plain @click="onResetClick">重置</el-button>
        <el-button class="btn-same-width" type="primary" plain @click="onMoreFilterClick">更多筛选</el-button>
      </el-form-item>
    </el-form>
    <el-form
      class="header-form"
      v-model="progressCtrlStore.queryObj"
      :inline="true"
      :label-width="90"
      v-show="moreFilterVisible">
      <el-form-item class="header-form-item-330" label="受理日期:">
        <el-date-picker
          v-model="acceptDate"
          type="daterange"
          start-placeholder="开始日期"
          range-separator="至"
          end-placeholder="结束日期"
          format="YYYY-MM-DD"
          value-format="YYYY-MM-DD">
        </el-date-picker>
      </el-form-item>
      <el-form-item class="header-form-item-330" label="受检单位:">
        <el-input v-model="progressCtrlStore.queryObj.sjdwName" clearable />
      </el-form-item>
    </el-form>
  </div>
</template>

<style scoped lang="scss"></style>

8.4、子组件(主项数据) progress-ctrl-main.vue

<script setup lang="ts" name="progress-ctrl-main">
import useProgressCtrlStore from "../stores";

const progressCtrlStore = useProgressCtrlStore();

// 点击表格的行
const onTableRowClick = (row: any, column: any) => {
  progressCtrlStore.currentTableRow = row;
};
</script>

<template>
  <div class="main">
    <el-table
      ref="table"
      :data="progressCtrlStore.applyBasicInfoListData"
      :border="true"
      highlight-current-row
      style="width: 100%; height: 100%"
      @row-click="onTableRowClick">
      <el-table-column
        prop="outerApplyId"
        label="受理编号"
        width="120"
        fixed="left"
        header-align="center"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="stateDescription"
        label="状态"
        width="150"
        fixed="left"
        header-align="center"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="acceptDate"
        label="受理日期"
        width="110"
        header-align="center"
        :align="`center`"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="reportDate"
        label="报告限期"
        width="110"
        header-align="center"
        :align="`center`"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="verifyTypeName"
        label="检验类别"
        width="120"
        header-align="center"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="acceptTypeName"
        label="受理类别"
        width="150"
        header-align="center"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="acceptGroupName"
        label="受理组别"
        width="150"
        header-align="center"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="sjdwName"
        label="受检单位"
        width="300"
        header-align="center"
        sortable
        show-overflow-tooltip />
    </el-table>
  </div>
</template>

<style scoped lang="scss"></style>

8.5、子组件(选项卡) progress-ctrl-tabs.vue

<script setup lang="ts" name="progress-ctrl-tabs">
import ProgressCtrlTabsApply from './progress-ctrl-tabs-apply.vue';
import ProgressCtrlTabsJJD from './progress-ctrl-tabs-jjd.vue';
import ProgressCtrlTabsTest from './progress-ctrl-tabs-test.vue';
import ProgressCtrlTabsReport from './progress-ctrl-tabs-report.vue';
import useProgressCtrlStore from '../stores';
import type { TabsPaneContext } from "element-plus";

const progressCtrlStore = useProgressCtrlStore();

// 切换tab页
const onTabClick = async (tab: TabsPaneContext, event: Event) => {
  progressCtrlStore.activeTabName = tab.paneName as string;
};
</script>

<template>
  <div class="tabs">
    <el-tabs :model-value="progressCtrlStore.activeTabName" type="border-card" @tab-click="onTabClick">
      <el-tab-pane label="受理信息" name="apply">
        <ProgressCtrlTabsApply />
      </el-tab-pane>
      <el-tab-pane label="交接信息" name="jjd">
        <ProgressCtrlTabsJJD />
      </el-tab-pane>
      <el-tab-pane label="检测信息" name="test">
        <ProgressCtrlTabsTest />
      </el-tab-pane>
      <el-tab-pane label="报告信息" name="report">
        <ProgressCtrlTabsReport />
      </el-tab-pane>
    </el-tabs>
  </div>
</template>

<style scoped lang="scss"></style>

8.6、孙组件(选项卡的子组件-受理信息)progress-ctrl-tabs-apply.vue

<script setup lang="ts" name="progress-ctrl-tabs-apply">
import useProgressCtrlStore from "../stores";
import { computed, watch } from "vue";

const progressCtrlStore = useProgressCtrlStore();
const tableData = computed(() => progressCtrlStore.applyListData);

watch(
  () => progressCtrlStore.currentTableRow,
  async () => {
    if (progressCtrlStore.activeTabName === "apply") {
      await progressCtrlStore.postApplyListDataService();
    }
  }
);

watch(
  () => progressCtrlStore.activeTabName,
  async () => {
    if (progressCtrlStore.activeTabName === "apply") {
      await progressCtrlStore.postApplyListDataService();
    }
  }
);
</script>

<template>
  <div class="tabs-apply">
    <el-table ref="applyTable" :data="tableData" :border="true" highlight-current-row style="width: 100%; height: 100%">
      <el-table-column
        prop="applyId"
        label="子受理编号"
        width="120"
        fixed="left"
        header-align="center"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="acceptDate"
        label="受理日期"
        width="110"
        header-align="center"
        :align="`center`"
        show-overflow-tooltip />
      <el-table-column
        prop="acceptSmallTypeName"
        label="受理小类"
        width="150"
        header-align="center"
        show-overflow-tooltip />
      <el-table-column prop="sampleKind" label="检材类别" width="150" header-align="center" show-overflow-tooltip />
      <el-table-column prop="keepCondition" label="描述信息" width="150" header-align="center" show-overflow-tooltip />
      <el-table-column
        prop="acceptPersonName"
        label="受理人"
        width="100"
        header-align="center"
        :align="`center`"
        show-overflow-tooltip />
      <el-table-column
        prop="state"
        label="状态"
        width="100"
        header-align="center"
        :align="`center`"
        fixed="right"
        show-overflow-tooltip />
    </el-table>
  </div>
</template>

<style scoped lang="scss"></style>

8.7、孙组件(选项卡的子组件-交接信息)progress-ctrl-tabs-jjd.vue

<script setup lang="ts" name="progress-ctrl-tabs-jjd">
import useProgressCtrlStore from "../stores";
import { computed, watch } from "vue";

const progressCtrlStore = useProgressCtrlStore(); 
const tableData = computed(() => progressCtrlStore.jjdListData); 

watch(
  () => progressCtrlStore.currentTableRow,
  async () => {
    if (progressCtrlStore.activeTabName === "jjd") {
      await progressCtrlStore.postJJDListDataService();
    }
  }
);

watch(
  () => progressCtrlStore.activeTabName,
  async () => {
    if (progressCtrlStore.activeTabName === "jjd") {
      await progressCtrlStore.postJJDListDataService();
    }
  }
);
</script>

<template>
  <div class="tabs-jjd">
    <el-table ref="jjdTable" :data="tableData" :border="true" highlight-current-row style="width: 100%; height: 100%">
      <el-table-column
        prop="blPersonName"
        label="派样人"
        width="100"
        header-align="center"
        :align="`center`"
        show-overflow-tooltip />
      <el-table-column prop="submitTime" label="派样时间" width="200" header-align="center" show-overflow-tooltip />
      <el-table-column
        prop="checkGroupName"
        label="检验组别"
        width="150"
        header-align="center"
        :align="`center`"
        show-overflow-tooltip />
      <el-table-column
        prop="receivePersonName"
        label="接样人"
        width="100"
        header-align="center"
        :align="`center`"
        show-overflow-tooltip />
      <el-table-column prop="receiveTime" label="接样时间" width="200" header-align="center" show-overflow-tooltip />
      <el-table-column
        prop="deadlineTime"
        label="交接限期"
        width="110"
        header-align="center"
        :align="`center`"
        show-overflow-tooltip />
      <el-table-column
        prop="state"
        label="状态"
        width="100"
        header-align="center"
        :align="`center`"
        fixed="right"
        show-overflow-tooltip />
    </el-table>
  </div>
</template>

<style scoped lang="scss"></style>

8.8、孙组件(选项卡的子组件-检测信息)progress-ctrl-tabs-test.vue

<script setup lang="ts" name="progress-ctrl-tabs-test">
import useProgressCtrlStore from "../stores";
import { computed, watch } from "vue";

const progressCtrlStore = useProgressCtrlStore();
const tableData = computed(() => progressCtrlStore.testListData);

watch(
  () => progressCtrlStore.currentTableRow,
  async () => {
    if (progressCtrlStore.activeTabName === "test") {
      await progressCtrlStore.postTestListDataService();
    }
  }
);

watch(
  () => progressCtrlStore.activeTabName,
  async () => {
    if (progressCtrlStore.activeTabName === "test") {
      await progressCtrlStore.postTestListDataService();
    }
  }
);
</script>

<template>
  <div class="tabs-test">
    <el-table ref="testTable" :data="tableData" :border="true" highlight-current-row style="width: 100%; height: 100%">
      <el-table-column
        prop="sampleNo"
        label="样品编号"
        width="120"
        header-align="center"
        fixed
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="sampleName"
        label="样品名称"
        width="150"
        header-align="center"
        fixed
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="itemName"
        label="检验项目"
        width="150"
        header-align="center"
        fixed
        sortable
        show-overflow-tooltip />
      <el-table-column prop="result" label="结果" width="120" header-align="center" sortable show-overflow-tooltip />
      <el-table-column prop="conclusion" label="结论" width="80" header-align="center" sortable show-overflow-tooltip />
      <el-table-column
        prop="state"
        label="状态"
        width="100"
        header-align="center"
        :align="`center`"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="standardScript"
        label="标准值"
        width="120"
        header-align="center"
        sortable
        show-overflow-tooltip />
      <el-table-column prop="unit" label="单位" width="100" header-align="center" sortable show-overflow-tooltip />
      <el-table-column
        prop="ffbzId"
        label="检测标准编号"
        width="200"
        header-align="center"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="ffbzName"
        label="检测标准名称"
        width="300"
        header-align="center"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="verifyMethod"
        label="检验方法"
        width="150"
        header-align="center"
        sortable
        show-overflow-tooltip />
      <el-table-column prop="person" label="检验员" width="100" header-align="center" sortable show-overflow-tooltip />
      <el-table-column
        prop="allotTime"
        label="分派时间"
        width="200"
        header-align="center"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="submitTime"
        label="检测时间"
        width="200"
        header-align="center"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="deadlineDate"
        label="检测限期"
        width="110"
        header-align="center"
        :align="`center`"
        sortable
        show-overflow-tooltip />
    </el-table>
  </div>
</template>

<style scoped lang="scss"></style>

8.9、孙组件(选项卡的子组件-报告信息)progress-ctrl-tabs-report.vue

<script setup lang="ts" name="progress-ctrl-tabs-report">
import useProgressCtrlStore from "../stores";
import { watch } from "vue";
import { storeToRefs } from "pinia";

const progressCtrlStore = useProgressCtrlStore();
const { reportListData } = storeToRefs(progressCtrlStore);
const tableData = reportListData.value;

watch(
  () => progressCtrlStore.currentTableRow,
  async () => {
    if (progressCtrlStore.activeTabName === "report") {
      await progressCtrlStore.postReportListDataService();
    }
  }
);

watch(
  () => progressCtrlStore.activeTabName,
  async () => {
    if (progressCtrlStore.activeTabName === "report") {
      await progressCtrlStore.postReportListDataService();
    }
  }
);
</script>

<template>
  <div class="tabs-report">
    <el-table
      ref="reportTable"
      :data="tableData"
      :border="true"
      highlight-current-row
      style="width: 100%; height: 100%">
      <el-table-column
        prop="deptName"
        label="所属部门"
        width="150"
        header-align="center"
        fixed="left"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="type"
        label="类型"
        width="100"
        header-align="center"
        :align="`center`"
        fixed="left"
        sortable
        show-overflow-tooltip
        :formatter="(row: any) => { return row.type === 1 ? `检验报告` : `评价报告` }" />
      <el-table-column
        prop="reportTypeName"
        label="报告类型"
        width="200"
        header-align="center"
        fixed="left"
        sortable
        show-overflow-tooltip />
      <el-table-column
        prop="hbPerson"
        label="编制人"
        width="100"
        header-align="center"
        :align="`center`"
        show-overflow-tooltip />
      <el-table-column
        prop="hbDate"
        label="编制日期"
        width="110"
        header-align="center"
        :align="`center`"
        show-overflow-tooltip />
      <el-table-column
        prop="hdPerson"
        label="核对人"
        width="100"
        header-align="center"
        :align="`center`"
        show-overflow-tooltip />
      <el-table-column
        prop="hdDate"
        label="核对日期"
        width="110"
        header-align="center"
        :align="`center`"
        show-overflow-tooltip />
      <el-table-column
        prop="hfPerson"
        label="签发人"
        width="100"
        header-align="center"
        :align="`center`"
        show-overflow-tooltip />
      <el-table-column
        prop="hfDate"
        label="签发日期"
        width="110"
        header-align="center"
        :align="`center`"
        show-overflow-tooltip />
      <el-table-column
        prop="reportDate"
        label="报告限期"
        width="110"
        header-align="center"
        :align="`center`"
        show-overflow-tooltip />
      <el-table-column
        prop="state"
        label="状态"
        width="100"
        header-align="center"
        :align="`center`"
        fixed="right"
        show-overflow-tooltip />
    </el-table>
  </div>
</template>

<style scoped lang="scss"></style>

8.10、子组件(分页) progress-ctrl-pagination.vue

<script setup lang="ts" name="progress-ctrl-pagination">
import useProgressCtrlStore from "../stores";

const progressCtrlStore = useProgressCtrlStore();

// 改变页码、显示数量,重新获取数据
const onPageOrSizeChange = async (currentPage: number, pageSize: number) => {
  progressCtrlStore.queryObj.pageHelper.page = currentPage;
  progressCtrlStore.queryObj.pageHelper.size = pageSize;
  // 获取受理列表数据
  await progressCtrlStore.postApplyBasicInfoSjkByQueryDTOListDataService();
};
</script>

<template>
  <div class="pagination">
    <el-pagination
      :page-sizes="[5]"
      v-model:page-size="progressCtrlStore.queryObj.pageHelper.size"
      v-model:current-page="progressCtrlStore.queryObj.pageHelper.page"
      background
      layout="total, prev, pager, next"
      :small="true"
      @change="onPageOrSizeChange" />
  </div>
</template>

<style scoped lang="scss"></style>

运行效果:

9、设置样式

9.1、子组件(左侧树) progress-ctrl-tree.vue

<template>
  <div class="tree">
    <el-scrollbar>
      <el-tree
        :data="progressCtrlStore.treeData"
        :default-expand-all="true"
        :highlight-current="true"
        :expand-on-click-node="false"
        :indent="0"
        @node-click="onTreeNodeClick">
        <!-- 自定义节点内容,点击的节点字体变色加粗 -->
        <!-- 动态样式:通过<template #default>插槽自定义节点内容,使用:style绑定根据当前选择的节点值currentNode.value动态设置color和fontWeight -->
          <template #default="{ node, data }">
          <!-- 使用动态组件,添加图标,使用:style动态样式,设置图标大小和颜色 -->
          <component
            :is="data.icon"
            :style="{ width: `18px`, height: `18px`, color: data.iconColor, marginLeft: `5px` }" />
          <span
            :style="{
              color: progressCtrlStore.currentNode?.value === data.value ? data.iconColor ?? `#409EFF` : `#606266`,
              fontWeight: progressCtrlStore.currentNode?.value === data.value ? `bold` : `normal`,
              marginLeft: `5px`
            }">
            {{ node.label }}
          </span>
        </template>
      </el-tree>
    </el-scrollbar>
  </div>
</template>

<style scoped lang="scss">
.tree {
  width: 100%;
  height: 100%;
  overflow: auto;
}
// 树节点
::v-deep .el-tree-node__content {
  height: 32px;
}
// 树节点展开图标
:deep .el-tree-node__content > .el-tree-node__expand-icon {
  padding: 0;
}
</style>

运行效果:

9.2、子组件(查询栏) progress-ctrl-search.vue

<style scoped lang="scss">
* {
  margin: 0;
  padding: 0;
}
.search {
  .header-form {
    margin: 10px 0;
    .header-form-item-330 {
      width: 330px;
    }
    .header-form-item-auto {
      width: auto;
    }
    .btn-same-width {
      width: 100px;
      margin: 0 15px 0 0;
    }
  }
}
</style>

运行效果:

9.3、子组件(主项数据) progress-ctrl-main.vue

<style scoped lang="scss">
.main {
  width: 100%;
  height: 100%;
}
</style>

运行效果:

9.4、子组件(选项卡) progress-ctrl-tabs.vue

<style scoped lang="scss">
.tabs {
  .el-tabs {
    border: none;
    // border-bottom: 1px solid #ddd;
    // 高度需要减去上下边框宽度
    // height: calc(100% - 2px);
    // 使用 box-sizing: border-box; 就不用考虑边框宽度
    box-sizing: border-box;
    height: 340px;
    :deep .el-tabs__content {
      margin: 0;
      padding: 0;
    }
    .el-tab-pane {
      height: 300px;
    }
  }
}
</style>

运行效果:

9.5、 子组件(分页) progress-ctrl-pagination.vue

<style scoped lang="scss">
.pagination {
  padding: 2px 5px;
  display: flex;
  justify-content: center; /* 水平居中 */
}
</style>

运行效果:

10、加载数据的最终效果

 

11、组件结构图 

12、视图数据关系图(VM关系图:视图+数据模型)

 

相关文章:

  • CExercise04_1位运算符_2 定义一个函数判断给定的正整数是否为2的幂
  • 通过第k个最大元素深入浅出快排和堆排序
  • 开箱即用的可视化AI应用编排工具 Langflow,可调用魔搭免费API作为tool
  • C++实现对象单例模式
  • SQL操作之:连接(JOIN)
  • JavaScript DOM 节点操作
  • 极限编程(XP)简介及其价值观与最佳实践
  • VMware虚拟机卡顿、CPU利用率低、编译Linux内核慢,问题解决与实验对比
  • 【案例91】记一次高级版升级环境报错“fail to save VO Array”
  • 批处理脚本的主要解析规则
  • 正确安装PyTorch
  • WebSocket通信协议
  • OpenCV引擎:驱动实时应用开发的科技狂飙
  • leecode第19天
  • 使用YoloV5和Mediapipe实现——上课玩手机检测(附完整源码)
  • 使用 PyTorch 的 `torch.rot90` 进行张量旋转:数据增强的利器
  • 用matlab搭建一个简单的图像分类网络
  • OpenCV 图形API(14)用于执行矩阵(或图像)与一个标量值的逐元素乘法操作函数mulC()
  • Nyquist内置函数-概述
  • Spring Task 定时任务