尚医通 (二十二)预约下单

news2024/10/2 8:26:50

目录

  • 一、预约下单功能(一)
    • 1、需求
    • 2、搭建订单模块
    • 3、封装Feign调用获取就诊人接口
    • 4、封装Feign调用获取排班下单信息接口
  • 二、预约下单功能(二)
    • 1、实现生成订单接口
  • 三、预约下单功能(三)
  • 四、预约下单功能(四)
    • 1、生成订单后处理逻辑-封装短信接口
    • 2、生成订单后处理逻辑-更新排班数量
    • 3、生成订单后处理逻辑-完善订单接口
  • 五、订单列表功能
    • 1、订单列表接口
    • 2、订单列表前端
  • 六、订单详情功能

一、预约下单功能(一)

1、需求

(1)订单表结构
在这里插入图片描述
(2)生成订单分析
生成订单需要的参数:就诊人id与 排班id
第一、生成订单需要获取就诊人信息
第二、获取排班下单信息与规则信息
第三、下单后,然后通过接口去医院预约下单
第四、下单成功更新排班信息与发送短信

2、搭建订单模块

(1)搭建service_order模块
(2)引入依赖

<dependencies>
    <dependency>
        <groupId>com.donglin</groupId>
        <artifactId>service_cmn_client</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>
</dependencies>

(3)添加配置文件

# 服务端口
server.port=8207
# 服务名
spring.application.name=service-orders
# 环境设置:dev、test、prod
spring.profiles.active=dev

# mysql数据库连接
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.121.140:3306/yygh_order?characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456

#返回json的全局时间格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8

spring.data.mongodb.uri=mongodb://192.168.121.140:27017/test

# nacos服务地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848

#rabbitmq地址
#spring.rabbitmq.host=192.168.44.165
#spring.rabbitmq.port=5672
#spring.rabbitmq.username=guest
#spring.rabbitmq.password=guest

spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.database= 0
spring.redis.timeout=1800000

spring.redis.lettuce.pool.max-active=20
spring.redis.lettuce.pool.max-wait=-1
#最大阻塞等待时间(负数表示没限制)
spring.redis.lettuce.pool.max-idle=5
spring.redis.lettuce.pool.min-idle=0

(4)创建启动类

@SpringBootApplication
@MapperScan("com.donglin.yygh.order.mapper")
@ComponentScan(basePackages = {"com.donglin"})
@EnableDiscoveryClient
@EnableFeignClients(basePackages = {"com.donglin"})
public class ServiceOrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceOrderApplication.class, args);
    }
}

(5)配置网关
properties

