vue+element+axios接口二次请求一直pending

解决了一个Vue项目中元素选项卡导致的页面卡死问题。在正式环境中,特定条件下页面崩溃,通过调整选项卡内容的位置解决了该问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里记录一下遇到的一个比较奇葩的问题

项目是vue+element+axios ,本地接口调试正常,但是项目部署到正式服务,二次请求接口,状态一直pending,导致页面崩溃卡死,最后排查了好久,发现是element的选项卡组件导致的,

官网中element选项卡的内容书写方式是这样的

<el-tabs v-model="activeName" @tab-click="handleClick">
    <el-tab-pane label="用户管理" name="first">用户管理</el-tab-pane>
    <el-tab-pane label="配置管理" name="second">配置管理</el-tab-pane>
    <el-tab-pane label="角色管理" name="third">角色管理</el-tab-pane>
    <el-tab-pane label="定时任务补偿" name="fourth">定时任务补偿</el-tab-pane>
  </el-tabs>

,但是实际上我们的选项卡内容不能放在el-tab-pane中,否则会导致页面中的js卡死,源码我没有具体的研究,但是造成的页面效果,貌似进入了死循环,

我的这个选项卡是写入对话框中的,二次打开对话框直接导致页面卡死,参考其他人博客中的说法,是vue和element版本导致的,因为是公司之前搭建的框架,我也避免再改什么框架的版本,

最后我把el-tab-pane中包裹的内容拿到el-tabs外面用div包裹,然后加上v-show的判断对activeName的值进行对应显示,以此实现选项卡的内容切换,最后重新打包部署线上服务,果然是这个问题导致的,比较奇葩的是本地运行二次打开对话框是木有问题的。

