16 medical registration system_ [order by appointment]

1, Make an appointment to place an order

requirement analysis

Order table structure

Order analysis

Refer to business interface 5.1 of Shang Yi Tong API interface document.docx to make an appointment and place an order

Order parameters: visiting person id and shift id

  1. We need to get the information of the patient when placing an order
  2. Get shift scheduling and order information and rule information
  3. Get the signature information of the hospital, and then go to the hospital to make an appointment and place an order through the interface
  4. Order successfully, update the scheduling information and send SMS

2. Build the service order module

2.1 build the service order module

Refer to the service user module for the construction process

2.2 modify configuration

1. Modify pom XML, introducing dependencies

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

2. Add configuration file application properties

# Service port
server.port=8206
# service name
spring.application.name=service-order
# Environment settings: dev, test, prod
spring.profiles.active=dev

# mysql database connection
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.44.165:3306/yygh_hosp?characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=root123

#Return the global time format of json
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8

spring.data.mongodb.uri=mongodb://192.168.44.165:27017/yygh_hosp

# nacos service address
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848

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

2.3 startup

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

2.4 configure gateway

#Set routing id
spring.cloud.gateway.routes[6].id=service-order
#Set the uri of the route
spring.cloud.gateway.routes[6].uri=lb://service-order
#Set the route assertion, and the agent servicerId is the /auth/ path of auth service
spring.cloud.gateway.routes[6].predicates= Path=/*/order/**

3. Add order basic class

3.1 add model

Note: since entity objects have no logic, we have imported them uniformly

com.atguigu.yygh.model.order.OrderInfo

3.2 add Mapper

Add com atguigu. yygh. order. mapper. OrderInfoMapper

public interface OrderInfoMapper extends BaseMapper<OrderInfo> {
}

3.3 add service interface and implementation class

1. Add com atguigu. yygh. order. service. Orderservice interface

public interface OrderService extends IService<OrderInfo> {
    //Save order
    Long saveOrder(String scheduleId, Long patientId);
}

2. Add com atguigu. yygh. order. service. impl. Orderserviceimpl interface implementation

@Service
public class OrderServiceImpl extends
        ServiceImpl<OrderMapper, OrderInfo> implements OrderService {
    //Save order
    @Override
    public Long saveOrder(String scheduleId, Long patientId) {
        return null;
    }
}

3.4 add controller

Add com atguigu. yygh. order. api. Orderapicontroller class

@Api(tags = "Order interface")
@RestController
@RequestMapping("/api/order/orderInfo")
public class OrderApiController {

    @Autowired
    private OrderService orderService;

    @ApiOperation(value = "Create order")
    @PostMapping("auth/submitOrder/{scheduleId}/{patientId}")
    public Result submitOrder(
            @ApiParam(name = "scheduleId", value = "Scheduling id", required = true)
            @PathVariable String scheduleId,
            @ApiParam(name = "patientId", value = "the patient id", required = true)
            @PathVariable Long patientId) {
        return Result.ok(orderService.saveOrder(scheduleId, patientId));
    }
}

Encapsulate Feign call to get the doctor interface

4.1 api interface for obtaining patient information

Operation module: service user

Add a method in the PatientApiController class

@ApiOperation(value = "Get the patient")
@GetMapping("inner/get/{id}")
public Patient getPatientOrder(
        @ApiParam(name = "id", value = "the patient id", required = true)
        @PathVariable("id") Long id) {
    return patientService.getById(id);
}

4.2 build the service user client module

4.2.1 build the service user client module

The construction process is like the service CMN client module

4.2.2 add Feign interface class

@FeignClient(value = "service-user")
@Repository
public interface PatientFeignClient {
    //Get the patient
    @GetMapping("/api/user/patient/inner/get/{id}")
    Patient getPatient(@PathVariable("id") Long id);
}

Encapsulate Feign call to obtain shift scheduling and order information interface

5.1 api interface for obtaining shift scheduling and order information

Operation module: Service Hosp

5.1.1 add service interface and Implementation

1. Add an interface to the ScheduleService class

//Get the reservation and order data according to the shift id
ScheduleOrderVo getScheduleOrderVo(String scheduleId);

2. Add an implementation in the ScheduleServiceImpl class

//Get the reservation and order data according to the shift id
@Override
public ScheduleOrderVo getScheduleOrderVo(String scheduleId) {
    ScheduleOrderVo scheduleOrderVo = new ScheduleOrderVo();
    //Scheduling information
    Schedule schedule = baseMapper.selectById(scheduleId);
    if(null == schedule) {
        throw new YyghException(ResultCodeEnum.PARAM_ERROR);
    }

    //Get appointment rule information
    Hospital hospital = hospitalService.getByHoscode(schedule.getHoscode());
    if(null == hospital) {
        throw new YyghException(ResultCodeEnum.DATA_ERROR);
    }
    BookingRule bookingRule = hospital.getBookingRule();
    if(null == bookingRule) {
        throw new YyghException(ResultCodeEnum.PARAM_ERROR);
    }

    scheduleOrderVo.setHoscode(schedule.getHoscode());
    scheduleOrderVo.setHosname(hospitalService.getHospName(schedule.getHoscode()));
    scheduleOrderVo.setDepcode(schedule.getDepcode());
    scheduleOrderVo.setDepname(departmentService.getDepName(schedule.getHoscode(), schedule.getDepcode()));
    scheduleOrderVo.setHosScheduleId(schedule.getHosScheduleId());
    scheduleOrderVo.setAvailableNumber(schedule.getAvailableNumber());
    scheduleOrderVo.setTitle(schedule.getTitle());
    scheduleOrderVo.setReserveDate(schedule.getWorkDate());
    scheduleOrderVo.setReserveTime(schedule.getWorkTime());
    scheduleOrderVo.setAmount(schedule.getAmount());

    //The number of days until cancellation (for example, the day before the visit is -1, and the day is 0)
    int quitDay = bookingRule.getQuitDay();
    DateTime quitTime = this.getDateTime(new DateTime(schedule.getWorkDate()).plusDays(quitDay).toDate(), bookingRule.getQuitTime());
    scheduleOrderVo.setQuitTime(quitTime.toDate());

    //Appointment start time
    DateTime startTime = this.getDateTime(new Date(), bookingRule.getReleaseTime());
    scheduleOrderVo.setStartTime(startTime.toDate());

    //Appointment deadline
    DateTime endTime = this.getDateTime(new DateTime().plusDays(bookingRule.getCycle()).toDate(), bookingRule.getStopTime());
    scheduleOrderVo.setEndTime(endTime.toDate());

    //Registration stop time of the day
    DateTime stopTime = this.getDateTime(new Date(), bookingRule.getStopTime());
    scheduleOrderVo.setStartTime(startTime.toDate());
    return scheduleOrderVo;
}

5.1.2 add controller method

Add methods in the HospitalApiController class

@ApiOperation(value = "According to scheduling id Get appointment and order data")
@GetMapping("inner/getScheduleOrderVo/{scheduleId}")
public ScheduleOrderVo getScheduleOrderVo(
        @ApiParam(name = "scheduleId", value = "Scheduling id", required = true)
        @PathVariable("scheduleId") String scheduleId) {
    return scheduleService.getScheduleOrderVo(scheduleId);
}

5.2 interface for obtaining order reference signature information

Operation module: Service Hosp

5.2.1 add service interface and Implementation

1. Add an interface to the HospitalSetService class

//Get hospital signature information
SignInfoVo getSignInfoVo(String hoscode);

2. Add an implementation in the HospitalSetServiceImpl class

//Get hospital signature information
@Override
public SignInfoVo getSignInfoVo(String hoscode) {
    QueryWrapper<HospitalSet> wrapper = new QueryWrapper<>();
    wrapper.eq("hoscode",hoscode);
    HospitalSet hospitalSet = baseMapper.selectOne(wrapper);
    if(null == hospitalSet) {
        throw new YyghException(ResultCodeEnum.HOSPITAL_OPEN);
    }
    SignInfoVo signInfoVo = new SignInfoVo();
    signInfoVo.setApiUrl(hospitalSet.getApiUrl());
    signInfoVo.setSignKey(hospitalSet.getSignKey());
    return signInfoVo;
}

5.2.2 add controller method

Add methods in the HospitalApiController class

@ApiOperation(value = "Get hospital signature information")
@GetMapping("inner/getSignInfoVo/{hoscode}")
public SignInfoVo getSignInfoVo(
        @ApiParam(name = "hoscode", value = "hospital code", required = true)
        @PathVariable("hoscode") String hoscode) {
    return hospitalSetService.getSignInfoVo(hoscode);
}

5.3 build the service Hosp client module

5.3.1 build the service Hosp client module

The construction process is like the service CMN client module

5.3.2 add Feign interface class

@FeignClient(value = "service-hosp")
@Repository
public interface HospitalFeignClient {
    /**
     * Get the reservation and order data according to the shift id
     */
    @GetMapping("/api/hosp/hospital/inner/getScheduleOrderVo/{scheduleId}")
    ScheduleOrderVo getScheduleOrderVo(@PathVariable("scheduleId") String scheduleId);
    /**
     * Get hospital signature information
     */
    @GetMapping("/api/hosp/hospital/inner/getSignInfoVo/{hoscode}")
    SignInfoVo getSignInfoVo(@PathVariable("hoscode") String hoscode);
}