#设置路由id
spring.cloud.gateway.routes[7].id=service-orders
#设置路由的uri
spring.cloud.gateway.routes[7].uri=lb://service-orders
#设置路由断言,代理servicerId为auth-service的/auth/路径
spring.cloud.gateway.routes[7].predicates= Path=/*/order/**

yml

        - id: service-orders
          uri: lb://service-orders
          predicates:
            - Path=/*/order/** # 路径匹配

(6)创建订单的Mapper、Service和Controller

//创建mapper
public interface OrderInfoMapper extends BaseMapper<OrderInfo> {

}


//创建service
public interface OrderInfoService extends IService<OrderInfo> {
    //保存订单
    Long submitOrder(String scheduleId, Long patientId);
}

//创建service实现类
@Service
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {

    @Override
    public Long submitOrder(String scheduleId, Long patientId) {
        return null;
    }
}

@Api(tags = "订单接口")
@RestController
@RequestMapping("/api/order/orderInfo")
public class OrderInfoController {

    @Autowired
    private OrderInfoService orderInfoService;

    @ApiOperation(value = "创建订单")
    @PostMapping("/{scheduleId}/{patientId}")
    public R submitOrder(
            @ApiParam(name = "scheduleId", value = "排班id", required = true)
            @PathVariable String scheduleId,
            @ApiParam(name = "patientId", value = "就诊人id", required = true)
            @PathVariable Long patientId) {

        Long orderId = orderInfoService.submitOrder(scheduleId, patientId);
        return R.ok().data("orderId",orderId);
    }

}

3、封装Feign调用获取就诊人接口

(1)在PatientController类添加方法
操作模块service_user

    @ApiOperation(value = "获取就诊人")
    @GetMapping("{id}")
    public Patient getPatientOrder(
            @ApiParam(name = "id", value = "就诊人id", required = true)
            @PathVariable("id") Long id) {
        return patientService.getById(id);
    }

(2)搭建service_user_client模块
(3)添加Feign接口类

在这里插入图片描述

@FeignClient(value = "service-user")
@Repository
public interface PatientFeignClient {
    //获取就诊人
    @GetMapping("/user/userinfo/patient/{id}")
    public Patient getPatientOrder(@PathVariable("id") Long id);
}

4、封装Feign调用获取排班下单信息接口

(1)在ScheduleService添加接口和实现
操作模块service_hosp

    //根据排班id获取预约下单数据实现
    @Override
    public ScheduleOrderVo getScheduleOrderVo(String scheduleId) {
        ScheduleOrderVo scheduleOrderVo = new ScheduleOrderVo();
        //排班信息
        Schedule schedule = scheduleRepository.findById(scheduleId).get();
        if(null == schedule) {
            throw new YyghException();
        }

        //获取预约规则信息
        Hospital hospital = hospitalService.getByHoscode(schedule.getHoscode());
        if(null == hospital) {
            throw new YyghException();
        }
        BookingRule bookingRule = hospital.getBookingRule();
        if(null == bookingRule) {
            throw new YyghException();
        }

        scheduleOrderVo.setHoscode(schedule.getHoscode());
        scheduleOrderVo.setHosname(hospital.getHosname());
        scheduleOrderVo.setDepcode(schedule.getDepcode());
        scheduleOrderVo.setDepname(departmentService.getDepartment(schedule.getHoscode(), schedule.getDepcode()).getDepname());
        scheduleOrderVo.setHosScheduleId(schedule.getHosScheduleId());
        scheduleOrderVo.setAvailableNumber(schedule.getAvailableNumber());
        scheduleOrderVo.setTitle(schedule.getTitle());
        scheduleOrderVo.setReserveDate(schedule.getWorkDate());
        scheduleOrderVo.setReserveTime(schedule.getWorkTime());
        scheduleOrderVo.setAmount(schedule.getAmount());

        //退号截止天数(如:就诊前一天为-1,当天为0)
        int quitDay = bookingRule.getQuitDay();
        DateTime quitTime = this.getDateTime(new DateTime(schedule.getWorkDate()).plusDays(quitDay).toDate(), bookingRule.getQuitTime());
        scheduleOrderVo.setQuitTime(quitTime.toDate());

        //预约开始时间
        DateTime startTime = this.getDateTime(new Date(), bookingRule.getReleaseTime());
        scheduleOrderVo.setStartTime(startTime.toDate());

        //预约截止时间
        DateTime endTime = this.getDateTime(new DateTime().plusDays(bookingRule.getCycle()).toDate(), bookingRule.getStopTime());
        scheduleOrderVo.setEndTime(endTime.toDate());

        //当天停止挂号时间
        DateTime stopTime = this.getDateTime(schedule.getWorkDate(), bookingRule.getStopTime());
        scheduleOrderVo.setStopTime(stopTime.toDate());
        return scheduleOrderVo;
    }

(3)搭建service_hosp_client
(4)添加Feign接口类
注意调用的时候两方都加上@PathVariable,以免之后报错

@FeignClient(value = "service-hosp")
@Repository
public interface HospitalFeignClient {

    @GetMapping("/user/hosp/schedule/{scheduleId}")
    public ScheduleOrderVo getScheduleOrderVo(@PathVariable("scheduleId") String scheduleId);
}

二、预约下单功能(二)

1、实现生成订单接口

(1)service_order引入依赖

<dependencies>
    <dependency>
        <groupId>com.donglin</groupId>
        <artifactId>service_cmn_client</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>

    <dependency>
        <groupId>com.donglin</groupId>
        <artifactId>service_hosp_client</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>

    <dependency>
        <groupId>com.donglin</groupId>
        <artifactId>service_user_client</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>
</dependencies>

(2)封装工具类
在这里插入图片描述
(3)实现生成订单

@Service
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {


    @Autowired
    private HospitalFeignClient hospitalFeignClient;
    @Autowired
    private PatientFeignClient patientFeignClient;
    @Autowired
    private RabbitService rabbitService;

    //生成订单
    @Override
    public Long submitOrder(String scheduleId, Long patientId) {
        //1 根据scheduleId获取排班数据
        ScheduleOrderVo scheduleOrderVo = hospitalFeignClient.getScheduleOrderVo(scheduleId);

        //2 根据patientId获取就诊人信息
        Patient patient = patientFeignClient.getPatientOrder(patientId);

        //3 平台里面 ==> 调用医院订单确认接口,
        // 3.1 如果医院返回失败,挂号失败
        //使用map集合封装需要传过医院数据
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("hoscode",scheduleOrderVo.getHoscode());
        paramMap.put("depcode",scheduleOrderVo.getDepcode());
        paramMap.put("hosScheduleId",scheduleOrderVo.getHosScheduleId());
        paramMap.put("reserveDate",new DateTime(scheduleOrderVo.getReserveDate()).toString("yyyy-MM-dd"));
        paramMap.put("reserveTime", scheduleOrderVo.getReserveTime());
        paramMap.put("amount",scheduleOrderVo.getAmount()); //挂号费用
        paramMap.put("name", patient.getName());
        paramMap.put("certificatesType",patient.getCertificatesType());
        paramMap.put("certificatesNo", patient.getCertificatesNo());
        paramMap.put("sex",patient.getSex());
        paramMap.put("birthdate", patient.getBirthdate());
        paramMap.put("phone",patient.getPhone());
        paramMap.put("isMarry", patient.getIsMarry());
        paramMap.put("provinceCode",patient.getProvinceCode());
        paramMap.put("cityCode", patient.getCityCode());
        paramMap.put("districtCode",patient.getDistrictCode());
        paramMap.put("address",patient.getAddress());
        //联系人
        paramMap.put("contactsName",patient.getContactsName());
        paramMap.put("contactsCertificatesType", patient.getContactsCertificatesType());
        paramMap.put("contactsCertificatesNo",patient.getContactsCertificatesNo());
        paramMap.put("contactsPhone",patient.getContactsPhone());
        paramMap.put("timestamp", HttpRequestHelper.getTimestamp());
        //String sign = HttpRequestHelper.getSign(paramMap, signInfoVo.getSignKey());
        paramMap.put("sign", "");

        //使用httpclient发送请求,请求医院接口
        JSONObject result =
                HttpRequestHelper.sendRequest(paramMap, "http://localhost:9998/order/submitOrder");
        //根据医院接口返回状态码判断  200 成功
        if(result.getInteger("code") == 200) { //挂号成功
            // 3.2 如果返回成功,得到返回其他数据
            JSONObject jsonObject = result.getJSONObject("data");
            //预约记录唯一标识(医院预约记录主键)
            String hosRecordId = jsonObject.getString("hosRecordId");
            //预约序号
            Integer number = jsonObject.getInteger("number");;
            //取号时间
            String fetchTime = jsonObject.getString("fetchTime");;
            //取号地址
            String fetchAddress = jsonObject.getString("fetchAddress");;

            //4 如果医院接口返回成功,添加上面三部分数据到数据库
            OrderInfo orderInfo = new OrderInfo();
            //设置添加数据--排班数据
            BeanUtils.copyProperties(scheduleOrderVo, orderInfo);
            //设置添加数据--就诊人数据
            //订单号
            String outTradeNo = System.currentTimeMillis() + ""+ new Random().nextInt(100);
            orderInfo.setOutTradeNo(outTradeNo);
            orderInfo.setScheduleId(scheduleOrderVo.getHosScheduleId());
            orderInfo.setUserId(patient.getUserId());
            orderInfo.setPatientId(patientId);
            orderInfo.setPatientName(patient.getName());
            orderInfo.setPatientPhone(patient.getPhone());
            orderInfo.setOrderStatus(OrderStatusEnum.UNPAID.getStatus());

            //设置添加数据--医院接口返回数据
            orderInfo.setHosRecordId(hosRecordId);
            orderInfo.setNumber(number);
            orderInfo.setFetchTime(fetchTime);
            orderInfo.setFetchAddress(fetchAddress);

            //调用方法添加
            baseMapper.insert(orderInfo);

            //TODO 5 根据医院返回数据,更新排班数量
            //排班可预约数
            Integer reservedNumber = jsonObject.getInteger("reservedNumber");
            //排班剩余预约数
            Integer availableNumber = jsonObject.getInteger("availableNumber");

            //TODO 6 给就诊人发送短信

            //7.返回订单的id
            return orderInfo.getId();
        } else {
            throw new YyghException(20001, "号源已满");
        }
    }

}

三、预约下单功能(三)

1、生成订单前端整合
(1)封装api方法
创建api/order.js

import request from '@/utils/request'

const api_name = `/api/order/orderInfo`

export default {
 submitOrder(scheduleId, patientId) {
  return request({
    url: `${api_name}/${scheduleId}/${patientId}`,
    method: 'post'
  })
 }
}

(2)在booking.vue组件完善下单方法

import orderInfoApi from '@/api/order'

submitOrder() {
    if(this.patient.id == null) {
        this.$message.error('请选择就诊人')
        return
    }
    // 防止重复提交
    if(this.submitBnt == '正在提交...') {
        this.$message.error('重复提交')
        return
    }

    this.submitBnt = '正在提交...'
    orderInfoApi.submitOrder(this.scheduleId, this.patient.id).then(response => {
        let orderId = response.data.orderId
        window.location.href = '/order/show?orderId=' + orderId
    }).catch(e => {
        this.submitBnt = '确认挂号'
    })
},

2、生成订单后处理逻辑-更新订单信息
预约成功后我们要 更新订单信息,更新预约数 和 短信提醒预约成功,为了提高下单的并发性,这部分逻辑我们就交给mq为我们完成,预约成功发送消息即可
(1)修改OrderServiceImpl方法

//生成预约挂号订单
@Override
public Long submitOrder(String scheduleId, Long patientId) {
    
    ...............
        
            //TODO 5 根据医院返回数据,更新排班数量
            //排班可预约数
            Integer reservedNumber = jsonObject.getInteger("reservedNumber");
            //排班剩余预约数
            Integer availableNumber = jsonObject.getInteger("availableNumber");
            //发送mq信息更新号源和短信通知
            OrderMqVo orderMqVo = new OrderMqVo();
            orderMqVo.setScheduleId(scheduleId);
            orderMqVo.setReservedNumber(reservedNumber);
            orderMqVo.setAvailableNumber(availableNumber);

            //TODO 6 给就诊人发送短信
            //短信提示
            SmsVo msmVo = new SmsVo();
            msmVo.setPhone(orderInfo.getPatientPhone());
            String reserveDate =
                    new DateTime(orderInfo.getReserveDate()).toString("yyyy-MM-dd")
                            + (orderInfo.getReserveTime()==0 ? "上午": "下午");
            Map<String,Object> param = new HashMap<String,Object>(){{
                put("title", orderInfo.getHosname()+"|"+orderInfo.getDepname()+"|"+orderInfo.getTitle());
                put("amount", orderInfo.getAmount());
                put("reserveDate", reserveDate);
                put("name", orderInfo.getPatientName());
                put("quitTime", new DateTime(orderInfo.getQuitTime()).toString("yyyy-MM-dd HH:mm"));
            }};
            msmVo.setParam(param);

            orderMqVo.setSmsVo(msmVo);
            rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_ORDER, MqConst.ROUTING_ORDER, orderMqVo);
            //返回订单号
            return orderInfo.getId();

3、生成订单后处理逻辑-rabbit-util模块封装
(1)rabbitMQ简介
以商品订单场景为例,
如果商品服务和订单服务是两个不同的微服务,在下单的过程中订单服务需要调用商品服务进行扣库存操作。按照传统的方式,下单过程要等到调用完毕之后才能返回下单成功,如果网络产生波动等原因使得商品服务扣库存延迟或者失败,会带来较差的用户体验,如果在高并发的场景下,这样的处理显然是不合适的,那怎么进行优化呢?这就需要消息队列登场了。
消息队列提供一个异步通信机制,消息的发送者不必一直等待到消息被成功处理才返回,而是立即返回。消息中间件负责处理网络通信,如果网络连接不可用,消息被暂存于队列当中,当网络畅通的时候在将消息转发给相应的应用程序或者服务,当然前提是这些服务订阅了该队列。如果在商品服务和订单服务之间使用消息中间件,既可以提高并发量,又降低服务之间的耦合度。
RabbitMQ就是这样一款消息队列。RabbitMQ是一个开源的消息代理的队列服务器,用来通过普通协议在完全不同的应用之间共享数据。
典型应用场景:
异步处理。把消息放入消息中间件中,等到需要的时候再去处理。
流量削峰。例如秒杀活动,在短时间内访问量急剧增加,使用消息队列,当消息队列满了就拒绝响应,跳转到错误页面,这样就可以使得系统不会因为超负载而崩溃
(2)安装rabbitMQ

#拉取镜像
docker pull rabbitmq:3.8-management

#创建容器启动
docker run -d --restart=always -p 5672:5672 -p 15672:15672 --name rabbitmq rabbitmq:3.8-management

(3)服务rabbitMQ后台

管理后台:http://IP:15672
在这里插入图片描述
在这里插入图片描述
(4)在common搭建rabbit_util模块
在这里插入图片描述
(4)在rabbit_util引入依赖

<dependencies>
    <!--rabbitmq消息队列-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-bus-amqp</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
    </dependency>
</dependencies>

(5)添加service方法

@Component
public class RabbitService {
   @Autowired
    private RabbitTemplate rabbitTemplate;

   //rabbirmq: String.getBytes()

    //{
    //  key:value1,

    // }
   public boolean sendMessage(String exchange,String routingkey,Object message){
       rabbitTemplate.convertAndSend(exchange,routingkey,message);
       return true;
   }
}

(6)配置mq消息转换器

@SpringBootConfiguration
public class RabbitConfig {

    //作用:就是将发送到RabbitMQ中的pojo对象自动就行转换为json格式存储
      //   从rabbitmq中消费消息时,自动把json格式的字符串转换为pojo对象

    @Bean
    public MessageConverter getMessageConverter(){
        return new Jackson2JsonMessageConverter();
    }
}

说明:默认是字符串转换器
(7)添加常量类

public class MqConst {
    /**
     * 预约下单
     */
    public static final String EXCHANGE_DIRECT_ORDER = "exchange.direct.order";
    public static final String ROUTING_ORDER = "order";
    //队列
    public static final String QUEUE_ORDER  = "queue.order";
    
    /**
     * 短信
     */
    public static final String EXCHANGE_DIRECT_SMS = "exchange.direct.msm";
    public static final String ROUTING_SMS_ITEM = "msm.item";
    //队列
    public static final String QUEUE_MSM_SMS  = "queue.msm.item";
}

