Explorar el Código

Merge branch 'wuguojie' into liuheng

刘恒 hace 1 año
padre
commit
d990a66c30

+ 4 - 2
src/api/index.ts

@@ -8,8 +8,9 @@ import Message from 'vue-m-message'
 import appApi from './modules/app'
 import userApi from './modules/user'
 import roleApi from './modules/role'
-import institutionApi from "./modules/institution"
+import institutionApi from './modules/institution'
 import areaApi from "./modules/area"
+import operationApi from './modules/operation.ts'
 
 const axiosInstance:ApiInstance = axios.create({
   baseURL: (import.meta.env.DEV && import.meta.env.VITE_OPEN_PROXY === 'true') ? '/proxy/' : import.meta.env.VITE_APP_API_BASEURL,
@@ -90,6 +91,7 @@ const api = {
   userApi: userApi(axiosInstance),
   roleApi: roleApi(axiosInstance),
   institutionApi:institutionApi(axiosInstance),
-  areaApi:areaApi(axiosInstance)
+  areaApi:areaApi(axiosInstance),
+  operationApi: operationApi(axiosInstance)
 }
 export default api

+ 70 - 0
src/api/modules/operation.ts

@@ -0,0 +1,70 @@
+import { ApiInstance } from '../type'
+import {LocationQueryValue} from "vue-router";
+
+// 新增
+export interface AddOperation {
+  typeAttr: string,
+  deptId: string,
+  username: string,
+  mobile: string,
+  identity: string,
+  identityTimeStart: string,
+  identityTimeEnd: string,
+  leaderId: string,
+  referrerId: string,
+
+  sex?: string,
+  birthday?: string,
+  nations?: string,
+  koseki?: string,
+  maritalStatus?: string,
+  politicsStatus?: string,
+  health?: string,
+  province?: string,
+  city?: string,
+  district?: string,
+  liveAddress?: string,
+  postalCode?: string,
+  education?: string,
+  graduationTime?: string,
+  school?: string,
+  isComputer?: string,
+  emergencyContactName?: string,
+  emergencyContactTel?: string,
+  salary?: string,
+  salaryLevel?: string,
+  bankCardId?: string,
+  bankName?: string
+
+}
+// 列表
+export interface OperationSearch {
+  pages: number,
+  size: number,
+  salesman?: string
+  deptId?: string,
+  typeAttr?: string,
+  deptName?: string,
+  status?: number,
+  isEnable?: number,
+  leaderId?: string
+}
+// 启用/禁用
+export interface OperationIsEnable {
+  id: string[],
+  isEnable: number
+}
+export interface OperationEdit extends AddOperation {
+  id: string
+}
+// 业务员管理相关接口
+const operationApi = (axiosInstance: ApiInstance) => ({
+  addOperation: (data: AddOperation) => axiosInstance.post('/userInfo/add', data), // 新赠
+  operationList: (data: OperationSearch) => axiosInstance.post('/userInfo/getUserInfoList', data), // 列表
+  operationDelete: (data: string[]) => axiosInstance.post('/userInfo/delete', data), // 删除
+  operationIsEnable: (data: OperationIsEnable) => axiosInstance.post('/userInfo/isEnable', data), // 启用/禁用
+  operationDetail: (data: string | null | LocationQueryValue[] | undefined) => axiosInstance.get(`/userInfo/getUserInfo?id=${data}`), // 详情
+  operationEdit: (data: OperationEdit) => axiosInstance.post('/userInfo/update', data), // 编辑
+})
+
+export default operationApi

+ 1 - 2
src/components/LoginForm/index.vue

@@ -40,7 +40,7 @@ const form = ref({
   captcha: "",
   system: "PLATFORM",
   captchaId: 0,
-  system: "",
+  systemCode: "",
 });
 const rules = ref<FormRules>({
   userName: [{ required: true, trigger: "blur", message: "请输入用户名" }],
@@ -86,7 +86,6 @@ function handleLogin() {
         .then(() => {
           if (remember) {
             localStorage.setItem("login_account", form.value.userName);
-
           } else {
             localStorage.removeItem("login_account");
           }

+ 168 - 171
src/components/Table/index.vue

@@ -1,188 +1,185 @@
+<<<<<<< HEAD
+
 <template>
-  <div class="container">
-    <div class="table_box">
+	<div class="container">
+		<div class="table_box">
       <div class="table-title-btn">
         <slot name="table-title-btn"></slot>
       </div>
-      <el-table
-        ref="multipleTableRef"
-        :header-cell-style="{ 'background-color': '#f2f2f2' }"
-        :data="props.tableData"
-        style="width: 100%"
-        row-key="id"
-        :tree-props="props.treeProps"
-      >
-        <el-table-column
-          type="selection"
-          v-if="showSelect"
-          :selectable="selectable"
-          width="55"
-        />
+			<el-table ref="multipleTableRef"  :header-cell-style="{'background-color': '#f2f2f2'}" :data="props.tableData" style="width: 100%">
+				<el-table-column type="selection" v-if="showSelect" :selectable="selectable" width="55" />
 
-        <el-table-column
-          v-if="showIndex"
-          type="index"
-          label="序号"
-          width="55"
-        />
-        <el-table-column
-          v-for="column in columns"
-          :key="column.prop"
-          :prop="column.prop"
-          :label="column.label"
-          :sortable="column.sortable ? 'custom' : false"
-          :width="column.width"
-        >
-          <template #header>
-            <slot name="search" :slotData="column"></slot>
-          </template>
-          <template #default="scope">
-            
-          
-              
-              <component v-if="column.formatter" :is="column.formatter(scope.row, column, scope.row[column.prop], scope.$index)" class="routerlick" />
-              <span v-else>{{ scope.row[column.prop] }}</span>
-            
-            
-          </template>
-        </el-table-column>
-        <el-table-column label="操作">
-          <template #default="scope">
-            <slot name="operation" :operationData="scope"></slot>
-          </template>
-          <!-- <template #default="scope">
-						<div v-if="scope.row._edit">
-							<el-button type="primary" @click="handleSave(scope)"> 保存 </el-button>
-							<el-button @click="handleCancle(scope)"> 取消 </el-button>
-						</div>
-						<el-button v-else type="primary" @click="handleEdit(scope)"> 编辑 </el-button>
-					</template> -->
-        </el-table-column>
-      </el-table>
-    </div>
-    <div class="page_box">
-      <el-pagination
-        v-model:current-page="props.pageInfo.pageNum"
-        v-model:page-size="props.pageInfo.pageSize"
-        :page-sizes="props.pageInfo.sizes"
-        layout="total, sizes, prev, pager, next, jumper"
-        :total="props.pageInfo.total"
-        @size-change="handleSizeChange"
-        @current-change="handleCurrentChange"
-      />
-    </div>
-  </div>
+				<el-table-column v-if="showIndex" type="index" label="序号" width="55" />
+				<el-table-column
+					v-for="column in columns"
+					:key="column.prop"
+					:prop="column.prop"
+					:label="column.label"
+					:sortable="column.sortable ? 'custom' : false"
+					:width="column.width"
+				>
+					<template #header>
+						<slot name="search" :slotData="column"></slot>
+					</template>
+					<template #default="{ row }">
+						<template v-if="row._edit">
+							<el-input
+								v-if="
+									column.prop === 'Date' || column.prop === 'Name' || column.prop === 'Organization'
+								"
+								v-model="row[column.prop]"
+							/>
+							<el-select v-if="column.prop === 'Tag'" v-model="Tagvalue">
+								<el-option
+									v-for="(type, label) in tagTypes"
+									:key="label"
+									:label="label"
+									:value="label"
+								/>
+							</el-select>
+						</template>
+						<template v-else>
+							<span v-if="column.prop !== 'Tag'">{{ row[column.prop] }}</span>
+							<el-tag v-if="column.prop === 'Tag'" :type="getTagType(row[column.prop])">{{
+								row[column.prop]
+							}}</el-tag>
+						</template>
+					</template>
+				</el-table-column>
+				<el-table-column label="操作">
+                    <template #default="scope">
+                        <slot name="operation" :operationData="scope"></slot>
+                    </template>
+				</el-table-column>
+			</el-table>
+		</div>
+		<div class="page_box">
+			<el-pagination
+                v-model:current-page="props.pageInfo.pageNum"
+                v-model:page-size="props.pageInfo.pageSize"
+                :page-sizes="props.pageInfo.sizes"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="props.pageInfo.total"
+                @size-change="handleSizeChange"
+                @current-change="handleCurrentChange"
+            />
+		</div>
+	</div>
 </template>
 
 <script lang="ts" setup>
-import { defineProps, ref, onMounted, defineEmits } from "vue";
-import type { TableInstance } from "element-plus";
+	import { defineProps, ref, onMounted,defineEmits  } from "vue";
+	import type { TableInstance } from "element-plus";
+
+	interface TableRow {
+		[key: string]: any;
+	}
+    interface TagTypes{
+        [key:string]:string;
+    }
+    const emit = defineEmits(['getList']);
+	const props = defineProps<{
+		tableData: Array<TableRow>;
+		columns: {
+			prop: string;
+			label: string;
+			sortable?: boolean;
+			width?: string;
+			style?: string;
+		}[];
+        pageInfo:{
+            pageNum: number;
+            pageSize: number;
+            sizes: number[];
+            total: number;
+        };
+        showSelect:boolean;
+        showIndex:boolean;
+
+	}>();
+	const multipleTableRef = ref<TableInstance>();
+	const TableData = ref<TableRow[]>();
+	onMounted(() => {
+		let counter = 1;
+		TableData.value = props.tableData.map((row) => ({
+			...row,
+			_edit: false, // 设置默认非编辑状态
+			counter: counter++
+		}));
+	});
+	const selectable = () => true;
+	const Tagvalue = ref("");
+	const tagTypes:TagTypes = {
+		'公司': "primary",
+		'甲方': "success",
+		'合作伙伴': "primary"
+	};
+    const handleSizeChange = (val: number) => {
+
+        props.pageInfo.pageSize=val
+
+        emit('getList', props.pageInfo);
+    }
+    const handleCurrentChange = (val: number) => {
+
+        props.pageInfo.pageNum=val
+        emit('getList', props.pageInfo);
 
-interface TableRow {
-  [key: string]: any;
-}
-interface TagTypes {
-  [key: string]: string;
-}
-const emit = defineEmits(["getList"]);
-const props = defineProps<{
-  tableData: Array<TableRow>;
-  columns: {
-    prop: string;
-    label: string;
-    sortable?: boolean;
-    width?: string;
-    style?: string;
-    formatter?: (row: any, column: any, cellValue: any, index: number) => any;
-  }[];
-  pageInfo: {
-    pageNum: number;
-    pageSize: number;
-    sizes: number[];
-    total: number;
-  };
-  showSelect: boolean;
-  showIndex: boolean;
-  treeProps:{}
-}>();
-const multipleTableRef = ref<TableInstance>();
-const TableData = ref<TableRow[]>();
-onMounted(() => {
-  let counter = 1;
-  TableData.value = props.tableData.map((row) => ({
-    ...row,
-    _edit: false, // 设置默认非编辑状态
-    counter: counter++,
-  }));
-});
-const selectable = () => true;
-const Tagvalue = ref("");
-const tagTypes: TagTypes = {
-  公司: "primary",
-  甲方: "success",
-  合作伙伴: "primary",
-};
-const handleSizeChange = (val: number) => {
-  props.pageInfo.pageSize = val;
 
-  emit("getList", props.pageInfo);
-};
-const handleCurrentChange = (val: number) => {
-  props.pageInfo.pageNum = val;
-  emit("getList", props.pageInfo);
-};
-const getTagType = (tag: string) => {
-  return tagTypes[tag] || tagTypes["公司"];
-};
-const handleEdit = (scope: { row: TableRow }) => {
-  Tagvalue.value = scope.row.Tag || "";
-  scope.row._edit = true;
-};
-const handleSave = (scope: { row: TableRow }) => {
-  scope.row.Tag = Tagvalue.value;
-  scope.row._edit = false;
-};
-const handleCancle = (scope: { row: TableRow }) => {
-  scope.row._edit = false;
-};
-const headClass = (scope: { row: TableRow }) => {
-  // return 'background:#F8F8F9'
-};
+    }
+	const getTagType = (tag: string) => {
+		return tagTypes[tag] || tagTypes["公司"];
+	};
+	const handleEdit = (scope: { row: TableRow }) => {
+		Tagvalue.value = scope.row.Tag || "";
+		scope.row._edit = true;
+	};
+	const handleSave = (scope: { row: TableRow }) => {
+		scope.row.Tag = Tagvalue.value;
+		scope.row._edit = false;
+	};
+	const handleCancle = (scope: { row: TableRow }) => {
+		scope.row._edit = false;
+	};
+  const headClass= (scope: { row: TableRow }) =>  {
+      // return 'background:#F8F8F9'
+    }
 </script>
 <style lang="scss" scoped>
-.container {
-  width: 100%;
-  height: auto;
-  margin: 5px;
-  display: flex;
-  flex-direction: column;
-}
-.table_box {
-  flex: 1;
-  margin-bottom: 10px;
-  overflow-y: auto;
-  .table_item_container {
-    margin-left: 20px;
-    padding: 0;
-    .table_item {
-      margin: 5px 0;
+	.container {
+		width: 100%;
+		height: auto;
+		margin: 5px;
+		display: flex;
+		flex-direction: column;
+	}
+ .table_box {
+		flex: 1;
+		margin-bottom: 10px;
+		overflow-y: auto;
+		.table_item_container {
+			margin-left: 20px;
+			padding: 0;
+			.table_item {
+				margin: 5px 0;
+			}
+		}
+    :deep(.cell){
+      display: flex;
+      align-items: center;
+      justify-content: center;
     }
-  }
-  :deep(.cell) {
+    .table-title-btn {
+      margin-bottom: 20px;
+      :deep(.el-button){
+        margin-right: 20px;
+      }
+    }
+
+	}
+  .page_box{
     display: flex;
     align-items: center;
-    justify-content: center;
-  }
-  .table-title-btn {
-    margin-bottom: 20px;
-    :deep(.el-button) {
-      margin-right: 20px;
-    }
+    justify-content: flex-end;
   }
-}
-.page_box {
-  display: flex;
-  align-items: center;
-  justify-content: flex-end;
-}
 </style>

+ 0 - 1
src/main.ts

@@ -32,7 +32,6 @@ for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
   app.component(key, component)
 }
 // 添加 Element Plus
-
 app.use(FloatingVue, {
   distance: 12,
 })

+ 57 - 0
src/router/modules/operation.ts

@@ -0,0 +1,57 @@
+import type { RouteRecordRaw } from 'vue-router'
+
+const Layout = () => import('@/layouts/index.vue')
+
+const routes: RouteRecordRaw = {
+  path: '/operationManagement',
+  component: Layout,
+  redirect: '/operationManagement/operation',
+  name: 'OperationManagement',
+  meta: {
+    title: '业务团队',
+
+  },
+  children: [
+    {
+      path: '/operationDetail',
+      name: 'OperationDetail',
+      component: () => import('@/views/operationManagement/operationDetail.vue'),
+      meta: {
+        title: '业务员详情',
+        sidebar: false,
+      },
+    },
+    {
+      path: 'operation',
+      name: 'Operation',
+      component: () => import('@/views/operationManagement/operation.vue'),
+      meta: {
+        title: '业务员管理',
+      },
+    },{
+      path: 'team',
+      name: 'Team',
+      component: () => import('@/views/operationManagement/team.vue'),
+      meta: {
+        title: '团队管理',
+      },
+    },{
+      path: 'channel',
+      name: 'Channel',
+      component: () => import('@/views/operationManagement/channel.vue'),
+      meta: {
+        title: '渠道管理',
+      },
+    },{
+      path: 'telemarketing',
+      name: 'Telemarketing',
+      component: () => import('@/views/operationManagement/telemarketing.vue'),
+      meta: {
+        title: '电销组管理',
+      },
+    },
+
+  ],
+}
+
+export default routes

+ 20 - 0
src/router/routes.ts

@@ -5,6 +5,7 @@ import generatedRoutes from 'virtual:generated-pages'
 import { setupLayouts } from 'virtual:meta-layouts'
 import MultilevelMenuExample from './modules/multilevel.menu.example'
 import organizationManagement from './modules/organization'
+import operationManagement from './modules/operation'
 import personnel from './modules/personnel'
 
 // 固定路由(默认路由)
@@ -61,6 +62,16 @@ const systemRoutes: RouteRecordRaw[] = [
 
 // 动态路由(异步路由、导航栏路由)
 const asyncRoutes: Route.recordMainRaw[] = [
+  {
+    meta: {
+      title: '演示',
+      icon: 'i-uim:box',
+    },
+    children: [
+      MultilevelMenuExample,
+
+    ],
+  },
   // {
   //   meta: {
   //     title: '演示',
@@ -91,6 +102,15 @@ const asyncRoutes: Route.recordMainRaw[] = [
 
     ],
   },
+  {
+    meta: {
+      title: '业务管理',
+      icon: 'i-uim:box',
+    },
+    children: [
+      operationManagement
+    ],
+  },
   {
     meta: {
       title: '租户运营',

+ 3 - 22
src/views/login.vue

@@ -4,7 +4,6 @@
     constant: true
     layout: false
   </route>
-  
   <script setup lang="ts">
   import { ref } from 'vue'
   import { useRoute, useRouter } from 'vue-router'
@@ -12,21 +11,20 @@
   defineOptions({
     name: 'Login',
   })
-  
+
   const route = useRoute()
   const router = useRouter()
   const settingsStore = useUserStore()
-  
+
   const redirect = ref(route.query.redirect?.toString() ?? settingsStore.settings.home.fullPath)
   const account = ref<string>()
   // // 表单类型
   const formType = ref<'login' | 'register' | 'resetPassword'>('login')
   </script>
-  
+
   <template>
     <div class="bg-banner" />
     <img class="bgback" src=".././assets/images/loginback1.png" alt="">
-  
     <div class="login-box">
       <!-- <div class="login-banner">
         <img
@@ -35,7 +33,6 @@
         >
         <img src="@/assets/images/login-banner.png" class="banner">
       </div> -->
-  
       <div class="login-form flex-col-center">
         <Transition name="fade" mode="out-in">
           <LoginForm
@@ -55,7 +52,6 @@
       </div>
     </div>
   </template>
-  
   <style lang="scss" scoped>
   .bg-banner {
     position: fixed;
@@ -66,7 +62,6 @@
     background-image: url(".././assets/images/loginback.png");
     background-size: cover;
   }
-  
   .bgback {
     position: fixed;
     top: 58%;
@@ -74,18 +69,15 @@
     z-index: 0;
     transform: translateX(-50%) translateY(-50%);
   }
-  
   [data-mode="mobile"] {
     .login-box {
       position: relative;
       flex-direction: column;
       justify-content: start;
       width: 100%;
-  
       .login-banner {
         width: 100%;
         padding: 20px 0;
-  
         .banner {
           position: relative;
           top: inherit;
@@ -97,23 +89,19 @@
           transform: translateY(0);
         }
       }
-  
       .login-form {
         width: 100%;
       }
     }
-  
     .copyright {
       position: relative;
     }
   }
-  
   .login-box {
     position: absolute;
     display: flex;
     overflow: hidden;
     background-color: var(--g-container-bg);
-  
     [data-mode="pc"] & {
       top: 50%;
       left: 70%;
@@ -121,13 +109,11 @@
       box-shadow: var(--el-box-shadow);
       transform: translateX(-50%) translateY(-50%);
     }
-  
     .login-banner {
       position: relative;
       width: 450px;
       overflow: hidden;
       background-color: var(--g-bg);
-  
       .banner {
         position: absolute;
         top: 50%;
@@ -135,13 +121,11 @@
         transform: translateY(-50%);
       }
     }
-  
     .login-form {
       width: 500px;
       transition: height 0.15s ease;
     }
   }
-  
   .copyright {
     position: absolute;
     bottom: 0;
@@ -149,15 +133,12 @@
     padding: 20px;
     margin: 0;
   }
-  
   .fade-enter-active,
   .fade-leave-active {
     transition: opacity 0.15s ease;
   }
-  
   .fade-enter-from,
   .fade-leave-to {
     opacity: 0;
   }
   </style>
-  

+ 11 - 0
src/views/operationManagement/channel.vue

@@ -0,0 +1,11 @@
+<template>
+  <div>channel</div>
+</template>
+
+<script setup>
+
+</script>
+
+<style scoped>
+
+</style>

+ 76 - 0
src/views/operationManagement/modules/addCard.vue

@@ -0,0 +1,76 @@
+<template>
+  <div>
+    <el-form ref="BankRef" :rules="bankRules" :model="bankForm" label-width="80">
+      <el-form-item prop="name" label="姓名">
+        <el-input v-model="bankForm.name" disabled></el-input>
+      </el-form-item>
+      <el-form-item prop="bank" label="银行">
+        <el-select v-model="bankForm.bank">
+          <el-option key="1" value="银行1"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item prop="card" label="银行卡号">
+        <el-input v-model="bankForm.card"></el-input>
+      </el-form-item>
+      <el-form-item prop="bankName" label="开户行">
+        <el-input v-model="bankForm.bankName"></el-input>
+      </el-form-item>
+      <el-form-item prop="photo" label="照片">
+        <ImageUpload action="#" :ext="['png','jpg','jpeg']" :size="5"></ImageUpload>
+      </el-form-item>
+      <div style="display: flex; justify-content: flex-end">
+        <el-button @click="onSubmit(0)">取消</el-button>
+        <el-button type="primary" @click="onSubmit(BankRef, 1)">确定</el-button>
+      </div>
+    </el-form>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue'
+import {ElMessage, FormInstance} from 'element-plus'
+
+const BankRef = ref<FormInstance>()
+
+const emits = defineEmits(['closeDialog'])
+
+let bankForm = ref({
+  name: '',
+  bank: '',
+  card: '',
+  bankName: '',
+  photo: ''
+})
+const bankRules = {
+  name: [
+    { required: true, message: '请填写姓名', trigger: 'blur' }
+  ],
+  card: [
+    { required: true, message: '请填写银行卡号', trigger: 'blur' }
+  ],
+  bankName: [
+    { required: true, message: '请填写开户行', trigger: 'blur' }
+  ],
+}
+const onSubmit = async (BankRef:FormInstance, type: number) => {
+  if(!BankRef) {
+    emits('closeDialog', false)
+    return
+  }
+  await BankRef.validate((valid) => {
+    if(valid) {
+
+    } else {
+      ElMessage({
+        message: '请正确填写相关信息!',
+        type: 'warning'
+      })
+    }
+  })
+}
+
+</script>
+
+<style scoped lang="scss">
+
+</style>

+ 694 - 0
src/views/operationManagement/modules/addOperation.vue

@@ -0,0 +1,694 @@
+<template>
+  <div>
+    <el-form
+      :model="operationForm"
+      ref="OperationFormRef"
+      :rules="operationRules"
+      label-width="120"
+    >
+      <el-descriptions title="基本信息">
+        <el-descriptions-item>
+          <template #default>
+            <el-row :gutter="20">
+              <el-col :span="10">
+                <el-form-item prop="typeAttr" label="业务员类型">
+                  <el-select v-model="operationForm.typeAttr" placeholder="请选择业务员类型">
+                    <el-option key="1" value="类型1"></el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :span="10">
+                <el-form-item prop="deptId" label="所属团队">
+                  <el-select v-model="operationForm.deptId" placeholder="请选择所属团队">
+                    <el-option key="1" value="团队1"></el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="20">
+              <el-col :span="10">
+                <el-form-item prop="username" label="姓名">
+                  <el-input v-model="operationForm.username" placeholder="请填写姓名"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="10">
+                <el-form-item prop="mobile" label="手机号">
+                  <el-input v-model="operationForm.mobile" placeholder="请填写手机号"></el-input>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="20">
+              <el-col :span="10">
+                <el-form-item prop="organization" label="所属机构">
+                  <el-select v-model="operationForm.organization" placeholder="请选择所属机构">
+                    <el-option key="1" value="机构1"></el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :span="10">
+                <el-form-item prop="identity" label="证件号">
+                  <el-input v-model="operationForm.identity" placeholder="请填写证件号"></el-input>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="20">
+              <el-col :span="10">
+                <el-form-item prop="identityTimeStart" label="证件有效期始">
+                  <el-date-picker
+                    v-model="operationForm.identityTimeStart"
+                    type="date"
+                    placeholder="请选择"
+                    format="YYYY-MM-DD"
+                    style="width: 100%"
+                  />
+                </el-form-item>
+              </el-col>
+              <el-col :span="10">
+                <el-form-item prop="identityTimeEnd" label="证件有效期止">
+                  <el-date-picker
+                    v-model="operationForm.identityTimeEnd"
+                    type="date"
+                    placeholder="请选择"
+                    format="YYYY-MM-DD"
+                    style="width: 100%"
+                  />
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </template>
+        </el-descriptions-item>
+      </el-descriptions>
+      <el-descriptions title="其他信息">
+        <el-descriptions-item>
+          <template #default>
+            <el-row :gutter="20">
+              <el-col :span="10">
+                <el-form-item prop="leaderId" label="管理人">
+                  <el-select v-model="operationForm.leaderId" placeholder="请选择管理人">
+                    <el-option key="1" value="机构1"></el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :span="10">
+                <el-form-item prop="leaderNumber" label="管理人工号">
+                  <el-input v-model="operationForm.leaderNumber" placeholder="请填写管理人工号"></el-input>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="20">
+              <el-col :span="10">
+                <el-form-item prop="referrerId" label="推荐人">
+                  <el-select v-model="operationForm.referrerId" placeholder="请选择推荐人">
+                    <el-option key="1" value="机构1"></el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :span="10">
+                <el-form-item prop="referrerNumber" label="推荐人工号">
+                  <el-input v-model="operationForm.referrerNumber" placeholder="请填写推荐人工号"></el-input>
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </template>
+        </el-descriptions-item>
+      </el-descriptions>
+      <el-descriptions title="资料附件">
+        <el-descriptions-item>
+          <template #default>
+            <el-form-item prop="" label="身份证(人像面)" label-width="150">
+              <el-upload v-if="!IDCardFront" action="#" :show-file-list="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 1)">
+                <el-button link type="primary">上传</el-button>
+              </el-upload>
+              <div class="fileInfo" v-else>
+                <div class="fileName">{{ IDCardFrontName }}</div>
+                <div class="fileBtn">
+                  <el-upload action="#" :show-file-list="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 1)" style="display: flex; align-items: center">
+                    <el-icon class="btn-icon"><Upload /></el-icon>
+                  </el-upload>
+                  <el-icon class="btn-icon" @click="imageView(1)"><View /></el-icon>
+                  <el-icon class="btn-icon"><Download /></el-icon>
+                  <el-icon class="btn-icon"><Delete /></el-icon>
+                </div>
+              </div>
+            </el-form-item>
+            <el-form-item prop="" label="身份证(国徽面)" label-width="150">
+              <el-upload v-if="!IDCardBack" action="#" :show-file-list="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 2)">
+                <el-button link type="primary">上传</el-button>
+              </el-upload>
+              <div class="fileInfo" v-else>
+                <div class="fileName">{{ IDCardBackName }}</div>
+                <div class="fileBtn">
+                  <el-upload action="#" :show-file-list="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 2)" style="display: flex; align-items: center">
+                    <el-icon class="btn-icon"><Upload /></el-icon>
+                  </el-upload>
+                  <el-icon class="btn-icon" @click="imageView(2)"><View /></el-icon>
+                  <el-icon class="btn-icon"><Download /></el-icon>
+                  <el-icon class="btn-icon"><Delete /></el-icon>
+                </div>
+              </div>
+            </el-form-item>
+            <el-form-item prop="" label="展业资格证" label-width="150">
+              <el-upload v-if="!certification" action="#" :show-file-list="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 3)">
+                <el-button link type="primary">上传</el-button>
+              </el-upload>
+              <div class="fileInfo" v-else>
+                <div class="fileName">{{ certificationName }}</div>
+                <div class="fileBtn">
+                  <el-upload action="#" :show-file-list="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 3)" style="display: flex; align-items: center">
+                    <el-icon class="btn-icon"><Upload /></el-icon>
+                  </el-upload>
+                  <el-icon class="btn-icon" @click="imageView(3)"><View /></el-icon>
+                  <el-icon class="btn-icon"><Download /></el-icon>
+                  <el-icon class="btn-icon"><Delete /></el-icon>
+                </div>
+              </div>
+            </el-form-item>
+          </template>
+        </el-descriptions-item>
+      </el-descriptions>
+      <el-divider />
+      <el-button v-if="!recordShow" link type="primary" icon="plus" @click="recordShow = !recordShow">填写人事档案(选填)</el-button>
+      <el-button v-else link type="primary" icon="ArrowUp" @click="recordShow = !recordShow">收起人事档案(选填)</el-button>
+      <br/><br/>
+      <el-descriptions title="个人信息" v-show="recordShow">
+        <el-descriptions-item>
+          <template #default>
+            <el-row :gutter="20">
+              <el-col :span="10">
+                <el-form-item prop="sex" label="性别">
+                  <el-select v-model="operationForm.sex" placeholder="请选择性别">
+                    <el-option key="1" value="类型1"></el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :span="10">
+                <el-form-item prop="born" label="出生日期">
+                  <el-date-picker
+                    v-model="operationForm.birthday"
+                    type="date"
+                    placeholder="请选择"
+                    format="YYYY-MM-DD"
+                    style="width: 100%"
+                  />
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="20">
+              <el-col :span="10">
+                <el-form-item prop="type" label="民族">
+                  <el-select v-model="operationForm.nations" placeholder="请选择业务员类型">
+                    <el-option key="1" value="类型1"></el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :span="10">
+                <el-form-item prop="team" label="户籍">
+                  <el-input v-model="operationForm.koseki" placeholder="请填写户籍"></el-input>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="20">
+              <el-col :span="10">
+                <el-form-item prop="type" label="婚姻状况">
+                  <el-select v-model="operationForm.maritalStatus" placeholder="请选择婚姻状况">
+                    <el-option key="1" value="类型1"></el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :span="10">
+                <el-form-item prop="team" label="政治面貌">
+                  <el-select v-model="operationForm.politicsStatus" placeholder="请选择政治面貌">
+                    <el-option key="1" value="团队1"></el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="20">
+              <el-col :span="10">
+                <el-form-item prop="type" label="健康状况">
+                  <el-select v-model="operationForm.health" placeholder="请选择健康状况">
+                    <el-option key="1" value="类型1"></el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :span="10">
+                <el-form-item prop="team" label="居住地区">
+                  <el-select v-model="operationForm.address" placeholder="请选择居住地区">
+                    <el-option key="1" value="团队1"></el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="20">
+              <el-col :span="10">
+                <el-form-item prop="team" label="详细地址">
+                  <el-input v-model="operationForm.liveAddress" placeholder="请填写详细地址"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="10">
+                <el-form-item prop="team" label="邮政编码">
+                  <el-input v-model="operationForm.postalCode" placeholder="请填写邮政编码"></el-input>
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </template>
+        </el-descriptions-item>
+      </el-descriptions>
+      <el-descriptions title="学历信息" v-show="recordShow">
+        <el-descriptions-item>
+          <template #default>
+            <el-row :gutter="20">
+              <el-col :span="10">
+                <el-form-item prop="sex" label="学历">
+                  <el-select v-model="operationForm.education" placeholder="请选择学历">
+                    <el-option key="1" value="类型1"></el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :span="10">
+                <el-form-item prop="born" label="毕业时间">
+                  <el-date-picker
+                    v-model="operationForm.graduationTime"
+                    type="date"
+                    placeholder="请选择"
+                    format="YYYY-MM-DD"
+                    style="width: 100%"
+                  />
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="20">
+              <el-col :span="10">
+                <el-form-item prop="type" label="毕业院校">
+                  <el-input v-model="operationForm.school" placeholder="请填写毕业院校"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="10">
+                <el-form-item prop="team" label="是否计算机专业">
+                  <el-select v-model="operationForm.isComputer" placeholder="请选择是否计算机专业">
+                    <el-option key="是" value="是"></el-option>
+                    <el-option key="否" value="否"></el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </template>
+        </el-descriptions-item>
+      </el-descriptions>
+      <el-descriptions title="紧急联系人信息" v-show="recordShow">
+        <el-descriptions-item>
+          <template #default>
+            <el-row :gutter="20">
+              <el-col :span="10">
+                <el-form-item prop="team" label="姓名">
+                  <el-input v-model="operationForm.emergencyContactName" placeholder="请填写姓名"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="10">
+                <el-form-item prop="team" label="手机号">
+                  <el-input v-model="operationForm.emergencyContactTel" placeholder="请填写手机号"></el-input>
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </template>
+        </el-descriptions-item>
+      </el-descriptions>
+      <el-descriptions title="工资信息" v-show="recordShow">
+        <el-descriptions-item>
+          <template #default>
+            <el-row :gutter="20">
+              <el-col :span="10">
+                <el-form-item prop="team" label="工资">
+                  <el-input v-model="operationForm.salary" placeholder="请填写工资"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="10">
+                <el-form-item prop="team" label="工资等级">
+                  <el-input v-model="operationForm.salaryLevel" placeholder="请填写工资等级"></el-input>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="20">
+              <el-col :span="10">
+                <el-form-item prop="team" label="银行卡号">
+                  <el-input v-model="operationForm.bankCardId" placeholder="请填写银行卡号"></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="10">
+                <el-form-item prop="team" label="开户行">
+                  <el-input v-model="operationForm.bankName" placeholder="请填写开户行"></el-input>
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </template>
+        </el-descriptions-item>
+      </el-descriptions>
+      <el-divider v-show="recordShow" />
+      <el-descriptions v-show="recordShow" title="其它附件">
+        <el-descriptions-item>
+          <template #default>
+            <el-form-item prop="" label="劳动合同" label-width="150">
+              <el-upload v-if="!contract" action="#" :show-file-list="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 4)">
+                <el-button link type="primary">上传</el-button>
+              </el-upload>
+              <div class="fileInfo" v-else>
+                <div class="fileName">{{ contractName }}</div>
+                <div class="fileBtn">
+                  <el-upload action="#" :show-file-list="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 4)" style="display: flex; align-items: center">
+                    <el-icon class="btn-icon"><Upload /></el-icon>
+                  </el-upload>
+                  <el-icon class="btn-icon" @click="imageView(4)"><View /></el-icon>
+                  <el-icon class="btn-icon"><Download /></el-icon>
+                  <el-icon class="btn-icon"><Delete /></el-icon>
+                </div>
+              </div>
+            </el-form-item>
+            <el-form-item prop="" label="应聘表" label-width="150">
+              <el-upload v-if="!applicant" action="#" :show-file-list="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 5)">
+                <el-button link type="primary">上传</el-button>
+              </el-upload>
+              <div class="fileInfo" v-else>
+                <div class="fileName">{{ applicantName }}</div>
+                <div class="fileBtn">
+                  <el-upload action="#" :show-file-list="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 5)" style="display: flex; align-items: center">
+                    <el-icon class="btn-icon"><Upload /></el-icon>
+                  </el-upload>
+                  <el-icon class="btn-icon" @click="imageView(5)"><View /></el-icon>
+                  <el-icon class="btn-icon"><Download /></el-icon>
+                  <el-icon class="btn-icon"><Delete /></el-icon>
+                </div>
+              </div>
+            </el-form-item>
+            <el-form-item prop="" label="定薪表" label-width="150">
+              <el-upload v-if="!decidePay" action="#" :show-file-list="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 6)">
+                <el-button link type="primary">上传</el-button>
+              </el-upload>
+              <div class="fileInfo" v-else>
+                <div class="fileName">{{ decidePayName }}</div>
+                <div class="fileBtn">
+                  <el-upload action="#" :show-file-list="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 6)" style="display: flex; align-items: center">
+                    <el-icon class="btn-icon"><Upload /></el-icon>
+                  </el-upload>
+                  <el-icon class="btn-icon" @click="imageView(6)"><View /></el-icon>
+                  <el-icon class="btn-icon"><Download /></el-icon>
+                  <el-icon class="btn-icon"><Delete /></el-icon>
+                </div>
+              </div>
+            </el-form-item>
+            <el-form-item prop="" label="离职表" label-width="150">
+              <el-upload v-if="!dimission" action="#" :show-file-list="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 7)">
+                <el-button link type="primary">上传</el-button>
+              </el-upload>
+              <div class="fileInfo" v-else>
+                <div class="fileName">{{ dimissionName }}</div>
+                <div class="fileBtn">
+                  <el-upload action="#" :show-file-list="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, 7)" style="display: flex; align-items: center">
+                    <el-icon class="btn-icon"><Upload /></el-icon>
+                  </el-upload>
+                  <el-icon class="btn-icon" @click="imageView(7)"><View /></el-icon>
+                  <el-icon class="btn-icon"><Download /></el-icon>
+                  <el-icon class="btn-icon"><Delete /></el-icon>
+                </div>
+              </div>
+            </el-form-item>
+          </template>
+        </el-descriptions-item>
+      </el-descriptions>
+      <div style="display: flex; justify-content: flex-end">
+        <el-button @click="onSubmit(0)">取消</el-button>
+        <el-button type="primary" @click="onSubmit(OperationFormRef, 1)">确定</el-button>
+      </div>
+    </el-form>
+    <div class="image-view" v-if="imageShow" @click="imageShow = false">
+      <img :src="imageUrl" />
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, defineEmits } from 'vue'
+import type { AddOperation } from '@/api/modules/operation.ts'
+import type { FormRules, FormInstance } from "element-plus";
+import api from "@/api";
+import {ElMessage} from "element-plus";
+
+interface OperationFormProps extends AddOperation {
+  organization: string
+  leaderNumber: string,
+  referrerNumber: string,
+  address?: string[]
+}
+
+let emits = defineEmits(['closeDialog'])
+
+const OperationFormRef = ref<FormInstance>()
+// 添加/编辑业务员表单
+let operationForm = ref<OperationFormProps>({
+  typeAttr: '',
+  deptId: '',
+  username: '',
+  mobile: '',
+  identity: '',
+  identityTimeStart: '',
+  identityTimeEnd: '',
+  leaderId: '',
+  leaderNumber: '',
+  referrerId: '',
+  referrerNumber: '',
+
+  sex: '',
+  birthday: '',
+  nations: '',
+  koseki: '',
+  maritalStatus: '',
+  politicsStatus: '',
+  health: '',
+  province: '',
+  city: '',
+  district: '',
+  address: [],
+  liveAddress: '',
+  postalCode: '',
+  education: '',
+  graduationTime: '',
+  school: '',
+  isComputer: '',
+  emergencyContactName: '',
+  emergencyContactTel: '',
+  salary: '',
+  salaryLevel: '',
+  bankCardId: '',
+  bankName: ''
+})
+// 添加/编辑业务员表单校验
+const operationRules = ref<FormRules>({
+  typeAttr: [
+    { required: true, trigger: "change", message: "请选择业务员类型" }
+  ],
+  deptId: [
+    { required: true, trigger: "change", message: "请选择所属团队" }
+  ],
+  username: [
+    { required: true, trigger: "blur", message: "请填写姓名" }
+  ],
+  mobile: [
+    { required: true, trigger: "blur", message: "请填写手机号" },
+    {
+      pattern: /^1[34578][0-9]{9}$/,
+      message: '请填写正确的手机号',
+      trigger: 'blur'
+    }
+  ],
+  organization: [
+    { required: true, trigger: "change", message: "请选择所属机构" }
+  ],
+  identity: [
+    { required: true, trigger: "blur", message: "请填写证件号" },
+    {
+      pattern: /^[1-9]\d{5}(19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9X]$/,
+      message: '请填写正确的身份证号',
+      trigger: 'blur'
+    }
+  ],
+  identityTimeStart: [
+    { required: true, trigger: "change", message: "请选择证件有效期始" }
+  ],
+  identityTimeEnd: [
+    { required: true, trigger: "change", message: "请选择证件有效期止" }
+  ],
+  leaderId: [
+    { required: true, trigger: "change", message: "请选择管理人" }
+  ],
+  leaderNumber: [
+    { required: true, trigger: "blur", message: "请填写管理人工号" }
+  ],
+  referrerId: [
+    { required: true, trigger: "change", message: "请选择推荐人" }
+  ],
+  referrerNumber: [
+    { required: true, trigger: "blur", message: "请填写推荐人工号" }
+  ],
+})
+// 身份证人像面
+let IDCardFrontName = ref('')
+let IDCardFront = ref('')
+// 身份证国徽面
+let IDCardBackName = ref('')
+let IDCardBack = ref('')
+// 展业资格证
+let certificationName = ref('')
+let certification = ref('')
+// 劳务合同
+let contractName = ref('')
+let contract = ref('')
+// 应聘表
+let applicantName = ref('')
+let applicant = ref('')
+// 定薪表
+let decidePayName = ref('')
+let decidePay = ref('')
+// 离职表
+let dimissionName = ref('')
+let dimission = ref('')
+// 图片预览地址
+let imageShow = ref(false)
+let imageUrl = ref('')
+
+// 上传图片
+const uploadImage = (file, type) => {
+  let files = file.raw
+  let url = window.URL.createObjectURL(files); //转临时路径
+  console.log(123123123, file, type)
+  switch (type) {
+    case 1:
+      IDCardFrontName.value = files.name
+      IDCardFront.value = url
+      break;
+    case 2:
+      IDCardBackName.value = files.name
+      IDCardBack.value = url
+      break;
+    case 3:
+      certificationName.value = files.name
+      certification.value = url
+      break;
+    case 4:
+      contractName.value = files.name
+      contract.value = url
+      break;
+    case 5:
+      applicantName.value = files.name
+      applicant.value = url
+      break;
+    case 6:
+      decidePayName.value = files.name
+      decidePay.value = url
+      break;
+    case 7:
+      dimissionName.value = files.name
+      dimission.value = url
+      break;
+  }
+  const params = new FormData(); // 声明formData数据类型
+  params.append("multipartFile", files);
+  params.append("type", "image");
+}
+
+// 人事档案
+let recordShow = ref(false)
+
+const imageView = (type) => {
+  imageShow.value = true
+  switch (type) {
+    case 1:
+      imageUrl.value = IDCardFront.value
+      break;
+    case 2:
+      imageUrl.value = IDCardBack.value
+      break;
+    case 3:
+      imageUrl.value = certification.value
+      break;
+    case 4:
+      imageUrl.value = contract.value
+      break;
+    case 5:
+      imageUrl.value = applicant.value
+      break;
+    case 6:
+      imageUrl.value = decidePay.value
+      break;
+    case 7:
+      imageUrl.value = dimission.value
+      break;
+  }
+}
+
+const onSubmit = async (OperationFormRef: FormInstance, type: number) => {
+  if(!OperationFormRef) {
+    emits('closeDialog', false)
+    return
+  }
+  await OperationFormRef.validate((valid) => {
+    if(valid) {
+      api.operationApi.addOperation(operationForm.value).then(res => {
+        console.log(123, res)
+      })
+    } else {
+      ElMessage({
+        message: '请正确填写相关信息!',
+        type: 'warning'
+      })
+    }
+  })
+}
+</script>
+
+<style scoped lang="scss">
+.fileInfo{
+  display: flex;
+  align-items: center;
+  justify-content: flex-start;
+  padding: 2px 20px;
+  border-radius: 5px;
+  margin: 0 10px;
+  &:hover{
+    background: #ccc;
+  }
+  .fileName{
+    width: 200px;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+  .fileBtn{
+    display: flex;
+    align-items: center;
+    .btn-icon{
+      margin: 0 10px;
+      font-size: 16px;
+      cursor: pointer;
+      &:hover{
+        color: #00a0f4;
+      }
+    }
+  }
+}
+.image-view{
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background: rgba(0,0,0,.6);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  z-index: 9999;
+  img{
+    width: 800px;
+    height: 800px;
+    border-radius: 5px;
+  }
+}
+</style>

+ 125 - 0
src/views/operationManagement/modules/allocation.vue

@@ -0,0 +1,125 @@
+<template>
+  <div class="allocation">
+    <el-input v-model="searchValue" style="width: 240px" placeholder="输入姓名、手机号、工号查找">
+      <template #prefix>
+        <el-icon class="el-input__icon" @click="handleSearch"><Search /></el-icon>
+      </template>
+    </el-input>
+    <el-row :gutter="20" class="allocation-content">
+      <el-col :span="12" style="padding: 10px">
+        <el-tree
+          :data="data"
+          @node-click="handleNodeClick"
+        />
+      </el-col>
+      <el-col :span="12" style="padding: 10px">
+        <el-radio-group v-model="radioValue" class="allocation-radio">
+          <el-radio value="1" size="large">
+            <template #default>
+              <div>姓名1</div>
+              <div>99140109M60D01001</div>
+            </template>
+          </el-radio>
+          <el-radio value="1" size="large">
+            <template #default>
+              <div>姓名2</div>
+              <div>99140109M60D01001</div>
+            </template>
+          </el-radio>
+        </el-radio-group>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue'
+
+let searchValue = ref('')
+const handleSearch = () => {
+
+}
+
+let data = [
+  {
+    label: 'Level one 1',
+    children: [
+      {
+        label: 'Level two 1-1',
+        children: [
+          {
+            label: 'Level three 1-1-1',
+          },
+        ],
+      },
+    ],
+  },
+  {
+    label: 'Level one 2',
+    children: [
+      {
+        label: 'Level two 2-1',
+        children: [
+          {
+            label: 'Level three 2-1-1',
+          },
+        ],
+      },
+      {
+        label: 'Level two 2-2',
+        children: [
+          {
+            label: 'Level three 2-2-1',
+          },
+        ],
+      },
+    ],
+  },
+  {
+    label: 'Level one 3',
+    children: [
+      {
+        label: 'Level two 3-1',
+        children: [
+          {
+            label: 'Level three 3-1-1',
+          },
+        ],
+      },
+      {
+        label: 'Level two 3-2',
+        children: [
+          {
+            label: 'Level three 3-2-1',
+          },
+        ],
+      },
+    ],
+  },
+]
+const handleNodeClick = (data) => {
+  console.log(data)
+}
+
+let radioValue = ref('')
+
+</script>
+
+<style scoped lang="scss">
+.allocation {
+  .allocation-content {
+    width: 100%;
+    margin: 20px;
+    border: 1px solid #ccc;
+    border-radius: 5px;
+    .allocation-radio{
+      display: flex;
+      flex-direction: column;
+      :deep(.el-radio) {
+        margin-right: 0;
+        margin-top: 10px;
+      }
+    }
+  }
+}
+</style>

+ 540 - 0
src/views/operationManagement/operation.vue

@@ -0,0 +1,540 @@
+<template>
+  <div class="operation">
+    <el-form
+      class="operationForm"
+      ref="OperationRef"
+      :model="form"
+      label-width="auto"
+    >
+      <el-row :gutter="20">
+        <el-col :span="8">
+          <el-form-item label="业务员" class="formItem">
+            <el-input v-model="form.salesman" placeholder="输入姓名、手机号、工号查找"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="归属机构" class="formItem">
+            <el-cascader style="width: 100%" :options="options" @change="organizationChange" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="类型" class="formItem">
+            <el-select v-model="form.typeAttr">
+              <el-option key="1" value="type1"></el-option>
+              <el-option key="2" value="type2"></el-option>
+              <el-option key="3" value="type3"></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row :gutter="20">
+        <el-col :span="8">
+          <el-form-item label="所属" class="formItem">
+            <el-input v-model="form.deptName" placeholder="渠道、团队、电销组名称查找"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="人员状态" class="formItem">
+            <el-select v-model="form.status">
+              <el-option key="1" value="type1"></el-option>
+              <el-option key="2" value="type2"></el-option>
+              <el-option key="3" value="type3"></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="账号状态" class="formItem">
+            <el-select v-model="form.isEnable">
+              <el-option key="0" value="禁用"></el-option>
+              <el-option key="1" value="启用"></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row :gutter="20">
+        <el-col :span="8">
+          <el-form-item label="管理人" class="formItem">
+            <el-input v-model="form.leaderId" placeholder="管理人姓名、工号"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-button type="primary" @click="search()">查询</el-button>
+          <el-button type="primary" plain @click="reset()">重置</el-button>
+        </el-col>
+      </el-row>
+    </el-form>
+    <el-row :gutter="20" style="margin: 20px 0" flex>
+      <el-col :span="3" style="display: flex">
+        <el-checkbox @change="selectAll" v-model="selectAllValue"></el-checkbox>&nbsp;
+        <el-select class="select-all" placeholder="全选" v-model="selectType" style="width: 120px" @change="selectTypeChange">
+          <el-option key="all" value="选中所有数据"></el-option>
+          <el-option key="cur" value="选中本页数据"></el-option>
+        </el-select>
+      </el-col>
+      <el-col :span="2">
+        <el-button type="primary" icon="plus" @click="addNumber">添加成员</el-button>
+      </el-col>
+      <el-col :span="2">
+        <el-dropdown trigger="click" placement="bottom" @command="dropdownCommand">
+          <el-button>批量管理</el-button>
+          <template #dropdown>
+            <el-dropdown-menu>
+              <el-dropdown-item command="启用">启用</el-dropdown-item>
+              <el-dropdown-item command="禁用">禁用</el-dropdown-item>
+              <el-dropdown-item command="删除">删除</el-dropdown-item>
+              <el-dropdown-item command="分配管理人">分配管理人</el-dropdown-item>
+            </el-dropdown-menu>
+          </template>
+        </el-dropdown>
+      </el-col>
+    </el-row>
+    <el-table
+      :data="tableData"
+      ref="operationListRef"
+      height="460"
+      @selection-change="handleSelectionChange"
+    >
+      <el-table-column type="selection" width="55"></el-table-column>
+      <el-table-column label="姓名" prop="username" width="80"></el-table-column>
+      <el-table-column label="手机号" prop="mobile" width="150"></el-table-column>
+      <el-table-column label="工号" prop="userId" width="200"></el-table-column>
+      <el-table-column label="类型" prop="typeAttr" width="100"></el-table-column>
+      <el-table-column label="归属" prop="deptName" width="200"></el-table-column>
+      <el-table-column label="所属机构" prop="deptName" width="200"></el-table-column>
+      <el-table-column label="人员状态" prop="status" width="150"></el-table-column>
+      <el-table-column label="账号状态" prop="isEnable" width="150"></el-table-column>
+      <el-table-column label="管理人" prop="leaderName" width="150"></el-table-column>
+      <el-table-column label="管理人工号" prop="leaderId" width="200"></el-table-column>
+      <el-table-column label="推荐人" prop="referrerName" width="150"></el-table-column>
+      <el-table-column label="推荐人工号" prop="referrerId" width="200"></el-table-column>
+      <el-table-column fixed="right" label="操作" width="120">
+        <template #default="scope">
+          <div style="display: flex; align-items: center; justify-content: space-between">
+            <a style="color: #409EFF; cursor: pointer" @click="showDetail(scope)">详情</a>&nbsp;
+            <el-dropdown placement="bottom" trigger="click" @command="tableDataCommand(scope, $event)">
+              <a style="color: #409EFF; cursor: pointer">更多</a>
+              <template #dropdown>
+                <el-dropdown-menu>
+                  <el-dropdown-item command="编辑">编辑</el-dropdown-item>
+                  <el-dropdown-item command="启用">启用</el-dropdown-item>
+                  <el-dropdown-item command="禁用">禁用</el-dropdown-item>
+                  <el-dropdown-item command="删除">删除</el-dropdown-item>
+                  <el-dropdown-item command="分配管理人">分配管理人</el-dropdown-item>
+                  <el-dropdown-item command="添加银行卡">添加银行卡</el-dropdown-item>
+                </el-dropdown-menu>
+              </template>
+            </el-dropdown>
+          </div>
+        </template>
+      </el-table-column>
+    </el-table>
+    <div style="display: flex; justify-content: center; margin-top: 15px">
+      <el-pagination
+        v-model:current-page="currentPage"
+        v-model:page-size="pageSize"
+        :page-sizes="[10, 20, 30, 40]"
+        layout="total, sizes, prev, pager, next, jumper"
+        :total="total"
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+      />
+    </div>
+    <el-dialog
+      v-model="dialogShow"
+      :title="title"
+      width="1000"
+    >
+      <addOperation @closeDialog="closeAddOperation"></addOperation>
+    </el-dialog>
+    <el-dialog
+      v-model="bankCardDialogShow"
+      title="添加银行卡"
+      width="500"
+    >
+      <addCard @closeDialog="closeAddBankCard"></addCard>
+    </el-dialog>
+    <el-dialog
+      v-model="allocationShow"
+      title="分配管理人"
+      width="800"
+    >
+      <allocation></allocation>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue'
+import { useRouter } from 'vue-router'
+import addOperation from './modules/addOperation.vue'
+import addCard from './modules/addCard.vue'
+import allocation from './modules/allocation.vue'
+import type { OperationSearch, OperationIsEnable } from '@/api/modules/operation.ts'
+import api from "@/api";
+import {ElMessageBox, ElMessage, TableInstance} from 'element-plus'
+import type { TabBarInstance } from 'element-plus'
+import Allocation from "@/views/operationManagement/modules/allocation.vue";
+
+let muRouter = useRouter()
+
+const operationListRef = ref<TableInstance>()
+
+interface TableDataProps {
+  username: string,
+  mobile: string,
+  id: string,
+  typeAttr: string,
+  deptName: string,
+  userId: string,
+  status: number,
+  isEnable: number,
+  leaderName: string,
+  leaderId: string,
+  referrerName: string,
+  referrerId: string
+}
+
+const organizationChange = (e) => {
+  console.log(123, e)
+}
+
+// 查询条件
+let form = ref<OperationSearch>({
+  salesman: '',
+  deptId: '',
+  typeAttr: '',
+  deptName: '',
+  status: '',
+  isEnable: '',
+  leaderId: ''
+})
+let options = [
+  {
+    value: 'guide',
+    label: 'Guide',
+    children: [
+      {
+        value: 'disciplines',
+        label: 'Disciplines',
+        children: [
+          {
+            value: 'consistency',
+            label: 'Consistency',
+          },
+          {
+            value: 'feedback',
+            label: 'Feedback',
+          },
+          {
+            value: 'efficiency',
+            label: 'Efficiency',
+          },
+          {
+            value: 'controllability',
+            label: 'Controllability',
+          },
+        ],
+      }
+    ]
+  }
+]
+// 获取列表数据
+const init = () => {
+  api.operationApi.operationList({
+    pages: currentPage.value,
+    size: pageSize.value,
+    ...form.value
+  }).then(res => {
+    if(res?.code == 200) {
+      tableData.value = res.data.records
+      total.value = res.data.total
+    } else {
+      ElMessage({
+        message: res?.msg,
+        type: 'error'
+      })
+    }
+  })
+}
+// 删除
+const operationDel = (id: string[]) => {
+  api.operationApi.operationDelete({ id: id }).then(res => {
+    if(res?.code == 200) {
+      ElMessage({
+        message: res.msg,
+        type: 'success'
+      })
+      init()
+    } else {
+      ElMessage({
+        message: res.msg,
+        type: 'warning'
+      })
+    }
+  })
+}
+const operationIsEnable = (data: OperationIsEnable) => {
+  api.operationApi.operationIsEnable(data).then(res => {
+    if(res?.code == 200) {
+      ElMessage({
+        message: res.msg,
+        type: 'success'
+      })
+      init()
+    } else {
+      ElMessage({
+        message: res.msg,
+        type: 'warning'
+      })
+    }
+  })
+}
+// 搜索
+const search = () => {
+  init();
+}
+// 重置
+const reset = () => {
+  form.value = {
+    salesman: '',
+    deptId: '',
+    typeAttr: '',
+    deptName: '',
+    status: '',
+    isEnable: '',
+    leaderId: ''
+  }
+  currentPage.value = 1
+  pageSize.value = 10
+  init()
+}
+// 全选的类型
+let selectType = ref('')
+// 外部全选是否勾选
+let selectAllValue = ref(false)
+// 外部的全选
+const selectAll = (type: boolean) => {
+  console.log(1111, type)
+  if(type) {
+    if(selectType.value) {
+      tableData.value.forEach((item: TableDataProps) => {
+        operationListRef.value!.toggleRowSelection(item, true)
+      })
+    }
+  } else {
+    tableData.value.forEach((item: TableDataProps) => {
+      operationListRef.value!.toggleRowSelection(item, false)
+    })
+    selectType.value = ''
+  }
+}
+// 表格组件中的勾选
+const handleSelectionChange = (row: TableDataProps) => {
+
+}
+// 全选类型改变
+const selectTypeChange = (type) => {
+  selectAllValue.value = true
+  tableData.value.forEach((item: TableDataProps) => {
+    operationListRef.value!.toggleRowSelection(item, true)
+  })
+}
+// 批量管理
+const dropdownCommand = (e) => {
+  switch (e) {
+    case '删除':
+      ElMessageBox({
+        title: '删除业务员',
+        message: '确定要删除该业务员吗?',
+        type: 'warning',
+        showCancelButton: true,
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+      }).then(( action ) => {
+        init()
+      }).catch(( action ) => {
+
+      })
+      break;
+    case '禁用':
+      ElMessageBox({
+        title: '禁用业务员',
+        message: '确定要禁用该业务员吗?',
+        type: 'warning',
+        showCancelButton: true,
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+      }).then(( action ) => {
+        init()
+      }).catch(( action ) => {
+
+      })
+      break;
+    case '启用':
+      ElMessageBox({
+        title: '启用业务员',
+        message: '确定要启用该业务员吗?',
+        type: 'warning',
+        showCancelButton: true,
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+      }).then(( action ) => {
+        init()
+      }).catch(( action ) => {
+
+      })
+      break;
+    case '分配管理人':
+      allocationShow.value = true
+      break;
+  }
+}
+// 列表数据
+let tableData = ref<TableDataProps[]>([])
+
+// 分页数据
+// 页码
+let currentPage = ref(1)
+// 单页数量
+let pageSize = ref(10)
+// 总数
+let total = ref(0)
+// 单页数量变化
+const handleSizeChange = (size) => {
+  pageSize.value = size
+  init()
+}
+// 页码变化
+const handleCurrentChange = (page) => {
+  currentPage.value = page
+  init()
+}
+
+// 详情
+const showDetail = (scope) => {
+  muRouter.push({
+    path: '/operationDetail',
+    query: {
+      id: scope.row.id
+    }
+  })
+}
+
+// 添加银行卡弹框
+let bankCardDialogShow = ref(false)
+
+// 更多
+const tableDataCommand = (scope, e) => {
+  switch (e) {
+    case '编辑':
+      dialogShow.value = true
+      title.value = '编辑'
+      break;
+    case '删除':
+      ElMessageBox({
+        title: '删除业务员',
+        message: '确定要删除该业务员吗?',
+        type: 'warning',
+        showCancelButton: true,
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+      }).then(( action ) => {
+        if(action === 'confirm') {
+          let ids = [scope.row.id]
+          console.log(123123, ids)
+          operationDel(ids)
+        }
+      }).catch(( action ) => {
+
+      })
+      break;
+    case '禁用':
+      ElMessageBox({
+        title: '禁用业务员',
+        message: '确定要禁用该业务员吗?',
+        type: 'warning',
+        showCancelButton: true,
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+      }).then(( action ) => {
+        if(action === 'confirm') {
+          let data = {
+            id: [scope.row.id],
+            isEnable: 0
+          }
+          operationIsEnable(data)
+        }
+      }).catch(( action ) => {
+
+      })
+      break;
+    case '启用':
+      ElMessageBox({
+        title: '启用业务员',
+        message: '确定要启用该业务员吗?',
+        type: 'warning',
+        showCancelButton: true,
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+      }).then(( action ) => {
+        if(action === 'confirm'){
+          let data = {
+            id: [scope.row.id],
+            isEnable: 1
+          }
+          operationIsEnable(data)
+        }
+      }).catch(( action ) => {
+
+      })
+      break;
+    case '添加银行卡':
+      bankCardDialogShow.value = true
+      break;
+    case '分配管理人':
+      allocationShow.value = true
+      break;
+  }
+}
+// 添加业务员
+const addNumber = () => {
+  dialogShow.value = true
+  title.value = '添加'
+}
+// 添加/编辑业务员弹框
+let dialogShow = ref(false)
+// 关闭新增弹框
+const closeAddOperation = (bool: boolean) => {
+  dialogShow.value = bool
+}
+// 关闭添加银行卡弹框
+const closeAddBankCard = (bool: boolean) => {
+  bankCardDialogShow.value = bool
+}
+// 添加/编辑业务员弹框标题
+let title = ref('添加')
+
+// 分配管理人
+let allocationShow = ref(false)
+
+onMounted(() => {
+  init()
+})
+
+</script>
+
+<style scoped lang="scss">
+.operation{
+  margin: 0 20px;
+  .operationForm{
+    margin: 20px 0;
+  }
+  .formItem{
+    width: 350px;
+  }
+  :deep(.select-all .el-select__wrapper){
+    box-shadow: none;
+    background: none;
+  }
+}
+</style>

+ 368 - 0
src/views/operationManagement/operationDetail.vue

@@ -0,0 +1,368 @@
+<template>
+  <div class="detail">
+    <div class="state">
+      <el-icon :size="20" style="color: red; margin: 3px 10px 0 0;">
+        <CircleClose />
+      </el-icon>
+      <div>
+        <h3>审核不通过</h3>
+        <p>失败原因。如有问题,请联系审核人员或者拨打客服电话400-400-400。</p>
+        <el-button link type="primary" @click="editDetail">修改并重提交</el-button>
+      </div>
+    </div>
+    <div class="info">
+      <el-descriptions>
+        <template #title>
+          <el-row :gutter="20" flex justify="space-between">
+            <el-col :span="12" style="display: flex; align-items: center;">
+              <span class="firstName">{{ dataDetail.username?dataDetail.username:'' }}</span>
+              <span class="allName">{{ dataDetail.username?dataDetail.username:'--' }}</span>
+            </el-col>
+            <el-col :span="12" style="display: flex; justify-content: flex-end">
+              <el-button plain @click="checkPass">审核通过</el-button>
+              <el-button plain @click="checkNotPass">审核不通过</el-button>
+              <el-button plain @click="editDetail">编辑</el-button>&nbsp;
+              <el-dropdown trigger="click" @command="handleCommand">
+                <el-button plain>更多</el-button>
+                <template #dropdown>
+                  <el-dropdown-menu>
+                    <el-dropdown-item command="启用">启用</el-dropdown-item>
+                    <el-dropdown-item command="禁用">禁用</el-dropdown-item>
+                    <el-dropdown-item command="删除">删除</el-dropdown-item>
+                    <el-dropdown-item command="分配管理人">分配管理人</el-dropdown-item>
+                  </el-dropdown-menu>
+                </template>
+              </el-dropdown>
+            </el-col>
+          </el-row>
+        </template>
+        <el-descriptions-item label="工号:">工号</el-descriptions-item>
+        <el-descriptions-item label="所属机构:">机构</el-descriptions-item>
+        <el-descriptions-item label="状态:">状态</el-descriptions-item>
+        <el-descriptions-item label="类型:">类型</el-descriptions-item>
+        <el-descriptions-item label="所属团队:">团队</el-descriptions-item>
+        <el-descriptions-item label="创建人:">创建人</el-descriptions-item>
+        <el-descriptions-item label="创建时间:">时间</el-descriptions-item>
+      </el-descriptions>
+      <el-tabs v-model="activeName" class="demo-tabs" @tab-click="(tab) => { activeName = tab }">
+        <el-tab-pane label="基本信息" name="msg">
+          <div class="other">
+            <el-descriptions title="个人信息">
+              <el-descriptions-item label="姓名:">姓名</el-descriptions-item>
+              <el-descriptions-item label="手机号:">手机号</el-descriptions-item>
+              <el-descriptions-item label="证件号:">证件号</el-descriptions-item>
+              <el-descriptions-item label="证件有效期始:">证件有效期始</el-descriptions-item>
+              <el-descriptions-item label="证件有效期止:">证件有效期止</el-descriptions-item>
+            </el-descriptions>
+            <el-descriptions title="其他信息">
+              <el-descriptions-item label="管理人:">管理人</el-descriptions-item>
+              <el-descriptions-item label="管理人工号:">管理人工号</el-descriptions-item>
+              <el-descriptions-item label="推荐人:">推荐人</el-descriptions-item>
+              <el-descriptions-item label="推荐人工号:">推荐人工号</el-descriptions-item>
+            </el-descriptions>
+            <el-descriptions title="银行卡信息">
+              <el-descriptions-item>
+                <template #default>
+                  <el-table
+                    :data="tableData"
+                  >
+                    <el-table-column prop="name" label="姓名"></el-table-column>
+                    <el-table-column prop="" label="开户行"></el-table-column>
+                    <el-table-column prop="" label="卡号"></el-table-column>
+                    <el-table-column prop="" label="开户支行"></el-table-column>
+                    <el-table-column prop="" label="审核状态"></el-table-column>
+                    <el-table-column prop="" label="身份证件照"></el-table-column>
+                    <el-table-column prop="" label="银行卡照"></el-table-column>
+                    <el-table-column label="操作">
+                      <template #default>
+                        <a style="color: #409EFF; cursor: pointer">详情</a>
+                      </template>
+                    </el-table-column>
+                  </el-table>
+                </template>
+              </el-descriptions-item>
+            </el-descriptions>
+            <el-button icon="plus" style="margin-left: 20px" @click="addBankCard">添加银行卡</el-button>
+          </div>
+        </el-tab-pane>
+        <el-tab-pane label="资料附件" name="file">
+          <div class="other">
+            <el-descriptions title="资料附件">
+              <el-descriptions-item>
+                <template #default>
+                  <div class="fileItem">
+                    <span class="label">身份证(人像面)</span>
+                    <div class="fileName">
+                      <span class="file-name">文件名文件名文件名文件名文件名文件名文件名文件名文件名文件名文件名文件名文件名文件名文件名文件名文件名文件名文件名文件名文件名</span>
+                      <el-icon class="file-icon"><View /></el-icon>
+                    </div>
+                  </div>
+                  <div class="fileItem">
+                    <span class="label">身份证(国徽面)</span>
+                    <div class="fileName">
+                      <span class="file-name">文件名</span>
+                      <el-icon class="file-icon"><View /></el-icon>
+                    </div>
+                  </div>
+                  <div class="fileItem">
+                    <span class="label">展业资格证</span>
+                    <div class="fileName">
+                      <span class="file-name">文件名</span>
+                      <el-icon class="file-icon"><View /></el-icon>
+                    </div>
+                  </div>
+                </template>
+              </el-descriptions-item>
+            </el-descriptions>
+          </div>
+        </el-tab-pane>
+      </el-tabs>
+    </div>
+    <el-dialog
+      v-model="bankCardDialogShow"
+      title="添加银行卡"
+      width="500"
+    >
+      <addCard></addCard>
+      <template #footer>
+        <div>
+          <el-button plain @click="() => { bankCardDialogShow = false }">取消</el-button>
+          <el-button type="primary">确定</el-button>
+        </div>
+      </template>
+    </el-dialog>
+    <el-dialog
+      v-model="dialogShow"
+      title="编辑"
+      width="1000"
+    >
+      <addOperation></addOperation>
+    </el-dialog>
+    <el-dialog
+      v-model="allocationShow"
+      title="分配管理人"
+      width="800"
+    >
+      <allocation></allocation>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue'
+import addOperation from './modules/addOperation.vue'
+import addCard from './modules/addCard.vue'
+import allocation from './modules/allocation.vue'
+import {ElMessage, ElMessageBox} from 'element-plus'
+import Allocation from "@/views/operationManagement/modules/allocation.vue";
+import { useRoute } from 'vue-router'
+import api from '@/api'
+
+const myRoute = useRoute()
+
+// 更多
+const handleCommand = (e) => {
+  switch (e) {
+    case '删除':
+      ElMessageBox({
+        title: '删除业务员',
+        message: '确定要删除该业务员吗?',
+        type: 'warning',
+        showCancelButton: true,
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+      }).then(( action ) => {
+
+      }).catch(( action ) => {
+
+      })
+      break;
+    case '禁用':
+      ElMessageBox({
+        title: '禁用业务员',
+        message: '确定要禁用该业务员吗?',
+        type: 'warning',
+        showCancelButton: true,
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+      }).then(( action ) => {
+
+      }).catch(( action ) => {
+
+      })
+      break;
+    case '启用':
+      ElMessage({
+        message: '启用成功!',
+        type: 'success',
+      })
+      break;
+    case '分配管理人':
+      allocationShow.value = true
+      break;
+  }
+}
+// 分配管理人
+let allocationShow = ref(false)
+
+// 银行卡列表数据
+let tableData = ref([])
+
+// Tabs切换
+let activeName = ref('msg')
+
+// 添加银行卡弹框
+let bankCardDialogShow = ref(false)
+// 添加银行卡
+const addBankCard = () => {
+  bankCardDialogShow.value = true
+}
+// 审核通过
+const checkPass = () => {
+  ElMessage({
+    message: '审核通过!',
+    type: 'success',
+  })
+}
+// 审核不通过
+const checkNotPass = () => {
+  ElMessageBox({
+    title: '审核不通过',
+    showInput: true,
+    inputPlaceholder: '请输入原因',
+    inputValue: '',
+    showCancelButton: true,
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+  }).then(( action ) => {
+
+  }).catch(( action ) => {
+
+  })
+}
+
+// 编辑/修改
+let dialogShow = ref(false)
+const editDetail = () => {
+  dialogShow.value = true
+}
+
+// 详情
+let dataDetail = ref({})
+const initDetail = () => {
+  let id = myRoute.query?.id
+  api.operationApi.operationDetail(id).then(res => {
+    console.log(123, res)
+    if(res?.code == 200) {
+      dataDetail.value = res.data.data
+    } else {
+      ElMessage({
+        message: res.msg,
+        type: 'warning'
+      })
+    }
+  })
+}
+
+onMounted(() => {
+  initDetail()
+})
+
+</script>
+
+<style scoped lang="scss">
+.detail{
+  margin: 0 10px;
+  .state{
+    border: 1px solid rgba(255,0,0,.3);
+    border-radius: 10px;
+    padding: 10px 20px;
+    background: #FFEFEE;
+    display: flex;
+    margin: 5px 0;
+    h3{
+      font-weight: 500;
+      margin: 0 0 10px;
+      color: rgba(0,0,0,.64);
+    }
+    p{
+      margin: 10px 0;
+      color: #888;
+    }
+  }
+  .info{
+    background: white;
+    padding: 5px 10px;
+    border-radius: 10px;
+    :deep(.el-descriptions__title) {
+      width: 100%;
+    }
+    :deep(.el-descriptions__body) {
+      padding-left: 60px;
+    }
+    :deep(.el-tabs__nav-wrap) {
+      padding: 0 25px;
+    }
+    :deep(.el-tabs__item) {
+      font-size: 18px;
+    }
+    .firstName{
+      width: 30px;
+      height: 30px;
+      text-align: center;
+      line-height: 30px;
+      border-radius: 15px;
+      background: #409EFF;
+      color: white;
+      font-size: 18px;
+      margin-right: 10px;
+      margin-left: 20px;
+    }
+    .allName{
+      font-size: 14px;
+    }
+    .other{
+      .fileItem{
+        display: flex;
+        justify-content: flex-start;
+        align-items: center;
+        margin: 10px 0;
+        .label{
+          width: 200px;
+        }
+        .fileName{
+          width: calc(100% - 500px);
+          line-height: 30px;
+          display: flex;
+          align-items: center;
+          padding: 0 20px;
+          &:hover{
+            background: #ccc;
+          }
+          .file-name{
+            width: 200px;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            white-space: nowrap;
+            margin-right: 20px;
+          }
+          .file-icon{
+            display: flex;
+            justify-content: flex-start;
+            align-items: center;
+            height: 30px;
+            cursor: pointer;
+            &:hover{
+              color: #00a0f4;
+            }
+          }
+        }
+      }
+      :deep(.el-descriptions__title) {
+        padding-left: 20px;
+        font-size: 16px;
+      }
+    }
+  }
+}
+</style>

+ 71 - 0
src/views/operationManagement/team.vue

@@ -0,0 +1,71 @@
+<template>
+  <div class="team">
+    <el-row :gutter="20">
+      <el-col :span="4">
+        <div>
+          <el-input class="search-input" v-model="teamValue" placeholder="团队名称查找" prefix-icon="Search"></el-input>
+
+        </div>
+        <el-button class="add-btn" link icon="plus">添加团队</el-button>
+      </el-col>
+      <el-col :span="20">
+        222
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue'
+
+// 团队
+let teamTree = ref([
+  {
+    label: '团队1',
+    value: '1',
+    children: [
+      {
+        label: '团队1-1',
+        value: '1-1',
+        children: [
+          {
+            label: '团队1-1-1',
+            value: '1-1-1',
+          }
+        ]
+      }
+    ]
+  },{
+    label: '团队2',
+    value: '2',
+    children: [
+      {
+        label: '团队2-1',
+        value: '2-1',
+        children: [
+          {
+            label: '团队2-1-1',
+            value: '2-1-1',
+          }
+        ]
+      }
+    ]
+  }
+])
+let teamValue = ref('')
+
+</script>
+
+<style scoped lang="scss">
+.team{
+  background: #00a0f4;
+  height: 100% !important;
+  .search-input{
+    margin: 10px 20px;
+  }
+  .add-btn{
+    display: block;
+    margin: 0 auto;
+  }
+}
+</style>

+ 11 - 0
src/views/operationManagement/telemarketing.vue

@@ -0,0 +1,11 @@
+<template>
+  <div>telemarketing</div>
+</template>
+
+<script setup>
+
+</script>
+
+<style scoped>
+
+</style>

+ 1 - 1
vite.config.ts

@@ -21,7 +21,7 @@ export default defineConfig(({ mode, command }) => {
     server: {
       open: true,
       host: '0.0.0.0', // 监听所有接口
-      port: 9000,
+      port: 9001,
       proxy: {
         '/proxy': {
           target: env.VITE_APP_API_BASEURL,