Jelajahi Sumber

销售代制单分享链接

wangxy 10 jam lalu
induk
melakukan
8178b14969

+ 29 - 0
src/api/crm/proxyOrderMsg.js

@@ -0,0 +1,29 @@
+import request from '@/utils/request'
+
+export function getLatestUnreadMsg() {
+  return request({
+    url: '/crm/proxyOrderMsg/getLatestUnread',
+    method: 'get'
+  })
+}
+
+export function getUnreadCount() {
+  return request({
+    url: '/crm/proxyOrderMsg/getUnreadCount',
+    method: 'get'
+  })
+}
+
+export function markAsRead(msgId) {
+  return request({
+    url: '/crm/proxyOrderMsg/markAsRead/' + msgId,
+    method: 'post'
+  })
+}
+
+export function markAllAsRead() {
+  return request({
+    url: '/crm/proxyOrderMsg/markAllAsRead',
+    method: 'post'
+  })
+}

+ 8 - 0
src/api/store/inquiryOrder.js

@@ -136,3 +136,11 @@ export function createInquiryOrderManually(data) {
     data: data
   })
 }
+
+export function shareInquiryOrderLink(data) {
+  return request({
+    url: '/store/inquiryOrder/shareLink',
+    method: 'post',
+    data: data
+  })
+}

+ 8 - 0
src/api/store/package.js

@@ -145,3 +145,11 @@ export function addPackageOrder(data) {
     data: data
   })
 }
+
+export function sharePackageOrderLink(data) {
+  return request({
+    url: '/store/packageOrder/shareLink',
+    method: 'post',
+    data: data
+  })
+}

+ 272 - 0
src/components/ProxyOrderMsgDialog/index.vue