四、预约下单功能(四)

1、生成订单后处理逻辑-封装短信接口

操作service_sms模块
(1)service_sms引入依赖

<dependency>
    <groupId>com.donglin</groupId>
    <artifactId>rabbit_util</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

(2)service_sms添加配置

#rabbitmq地址
spring.rabbitmq.host=192.168.121.140
spring.rabbitmq.port=5672
spring.rabbitmq.virtual-host=/
spring.rabbitmq.username=admin
spring.rabbitmq.password=admin

(3)在model模块封装短信实体

@Data
@ApiModel(description = "短信实体")
public class SmsVo {

    @ApiModelProperty(value = "phone")
    private String phone;

    @ApiModelProperty(value = "短信模板code")
    private String templateCode;

    @ApiModelProperty(value = "短信模板参数")
    private Map<String,Object> param;
}

(4)service_sms封装service接口和实现

    //发送短信接口
    boolean sendMessage(SmsVo smsVo);

    //发送短信实现
    @Override
    public boolean sendMessage(SmsVo smsVo) {
        if (!StringUtils.isEmpty(smsVo.getPhone())) {
            //给就诊人短信提醒
            System.out.println("给就诊人短信提醒");
            //仅为了测试
            return this.sendCode(smsVo.getPhone());
        }
        return false;
    }

