门诊发退药追溯码采集系统解析:

一、门诊发退药追溯码数据表

1.1、Wm_ware_dispense_bill表:该表用于存储处方信息

1.2 Wm_ware_dispense_tracecode:追溯码采集表

二、发退药后端代码

        后端代码基于Springboot架构和mybatis-plus,先看主要接口信息:

1.1、该接口用于接收处方号、部门id和操作人三个参数,回参是处方单的药品信息

/*** 接口名称: WareDispenseBillController$* 功能描述:用于存储处方单信息,以及查询信息并输出到页面*/@RestController
@RequestMapping("/wareDispenseBill")
public class WareDispenseBillController {@Resourceprivate WmWareDispenseBillService wmWareDispenseBillService;@GetMapping("/split/{Rxno}/{departmentid}/{username}")@Transactional(rollbackFor = Exception.class)public R getWareBaseInfo_tz_v_split(@PathVariable String Rxno,@PathVariable String departmentid,@PathVariable String username) {try {AtomicInteger statusCode = new AtomicInteger(0);List<WareInfoSplit> wareInfo_t = wmWareDispenseBillService.querySplit(Rxno, departmentid, username, statusCode);// 已上传医保或查询失败时,返回空数组而非错误消息if (wareInfo_t == null) {return R.OK(new ArrayList<>());}return R.OK(wareInfo_t);} catch (Exception e) {return R.FAIL("系统错误");}}
}

其中回参WareInfoSplit,用于传递给前端渲染,供发药医师确定发药情况:

  1. splitFlag代表拆零标志,如果 splitFlag=00 说明该药品是非拆零药品,非拆零药品需要门诊挨个扫码,而拆零药品需要药库提前扫码,储备子码库方表调用
  2. billid是处方表的主键
  3. wareid是商品id
  4. patientName是患者名
  5. spec是规格
  6. quantity是发药数量
  7. manufacturer是生成厂家
  8. tracecodePrefix是药品追溯码前七位,也被称为标识码
  9. scanFlag是用于院内制剂,没有追溯码的药品的标识
  10. enoughFlag是当药品为拆零药品,且储备的剩余子码不足发药数量时,用于前端提示
  11. splitTracecode是待拆追溯码
  12. subcodeids是存储拆零子码的codeid
@Data
@AllArgsConstructor
public class WareInfoSplit {private String splitFlag;private Long billid;private Integer wareid;private String patientName;private String wareName;private String spec;private Integer quantity;private String manufacturer;private String tracecodePrefix; //药品标识码,前七位private String scanFlag;  //是否需要扫码private String enoughFlag; //库存追溯码数量,是否能覆盖发药需求,00是能覆盖,10是不能覆盖private String splitTracecode;  //待拆追溯码private List<Integer> subcodeids; //存储拆零子码的codeid

1.2 上面的querySplit方法如下:

1.2.1 该方法首先需要对接his接口,该接口通过处方号来获取药品基本信息。

 @Transactional@Overridepublic List<WareInfoSplit> querySplit(String RecipeNo, String departmentid, String username, AtomicInteger statusCode) {// 1. 调用外部API获取处方数据final String API_URL = "http://ip:post/QueryRxno";//创建一个 JSON 格式的字符串//这里用到了转义字符,把双引号转义为普通的字符String requestJson = String.format("{\"RecipeNo\":\"%s\"}", RecipeNo);try {// 发送API请求RestTemplate restTemplate = new RestTemplate();HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_JSON);//HttpEntity封装请求体和请求头。HttpEntity<String> requestEntity = new HttpEntity<>(requestJson, headers);//返回的ResponseEntity<String>包含响应状态码和响应体ResponseEntity<String> response = restTemplate.exchange(API_URL, HttpMethod.POST, requestEntity, String.class);if (response.getStatusCode() != HttpStatus.OK) {statusCode.set(1);   //此时就是没能成功调用接口return null;}//将 HTTP 响应中的 JSON 字符串转换为 Java 的Map<String, Object>对象ObjectMapper objectMapper = new ObjectMapper();Map<String, Object> resultMap = objectMapper.readValue(response.getBody(), new TypeReference<Map<String, Object>>() {});if (!"1".equals(resultMap.get("ReturnCode"))) { //ReturnCode如果不等于1就一定不正常statusCode.set(2);return null;}//ReturnCode等于1,也有可能回传空的列表List<Map<String, Object>> details = (List<Map<String, Object>>) resultMap.get("Details");if (details == null || details.isEmpty()) {statusCode.set(3);return null;  //未查询到处方}

医院his接口部分回参如下:

1.2.2  第二段的代码逻辑:

1)医院只会传药品编码,我需要通过维护的药品基础表来查询对应的药品基础信息记录,其中比较重要的是

tracecode_prefix:药品标识码

split_flag:拆零标志

split_ratio:拆零系数,若药品为拆零药品,假设追溯码贴在药盒上,一盒有10支,则拆零系数为10

2)源码:

        有些处方号可能之前已经扫过,这里存在两种情况:一是医生开具处方之后,患者没有及时过来拿,而医院没有报道机的情况下,就会在打印处方单的同时扫码;二是发药医师扫过处方单之后,又误扫处方单,此时在处方表内就会有历史记录,需要找到记录扫处方的记录

// 2. 性能优化 - 批量收集药品编码并查询Set<String> drugCodes = new HashSet<>();  //发药的药品编码List<String> rxNos = new ArrayList<>();   //发药的处方号List<String> rxSerialNos = new ArrayList<>();  //发药的处方明细号for (Map<String, Object> item : details) {drugCodes.add(item.get("ware_code").toString());rxNos.add(item.get("rxno").toString());rxSerialNos.add(item.get("rx_serialno").toString());}// 批量查询药品基础信息// 通过药品编码查询药品信息,并转换为Map<ware_code, PubWareBase>的结构。Map<String, PubWareBase> wareBaseMap = drugCodes.isEmpty() ? new HashMap<>() :pubWareBaseMapper.selectList(new LambdaQueryWrapper<PubWareBase>().in(PubWareBase::getWareCode, drugCodes)).stream().collect(Collectors.toMap(PubWareBase::getWareCode,Function.identity(),(existing, replacement) -> existing));List<WmWareDispenseBill> billsToSave = new ArrayList<>();   //准备插入到WmWareDispenseBill表中的记录List<WareInfoSplit> wareInfoList = new ArrayList<>();   //准备回传的接口数据// 3. 批量查询已存在的处方记录// map对象的键是rxno|rxSerialno的组合字符串,值为对应的处方对象。Map<String, WmWareDispenseBill> existingBillsMap = new HashMap<>();  //记录哪写处方以前创建过if (!rxNos.isEmpty()) {  //根据处方号和处方明细号,查询已有的处方记录List<WmWareDispenseBill> existingBills = this.list(new LambdaQueryWrapper<WmWareDispenseBill>().in(WmWareDispenseBill::getRxno, rxNos).in(WmWareDispenseBill::getRxSerialno, rxSerialNos));existingBills.forEach(bill ->existingBillsMap.put(bill.getRxno() + "|" + bill.getRxSerialno(), bill));}

        

1.2.3 对有扫码记录的处方单,我们区分了以下的几种情况。

        (1)如果此处方号是第一次扫描,则在下表内新增处方信息

        (2)如果此处方之前扫过,但是并没有扫描对应的追溯码,则处方表内有记录,且status为00,此时记录billid,返回该记录,并在高拍仪屏幕显示

        (3)如果 此处方之前扫过,且已经扫过追溯码并提交,则默认为该患者开方当天并未取药,此时应重新扫描追溯码并作废之前已扫追溯码