@@ -0,0 +1,272 @@
+<template>
+  <el-dialog
+    title="代制单下单提醒"
+    :visible.sync="visible"
+    width="480px"
+    :close-on-click-modal="false"
+    :show-close="true"
+    custom-class="proxy-order-msg-dialog"
+    @close="handleClose"
+    center
+  >
+    <div class="msg-content">
+      <div class="msg-icon proxy">
+        <i class="el-icon-s-order"></i>
+      </div>
+      <div class="msg-text">
+        <h3>{{ msgData.title }}</h3>
+        <p>{{ msgData.content }}</p>
+        <div class="msg-stats">
+          <div class="stat-item">
+            <span class="stat-label">未处理消息</span>
+            <span class="stat-value">{{ unreadCount }}条</span>
+          </div>
+          <div class="stat-item">
+            <span class="stat-label">未处理率</span>
+            <span class="stat-value percent">{{ unreadPercent }}%</span>
+          </div>
+        </div>
+        <div class="msg-time" v-if="msgData.createTime">
+          <i class="el-icon-time"></i>
+          {{ msgData.createTime }}
+        </div>
+      </div>
+    </div>
+    <span slot="footer" class="dialog-footer">
+      <el-button @click="handleKnow" size="medium">
+        <i class="el-icon-check"></i> 知道了
+      </el-button>
+      <el-button type="primary" @click="handleGoProcess" size="medium">
+        <i class="el-icon-right"></i> 去处理
+      </el-button>
+    </span>
+  </el-dialog>
+</template>
+
+<script>
+import { getLatestUnreadMsg, markAsRead } from '@/api/crm/proxyOrderMsg'
+
+export default {
+  name: 'ProxyOrderMsgDialog',
+  data() {
+    return {
+      visible: false,
+      msgData: {
+        msgId: null,
+        title: '',
+        content: '',
+        actionUrl: '',
+        createTime: ''
+      },
+      unreadCount: 0,
+      totalCount: 0
+    }
+  },
+  computed: {
+    unreadPercent() {
+      if (this.totalCount === 0) return 0
+      return Math.round((this.unreadCount / this.totalCount) * 100)
+    }
+  },
+  methods: {
+    checkNewMsg() {
+      getLatestUnreadMsg().then(res => {
+        if (res.code === 200 && res.data) {
+          if (res.data.msg) {
+            this.msgData = res.data.msg
+            this.unreadCount = res.data.unreadCount || 0
+            this.totalCount = res.data.totalCount || 0
+            this.visible = true
+          }
+        }
+      }).catch(err => {
+        console.error('获取代制单下单提醒消息失败:', err)
+      })
+    },
+    handleKnow() {
+      this.visible = false
+    },
+    handleGoProcess() {
+      if (this.msgData.msgId) {
+        markAsRead(this.msgData.msgId).then(() => {
+          this.visible = false
+          this.$emit('msg-read')
+          if (this.msgData.actionUrl) {
+            this.navigateToUrl(this.msgData.actionUrl)
+          }
+          setTimeout(() => {
+            this.checkNewMsg()
+          }, 500)
+        })
+      } else {
+        this.visible = false
+        if (this.msgData.actionUrl) {
+          this.navigateToUrl(this.msgData.actionUrl)
+        }
+      }
+    },
+    navigateToUrl(url) {
+      if (url.endsWith('/index')) {
+        url = url.slice(0, -6)
+      }
+      if (!url.startsWith('/')) {
+        url = '/' + url
+      }
+      this.$router.push(url).catch(err => {
+        console.error('路由跳转失败:', err)
+      })
+    },
+    handleClose() {
+      this.visible = false
+    },
+    show() {
+      this.checkNewMsg()
+    }
+  }
+}
+</script>
+
+<style scoped>
+.proxy-order-msg-dialog {
+  border-radius: 12px;
+  overflow: hidden;
+}
+
+.msg-content {
+  display: flex;
+  align-items: flex-start;
+  padding: 24px 16px;
+}
+
+.msg-icon {
+  flex-shrink: 0;
+  width: 56px;
+  height: 56px;
+  border-radius: 50%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-right: 20px;
+  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+}
+
+.msg-icon.proxy {
+  background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
+}
+
+.msg-icon i {
+  font-size: 28px;
+  color: #fff;
+  animation: bell-ring 1s ease-in-out infinite;
+}
+
+@keyframes bell-ring {
+  0%, 100% {
+    transform: rotate(0);
+  }
+  10%, 30% {
+    transform: rotate(10deg);
+  }
+  20%, 40% {
+    transform: rotate(-10deg);
+  }
+  50% {
+    transform: rotate(0);
+  }
+}
+
+.msg-text {
+  flex: 1;
+}
+
+.msg-text h3 {
+  margin: 0 0 12px 0;
+  font-size: 18px;
+  font-weight: 600;
+  color: #303133;
+}
+
+.msg-text p {
+  margin: 0 0 12px 0;
+  font-size: 14px;
+  color: #606266;
+  line-height: 1.6;
+}
+
+.msg-stats {
+  display: flex;
+  gap: 20px;
+  margin-bottom: 12px;
+  padding: 12px;
+  background: #fef0f0;
+  border-radius: 8px;
+}
+
+.stat-item {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+
+.stat-label {
+  font-size: 12px;
+  color: #909399;
+  margin-bottom: 4px;
+}
+
+.stat-value {
+  font-size: 20px;
+  font-weight: 600;
+  color: #f5576c;
+}
+
+.stat-value.percent {
+  color: #e6a23c;
+}
+
+.msg-time {
+  font-size: 12px;
+  color: #909399;
+  display: flex;
+  align-items: center;
+}
+
+.msg-time i {
+  margin-right: 4px;
+}
+
+.dialog-footer {
+  text-align: center;
+  padding: 10px 20px 20px;
+}
+
+.dialog-footer .el-button {
+  min-width: 100px;
+}
+
+.dialog-footer .el-button i {
+  margin-right: 4px;
+}
+</style>
+
+<style>
+.proxy-order-msg-dialog .el-dialog__header {
+  background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
+  padding: 16px 20px;
+}
+
+.proxy-order-msg-dialog .el-dialog__title {
+  color: #fff;
+  font-size: 16px;
+  font-weight: 600;
+}
+
+.proxy-order-msg-dialog .el-dialog__headerbtn .el-dialog__close {
+  color: #fff;
+  font-size: 18px;
+}
+
+.proxy-order-msg-dialog .el-dialog__body {
+  padding: 0;
+}
+</style>

+ 7 - 1
src/layout/components/Navbar.vue

@@ -58,6 +58,7 @@
 
     <red-packet-balance-msg-dialog ref="redPacketBalanceMsgDialog" @msg-read="getMsgCount" />
     <order-audit-msg-dialog ref="orderAuditMsgDialog" @msg-read="getMsgCount" />
+    <proxy-order-msg-dialog ref="proxyOrderMsgDialog" @msg-read="getMsgCount" />
 
   </div>
 </template>
@@ -75,6 +76,7 @@ import msg from "@/views/crm/components/msg";
 import { getMsg,getMsgList,getMsgCount,setRead } from "@/api/crm/msg";
 import RedPacketBalanceMsgDialog from '@/components/RedPacketBalanceMsgDialog'
 import OrderAuditMsgDialog from '@/components/OrderAuditMsgDialog'
+import ProxyOrderMsgDialog from '@/components/ProxyOrderMsgDialog'
 
 export default {
   components: {
@@ -86,7 +88,8 @@ export default {
     Search,
     msg,
     RedPacketBalanceMsgDialog,
-    OrderAuditMsgDialog
+    OrderAuditMsgDialog,
+    ProxyOrderMsgDialog
   },
   computed: {
     ...mapGetters([
@@ -153,6 +156,9 @@ export default {
       if (this.$refs.orderAuditMsgDialog) {
         this.$refs.orderAuditMsgDialog.show();
       }
+      if (this.$refs.proxyOrderMsgDialog) {
+        this.$refs.proxyOrderMsgDialog.show();
+      }
     },
     getMsgCount(){
       getMsg().then(response => {

+ 1 - 84
src/views/member/mylist.vue

@@ -256,12 +256,6 @@
             type="text"
             @click="handledetails(scope.row)"
           >详情</el-button>
-          <el-button
-            size="mini"
-            type="text"
-            @click="handleCreateOrder(scope.row)"
-              v-hasPermi="['store:packageOrder:manually', 'store:inquiryOrder:manually','his:integralOrder:createByManually']"
-          >去下单</el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -358,45 +352,6 @@
       <userCoursePeriod :userIds="ids" :companyId="companyId" :companyUserId="companyUserId"/>
     </el-dialog>
 
-    <el-dialog title="选择订单类型" :visible.sync="orderTypeDialogVisible" width="500px" append-to-body>
-      <el-radio-group v-model="selectedOrderType" style="width: 100%;">
-        <el-row :gutter="20">
-          <el-col :span="8">
-            <el-card shadow="hover" :class="{'selected-card': selectedOrderType === 'package'}" @click.native="selectedOrderType = 'package'">
-              <div style="text-align: center; padding: 20px;">
-                <i class="el-icon-box" style="font-size: 40px; color: #409EFF;"></i>
-                <p style="margin-top: 10px; font-size: 16px;">套餐包订单</p>
-              </div>
-            </el-card>
-          </el-col>
-          <el-col :span="8">
-            <el-card shadow="hover" :class="{'selected-card': selectedOrderType === 'consultation'}" @click.native="selectedOrderType = 'consultation'">
-              <div style="text-align: center; padding: 20px;">
-                <i class="el-icon-chat-dot-round" style="font-size: 40px; color: #67C23A;"></i>
-                <p style="margin-top: 10px; font-size: 16px;">问诊订单</p>
-              </div>
-            </el-card>
-          </el-col>
-          <el-col :span="8">
-            <el-card shadow="hover" :class="{'selected-card': selectedOrderType === 'integral'}" @click.native="selectedOrderType = 'integral'">
-              <div style="text-align: center; padding: 20px;">
-                <i class="el-icon-coin" style="font-size: 40px; color: #E6A23C;"></i>
-                <p style="margin-top: 10px; font-size: 16px;">积分订单</p>
-              </div>
-            </el-card>
-          </el-col>
-        </el-row>
-      </el-radio-group>
-      <div slot="footer" class="dialog-footer">
-        <el-button @click="orderTypeDialogVisible = false">取 消</el-button>
-        <el-button type="primary" @click="confirmOrderType">确 定</el-button>
-      </div>
-    </el-dialog>
-
-    <package-order-dialog ref="packageOrderDialog" :userInfo="currentOrderUser" @success="handleOrderSuccess" />
-    <consultation-order-dialog ref="consultationOrderDialog" :userInfo="currentOrderUser" @success="handleOrderSuccess" />
-    <integral-order-dialog ref="integralOrderDialog" :userInfo="currentOrderUser" @success="handleOrderSuccess" />
-
 
 
   </div>
@@ -408,12 +363,9 @@ import {transferUser} from "@/api/users/user";
 import {getUserList} from "@/api/company/companyUser";
 import userDetails from '@/views/store/components/userDetails.vue';
 import userCoursePeriod from '../../components/course/userCoursePeriod.vue'
-import packageOrderDialog from './components/packageOrderDialog.vue';
-import consultationOrderDialog from './components/consultationOrderDialog.vue';
-import integralOrderDialog from './components/integralOrderDialog.vue';
 export default {
   name: "FsUser",
-  components: {userDetails,userCoursePeriod,packageOrderDialog,consultationOrderDialog,integralOrderDialog},
+  components: {userDetails,userCoursePeriod},
   data() {
     return {
 
@@ -499,9 +451,6 @@ export default {
         ]
       },
       projectOptions: [],
-      orderTypeDialogVisible: false,
-      selectedOrderType: 'package',
-      currentOrderUser: {}
     };
   },
   created() {
@@ -801,38 +750,6 @@ export default {
     },
     handleClose(){
       this.dialogVisible = false;
-    },
-    handleCreateOrder(row) {
-      this.currentOrderUser = {
-        userId: row.userId,
-        nickname: row.nickname,
-        phone: row.phone
-      };
-      this.selectedOrderType = 'package';
-      this.orderTypeDialogVisible = true;
-    },
-    confirmOrderType() {
-      if (!this.selectedOrderType) {
-        this.$message.warning('请选择订单类型');
-        return;
-      }
-      this.orderTypeDialogVisible = false;
-      this.$nextTick(() => {
-        switch (this.selectedOrderType) {
-          case 'package':
-            this.$refs.packageOrderDialog.init(this.currentOrderUser);
-            break;
-          case 'consultation':
-            this.$refs.consultationOrderDialog.init(this.currentOrderUser);
-            break;
-          case 'integral':
-            this.$refs.integralOrderDialog.init(this.currentOrderUser);
-            break;
-        }
-      });
-    },
-    handleOrderSuccess() {
-      this.getList();
     }
   }
 };

+ 263 - 0
src/views/store/user/components/consultationOrderDialog.vue

@@ -0,0 +1,263 @@
+<template>
+  <el-dialog title="创建问诊订单" :visible.sync="dialogVisible" width="1000px" append-to-body :close-on-click-modal="false" @close="handleClose">
+    <el-form ref="form" :model="form" :rules="rules" label-width="120px">
+      <el-form-item label="就诊人信息" prop="patientId">
+        <el-row>
+          <el-col>
+            <el-button plain type="primary" icon="el-icon-plus" @click="handleAddUserPatient()">添加就诊人</el-button>
+          </el-col>
+        </el-row>
+        <el-radio-group v-model="form.patientId" style="width:100%">
+          <el-table border style="margin-top:5px;" v-loading="patientLoading" :data="patientList">
+            <el-table-column label="ID" align="center">
+              <template slot-scope="scope">
+                <el-radio :label="scope.row.patientId"></el-radio>
+              </template>
+            </el-table-column>
+            <el-table-column label="患者姓名" align="center" prop="patientName" />
+            <el-table-column label="身份证号" align="center" prop="idCard" width="170px"/>
+            <el-table-column label="出生年月" align="center" prop="birthday" width="180">
+              <template slot-scope="scope">
+                <span>{{ parseTime(scope.row.birthday, '{y}-{m}-{d}') }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="性别" align="center" prop="sex">
+              <template slot-scope="scope">
+                <dict-tag :options="sexOptions" :value="scope.row.sex"/>
+              </template>
+            </el-table-column>
+            <el-table-column label="手机号" align="center" prop="mobile" />
+          </el-table>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="病情描述" prop="illnessDesc">
+        <el-input type="textarea" rows="4" v-model="form.illnessDesc" placeholder="请输入病情描述" />
+      </el-form-item>
+      <el-form-item label="订单类型" prop="orderType">
+        <el-radio-group v-model="form.orderType">
+          <el-radio label="1">图文问诊</el-radio>
+          <el-radio label="2">视频问诊</el-radio>
+          <el-radio label="3">健康咨询</el-radio>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="医生信息" prop="doctorId">
+        <el-select v-model="form.doctorId" remote filterable reserve-keyword placeholder="请选择医生" :remote-method="getDoctorList" style="width: 300px;" @change="handleDoctorChange">
+          <el-option
+            v-for="item in doctorList"
+            :key="item.doctorId"
+            :label="item.doctorName"
+            :value="item.doctorId">
+            <span style="float: left">{{ item.doctorName }}</span>
+            <span style="float: right; color: #8492a6; font-size: 13px">{{ item.deptName }}</span>
+          </el-option>
+        </el-select>
+        <el-table v-if="selectedDoctor" border style="margin-top:5px;" :data="[selectedDoctor]">
+          <el-table-column label="医生姓名" align="center" prop="doctorName" />
+          <el-table-column label="所属科室" align="center" prop="deptName" />
+          <el-table-column label="问诊费用" align="center">
+            <template slot-scope="scope">
+              <span>{{ getConsultFee(scope.row.priceJson) }}元</span>
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-form-item>
+      <el-form-item label="优惠券" prop="couponId">
+        <el-select v-model="form.couponId" placeholder="请选择优惠券" clearable style="width: 300px;" @change="handleCouponChange">
+          <el-option
+            v-for="item in couponList"
+            :key="item.couponId"
+            :label="item.title + ' - ' + item.price + '元'"
+            :value="item.couponId"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="订单备注" prop="companyUserRemark">
+        <el-input type="textarea" rows="2" v-model="form.companyUserRemark" placeholder="" />
+      </el-form-item>
+    </el-form>
+    <div v-if="shareLink" style="margin-top: 10px; padding: 10px; background: #f5f7fa; border-radius: 4px;">
+      <el-form label-width="120px">
+        <el-form-item label="分享链接">
+          <el-input v-model="shareLink" readonly style="width: 400px;">
+            <el-button slot="append" icon="el-icon-document-copy" @click="copyShareLink">复制</el-button>
+          </el-input>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div slot="footer" class="dialog-footer">
+      <el-button type="primary" @click="submitForm" :loading="submitLoading">分 享</el-button>
+      <el-button @click="handleClose">取 消</el-button>
+    </div>
+
+    <el-dialog :title="userPatient.title" v-if="userPatient.open" :visible.sync="userPatient.open" width="800px" append-to-body>
+      <add-patient ref="addPatient" @addUserPatient="addUserPatient" />
+    </el-dialog>
+  </el-dialog>
+</template>
+
+<script>
+import { listPatient } from "@/api/store/patient";
+import { shareInquiryOrderLink } from "@/api/store/inquiryOrder";
+import { getDoctorList } from "@/api/his/doctor";
+import { getUserCoupon } from "@/api/store/coupon";
+import addPatient from "@/views/store/components/addPatient";
+
+export default {
+  name: "StoreConsultationOrderDialog",
+  components: { addPatient },
+  props: {
+    userInfo: {
+      type: Object,
+      default: () => ({})
+    }
+  },
+  data() {
+    return {
+      dialogVisible: false,
+      submitLoading: false,
+      shareLink: null,
+      form: {
+        patientId: null,
+        illnessDesc: null,
+        orderType: '1',
+        doctorId: null,
+        companyUserRemark: null,
+        couponId: null
+      },
+      rules: {
+        patientId: [{ required: true, message: "请选择就诊人", trigger: "change" }],
+        illnessDesc: [{ required: true, message: "请输入病情描述", trigger: "blur" }],
+        orderType: [{ required: true, message: "请选择订单类型", trigger: "change" }],
+        doctorId: [{ required: true, message: "请选择医生", trigger: "change" }]
+      },
+      patientList: [],
+      patientLoading: false,
+      doctorList: [],
+      selectedDoctor: null,
+      couponList: [],
+      sexOptions: [],
+      userPatient: {
+        open: false,
+        title: "创建就诊人"
+      }
+    };
+  },
+  created() {
+    this.getDicts("sys_user_sex").then(response => {
+      this.sexOptions = response.data;
+    });
+  },
+  methods: {
+    init(userInfo) {
+      this.dialogVisible = true;
+      this.shareLink = null;
+      this.resetForm();
+      this.$nextTick(() => {
+        this.getPatientList(userInfo.userId);
+        this.getCouponList(userInfo.userId);
+        this.getDoctorList();
+      });
+    },
+    resetForm() {
+      this.form = {
+        patientId: null,
+        illnessDesc: null,
+        orderType: '1',
+        doctorId: null,
+        companyUserRemark: null,
+        couponId: null
+      };
+      this.selectedDoctor = null;
+      if (this.$refs.form) {
+        this.$refs.form.resetFields();
+      }
+    },
+    getPatientList(userId) {
+      var data = { userId: userId };
+      this.patientLoading = true;
+      listPatient(data).then(response => {
+        this.patientList = response.rows;
+        this.patientLoading = false;
+      });
+    },
+    getCouponList(userId) {
+      getUserCoupon({ userId: userId, couponType: 3 }).then(response => {
+        this.couponList = response.rows || [];
+      });
+    },
+    getDoctorList(query) {
+      var data = { doctorName: query, pageNum: 1, pageSize: 100 };
+      getDoctorList(data).then(response => {
+        this.doctorList = response.rows || [];
+      });
+    },
+    handleDoctorChange(doctorId) {
+      var item = this.doctorList.find(d => d.doctorId === doctorId);
+      if (item) {
+        this.selectedDoctor = item;
+      }
+    },
+    getConsultFee(priceJson) {
+      if (!priceJson) return 0;
+      try {
+        var priceList = JSON.parse(priceJson);
+        var item = priceList.find(p => p.type === parseInt(this.form.orderType));
+        return item ? item.price : 0;
+      } catch (e) {
+        return 0;
+      }
+    },
+    handleCouponChange(couponId) {
+      console.log('Selected coupon:', couponId);
+    },
+    handleAddUserPatient() {
+      this.userPatient.open = true;
+      setTimeout(() => {
+        this.$refs.addPatient.init(this.userInfo.userId);
+      }, 500);
+    },
+    addUserPatient() {
+      this.userPatient.open = false;
+      this.getPatientList(this.userInfo.userId);
+    },
+    copyShareLink() {
+      if (!this.shareLink) return;
+      var input = document.createElement('input');
+      input.value = this.shareLink;
+      document.body.appendChild(input);
+      input.select();
+      document.execCommand('copy');
+      document.body.removeChild(input);
+      this.$message.success('链接已复制');
+    },
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          var submitData = {
+            userId: this.userInfo.userId,
+            patientId: this.form.patientId,
+            title: this.form.illnessDesc,
+            orderType: this.form.orderType,
+            doctorId: this.form.doctorId,
+            companyUserRemark: this.form.companyUserRemark,
+            couponId: this.form.couponId
+          };
+          this.submitLoading = true;
+          shareInquiryOrderLink(submitData).then(response => {
+            if (response.code === 200) {
+              this.shareLink = response.shareLink || (response.data && response.data.shareLink);
+              this.$emit("success");
+            }
+          }).finally(() => {
+            this.submitLoading = false;
+          });
+        }
+      });
+    },
+    handleClose() {
+      this.dialogVisible = false;
+      this.shareLink = null;
+    }
+  }
+};
+</script>

+ 305 - 0
src/views/store/user/components/integralOrderDialog.vue

@@ -0,0 +1,305 @@
+<template>
+  <el-dialog title="创建积分订单" :visible.sync="dialogVisible" width="1000px" append-to-body :close-on-click-modal="false" @close="handleClose">
+    <el-form ref="form" :model="form" :rules="rules" label-width="120px">
+      <el-form-item label="收货信息" prop="addressId">
+        <el-row>
+          <el-col>
+            <el-button plain type="primary" icon="el-icon-plus" @click="handleAddUserAddress()">添加收货地址</el-button>
+          </el-col>
+        </el-row>
+        <el-radio-group v-model="form.addressId" style="width:100%">
+          <el-table border style="margin-top:5px;" v-loading="addressloading" :data="address">
+            <el-table-column label="ID" align="center">
+              <template slot-scope="scope">
+                <el-radio :label="scope.row.addressId"></el-radio>
+              </template>
+            </el-table-column>
+            <el-table-column label="收货人姓名" align="center" prop="realName" />
+            <el-table-column label="收货人所在省" align="center" prop="province" />
+            <el-table-column label="收货人所在市" align="center" prop="city" />
+            <el-table-column label="收货人所在区" align="center" prop="district" />
+            <el-table-column label="收货人详细地址" align="center" prop="detail" />
+          </el-table>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="商品信息" prop="goodsIds">
+        <div style="float: right;"><el-button plain type="primary" icon="el-icon-plus" @click="handleAddProduct">添加商品</el-button></div>
+        <el-table border width="100%" style="margin-top:5px;" :data="drugList">
+          <el-table-column label="商品图片" align="center" width="100">
+            <template slot-scope="scope">
+              <el-popover placement="right" title="" trigger="hover">
+                <img slot="reference" :src="scope.row.imgUrl" width="50">
+                <img :src="scope.row.imgUrl" style="max-width: 150px">
+              </el-popover>
+            </template>
+          </el-table-column>
+          <el-table-column label="商品名称" show-overflow-tooltip align="center" prop="goodsName" />
+          <el-table-column label="积分" align="center" prop="integral" />
+          <el-table-column label="金额" align="center" prop="cash">
+            <template slot-scope="scope">
+              <span v-if="scope.row.cash!=null">{{ Number(scope.row.cash).toFixed(1) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="操作" align="center" width="100px" fixed="right">
+            <template slot-scope="scope">
+              <el-button size="mini" type="text" icon="el-icon-delete" @click="handleProductDelete(scope.row)">删除</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-form-item>
+      <el-form-item label="优惠券" prop="couponId">
+        <el-select v-model="form.couponId" placeholder="请选择优惠券" clearable style="width: 300px;" @change="handleCouponChange">
+          <el-option
+            v-for="item in couponList"
+            :key="item.couponId"
+            :label="item.title + ' - ' + item.price + '元'"
+            :value="item.couponId"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="支付方式" prop="payType">
+        <el-select v-model="form.payType" placeholder="请选择支付方式" clearable size="small">
+          <el-option
+            v-for="item in payTypeOptions"
+            :key="item.dictValue"
+            :label="item.dictLabel"
+            :value="item.dictValue"
+          />
+        </el-select>
+      </el-form-item>
+    </el-form>
+    <div slot="footer" class="dialog-footer">
+      <el-button type="primary" @click="submitForm">确 定</el-button>
+      <el-button @click="handleClose">取 消</el-button>
+    </div>
+
+    <el-dialog :title="userAddress.title" v-if="userAddress.open" :visible.sync="userAddress.open" width="800px" append-to-body>
+      <add-user-address ref="addUserAddress" @addUserAddress="addUserAddress" />
+    </el-dialog>
+
+    <el-dialog title="选择商品" :visible.sync="productDialogVisible" width="900px" append-to-body>
+      <el-row style="margin-bottom: 10px;">
+        <el-input v-model="productNameSearch" placeholder="请输入商品名称搜索" clearable size="small" style="width: 300px;" @keyup.enter.native="searchProductDialog" />
+        <el-button type="primary" size="small" style="margin-left: 10px;" @click="searchProductDialog">搜索</el-button>
+      </el-row>
+      <el-table border :data="productJson" @row-click="selectProduct" highlight-current-row style="cursor: pointer;">
+        <el-table-column label="商品图片" align="center" width="100">
+          <template slot-scope="scope">
+            <el-popover placement="right" title="" trigger="hover">
+              <img slot="reference" :src="scope.row.imgUrl" width="50">
+              <img :src="scope.row.imgUrl" style="max-width: 150px">
+            </el-popover>
+          </template>
+        </el-table-column>
+        <el-table-column label="商品名称" show-overflow-tooltip align="center" prop="goodsName" />
+        <el-table-column label="积分" align="center" prop="integral" />
+        <el-table-column label="金额" align="center" prop="cash">
+          <template slot-scope="scope">
+            <span v-if="scope.row.cash!=null">{{ Number(scope.row.cash).toFixed(1) }}</span>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination
+        v-show="productTotal > 0"
+        :total="productTotal"
+        :page.sync="productQueryParams.pageNum"
+        :limit.sync="productQueryParams.pageSize"
+        @pagination="getProductList"
+      />
+    </el-dialog>
+  </el-dialog>
+</template>
+
+<script>
+import { listUserAddress } from "@/api/store/userAddress";
+import { getIntegralGoods, createIntegralOrder } from "@/api/his/integralOrder";
+import { getUserCoupon } from "@/api/store/coupon";
+import addUserAddress from "@/views/store/components/addUserAddress";
+
+export default {
+  name: "StoreIntegralOrderDialog",
+  components: { addUserAddress },
+  props: {
+    userInfo: {
+      type: Object,
+      default: () => ({})
+    }
+  },
+  data() {
+    return {
+      dialogVisible: false,
+      productDialogVisible: false,
+      productNameSearch: null,
+      productTotal: 0,
+      productQueryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        goodsName: null
+      },
+      form: {
+        addressId: null,
+        payType: null,
+        goodsIds: [],
+        couponId: null
+      },
+      rules: {
+        addressId: [{ required: true, message: "请选择收货地址", trigger: "change" }],
+        payType: [{ required: true, message: "请选择支付方式", trigger: "change" }]
+      },
+      address: [],
+      addressloading: false,
+      drugList: [],
+      productJson: [],
+      couponList: [],
+      payTypeOptions: [],
+      userAddress: {
+        open: false,
+        title: "创建收货地址"
+      }
+    };
+  },
+  created() {
+    this.getDicts("sys_package_pay_type").then(response => {
+      this.payTypeOptions = response.data;
+    });
+  },
+  methods: {
+    init(userInfo) {
+      this.dialogVisible = true;
+      this.resetForm();
+      this.$nextTick(() => {
+        this.getAddressList(userInfo.userId);
+      });
+    },
+    resetForm() {
+      this.form = {
+        addressId: null,
+        payType: null,
+        goodsIds: [],
+        couponId: null
+      };
+      this.drugList = [];
+      this.productJson = [];
+      this.productTotal = 0;
+      this.productNameSearch = null;
+      this.productQueryParams = {
+        pageNum: 1,
+        pageSize: 10,
+        goodsName: null
+      };
+      this.productDialogVisible = false;
+      this.couponList = [];
+      if (this.$refs.form) {
+        this.$refs.form.resetFields();
+      }
+    },
+    getAddressList(userId) {
+      var data = { userId: userId };
+      this.addressloading = true;
+      listUserAddress(data).then(response => {
+        this.address = response.rows;
+        this.addressloading = false;
+      });
+    },
+    getCouponList(userId, goodsId) {
+      if (!goodsId) {
+        this.couponList = [];
+        return;
+      }
+      getUserCoupon({ userId: userId, couponType: 7, goodsId: goodsId }).then(response => {
+        this.couponList = response.rows || [];
+      });
+    },
+    handleAddProduct() {
+      this.productNameSearch = null;
+      this.productQueryParams.pageNum = 1;
+      this.productQueryParams.goodsName = null;
+      this.getProductList();
+      this.productDialogVisible = true;
+    },
+    searchProductDialog() {
+      this.productQueryParams.pageNum = 1;
+      this.productQueryParams.goodsName = this.productNameSearch;
+      this.getProductList();
+    },
+    getProductList() {
+      const data = {
+        pageNum: this.productQueryParams.pageNum,
+        pageSize: this.productQueryParams.pageSize,
+        goodsName: this.productQueryParams.goodsName
+      };
+      getIntegralGoods(data).then(response => {
+        this.productJson = response.rows || [];
+        this.productTotal = response.total || 0;
+      });
+    },
+    selectProduct(row) {
+      for (var i = 0; i < this.drugList.length; i++) {
+        if (this.drugList[i].goodsId === row.goodsId) {
+          this.$message({ message: "该商品已添加", type: "warning" });
+          return;
+        }
+      }
+      this.drugList.push({ ...row });
+      this.syncGoodsIds();
+      this.$message({ message: "添加成功", type: "success" });
+    },
+    handleProductDelete(row) {
+      var index = this.drugList.findIndex(item => item.goodsId === row.goodsId);
+      if (index !== -1) {
+        this.drugList.splice(index, 1);
+      }
+      this.syncGoodsIds();
+    },
+    syncGoodsIds() {
+      this.form.goodsIds = this.drugList.map(item => item.goodsId);
+      this.form.couponId = null;
+      if (this.form.goodsIds.length > 0) {
+        this.getCouponList(this.userInfo.userId, this.form.goodsIds[0]);
+      } else {
+        this.couponList = [];
+      }
+    },
+    handleCouponChange(couponId) {
+      console.log("Selected coupon:", couponId);
+    },
+    handleAddUserAddress() {
+      this.userAddress.open = true;
+      setTimeout(() => {
+        this.$refs.addUserAddress.init(this.userInfo.userId);
+      }, 500);
+    },
+    addUserAddress() {
+      this.userAddress.open = false;
+      this.getAddressList(this.userInfo.userId);
+    },
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.goodsIds.length === 0) {
+            this.msgError("请选择至少一个商品");
+            return;
+          }
+          var submitData = {
+            userId: this.userInfo.userId,
+            addressId: this.form.addressId,
+            payType: this.form.payType,
+            goodsIds: this.form.goodsIds,
+            couponId: this.form.couponId
+          };
+          createIntegralOrder(submitData).then(response => {
+            if (response.code === 200) {
+              this.msgSuccess("创建成功");
+              this.$emit("success");
+              this.handleClose();
+            }
+          });
+        }
+      });
+    },
+    handleClose() {
+      this.dialogVisible = false;
+    }
+  }
+};
+</script>

+ 339 - 0
src/views/store/user/components/packageOrderDialog.vue

@@ -0,0 +1,339 @@
+<template>
+  <el-dialog title="创建套餐包订单" :visible.sync="dialogVisible" width="1000px" append-to-body :close-on-click-modal="false" @close="handleClose">
+    <el-form ref="form" :model="form" :rules="rules" label-width="120px">
+      <el-form-item label="收货信息" prop="addressId">
+        <el-row>
+          <el-col>
+            <el-button plain type="primary" icon="el-icon-plus" @click="handleAddUserAddress()">添加收货地址</el-button>
+          </el-col>
+        </el-row>
+        <el-radio-group v-model="form.addressId" style="width:100%">
+          <el-table border style="margin-top:5px;" v-loading="addressloading" :data="address">
+            <el-table-column label="ID" align="center">
+              <template slot-scope="scope">
+                <el-radio :label="scope.row.addressId"></el-radio>
+              </template>
+            </el-table-column>
+            <el-table-column label="收货人姓名" align="center" prop="realName" />
+            <el-table-column label="收货人所在省" align="center" prop="province" />
+            <el-table-column label="收货人所在市" align="center" prop="city" />
+            <el-table-column label="收货人所在区" align="center" prop="district" />
+            <el-table-column label="收货人详细地址" align="center" prop="detail" />
+          </el-table>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="就诊人信息" prop="patientId">
+        <el-row>
+          <el-col>
+            <el-button plain type="primary" icon="el-icon-plus" @click="handleAddUserPatient()">添加就诊人</el-button>
+          </el-col>
+        </el-row>
+        <el-radio-group v-model="form.patientId" style="width:100%">
+          <el-table border style="margin-top:5px;" v-loading="patientLoading" :data="patientList">
+            <el-table-column label="ID" align="center">
+              <template slot-scope="scope">
+                <el-radio :label="scope.row.patientId"></el-radio>
+              </template>
+            </el-table-column>
+            <el-table-column label="患者姓名" align="center" prop="patientName" />
+            <el-table-column label="身份证号" align="center" prop="idCard" width="170px"/>
+            <el-table-column label="出生年月" align="center" prop="birthday" width="180">
+              <template slot-scope="scope">
+                <span>{{ parseTime(scope.row.birthday, '{y}-{m}-{d}') }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="性别" align="center" prop="sex">
+              <template slot-scope="scope">
+                <dict-tag :options="sexOptions" :value="scope.row.sex"/>
+              </template>
+            </el-table-column>
+            <el-table-column label="手机号" align="center" prop="mobile" />
+          </el-table>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="套餐包" prop="packageId">
+        <el-select v-model="form.packageId" remote filterable reserve-keyword placeholder="套餐包" :remote-method="packageMethod" style="width: 300px;" @change="changePackage">
+          <el-option
+            v-for="dict in packageList"
+            :key="dict.packageId"
+            :label="dict.packageName"
+            :value="dict.packageId">
+            <span style="float: left ;margin-right: 20px;">{{ dict.packageName }}</span>
+            <span style="float: left">{{ dict.secondName }}</span>
+          </el-option>
+        </el-select>
+        <el-table border style="margin-top:5px;" :data="package">
+          <el-table-column label="套餐包名称" align="center" prop="packageName" />
+          <el-table-column label="别名" align="center" prop="secondName" />
+          <el-table-column label="类型" align="center" prop="packageType">
+            <template slot-scope="scope">
+              <dict-tag :options="packageTypeOptions" :value="scope.row.packageType"/>
+            </template>
+          </el-table-column>
+          <el-table-column label="子类型" align="center" prop="packageSubType">
+            <template slot-scope="scope">
+              <dict-tag :options="packageSubTypeOptions" :value="scope.row.packageSubType"/>
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-form-item>
+      <el-form-item label="优惠券" prop="couponId">
+        <el-select v-model="form.couponId" placeholder="请选择优惠券" clearable style="width: 300px;" @change="handleCouponChange">
+          <el-option
+            v-for="item in couponList"
+            :key="item.couponId"
+            :label="item.title + ' - ' + item.price + '元'"
+            :value="item.couponId"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="支付方式" prop="payType">
+        <el-select v-model="form.payType" placeholder="请选择支付方式" clearable size="small" @change="handlePayTypeChange">
+          <el-option
+            v-for="item in payTypeOptions"
+            :key="item.dictValue"
+            :label="item.dictLabel"
+            :value="item.dictValue"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item v-if="form.payType && form.payType !== '1' && form.payType !== 1" label="实付金额" prop="payMoney">
+        <el-input-number v-model="form.payMoney" :precision="2" :min="0" placeholder="请输入实付金额" style="width: 300px;" />
+      </el-form-item>
+      <el-form-item v-if="form.payType && form.payType !== '1' && form.payType !== 1" label="应付金额" prop="payableAmount">
+        <el-input-number v-model="form.payableAmount" :precision="2" :min="0" placeholder="请输入应付金额" style="width: 300px;" />
+      </el-form-item>
+      <el-form-item v-if="form.payType && (form.payType === '1' || form.payType === 1)" label="实付金额" prop="payMoney">
+        <el-input-number v-model="form.payMoney" :precision="2" :min="0" placeholder="请输入实付金额" style="width: 300px;" />
+      </el-form-item>
+      <el-form-item label="订单备注" prop="orderRemark">
+        <el-input type="textarea" rows="2" v-model="form.orderRemark" placeholder="" />
+      </el-form-item>
+    </el-form>
+    <div v-if="shareLink" style="margin-top: 10px; padding: 10px; background: #f5f7fa; border-radius: 4px;">
+      <el-form label-width="120px">
+        <el-form-item label="分享链接">
+          <el-input v-model="shareLink" readonly style="width: 400px;">
+            <el-button slot="append" icon="el-icon-document-copy" @click="copyShareLink">复制</el-button>
+          </el-input>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div slot="footer" class="dialog-footer">
+      <el-button type="primary" @click="submitForm" :loading="submitLoading">分 享</el-button>
+      <el-button @click="handleClose">取 消</el-button>
+    </div>
+
+    <el-dialog :title="userAddress.title" v-if="userAddress.open" :visible.sync="userAddress.open" width="800px" append-to-body>
+      <add-user-address ref="addUserAddress" @addUserAddress="addUserAddress" />
+    </el-dialog>
+    <el-dialog :title="userPatient.title" v-if="userPatient.open" :visible.sync="userPatient.open" width="800px" append-to-body>
+      <add-patient ref="addPatient" @addUserPatient="addUserPatient" />
+    </el-dialog>
+  </el-dialog>
+</template>
+
+<script>
+import { listUserAddress } from "@/api/store/userAddress";
+import { listPatient } from "@/api/store/patient";
+import { packageList, sharePackageOrderLink } from "@/api/store/package";
+import { getUserCoupon } from "@/api/store/coupon";
+import addUserAddress from "@/views/store/components/addUserAddress";
+import addPatient from "@/views/store/components/addPatient";
+
+export default {
+  name: "StorePackageOrderDialog",
+  components: { addUserAddress, addPatient },
+  props: {
+    userInfo: {
+      type: Object,
+      default: () => ({})
+    }
+  },
+  data() {
+    return {
+      dialogVisible: false,
+      submitLoading: false,
+      shareLink: null,
+      form: {
+        addressId: null,
+        patientId: null,
+        packageId: null,
+        payType: null,
+        payMoney: null,
+        payableAmount: null,
+        orderRemark: null,
+        couponId: null
+      },
+      rules: {
+        addressId: [{ required: true, message: "请选择收货地址", trigger: "change" }],
+        packageId: [{ required: true, message: "请选择套餐包", trigger: "change" }],
+        payType: [{ required: true, message: "请选择支付方式", trigger: "change" }]
+      },
+      address: [],
+      addressloading: false,
+      patientList: [],
+      patientLoading: false,
+      package: [],
+      packageList: [],
+      couponList: [],
+      payTypeOptions: [],
+      packageTypeOptions: [],
+      packageSubTypeOptions: [],
+      sexOptions: [],
+      userAddress: {
+        open: false,
+        title: "创建收货地址"
+      },
+      userPatient: {
+        open: false,
+        title: "创建就诊人"
+      }
+    };
+  },
+  created() {
+    this.getDicts("sys_package_pay_type").then(response => {
+      this.payTypeOptions = response.data;
+      this.payTypeOptions.push({ dictValue: '4', dictLabel: '线下实付' });
+    });
+    this.getDicts("sys_package_type").then(response => {
+      this.packageTypeOptions = response.data;
+    });
+    this.getDicts("sys_package_sub_type").then(response => {
+      this.packageSubTypeOptions = response.data;
+    });
+    this.getDicts("sys_user_sex").then(response => {
+      this.sexOptions = response.data;
+    });
+  },
+  methods: {
+    init(userInfo) {
+      this.dialogVisible = true;
+      this.shareLink = null;
+      this.resetForm();
+      this.$nextTick(() => {
+        this.getAddressList(userInfo.userId);
+        this.getPatientList(userInfo.userId);
+        this.getCouponList(userInfo.userId);
+      });
+    },
+    resetForm() {
+      this.form = {
+        addressId: null,
+        patientId: null,
+        packageId: null,
+        payType: null,
+        payMoney: null,
+        payableAmount: null,
+        orderRemark: null,
+        couponId: null
+      };
+      this.package = [];
+      if (this.$refs.form) {
+        this.$refs.form.resetFields();
+      }
+    },
+    handlePayTypeChange() {
+      this.form.payMoney = null;
+      this.form.payableAmount = null;
+    },
+    getAddressList(userId) {
+      var data = { userId: userId };
+      this.addressloading = true;
+      listUserAddress(data).then(response => {
+        this.address = response.rows;
+        this.addressloading = false;
+      });
+    },
+    getPatientList(userId) {
+      var data = { userId: userId };
+      this.patientLoading = true;
+      listPatient(data).then(response => {
+        this.patientList = response.rows;
+        this.patientLoading = false;
+      });
+    },
+    getCouponList(userId) {
+      getUserCoupon({ userId: userId, couponType: 5 }).then(response => {
+        this.couponList = response.rows || [];
+      });
+    },
+    packageMethod(query) {
+      if (query !== '') {
+        packageList(query).then(response => {
+          this.packageList = response.data || [];
+        });
+      }
+    },
+    changePackage(packageId) {
+      var item = this.packageList.find(p => p.packageId === packageId);
+      if (item) {
+        this.package = [item];
+      }
+    },
+    handleCouponChange(couponId) {
+      console.log('Selected coupon:', couponId);
+    },
+    handleAddUserAddress() {
+      this.userAddress.open = true;
+      setTimeout(() => {
+        this.$refs.addUserAddress.init(this.userInfo.userId);
+      }, 500);
+    },
+    addUserAddress() {
+      this.userAddress.open = false;
+      this.getAddressList(this.userInfo.userId);
+    },
+    handleAddUserPatient() {
+      this.userPatient.open = true;
+      setTimeout(() => {
+        this.$refs.addPatient.init(this.userInfo.userId);
+      }, 500);
+    },
+    addUserPatient() {
+      this.userPatient.open = false;
+      this.getPatientList(this.userInfo.userId);
+    },
+    copyShareLink() {
+      if (!this.shareLink) return;
+      var input = document.createElement('input');
+      input.value = this.shareLink;
+      document.body.appendChild(input);
+      input.select();
+      document.execCommand('copy');
+      document.body.removeChild(input);
+      this.$message.success('链接已复制');
+    },
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          var submitData = {
+            userId: this.userInfo.userId,
+            addressId: this.form.addressId,
+            patientId: this.form.patientId,
+            packageId: this.form.packageId,
+            payType: this.form.payType,
+            payMoney: this.form.payMoney,
+            payableAmount: this.form.payableAmount,
+            orderRemark: this.form.orderRemark,
+            couponId: this.form.couponId
+          };
+          this.submitLoading = true;
+          sharePackageOrderLink(submitData).then(response => {
+            if (response.code === 200) {
+              this.shareLink = response.shareLink || (response.data && response.data.shareLink);
+              this.$emit("success");
+            }
+          }).finally(() => {
+            this.submitLoading = false;
+          });
+        }
+      });
+    },
+    handleClose() {
+      this.dialogVisible = false;
+      this.shareLink = null;
+    }
+  }
+};
+</script>