(5)封装mq监听器

@Component
public class SmsListener {

    @Autowired
    private SmsService smsService;

    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue(name = MqConst.QUEUE_MSM_SMS),
                    exchange = @Exchange(name = MqConst.EXCHANGE_DIRECT_SMS),
                    key = MqConst.ROUTING_SMS_ITEM
            )
    })
    public void consume(SmsVo msmVo, Message message, Channel channel){
        smsService.sendMessage(msmVo);
    }
}

2、生成订单后处理逻辑-更新排班数量

操作模块:service_hosp
(1)service_hosp引入依赖

<!--rabbitmq消息队列-->
<dependency>
    <groupId>com.donglin</groupId>
    <artifactId>rabbit_util</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

(2)添加配置

rabbitmq地址
spring.rabbitmq.host=192.168.121.140
spring.rabbitmq.port=5672
spring.rabbitmq.virtual-host=/
spring.rabbitmq.username=admin
spring.rabbitmq.password=admin

(3)在model模块封装更新排班实体

@Data
@ApiModel(description = "OrderMqVo")
public class OrderMqVo {

	@ApiModelProperty(value = "可预约数")
	private Integer reservedNumber;

	@ApiModelProperty(value = "剩余预约数")
	private Integer availableNumber;

	@ApiModelProperty(value = "排班id")
	private String scheduleId;

	@ApiModelProperty(value = "短信实体")
	private SmsVo smsVo;

}

(4)封装更新排班方法
操作ScheduleService


     boolean updateAvailableNumber(String scheduleId, Integer availableNumber);

    @Override
    public boolean updateAvailableNumber(String scheduleId, Integer availableNumber) {
        Schedule schedule = scheduleRepository.findById(scheduleId).get();
        schedule.setAvailableNumber(availableNumber);
        schedule.setUpdateTime(new Date());
        scheduleRepository.save(schedule);
        return true;
    }

(5)封装mq监听器

@Component
public class OrderMqListener {

    @Autowired
    private ScheduleService scheduleService;
    @Autowired
    private RabbitService rabbitService;

    @RabbitListener(bindings = {
            @QueueBinding(
                    value =@Queue(name = MqConst.QUEUE_ORDER,durable = "true"),//创建队列
                    exchange = @Exchange(name = MqConst.EXCHANGE_DIRECT_ORDER), //创建交换机
                    key=MqConst.ROUTING_ORDER
            )
    })
    public void consume(OrderMqVo orderMqVo, Message message, Channel channel){
        String scheduleId = orderMqVo.getScheduleId();
        Integer availableNumber = orderMqVo.getAvailableNumber();
        boolean flag= scheduleService.updateAvailableNumber(scheduleId,availableNumber);

        SmsVo msmVo = orderMqVo.getSmsVo();

        if(flag && msmVo != null){
            rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_SMS,MqConst.ROUTING_SMS_ITEM,msmVo);
        }

    }
}

3、生成订单后处理逻辑-完善订单接口

操作service_order
(1)引入依赖

<dependency>
    <groupId>com.donglin</groupId>
    <artifactId>rabbit_util</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

(2)添加配置

#rabbitmq地址
spring.rabbitmq.host=192.168.121.140
spring.rabbitmq.port=5672
spring.rabbitmq.virtual-host=/
spring.rabbitmq.username=admin
spring.rabbitmq.password=admin

(3)修改OrderServiceImpl类下单方法

@Autowired
private RabbitService rabbitService;

