ruoyi-nbcio-plus基于vue3的flowable的支持自定义业务流程处理页面detail.vue的升级修改

news2024/11/29 22:54:01

更多ruoyi-nbcio功能请看演示系统

gitee源代码地址

前后端代码: https://gitee.com/nbacheng/ruoyi-nbcio

演示地址:RuoYi-Nbcio后台管理系统 http://122.227.135.243:9666/

更多nbcio-boot功能请看演示系统 

gitee源代码地址

后端代码: https://gitee.com/nbacheng/nbcio-boot

前端代码:https://gitee.com/nbacheng/nbcio-vue.git

在线演示(包括H5) : http://122.227.135.243:9888

1、因为修改vue3后也要支持自定义表单额显示处理,所以修改如下:

<template>
  <div class="app-container">
    <el-tabs tab-position="top" :model-value="processed === true ? 'approval' : 'form'">
      <el-tab-pane label="任务办理" name="approval" v-if="processed === true">
        <el-card class="box-card" shadow="hover" v-if="taskFormOpen">
          <template #header>
            <span>填写表单</span>
          </template>
          <div class="cu-content">
            <v-form-render :form-json="{}" :form-data="{}" ref="vfRenderRef" />
          </div>
        </el-card>
        <el-card class="box-card" shadow="hover">
          <template #header>
            <span>审批流程</span>
          </template>
          <el-row>
            <el-col :span="20" :offset="2">
              <el-form ref="taskFormRef" :model="taskForm" :rules="rules" label-width="120px">
                <el-form-item label="审批意见" prop="comment">
                  <el-input type="textarea" :rows="5" v-model="taskForm.comment" placeholder="请输入 审批意见" />
                </el-form-item>
                <el-form-item label="抄送人" prop="copyUserIds">
                  <el-tag :key="index" v-for="(item, index) in copyUser" closable :disable-transitions="false" @close="handleClose('copy', item)">
                    {{ item.nickName }}
                  </el-tag>
                  <el-button class="button-new-tag" type="primary" icon="el-icon-plus" circle @click="onSelectCopyUsers" />
                </el-form-item>
                <el-form-item label="指定审批人" prop="copyUserIds">
                  <el-tag :key="index" v-for="(item, index) in nextUser" closable :disable-transitions="false" @close="handleClose('next', item)">
                    {{ item.nickName }}
                  </el-tag>
                  <el-button class="button-new-tag" type="primary" icon="el-icon-plus" circle @click="onSelectNextUsers" />
                </el-form-item>
              </el-form>
            </el-col>
          </el-row>
          <el-row :gutter="10" type="flex" justify="center">
            <el-col :span="1.5">
              <el-button icon="CircleCheck" type="success" @click="handleComplete">通过</el-button>
            </el-col>
            <el-col :span="1.5">
              <el-button icon="ChatLineSquare" type="primary" @click="handleDelegate">委派</el-button>
            </el-col>
            <el-col :span="1.5">
              <el-button icon="Switch" type="success" @click="handleTransfer">转办</el-button>
            </el-col>
            <el-col :span="1.5">
              <el-button icon="RefreshLeft" type="warning" @click="handleReturn">退回</el-button>
            </el-col>
            <el-col :span="1.5">
              <el-button icon="CircleClose" type="danger" @click="handleReject">拒绝</el-button>
            </el-col>
          </el-row>
        </el-card>
      </el-tab-pane>

      <el-tab-pane label="表单信息" name="form">
        <div v-if="customForm.visible"> <!-- 自定义表单 -->
          <component ref="refCustomForm" :disabled="customForm.disabled" :is="customForm.formComponent" :model="customForm.model"
            :customFormData="customForm.customFormData" :isNew = "customForm.isNew"></component>
        </div>
        <div v-if="formVisible">
          <el-card class="box-card" shadow="never" v-for="(item, index) in processFormList" :key="index">
            <template #header>
              <span>{{ item.title }}</span>
            </template>
            <!--流程处理表单模块-->
            <div class="cu-content">
              <v-form-render :form-json="item.formModel" :form-data="item.formData" ref="vFormRenderRef" />
            </div>
          </el-card>
        </div>
        <div style="margin-left:10%;margin-bottom: 30px">
           <!--对上传文件进行显示处理,临时方案 add by nbacheng 2022-07-27 -->
        <!--   <el-upload action="#" :on-preview="handleFilePreview" :file-list="fileList" v-if="fileDisplay" /> -->
        </div>
      </el-tab-pane >

      <el-tab-pane label="流转记录" name="record">
        <el-card class="box-card" shadow="never">
          <el-col :span="20" :offset="2">
            <div class="block">
              <el-timeline>
                <el-timeline-item v-for="(item, index) in historyProcNodeList" :key="index" :type="tagType(item.endTime)">
                  <p style="font-weight: 700">{{ item.activityName }}</p>
                  <el-card v-if="item.activityType === 'startEvent'" class="box-card" shadow="hover">
                    {{ item.assigneeName }} 在 {{ item.createTime }} 发起流程
                  </el-card>
                  <el-card v-if="item.activityType === 'userTask'" class="box-card" shadow="hover">
                    <el-descriptions :column="5" :labelStyle="{'font-weight': 'bold'}">
                      <el-descriptions-item label="实际办理">{{ item.assigneeName || '-'}}</el-descriptions-item>
                      <el-descriptions-item label="候选办理">{{ item.candidate || '-'}}</el-descriptions-item>
                      <el-descriptions-item label="接收时间">{{ item.createTime || '-'}}</el-descriptions-item>
                      <el-descriptions-item label="办结时间">{{ item.endTime || '-' }}</el-descriptions-item>
                      <el-descriptions-item label="耗时">{{ item.duration || '-'}}</el-descriptions-item>
                    </el-descriptions>
                    <div v-if="item.commentList && item.commentList.length > 0">
                      <div v-for="(comment, index) in item.commentList" :key="index">
                        <el-divider content-position="left">
                          <el-tag :type="approveTypeTag(comment.type)">{{ commentType(comment.type) }}</el-tag>
                          <el-tag type="info" effect="plain">{{ comment.time }}</el-tag>
                        </el-divider>
                        <span>{{ comment.fullMessage }}</span>
                      </div>
                    </div>
                  </el-card>
                  <el-card v-if="item.activityType === 'endEvent'" class="box-card" shadow="hover">
                    {{ item.createTime }} 结束流程
                  </el-card>
                </el-timeline-item>
              </el-timeline>
            </div>
          </el-col>
        </el-card>
      </el-tab-pane>

      <el-tab-pane label="流程跟踪" name="track">
        <el-card class="box-card" shadow="never">
          <process-viewer
            :key="`designer-${loadIndex}`"
            :style="'height:' + height"
            :xml="processXml"
            :finishedInfo="finishedInfo"
            :allCommentList="historyProcNodeList"
          />
        </el-card>
      </el-tab-pane>
    </el-tabs>

    <!--退回流程-->
    <el-dialog :title="returnDialog.title" v-model="returnDialog.visible" width="40%" append-to-body>
      <el-radio-group v-model="returnTaskKey">
        <el-radio-button v-for="item in returnTaskList" :key="item.id" :label="item.id">
          {{ item.name }}
        </el-radio-button>
      </el-radio-group>
      <template #footer>
        <el-button @click="returnDialog.visible = false">取 消</el-button>
        <el-button type="primary" @click="submitReturn">确 定</el-button>
      </template>
    </el-dialog>

    <el-dialog :title="userSelectDialog.title" v-model="userSelectDialog.visible" width="60%" append-to-body>
      <el-row type="flex" :gutter="20">
        <!--部门数据-->
        <el-col :span="5">
          <el-card shadow="never" style="height: 100%">
            <template #header>
              <span>部门列表</span>
            </template>
            <div class="head-container">
              <el-input v-model="deptName" placeholder="请输入部门名称" prefix-icon="Search" clearable />
              <el-tree
                :data="deptOptions"
                :props="{ label: 'label', children: 'children' }"
                :expand-on-click-node="false"
                :filter-node-method="filterNode"
                ref="deptTreeRef"
                default-expand-all
                @node-click="handleNodeClick"
              />
            </div>
          </el-card>
        </el-col>
        <el-col :span="18">
          <el-table
            ref="userTable"
            :key="userSelectType"
            height="500"
            v-loading="userLoading"
            :data="userList"
            highlight-current-row
            @current-change="changeCurrentUser"
            @selection-change="handleSelectionChange"
          >
            <el-table-column v-if="userSelectType === 'copy' || userSelectType === 'next'" width="55" type="selection" />
            <el-table-column v-else width="30">
              <template #default="scope">
                <el-radio :label="scope.row.userId" v-model="currentUserId">{{''}}</el-radio>
              </template>
            </el-table-column>
            <el-table-column label="用户名称" align="center" prop="userName" />
            <el-table-column label="用户昵称" align="center" prop="nickName" />
            <el-table-column label="手机" align="center" prop="phonenumber" />
          </el-table>
          <pagination :total="userTotal" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
        </el-col>
      </el-row>
      <template #footer>
        <el-button @click="userSelectDialog.visible = false">取 消</el-button>
        <el-button type="primary" @click="submitUserData">确 定</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup name="Detail" lang="ts">
  import { detailProcess, processIscompleted } from "@/api/workflow/process";
  import { getProcessVariables } from '@/api/workflow/task';
  import { complete, delegate, transfer, rejectTask, returnList, returnTask } from "@/api/workflow/work/task";
  import { deptTreeSelect, selectUser } from "@/api/workflow/identity";
  import { TaskForm } from "@/api/workflow/work/types";
  import { UserVO, DeptVO } from "@/api/workflow/identity/types";

  import { ComponentInternalInstance } from "vue";
  import {useRoute} from "vue-router";
  import {
        useFlowable
    } from '@/views/workflow/hooks/useFlowable'

  const route = useRoute();
  const router = useRouter();
  const { proxy } = getCurrentInstance() as ComponentInternalInstance;
  const { getFormComponent } = useFlowable()

  const userList = ref<UserVO[]>([]);
  const processed = ref(false);
  const taskFormOpen = ref(false)
  const userMultipleSelection = ref([]);
  const userSelectType = ref();
  const currentUserId = ref();
  const userLoading = ref(false);
  const userTotal = ref(0);
  const loadIndex = ref('');
  const height = ref(document.documentElement.clientHeight - 205 + 'px;');
  const processXml = ref('');
  const taskFormVisible = ref(false);
  const processFormList = ref([]);
  const taskFormData = ref([]);
  const historyProcNodeList = ref<any>();
  const formVisible = ref(false);
  const finishedInfo = ref({});
  const customForm = ref({ //自定义业务表单
    formId: '',
    title: '',
    disabled: false,
    visible: false,
    formComponent: null,
    model: {},
    /*流程数据*/
    customFormData: {},
    isNew: false,
    disableSubmit: true
  })

  const deptName = ref('');
  const deptOptions = ref<DeptVO[]>([]);

  const returnTaskList = ref();
  const returnTaskKey = ref();

  const copyUser = ref([]);
  const nextUser = ref([]);

  const taskFormRef = ref(ElForm);
  const vFormRenderRef = ref(null);
  const deptTreeRef = ref(null);
  const refCustomForm = ref(null);

  const activeName = ref(''); //获取当然tabname

  const returnDialog = reactive<DialogOption>({
    visible: false,
    title: '退回流程'
  });

  const userSelectDialog = reactive<DialogOption>({
    visible: false,
    title: ''
  });

  const taskForm = reactive<TaskForm>({
    comment: '',
    procInsId: '',
    taskId: '',
    userId: '',
    copyUserIds: '',
    nextUserIds: '',
    vars: '',
    targetKey: ''
  });

  const rules = ref({
    comment: [{ required: true, message: '请输入审批意见', trigger: 'blur' }]
  });

  const queryParams = ref({
    pageNum: 1,
    pageSize: 10
  });
  const tagType = (val: any) => {
    if (val) {
        return "success";
    } else {
        return "info";
    }
  }
  const commentType = (val: string) => {
    switch (val) {
      case '1': return '通过'
      case '2': return '退回'
      case '3': return '驳回'
      case '4': return '委派'
      case '5': return '转办'
      case '6': return '终止'
      case '7': return '撤回'
      case '8': return '拒绝'
      case '9': return '跳过'
      case '10': return '前加签'
      case '11': return '后加签'
      case '12': return '多实例加签'
      case '13': return '跳转'
      case '14': return '收回'
    }
  }
  const approveTypeTag = (val: string) => {
    switch (val) {
      case '1': return 'success'
      case '2': return 'warning'
      case '3': return 'danger'
      case '4': return 'primary'
      case '5': return 'success'
      case '6': return 'danger'
      case '7': return 'info'
    }
  }

  const initData = () => {
    taskForm.procInsId = route.params && route.params.procInsId as string;
    taskForm.taskId  = route.query && route.query.taskId as string;
    processed.value = route.query && (route.query.processed || false) === "true";

    // 流程任务重获取变量表单
    //getProcessDetails(taskForm.procInsId, taskForm.taskId);
    //判断流程是否结束
    processIscompleted({procInsId: taskForm.procInsId}).then(res => {
      console.log("processIscompleted res=",res);
      if(res.data) {
       processed.value = false;
      }
      // 获取流程变量
      processVariables(taskForm.taskId);
    });
  };
  /** 通过条件过滤节点  */
  const filterNode = (value: string, data: any) => {
    if (!value) return true
    return data.label.indexOf(value) !== -1
  }
  // /** 根据名称筛选部门树 */
  // watchEffect(
  //     () => {deptTreeRef.value.filter(deptName.value);},
  //     {
  //       flush: 'post' // watchEffect会在DOM挂载或者更新之前就会触发,此属性控制在DOM元素更新后运行
  //     }
  // );
  // 节点单击事件
  const handleNodeClick = (data: any) => {
    getList(data.id);
  }
  /** 查询部门下拉树结构 */
  const getTreeSelect = async () => {
    const res = await deptTreeSelect();
    deptOptions.value = res.data;
  };
  /** 查询用户列表 */
  const getList = async (deptId?: number) => {
    userLoading.value = true;
    const res = await selectUser({deptId: deptId});
    userLoading.value = false;
    userList.value = res.rows;
    userTotal.value = res.total;
  }

  /** 获取流程变量内容 */
  const processVariables = (taskId: string) => {
    console.log("processVariables taskId",taskId);
    if (taskId) {
      getProcessVariables(taskId).then(res => {
        console.log("getProcessVariables res=",res);
        if(res.code == 200) {
          if(res.data.hasOwnProperty('dataId') && res.data.dataId) {
            customForm.value.formId = res.data.dataId;
            // 流程任务重获取变量表单
            getProcessDetails(taskForm.procInsId, taskForm.taskId, res.data.dataId);
            loadIndex.value = taskForm.procInsId;
            if(processed.value) {
              activeName.value = "approval";
            }
            else {
              activeName.value = "form";
            }
          }
          else {
            // 流程任务重获取变量表单
            getProcessDetails(taskForm.procInsId, taskForm.taskId, "");
            loadIndex.value = taskForm.procInsId;
            if(processed.value) {
              activeName.value = "approval";
            }
            else {
              activeName.value = "form";
              // 回填数据,这里主要是处理文件列表显示,临时解决,以后应该在formdesigner里完成
              /*this.processFormList.forEach((item, i) => {
                if (item?.hasOwnProperty('list')) {
                  fillFormData(item.list, item)
                  // 更新表单
                  this.key = +new Date().getTime()
                }
              });*/
            }
          }
        }
      });
    }
  }

  const fillFormData = (list, formConf) => { // for formdesigner
    console.log("fillFormData list=",list);
    console.log("fillFormData formConf=",formConf);
    list.forEach((item, i) => {
      // 特殊处理el-upload,包括 回显图片
      if(formConf.formValues[item.id] != '') {
        const val = formConf.formValues[item.id];
        if (item.ele === 'el-upload') {
          console.log('fillFormData val=',val)
          if(item['list-type'] != 'text') {//图片
            this.fileList = []    //隐藏加的el-upload文件列表
            //item['file-list'] = JSON.parse(val)
            if(val != '') {
              item['file-list'] = JSON.parse(val)
            }
          }
          else {  //列表
            console.log("列表fillFormData val",val)
            this.fileList = JSON.parse(val)
            item['file-list'] = [] //隐藏加的表单设计器的文件列表
          }
          // 回显图片
          this.fileDisplay = true
        }
      }

      if (Array.isArray(item.columns)) {
        this.fillFormData(item.columns, formConf)
      }
    })
  }

  const getProcessDetails = async (procInsId: string, taskId: string, dataId: string) => {
    const params = {procInsId: procInsId, taskId: taskId, dataId: dataId}
    const res = await detailProcess(params);
    const data = res.data;
    console.log("getProcessDetails data",data);
    processXml.value = data.bpmnXml;
    processFormList.value = data.processFormList;
    console.log("processFormList",processFormList);
    if(processFormList.value.length == 1 &&processFormList.value[0].formValues.hasOwnProperty('routeName')) {
      customForm.value.disabled = true;
      customForm.value.visible = true;
      customForm.value.formComponent = getFormComponent(processFormList.value[0].formValues.routeName).component;
      customForm.value.model = processFormList.value[0].formValues.formData;
      customForm.value.customFormData = processFormList.value[0].formValues.formData;
      if(data.startUserNode) {
        customForm.value.isNew = true;
        customForm.value.disabled = false;
      }
     console.log("detailProcess customForm",customForm.value);
    }
    else {
      taskFormVisible.value = data.existTaskForm;
      if (taskFormVisible.value) {
        taskFormData.value = data.taskFormData;
      }
      formVisible.value = true;
      nextTick(() => {
        processFormList.value.forEach((item: any, index: any) => {
          if (item.disabled) {
            vFormRenderRef.value[index].disableForm();
          }
        })
      })
    }
    historyProcNodeList.value = data.historyProcNodeList;
    finishedInfo.value = data.flowViewer;

  }
  const onSelectCopyUsers = () => {
    userMultipleSelection.value = copyUser;
    onSelectUsers('添加抄送人', 'copy')
  }
  const onSelectNextUsers = () => {
    userMultipleSelection.value = nextUser;
    onSelectUsers('指定审批人', 'next')
  }
  const onSelectUsers = (title: string, type: string) => {
    userSelectType.value = type;
    userSelectDialog.title = title;
    userSelectDialog.visible = true;
    getTreeSelect();
    getList()
  }
  /** 通过任务 */
  const handleComplete = () => {
    // 校验表单
    taskFormRef.value.validate(async (valid: boolean) => {
      if (valid) {
        const res = await complete(taskForm)
        proxy?.$modal.msgSuccess(res.msg);
        goBack();
      }
    });
  }
  /** 委派任务 */
  const handleDelegate = () => {
    userSelectType.value = 'delegate';
    userSelectDialog.title = '委派任务'
    userSelectDialog.visible = true;
    getTreeSelect();
  }
  /** 转办任务 */
  const handleTransfer = () => {
    userSelectType.value = 'transfer';
    userSelectDialog.title = '转办任务';
    userSelectDialog.visible = true;
    getTreeSelect();
  }
  /** 退回任务 */
  const handleReturn = async () => {
    // 校验表单
    taskFormRef.value.validate(async (valid: boolean) => {
      if (valid) {
        const res = await returnList(taskForm);
        returnTaskList.value = res.data;
        returnDialog.visible = true;
      }
    });
  }
  /** 拒绝任务 */
  const handleReject = async () => {
    await proxy?.$modal.confirm('拒绝审批单流程会终止,是否继续?');
    await rejectTask(taskForm);
    proxy?.$modal.msgSuccess("操作成功");
    goBack();
  }

  /** 返回页面 */
  const goBack = () => {
    // 关闭当前标签页并返回上个页面
    proxy?.$tab.closePage(route);
    router.back()
  }
  // 关闭标签
  const handleClose = (type: any, tag: any) => {
    let userObj = userMultipleSelection.value.find(item => item.userId === tag.id);
    userMultipleSelection.value.splice(userMultipleSelection.value.indexOf(userObj), 1);
    if (type === 'copy') {
      copyUser.value = userMultipleSelection.value;
      // 设置抄送人ID
      if (copyUser.value && copyUser.value.length > 0) {
        const val = copyUser.value.map(item => item.id);
        taskForm.copyUserIds = val instanceof Array ? val.join(',') : val;
      } else {
        taskForm.copyUserIds = '';
      }
    } else if (type === 'next') {
      nextUser.value = userMultipleSelection.value;
      // 设置抄送人ID
      if (nextUser.value && nextUser.value.length > 0) {
        const val = nextUser.value.map(item => item.id);
        taskForm.nextUserIds = val instanceof Array ? val.join(',') : val;
      } else {
        taskForm.nextUserIds = '';
      }
    }
  }
  const changeCurrentUser = (val: any) => {
    // currentUserId = val.userId
  }
  const handleSelectionChange = () => {

  }
  const submitReturn = () => {
    // 校验表单
    taskFormRef.value.validate(async (valid: boolean) => {
      if (valid) {
        if (!returnTaskKey) {
          proxy?.$modal.msgError("请选择退回节点!");
        }
        taskForm.targetKey = returnTaskKey.value;
        const res = await returnTask(taskForm);
        proxy?.$modal.msgSuccess(res.msg);
        goBack()
      }
    });
    console.log("taskForm => ", taskForm.targetKey);
  }
  const submitUserData = () => {
    let type = userSelectType.value;
    if (type === 'copy' || type === 'next') {
      if (!userMultipleSelection || userMultipleSelection.value.length <= 0) {
        proxy?.$modal.msgError("请选择用户");
        return false;
      }
      let userIds = userMultipleSelection.value.map(k => k.userId);
      if (type === 'copy') {
        // 设置抄送人ID信息
        copyUser.value = userMultipleSelection.value;
        taskForm.copyUserIds = userIds instanceof Array ? userIds.join(',') : userIds;
      } else if (type === 'next') {
        // 设置下一级审批人ID信息
        nextUser.value = userMultipleSelection.value;
        taskForm.nextUserIds = userIds instanceof Array ? userIds.join(',') : userIds;
      }
      userSelectDialog.visible = false;
    } else {
      if (!taskForm.comment) {
        proxy?.$modal.msgError("请输入审批意见");
        return false;
      }
      if (!currentUserId.value) {
        proxy?.$modal.msgError("请选择用户");
        return false;
      }
      taskForm.userId = currentUserId.value;
      if (type === 'delegate') {
        delegate(taskForm).then(res => {
          proxy?.$modal.msgSuccess(res.msg);
          goBack();
        });
      }
      if (type === 'transfer') {
        transfer(taskForm).then(res => {
          proxy?.$modal.msgSuccess(res.msg);
          goBack();
        });
      }
    }
  }

  onMounted(() => {
    initData();
  });