Realize the order interface

Operation module: Service Order

6.1 import dependency

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

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

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

6.2 packaging and ordering tools

Encapsulate the HttpRequestHelper class and add a signature request method

public class HttpRequestHelper {
    /**
     *
     * @param paramMap
     * @return
     */
    public static Map<String, Object> switchMap(Map<String, String[]> paramMap) {
        Map<String, Object> resultMap = new HashMap<>();
        for (Map.Entry<String, String[]> param : paramMap.entrySet()) {
            resultMap.put(param.getKey(), param.getValue()[0]);
        }
        return resultMap;
    }

    /**
     * Request data for signature
     * @param paramMap
     * @param signKey
     * @return
     */
    public static String getSign(Map<String, Object> paramMap, String signKey) {
        if(paramMap.containsKey("sign")) {
            paramMap.remove("sign");
        }
        TreeMap<String, Object> sorted = new TreeMap<>(paramMap);
        StringBuilder str = new StringBuilder();
        for (Map.Entry<String, Object> param : sorted.entrySet()) {
            str.append(param.getValue()).append("|");
        }
        str.append(signKey);
        log.info("Before encryption:" + str.toString());
        String md5Str = MD5.encrypt(str.toString());
        log.info("After encryption:" + md5Str);
        return md5Str;
    }

    /**
     * Signature verification
     * @param paramMap
     * @param signKey
     * @return
     */
    public static boolean isSignEquals(Map<String, Object> paramMap, String signKey) {
        String sign = (String)paramMap.get("sign");
        String md5Str = getSign(paramMap, signKey);
        if(!sign.equals(md5Str)) {
            return false;
        }
        return true;
    }

    /**
     * Get timestamp
     * @return
     */
    public static long getTimestamp() {
        return new Date().getTime();
    }

