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

Vue自定义流程图式菜单解决方案

【点赞收藏加关注,前端技术不迷路~】

一、前言

1.现状

        目前市面上基于Vue的中大型PC端业务管理系统,大部分广泛采用vue-router来构建三级/四级菜单结构。

2.痛点

        由于大中型管理系统的业务复杂程度,一项业务可能涉及到10+的业务流程流转,仅采用最基础的vue-router构建的菜单结构,对于业务的流转方向,前后关系均不能显示的呈现出来,这将会带来一系列的问题:

        1)对于每一位新承接的业务人员,需要培训学习完整的业务流程;

        2)每当业务流程发生变更时,需要重新对所有相关业务人员进行培训;

        3)企业的人员流动很有可能造成相关业务流程的丢失,那将是一件很可怕的事儿;

        4)系统的业务流程会越来越多,流程越来越多,管理成本越来越大。

3.优化方案

        菜单结构的流程图化显式管理的最佳方案,有效的降低了管理部门业务模块的培训成本。通过配置式开发理念,采用单元集成模式,完成对流程图配置及嵌入的解决方案设计及开发方案制定。

二、流程图配置

1.整体思路

        1)流程图信息存储在次末级菜单上,每一个流程节点对应的菜单为末级菜单

        2)通过单元集成模式思想,将整个流程图分解成每一个通用模块来单独配置,配置采用可视化配置。其中通用模块配置样式如下图;

        3)通过遍历通用模块来生成整个流程图;

        4)流程图嵌入页面应游离在vouter-view外,当次末级菜单路径变更时切换流程图末级菜单变更时流程图保持不动

2.通用模块配置

1)页面参数说明:

不同节点类型,含有不同参数字段

【连接线】:

        1.说明文字:对当前业务流转的文字说明;

        2.说明显示类型:如何展示说明文字,包含弹框、上横线上、上横线下、中横线上、中横线下、下横线上、下横线下。

【流程图】:

        1.图标类型:内置图标为el-icon图标,自定义图标为UI设计图标;

        2.跳转方式:包含禁用、本系统内部跳转、其他网站跳转(显示效果不同);

        3.节点名称:当前节点名称显示;

        4.图标ID:根据不同图标类型,选择不同图标ID;

        5.跳转地址:为当前节点指定的路由地址;

        6.透传参数:多个节点对应同一vue实例时,列表查询透传参数;

        7.显示数量:是否显示当前业务节点,待处理业务数量;

        8.数量关键字:当前业务节点,待处理业务数量统一查询接口对应的数据关键字;

        9.说明文字:对当前业务流转的文字说明;

        10.说明显示类型:如何展示说明文字,包含弹框、上横线上、上横线下、中横线上、中横线下、下横线上、下横线下。

// 流程节点默认信息
const detailInfoSource = {flowType: 'flow',flowCode: '',flowName: '',iconKeyword: '',iconType: 'system',jumpUrl: '',jumpParams: '',numberKeyword: '',tipsTitle: '',leftFlowType: '00000000000000000000',jumpFlag: 1,showLeftLine: 0,showNumber: 0
};

2)流程节点连接线参数说明

        为节约存储开支,连接线及箭头等信息采用一个长度为20的数字字符串来存储,初始值为:"00000000000000000000"。外围8个线段、内部4条线段,再加上8个箭头,共计20个信息点位。其中:0-5点位为横线,6-11点位为竖线,12/13/18/19点位为竖向箭头,14-17点位为横向箭头。

        线段点位说明:0为无(灰色),1为蓝色实线,2为蓝色虚线。

        箭头点位说明:0为无(空白),1为向左或向上箭头,2为向右或向下箭头。

        上图中点位信息为:"00110000002000020000"。

3.整体流程图

        整体流程图每行流程节点数量为12个。12是2,3,4,6的最小公倍数,且element-ui中el-col布局span总值为24,可直接使用。从使用角度来看,每行12个流程节点是一个不错的选择。

1)页面参数说明:

        1.定制流程图:支持默认为vue-router菜单列表、通用流程图、还支持为指定业务模块单独开发流程图;

        2.默认跳转地址:进入当前业务模块默认跳转的菜单路由;

        3.查询流程项数量:是否调用查询接口,default为进入当前业务模块时调用一次,也可直接设置多少ms查询一次;

        4.查询接口地址:待处理业务数量统一查询接口(含当前业务模块字段);

        5.新增一行节点:用Array.push增加12个空节点;

        6.删除最后一行节点:用Array.pop()删除最后一行12个节点信息。