</script>

<style lang="scss" scoped>
  .clearfix:before,
  .clearfix:after {
    display: table;
    content: "";
  }
  .clearfix:after {
    clear: both
  }

  .box-card {
    width: 100%;
    margin-bottom: 20px;
  }

  .el-tag + .el-tag {
    margin-left: 10px;
  }

  .el-row {
    margin-bottom: 20px;
    &:last-child {
      margin-bottom: 0;
    }
  }
  .el-col {
    border-radius: 4px;
  }

  .button-new-tag {
    margin-left: 10px;
  }
</style>

2、其中hooks的useFlowable修改如下(原先minixs)

export const useFlowable = () => {
  const allFormComponent = computed(() => {
    return [
        {
          text:'单表示例',
          routeName: '@/views/workflow/demo/wf',
          component: defineAsyncComponent( () => import('@/views/workflow/demo/wf')),
          businessTable:'wf_demo'
        },
        /*{
          text:'主子表示例',
          routeName:'@/views/workflow/demo/modules/CesOrderMainForm',
          component:() => defineAsyncComponent(import(`@/views/workflow/demo/modules/CesOrderMainForm`)),
          businessTable:'ces_order_main'
        }*/
    ]
  })
  const getFormComponent = (routeName) => {
    return allFormComponent.value.find((item) => item.routeName === routeName) || {}
  }
  return {
    allFormComponent,
    getFormComponent
  }
}