    /**
     * Encapsulate synchronization request
     */
    public static JSONObject sendRequest(Map<String, Object> paramMap, String url){
        String result = "";
        try {
            //Encapsulate post parameters
            StringBuilder postdata = new StringBuilder();
            for (Map.Entry<String, Object> param : paramMap.entrySet()) {
                postdata.append(param.getKey()).append("=")
                        .append(param.getValue()).append("&");
            }
            log.info(String.format("--> Send request: post data %1s", postdata));
            byte[] reqData = postdata.toString().getBytes("utf-8");
            byte[] respdata = HttpUtil.doPost(url,reqData);
            result = new String(respdata);
            log.info(String.format("--> Response result: result data %1s", result));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return JSONObject.parseObject(result);
    }
}

6.3 realize the order interface

Modify the ordering method of OrderServiceImpl class

@Service
public class OrderServiceImpl extends
        ServiceImpl<OrderMapper, OrderInfo> implements OrderService {

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

    //Save order
    @Override
    public Long saveOrder(String scheduleId, Long patientId) {
        Patient patient = patientFeignClient.getPatient(patientId);
        if(null == patient) {
            throw new YyghException(ResultCodeEnum.PARAM_ERROR);
        }
        ScheduleOrderVo scheduleOrderVo = hospitalFeignClient.getScheduleOrderVo(scheduleId);
        if(null == scheduleOrderVo) {
            throw new YyghException(ResultCodeEnum.PARAM_ERROR);
        }
        //Cannot make an appointment at the current time
        if(new DateTime(scheduleOrderVo.getStartTime()).isAfterNow()
                || new DateTime(scheduleOrderVo.getEndTime()).isBeforeNow()) {
            throw new YyghException(ResultCodeEnum.TIME_NO);
        }
        SignInfoVo signInfoVo = hospitalFeignClient.getSignInfoVo(scheduleOrderVo.getHoscode());
        if(null == scheduleOrderVo) {
            throw new YyghException(ResultCodeEnum.PARAM_ERROR);
        }
        if(scheduleOrderVo.getAvailableNumber() <= 0) {
            throw new YyghException(ResultCodeEnum.NUMBER_NO);
        }
        OrderInfo orderInfo = new OrderInfo();
        BeanUtils.copyProperties(scheduleOrderVo, orderInfo);
        String outTradeNo = System.currentTimeMillis() + ""+ new Random().nextInt(100);
        orderInfo.setOutTradeNo(outTradeNo);
        orderInfo.setScheduleId(scheduleId);
        orderInfo.setUserId(patient.getUserId());
        orderInfo.setPatientId(patientId);
        orderInfo.setPatientName(patient.getName());
        orderInfo.setPatientPhone(patient.getPhone());
        orderInfo.setOrderStatus(OrderStatusEnum.UNPAID.getStatus());
        this.save(orderInfo);

        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("hoscode",orderInfo.getHoscode());
        paramMap.put("depcode",orderInfo.getDepcode());
        paramMap.put("hosScheduleId",orderInfo.getScheduleId());
        paramMap.put("reserveDate",new DateTime(orderInfo.getReserveDate()).toString("yyyy-MM-dd"));
        paramMap.put("reserveTime", orderInfo.getReserveTime());
        paramMap.put("amount",orderInfo.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());
        //contacts
        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", sign);
        JSONObject result = HttpRequestHelper.sendRequest(paramMap, signInfoVo.getApiUrl()+"/order/submitOrder");
        
        if(result.getInteger("code") == 200) {
            JSONObject jsonObject = result.getJSONObject("data");
            //Unique ID of appointment record (primary key of hospital appointment record)
            String hosRecordId = jsonObject.getString("hosRecordId");
            //Appointment serial number
            Integer number = jsonObject.getInteger("number");;
            //Number acquisition time
            String fetchTime = jsonObject.getString("fetchTime");;
            //Number taking address
            String fetchAddress = jsonObject.getString("fetchAddress");;
            //Update order
            orderInfo.setHosRecordId(hosRecordId);
            orderInfo.setNumber(number);
            orderInfo.setFetchTime(fetchTime);
            orderInfo.setFetchAddress(fetchAddress);
            baseMapper.updateById(orderInfo);
            //Number of scheduled appointments
            Integer reservedNumber = jsonObject.getInteger("reservedNumber");
            //Remaining appointments of shift scheduling
            Integer availableNumber = jsonObject.getInteger("availableNumber");
            //Send mq information update number source and SMS notification
        } else {
            throw new YyghException(result.getString("message"), ResultCodeEnum.FAIL.getCode());
        }
        return orderInfo.getId();
    }
}

Post appointment processing logic

After the appointment is successful, we need to update the number of appointments and SMS to remind us that the appointment is successful. In order to improve the concurrency of the order, we will hand over this part of the logic to mq to complete for us. If the appointment is successful, we can send a message

(1) Introduction to RabbitMQ

Take the commodity order scenario as an example,

If the commodity service and order service are two different micro services, the order service needs to call the commodity service to deduct inventory during the order placing process. According to the traditional way, the order placing process can only return to the success of the order after the call is completed. If the inventory deduction of goods and services is delayed or failed due to network fluctuations and other reasons, it will bring poor user experience. If such processing is obviously inappropriate in high concurrency scenarios, how to optimize it? This requires message queuing.

Message queuing provides an asynchronous communication mechanism. The sender of a message does not have to wait until the message is successfully processed before returning, but returns immediately. Message oriented middleware is responsible for handling network communication. If the network connection is unavailable, the messages are temporarily stored in the queue. When the network is unblocked, the messages are forwarded to the corresponding applications or services, provided that these services subscribe to the queue. If message oriented middleware is used between Commodity services and order services, it can not only improve the concurrency, but also reduce the coupling between services.

RabbitMQ is such a message queue. RabbitMQ is an open source message broker queue server used to share data between completely different applications through common protocols.

(2) Typical application scenarios:

Asynchronous processing. Put the message into the message middleware and wait until it is needed.

Flow peak shaving. For example, in the second kill activity, the number of visits increases sharply in a short time. Using the message queue, when the message queue is full, it will refuse to respond and jump to the error page, so that the system will not crash due to overload.

Log processing

Application decoupling

(2) Install RabbitMQ

docker pull rabbitmq:management
docker run -d -p 5672:5672 -p 15672:15672 --name rabbitmq rabbitmq:management

Management background: http://IP:15672

7.1 rabbit util module packaging

Since mq may be used by many modules in the future, we can package it into a module and directly reference it where necessary

7.1.1 build rabbit util module

It is built under the common module. The building process is as follows: common util

7.1.2 modify pom xml

<dependencies>
    <!--rabbitmq Message queue-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-bus-amqp</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
    </dependency>
</dependencies>

7.1.3 packaging service method

@Service
public class RabbitService {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    /**
     *  send message
     * @param exchange Switch
     * @param routingKey Routing key
     * @param message news
     */
    public boolean sendMessage(String exchange, String routingKey, Object message) {
        rabbitTemplate.convertAndSend(exchange, routingKey, message);
        return true;
    }
}

7.1.4 configure mq message converter

@Configuration
public class MQConfig {
    @Bean
    public MessageConverter messageConverter(){
        return new Jackson2JsonMessageConverter();
    }
}

Note: the default is string converter

7.2 encapsulated SMS interface

Operation module: Service MSM

7.2.1 import dependency

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

7.2.2 add configuration

In resources/application Properties add

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

7.2.3 add constant configuration

In rabbit util module com atguigu. yygh. common. constant. Mqconst class add

public class MqConst {
    /**
     * Make an appointment to place an order
     */
    public static final String EXCHANGE_DIRECT_ORDER 
= "exchange.direct.order";
    public static final String ROUTING_ORDER = "order";
    //queue
    public static final String QUEUE_ORDER  = "queue.order";
    /**
     * short message
     */
    public static final String EXCHANGE_DIRECT_MSM = "exchange.direct.msm";
    public static final String ROUTING_MSM_ITEM = "msm.item";
    //queue
    public static final String QUEUE_MSM_ITEM  = "queue.msm.item";
}

7.2.4 encapsulate the SMS entity in the model module

@Data
@ApiModel(description = "SMS entity")
public class MsmVo {
    @ApiModelProperty(value = "phone")
    private String phone;
    @ApiModelProperty(value = "SMS template code")
    private String templateCode;
    @ApiModelProperty(value = "SMS template parameters")
    private Map<String,Object> param;
}

Note: unified introduction

7.2.5 encapsulating the service interface

1. Add an interface to the MsmService class

boolean send(MsmVo msmVo);

2. Add interface implementation in MsmServiceImpl class

@Override
public boolean send(MsmVo msmVo) {
    if(!StringUtils.isEmpty(msmVo.getPhone())) {
        String code = (String)msmVo.getParam().get("code");
        return this.send(msmVo.getPhone(),code);
    }
    return false;
}

7.2.6 package mq listener

@Component
public class SmsReceiver {
    @Autowired
    private MsmService msmService;
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = MqConst.QUEUE_MSM_ITEM, durable = "true"),
            exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_MSM),
            key = {MqConst.ROUTING_MSM_ITEM}
    ))
    public void send(MsmVo msmVo, Message message, Channel channel) {
        msmService.send(msmVo);
    }
}