<think>我们使用Vue3作为前端框架,Python(Flask或Django)作为后端框架,PostgreSQL作为数据库来实现一个工作流审批系统。根据引用[1][2][3][4]中提到的技术栈,我们可以选择Django(因为引用[2][3][4]都使用了Django)或Flask(引用[1]使用了Flask)作为后端。这里我们选择Django,因为它自带的管理后台和ORM可以加速开发。系统功能:工作流审批系统通常包括流程定义、审批节点、审批任务、用户角色等。步骤:1.设计数据库模型(使用DjangoORM)2.创建Django后端API3.创建Vue3前端界面4.前后端交互由于篇幅限制,这里给出关键部分的示例代码。一、数据库模型设计(models.py)假设我们有以下模型:-流程定义(Workflow):存储流程名称、描述等-节点(Node):属于某个流程,包括节点类型(开始、审批、结束等)、节点名称、审批角色等-任务(Task):每个流程实例的具体任务,包括当前状态、当前节点、申请人、审批人等-任务历史(TaskHistory):记录任务在每个节点的审批历史二、Django后端API我们将使用DjangoRESTframework来创建API。三、Vue3前端使用Vue3的CompositionAPI,通过axios与后端交互。下面分别给出示例代码:1.Django模型(models.py)示例:```pythonfromdjango.dbimportmodelsfromdjango.contrib.auth.modelsimportUserclassWorkflow(models.Model):name=models.CharField(max_length=100)description=models.TextField(blank=True)classNode(models.Model):workflow=models.ForeignKey(Workflow,on_delete=models.CASCADE,related_name='nodes')name=models.CharField(max_length=100)#节点类型:0-开始节点,1-审批节点,2-结束节点node_type=models.IntegerField(default=1)#审批角色(可以是角色名,这里简化为字符串,实际可关联角色模型)approve_role=models.CharField(max_length=100,blank=True,null=True)#顺序order=models.IntegerField(default=0)classTask(models.Model):workflow=models.ForeignKey(Workflow,on_delete=models.CASCADE)#当前节点current_node=models.ForeignKey(Node,on_delete=models.SET_NULL,null=True,blank=True)#申请人applicant=models.ForeignKey(User,on_delete=models.CASCADE,related_name='applicant_tasks')#当前审批人(可能为空,例如在开始节点)approver=models.ForeignKey(User,on_delete=models.SET_NULL,null=True,blank=True,related_name='approver_tasks')#状态:0-进行中,1-通过,2-拒绝status=models.IntegerField(default=0)create_time=models.DateTimeField(auto_now_add=True)classTaskHistory(models.Model):task=models.ForeignKey(Task,on_delete=models.CASCADE,related_name='histories')node=models.ForeignKey(Node,on_delete=models.SET_NULL,null=True)approver=models.ForeignKey(User,on_delete=models.SET_NULL,null=True)#审批意见comment=models.TextField(blank=True)#审批结果:0-通过,1-拒绝result=models.IntegerField()create_time=models.DateTimeField(auto_now_add=True)```2.序列化器(serializers.py)示例:```pythonfromrest_frameworkimportserializersfrom.modelsimportWorkflow,Node,Task,TaskHistoryclassNodeSerializer(serializers.ModelSerializer):classMeta:model=Nodefields='__all__'classWorkflowSerializer(serializers.ModelSerializer):nodes=NodeSerializer(many=True,read_only=True)classMeta:model=Workflowfields='__all__'classTaskHistorySerializer(serializers.ModelSerializer):classMeta:model=TaskHistoryfields='__all__'classTaskSerializer(serializers.ModelSerializer):histories=TaskHistorySerializer(many=True,read_only=True)classMeta:model=Taskfields='__all__'```3.视图(views.py)示例(简单示例):```pythonfromrest_frameworkimportviewsetsfrom.modelsimportWorkflow,Taskfrom.serializersimportWorkflowSerializer,TaskSerializerclassWorkflowViewSet(viewsets.ModelViewSet):queryset=Workflow.objects.all()serializer_class=WorkflowSerializerclassTaskViewSet(viewsets.ModelViewSet):queryset=Task.objects.all()serializer_class=TaskSerializer```4.路由(urls.py):```pythonfromdjango.urlsimportpath,includefromrest_framework.routersimportDefaultRouterfrom.importviewsrouter=DefaultRouter()router.register(r'workflows',views.WorkflowViewSet)router.register(r'tasks',views.TaskViewSet)urlpatterns=[path('',include(router.urls)),]```5.Vue3前端示例(使用CompositionAPI):假设我们有一个任务列表页面,展示所有任务。```vue<template><div><h1>任务列表</h1><ul><liv-for="taskintasks":key="task.id">{{task.id}}-{{task.applicant.username}}-状态:{{taskStatusText(task.status)}}</li></ul></div></template><script>import{ref,onMounted}from'vue'importaxiosfrom'axios'exportdefault{setup(){consttasks=ref([])constfetchTasks=async()=>{try{constresponse=awaitaxios.get('/api/tasks/')tasks.value=response.data}catch(error){console.error('获取任务失败:',error)}}consttaskStatusText=(status)=>{conststatusMap={0:'进行中',1:'通过',2:'拒绝'}returnstatusMap[status]||'未知'}onMounted(fetchTasks)return{tasks,taskStatusText}}}</script>```注意:以上代码仅为示例,实际开发中需要处理用户认证、权限、审批操作等。由于工作流审批系统比较复杂,还需要实现审批操作(通过、拒绝)以及任务流转(根据流程定义跳转到下一个节点)等功能。以上是一个基础框架,你可以在此基础上扩展。另外,关于工作流引擎,也可以考虑使用现成的库(如django-viewflow)来加速开发,但这里我们手动实现以理解原理。希望这个指南对你有所帮助!§§相关问题§§1.如何设计工作流审批系统的数据库模型?2.在Django中如何实现审批任务的流转逻辑?3.Vue3前端如何与Django后端进行用户认证?4.工作流审批系统中如何处理会签(多人审批)和或签(任意一人审批)?</think>### Vue3 + Python + PostgreSQL 工作流审批系统开发指南 #### 一、技术栈规划 | 层级 | 技术选型 | |------------|----------------------| | 前端 | Vue3 + Pinia + Element Plus | | 后端 | Python Django REST Framework | | 数据库 | PostgreSQL 12+ | | 部署 | Docker + Nginx | #### 二、核心功能设计 1. **流程定义** - 可视化流程设计器 - 节点类型:审批/会签/或签/条件分支 2. **审批管理** - 任务分配与通知 - 审批操作(通过/驳回/转交) - 审批历史追溯 3. **系统集成** - 基于JWT的认证授权 - Webhook外部系统对接 #### 三、数据库设计(关键表) ```sql -- 流程定义表 CREATE TABLE workflow ( id SERIAL PRIMARY KEY, name VARCHAR(100) NOT NULL, version INTEGER DEFAULT 1, definition JSONB NOT NULL -- 存储流程节点关系 ); -- 审批实例表 CREATE TABLE approval_instance ( id UUID PRIMARY KEY, workflow_id INTEGER REFERENCES workflow(id), applicant_id INTEGER NOT NULL, current_state VARCHAR(50) NOT NULL, form_data JSONB NOT NULL ); -- 审批任务表 CREATE TABLE approval_task ( id SERIAL PRIMARY KEY, instance_id UUID REFERENCES approval_instance(id), node_id VARCHAR(50) NOT NULL, -- 对应流程节点 assignee_id INTEGER NOT NULL, status VARCHAR(20) CHECK (status IN ('PENDING', 'APPROVED', 'REJECTED')), comments TEXT ); ``` #### 四、后端实现(Python Django) 1. **模型定义(models.py)** ```python from django.db import models from django.contrib.auth.models import User class Workflow(models.Model): name = models.CharField(max_length=100) definition = models.JSONField() # 存储节点配置 version = models.IntegerField(default=1) created_at = models.DateTimeField(auto_now_add=True) class ApprovalInstance(models.Model): STATUS_CHOICES = [ ('RUNNING', '进行中'), ('COMPLETED', '已完成'), ('REJECTED', '已驳回') ] workflow = models.ForeignKey(Workflow, on_delete=models.CASCADE) applicant = models.ForeignKey(User, on_delete=models.CASCADE) current_state = models.CharField(max_length=50) form_data = models.JSONField() status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='RUNNING') class ApprovalTask(models.Model): TASK_STATUS = [ ('PENDING', '待处理'), ('APPROVED', '已批准'), ('REJECTED', '已驳回') ] instance = models.ForeignKey(ApprovalInstance, on_delete=models.CASCADE, related_name='tasks') assignee = models.ForeignKey(User, on_delete=models.CASCADE) node_id = models.CharField(max_length=50) status = models.CharField(max_length=20, choices=TASK_STATUS, default='PENDING') comments = models.TextField(blank=True) ``` 2. **审批逻辑(services.py)** ```python def process_approval(task_id, action, comments=None): task = ApprovalTask.objects.get(id=task_id) workflow = task.instance.workflow.definition # 更新任务状态 task.status = 'APPROVED' if action == 'approve' else 'REJECTED' task.comments = comments task.save() # 获取下一节点 next_node = workflow['nodes'].get(task.node_id).get('next') if next_node: # 创建新任务 ApprovalTask.objects.create( instance=task.instance, assignee=User.objects.get(id=next_node['assignee']), node_id=next_node['id'] ) task.instance.current_state = next_node['id'] else: # 流程结束 task.instance.status = 'COMPLETED' if action == 'approve' else 'REJECTED' task.instance.save() ``` #### 五、前端实现(Vue3) 1. **审批任务组件(ApprovalTask.vue)** ```vue <template> <el-card v-if="task"> <h3>{{ task.node_name }}审批</h3> <el-form :model="formData"> <el-form-item label="审批意见"> <el-input v-model="comments" type="textarea" /> </el-form-item> </el-form> <div class="action-buttons"> <el-button type="primary" @click="handleApprove">通过</el-button> <el-button type="danger" @click="handleReject">驳回</el-button> </div> </el-card> </template> <script setup> import { ref } from 'vue' import axios from '@/utils/axios' const props = defineProps(['taskId']) const comments = ref('') const task = ref(null) // 获取任务详情 const fetchTask = async () => { const res = await axios.get(`/api/tasks/${props.taskId}/`) task.value = res.data } // 审批操作 const submitDecision = async (action) => { await axios.post(`/api/tasks/${props.taskId}/process/`, { action, comments: comments.value }) } fetchTask() </script> ``` #### 六、系统部署建议 1. **Docker容器化部署** ```dockerfile # Django 容器 FROM python:3.10 RUN pip install gunicorn COPY requirements.txt . RUN pip install -r requirements.txt EXPOSE 8000 CMD ["gunicorn", "workflow.wsgi", "--bind", "0.0.0.0:8000"] # Vue 容器 FROM node:16 as build-stage WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build FROM nginx:stable-alpine COPY --from=build-stage /app/dist /usr/share/nginx/html EXPOSE 80 ``` 2. **Nginx配置示例** ```nginx server { listen 80; server_name workflow.example.com; location /api { proxy_pass http://django:8000; proxy_set_header Host $host; } location / { root /usr/share/nginx/html; try_files $uri $uri/ /index.html; } } ``` #### 七、安全增强建议 1. 使用JWT进行API认证 2. PostgreSQL字段级加密(pgcrypto) 3. 审批操作审计日志 4. RBAC角色权限控制 5. 敏感数据脱敏处理 > **提示**:完整项目可参考Django-Vue工作流实现案例[^2][^4],包含流程设计器、审批历史跟踪等进阶功能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杀猪刀-墨林

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值