Bläddra i källkod

Merge branch 'dev' of http://39.101.143.165:8090/dong_k/tenant-Platform into dev

祁鹏飞 4 månader sedan
förälder
incheckning
fd7046d6bf

+ 198 - 175
src/components/DialogSetDeptLeader/index.vue

@@ -1,73 +1,49 @@
 <template>
   <div>
-    <el-dialog
-      v-model="props.dialogVisible"
-      :title="props.title"
-      width="1000"
-      append-to-body
-      draggable
-      :before-close="handleClose"
-    >
-      <el-select
-        v-model="userId"
-        filterable
-        remote
-        reserve-keyword
-        placeholder="输入姓名,手机号,工号查找"
-        :remote-method="remoteMethod"
-        :loading="loading"
-        style="width: 240px"
-        clearable
-      >
-        <el-option
-          v-for="item in options"
-          :key="item.value"
-          :label="`${item.label}-${item.mobile}`"
-          :value="item.value"
-        >
-        </el-option>
-      </el-select>
+    <el-dialog v-model="visible" :title="props.title" top="10vh" draggable :show-close="false">
+      <el-form label-position="left" label-width="auto">
+        <el-row :gutter="24">
+          <el-col :span="24">
+            <el-form-item label="">
+              <el-input v-model="searchName" class="search-input1" placeholder="请输入负责人姓名,工号,手机号查找"
+                :prefix-icon="Search" clearable  @input="searchinput">
+                <template #append>
+                  <el-button text type="primary" class="" @click="searchUser">搜索</el-button>
+                </template>
+              </el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
       <div class="dialog-mian">
-        <div v-show="userId == '' || userId == null">
-          <el-tree
-            ref="treeRef"
-            style="max-width: 600px"
-            class="filter-tree"
-            :data="deptList"
-            :props="defaultProps"
-            :default-expand-all="true"
-            :expand-on-click-node="false"
-            @node-click="treeClick"
-            node-key="id"
-            highlight-current
-          >
-          </el-tree>
-        </div>
-        <div>
-          <el-radio-group v-model="userId" v-show="userId">
+        <div v-if="searchName && userList1.length > 1">
+          <el-radio-group v-model="treeReId" >
             <div style="display: flex; flex-direction: column">
-              <el-radio
-                v-for="item in options"
-                :key="item.value"
-                :value="item.value"
-                style="margin-bottom: 15px"
-              >
-                <p style="margin: 0">{{ item.label }}</p>
-                <p style="margin: 0">{{ item.value }}</p>
+              <el-radio class="mb-[12px] flex a-start" v-for="item in userList1" :key="item.userId" :value="item.userId">
+                <div>
+                  <span style="margin: 0;line-height: 1;color: #333 !important;">{{ item.name }}</span>
+                  <span style="line-height: 1;color: #333 !important;" class="ml-[10px]">{{ item.mobile }}</span>
+                </div>
+
               </el-radio>
             </div>
           </el-radio-group>
-
-          <el-radio-group v-model="treeReId" v-show="userList.length > 0 && !userId">
+        </div>
+        <div v-show=" userList1.length < 1">
+          <el-tree ref="treeRef" style="max-width: 600px" class="filter-tree" :data="deptList" :props="defaultProps"
+            :default-expand-all="true" :expand-on-click-node="false" @node-click="treeClick"
+            :current-node-key="defaultSelectedId" node-key="id" highlight-current :check-on-click-node="true">
+          </el-tree>
+        </div>
+        <div v-show=" userList1.length < 1">
+          <el-radio-group v-model="treeReId" v-show="userList.length > 0">
             <div style="display: flex; flex-direction: column">
-              <el-radio
-                v-for="item in userList"
-                :key="item.userId"
-                :value="item.userId"
-                style="margin-bottom: 15px"
-              >
-                <p style="margin: 0">{{ item.name }}</p>
-                <p style="margin: 0">{{ item.mobile }}</p>
+              <el-radio class="mb-[12px] flex a-start" v-for="item in userList" :key="item.userId" :value="item.userId">
+                <div>
+                  <span style="margin: 0;line-height: 1;color: #333 !important;">{{ item.name }}</span>
+                  <span style="line-height: 1;color: #333 !important;" class="ml-[10px]">{{ item.mobile }}</span>
+                </div>
+
               </el-radio>
             </div>
           </el-radio-group>
@@ -75,7 +51,7 @@
       </div>
       <template #footer>
         <div class="dialog-footer">