7.3 number of package update shifts

Operation module: Service Hosp

7.3.1 import dependency

<!--rabbitmq Message queue-->
<dependency>
    <groupId>com.atguigu.yygh</groupId>
    <artifactId>rabbit-util</artifactId>
    <version>1.0</version>
</dependency>

7.3.2 add configuration

In resources/application Properties add

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

7.3.3 add constant configuration

In rabbit util module com atguigu. yygh. common. constant. Mqconst class add

/**
 * Make an appointment to place an order
 */
public static final String EXCHANGE_DIRECT_ORDER = "exchange.direct.order";
public static final String ROUTING_ORDER = "order";
//queue
public static final String QUEUE_ORDER  = "queue.order";

7.3.4 package and update the scheduling entity in the model module

@Data
@ApiModel(description = "OrderMqVo")
public class OrderMqVo {
   @ApiModelProperty(value = "Bookable number")
   private Integer reservedNumber;

   @ApiModelProperty(value = "Remaining appointments")
   private Integer availableNumber;

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

   @ApiModelProperty(value = "SMS entity")
   private MsmVo msmVo;
}

Note: it has been uniformly introduced. This object puts a SMS entity. After the order is placed successfully, we send a message and let mq ensure that both messages are sent successfully

7.3.5 encapsulating the service interface

1. Add an interface to the ScheduleService class

/**
 * Modify shift scheduling
*/
void update(Schedule schedule);

2. Add interface implementation in ScheduleServiceImpl class

@Override
public void update(Schedule schedule) {
    schedule.setUpdateTime(new Date());
    //If the primary key is consistent, it means updating
    scheduleRepository.save(schedule);
}

7.3.6 package mq listener

@Component
public class HospitalReceiver {

    @Autowired
    private ScheduleService scheduleService;

    @Autowired
    private RabbitService rabbitService;

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = MqConst.QUEUE_ORDER, durable = "true"),
            exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_ORDER),
            key = {MqConst.ROUTING_ORDER}
    ))
    public void receiver(OrderMqVo orderMqVo, Message message, Channel channel) throws IOException {
        //Number of appointments updated successfully
        Schedule schedule = scheduleService.getScheduleId(orderMqVo.getScheduleId());
        schedule.setReservedNumber(orderMqVo.getReservedNumber());
        schedule.setAvailableNumber(orderMqVo.getAvailableNumber());
        scheduleService.update(schedule);
        //Send SMS
        MsmVo msmVo = orderMqVo.getMsmVo();
        if(null != msmVo) {
            rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_MSM, MqConst.ROUTING_MSM_ITEM, msmVo);
        }
    }
}

7.4 adjust the order interface

Operation module: Service Order

7.4.1 import dependency

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

7.4.2 add configuration

In resources/application Properties add

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

7.4.3 modify the order interface

Modify the ordering method of OrderServiceImpl class

@Autowired
private RabbitService rabbitService;
@Transactional(rollbackFor = Exception.class)
@Override
public Long saveOrder(String scheduleId, Long patientId) {
 .......
        //Number of scheduled appointments
        Integer reservedNumber = jsonObject.getInteger("reservedNumber");
        //Remaining appointments of shift scheduling
        Integer availableNumber = jsonObject.getInteger("availableNumber");
        //Send mq information update number source and SMS notification
        //Send mq information update number source
        OrderMqVo orderMqVo = new OrderMqVo();
        orderMqVo.setScheduleId(scheduleId);
        orderMqVo.setReservedNumber(reservedNumber);
        orderMqVo.setAvailableNumber(availableNumber);

        //SMS prompt
        MsmVo msmVo = new MsmVo();
        msmVo.setPhone(orderInfo.getPatientPhone());
        msmVo.setTemplateCode("SMS_194640721");
        String reserveDate = 
new DateTime(orderInfo.getReserveDate()).toString("yyyy-MM-dd") 
+ (orderInfo.getReserveTime()==0 ? "morning": "afternoon");
        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.setMsmVo(msmVo);
        rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_ORDER, MqConst.ROUTING_ORDER, orderMqVo);
    } else {
        throw new YyghException(result.getString("message"), ResultCodeEnum.FAIL.getCode());
    }
    return orderInfo.getId();
}

2, Order management

Order list

api interface

1.1.1 add service interface and implementation class

1. Add an interface to the OrderInfoService class

/**
 * Paging list
*/
IPage<OrderInfo> selectPage(Page<OrderInfo> pageParam, OrderQueryVo orderQueryVo);

2. Add interface implementation in OrderInfoServiceImpl class