+ 92 - 2
src/views/store/user/myList.vue

@@ -119,7 +119,7 @@
           </el-tag>
         </template>
       </el-table-column>
-      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="150px">
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="200px">
         <template slot-scope="scope">
 
           <el-button
@@ -132,6 +132,12 @@
             type="text"
             @click="handleNickName(scope.row)"
           >修改昵称</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            @click="handleCreateOrder(scope.row)"
+            v-hasPermi="['store:packageOrder:add']"
+          >去下单</el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -177,6 +183,45 @@
          <userDetails  ref="userDetails" />
        </el-drawer>
 
+    <el-dialog title="选择订单类型" :visible.sync="orderTypeDialogVisible" width="600px" append-to-body>
+      <el-radio-group v-model="selectedOrderType" style="width: 100%;">
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-card shadow="hover" :class="{'selected-card': selectedOrderType === 'package'}" @click.native="selectedOrderType = 'package'">
+              <div style="text-align: center; padding: 20px;">
+                <i class="el-icon-box" style="font-size: 32px; color: #409EFF;"></i>
+                <div style="margin-top: 10px; font-size: 14px; color: #303133;">套餐包订单</div>
+              </div>
+            </el-card>
+          </el-col>
+          <el-col :span="8">
+            <el-card shadow="hover" :class="{'selected-card': selectedOrderType === 'consultation'}" @click.native="selectedOrderType = 'consultation'">
+              <div style="text-align: center; padding: 20px;">
+                <i class="el-icon-chat-dot-round" style="font-size: 32px; color: #67C23A;"></i>
+                <div style="margin-top: 10px; font-size: 14px; color: #303133;">问诊订单</div>
+              </div>
+            </el-card>
+          </el-col>
+          <el-col :span="8">
+            <el-card shadow="hover" :class="{'selected-card': selectedOrderType === 'integral'}" @click.native="selectedOrderType = 'integral'">
+              <div style="text-align: center; padding: 20px;">
+                <i class="el-icon-coin" style="font-size: 32px; color: #E6A23C;"></i>
+                <div style="margin-top: 10px; font-size: 14px; color: #303133;">积分订单</div>
+              </div>
+            </el-card>
+          </el-col>
+        </el-row>
+      </el-radio-group>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="orderTypeDialogVisible = false">取 消</el-button>
+        <el-button type="primary" @click="confirmOrderType">确 定</el-button>
+      </div>
+    </el-dialog>
+
+    <package-order-dialog ref="packageOrderDialog" :userInfo="currentOrderUser" @success="handleOrderSuccess" />
+    <consultation-order-dialog ref="consultationOrderDialog" :userInfo="currentOrderUser" @success="handleOrderSuccess" />
+    <integral-order-dialog ref="integralOrderDialog" :userInfo="currentOrderUser" @success="handleOrderSuccess" />
+
 
   </div>
 </template>