2)流程图操作方法:

        1.新增一行节点:用Array.push增加12个空节点;

        2.删除最后一行节点:用Array.pop()删除最后一行12个节点信息。

3)流程图的可视化展示

        图中的流程图展示即为实际菜单显示效果,一方面方便配置;另一方面该处的流程图显示和实际菜单出的流程图显示可以进行组件抽离,提高代码复用。

三、关键代码实现

1.流程图节点
1)template
<div v-if="detailInfo.flowType === 'flow'" class="flow_item_box"> // 流程节点类型
// 节点图标及节点文字<div :class="'flow_line_content ' + (detailInfo.jumpFlag === 1 ? 'can_click' : (detailInfo.jumpFlag === 2 ? 'can_click go' : ''))"><div class="flow_line_icon"><svg-icon v-if="detailInfo.iconType === 'system'" :icon-class="detailInfo.iconKeyword || ''" /><img v-else-if="detailInfo.iconType === 'custom' && customIconsList.includes(detailInfo.iconKeyword)" :src="require('@/assets/system_icons/' + detailInfo.iconKeyword)" style="" /> </div><div class="flow_line_label">{{ detailInfo.flowName }}</div></div>
// 横向线段<div v-for="sub in [0, 1, 2, 3, 4, 5]" :key="'line_' + sub" :class="'flow_line line_' + sub + ' ' + (detailInfo.leftFlowType[sub] === '1' ? 'isActive' : (detailInfo.leftFlowType[sub] === '2' ? 'isActiveDashed' : ''))" @click="lineChange(sub)"/>
// 竖向线段<div v-for="sub in [6, 7, 8, 9, 10, 11]" :key="'line_' + sub" :class="'flow_line_vertical line_' + sub + ' ' + (detailInfo.leftFlowType[sub] === '1' ? 'isActive' : (detailInfo.leftFlowType[sub] === '2' ? 'isActiveDashed' : ''))" @click="lineChange(sub)"/>
// 竖向箭头<div v-for="sub in [12, 13, 18, 19]" :key="'arrow_' + sub" :class="'flow_line_arrow arrow_' + sub" @click="lineChange(sub)"><i v-if="detailInfo.leftFlowType[sub] === '1'" class="el-icon-caret-top color_theme_main" /><i v-else-if="detailInfo.leftFlowType[sub] === '2'" class="el-icon-caret-bottom color_theme_main" /><i v-else class="el-icon-full-screen" /></div>
// 横向箭头<div v-for="sub in [14, 15, 16, 17]" :key="'arrow_' + sub" :class="'flow_line_arrow arrow_' + sub" @click="lineChange(sub)"><i v-if="detailInfo.leftFlowType[sub] === '1'" class="el-icon-caret-left color_theme_main" /><i v-else-if="detailInfo.leftFlowType[sub] === '2'" class="el-icon-caret-right color_theme_main" /><i v-else class="el-icon-full-screen" /></div>
// 流程说明文字<div v-if="[1, 2, 3, 4, 5, 6].includes(detailInfo.showLeftLine)" :class="tipsClass(detailInfo)">{{ detailInfo.tipsTitle }}</div>
</div>
<div v-else class="flow_line_box"> // 流程线类型
// 横向线段<div v-for="sub in [0, 1, 2, 3, 4, 5]" :key="'line_' + sub" :class="'flow_line line_' + sub + ' ' + (detailInfo.leftFlowType[sub] === '1' ? 'isActive' : (detailInfo.leftFlowType[sub] === '2' ? 'isActiveDashed' : ''))" @click="lineChange(sub)"/>
// 竖向线段<div v-for="sub in [6, 7, 8, 9, 10, 11]" :key="'line_' + sub" :class="'flow_line_vertical line_' + sub + ' ' + (detailInfo.leftFlowType[sub] === '1' ? 'isActive' : (detailInfo.leftFlowType[sub] === '2' ? 'isActiveDashed' : ''))" @click="lineChange(sub)"/>
// 竖向箭头<div v-for="sub in [12, 19]" :key="'arrow_' + sub" :class="'flow_line_arrow arrow_' + sub" @click="lineChange(sub)"><i v-if="detailInfo.leftFlowType[sub] === '1'" class="el-icon-caret-top color_theme_main" /><i v-else-if="detailInfo.leftFlowType[sub] === '2'" class="el-icon-caret-bottom color_theme_main" /><i v-else class="el-icon-full-screen" /></div>
// 横向箭头<div v-for="sub in [14, 17]" :key="'arrow_' + sub" :class="'flow_line_arrow arrow_' + sub" @click="lineChange(sub)"><i v-if="detailInfo.leftFlowType[sub] === '1'" class="el-icon-caret-left color_theme_main" /><i v-else-if="detailInfo.leftFlowType[sub] === '2'" class="el-icon-caret-right color_theme_main" /><i v-else class="el-icon-full-screen" /></div>
// 流程说明文字<div v-if="[1, 2, 3, 4, 5, 6].includes(detailInfo.showLeftLine)" :class="tipsClass(detailInfo)">{{ detailInfo.tipsTitle }}</div>
</div>
2)节点编辑入口
handleEdit(item) {    // 点击流程图中的单个节点,触发该节点编辑this.detailInfo = object.assign({}, item);this.detailVisible = true;
},
3)线段、箭头点击事件
lineChange(index) {const max = 2;    // 线段、箭头均有3个值,0, 1, 2let target = parseInt(this.detailInfo.leftFlowType[index]);if (target < max) {target++;} else {target = 0;}this.detailInfo.leftFlowType = this.detailInfo.leftFlowType.substring(0, index) + target + this.detailInfo.leftFlowType.substring(index + 1, this.detailInfo.leftFlowType.length);
},
4)节点重置及保存
handleDetailReset() {    // 节点重置// detailInfoSource 节点默认信息const resetData = Object.assign({}, detailInfoSource);Object.keys(resetData).forEach(dataKey => {this.detailInfo[dataKey] = resetData[dataKey];});
},
handleDetailSave() {    // 节点保存// 保存使用splice替换原位置节点信息// flowCode保存的当前节点的索引this.list.splice(this.detailInfo.flowCode, 1, Object.assign({}, this.detailInfo));this.detailVisible = false;
},
2.流程图预览
1)template
<el-col v-for="item in list" :span="2" :key="item.flowCode"><div v-if="item.flowType === 'flow'" class="flow_item_box_mini" @click="handleEdit(item)"> // 流程节点类型
// 节点图标及节点文字<div :class="'flow_line_content ' + (item.jumpFlag === 1 ? 'can_click' : (item.jumpFlag === 2 ? 'can_click go' : ''))"><div class="flow_line_icon"><svg-icon v-if="item.iconType === 'system'" :icon-class="item.iconKeyword || ''" /><img v-else-if="item.iconType === 'custom' && customIconsList.includes(item.iconKeyword)" :src="require('@/assets/system_icons/' + item.iconKeyword)" style="" /> </div><div class="flow_line_label">{{ item.flowName }}</div></div>
// 横向线段<div v-for="sub in [0, 1, 2, 3, 4, 5]" :key="'line_' + sub" :class="'flow_line line_' + sub + ' ' + (item.leftFlowType[sub] === '1' ? 'isActive' : (item.leftFlowType[sub] === '2' ? 'isActiveDashed' : ''))"/>
// 竖向线段<div v-for="sub in [6, 7, 8, 9, 10, 11]" :key="'line_' + sub" :class="'flow_line_vertical line_' + sub + ' ' + (item.leftFlowType[sub] === '1' ? 'isActive' : (item.leftFlowType[sub] === '2' ? 'isActiveDashed' : ''))"/>
// 竖向箭头<div v-for="sub in [12, 13, 18, 19]" :key="'arrow_' + sub" :class="'flow_line_arrow arrow_' + sub"><i v-if="item.leftFlowType[sub] === '1'" class="el-icon-caret-top color_theme_main" /><i v-else-if="item.leftFlowType[sub] === '2'" class="el-icon-caret-bottom color_theme_main" /><i v-else class="el-icon-full-screen" /></div>
// 横向箭头<div v-for="sub in [14, 15, 16, 17]" :key="'arrow_' + sub" :class="'flow_line_arrow arrow_' + sub"><i v-if="item.leftFlowType[sub] === '1'" class="el-icon-caret-left color_theme_main" /><i v-else-if="item.leftFlowType[sub] === '2'" class="el-icon-caret-right color_theme_main" /><i v-else class="el-icon-full-screen" /></div></div><div v-else class="flow_line_box_mini" @click="handleEdit(item)"> // 流程线类型
// 横向线段<div v-for="sub in [0, 1, 2, 3, 4, 5]" :key="'line_' + sub" :class="'flow_line line_' + sub + ' ' + (item.leftFlowType[sub] === '1' ? 'isActive' : (item.leftFlowType[sub] === '2' ? 'isActiveDashed' : ''))"/>
// 竖向线段<div v-for="sub in [6, 7, 8, 9, 10, 11]" :key="'line_' + sub" :class="'flow_line_vertical line_' + sub + ' ' + (item.leftFlowType[sub] === '1' ? 'isActive' : (item.leftFlowType[sub] === '2' ? 'isActiveDashed' : ''))"/>
// 竖向箭头<div v-for="sub in [12, 19]" :key="'arrow_' + sub" :class="'flow_line_arrow arrow_' + sub"><i v-if="item.leftFlowType[sub] === '1'" class="el-icon-caret-top color_theme_main" /><i v-else-if="item.leftFlowType[sub] === '2'" class="el-icon-caret-bottom color_theme_main" /><i v-else class="el-icon-full-screen" /></div>
// 横向箭头<div v-for="sub in [14, 17]" :key="'arrow_' + sub" :class="'flow_line_arrow arrow_' + sub"><i v-if="item.leftFlowType[sub] === '1'" class="el-icon-caret-left color_theme_main" /><i v-else-if="item.leftFlowType[sub] === '2'" class="el-icon-caret-right color_theme_main" /><i v-else class="el-icon-full-screen" /></div>
// 流程说明文字<div v-if="[1, 2, 3, 4, 5, 6].includes(item.showLeftLine)" :class="tipsClass(item)">{{ item.tipsTitle }}</div></div>
</el-col>
2)流程初始化
created() {// http请求落库数据,若没有数据,则默认增加第一行节点this.handleAdd();
},
3)流程节点增删操作
handleAdd(){// flowCode保存当前节点索引,方便节点编辑保存for (let i = 0;i <= 11; i++) {this.list.push(Object.assign({}, detailInfoSource, { flowCode:this.list.length }));}
},
handleDeleteBatch() {// 剔除最后的一行节点(12个)for (let i = 0;i < 11;i++){this.list.pop();}
},