//Order list (condition query with pagination)
@Override
public IPage<OrderInfo> selectPage(Page<OrderInfo> pageParam, OrderQueryVo orderQueryVo) {
    //orderQueryVo get condition value
    String name = orderQueryVo.getKeyword(); //Hospital name
    Long patientId = orderQueryVo.getPatientId(); //Name of the patient
    String orderStatus = orderQueryVo.getOrderStatus(); //Order status
    String reserveDate = orderQueryVo.getReserveDate();//Schedule time
    String createTimeBegin = orderQueryVo.getCreateTimeBegin();
    String createTimeEnd = orderQueryVo.getCreateTimeEnd();
    //Judge whether the condition value is not empty
    QueryWrapper<OrderInfo> wrapper = new QueryWrapper<>();
    if(!StringUtils.isEmpty(name)) {
        wrapper.like("hosname",name);
    }
    if(!StringUtils.isEmpty(patientId)) {
        wrapper.eq("patient_id",patientId);
    }
    if(!StringUtils.isEmpty(orderStatus)) {
        wrapper.eq("order_status",orderStatus);
    }
    if(!StringUtils.isEmpty(reserveDate)) {
        wrapper.ge("reserve_date",reserveDate);
    }
    if(!StringUtils.isEmpty(createTimeBegin)) {
        wrapper.ge("create_time",createTimeBegin);
    }
    if(!StringUtils.isEmpty(createTimeEnd)) {
        wrapper.le("create_time",createTimeEnd);
    }
    //Call the method of mapper
    IPage<OrderInfo> pages = baseMapper.selectPage(pageParam, wrapper);
    //Number becomes corresponding value encapsulation
    pages.getRecords().stream().forEach(item -> {
        this.packOrderInfo(item);
    });
    return pages;
}
private OrderInfo packOrderInfo(OrderInfo orderInfo) {
    orderInfo.getParam().put("orderStatusString", OrderStatusEnum.getStatusNameByStatus(orderInfo.getOrderStatus()));
    return orderInfo;
}

1.1.2 add controller

Add a method in the OrderApiController class

//Order list (condition query with pagination)
@GetMapping("auth/{page}/{limit}")
public Result list(@PathVariable Long page,
                   @PathVariable Long limit,
                   OrderQueryVo orderQueryVo, HttpServletRequest request) {
    //Set current user id
    orderQueryVo.setUserId(AuthContextHolder.getUserId(request));
    Page<OrderInfo> pageParam = new Page<>(page,limit);
    IPage<OrderInfo> pageModel =
            orderService.selectPage(pageParam,orderQueryVo);
    return Result.ok(pageModel);
}

@ApiOperation(value = "Get order status")
@GetMapping("auth/getStatusList")
public Result getStatusList() {
    return Result.ok(OrderStatusEnum.getStatusList());
}

Note: the order status is encapsulated in enumeration. A drop-down list is required for page search, so we return to the page through the interface

front end

1.2.1 encapsulating api requests

At /api/orderinfo JS add method

//Order list
getPageList(page, limit, searchObj) {
    return request({
        url: `${api_name}/auth/${page}/${limit}`,
        method: `get`,
        params: searchObj
    })
},
//Order status
getStatusList() {
    return request({
        url: `${api_name}/auth/getStatusList`,
        method: 'get'
    })
},

1.2.2 page display

Create /pages/order/index Vue component

<template>
  <!-- header -->
  <div class="nav-container page-component">
    <!--Left Navigation  #start -->
    <div class="nav left-nav">
      <div class="nav-item ">
        <span class="v-link clickable dark" οnclick="javascript:window.location='/user'">Real name authentication </span>
      </div>
      <div class="nav-item selected">
        <span class="v-link selected dark" οnclick="javascript:window.location='/order'"> Registered order </span>
      </div>
      <div class="nav-item ">
        <span class="v-link clickable dark" οnclick="javascript:window.location='/patient'"> Patient management </span>
      </div>
      <div class="nav-item ">
        <span class="v-link clickable dark"> Modify account information </span>
      </div>
      <div class="nav-item ">
        <span class="v-link clickable dark"> Feedback </span>
      </div>
    </div>
    <!-- Left Navigation  #end -->
    <!-- Content on the right #start -->
    <div class="page-container">
      <div class="personal-order">
        <div class="title"> Registered order</div>
        <el-form :inline="true">
          <el-form-item label="the patient:">
            <el-select v-model="searchObj.patientId" placeholder="Please select a doctor" 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="Order status:" style="margin-left: 80px">
            <el-select v-model="searchObj.orderStatus" placeholder="whole" 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()">
              query
            </el-button>
          </el-form-item>
        </el-form>
        <div class="table-wrapper table">
          <el-table
            :data="list"
            stripe
            style="width: 100%">
            <el-table-column
              label="Visit time"
              width="120">
              <template slot-scope="scope">
                {{ scope.row.reserveDate }} {{ scope.row.reserveTime === 0 ? 'morning' : 'afternoon' }}
              </template>
            </el-table-column>
            <el-table-column
              prop="hosname"
              label="hospital"
              width="100">
            </el-table-column>
            <el-table-column
              prop="depname"
              label="Department">
            </el-table-column>
            <el-table-column
              prop="title"
              label="doctor">
            </el-table-column>
            <el-table-column
              prop="amount"
              label="medical service fee ">
            </el-table-column>
            <el-table-column
              prop="patientName"
              label="the patient">
            </el-table-column>
            <el-table-column
              prop="param.orderStatusString"
              label="Order status">
            </el-table-column>
            <el-table-column label="operation">
              <template slot-scope="scope">
                <el-button type="text" class="v-link highlight clickable selected" @click="show(scope.row.id)">details</el-button>
              </template>
            </el-table-column>
          </el-table>
        </div>
        <!-- paging -->
        <el-pagination
          class="pagination"
          layout="prev, pager, next"
          :current-page="page"
          :total="total"
          :page-size="limit"
          @current-change="fetchData">
        </el-pagination>
      </div>
    </div>
    <!-- Content on the right #end -->
  </div>
  <!-- footer -->
</template>
<script>
import '~/assets/css/hospital_personal.css'
import '~/assets/css/hospital.css'
import orderInfoApi from '@/api/order/orderInfo'
import patientApi from '@/api/user/patient'
export default {
  data() {
    return {
      list: [], // banner list
      total: 0, // Total records in the database
      page: 1, // Default page number
      limit: 10, // Records per page
      searchObj: {}, // Query form object
      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.records
        this.total = response.data.total
      })
    },
    findPatientList() {
      patientApi.findList().then(response => {
        this.patientList = response.data
      })
    },
    getStatusList() {
      orderInfoApi.getStatusList().then(response => {
        this.statusList = response.data
      })
    },
    changeSize(size) {
      console.log(size)
      this.limit = size
      this.fetchData(1)
    },
    show(id) {
      window.location.href = '/order/show?orderId=' + id
    }
  }
}
</script>