3、效果图如下:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1586481.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Training - PyTorch Lightning 分布式训练的 global_step 参数 (accumulate_grad_batches)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://blog.csdn.net/caroline_wendy/article/details/137640653 在 PyTorch Lightning 中&#xff0c;pl.Trainer 的 accumulate_grad_batches 参数允许在执行反向传播和优化器步骤之前&…

priority_queue的使用以及模拟实现

前言 上一期我们对stack和queue进行了使用的介绍&#xff0c;以及对底层的模拟实现&#xff01;以及容器适配器做了介绍&#xff0c;本期我们在来介绍一个容器适配器priority_queue&#xff01; 本期内容介绍 priority_queue的使用 仿函数介绍 priority_queue的模拟实现 什么…

2024年3月文章一览

2024年3月编程人总共更新了12篇文章&#xff1a; 1.2024年2月文章一览 2.Programming Abstractions in C阅读笔记&#xff1a;p308-p311 3.Programming Abstractions in C阅读笔记&#xff1a;p312-p326 4.Programming Abstractions in C阅读笔记&#xff1a;p327-p330 5.…

更改el-cascade默认的value和label的键值

后端返回的树结构中&#xff0c;label的key不是el-cascade默认的label&#xff0c;我需要改成对应的字段&#xff0c;但是一直没有成功&#xff0c;我也在文档中找到了说明&#xff0c;但是我没注意这是在props中改&#xff0c;导致一直不成功 这是我一开始错误的写法&#xf…