//生成预约挂号订单
@Override
public Long submitOrder(String scheduleId, Long patientId) {
    
   .....................................
       
            //TODO 5 根据医院返回数据,更新排班数量
            //排班可预约数
            Integer reservedNumber = jsonObject.getInteger("reservedNumber");
            //排班剩余预约数
            Integer availableNumber = jsonObject.getInteger("availableNumber");


            //TODO 6 给就诊人发送短信
            //发送mq信息更新号源和短信通知
            OrderMqVo orderMqVo = new OrderMqVo();
            orderMqVo.setScheduleId(scheduleId);
            orderMqVo.setReservedNumber(reservedNumber);
            orderMqVo.setAvailableNumber(availableNumber);

            //短信提示
            SmsVo smsVo = new SmsVo();
            smsVo.setPhone(orderInfo.getPatientPhone());
            String reserveDate =
                    new DateTime(orderInfo.getReserveDate()).toString("yyyy-MM-dd")
                            + (orderInfo.getReserveTime()==0 ? "上午": "下午");
            Map<String,Object> param = new HashMap<String,Object>(){{
                put("title", orderInfo.getHosname()+"|"+orderInfo.getDepname()+"|"+orderInfo.getTitle());
                put("amount", orderInfo.getAmount());
                put("reserveDate", reserveDate);
                put("name", orderInfo.getPatientName());
                put("quitTime", new DateTime(orderInfo.getQuitTime()).toString("yyyy-MM-dd HH:mm"));
            }};
            smsVo.setParam(param);

            orderMqVo.setSmsVo(smsVo);
            rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_ORDER, MqConst.ROUTING_ORDER, orderMqVo);
            //7 返回订单号
            return orderInfo.getId();
        } else { //挂号失败
            throw new YyghException(20001, "挂号失败");
        }

五、订单列表功能

在这里插入图片描述
在这里插入图片描述

1、订单列表接口

(1)创建service接口和实现
OrderInfoService接口和实现类

     /**
     * 分页列表
     */
    Page<OrderInfo> getOrderInfoPage(Integer pageNum, Integer pageSize, OrderQueryVo orderQueryVo);

    //实现列表
    //(条件查询带分页)
    @Override
    public Page<OrderInfo> getOrderInfoPage(Integer pageNum, Integer pageSize, OrderQueryVo orderQueryVo) {
        Page page=new Page(pageNum,pageSize);
        QueryWrapper<OrderInfo> queryWrapper=new QueryWrapper<OrderInfo>();

        Long userId = orderQueryVo.getUserId(); //用户id
        String outTradeNo = orderQueryVo.getOutTradeNo();//订单号
        String keyword = orderQueryVo.getKeyword();//医院名称
        Long patientId = orderQueryVo.getPatientId(); //就诊人id
        String orderStatus = orderQueryVo.getOrderStatus();//订单状态
        String reserveDate = orderQueryVo.getReserveDate(); //预约日期
        String createTimeBegin = orderQueryVo.getCreateTimeBegin();//下订单时间
        String createTimeEnd = orderQueryVo.getCreateTimeEnd();//下订单时间

        if(!StringUtils.isEmpty(userId)){
            queryWrapper.eq("user_id", userId);
        }
        if(!StringUtils.isEmpty(outTradeNo)){
            queryWrapper.eq("out_trade_no", outTradeNo);
        }
        if(!StringUtils.isEmpty(keyword)){
            queryWrapper.like("hosname", keyword);
        }
        if(!StringUtils.isEmpty(patientId)){
            queryWrapper.eq("patient_id", patientId);
        }
        if(!StringUtils.isEmpty(orderStatus)){
            queryWrapper.eq("order_status", orderStatus);
        }
        if(!StringUtils.isEmpty(reserveDate)){
            queryWrapper.ge("reserve_date", reserveDate);
        }
        if(!StringUtils.isEmpty(createTimeBegin)){
            queryWrapper.ge("create_time", createTimeBegin);
        }
        if(!StringUtils.isEmpty(createTimeEnd)){
            queryWrapper.le("create_time", createTimeEnd);
        }
        Page<OrderInfo> page1 = baseMapper.selectPage(page, queryWrapper);
        page1.getRecords().parallelStream().forEach(item->{
            this.packageOrderInfo(item);
        });

        return page1;
    }

    private void packageOrderInfo(OrderInfo item) {
        item.getParam().put("orderStatusString",OrderStatusEnum.getStatusNameByStatus(item.getOrderStatus()));
    }

(2)创建controller
在OrderInfoController类添加方法

    @GetMapping("/list")
    public R getOrderList(){
        List<Map<String, Object>> statusList = OrderStatusEnum.getStatusList();
        return R.ok().data("list",statusList);
    }


    @GetMapping("/{pageNum}/{pageSize}")
    public R getOrderInfoPage(@PathVariable Integer pageNum,
                              @PathVariable Integer pageSize,
                              OrderQueryVo orderQueryVo,
                              @RequestHeader String token){

        Long userId = JwtHelper.getUserId(token);
        orderQueryVo.setUserId(userId);
        Page<OrderInfo>  page= orderInfoService.getOrderInfoPage(pageNum,pageSize,orderQueryVo);
        return R.ok().data("page",page);
    }

2、订单列表前端

(1)封装api请求
在api/order.js定义方法

 //订单列表
 getPageList(pageNum, pageSize, searchObj) {
    return request({
        url: `${api_name}/${pageNum}/${pageSize}`,
        method: `get`,
        params: searchObj
    })
},
//订单状态
 getStatusList() {
    return request({
         url: `${api_name}/list`,
         method: 'get'
    })
 },

(2)页面显示
创建/pages/order/index.vue组件