Order details

2.1 api interface

2.1.1 add service interface and implementation class

1. Add an interface to the OrderInfoService class

/**
 * Get order details
*/
OrderInfo getOrderInfo(Long id);

2. Add interface implementation in OrderInfoServiceImpl class

//Query order details according to order id
@Override
public OrderInfo getOrder(String orderId) {
    OrderInfo orderInfo = baseMapper.selectById(orderId);
    return this.packOrderInfo(orderInfo);
}

2.1.2 add controller

Add a method in the OrderApiController class

//Query order details according to order id
@GetMapping("auth/getOrders/{orderId}")
public Result getOrders(@PathVariable String orderId) {
    OrderInfo orderInfo = orderService.getOrder(orderId);
    return Result.ok(orderInfo);
}

2.2 front end

2.2.1 encapsulating api requests

At /api/order/orderinfo JS add method

    //Order details
    getOrders(orderId) {
        return request({
            url: `${api_name}/auth/getOrders/${orderId}`,
            method: `get`
        })
    },

2.2.2 page display

Create /pages/order/show Vue component

<template>
  <!-- header -->
  <div class="nav-container page-component">
    <!--Left Navigation  #start -->
    <div class="nav left-nav">
      <div class="nav-item ">
        <span class="v-link clickable dark" οnclick="javascript:window.location='/user'">Real name authentication </span>
      </div>
      <div class="nav-item selected">
        <span class="v-link selected dark" οnclick="javascript:window.location='/order'"> Registered order </span>
      </div>
      <div class="nav-item ">
        <span class="v-link clickable dark" οnclick="javascript:window.location='/patient'"> Patient management </span>
      </div>
      <div class="nav-item ">
        <span class="v-link clickable dark"> Modify account information </span>
      </div>
      <div class="nav-item ">
        <span class="v-link clickable dark"> Feedback </span>
      </div>
    </div>
    <!-- Left Navigation  #end -->
    <!-- Content on the right #start -->
    <div class="page-container">
      <div class="order-detail">
        <div class="title"> Registration details</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> WeChat<span class="iconfont"></span>Follow "Beijing 114 appointment registration"</div>
              <div class="watch-wrapper"> Fast registration and easy medical treatment</div>
            </div>
          </div>
        </div>
        <div class="info-wrapper">
          <div class="title-wrapper">
            <div class="block"></div>
            <div>Registration information</div>
          </div>
          <div class="info-form">
            <el-form ref="form" :model="form">
              <el-form-item label="Patient information:">
                <div class="content"><span>{{ orderInfo.patientName }}</span></div>
              </el-form-item>
              <el-form-item label="Date of visit:">
                <div class="content"><span>{{ orderInfo.reserveDate }} {{ orderInfo.reserveTime == 0 ? 'morning' : 'afternoon' }}</span></div>
              </el-form-item>
              <el-form-item label="Hospital:">
                <div class="content"><span>{{ orderInfo.hosname }} </span></div>
              </el-form-item>
              <el-form-item label="Department:">
                <div class="content"><span>{{ orderInfo.depname }} </span></div>
              </el-form-item>
              <el-form-item label="Doctor Title:">
                <div class="content"><span>{{ orderInfo.title }} </span></div>
              </el-form-item>
              <el-form-item label="Medical service fee:">
                <div class="content">
                  <div class="fee">{{ orderInfo.amount }}element
                  </div>
                </div>
              </el-form-item>
              <el-form-item label="Registration No.:">
                <div class="content"><span>{{ orderInfo.outTradeNo }} </span></div>
              </el-form-item>
              <el-form-item label="Registration time:">
                <div class="content"><span>{{ orderInfo.createTime }}</span></div>
              </el-form-item>
            </el-form>
          </div>
        </div>
        <div class="rule-wrapper mt40">
          <div class="rule-title"> matters needing attention</div>
          <div>1,Please confirm whether the information of the doctor is accurate. If you fill in the wrong number, you will not be able to get a doctor, and the loss will be borne by yourself;<br>
            <span style="color:red">2,[Take number] on the day of treatment{{ orderInfo.fetchTime }}Take a number in the hospital. If you don't take a number, it will be regarded as breaking the appointment, and the number will not be returned or replaced;</span><br>
            3,[Back number] in{{ orderInfo.quitTime }}The number can be refunded online before, and the number and fee can not be refunded after the expiration of the time limit;<br>
            4,Beijing 114 appointment registration supports self funded patients to make an appointment with their ID card, and supports Beijing medical insurance patients to make an appointment with the Beijing social security card on the platform. Please bring the valid ID card used for appointment registration to the hospital to get the number on the day of treatment;<br>
            5,Please note that medical insurance patients in Beijing cannot use social security cards to get numbers in outpatient clinics during hospitalization.
          </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()">cancel reservation</div>
          </div>
          <div class="button-wrapper ml20" v-if="orderInfo.orderStatus == 0">
            <div class="v-button" @click="pay()">payment</div>
          </div>
        </div>
      </div>
    </div>
    <!-- Content on the right #end -->
    <!-- Wechat payment pop-up box -->
    <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;">
                Please use wechat to scan<br/>
                Scanning QR code for payment
              </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/orderInfo'
export default {
  data() {
    return {
      orderId: null,
      orderInfo: {
        param: {}
      },
      dialogPayVisible: false,
      payObj: {},
      timer: null  // Timer name
    }
  },
  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
      })
    }
  }
}
</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>

3, Platform order management

Order list

api interface

Add controller method

Add com atguigu. yygh. order. controller. Ordercontroller class

@Api(tags = "Order interface")
@RestController
@RequestMapping("/admin/order/orderInfo")
public class OrderController {

    @Autowired
    private OrderService orderService;