四、样式具体代码

<style lang="scss" scoped>
.flow_item_box {width:480px;height:400px;text-align:center;.flow_line_content {width:240px;height:200px;float:left;margin-left:120px;margin-top:100px;padding-top:24px;border:1px dashed #eaeaea;.flow_line_icon {font-size:72px;}.flow_line_label {margin-top:12px;font-size:24px;font-weight:bold;}&.can_click {color:$theme-color-main;&.go {color:#f56c6c;}}}.flow_line {position:absolute;height:6px;width:230px;background:#ccc;cursor:pointer;&.line_1 {right:0;}&.line_2 {width:80px;left:20px;top:calc(50% - 3px);}&.line_3 {width:80px;right:20px;top:calc(50% - 3px);}&.line_4 {bottom:0;}&.line_5 {right:0;bottom:0;}&.isActive {background:$theme-color-main;}&.isActiveDashed {background:linear-gradient(90deg, $theme-color-main 50%, #fff 50%);background-size:12px 100%;}}.flow_line_vertical {position:absolute;height:190px;width:6px;background:#ccc;cursor:pointer;&.line_7 {top:20px;height:60px;right:calc(50% - 3px);}&.line_8 {right:0;}&.line_9 {bottom:0;}&.line_10 {bottom:20px;height:60px;right:calc(50% - 3px);}&.1ine_11 {right:0;bottom:0;}&.isActive {background:$theme-color-main;}&.isActiveDashed {background:linear-gradient($theme-color-main 50%, #fff 50%);background-size:100% 12px;}}.flow_line_arrow {position:absolute;width:20px;height:20px;text-align:center;cursor:pointer;font-size:18px;font-weight:bold;line-height:20px;&.arrow_12 {right:calc(50% - 10px);}&.arrow_13 {top:80px;right:calc(50% - 10px);}&.arrow_14 {top:calc(50% - 10px);}&.arrow_15 {top:calc(50% - 10px);left:100px;}&.arrow_16 {top:calc(50% - 10px);right:100px;}&.arrow_17 {top:calc(50% - 10px);right:0;}&.arrow_18 {bottom:80px;right:calc(50% - 10px);}&.arrow_19 {bottom:0;right:calc(50% - 10px);}}.flow_line_tips {position:absolute;width:80px;line-height:20px;font-size:14px;left:calc(75% + 20px);text-align:left;&.tips_t_u {top:-20px;}&.tips_t_d {top:4px;}&.tips_m_u {top:calc(50% - 20px);}&.tips_m_d {top:calc(50% + 4px);}&.tips_b_u {top:calc(100% - 24px);}&.tips_b_d {top:100%;}}
}
.flow_line_box {width:480px;height:400px;text-align:center;.flow_line {position:absolute;height:6px;width:230px;background:#ccc;cursor:pointer;&.line_1 {right:0;}&.line_2 {width:220px;left:20px;top:calc(50% - 3px);}&.line_3 {width:220px;right:20px;top:calc(50% - 3px);}&.line_4 {bottom:0;}&.line_5 {right:0;bottom:0;}&.isActive {background:$theme-color-main;}&.isActiveDashed {background:linear-gradient(90deg, $theme-color-main 50%, #fff 50%);background-size:12px 100%;}}.flow_line_vertical {position:absolute;height:190px;width:6px;background:#ccc;cursor:pointer;&.line_7 {height:180px;top:20px;right:calc(50% - 3px);}&.line_8 {right:0;}&.line_9 {bottom:0;}&.line_10 {height:180px;bottom:20px;right:calc(50% - 3px);}&.1ine_11 {right:0;bottom:0;}&.isActive {background:$theme-color-main;}&.isActiveDashed {background:linear-gradient($theme-color-main 50%,#fff 50%);background-size:100% 12px;}}.flow_line_arrow {position:absolute;width:20px;height:20px;text-align:center;cursor:pointer;font-size:18px;font-weight:bold;line-height:20px;&.arrow_12 {right:calc(50% - 10px);}&.arrow_14 {top:calc(50% - 10px);}&.arrow_17 {top:calc(50% - 10px);right:0;}&.arrow_19 {bottom:0;right:calc(50% - 10px);}}.flow_line_tips {position:absolute;width:440px;line-height:20px;font-size:14px;left:20px;text-align:left;&.tips_t_u {top:-20px;}&.tips_t_d {top:4px;}&.tips_m_u {top:calc(50% - 20px);}&.tips_m_d {top:calc(50% + 4px);}&.tips_b_u {top:calc(100% - 24px);}&.tips_b_d {top:100%;}}
}
.flow_item_box_mini {width:120px;height:120px;text-align:centercursor:pointer;.flow_line_content {width:60px;height:60px;float:left;margin-left:30px;margin-top:30px;padding-top:2px;border:1px dashed #eaeaea;.flow_line_icon {font-size:24px;}flow_line_label {margin-top:2px;font-size:12px;font-weight:bold;}&.can_click {color:$theme-color-main;&.go {color:#f56c6c;}}}.flow_line {position:absolute;height:1px;width:60px;background:#ccc;&.line_1 {margin-left:60px;}&.line_2 {width:30px;margin-top:59px;}&.line_3 {margin-left:90px;width:30px;margin-top:59px;}&.line_4 {margin-top:118px;}&.line_5 {margin-left:60px;margin-top:118px;}&.isActive {height:2px;background:$theme-color-main;}&.isActiveDashed {height:2px;background:linear-gradient(90deg, $theme-color-main 50%, #fff 50%);background-size:4px 100%;}}.flow_line_vertical {position:absolute;height:60px;width:1px;background:#ccc;&.line_7 {height:30px;margin-left:59px;}&.1ine_8 {margin-left:118px;}&.line_9 {margin-top:60px;}&.line_10 {margin-top:90px;height:30px;margin-left:59px;}&.line_11 {margin-left:118px;margin-top:60px;}&.isActive {width:2px;background:$theme-color-main;}&.isActiveDashed {width:2px;background:linear-gradient($theme-color-main 50%, #fff 50%);background-size:100% 4px;}}.flow_line_arrow {position:absolute;width:14px;height:14px;text-align:center;font-size:14px;font-weight:bold;line-height:14px;&.arrow_12 {margin-left:53px;margin-top:-4px;}&.arrow_13 {margin-top:21px;margin-left:53px;}&.arrow_14 {margin-top:53px;margin-left:-4px;}&.arrow_15 {margin-top:53px;margin-left:20px;}&.arrow_16 {margin-top:53px;margin-Left:85px;}&.arrow_17 {margin-top:53px;margin-left:108px;}&.arrow_18 {margin-top:85px;margin-left:53px;}&.arrow_19 {margin-top:110px;margin-left:53px;}}
}
.flow_line_box_mini {width:120px;height:120px;text-align:center;cursor:pointer;.flow_line{position:absolute;height:1px;width:60px;background:#ccc;&.line_1 {margin-left:60px;}&.line_2 {margin-top:59px;}&.line_3 {margin-left:60px;margin-top:59px;}&.line_4 {margin-top:118px;}&.line_5 {margin-lLeft:60px;margin-top:118px;}&.isActive {height:2px;background:$theme-color-main;}&.isActiveDashed {height:2px;background:linear-gradient(90deg, $theme-color-main 50%, #fff 50%);background-size:4px 100%;}}.flow_line_vertical {position:absolute;height:60px;width:1px;background:#ccc;&.line_7 {height:60px;margin-left:59px;}&.line_8 {margin-left:118px;}&.line_9 {margin-top:60px;}&.line_10 {margin-top:60px;margin-left:59px;}&.1ine_11 {margin-left:118px;margin-top:60px;}&.isActive {width:2px;background:$theme-color-main;}&.isActiveDashed {width:2px;background:linear-gradient($theme-color-main 50%, #fff 50%);background-size:100% 4px;}}.flow_line_arrow {position:absolute;width:14px;height:14px;text-align:center;font-size:14px;font-weight:bold;line-height:14px;&.arrow_12 {margin-left:53px;margin-top:-4px;}&.arrow_14 {margin-top:53px;margin-left:-4px;}&.arrow_17 {margin-top:53px;margin-left:108px;}&.arrow_19 {margin-top:110px;margin-left:53px;}}.flow_line_tips {position:absolute;width:102px;line-height:16px;font-size:12px;margin-left:8px;text-align:left;max-height:66px;overflow:hidden;&.tips_t_u {margin-top:-16px;}&.tips_t_d {margin-top:2px;}&.tips_m_u {margin-top:43px;}&.tips_m_d {margin-top:60px;}&.tips_b_u {margin-top:102px;}&.tips_b_d {margin-top:120px;}}
}
</style>

五、总结

        以上为显式管理业务流程的全部内容,各位感兴趣的筒子们,若在实践过程中有哪些好的优化方向或具体优化方案,欢迎踊跃讨论~

http://www.dtcms.com/a/319857.html

相关文章:

  • [激光原理与应用-171]:测量仪器 - 能量型 - 激光能量计(单脉冲能量测量)
  • DicomObjects COM 8.XX
  • VUE+SPRINGBOOT从0-1打造前后端-前后台系统-文章列表
  • [TIP 2025] 轻量级光谱注意力LSA,极致优化,减少99.8%参数,提升性能!
  • kafka安装与参数配置
  • MPC-in-the-Head 转换入门指南
  • 抖音、快手、视频号等多平台视频解析下载 + 磁力嗅探下载、视频加工(提取音频 / 压缩等)
  • 【性能测试】---测试工具篇(jmeter)
  • Java垃圾回收(GC)探析
  • 图像理解、计算机视觉相关名词解释
  • 最新教程 | CentOS 7 内网环境 Nginx + ECharts 页面离线部署手册(RPM 安装方式)
  • yolo目标检测技术:基础概念(一)
  • Vscode Data Wrangler 数据查看和处理工具
  • Docker容器技术详解
  • 施易德智慧门店管理系统:零售品牌出海的高效引擎
  • mysql 索引失效分析
  • Cesium粒子系统模拟风场动态效果
  • 国内使用 npm 时配置镜像源
  • 网络安全等级保护(等保)2.0 概述
  • 树莓派下载安装miniconda(linux版小anaconda)
  • 【奔跑吧!Linux 内核(第二版)】第6章:简单的字符设备驱动(一)
  • 解决 Nginx 反代中 proxy_ssl_name 环境变量失效问题:网页能打开但登录失败
  • 3深度学习Pytorch-神经网络--全连接神经网络、数据准备(构建数据类Dataset、TensorDataset 和数据加载器DataLoader)
  • TCP 如何保证可靠性
  • Linux openssl、openssh 升级 保留旧版本
  • 【插件式微服务架构系统分享】之 解耦至上:gateway 网关与APISIX 网关的不同分工
  • React 为什么要自定义 Hooks?
  • 一文解读“Performance面板”前端性能优化工具基础用法!
  • 顺序表——C语言
  • FPGA学习笔记——VGA静态字符的显示(寄存器)