初始化医疗模块
diff --git a/backend/src/main/java/com/supwisdom/dlpay/medicine/dao/impl/AppointmentRepositoryImpl.java b/backend/src/main/java/com/supwisdom/dlpay/medicine/dao/impl/AppointmentRepositoryImpl.java
new file mode 100644
index 0000000..5904a4b
--- /dev/null
+++ b/backend/src/main/java/com/supwisdom/dlpay/medicine/dao/impl/AppointmentRepositoryImpl.java
@@ -0,0 +1,19 @@
+package com.supwisdom.dlpay.medicine.dao.impl;
+
+import com.supwisdom.dlpay.framework.jpa.BaseRepository;
+import com.supwisdom.dlpay.framework.jpa.Finder;
+import com.supwisdom.dlpay.framework.jpa.page.Pagination;
+import com.supwisdom.dlpay.medicine.dao.AppointmentRepository;
+import com.supwisdom.dlpay.medicine.domain.TBAppointmentDtl;
+import org.hibernate.transform.Transformers;
+import org.jetbrains.annotations.NotNull;
+
+public class AppointmentRepositoryImpl extends BaseRepository implements AppointmentRepository {
+  @NotNull
+  @Override
+  public Pagination getAppointmentList(int pageno, int pagesize, @NotNull String uid) {
+    Finder f = Finder.create("select * from tb_appointmentdtl where uid=:uid and delete=false order by createtime desc");
+    f.setParameter("uid", uid);
+    return findNative(f, Transformers.aliasToBean(TBAppointmentDtl.class), pageno, pagesize);
+  }
+}
diff --git a/backend/src/main/java/com/supwisdom/dlpay/medicine/dao/impl/HospitalRepositoryImpl.java b/backend/src/main/java/com/supwisdom/dlpay/medicine/dao/impl/HospitalRepositoryImpl.java
new file mode 100644
index 0000000..087e208
--- /dev/null
+++ b/backend/src/main/java/com/supwisdom/dlpay/medicine/dao/impl/HospitalRepositoryImpl.java
@@ -0,0 +1,28 @@
+package com.supwisdom.dlpay.medicine.dao.impl;
+
+import com.supwisdom.dlpay.framework.jpa.BaseRepository;
+import com.supwisdom.dlpay.framework.jpa.Finder;
+import com.supwisdom.dlpay.framework.jpa.page.Pagination;
+import com.supwisdom.dlpay.framework.util.StringUtil;
+import com.supwisdom.dlpay.medicine.dao.HospitalRepository;
+import com.supwisdom.dlpay.medicine.domain.TBHospital;
+import org.hibernate.transform.Transformers;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class HospitalRepositoryImpl extends BaseRepository implements HospitalRepository {
+  @NotNull
+  @Override
+  public Pagination getHospitalList(int pageno, int pageSize, @Nullable String name) {
+    StringBuilder sql = new StringBuilder("select * from th_hospital where status='normal'");
+    if (!StringUtil.isEmpty(name)) {
+      sql.append(" and name like :name");
+    }
+    sql.append(" order by hospitalcode");
+    Finder f = Finder.create(sql.toString());
+    if (!StringUtil.isEmpty(name)) {
+      f.setParameter("name", "%" + name.trim() + "%");
+    }
+    return findNative(f, Transformers.aliasToBean(TBHospital.class), pageno, pageSize);
+  }
+}
diff --git a/backend/src/main/java/com/supwisdom/dlpay/medicine/domain/TBAppointmentDtl.java b/backend/src/main/java/com/supwisdom/dlpay/medicine/domain/TBAppointmentDtl.java
new file mode 100644
index 0000000..786fa09
--- /dev/null
+++ b/backend/src/main/java/com/supwisdom/dlpay/medicine/domain/TBAppointmentDtl.java
@@ -0,0 +1,146 @@
+package com.supwisdom.dlpay.medicine.domain;
+
+import org.hibernate.annotations.GenericGenerator;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "th_appointmentdtl", indexes = {@Index(name = "appointment_idx", columnList = "uid")})
+public class TBAppointmentDtl {
+  @Id
+  @GenericGenerator(name = "idGenerator", strategy = "uuid")
+  @GeneratedValue(generator = "idGenerator")
+  @Column(name = "id", nullable = false, length = 32)
+  private String id;
+  @Column(name = "organizationid", length = 30)
+  private String organizationid;
+  @Column(name = "departmentid", length = 64)
+  private String departmentid;
+  @Column(name = "departmentname", length = 30)
+  private String departmentname;
+  @Column(name = "ghrq")
+  private Integer ghrq;
+  @Column(name = "zblb")
+  private Integer zblb;
+  @Column(name = "patientid", length = 64)
+  private String patientid;
+  @Column(name = "patientname", length = 20)
+  private String patientname;
+  @Column(name = "patientmobile", length = 30)
+  private String patientmobile;
+  /**
+   * 医院的挂号序号
+   */
+  @Column(name = "serialnumber")
+  private Integer serialnumber;
+  @Column(name = "createdate", length = 14)
+  private String createdate;
+  @Column(name = "uid", length = 32)
+  private String uid;
+  @Column(name = "delete")
+  private Boolean delete;
+
+  public String getId() {
+    return id;
+  }
+
+  public void setId(String id) {
+    this.id = id;
+  }
+
+  public String getOrganizationid() {
+    return organizationid;
+  }
+
+  public void setOrganizationid(String organizationid) {
+    this.organizationid = organizationid;
+  }
+
+  public String getDepartmentid() {
+    return departmentid;
+  }
+
+  public void setDepartmentid(String departmentid) {
+    this.departmentid = departmentid;
+  }
+
+  public String getDepartmentname() {
+    return departmentname;
+  }
+
+  public void setDepartmentname(String departmentname) {
+    this.departmentname = departmentname;
+  }
+
+  public Integer getGhrq() {
+    return ghrq;
+  }
+
+  public void setGhrq(Integer ghrq) {
+    this.ghrq = ghrq;
+  }
+
+  public Integer getZblb() {
+    return zblb;
+  }
+
+  public void setZblb(Integer zblb) {
+    this.zblb = zblb;
+  }
+
+  public String getPatientid() {
+    return patientid;
+  }
+
+  public void setPatientid(String patientid) {
+    this.patientid = patientid;
+  }
+
+  public String getPatientname() {
+    return patientname;
+  }
+
+  public void setPatientname(String patientname) {
+    this.patientname = patientname;
+  }
+
+  public String getPatientmobile() {
+    return patientmobile;
+  }
+
+  public void setPatientmobile(String patientmobile) {
+    this.patientmobile = patientmobile;
+  }
+
+  public Integer getSerialnumber() {
+    return serialnumber;
+  }
+
+  public void setSerialnumber(Integer serialnumber) {
+    this.serialnumber = serialnumber;
+  }
+
+  public String getCreatedate() {
+    return createdate;
+  }
+
+  public void setCreatedate(String createdate) {
+    this.createdate = createdate;
+  }
+
+  public String getUid() {
+    return uid;
+  }
+
+  public void setUid(String uid) {
+    this.uid = uid;
+  }
+
+  public Boolean getDelete() {
+    return delete;
+  }
+
+  public void setDelete(Boolean delete) {
+    this.delete = delete;
+  }
+}
diff --git a/backend/src/main/java/com/supwisdom/dlpay/medicine/domain/TBHospital.java b/backend/src/main/java/com/supwisdom/dlpay/medicine/domain/TBHospital.java
new file mode 100644
index 0000000..44751d6
--- /dev/null
+++ b/backend/src/main/java/com/supwisdom/dlpay/medicine/domain/TBHospital.java
@@ -0,0 +1,121 @@
+package com.supwisdom.dlpay.medicine.domain;
+
+import org.hibernate.annotations.GenericGenerator;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "th_hospital", indexes = {@Index(name = "hospital_idx", columnList = "hospitalcode", unique = true)})
+public class TBHospital {
+  @Id
+  @GenericGenerator(name = "idGenerator", strategy = "uuid")
+  @GeneratedValue(generator = "idGenerator")
+  @Column(name = "id", nullable = false, length = 32)
+  private String id;
+
+  @Column(name = "name", length = 50)
+  private String name;
+
+  @Column(name = "address", length = 200)
+  private String address;
+
+  @Column(name = "hospitalcode", length = 30)
+  private String hospitalcode;
+
+  @Column(name = "time", length = 50)
+  private String time;
+
+  @Column(name = "tel", length = 30)
+  private String tel;
+
+  @Column(name = "level", length = 10)
+  private String level;
+
+  @Column(name = "status", length = 10)
+  private String status;
+
+  @Column(name = "picid", length = 32)
+  private String picid;
+  @Column(name = "minpicid", length = 32)
+  private String minpicid;
+
+  public String getId() {
+    return id;
+  }
+
+  public void setId(String id) {
+    this.id = id;
+  }
+
+  public String getAddress() {
+    return address;
+  }
+
+  public void setAddress(String address) {
+    this.address = address;
+  }
+
+  public String getHospitalcode() {
+    return hospitalcode;
+  }
+
+  public void setHospitalcode(String hospitalcode) {
+    this.hospitalcode = hospitalcode;
+  }
+
+  public String getTime() {
+    return time;
+  }
+
+  public void setTime(String time) {
+    this.time = time;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+  public String getLevel() {
+    return level;
+  }
+
+  public void setLevel(String level) {
+    this.level = level;
+  }
+
+  public String getStatus() {
+    return status;
+  }
+
+  public void setStatus(String status) {
+    this.status = status;
+  }
+
+  public String getTel() {
+    return tel;
+  }
+
+  public void setTel(String tel) {
+    this.tel = tel;
+  }
+
+  public String getPicid() {
+    return picid;
+  }
+
+  public void setPicid(String picid) {
+    this.picid = picid;
+  }
+
+  public String getMinpicid() {
+    return minpicid;
+  }
+
+  public void setMinpicid(String minpicid) {
+    this.minpicid = minpicid;
+  }
+}
diff --git a/backend/src/main/java/com/supwisdom/dlpay/medicine/domain/TBMedicalCard.java b/backend/src/main/java/com/supwisdom/dlpay/medicine/domain/TBMedicalCard.java
new file mode 100644
index 0000000..cbc0f83
--- /dev/null
+++ b/backend/src/main/java/com/supwisdom/dlpay/medicine/domain/TBMedicalCard.java
@@ -0,0 +1,168 @@
+package com.supwisdom.dlpay.medicine.domain;
+
+import org.hibernate.annotations.GenericGenerator;
+
+import javax.persistence.*;
+import java.util.Date;
+
+@Entity
+@Table(name = "th_medical_card", indexes = {@Index(name = "medicalcard_idx", columnList = "uid")})
+public class TBMedicalCard {
+  @Id
+  @GenericGenerator(name = "idGenerator", strategy = "uuid")
+  @GeneratedValue(generator = "idGenerator")
+  @Column(name = "cardid", nullable = false, length = 32)
+  private String cardid;
+  /**
+   * 手机用户id
+   */
+  @Column(name = "uid", nullable = false, length = 32)
+  private String uid;
+  /**
+   * 证件号码
+   */
+  @Column(name = "cardnumber", nullable = false, length = 18)
+  private String cardnumber;
+  /**
+   * 证件类型
+   */
+  @Column(name = "cardtype", nullable = false, length = 2)
+  private Integer cardtype;
+  /**
+   * 患者id
+   */
+  @Column(name = "patientid", nullable = false, length = 64)
+  private String patientid;
+  /**
+   * 姓名
+   */
+  @Column(name = "patientname", length = 50)
+  private String patientname;
+  /**
+   * 性别
+   */
+  @Column(name = "patientsex", length = 2)
+  private String patientsex;
+  /**
+   * 出生日期(yyyy-MM-dd HH:mm:ss)
+   */
+  @Column(name = "patientbirthday")
+  private Date patientbirthday;
+  /**
+   * 医院预留手机号
+   */
+  @Column(name = "patientmobile", length = 30)
+  private String patientmobile;
+  /**
+   * 医院id
+   */
+  @Column(name = "organizationid", nullable = false, length = 30)
+  private String organizationid;
+  /**
+   * 就诊卡类型
+   */
+  @Column(name = "medicalcardtype", length = 2)
+  private Integer medicalcardtype;
+  /**
+   * 就诊卡号码
+   */
+  @Column(name = "medicalcardnumber", length = 64)
+  private String medicalcardnumber;
+
+  public String getCardid() {
+    return cardid;
+  }
+
+  public void setCardid(String cardid) {
+    this.cardid = cardid;
+  }
+
+  public String getUid() {
+    return uid;
+  }
+
+  public void setUid(String uid) {
+    this.uid = uid;
+  }
+
+  public String getCardnumber() {
+    return cardnumber;
+  }
+
+  public void setCardnumber(String cardnumber) {
+    this.cardnumber = cardnumber;
+  }
+
+  public Integer getCardtype() {
+    return cardtype;
+  }
+
+  public void setCardtype(Integer cardtype) {
+    this.cardtype = cardtype;
+  }
+
+  public String getPatientid() {
+    return patientid;
+  }
+
+  public void setPatientid(String patientid) {
+    this.patientid = patientid;
+  }
+
+  public String getPatientname() {
+    return patientname;
+  }
+
+  public void setPatientname(String patientname) {
+    this.patientname = patientname;
+  }
+
+  public String getPatientsex() {
+    return patientsex;
+  }
+
+  public void setPatientsex(String patientsex) {
+    this.patientsex = patientsex;
+  }
+
+  public Date getPatientbirthday() {
+    return patientbirthday;
+  }
+
+  public void setPatientbirthday(Date patientbirthday) {
+    this.patientbirthday = patientbirthday;
+  }
+
+  public String getPatientmobile() {
+    return patientmobile;
+  }
+
+  public void setPatientmobile(String patientmobile) {
+    this.patientmobile = patientmobile;
+  }
+
+  public String getOrganizationid() {
+    return organizationid;
+  }
+
+  public void setOrganizationid(String organizationid) {
+    this.organizationid = organizationid;
+  }
+
+  public Integer getMedicalcardtype() {
+    return medicalcardtype;
+  }
+
+  public void setMedicalcardtype(Integer medicalcardtype) {
+    this.medicalcardtype = medicalcardtype;
+  }
+
+  public String getMedicalcardnumber() {
+    return medicalcardnumber;
+  }
+
+  public void setMedicalcardnumber(String medicalcardnumber) {
+    this.medicalcardnumber = medicalcardnumber;
+  }
+}
+
diff --git a/backend/src/main/java/com/supwisdom/dlpay/medicine/util/MedicalClient.java b/backend/src/main/java/com/supwisdom/dlpay/medicine/util/MedicalClient.java
new file mode 100644
index 0000000..e6d8b7c
--- /dev/null
+++ b/backend/src/main/java/com/supwisdom/dlpay/medicine/util/MedicalClient.java
@@ -0,0 +1,94 @@
+package com.supwisdom.dlpay.medicine.util;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.TypeReference;
+import com.supwisdom.dlpay.framework.service.SystemUtilService;
+import com.supwisdom.dlpay.framework.util.StringUtil;
+import com.supwisdom.dlpay.medicine.bean.*;
+import com.supwisdom.dlpay.medicine.exception.MedicineException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.*;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Component
+public class MedicalClient {
+  @Autowired
+  private RestTemplate restTemplate;
+  @Autowired
+  private SystemUtilService systemUtilService;
+
+  public PatientInfoResponse getPatientMedicalCardList(AddPatientBean bean) {
+    String url = getMedicalUrl();
+    Map<String, Object> param = new HashMap<>(8);
+    param.put("organizationId", bean.getHospitalcode());
+    param.put("cardType", MedicalConstant.CARD_TYPE_IDCAED);
+    param.put("cardNumber", bean.getCardno());
+    param.put("patientName", bean.getName());
+    param.put("patientSex", bean.getSex());
+    String response = httpPost(url + "register/getPhoneAndCards", JSON.toJSONString(param));
+    return JSON.parseObject(response, new TypeReference<MedicalResponse<PatientInfoResponse>>() {
+    }).getData();
+  }
+
+  public MedicalCardInfoResponse getMedicalCardDetail(String organizationId, String patientId) {
+    String url = getMedicalUrl();
+    Map<String, Object> param = new HashMap<>(2);
+    param.put("organizationId", organizationId);
+    param.put("patientId", patientId);
+    String response = httpPost(url + "register/queryBusCards", JSON.toJSONString(param));
+    return JSON.parseObject(response, new TypeReference<MedicalResponse<MedicalCardInfoResponse>>() {
+    }).getData();
+  }
+
+  public List<ArrangeInfoResponse> getArrangeInfo(String organizationId, String date) {
+    String url = getMedicalUrl();
+    Map<String, Object> param = new HashMap<>(2);
+    param.put("organizationId", organizationId);
+    String response = httpPost(url + "appointment/listArrange", JSON.toJSONString(param));
+    return JSON.parseObject(response, new TypeReference<MedicalResponse<List<ArrangeInfoResponse>>>() {
+    }).getData();
+  }
+
+  public AppointmentResponse confirmAppointment(ConfirmRequestBean bean) {
+    String url = getMedicalUrl();
+    Map<String, Object> param = new HashMap<>(8);
+    param.put("organizationId", bean.getOrganizationid());
+    param.put("departmentId", bean.getDepartmentid());
+    param.put("ghrq", bean.getGhrq());
+    param.put("zblb", bean.getZblb());
+    param.put("patientId", bean.getPatientid());
+    param.put("patientName", bean.getPatientname());
+    param.put("patientMobile", bean.getPatientmobile());
+    String response = httpPost(url + "appointment/confirmAppointment", JSON.toJSONString(param));
+    return JSON.parseObject(response, new TypeReference<MedicalResponse<AppointmentResponse>>() {
+    }).getData();
+  }
+
+
+  private String getMedicalUrl() {
+    String url = systemUtilService.getBusinessValue(MedicalConstant.SYSPARA_MEDICAL_URL);
+    if (StringUtil.isEmpty(url)) {
+      throw new MedicineException("医疗系统地址未配置");
+    }
+    return url;
+  }
+
+  private String httpPost(String url, String json) {
+    HttpHeaders headers = new HttpHeaders();
+    MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
+    headers.setContentType(type);
+    headers.add("Accept", MediaType.APPLICATION_JSON.toString());
+    HttpEntity<String> formEntity = new HttpEntity<>(json, headers);
+    ResponseEntity<String> postEntity = restTemplate.postForEntity(url, formEntity, String.class);
+    if (postEntity.getStatusCode().equals(HttpStatus.OK) && postEntity.hasBody()) {
+      return postEntity.getBody();
+    } else {
+      throw new MedicineException("请求医疗系统异常");
+    }
+  }
+}
diff --git a/backend/src/main/java/com/supwisdom/dlpay/medicine/util/MedicalConstant.java b/backend/src/main/java/com/supwisdom/dlpay/medicine/util/MedicalConstant.java
new file mode 100644
index 0000000..1f5e7a8
--- /dev/null
+++ b/backend/src/main/java/com/supwisdom/dlpay/medicine/util/MedicalConstant.java
@@ -0,0 +1,15 @@
+package com.supwisdom.dlpay.medicine.util;
+
+public class MedicalConstant {
+  /**
+   * 证件类型
+   */
+  public final static int CARD_TYPE_IDCAED = 1;//身份证
+  /**
+   *
+   */
+  public final static int UNPAYED_QUERYTYPE_MEDICALCARD = 3;//按诊疗卡类型查询
+
+
+  public static final String SYSPARA_MEDICAL_URL = "medical.url";
+}
diff --git a/backend/src/main/java/com/supwisdom/dlpay/medicine/util/MedicalResponse.java b/backend/src/main/java/com/supwisdom/dlpay/medicine/util/MedicalResponse.java
new file mode 100644
index 0000000..2d83be9
--- /dev/null
+++ b/backend/src/main/java/com/supwisdom/dlpay/medicine/util/MedicalResponse.java
@@ -0,0 +1,31 @@
+package com.supwisdom.dlpay.medicine.util;
+
+public class MedicalResponse<T> {
+  private int code;
+  private String message;
+  private T data;
+
+  public int getCode() {
+    return code;
+  }
+
+  public void setCode(int code) {
+    this.code = code;
+  }
+
+  public String getMessage() {
+    return message;
+  }
+
+  public void setMessage(String message) {
+    this.message = message;
+  }
+
+  public T getData() {
+    return data;
+  }
+
+  public void setData(T data) {
+    this.data = data;
+  }
+}
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/user_service_impl.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/user_service_impl.kt
index ae8b3fd..2509939 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/user_service_impl.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/user_service_impl.kt
@@ -122,7 +122,7 @@
                 user.lastsignintime = hostDateTime
                 mobileUserDao.save(user)
             } else {
-                return JsonResult.error(500,"签到时间异常")
+                return JsonResult.error(500,"今日已签到,无须重复操作")
             }
         }else{
             user.lastsignintime = hostDateTime
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/MedicineApi.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/MedicineApi.kt
new file mode 100644
index 0000000..5635ee4
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/MedicineApi.kt
@@ -0,0 +1,153 @@
+package com.supwisdom.dlpay.medicine
+
+import com.supwisdom.dlpay.api.bean.JsonResult
+import com.supwisdom.dlpay.medicine.bean.AddPatientBean
+import com.supwisdom.dlpay.medicine.bean.ConfirmRequestBean
+import com.supwisdom.dlpay.medicine.exception.MedicineException
+import com.supwisdom.dlpay.medicine.service.MedicineService
+import com.supwisdom.dlpay.mobile.service.MobileApiService
+import mu.KotlinLogging
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.security.core.context.SecurityContextHolder
+import org.springframework.web.bind.annotation.*
+
+@RestController
+@RequestMapping("/mobileapi/medicineapi")
+class MedicineApi {
+    @Autowired
+    lateinit var medicineService: MedicineService
+    @Autowired
+    lateinit var mobileApiService: MobileApiService
+
+    val logger = KotlinLogging.logger { }
+
+    @RequestMapping("/test")
+    fun test(): JsonResult {
+        return JsonResult.ok("测试")
+    }
+
+    /**
+     * 查询医院列表
+     */
+    @GetMapping("/hospital/list")
+    fun getHospitalList(pageno: Int, pagesize: Int, name: String?): JsonResult? {
+        val data = medicineService.getHospitalList(pageno, pagesize, name)
+        return JsonResult.ok().put("data", data)
+    }
+
+    /**
+     * 获取医院下的就诊卡
+     */
+    @GetMapping("/medicalcard")
+    fun getMedicalCardList(hospitalcode: String): JsonResult? {
+        val p = SecurityContextHolder.getContext().authentication
+        val user = mobileApiService.findUserById(p.name)
+                ?: return JsonResult.error("用户不存在,请注册")
+        val data = medicineService.getMedicalCardList(user.uid, hospitalcode)
+        return JsonResult.ok().put("data", data)
+    }
+
+    /**
+     * 删除就诊卡
+     */
+    @PostMapping("/medicalcard/delete/{cardid}")
+    fun deleteMedicalCard(hospitalcode: String, @PathVariable cardid: String): JsonResult? {
+        try {
+            val p = SecurityContextHolder.getContext().authentication
+            val user = mobileApiService.findUserById(p.name)
+                    ?: return JsonResult.error("用户不存在,请注册")
+            medicineService.deleteMedicalCard(user.uid, cardid)
+            return JsonResult.ok()
+        } catch (e: MedicineException) {
+            logger.error(e.message)
+            return JsonResult.error(e.message)
+        }
+    }
+
+    /**
+     * 添加就诊人
+     */
+    @PostMapping("/medicalcard/add")
+    fun addPatient(@RequestBody bean: AddPatientBean): JsonResult? {
+        try {
+            val p = SecurityContextHolder.getContext().authentication
+            val user = mobileApiService.findUserById(p.name)
+                    ?: return JsonResult.error("用户不存在,请注册")
+            bean.uid = user.uid
+            medicineService.addPatient(bean)
+            return JsonResult.ok()
+        } catch (e: Exception) {
+            logger.error(e.message)
+            return JsonResult.error("系统异常,请稍后重试")
+        }
+    }
+
+    /**
+     * 获取某日的排班日期
+     */
+    @GetMapping("/arrange/info/{hospitalcode}")
+    fun addPatient(date: String, @PathVariable hospitalcode: String): JsonResult? {
+        return try {
+            val data = medicineService.getArrangeInfo(hospitalcode, date)
+            JsonResult.ok().put("data", data)
+        } catch (e: Exception) {
+            logger.error(e.message)
+            JsonResult.error("系统异常,请稍后重试")
+        }
+    }
+
+    /**
+     * 挂号提交
+     */
+    @PostMapping("/appointment/confirm")
+    fun confirmAppointment(@RequestBody bean: ConfirmRequestBean): JsonResult? {
+        val p = SecurityContextHolder.getContext().authentication
+        val user = mobileApiService.findUserById(p.name)
+                ?: return JsonResult.error("用户不存在,请注册")
+        bean.uid = user.uid
+        medicineService.confirmAppointment(bean)
+        return JsonResult.ok()
+    }
+
+    /**
+     * 查询挂号记录
+     */
+    @PostMapping("/appointment/list")
+    fun getAppointmentList(pageno: Int, pagesize: Int): JsonResult? {
+        val p = SecurityContextHolder.getContext().authentication
+        val user = mobileApiService.findUserById(p.name)
+                ?: return JsonResult.error("用户不存在,请注册")
+        val data = medicineService.getAppointmentList(pageno, pagesize, user.uid)
+        return JsonResult.ok().put("data", data)
+    }
+
+    /**
+     * 删除挂号记录
+     */
+    @PostMapping("/appointment/delete/{appointmentid}")
+    fun getAppointmentList(@PathVariable appointmentid: String): JsonResult? {
+        try {
+            val p = SecurityContextHolder.getContext().authentication
+            val user = mobileApiService.findUserById(p.name)
+                    ?: return JsonResult.error("用户不存在,请注册")
+            val data = medicineService.deleteAppointment(appointmentid, user.uid)
+            return JsonResult.ok().put("data", data)
+        } catch (e: MedicineException) {
+            logger.error(e.message)
+            return JsonResult.error(e.message)
+        }
+    }
+
+    /**
+     * 获取待支付列表
+     */
+    @GetMapping("/unpayed/list")
+    fun getUnpayedList(): JsonResult? {
+        val p = SecurityContextHolder.getContext().authentication
+        val user = mobileApiService.findUserById(p.name)
+                ?: return JsonResult.error("用户不存在,请注册")
+        medicineService.getUnpayedList(user.uid)
+        return JsonResult.ok()
+    }
+
+}
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/bean/AddPatientBean.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/bean/AddPatientBean.kt
new file mode 100644
index 0000000..5891c12
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/bean/AddPatientBean.kt
@@ -0,0 +1,10 @@
+package com.supwisdom.dlpay.medicine.bean
+
+class AddPatientBean {
+    var name = ""
+    var sex = ""
+    var cardno = ""
+    var tel = ""
+    var hospitalcode = ""
+    var uid = ""
+}
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/bean/AppointmentResponse.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/bean/AppointmentResponse.kt
new file mode 100644
index 0000000..4e5c63d
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/bean/AppointmentResponse.kt
@@ -0,0 +1,7 @@
+package com.supwisdom.dlpay.medicine.bean
+
+class AppointmentResponse {
+    var organizationId = ""
+    var serialNumber = 0
+    var patientId = ""
+}
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/bean/ArrangeInfoResponse.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/bean/ArrangeInfoResponse.kt
new file mode 100644
index 0000000..c8928d4
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/bean/ArrangeInfoResponse.kt
@@ -0,0 +1,10 @@
+package com.supwisdom.dlpay.medicine.bean
+
+class ArrangeInfoResponse {
+    var departmentId = ""
+    var departmentName = ""
+    var ygrs = ""
+    var ghrq = ""
+    var zblb = ""
+    var syrs = ""
+}
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/bean/ConfirmRequestBean.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/bean/ConfirmRequestBean.kt
new file mode 100644
index 0000000..b8ccbcc
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/bean/ConfirmRequestBean.kt
@@ -0,0 +1,13 @@
+package com.supwisdom.dlpay.medicine.bean
+
+class ConfirmRequestBean {
+    var organizationid = ""
+    var departmentid = ""
+    var departmentname = ""
+    var ghrq = 0
+    var zblb = 0
+    var patientid = ""
+    var patientname = ""
+    var patientmobile = ""
+    var uid = ""
+}
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/bean/MedicalCardBean.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/bean/MedicalCardBean.kt
new file mode 100644
index 0000000..bb69e00
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/bean/MedicalCardBean.kt
@@ -0,0 +1,8 @@
+package com.supwisdom.dlpay.medicine.bean
+
+class MedicalCardBean {
+    var patientMedicalCardNumber = ""
+    var patientMedicalCardType = 0
+    var patientId = ""
+    var patientNature = ""
+}
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/bean/MedicalCardInfoResponse.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/bean/MedicalCardInfoResponse.kt
new file mode 100644
index 0000000..62a566f
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/bean/MedicalCardInfoResponse.kt
@@ -0,0 +1,13 @@
+package com.supwisdom.dlpay.medicine.bean
+
+import java.util.*
+
+class MedicalCardInfoResponse {
+    var patientName = ""
+    var patientId = ""
+    var patientSex = ""
+    var patientBirthday = Date()
+    var patientMobile = ""
+    var patientMedicalCardType = 0
+    var patientMedicalCardNumber = ""
+}
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/bean/PatientInfoResponse.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/bean/PatientInfoResponse.kt
new file mode 100644
index 0000000..7c81700
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/bean/PatientInfoResponse.kt
@@ -0,0 +1,6 @@
+package com.supwisdom.dlpay.medicine.bean
+
+class PatientInfoResponse {
+    var patientMobile = ""
+    var listMedicalCard = ArrayList<MedicalCardBean>()
+}
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/dao/AppointmentDtlDao.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/dao/AppointmentDtlDao.kt
new file mode 100644
index 0000000..ed1f13c
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/dao/AppointmentDtlDao.kt
@@ -0,0 +1,8 @@
+package com.supwisdom.dlpay.medicine.dao
+
+import com.supwisdom.dlpay.medicine.domain.TBAppointmentDtl
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface AppointmentDtlDao : JpaRepository<TBAppointmentDtl, String>, AppointmentRepository {
+    fun findByIdAndUidAndDelete(id: String, uid: String, delete: Boolean): TBAppointmentDtl?
+}
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/dao/AppointmentRepository.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/dao/AppointmentRepository.kt
new file mode 100644
index 0000000..c91f877
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/dao/AppointmentRepository.kt
@@ -0,0 +1,7 @@
+package com.supwisdom.dlpay.medicine.dao
+
+import com.supwisdom.dlpay.framework.jpa.page.Pagination
+
+interface AppointmentRepository {
+    fun getAppointmentList(pageno: Int, pagesize: Int, uid: String): Pagination
+}
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/dao/HospitalDao.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/dao/HospitalDao.kt
new file mode 100644
index 0000000..8e05468
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/dao/HospitalDao.kt
@@ -0,0 +1,8 @@
+package com.supwisdom.dlpay.medicine.dao
+
+import com.supwisdom.dlpay.medicine.domain.TBHospital
+import org.springframework.data.jpa.repository.JpaRepository
+import org.springframework.stereotype.Repository
+
+@Repository
+interface HospitalDao : JpaRepository<TBHospital, String>, HospitalRepository
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/dao/HospitalRepository.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/dao/HospitalRepository.kt
new file mode 100644
index 0000000..fe14f04
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/dao/HospitalRepository.kt
@@ -0,0 +1,7 @@
+package com.supwisdom.dlpay.medicine.dao
+
+import com.supwisdom.dlpay.framework.jpa.page.Pagination
+
+interface HospitalRepository {
+    fun getHospitalList(pageno: Int, pageSize: Int, name: String?): Pagination
+}
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/dao/MedicalCardDao.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/dao/MedicalCardDao.kt
new file mode 100644
index 0000000..5d43e44
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/dao/MedicalCardDao.kt
@@ -0,0 +1,12 @@
+package com.supwisdom.dlpay.medicine.dao
+
+import com.supwisdom.dlpay.medicine.domain.TBMedicalCard
+import org.springframework.data.jpa.repository.JpaRepository
+import org.springframework.stereotype.Repository
+
+@Repository
+interface MedicalCardDao : JpaRepository<TBMedicalCard, String> {
+    fun findByUidAndOrganizationid(uid: String, organizationid: String): List<TBMedicalCard>?
+    fun findByCardidAndUid(cardid: String, uid: String): TBMedicalCard?
+    fun findByUidAndOrganizationidAndCardnumberAndCardtype(uid: String, organizationid: String, cardnumber: String, cardtype: Int): List<TBMedicalCard>?
+}
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/exception/MedicineException.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/exception/MedicineException.kt
new file mode 100644
index 0000000..60c422c
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/exception/MedicineException.kt
@@ -0,0 +1,5 @@
+package com.supwisdom.dlpay.medicine.exception
+
+import java.lang.RuntimeException
+
+class MedicineException(msg: String) : RuntimeException(msg)
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/service/MedicineService.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/service/MedicineService.kt
new file mode 100644
index 0000000..bdf627d
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/service/MedicineService.kt
@@ -0,0 +1,37 @@
+package com.supwisdom.dlpay.medicine.service
+
+import com.supwisdom.dlpay.framework.jpa.page.Pagination
+import com.supwisdom.dlpay.medicine.bean.AddPatientBean
+import com.supwisdom.dlpay.medicine.bean.ArrangeInfoResponse
+import com.supwisdom.dlpay.medicine.bean.ConfirmRequestBean
+import com.supwisdom.dlpay.medicine.domain.TBMedicalCard
+import org.springframework.transaction.annotation.Transactional
+
+interface MedicineService {
+    @Transactional(readOnly = true)
+    fun getHospitalList(pageno: Int, pageSize: Int, name: String?): Pagination
+
+    @Transactional(readOnly = true)
+    fun getMedicalCardList(uid: String, hospitalcode: String): List<TBMedicalCard>?
+
+    @Transactional
+    fun deleteMedicalCard(uid: String, cardid: String)
+
+    @Transactional
+    fun addPatient(bean: AddPatientBean)
+
+    @Transactional(readOnly = true)
+    fun getArrangeInfo(organizationid: String, date: String): List<ArrangeInfoResponse>
+
+    @Transactional
+    fun confirmAppointment(bean: ConfirmRequestBean)
+
+    @Transactional(readOnly = true)
+    fun getAppointmentList(pageno: Int, pagesize: Int, uid: String): Pagination
+
+    @Transactional
+    fun deleteAppointment(appointmentId: String, uid: String)
+
+    @Transactional(readOnly = true)
+    fun getUnpayedList(uid: String)
+}
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/service/impl/MedicineServiceImpl.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/service/impl/MedicineServiceImpl.kt
new file mode 100644
index 0000000..488bc9c
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/medicine/service/impl/MedicineServiceImpl.kt
@@ -0,0 +1,145 @@
+package com.supwisdom.dlpay.medicine.service.impl
+
+import com.supwisdom.dlpay.framework.jpa.page.Pagination
+import com.supwisdom.dlpay.framework.service.SystemUtilService
+import com.supwisdom.dlpay.framework.util.StringUtil
+import com.supwisdom.dlpay.medicine.bean.*
+import com.supwisdom.dlpay.medicine.dao.AppointmentDtlDao
+import com.supwisdom.dlpay.medicine.dao.HospitalDao
+import com.supwisdom.dlpay.medicine.dao.MedicalCardDao
+import com.supwisdom.dlpay.medicine.domain.TBAppointmentDtl
+import com.supwisdom.dlpay.medicine.domain.TBMedicalCard
+import com.supwisdom.dlpay.medicine.exception.MedicineException
+import com.supwisdom.dlpay.medicine.service.MedicineService
+import com.supwisdom.dlpay.medicine.util.MedicalClient
+import com.supwisdom.dlpay.medicine.util.MedicalConstant
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.stereotype.Service
+
+@Service
+class MedicineServiceImpl : MedicineService {
+    @Autowired
+    lateinit var hospitalDao: HospitalDao
+    @Autowired
+    lateinit var medicalCardDao: MedicalCardDao
+    @Autowired
+    lateinit var systemUtilService: SystemUtilService
+    @Autowired
+    lateinit var appointmentDtlDao: AppointmentDtlDao
+    @Autowired
+    lateinit var medicalClient: MedicalClient
+
+    override fun getHospitalList(pageno: Int, pageSize: Int, name: String?): Pagination {
+        return hospitalDao.getHospitalList(pageno, pageSize, name)
+    }
+
+    override fun getMedicalCardList(uid: String, hospitalcode: String): List<TBMedicalCard>? {
+        return medicalCardDao.findByUidAndOrganizationid(uid, hospitalcode)
+    }
+
+    override fun deleteMedicalCard(uid: String, cardid: String) {
+        val medicalCard = medicalCardDao.findByCardidAndUid(cardid, uid)
+                ?: throw MedicineException("未找到该就诊卡")
+        medicalCardDao.delete(medicalCard)
+    }
+
+    override fun addPatient(bean: AddPatientBean) {
+        //  查询当前就诊人在该医院的就诊卡列表
+        val response = medicalClient.getPatientMedicalCardList(bean)
+        val list = response.listMedicalCard
+        if (!list.isNullOrEmpty()) {
+            //  已有就诊卡:查询详情后本地保存
+            //  删除本地该患者原有就诊卡
+            val localCard = medicalCardDao.findByUidAndOrganizationidAndCardnumberAndCardtype(
+                    bean.uid, bean.hospitalcode, bean.cardno, MedicalConstant.CARD_TYPE_IDCAED)
+            if (!localCard.isNullOrEmpty()) {
+                medicalCardDao.deleteAll(localCard)
+            }
+            list.forEach {
+                val detailResponse = medicalClient.getMedicalCardDetail(bean.hospitalcode, it.patientId)
+                val medicalCard = TBMedicalCard().apply {
+                    this.cardnumber = bean.cardno
+                    this.cardtype = MedicalConstant.CARD_TYPE_IDCAED
+                    this.medicalcardnumber = detailResponse.patientMedicalCardNumber
+                    this.medicalcardtype = detailResponse.patientMedicalCardType
+                    this.organizationid = bean.hospitalcode
+                    this.patientbirthday = detailResponse.patientBirthday
+                    this.patientid = detailResponse.patientId
+                    this.patientname = detailResponse.patientName
+                    this.patientsex = detailResponse.patientSex
+                    this.uid = bean.uid
+                    if (!StringUtil.isEmpty(detailResponse.patientMobile)) {
+                        this.patientmobile = detailResponse.patientMobile
+                    } else {
+                        this.patientmobile = response.patientMobile
+                    }
+                }
+                medicalCardDao.save(medicalCard)
+            }
+        } else {
+            //  无就诊卡,在HIS中新建,成功后本地保存
+            val addResponse = medicalClient.getPatientMedicalCardList(bean)
+            val addList = addResponse.listMedicalCard
+            if (!addList.isNullOrEmpty()) {
+                //  删除本地该患者原有就诊卡
+                val localCard = medicalCardDao.findByUidAndOrganizationidAndCardnumberAndCardtype(
+                        bean.uid, bean.hospitalcode, bean.cardno, MedicalConstant.CARD_TYPE_IDCAED)
+                if (!localCard.isNullOrEmpty()) {
+                    medicalCardDao.deleteAll(localCard)
+                }
+                addList.forEach {
+                    val medicalCard = TBMedicalCard().apply {
+                        this.cardnumber = bean.cardno
+                        this.cardtype = MedicalConstant.CARD_TYPE_IDCAED
+                        this.medicalcardnumber = it.patientMedicalCardNumber
+                        this.medicalcardtype = it.patientMedicalCardType
+                        this.organizationid = bean.hospitalcode
+                        this.patientid = it.patientId
+                        this.patientname = bean.name
+                        this.patientsex = bean.sex
+                        this.uid = bean.uid
+                        this.patientmobile = addResponse.patientMobile
+                    }
+                    medicalCardDao.save(medicalCard)
+                }
+            }
+        }
+    }
+
+    override fun getArrangeInfo(organizationid: String, date: String): List<ArrangeInfoResponse> {
+        return medicalClient.getArrangeInfo(organizationid, date)
+    }
+
+    override fun confirmAppointment(bean: ConfirmRequestBean) {
+        val appointmentResponse = medicalClient.confirmAppointment(bean)
+        val appointmentDtl = TBAppointmentDtl()
+        appointmentDtl.uid = bean.uid
+        appointmentDtl.organizationid = appointmentResponse.organizationId
+        appointmentDtl.departmentid = bean.departmentid
+        appointmentDtl.departmentname = bean.departmentname
+        appointmentDtl.ghrq = bean.ghrq
+        appointmentDtl.zblb = bean.zblb
+        appointmentDtl.patientid = bean.patientid
+        appointmentDtl.patientname = bean.patientname
+        appointmentDtl.patientmobile = bean.patientmobile
+        appointmentDtl.serialnumber = appointmentResponse.serialNumber
+        appointmentDtl.createdate = systemUtilService.sysdatetime.hostdatetime
+        appointmentDtl.delete = false
+        appointmentDtlDao.save(appointmentDtl)
+    }
+
+    override fun getAppointmentList(pageno: Int, pagesize: Int, uid: String): Pagination {
+        return appointmentDtlDao.getAppointmentList(pageno, pagesize, uid)
+    }
+
+    override fun deleteAppointment(appointmentId: String, uid: String) {
+        val appointmentDtl = appointmentDtlDao.findByIdAndUidAndDelete(appointmentId, uid, false)
+                ?: throw MedicineException("未找到该条就诊记录")
+        appointmentDtl.delete = true
+        appointmentDtlDao.save(appointmentDtl)
+    }
+
+    override fun getUnpayedList(uid: String) {
+        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+    }
+}
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/mobile/AuthLoginHandler.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/mobile/AuthLoginHandler.kt
index 04af1ff..67a5d81 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/mobile/AuthLoginHandler.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/mobile/AuthLoginHandler.kt
@@ -118,7 +118,7 @@
                     signed = TradeDict.STATUS_YES
                 }
             }