@@ -184,9 +229,12 @@
 <script>
 import { myListUser, getUser, delUser, addUser, updateUser, myExportUser } from "@/api/store/user";
 import userDetails from '../components/userDetails.vue';
+import packageOrderDialog from './components/packageOrderDialog.vue';
+import consultationOrderDialog from './components/consultationOrderDialog.vue';
+import integralOrderDialog from './components/integralOrderDialog.vue';
 export default {
   name: "User",
-  components: {userDetails},
+  components: {userDetails, packageOrderDialog, consultationOrderDialog, integralOrderDialog},
   data() {
     return {
       show:{
@@ -216,6 +264,9 @@ export default {
       open: false,
       createTime:null,
       appCreateTimeRange:null,
+      orderTypeDialogVisible: false,
+      selectedOrderType: 'package',
+      currentOrderUser: {},
       // 查询参数
       queryParams: {
         pageNum: 1,
@@ -369,6 +420,38 @@ export default {
       this.form.userId = row.userId;
       this.title = "修改用户昵称";
     },
+    handleCreateOrder(row) {
+      this.currentOrderUser = {
+        userId: row.userId,
+        nickname: row.nickname,
+        phone: row.phone
+      };
+      this.selectedOrderType = 'package';
+      this.orderTypeDialogVisible = true;
+    },
+    confirmOrderType() {
+      if (!this.selectedOrderType) {
+        this.$message.warning('请选择订单类型');
+        return;
+      }
+      this.orderTypeDialogVisible = false;
+      this.$nextTick(() => {
+        switch (this.selectedOrderType) {
+          case 'package':
+            this.$refs.packageOrderDialog.init(this.currentOrderUser);
+            break;
+          case 'consultation':
+            this.$refs.consultationOrderDialog.init(this.currentOrderUser);
+            break;
+          case 'integral':
+            this.$refs.integralOrderDialog.init(this.currentOrderUser);
+            break;
+        }
+      });
+    },
+    handleOrderSuccess() {
+      this.getList();
+    },
     /** 修改按钮操作 */
     handleUpdate(row) {
       this.reset();
@@ -432,3 +515,10 @@ export default {
   }
 };
 </script>
+
+<style scoped>
+.selected-card {
+  border-color: #409EFF;
+  background-color: #ecf5ff;
+}
+</style>