    @ApiOperation(value = "Get paging list")
    @GetMapping("{page}/{limit}")
    public Result index(
            @ApiParam(name = "page", value = "Current page number", required = true)
            @PathVariable Long page,
            @ApiParam(name = "limit", value = "Records per page", required = true)
            @PathVariable Long limit,
            @ApiParam(name = "orderCountQueryVo", value = "Query object", required = false) OrderQueryVo orderQueryVo) {
        Page<OrderInfo> pageParam = new Page<>(page, limit);
        IPage<OrderInfo> pageModel = orderService.selectPage(pageParam, orderQueryVo);
        return Result.ok(pageModel);
    }

    @ApiOperation(value = "Get order status")
    @GetMapping("getStatusList")
    public Result getStatusList() {
        return Result.ok(OrderStatusEnum.getStatusList());
    }
}

1.2 front end

1.2.1 add route

In src/router/index JS file add route

{
  path: '/order',
  component: Layout,
  redirect: '/order/orderInfo/list',
  name: 'BasesInfo',
  meta: { title: 'Order management', icon: 'table' },
  alwaysShow: true,
  children: [
      {
        path: 'orderInfo/list',
        name: 'Order list',
        component: () =>import('@/views/order/orderInfo/list'),
        meta: { title: 'Order list' }
      }
    ]
}

1.2.2 encapsulating api requests

Add /api/order/orderinfo JS file

import request from '@/utils/request'
const api_name = '/admin/order/orderInfo'
export default {
  getPageList(page, limit, searchObj) {
    return request({
      url: `${api_name}/${page}/${limit}`,
      method: 'get',
      params: searchObj
    })
  },
  getStatusList() {
    return request({
      url: `${api_name}/getStatusList`,
      method: 'get'
    })
  }
}

1.2.3 add components

Create /views/order/orderinfo/list Vue component

<template>
  <div class="app-container">
    <el-form :inline="true" class="demo-form-inline">
      <el-form-item>
        <el-input v-model="searchObj.hosname" placeholder="Hospital name"/>
      </el-form-item>
      <el-form-item>
        <el-input v-model="searchObj.outTradeNo" placeholder="order number"/>
      </el-form-item>
      <el-form-item>
        <el-input v-model="searchObj.patientName" placeholder="Name of the patient"/>
      </el-form-item>
      <el-form-item>
        <el-date-picker
          v-model="searchObj.createTimeBegin"
          type="date"
          placeholder="Select Start Date"
          value-format="yyyy-MM-dd" />
      </el-form-item>
      <el-form-item>
        <el-date-picker
          v-model="searchObj.createTimeEnd"
          type="date"
          placeholder="Select a deadline"
          value-format="yyyy-MM-dd" />
      </el-form-item>
      <el-form-item>
        <el-date-picker
          v-model="searchObj.reserveDate"
          type="date"
          placeholder="Date of visit"
          value-format="yyyy-MM-dd" />
      </el-form-item>
      <el-form-item>
        <el-select v-model="searchObj.orderStatus" placeholder="Order status" class="v-select patient-select">
          <el-option
            v-for="item in statusList"
            :key="item.status"
            :label="item.comment"
            :value="item.status">
          </el-option>
        </el-select>
      </el-form-item>
      <el-button type="primary" icon="el-icon-search" @click="fetchData()">query</el-button>
      <el-button type="default" @click="resetData()">empty</el-button>
    </el-form>
    <!-- list -->
    <el-table
      v-loading="listLoading"
      :data="list"
      border
      fit
      highlight-current-row>
      <el-table-column
        label="Serial number"
        width="60"
        align="center">
        <template slot-scope="scope">
          {{ (page - 1) * limit + scope.$index + 1 }}
        </template>
      </el-table-column>
      <el-table-column prop="outTradeNo" label="Order transaction number" width="160"/>
      <el-table-column prop="hosname" label="Hospital name" width="160"/>
      <el-table-column prop="depname" label="Department name" width="160"/>
      <el-table-column prop="title" label="Doctor title" />
      <el-table-column label="Schedule time" width="130">
        <template slot-scope="scope">
          {{ scope.row.reserveDate }} {{ scope.row.reserveTime === 0 ? 'morning' : 'afternoon' }}
        </template>
      </el-table-column>
      <el-table-column prop="patientName" label="the patient" />
      <el-table-column prop="number" label="Appointment number sequence" width="80"/>
      <el-table-column prop="amount" label="service charge" width="70"/>
      <el-table-column prop="param.orderStatusString" label="Order status" />
      <el-table-column prop="createTime" label="Creation time" width="156"/>
      <el-table-column label="operation" width="100" align="center">
        <template slot-scope="scope">
          <router-link :to="'/order/orderInfo/show/'+scope.row.id">
            <el-button type="primary" size="mini" icon="el-icon-edit">see</el-button>
          </router-link>
        </template>
      </el-table-column>
    </el-table>
    <!-- Paging component -->
    <el-pagination
      :current-page="page"
      :total="total"
      :page-size="limit"
      :page-sizes="[5, 10, 20, 30, 40, 50, 100]"
      style="padding: 30px 0; text-align: center;"
      layout="sizes, prev, pager, next, jumper, ->, total, slot"
      @current-change="fetchData"
      @size-change="changeSize"
    />
  </div>
</template>
<script>
import orderInfoApi from '@/api/order/orderInfo'

export default {
  data() {
    return {
      listLoading: true, // Whether the data is loading
      list: null, // banner list
      total: 0, // Total records in the database
      page: 1, // Default page number
      limit: 10, // Records per page
      searchObj: {} // Query form object
    }
  },
  // Life cycle function: the memory is ready, and the page has not been rendered
  created() {
    this.fetchData()
    this.getStatusList()
  },
  methods: {
    // When the page number changes
    changeSize(size) {
      console.log(size)
      this.limit = size
      this.fetchData(1)
    },
    // Load banner list data
    fetchData(page = 1) {
      console.log('Turn the page...' + page)
      // Get remote data asynchronously (ajax)
      this.page = page
      orderInfoApi.getPageList(this.page, this.limit, this.searchObj).then(
        response => {
          debugger
          this.list = response.data.records
          this.total = response.data.total
          // Data loading and binding succeeded
          this.listLoading = false
        }
      )
    },
    getStatusList() {
      orderInfoApi.getStatusList().then(response => {
        this.statusList = response.data
      })
    },
    // Reset query form
    resetData() {
      console.log('Reset query form')
      this.searchObj = {}
      this.fetchData()
    }
  }
}
</script>