超越ChatGPT,国内快速访问的强大 AI 工具 Claude

claude 3 opus面世后&#xff0c;网上盛传吊打了GPT-4。网上这几天也已经有了许多应用&#xff0c;但竟然还有很多小伙伴不知道国内怎么用gpt&#xff0c;也不知道怎么去用这个据说已经吊打了gpt-4的claude3。 今天我们想要进行的一项尝试就是—— 用claude3和gpt4&#xff0c…

互联网大厂ssp面经(操作系统:part1)

1. 什么是进程和线程&#xff1f;它们之间有什么区别&#xff1f; a. 进程是操作系统中运行的一个程序实例。它拥有独立的地址空间和资源&#xff0c;可以独立执行。 b. 线程是进程内的一个执行单元&#xff0c;一个进程可以包含多个线程。 c. 线程共享进程的资源&#xff0c;…

liunx系统发布.net core项目

liunx系统发布.net core项目 准备.net6程序运行环境部署nginx&#xff0c;通过一个地址既能访问web api&#xff0c;又能访问web项目有一个客户把web api放到docker中&#xff0c;想通过nginx转发&#xff0c;nginx也支持配置多个程序api接口的其它 liunx系统&#xff1a;cento…

程序员生产力工具推荐

1.SSH客户端 XTerminal Xterminal - 更好用的开发工具&#xff0c;但不止于(SSH/控制台/More) 有着比XShell好看的多的界面&#xff0c;免费版使用起来绰绰有余。 2.文件内容搜索工具 FileLocator FileLocator Pro 专业全文检索工具文件搜索软件丨中文网站特价购买 everyth…