        (4)如果此处方之前扫过,且扫过追溯码,且已提交医保,则不返回任何回参。

for (Map<String, Object> item : details) {WareInfoSplit wareInfo = new WareInfoSplit(); //需上传数据String rxno = item.get("rxno").toString();String rxSerialno = item.get("rx_serialno").toString();String key = rxno + "|" + rxSerialno;String drugCode = item.get("ware_code").toString();PubWareBase pubWareBase = wareBaseMap.get(drugCode);// 跳过无药品信息的记录if (pubWareBase == null) {continue;}// 这个处方记录以前创建过if (existingBillsMap.containsKey(key)) {//获取其对应的处方记录对象WmWareDispenseBill existingBill = existingBillsMap.get(key);// 情况1: status = '00',这个已创建的记录仍是待扫码,if ("00".equals(existingBill.getStatus())) {//新增,现在这种情况,该记录可能是从视图抓取并插入进来的数据,要把他没有但是接口给的数据补充上LambdaUpdateWrapper<WmWareDispenseBill> updateWrapper = new LambdaUpdateWrapper<>();updateWrapper.eq(WmWareDispenseBill::getBillid, existingBill.getBillid()).set(WmWareDispenseBill::getOperator, username).set(WmWareDispenseBill::getOperateTime, new Date());if (!this.update(updateWrapper)) {throw new RuntimeException("更新处方部门信息失败,未找到对应记录或更新失败");}//创建最终回传的一个WareInfo对象wareInfo = createWareInfo_split(item, pubWareBase,departmentid);wareInfo.setBillid(existingBill.getBillid());wareInfoList.add(wareInfo); //添加到最终回传的数据中continue;}// 情况2: status = '10' 且 uploadStatus为null或'00',此时虽然已经扫过码,但是还没有上传医保,仍可以更改if ("10".equals(existingBill.getStatus()) &&(existingBill.getUploadStatus() == null || "00".equals(existingBill.getUploadStatus()))) {//把这条处方记录的状态值、上传状态值、操作员等信息通过billid来更新WmWareDispenseBill updateEntity = new WmWareDispenseBill();updateEntity.setBillid(existingBill.getBillid()); //billid取以前创建的billidupdateEntity.setStatus("00");updateEntity.setUploadStatus("00");updateEntity.setOperator(username);updateEntity.setOperateTime(new Date());//更新处方信息if (!this.updateById(updateEntity)) {throw new RuntimeException("处方单状态重置失败");}wareInfo = createWareInfo_split(item, pubWareBase,departmentid);wareInfo.setBillid(existingBill.getBillid());wareInfoList.add(wareInfo);//添加到最终回传的数据中continue;}// 情况3: status = '10' 且 uploadStatus = '10'if ("10".equals(existingBill.getStatus()) && "10".equals(existingBill.getUploadStatus())) {statusCode.set(4);return null; //此时不可更改}}// 程序运行到这,说明这个处方是新处方,所以需要准备需要新建的处方数据WmWareDispenseBill bill = createNewBill_n(item, wareBaseMap, username, "patientId", departmentid);billsToSave.add(bill);  //添加到准备插入处方表的集合中wareInfoList.add(createWareInfo_split(item, pubWareBase,departmentid));}// 程序运行到这,说明这个处方是新处方,所以需要准备需要新建的处方数据WmWareDispenseBill bill = createNewBill_n(item, wareBaseMap, username, "patientId", departmentid);billsToSave.add(bill);  //添加到准备插入处方表的集合中wareInfoList.add(createWareInfo_split(item, pubWareBase,departmentid));}// 5. 新处方if (!billsToSave.isEmpty()) { //需要插入新处方if (!this.saveBatch(billsToSave)) { //保存到处方表throw new RuntimeException("保存处方数据失败");}//遍历wareInfoList,为billid为null的记录设置正确的billidupdateWareInfoListWithBillIds_split(billsToSave, wareInfoList);}return wareInfoList;} catch (Exception e) {log.error("处方数据获取失败:", e);return null;}}

        这里解释下,情况2: status = '10' 且 uploadStatus为null或'00',此时虽然已经扫过码,但是还没有上传医保,也就是说无论是误扫还是隔夜取药,都认为是这种情况。此时并不在wm_ware_dispense_bill表中插入新的记录,而是沿用之前的记录,并且把状态值复原。

        这里用到的updateById是在 MyBatis(以及 MyBatis-Plus)中用于根据实体对象的主键(ID)更新对应的数据记录

  • 它会根据传入实体对象的 主键字段(通常是id 定位到数据库中对应的记录
  • 然后将实体对象中非空的字段值更新到数据库表中对应的字段

        情况3意味着该条记录已经上传医保,此时不可再重新扫码,因为已经被监管机构记录,因此扫描该处方单时是不会出现药品信息的。

1.2.4 如果wm_ware_dispense_bill表中没有接口回传的处方信息,则会用到下面的创建处方表记录的代码

//处方对象原先不存在时,创建一个新的WmWareDispenseBill对象private WmWareDispenseBill createNewBill_n(Map<String, Object> item, Map<String, PubWareBase> wareBaseMap,String username, String patientid, String departmentid) {WmWareDispenseBill bill = new WmWareDispenseBill();bill.setHospitalid(1L);bill.setDepartmentid(Long.valueOf(departmentid));bill.setBillType(item.get("type").toString());bill.setRxno(item.get("rxno").toString());bill.setRxSerialno(item.get("rx_serialno").toString());bill.setPatientName(item.get("patient_name").toString());String drugCode = item.get("ware_code").toString();PubWareBase pubWareBase = wareBaseMap.get(drugCode);bill.setWareId(pubWareBase != null ? pubWareBase.getWareid() : null);if (pubWareBase != null) {String description = String.format("[%s]%s(%s)/%s/%s/%s",pubWareBase.getWareCode(),pubWareBase.getFormalName(),pubWareBase.getWareName(),pubWareBase.getSpec(),pubWareBase.getUnitName(),pubWareBase.getManufacturer());bill.setDescription(description);}bill.setQuantity(Integer.parseInt(item.get("quantity").toString()));bill.setOperator(username);bill.setOperateTime(new Date());bill.setStatus("00");bill.setPatientid(patientid);try {String dateStr = item.get("rx_date").toString();Date date = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse(dateStr);bill.setRxDate(date);} catch (ParseException e) {System.out.println(e);}bill.setDoctorName(item.get("doctor_name").toString());bill.setSettlementno(item.get("mdtrt_id").toString());return bill;}

1.2.5 拆零子码的分配

        扫描处方时,会有些药是拆零药品,发药时按照1支1粒这种样式,此时储备相应的子码就很有必要。

        具体拆零子码如何进表以后再讲,这里只要知道一个拆零药品的追溯码会根据其拆零系数,在该表内拆分成相应数量的子码。

        有上面的子码,就可以在扫描处方单时,分配需要的子码:

private WareInfoSplit createWareInfo_split(Map<String, Object> item, PubWareBase pubWareBase,String departmentid) {WareInfoSplit wareInfo = new WareInfoSplit();if ("10".equals(pubWareBase.getSplitFlag()) && !"盒".equals(item.get("price_unit").toString())) {int quantitySplit = Integer.parseInt(item.get("quantity").toString());List<PubTracecodeSubcode> lockedSubcodes = pubTracecodeSubcodeMapper.selectList(new LambdaQueryWrapper<PubTracecodeSubcode>().eq(PubTracecodeSubcode::getTracecodePrefix, pubWareBase.getTracecodePrefix()).eq(PubTracecodeSubcode::getStatus, "00").eq(PubTracecodeSubcode::getLockedStatus, "00").eq(PubTracecodeSubcode::getDepartmentid, departmentid).orderByAsc(PubTracecodeSubcode::getCodeid) // 按固定顺序避免死锁.last("LIMIT " + quantitySplit + " FOR UPDATE") // 核心:锁定指定数量记录);// 检查是否锁定到足够数量 ===if (lockedSubcodes.size() < quantitySplit) {wareInfo.setEnoughFlag("10"); // 数量不足}else {// 更新锁定状态 ===List<Integer> codeIdsToLock = lockedSubcodes.stream().map(PubTracecodeSubcode::getCodeid).collect(Collectors.toList());pubTracecodeSubcodeMapper.update(null, new LambdaUpdateWrapper<PubTracecodeSubcode>().in(PubTracecodeSubcode::getCodeid, codeIdsToLock).set(PubTracecodeSubcode::getLockedStatus, "10"));// 设置分配结果wareInfo.setEnoughFlag("00");wareInfo.setSubcodeids(codeIdsToLock);wareInfo.setSplitTracecode(lockedSubcodes.get(0).getTracecode());}}wareInfo.setSplitFlag(pubWareBase.getSplitFlag());wareInfo.setWareid(pubWareBase.getWareid().intValue());wareInfo.setPatientName(item.get("patient_name").toString());wareInfo.setWareName(pubWareBase.getWareName());wareInfo.setSpec(pubWareBase.getSpec());wareInfo.setQuantity(Integer.parseInt(item.get("quantity").toString()));wareInfo.setManufacturer(pubWareBase.getManufacturer());wareInfo.setTracecodePrefix(pubWareBase.getTracecodePrefix());wareInfo.setScanFlag(pubWareBase.getScanFlag());return wareInfo;}

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity编辑器相关

前言继承EditorWindow。 GUILayout类与EditorGUILayout类的应用区别&#xff1a;//TODO创建窗口的方法1&#xff09;GetWindow<T>() 已开则聚焦、未开则创建。无需再手动调用 Show()。GetWindow<T>() 提供多个重载。2&#xff09;CreateInstance<T>()始终创建…

ES支持哪些数据类型,和MySQL之间的映射关系是怎么样的?

Elasticsearch&#xff08;简称 ES&#xff09;是一个分布式搜索和分析引擎&#xff0c;支持丰富的数据类型来适应不同场景。MySQL 是一个关系型数据库&#xff0c;两者在数据类型上存在差异&#xff0c;但可以通过映射实现数据同步或集成。下面我将逐步解释 ES 支持的数据类型…

8.21IPSEC安全基础后篇,IKE工作过程

一、数据存储完整性校验数据存储完整性校验需通过加密密钥实现。数据存储前还需通过身份认证&#xff0c;该过程同样依赖密钥完成。二、对称key的产生、传递、管理VPN中需使用多组对称密钥&#xff1a;数据加解密需独立密钥数据完整性校验需独立密钥身份认证需独立密钥不同功能…

网络连接的核心机制

一、网络连接全流程拆解&#xff08;含7大步骤动态交互&#xff09; 1. 用户输入网址&#xff1a;从域名到IP的跨越 操作触发&#xff1a;用户在浏览器输入 www.example.com&#xff0c;触发 DNS域名解析。核心协议&#xff1a;DNS&#xff08;基于UDP/TCP&#xff09;。硬件设…

小程序个人信息安全检测技术:从监管视角看加密与传输合规

1. 前言 在监管通报中&#xff0c;小程序因“未采取加密、去标识化等安全技术措施”被处罚的案例屡见不鲜。很多开发者疑惑&#xff1a;明明用了HTTPS&#xff0c;为什么还会被判定“未加密”&#xff1f;监管机构是如何通过技术手段发现这些问题的&#xff1f;本文将从技术原…

ansible playbook 实战案例roles | 实现db2自动安装

文章目录一、核心功能描述二、roles内容2.1 文件结构2.2 主配置文件2.3 tasks文件内容三、files文件内容四、vars文件内容免费个人运维知识库&#xff0c;欢迎您的订阅&#xff1a;literator_ray.flowus.cn 一、核心功能描述 这个 Ansible Role 的核心功能是&#xff1a;​自动…

webrtc中win端音频---windows Core Audio

一、Core Audio 系统内核框架 图中显示的是渲染的音频数据如何从大多数应用程序流向扬声器的简化表示。对于采集来说,音频数据的路径是完全相同,但流向是相反的。从图中可以看到,一些高阶API(例如MME,DirectSound等),对 Core Audio APIs 进行了封装,使用这些API能够更容…

【数据可视化-96】使用 Pyecharts 绘制主题河流图(ThemeRiver):步骤与数据组织形式

&#x1f9d1; 博主简介&#xff1a;曾任某智慧城市类企业算法总监&#xff0c;目前在美国市场的物流公司从事高级算法工程师一职&#xff0c;深耕人工智能领域&#xff0c;精通python数据挖掘、可视化、机器学习等&#xff0c;发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…

【Android】Activity 如何进行数据传输

三三要成为安卓糕手 一&#xff1a;Activity之间的数据传输 问题&#xff1a;不同的Activity之间怎么进行数据传输呢? 比如第一个页面中有一些字符串数据之类的要通过数据传输&#xff0c;传递给第二个页面进行显示的 1&#xff1a;MainActivity做处理 在定义一个按钮&#xf…

C#语言的语法(数据类型)

数据类型 表2.1给出了C#的主要数据类型。注意&#xff0c;基本类型的长度与计算机或操作系统的类型无关。C# 中的字符是16位的宽度&#xff0c;可以表示非拉丁语言中的所有字符。它使用一种叫双字节码的字符编码 系统&#xff0c;其中定义了绝大多数可书写语言的数以千计的字符…

Vue3 + TypeScript全局阻止非输入区域的Backspace键,防止回退页面

main.ts/*** 应用程序主入口** 初始化 Vue 应用并挂载到 DOM*/ import "./assets/style/main.scss";import { createApp } from "vue"; // 全局引入element-plus&#xff0c;对打包后的文件大小不是很在乎&#xff0c;那么使用全局导入会更方便 import Ele…

01数据结构-堆排序

01数据结构-堆排序前言1.堆2.堆的操作逻辑3.堆的代码实现前言 数据结构中的堆是一种结构&#xff0c;C语言的堆是空间管理的程序员malloc&#xff0c;free的空间&#xff0c;两者没多大关系。 1.堆 逻辑上 堆&#xff08;Heap&#xff09;是一类基于完全二叉树的特殊数据结构…

在线课程|基于SprinBoot+vue的在线课程管理系统(源码+数据库+文档)

在线课程 目录 基于SprinBootvue的在线课程管理系统 一、前言 二、系统设计 三、系统功能设计 1 管理员模块的实现 2在线课程 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#xff1a;✌️大厂码农|…

Python海象运算符:=

文章目录简介​​条件判断优化循环控制简化​推导式高效计算​正则匹配与数据提取​性能对比参考文献简介 海象运算符 :&#xff0c;又称​​赋值表达式​​&#xff08;Assignment Expression&#xff09;&#xff0c;Python 3.8 后可用&#xff0c;PEP 572 引入&#xff0c;…

Vue 2 项目中快速集成 Jest 单元测试(超详细教程)

在 Vue 项目中编写单元测试&#xff0c;是提升代码质量和维护性的关键一步。本文将带你从零开始&#xff0c;在一个 Vue 2 Vue CLI 项目中集成 Jest 作为单元测试框架&#xff0c;并运行第一个测试用例。✅ 适用于 Vue 2 项目&#xff08;如你使用的是 vue-cli-service&#x…

PostgreSQL15——管理表空间

管理表空间一、基本概念二、创建表空间三、修改表空间四、删除表空间一、基本概念 在 PostgreSQL 中&#xff0c;它是通过表空间&#xff08;Tablespaces&#xff09;来实现逻辑对象&#xff08;表、索引等&#xff09;与物理文件之间的映射。创建数据库或者数据表&#xff08…

趣打印高级版--手机打印软件!软件支持多种不同的连接方式,打印神器有这一个就够了!

软件介绍&#xff08;文末获取&#xff09;趣打印高级版是一款手机打印软件。软件支持五种不同的连接方式&#xff0c;每种都有稳定且快速的反应&#xff0c;用户均可通过手机进行打印机的远程使用和设置。软件还支持上传不同格式的文档类型进行打印&#xff0c;方便快捷&#…

【开源框架】7 款流行的 Vue 3 后台管理框架对比

以下是 7 个流行的 Vue 3 后台管理框架在 Star 数&#xff08;截至 2025 年 8 月21日的 GitHub 最新数据&#xff09;、框架特点、基于的技术栈及开源协议四个方面的详细对比&#xff1a; 1. Vue-Vben-Admin GitHub 地址&#xff1a;https://github.com/vbenjs/vue-vben-admin…

Datawhale工作流自动化平台n8n入门教程(一):n8n简介与平台部署

前言 在数字化时代&#xff0c;重复性的工作任务正在消耗着我们大量的时间和精力。从数据同步到营销自动化&#xff0c;从客户服务到内容管理&#xff0c;这些琐碎但必要的任务往往让我们疲于应对。而工作流自动化工具的出现&#xff0c;为我们提供了一个优雅的解决方案。 今天…

SRE - 定位与能力

仅为个人知识总结与记录 Site Reliability Engineer&#xff1a;站点可靠性工程&#xff08;SRE 软件工程师 运维专家 可靠性专家&#xff09; 相对传统的运维工程师&#xff0c;SER 注重开发&#xff0c;效率&#xff0c;追求自动化。对于 SRE 工程师&#xff0c;追究的就是…