<template>
    <!-- header -->
    <div class="nav-container page-component">
      <!--左侧导航 #start -->
      <div class="nav left-nav">
        <div class="nav-item ">
          <span class="v-link clickable dark" onclick="javascript:window.location='/user'">实名认证 </span>
        </div>
        <div class="nav-item selected">
          <span class="v-link selected dark" onclick="javascript:window.location='/order'"> 挂号订单 </span>
        </div>
        <div class="nav-item ">
          <span class="v-link clickable dark" onclick="javascript:window.location='/patient'"> 就诊人管理 </span>
        </div>
        <div class="nav-item ">
          <span class="v-link clickable dark"> 修改账号信息 </span>
        </div>
        <div class="nav-item ">
          <span class="v-link clickable dark"> 意见反馈 </span>
        </div>
      </div>
      <!-- 左侧导航 #end -->
      <!-- 右侧内容 #start -->
      <div class="page-container">
        <div class="personal-order">
          <div class="title"> 挂号订单</div>
          <el-form :inline="true">
            <el-form-item label="就诊人:">
              <el-select v-model="searchObj.patientId" placeholder="请选择就诊人" class="v-select patient-select">
                <el-option
                  v-for="item in patientList"
                  :key="item.id"
                  :label="item.name + '【' + item.certificatesNo + '】'"
                  :value="item.id">
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="订单状态:" style="margin-left: 80px">
              <el-select v-model="searchObj.orderStatus" placeholder="全部" class="v-select patient-select" style="width: 200px;">
                <el-option
                  v-for="item in statusList"
                  :key="item.status"
                  :label="item.comment"
                  :value="item.status">
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item>
              <el-button type="text" class="search-button v-link highlight clickable selected" @click="fetchData()">
                查询
              </el-button>
            </el-form-item>
          </el-form>
          <div class="table-wrapper table">
            <el-table
              :data="list"
              stripe
              style="width: 100%">
              <el-table-column
                label="就诊时间"
                width="120">
                <template slot-scope="scope">
                  {{ scope.row.reserveDate }} {{ scope.row.reserveTime === 0 ? '上午' : '下午' }}
                </template>
              </el-table-column>
              <el-table-column
                prop="hosname"
                label="医院"
                width="100">
              </el-table-column>
              <el-table-column
                prop="depname"
                label="科室">
              </el-table-column>
              <el-table-column
                prop="title"
                label="医生">
              </el-table-column>
              <el-table-column
                prop="amount"
                label="医事服务费">
              </el-table-column>
              <el-table-column
                prop="patientName"
                label="就诊人">
              </el-table-column>
              <el-table-column
                prop="param.orderStatusString"
                label="订单状态">
              </el-table-column>
              <el-table-column label="操作">
                <template slot-scope="scope">
                  <el-button type="text" class="v-link highlight clickable selected" @click="show(scope.row.id)">详情</el-button>
                </template>
              </el-table-column>
            </el-table>
          </div>
          <!-- 分页 -->
          <el-pagination
            class="pagination"
            layout="prev, pager, next"
            :current-page="page"
            :total="total"
            :page-size="limit"
            @current-change="fetchData">
          </el-pagination>
        </div>
      </div>
      <!-- 右侧内容 #end -->
    </div>
    <!-- footer -->
  </template>
  <script>
  import '~/assets/css/hospital_personal.css'
  import '~/assets/css/hospital.css'
  import orderInfoApi from '@/api/order'
  import patientApi from '@/api/patient'
  export default {
    data() {
      return {
        list: [], // banner列表
        total: 0, // 数据库中的总记录数
        page: 1, // 默认页码
        limit: 10, // 每页记录数
        searchObj: {}, // 查询表单对象
        patientList: [],
        statusList: []
      }
    },
    created() {
      this.orderId = this.$route.query.orderId
      this.fetchData()
      this.findPatientList()
      this.getStatusList()
    },
    methods: {
      fetchData(page = 1) {
        this.page = page
        orderInfoApi.getPageList(this.page, this.limit, this.searchObj).then(response => {
          console.log(response.data);
          this.list = response.data.page.records
          this.total = response.data.page.total
        })
      },
      findPatientList() {
        patientApi.findList().then(response => {
          this.patientList = response.data.list
          console.log(this.patientList);
        })
      },
      getStatusList() {
        orderInfoApi.getStatusList().then(response => {
          this.statusList = response.data.list
          console.log(this.statusList);
        })
      },
      changeSize(size) {
        console.log(size)
        this.limit = size
        this.fetchData(1)
      },
      show(id) {
        window.location.href = '/order/show?orderId=' + id
      }
    }
  }
  </script>

六、订单详情功能

在这里插入图片描述

1、订单详情接口
(1)OrderInfoService添加方法

/**
     * 获取订单详情
     */
    OrderInfo detail(Long orderId);

    //实现方法
    @Override
    public OrderInfo detail(Long orderId) {
        OrderInfo orderInfo = baseMapper.selectById(orderId);
        this.packageOrderInfo(orderInfo);
        return orderInfo;
    }

(2)OrderApiCont添加方法
在OrderInfoController类添加方法

    //根据订单id查询订单详情
    @GetMapping("/{orderId}")
    public R detail(@PathVariable Long orderId){
        OrderInfo orderInfo = orderInfoService.detail(orderId);
        return R.ok().data("orderInfo",orderInfo);
    }

2、订单详情前端
(1)封装api方法
在order.js添加方法定义

//订单详情
getOrders(orderId) {
    return request({
        url: `${api_name}/${orderId}`,
        method: `get`
    })
},

(2)添加页面
创建/pages/order/show.vue组件