Excel 记录单 快速录入数据

一. 调出记录单 ⏹记录单功能默认是隐藏的&#xff0c;通过如下如图所示的方式&#xff0c;将记录单功能显示出来。 二. 录入数据 ⏹先在表格中录入一行数据&#xff0c;给记录单一个参考 ⏹将光标至于表格右上角&#xff0c;然后点击记录单按钮&#xff0c;调出记录单 然后点…

Terraform 状态不同步处理

背景 在使用 Terraform 创建 TencentCloud TKE 的时候&#xff0c;手贱把 node pool 删掉了。导致执行 destroy, plan 都会报错。 │ Error: [TencentCloudSDKError] CodeInternalError.UnexpectedInternal, Messagerelated node pool query err(get node pool failed: [E501…

kaggle 泰坦尼克号1(根据男女性存活率)

kaggle竞赛 泰坦尼克号 流程 下载kaggle数据集导入所要使用的包引入kaggle的数据集csv文件查看数据集的大小和长度去除冗余数据建立特征工程导出结果csv文件 1.下载kaggle数据集 2.导入所要使用的包 import pandas as pd import numpy as np import matplotlib.pyplot as …

2024.4.12蚂蚁庄园今日答案:豆腐在烹调时容易碎有什么办法可以避免?

原文来源&#xff1a;蚂蚁庄园今日答案 - 词令 蚂蚁庄园是一款爱心公益游戏&#xff0c;用户可以通过喂养小鸡&#xff0c;产生鸡蛋&#xff0c;并通过捐赠鸡蛋参与公益项目。用户每日完成答题就可以领取鸡饲料&#xff0c;使用鸡饲料喂鸡之后&#xff0c;会可以获得鸡蛋&…