Order details

2.1 api interface

2.1.1 add service interface and implementation class

1. Add an interface to the OrderInfoService class

/**
 * Order details
 * @param orderId
* @return
*/
Map<String,Object> show(Long orderId);

2. Add interface implementation in OrderInfoServiceImpl class

@Override
public Map<String, Object> show(Long orderId) {
   Map<String, Object> map = new HashMap<>();
   OrderInfo orderInfo = this.packOrderInfo(this.getById(orderId));
   map.put("orderInfo", orderInfo);
   Patient patient 
=  patientFeignClient.getPatient(orderInfo.getPatientId());
   map.put("patient", patient);
   return map;
}

2.1.2 add controller

Add method in OrderController class

@ApiOperation(value = "Get order")
@GetMapping("show/{id}")
public Result get(
@ApiParam(name = "orderId", value = "order id", required = true)
@PathVariable Long id) {
   return Result.ok(orderService.show(id));
}

2.2 front end

2.2.1 add route

In src/router/index JS file add route

{
  path: '/order',
  component: Layout,
  redirect: '/order/orderInfo/list',
  name: 'BasesInfo',
  meta: { title: 'Order management', icon: 'table' },
  alwaysShow: true,
  children: [
      {
        path: 'orderInfo/list',
        name: 'Order list',
        component: () =>import('@/views/order/orderInfo/list'),
        meta: { title: 'Order list' }
      },
      {
        path: 'orderInfo/show/:id',
        name: 'see',
              component: () =>import('@/views/order/orderInfo/show'),
        meta: { title: 'see', noCache: true },
        hidden: true
      }
    ]
}

2.2.2 encapsulating api requests

At /api/order/orderinfo JS file adding method

  getById(id) {
    return request({
      url: `${api_name}/show/${id}`,
      method: 'get'
    })
  }

2.2.3 modify list components

Modify /views/order/orderinfo/list Vue component

<el-table-column label="operation"width="100"align="center">
<template slot-scope="scope">
    <router-link :to="'/order/orderInfo/show/'+scope.row.id">
      <el-button type="primary" size="mini" icon="el-icon-edit">see</el-button>
    </router-link>
</template>
</el-table-column>

2.2.4 add components

Create /views/order/orderinfo/show Vue component

<template>
  <div class="app-container">
    <h4>Order information</h4>
    <table class="table table-striped table-condenseda table-bordered" width="100%">
      <tbody>
      <tr>
        <th width="15%">Order transaction number</th>
        <td width="35%"><b style="font-size: 14px">{{ orderInfo.outTradeNo }}</b> </td>
        <th width="15%">Hospital name</th>
        <td width="35%">{{ orderInfo.hosname }}</td>
      </tr>
      <tr>
        <th>Department name</th>
        <td>{{ orderInfo.depname }}</td>
        <th>Doctor title</th>
        <td>{{ orderInfo.title }}</td>
      </tr>
      <tr>
        <th>Scheduled date</th>
        <td>{{ orderInfo.reserveDate }} {{ orderInfo.reserveTime === 0 ? 'morning' : 'afternoon' }}</td>
        <th>Appointment number sequence</th>
        <td>{{ orderInfo.number }}</td>
      </tr>
      <tr>
        <th>medical service fee </th>
        <td>{{ orderInfo.amount }}</td>
        <th>Suggested date</th>
        <td>{{ orderInfo.fetchTime }}</td>
      </tr>
      <tr>
        <th>Location of number taking</th>
        <td>{{ orderInfo.fetchAddress }}</td>
        <th>Cancellation time</th>
        <td>{{ orderInfo.quitTime }}</td>
      </tr>
      <tr>
        <th>Order status</th>
        <td >{{ orderInfo.param.orderStatusString }}</td>
        <th>time of appointment</th>
        <td>{{ orderInfo.createTime }}</td>
      </tr>
      </tbody>
    </table>
    <h4>Patient information</h4>
    <table class="table table-striped table-condenseda table-bordered" width="100%">
      <tbody>
      <tr>
        <th width="15%">full name</th>
        <td width="35%">{{ patient.name }}day</td>
        <th width="15%">Document type </th>
        <td width="35%">{{ patient.param.certificatesTypeString }}</td>
      </tr>
      <tr>
        <th>Certificate No</th>
        <td>{{ patient.certificatesNo }}</td>
        <th>Gender</th>
        <td>{{ patient.sex === 1 ? 'male' : 'female' }}</td>
      </tr>
      <tr>
        <th>date of birth</th>
        <td>{{ patient.birthdate }}</td>
        <th>mobile phone</th>
        <td>{{ patient.phone }}</td>
      </tr>
      <tr>
        <th>Married or not</th>
        <td>{{ patient.isMarry === 1 ? 'yes' : 'no' }}</td>
        <th>address</th>
        <td>{{ patient.param.fullAddress }}</td>
      </tr>
      <tr>
        <th>Contact name</th>
        <td>{{ patient.contactsName }}</td>
        <th>Contact ID type</th>
        <td>{{ patient.param.contactsCertificatesTypeString }}</td>
      </tr>
      <tr>
        <th>Contact ID No</th>
        <td>{{ orderInfo.contactsCertificatesNo }}</td>
        <th>Cell Phone </th>
        <td>{{ orderInfo.contactsPhone }}</td>
      </tr>
      <br>
      <el-row>
        <el-button @click="back">return</el-button>
      </el-row>
      </tbody>
    </table>
  </div>
</template>
<script>
// Import components
import orderInfoApi from '@/api/order/orderInfo'
export default {
  data() {
    return {
      orderInfo: null,
      patient: null
    }
  },

  // Life cycle method (it will not be called when the route is switched and the components remain unchanged)
  created() {
    console.log('form created ......')
    this.init()
  },
  methods: {
    // Form initialization
    init() {
      const id = this.$route.params.id
      this.fetchDataById(id)
    },
    // Query records according to id
    fetchDataById(id) {
      orderInfoApi.getById(id).then(response => {
        this.orderInfo = response.data.orderInfo
        this.patient = response.data.patient
      })
    },
    back() {
      this.$router.push({ path: '/order/orderInfo/list' })
    }
  }
}
</script>

Tags: Java Spring Boot

Posted by zahadum on Sun, 03 Jul 2022 00:45:44 +0530