<template>
    <!-- header -->
    <div class="nav-container page-component">
      <!--左侧导航 #start -->
      <div class="nav left-nav">
        <div class="nav-item ">
          <span class="v-link clickable dark" onclick="javascript:window.location='/user'">实名认证 </span>
        </div>
        <div class="nav-item selected">
          <span class="v-link selected dark" onclick="javascript:window.location='/order'"> 挂号订单 </span>
        </div>
        <div class="nav-item ">
          <span class="v-link clickable dark" onclick="javascript:window.location='/patient'"> 就诊人管理 </span>
        </div>
        <div class="nav-item ">
          <span class="v-link clickable dark"> 修改账号信息 </span>
        </div>
        <div class="nav-item ">
          <span class="v-link clickable dark"> 意见反馈 </span>
        </div>
      </div>
      <!-- 左侧导航 #end -->
      <!-- 右侧内容 #start -->
      <div class="page-container">
        <div class="order-detail">
          <div class="title"> 挂号详情</div>
          <div class="status-bar">
            <div class="left-wrapper">
              <div class="status-wrapper BOOKING_SUCCESS">
                <span class="iconfont"></span> {{ orderInfo.param.orderStatusString }}
              </div>
            </div>
            <div class="right-wrapper">
              <img src="//img.114yygh.com/static/web/code_order_detail.png" class="code-img">
              <div class="content-wrapper">
                <div> 微信<span class="iconfont"></span>关注“北京114预约挂号”</div>
                <div class="watch-wrapper"> 快速挂号,轻松就医</div>
              </div>
            </div>
          </div>
          <div class="info-wrapper">
            <div class="title-wrapper">
              <div class="block"></div>
              <div>挂号信息</div>
            </div>
            <div class="info-form">
              <el-form ref="form" :model="form">
                <el-form-item label="就诊人信息:">
                  <div class="content"><span>{{ orderInfo.patientName }}</span></div>
                </el-form-item>
                <el-form-item label="就诊日期:">
                  <div class="content"><span>{{ orderInfo.reserveDate }} {{ orderInfo.reserveTime == 0 ? '上午' : '下午' }}</span></div>
                </el-form-item>
                <el-form-item label="就诊医院:">
                  <div class="content"><span>{{ orderInfo.hosname }} </span></div>
                </el-form-item>
                <el-form-item label="就诊科室:">
                  <div class="content"><span>{{ orderInfo.depname }} </span></div>
                </el-form-item>
                <el-form-item label="医生职称:">
                  <div class="content"><span>{{ orderInfo.title }} </span></div>
                </el-form-item>
                <el-form-item label="医事服务费:">
                  <div class="content">
                    <div class="fee">{{ orderInfo.amount }}</div>
                  </div>
                </el-form-item>
                <el-form-item label="挂号单号:">
                  <div class="content"><span>{{ orderInfo.outTradeNo }} </span></div>
                </el-form-item>
                <el-form-item label="挂号时间:">
                  <div class="content"><span>{{ orderInfo.createTime }}</span></div>
                </el-form-item>
              </el-form>
            </div>
          </div>
          <div class="rule-wrapper mt40">
            <div class="rule-title"> 注意事项</div>
            <div>1、请确认就诊人信息是否准确,若填写错误将无法取号就诊,损失由本人承担;<br>
              <span style="color:red">2、【取号】就诊当天需在{{ orderInfo.fetchTime }}在医院取号,未取号视为爽约,该号不退不换;</span><br>
              3、【退号】在{{ orderInfo.quitTime }}前可在线退号 ,逾期将不可办理退号退费;<br>
              4、北京114预约挂号支持自费患者使用身份证预约,同时支持北京市医保患者使用北京社保卡在平台预约挂号。请于就诊当日,携带预约挂号所使用的有效身份证件到院取号;<br>
              5、请注意北京市医保患者在住院期间不能使用社保卡在门诊取号。
            </div>
          </div>
          <div class="bottom-wrapper mt60" v-if="orderInfo.orderStatus == 0 || orderInfo.orderStatus == 1">
            <div class="button-wrapper">
              <div class="v-button white" @click="cancelOrder()">取消预约</div>
            </div>
            <div class="button-wrapper ml20" v-if="orderInfo.orderStatus == 0">
              <div class="v-button" @click="pay()">支付</div>
            </div>
          </div>
        </div>
      </div>
      <!-- 右侧内容 #end -->
      <!-- 微信支付弹出框 -->
      <el-dialog :visible.sync="dialogPayVisible" style="text-align: left" :append-to-body="true" width="500px" @close="closeDialog">
        <div class="container">
          <div class="operate-view" style="height: 350px;">
            <div class="wrapper wechat">
              <div>
                <img src="images/weixin.jpg" alt="">
                
                <div style="text-align: center;line-height: 25px;margin-bottom: 40px;">
                  请使用微信扫一扫<br/>
                  扫描二维码支付
                </div>
              </div>
            </div>
          </div>
        </div>
      </el-dialog>
    </div>
    <!-- footer -->
  </template>
  <script>
  import '~/assets/css/hospital_personal.css'
  import '~/assets/css/hospital.css'
  import orderInfoApi from '@/api/order'
  export default {
    data() {
      return {
        orderId: null,
        orderInfo: {
          param: {}
        },
        dialogPayVisible: false,
        payObj: {},
        timer: null  // 定时器名称
      }
    },
    created() {
      this.orderId = this.$route.query.orderId
      this.init()
    },
    methods: {
      init() {
        orderInfoApi.getOrders(this.orderId).then(response => {
          console.log(response.data);
          this.orderInfo = response.data.orderInfo
        })
      }
    }
  }
  </script>
  <style>
    .info-wrapper {
      padding-left: 0;
      padding-top: 0;
    }
    .content-wrapper {
      color: #333;
      font-size: 14px;
      padding-bottom: 0;
    }
    .bottom-wrapper {
      width: 100%;
    }
    .button-wrapper {
      margin: 0;
    }
    .el-form-item {
      margin-bottom: 5px;
    }
    .bottom-wrapper .button-wrapper {
      margin-top: 0;
    }
  </style>

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

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

相关文章

cracklib与libpwquality 评估密码的安全性

一、cracklib 检测密码强弱linux中采用pam pam_cracklib module来实现对密码强度的检测&#xff0c;可以通过配置让linux系统自动检测用户的密码是否为弱密码。yuminstall cracklib # centos apt-get install libcrack2 # ubuntu # 如果需要依赖此库做开发的话需要安装这个 y…

墨者——内部文件上传系统漏洞分析溯源 内部文件上传系统漏洞分析溯源

墨者——内部文件上传系统漏洞分析溯源 内部文件上传系统漏洞分析溯源 1.选择合适的文件上传 2.可以看到为*.asp文件 3.可以推测出此站点为IIS 4.上传shell.asp试试 5.上传报错&#xff0c;将其改名为shell.asp.txt上传&#xff0c;发现上传成功 6.有个问题就是服务器将我们所…

Node 10.0.8.6:9003 is unknown to cluster

解决方案解决方案一解决方案一 ① 概念介绍 公网ip&#xff1a;就是任意两台连接了互联网的电脑可以互相ping ip,能够通的ip 内网ip&#xff1a;只是在内网中使用无法与外网连接的ip ②问题背景 在腾讯云上搭建的一个redis集群&#xff0c;集群启动后 可以看到启动节点…

腾讯企微、泛微、契约锁举办的这场大会,超1000人共商数字化转型

全程数字化运营平台体验大会 2月23日下午&#xff0c;腾讯企业微信、泛微、契约锁在上海联合举办了全程数字化运营平台体验大会&#xff0c;旨在推动政企客户的数字化转型。 活动以“智能、协同、高效”为主题&#xff0c;吸引了上千位政府及企事单位的信息化负责人参与。 在…