构建高效网络:深入理解正向与反向代理的作用与配置

正向代理 如果把局域网外的互联网环境想象成一个巨大的资源库&#xff0c;则局域网中的客户端要访问互联网则需要通过代理服务器来访问&#xff0c;这种代理成为正向代理。 示例&#xff1a; 用户想要访问 https://chensir.ink &#xff08;目标服务器&#xff09;&#xff0…

vivado 在硬件中调试逻辑设计

在硬件中调试逻辑设计 设计中包含调试核后 &#xff0c; 您可使用运行时间逻辑分析器功能来对硬件中的设计进行调试。 使用 Vivado Logic Analyzer 进行设计调试 Vivado Logic Analyzer 功能可用于与设计中运行的新 ILA 、 VIO 和 JTAG-to-AXI Master 调试核进行交互。…

02 Windows操作系统密钥激活流程

Windows系统的激活流程通常包括以下步骤&#xff1a; AI步骤 1. 购买正版产品密钥&#xff1a;在正式激活Windows系统之前&#xff0c;你需要购买一个合法的产品密钥。你可以通过Microsoft官方网站或授权的零售商购买密钥。 2. 输入产品密钥&#xff1a;在购买后&#xff0c;你…

1.8V LDO电路 ➕1.2V bandgap电路

1.8V LDO电路 ➕1.2V bandgap电路&#xff08;WX:didadidadidida313&#xff0c;加我备注&#xff1a;CSDN LDO&#xff0c;谢绝白嫖哈&#xff09; 1.8V LDO电路 ➕1.2V bandgap电路,基于tsmc180nm工艺库 带设计仿真报告&#xff0c;非常适合新手入门&#xff01; 本文采用…