-          <el-button @click="handleClose ">取消</el-button>
+          <el-button @click="handleClose">取消</el-button>
           <el-button type="primary" @click="submit">
             确认
           </el-button>
@@ -86,9 +62,12 @@
 </template>
 
 <script setup lang="ts">
-import { defineProps, ref, onMounted, defineEmits,nextTick,watch } from "vue";
+import { defineProps, ref, onMounted, defineEmits, nextTick, watch } from "vue";
 import api from "@/api";
-import { ElMessage,ElTree } from "element-plus";
+import { ElMessage, ElTree } from "element-plus";
+import { Search } from "@element-plus/icons-vue";
+
+import user from "@/mock/user";
 type tableType = {
   id: string;
   name: string;
@@ -103,10 +82,27 @@ const props = defineProps<{
   deptIds: Array<[]>;
   deptList: Array<tableType>;
   title: string;
-  deptSelected: string;
+  deptSelected?: string;
   typeAttr: string;
 }>();
 
+const searchName = ref<string>("");
+// 本地响应式变量,用于控制对话框显示
+const visible = ref(props.dialogVisible);
+
+// 监听 props.dialogVisible 的变化,同步到本地变量
+watch(() => props.dialogVisible, (val) => {
+  console.log('val', val)
+  visible.value = val;
+});
+
+// 监听本地 visible 的变化,当弹窗关闭时通知父组件
+watch(visible, (val) => {
+  if (!val) {
+    emits('cancelDialog');
+  }
+});
+
 interface ListItem {
   value: string;
   label: string;
@@ -119,146 +115,127 @@ const treeRef = ref<InstanceType<typeof ElTree>>();
 //       treeRef.value!.setCurrentKey(props.deptIds[0]);
 //     }
 // })
-watch(props, (val) => {
-  nextTick(()=>{
-    if(props.dialogVisible)
-    if(props.deptIds.length<2){
-      treeRef.value?.setCurrentKey(props?.deptIds[0]);
-      treeClick({id:props.deptIds[0]})
-    }
-  })
-
-  // if(val.dialogVisible){
-
-
-  // }
-
-
+watch(() => props.dialogVisible, (val) => {
+  if (val) {
+    nextTick(() => {
+      if (props.deptIds.length < 2) {
+        treeRef.value?.setCurrentKey(props?.deptIds[0]);
+        treeClick({ id: props.deptIds[0] });
+      }
+    });
+  }
 });
 
 const list = ref<ListItem[]>([]);
 const options = ref<ListItem[]>([]);
 const userId = ref<string>("");
 const loading = ref(false);
-const treeReId=ref<string>(props.deptSelected);
+const treeReId = ref<string>('');
+  const defaultSelectedId = ref('');//默认选中的部门id
 
-const emits=defineEmits(["closeDialog",'cancelDialog']);
+const emits = defineEmits(["closeDialog", 'cancelDialog']);
 
 
 const userList = ref<any[]>([]);
-const remoteMethod = (query: string) => {
-  if (query) {
-    loading.value = true;
-    api.userApi
-      .AllMemberList({
-        name: query,
-        typeAttr:props.typeAttr
-      })
-      .then((res: any) => {
-
-        if (res.code === 200) {
-          // userList.value = res.data;
-          let arr: any = [];
-          console.log('res.data是啥', res.data)
-          res.data.forEach((item) => {
-            arr.push({
-              label: item.name,
-              value: item.id,
-              mobile: item.mobile,
-              userOd: item.userId
-            });
-          });
-          loading.value = false;
-          options.value = arr;
-        }
-      });
-    // setTimeout(() => {
-    //   loading.value = false
-    //   options.value = list.value.filter((item) => {
-    //     return item.label.toLowerCase().includes(query.toLowerCase())
-    //   })
-    // }, 200)
-  } else {
-    options.value = [];
+const userList1 = ref<any[]>([]);
+const searchinput = () => {
+  if (!searchName.value) {
+    userList1.value = [];
   }
+}
+//搜索用户
+const searchUser = () => {
+  api.userApi
+    .AllMemberList({
+      name: searchName.value,
+      typeAttr: props.typeAttr
+    })
+    .then((res: any) => {
+      if (res.code == 200) {
+        // 如果搜索结果只有一个用户,直接选中该用户 ,并默认选中该用户的部门
+        if (res.data.length == 1) {
+          userList.value = res.data;
+          treeReId.value = res.data[0].userId
+          defaultSelectedId.value = res.data[0].deptId
+        } else {
+          userList1.value = res.data;
+        }
+      }
+    })
 };
 function treeClick(node: any) {
   api.userApi
     .AllMemberList({
       deptId: node.id,
-      typeAttr:props.typeAttr
+      typeAttr: props.typeAttr
     })
     .then((res: any) => {
       if (res.code === 200) {
         userList.value = res.data;
-
-        // options.value=arr
       }
     });
 }
 
-function submit(){
+function submit() {
 
-  if(props.title=='设置负责人'){
-      console.log(111)
-    if(userId.value){
-        console.log(222)
-     const obj = options.value.find(a => a.value === userId.value)
+  if (props.title == '设置负责人') {
+    console.log(111)
+    if (userId.value) {
+      console.log(222)
+      const obj = options.value.find(a => a.value === userId.value)
       api.institutionApi.setDeptLeader({
-        deptId:props.deptIds,
-        leaderId:obj.userId
-      }).then(res=>{
+        deptId: props.deptIds,
+        leaderId: obj.userId
+      }).then(res => {
 
-        if(res.code==200){
+        if (res.code == 200) {
           ElMessage.success(res.msg)
           emits('closeDialog')
         } else {
-            ElMessage.warning(res.msg)
+          ElMessage.warning(res.msg)
         }
       })
 
 
-    }else{
-        console.log(333)
-     //  let flag={}
-     // userList.value.some((item:any)=>{
-     //
-     //     if( item.mobile==treeReId.value){
-     //      flag={...item}
-     //      return true
-     //     }
-     //     return false
-     //
-     //  })
+    } else {
+      console.log(333)
+      //  let flag={}
+      // userList.value.some((item:any)=>{
+      //
+      //     if( item.mobile==treeReId.value){
+      //      flag={...item}
+      //      return true
+      //     }
+      //     return false
+      //
+      //  })
       let flag = userList.value.find(a => a.userId == treeReId.value)
       api.institutionApi.setDeptLeader({
-        deptId:props.deptIds,
-        leaderId:flag.userId
-      }).then(res=>{
-        if(res.code==200){
+        deptId: props.deptIds,
+        leaderId: flag.userId
+      }).then(res => {
+        if (res.code == 200) {
           ElMessage.success(res.msg)
           emits('closeDialog')
         }
       })
       // emits('closeDialog',flag)
     }
-  }else{
-      console.log(444)
-    if(userId.value){
-        console.log(555)
-     const obj=options.value.map((item:any)=>{
-        if(item.value==userId.value){
+  } else {
+    if (userId.value) {
+      const obj = options.value.map((item: any) => {
+        if (item.value == userId.value) {
           return {
-            name:item.label,
-            id:item.value,
-            mobile:item.mobile
+            name: item.label,
+            id: item.value,
+            mobile: item.mobile
           }
         }
       })
 
-      emits('closeDialog',obj[0])
-    }else{
-        console.log(666)
+      emits('closeDialog', obj[0])
+    } else {
+      console.log(666)
       // let flag={}
       // userList.value.some((item:any)=>{
       //
@@ -269,41 +246,87 @@ function submit(){
       //    return false
       //
       // })
-        let flag = userList.value.find(a => a.userId == treeReId.value)
-      emits('closeDialog',flag)
+      let flag = userList.value.find(a => a.userId == treeReId.value)
+      emits('closeDialog', flag)
     }
   }
 
 
 }
 
-const handleClose = (done: () => void) => {
-
-  emits('cancelDialog',false)
-
+const handleClose = () => {
+  // 通知父组件关闭对话框
+  emits('cancelDialog');
 }
 
 
 </script>
 <style lang="scss" scoped>
+:deep(.el-radio-group .el-radio) {
+  line-height: 1;
+}
+
+:deep(.el-form-item__content .el-input-group.search-input1) {
+  --el-border-color: #F7F7F7;
+  --el-input-hover-border-color: #F7F7F7;
+}
+
+:deep(.el-input-group--append>.el-input__wrapper) {
+  background-color: #F7F7F7;
+}
+
+:deep(.search-input1 .el-button__text--expand) {
+  color: #0083FF;
+
+  &::before {
+    content: '';
+    position: absolute;
+    left: 0;
+    top: 0;
+    bottom: 0;
+    width: 1px;
+    height: 24px;
+    background: #EEEEEE;
+    margin: auto;
+  }
+}
+
+:deep(.el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content) {
+  background-color: #F3F9FF;
+
+  /* 浅黄色背景 */
+  .el-text {
+    font-size: 14px;
+    font-weight: 500;
+    color: #0083FF;
+  }
+
+  .el-icon {}
+
+  /* 深蓝色字体 */
+}
+
+:deep(.el-tree--highlight-current .el-tree-node>.el-tree-node__content .el-icon) {
+  color: #666;
+}
+
 .dialog-mian {
   display: flex;
-  border: 1px solid #ccc;
   border-radius: 10px;
   min-height: 500px;
-  margin-top: 20px;
-  .el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
-    background-color: #f0f9eb; /* 浅黄色背景 */
-    color: #1f569d; /* 深蓝色字体 */
-  }
-  > div {
-    flex: 1;
-    padding: 15px;
+  margin-top: 24px;
+
+
+
+  >div {
+    width: 50%;
     box-sizing: border-box;
     max-height: 500px;
     overflow-y: auto;
   }
-  > div:last-child {
+
+  >div:last-child {
+    padding: 0 32px;
     border-left: 1px solid #ccc;
   }
 }

+ 77 - 40
src/views/index.vue

@@ -228,9 +228,12 @@ const initChinaMap = () => {
   };
   myChart.setOption(option)
   myChart.on('click', function (a) {
-    provinceStr.value =a.data.code
-    provinceName.value = a.name
-    initBusinessDistribution()
+    console.log(a)
+    if (a.data.code) {
+      provinceStr.value = a.data.code
+      provinceName.value = a.data.name
+      initBusinessDistribution()
+    }
   })
   window.addEventListener('resize', () => {
     myChart.resize()
@@ -240,6 +243,7 @@ const initChinaMap = () => {
 // 市级地图
 let CityMap = ref()
 const initCityMap = (name) => {
+  console.log(name)
   let str = ''
   if (name.length == 3) {
     str = name.substring(0, 2)
@@ -254,17 +258,50 @@ const initCityMap = (name) => {
 }
 
 const initMap = (str) => {
+  console.log(str)
   const myChart = echarts.init(CityMap.value)
   let option = {
     tooltip: {
       formatter: function (e, t, n) {
         // return .5 == e.value ? e.name + ":有疑似病例" : e.seriesName + "<br />" + e.name + ":" + e.value
         return e.name + "<br />" +
-          "业务员数量:" + e.value + "<br />" +
+          "业务员数量2:" + e.value + "<br />" +
           "个代业务员数量:" + e.data.personalAgentCount + "<br />" +
           "渠道业务员数量:" + e.data.channelSalesmanCount
       }
     },
+    visualMap: {
+      min: 0,
+      max: 1000,
+      left: 26,
+      bottom: 40,
+      showLabel: !0,
+      text: ["高", "低"],
+      pieces: [{
+        gt: 150,
+        label: ">150",
+        color: "#0485FF"
+      }, {
+        gte: 100,
+        lte: 150,
+        label: "100-150",
+        color: "#2E9AFF"
+      }, {
+        gte: 50,
+        lt: 100,
+        label: "50-100",
+        color: "#81C2FF"
+      }, {
+        gt: 0,
+        lt: 50,
+        label: "<50",
+        color: "#BCDFFF"
+      }, {
+        value: 0,
+        color: "#DCEEFF"
+      }],
+      show: !0
+    },
     geo: {
       map: str,
       roam: !1,
@@ -491,11 +528,11 @@ const initFunnel = () => {
         top: 40,
         type: 'funnel',
         left: '10%',
-        width: '80%',
+        width: '50%',
         bottom: 0,
         gap: 16,
         minSize: 150,
-        maxSize: 410,
+        maxSize: 250,
         label: {
           show: true,
           color: '#ffffff',
@@ -508,7 +545,7 @@ const initFunnel = () => {
         top: 40,
         type: 'funnel',
         left: '10%',
-        width: '80%',
+        width: '50%',
         gap: 16,
         bottom: 0,
         z: 1,
@@ -882,44 +919,44 @@ onMounted(async () => {
           <div class="chinaMap" ref="ChinaMap"></div>
         </div>
         <div class="level">
-          <div class="title">市级</div>
-          <div class="cityMap" ref="CityMap"></div>
-        </div>
-      </div>
-      <PageMain class="ecology">
-        <div class="title">出单趋势</div>
-        <div class="orderTrend" ref="TrendRef"></div>
-      </PageMain>
-      <div class="otherBox">
-        <div class="funnel">
-          <div class="title">业务漏斗</div>
-          <div class="chinaMap" ref="FunnelRef"></div>
+          <div class="title">{{ provinceName || '市级' }}</div>
+            <div class="cityMap" ref="CityMap"></div>
+          </div>
         </div>
-        <div class="pie">
-          <div class="title">业务类型分布</div>
-          <div class="cityMap" ref="PieRef"></div>
+        <PageMain class="ecology">
+          <div class="title">出单趋势</div>
+          <div class="orderTrend" ref="TrendRef"></div>
+        </PageMain>
+        <div class="otherBox">
+          <div class="funnel">
+            <div class="title">业务漏斗</div>
+            <div class="chinaMap" ref="FunnelRef"></div>
+          </div>
+          <div class="pie">
+            <div class="title">业务类型分布</div>
+            <div class="cityMap" ref="PieRef"></div>
+          </div>
         </div>
       </div>
-    </div>
-    <PageMain class="right-section ">
-      <div class="title">业务动态</div>
-      <!-- 订单 -->
-      <div class="quoteOrder mt-[24px]">
-        <div class="item flex f-c mb-[16px]" v-for="i in 10" :key="i">
-          <div class="flex a-c j-s mb-[8px]">
-            <span class="Order-title">报价订单</span>
-            <span class="Order-time">2025.06.13 12:00:17</span>
+      <PageMain class="right-section ">
+        <div class="title">业务动态</div>
+        <!-- 订单 -->
+        <div class="quoteOrder mt-[24px]">
+          <div class="item flex f-c mb-[16px]" v-for="i in 10" :key="i">
+            <div class="flex a-c j-s mb-[8px]">
+              <span class="Order-title">报价订单</span>
+              <span class="Order-time">2025.06.13 12:00:17</span>
+            </div>
+            <span class="Order-premium">%保险公司名称名称%-%订单保费%</span>
           </div>
-          <span class="Order-premium">%保险公司名称名称%-%订单保费%</span>
         </div>
-      </div>
-      <!-- app二维码 -->
-      <div class="qrcode flex a-c f-c">
-        <img :src="downloadUrl" alt="">
-        <span>扫码下载App</span>
-      </div>
-    </PageMain>
-  </div>
+        <!-- app二维码 -->
+        <div class="qrcode flex a-c f-c">
+          <img :src="downloadUrl" alt="">
+          <span>扫码下载App</span>
+        </div>
+      </PageMain>
+    </div>
 </template>
 
 <style lang="scss" scoped>

+ 0 - 1
src/views/personnel/institutionManage.vue

@@ -13,7 +13,6 @@
           </el-col>
         </el-row>
       </el-form>
-
       <Table :tableData="tableData" :columns="columns" :showIndex="false" :showSelect="true" :pageInfo="pageInfo"
         @getList="getList" :treeProps="{ children: 'children', hasChildren: 'hasChildren' }"
         @select-all-change="selectAllChange" @select-change="selectChange">

+ 8 - 7
src/views/personnel/memberManagement.vue

@@ -149,6 +149,8 @@
       </el-dialog>
       <setDept :dialogVisible="deptDialogVisible" :dept-list="deptTreeData" :dept-ids="[deptItem.id]"
         @close-dialog="confirmDialogInfo" :title="title" typeAttr="2" @cancel-dialog="deptDialogVisible = false"></setDept>
+
+
       <el-dialog v-model="changeDeptDialog" title="变更机构" width="600" append-to-body draggable>
         <div>
           <el-input v-model="filterText" style="width: 240px" placeholder="请输入机构名称查找" :prefix-icon="Search" />
@@ -734,13 +736,8 @@ function manySetDeptUser() {
 
 </script>
 <style lang="scss" scoped>
-:deep(.el-input-group__append) {
-  background: linear-gradient( 91deg, #4FCAFF 0%, #2B62FF 100%);
-  color: #fff;
-  .el-button.is-link:not(.is-disabled):active{
-  color: #fff;
-
-  }
+:deep( .el-tree-node>.el-tree-node__content .el-icon) {
+  color: #666;
 }
 
 :deep(.el-table__inner-wrapper:before) {
@@ -764,6 +761,10 @@ function manySetDeptUser() {
   margin-right: 24px;
   :deep(.el-checkbox__inner) {
     border-radius: 50%
+  }
+  :deep(.el-tree-node.is-current>.el-tree-node__content){
+  background-color: #F3F9FF;
+
   }
   &::after{
     content:'';