-            val imageUrl = systemUtilService.getBusinessValue(PortalConstant.SYSPARA_IMAGE_URLPUSH)
+            val imageUrl = systemUtilService.getBusinessValue(PortalConstant.SYSPARA_IMAGESERVER_URL)
             response.status = HttpStatus.OK.value()
             response.contentType = "application/json;charset=UTF-8"
             response.writer.write(objectMapper.writeValueAsString(JsonResult.ok()
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/PortalApi.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/PortalApi.kt
index 867748c..a970849 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/PortalApi.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/PortalApi.kt
@@ -104,7 +104,7 @@
             val role = operatorDetailService.findRoleById(oper.roleid)
                     ?: return JsonResult.error("操作员的角色不存在")
             val data = HashMap<String, String>()
-            val url = systemUtilService.getBusinessValue(PortalConstant.SYSPARA_IMAGE_URLPUSH)
+            val url = systemUtilService.getBusinessValue(PortalConstant.SYSPARA_IMAGESERVER_URL)
             val mapKey = systemUtilService.getBusinessValue(PortalConstant.SYSPARA_PORTAL_AMAPKEY)
             val mapUrl = systemUtilService.getBusinessValue(PortalConstant.SYSPARA_PORTAL_AMAPURL)
             data["name"] = oper.opername
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/Impl/ColumnServiceImpl.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/Impl/ColumnServiceImpl.kt
index 787fb15..6985f35 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/Impl/ColumnServiceImpl.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/Impl/ColumnServiceImpl.kt
@@ -37,7 +37,7 @@
     }
 
     override fun getAllBanner(): List<TBBanner> {
-        val url = systemUtilService.getBusinessValue(PortalConstant.SYSPARA_IMAGE_URLPUSH)
+        val url = systemUtilService.getBusinessValue(PortalConstant.SYSPARA_IMAGESERVER_URL)
         if (StringUtil.isEmpty(url)) {
             logger.error { "图片服务器地址未配置" }
             return emptyList()
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/security.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/security.kt
index 0d67838..716dd2d 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/security.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/security.kt
@@ -158,56 +158,62 @@
         }
         logger.info(url)
         val authHeader:String? = request.getHeader(jwtConfig.header)
-        if (!authHeader.isNullOrEmpty()) {
-            try {
-                val jwt = if (authHeader.startsWith(jwtConfig.tokenHeader)) {
-                    authHeader.substring(jwtConfig.tokenHeader.length)
-                } else {
-                    throw JoseException("JWT Header error")
-                }
-                val claims = getUtil().verifyToken(jwt)
-                apiJwtRepository.findById(claims[ReservedClaimNames.JWT_ID].toString()).let {
-                    if (!it.isPresent) {
-                        throw JoseException("JWT has not been register")
+        if (url.startsWith("/mobileapi/v1")||url.startsWith("/mobileapi/medicineapi")) {
+            if (!authHeader.isNullOrEmpty()) {
+                try {
+                    val jwt = if (authHeader.startsWith(jwtConfig.tokenHeader)) {
+                        authHeader.substring(jwtConfig.tokenHeader.length)
+                    } else {
+                        throw JoseException("JWT Header error")
                     }
-                    // token 已被设为黑名单
-                    if (it.get().status != TradeDict.JWT_STATUS_NORMAL) {
-                        throw JoseException("JWT status error : ${it.get().status}")
+                    val claims = getUtil().verifyToken(jwt)
+                    apiJwtRepository.findById(claims[ReservedClaimNames.JWT_ID].toString()).let {
+                        if (!it.isPresent) {
+                            throw JoseException("JWT has not been register")
+                        }
+                        // token 已被设为黑名单
+                        if (it.get().status != TradeDict.JWT_STATUS_NORMAL) {
+                            throw JoseException("JWT status error : ${it.get().status}")
+                        }
                     }
-                }
-                if (jwtConfig.multiTenant) {
-                    val tenantId = request.getHeader(Constants.HEADER_TETANTID)
-                    if (tenantId == null) {
-                        response.status = HttpStatus.UNAUTHORIZED.value()
-                        return
+                    if (jwtConfig.multiTenant) {
+                        val tenantId = request.getHeader(Constants.HEADER_TETANTID)
+                        if (tenantId == null) {
+                            response.status = HttpStatus.UNAUTHORIZED.value()
+                            return
+                        }
+                        if (claims[Constants.JWT_CLAIM_TENANTID] != tenantId) {
+                            response.status = HttpStatus.UNAUTHORIZED.value()
+                            return
+                        }
+                        TenantContext.setTenantSchema(tenantId)
                     }
-                    if (claims[Constants.JWT_CLAIM_TENANTID] != tenantId) {
-                        response.status = HttpStatus.UNAUTHORIZED.value()
-                        return
+                    val auth = UsernamePasswordAuthenticationToken(claims[Constants.JWT_CLAIM_UID], null,
+                            (claims[Constants.JWT_CLAIM_AUTHORITIES] as ArrayList<*>)
+                                    .map { SimpleGrantedAuthority(it as String) })
+                    SecurityContextHolder.getContext().authentication = auth
+                } catch (e: InvalidJwtException) {
+                    SecurityContextHolder.clearContext()
+                    if (e.hasExpired()) {
+                        // jwt 过期后返回 401
+                        apiJwtRepository.deleteById(e.jwtContext.jwtClaims.jwtId)
                     }
-                    TenantContext.setTenantSchema(tenantId)
+                    response.status = HttpStatus.UNAUTHORIZED.value()
+                    return
+                } catch (e: JoseException) {
+                    SecurityContextHolder.clearContext()
+                    // jwt 失效后返回 401
+                    response.status = HttpStatus.UNAUTHORIZED.value()
+                    response.contentType = "application/json;charset=UTF-8"
+                    return
+                } catch (e: Exception) {
+                    SecurityContextHolder.clearContext()
+                    // jwt 失效后返回 401
+                    response.status = HttpStatus.UNAUTHORIZED.value()
+                    response.contentType = "application/json;charset=UTF-8"
+                    return
                 }
-                val auth = UsernamePasswordAuthenticationToken(claims[Constants.JWT_CLAIM_UID], null,
-                        (claims[Constants.JWT_CLAIM_AUTHORITIES] as ArrayList<*>)
-                                .map { SimpleGrantedAuthority(it as String) })
-                SecurityContextHolder.getContext().authentication = auth
-            } catch (e: InvalidJwtException) {
-                SecurityContextHolder.clearContext()
-                if (e.hasExpired()) {
-                    // jwt 过期后返回 401
-                    apiJwtRepository.deleteById(e.jwtContext.jwtClaims.jwtId)
-                }
-                response.status = HttpStatus.UNAUTHORIZED.value()
-                return
-            } catch (e: JoseException) {
-                SecurityContextHolder.clearContext()
-                // jwt 失效后返回 401
-                response.status = HttpStatus.UNAUTHORIZED.value()
-                response.contentType = "application/json;charset=UTF-8"
-                return
-            } catch (e: Exception) {
-                SecurityContextHolder.clearContext()
-                // jwt 失效后返回 401
+            }else {
                 response.status = HttpStatus.UNAUTHORIZED.value()
                 response.contentType = "application/json;charset=UTF-8"
                 return
diff --git a/frontend/src/views/role/index.vue b/frontend/src/views/role/index.vue
index 474ba9d..3b9b50a 100644
--- a/frontend/src/views/role/index.vue
+++ b/frontend/src/views/role/index.vue
@@ -67,7 +67,7 @@
 </template>
 <script>
 import Pagination from '@/components/Pagination'
-import { getRoleList } from '@/api/operator'
+import { getRoleList } from '@/api/role'
 export default {
   name: 'Role',
   components: {