【智能算法应用】灰狼算法求解TSP问题

目录 1.算法原理2.TSP数学模型3.结果展示4.参考文献 1.算法原理 【智能算法】灰狼算法&#xff08;GWO&#xff09;原理及实现 2.TSP数学模型 旅行商问题&#xff08;TSP&#xff09;是一种著名的组合优化问题&#xff0c;它涉及寻找给定一组城市及其之间的距离或成本&#…

室内定位中文综述阅读

1 室内高精度定位技术总结与展望 [4]柳景斌,赵智博,胡宁松等.室内高精度定位技术总结与展望[J].武汉大学学报(信息科学 版),2022,47(07):997-1008.DOI:10.13203/j.whugis20220029. 1.1.1 WiFi‐RTT定位 2016 年 12 月&#xff0c;随着新版 IEEE802.11 标准的公布&#xff0c…

逆向案例二十一——遇到混淆怎么办

开始新的板块尝试&#xff0c;混淆了怎么办 网址&#xff1a;极简壁纸_海量电脑桌面壁纸美图_4K超高清_最潮壁纸网站 抓包抓到&#xff0c;好久没做解密了&#xff0c;奥里给干他&#xff01;&#xff1a; 搜索关键字&#xff0c;打上断点&#xff0c;点击第二页。 _0x10a345…

中国企业级存储市场:五年来首次负增长,第二曲线在哪里?

出人意料&#xff0c;中国企业级存储市场出现过去五年来的首次负增长。 IDC最新《中国企业级存储市场跟踪报告,2023》显示&#xff0c;2023年中国企业级存储市场规模达到66亿美元&#xff0c;同比下降0.6%。外部环境的动荡与不确定性的陡增&#xff0c;让中国不少行业用户受到…