Tapdata 和 Databend 数仓数据同步实战

作者&#xff1a;韩山杰https://github.com/hantmacDatabend Cloud 研发工程师基础架构在云计算时代也发生着翻天地覆的变化&#xff0c;对于业务的支持变成了如何能利用好云资源实现降本增效&#xff0c;同时更好的支撑业务也成为新时代技术人员的挑战。 本篇文章通过&#xf…

含泪推荐5款小体积,超实用的工具

大家好&#xff0c;我又来啦&#xff0c;今天给大家带来的5款软件&#xff0c;共同特点都是体积小、无广告、超实用&#xff0c;大家观看完可以自行搜索下载哦。 1.文字自动验证工具——LanguageTool LanguageTool是一款文字自动验证工具&#xff0c;不仅支持中英文&#xff…

如何将虚拟机ubuntu设置网路连接为桥接模式

当将虚拟机的网络适配器设置为NAT模式时&#xff0c;一切正常&#xff0c;可以ping通所有ip, 但是当设置为桥接模式时&#xff0c;ping命令会提示ubuntu connect: Network is unreachable 这是因为桥接模式没有设置正确&#xff0c;通过下面的步骤可以将桥接模式配置正确。 1…

iOS 生命周期 (最新最完整)

要知道APP的生命周期&#xff0c;首先要了解一下生命周期的5种状态&#xff0c;结合状态理解生命周期的使用。 一、应用的状态 应用的状态包括&#xff1a; 1.1 未运行&#xff08;Not running&#xff09; 程序没启动 1.2 未激活&#xff08;Inactive&#xff09; 程序在…

尚医通 (二十一)预约挂号功能

目录一、预约挂号详情1、需求2、预约挂号详情接口3、预约挂号详情前端二、预约确认1、需求2、预约确认接口3、预约确认前端一、预约挂号详情 1、需求 接口分析 &#xff08;1&#xff09;根据预约周期&#xff0c;展示可预约日期数据&#xff0c;按分页展示 &#xff08;2&…

JAVA设计模式之工厂模式讲解

目录 前言 开始表演 前言 Java中使用工厂模式的主要原因是为了实现代码的灵活性和可维护性。工厂模式是一种创建型设计模式&#xff0c;它提供了一种将对象的创建和使用进行分离的方式。具体来说&#xff0c;工厂模式可以将对象的创建过程封装在一个独立的工厂类中&#xff…

自动微分记录

计算图(数据流图):AI系统化问题 - 计算图的提出 计算图和自动微分 单算子切分、图的切分和调度 前端->统一表示->优化层->运行时态->底层库 语言 计算网络模型中间表示 计算图 自动微分 计算图优化 内存管理、计算图调度和执行 内核代码优化与编译 多硬件支持…

ip-guard如何在控制台上判断策略是否下发成功?

方法1.看控制台策略设置是否带*号,一般带*,然后刷新控制台依旧带*,说明策略没下发。可以点击刷新按钮进行刷新。 方法2.运行cmd,将控制台程序拖入命令行中,加参数-ad,回车运行。 然后,选中指定客户端,在维护-命令行,输入policy,

骨传导耳机是怎么发声的,骨传导耳机值得入手嘛

现在市面上除了我们平时比较常见的有线耳机、头戴耳机、真无线耳机&#xff0c;近两年还涌现出了一种有着黑科技之称的特别耳机——骨传导耳机&#xff0c;并且因其在运动场景下的优势过于明显而得到了众多运动爱好者的大力追捧。那么今天我们就来聊聊这款所谓的黑科技骨传导耳…

webform如何升级mvc

1.创建项目 给项目起名字然后指定存储位置 选择asp.net 空项目 2.新建model namespace WebFormToMvc {/// <summary>/// 用户模型/// </summary>public class UserModel{/// <summary>/// id/// </summary>public int Id { get; set; }/// <sum…

解决Chrome浏览器内置翻译无法使用的问题

hosts文件 hosts是一个没有扩展名的系统文件&#xff0c;可以用记事本等工具打开&#xff0c;主要作用是定义IP地址和主机名的映射关系&#xff0c;是一个映射IP地址和主机名的规定。当用户在浏览器中输入一个需要登录的网址时&#xff0c;系统会首先自动从hosts文件中寻找对应…

上海亚商投顾:沪指收跌0.62% 东数西算板块逆势领涨

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。市场情绪三大指数今日震荡调整&#xff0c;盘中集体跌超1%&#xff0c;随后沪指跌幅有所收窄。东数西算概念午后走强&#xf…

【FLASH存储器系列二十一】如何评估固态硬盘的性能?

我们以三星消费级SSD 990 PRO为例进行介绍&#xff0c;下图为其产品配置&#xff1a; 简单说明一下产品配置&#xff1a;990 pro容量有1T和2T两种规格&#xff0c;固态硬盘容量计算一般是1T1000GB1000000MB&#xff0c;与操作系统容量计算1T1024GB不一样&#xff0c;使用M.2外形…

Editor工具开发基础三:自定义组件菜单拓展 CustomEditor

一.创建脚本路径 创建脚本路径不再限制 一般写在自定义组件类的下边二.特性CustomEditor 定义主设计图面由自定义代码实现数组的编辑器。两个构造函数1.public CustomEditor(Type inspectedType);2.public CustomEditor(Type inspectedType, bool editorForChildClasses);参数意…

[架构之路-118]-《软考-系统架构设计师》-软架构设计-11-可靠性相关设计

第11节 可靠性相关设计11.1 可靠性基本概念可靠性工程是研究产品生命周期中故障的发生、发展规律&#xff0c;达到预防故障&#xff0c;消灭故障&#xff0c;提高产品可用性的工程技术。信息系统的可靠性是指系统在满足一定条件的应用环境中能够正常工作的能力&#xff0c;可以…

如何理解「数据驱动业务」?

“数据驱动”描述了一种业务状态&#xff0c;在这种状态中&#xff0c;数据被用于实时有效地推动决策和其他相关活动。对于企业来说&#xff0c;达到数据驱动的状态就像是开车和骑马旅行的区别。数据驱动的业务能够更快、更高效地达到目标。 数据驱动特征包括质量良好的数据整…