diff --git a/src/api/crm/permission/index.ts b/src/api/crm/permission/index.ts
new file mode 100644
index 00000000..f71e2bfc
--- /dev/null
+++ b/src/api/crm/permission/index.ts
@@ -0,0 +1,32 @@
+import request from '@/config/axios'
+
+export interface PermissionVO {
+  id: number // 数据权限编号
+  userId: number // 用户编号
+  bizType: number // Crm 类型
+  bizId: number // Crm 类型数据编号
+  level: number // 权限级别
+  deptName: string // 部门名称
+  nickname: string // 用户昵称
+  postNames: string // 岗位名称数组
+}
+
+// 查询团队成员列表
+export const getPermissionList = async (params) => {
+  return await request.get({ url: `/crm/permission/list`, params })
+}
+
+// 新增团队成员
+export const createPermission = async (data: PermissionVO) => {
+  return await request.post({ url: `/crm/permission/add`, data })
+}
+
+// 修改团队成员
+export const updatePermission = async (data: PermissionVO) => {
+  return await request.put({ url: `/crm/permission/update`, data })
+}
+
+// 删除团队成员
+export const deletePermission = async (params) => {
+  return await request.delete({ url: '/crm/permission/delete', params })
+}
diff --git a/src/views/crm/components/CrmPermissionForm.vue b/src/views/crm/components/CrmPermissionForm.vue
new file mode 100644
index 00000000..1d217323
--- /dev/null
+++ b/src/views/crm/components/CrmPermissionForm.vue
@@ -0,0 +1,106 @@
+<template>
+  <Dialog v-model="dialogVisible" :title="dialogTitle">
+    <el-form
+      ref="formRef"
+      v-loading="formLoading"
+      :model="formData"
+      :rules="formRules"
+      label-width="100px"
+    >
+      <el-form-item v-if="formType === 'create'" label="选择人员" prop="userId">
+        <el-select v-model="formData.userId">
+          <el-option
+            v-for="item in userOptions"
+            :key="parseInt(item.id)"
+            :label="item.nickname"
+            :value="parseInt(item.id)"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="权限级别" prop="level">
+        <el-radio-group v-model="formData.level">
+          <el-radio label="2">只读</el-radio>
+          <el-radio label="3">读写</el-radio>
+        </el-radio-group>
+      </el-form-item>
+    </el-form>
+    <template #footer>
+      <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
+      <el-button @click="dialogVisible = false">取 消</el-button>
+    </template>
+  </Dialog>
+</template>
+<script lang="ts" setup>
+import * as UserApi from '@/api/system/user'
+
+defineOptions({ name: 'CrmPermissionForm' })
+const { t } = useI18n() // 国际化
+const message = useMessage() // 消息弹窗
+
+const dialogVisible = ref(false) // 弹窗的是否展示
+const dialogTitle = ref('') // 弹窗的标题
+const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+const formType = ref('') // 表单的类型:create - 新增;update - 修改
+const userOptions = ref<UserApi.UserVO[]>([]) // 用户列表
+const formData = ref({
+  userId: undefined, // 用户编号
+  bizType: undefined, // Crm 类型
+  bizId: undefined, // Crm 类型数据编号
+  level: undefined // 权限级别
+})
+const formRules = reactive({
+  userId: [{ required: true, message: '人员不能为空', trigger: 'blur' }],
+  level: [{ required: true, message: '权限级别不能为空', trigger: 'blur' }]
+})
+const formRef = ref() // 表单 Ref
+
+/** 打开弹窗 */
+const open = async (type: 'create' | 'update', bizType: number, bizId: number, id?: number) => {
+  dialogVisible.value = true
+  dialogTitle.value = t('action.' + type) + '团队成员'
+  formType.value = type
+  resetForm(bizType, bizId)
+  // 修改时,设置数据
+  if (id) {
+    formData.value.id = id
+  }
+  // 获得用户列表
+  userOptions.value = await UserApi.getSimpleUserList()
+}
+defineExpose({ open }) // 提供 open 方法,用于打开弹窗
+
+/** 提交表单 */
+const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
+const submitForm = async () => {
+  // 校验表单
+  if (!formRef) return
+  const valid = await formRef.value.validate()
+  if (!valid) return
+  // 提交请求
+  formLoading.value = true
+  try {
+    const data = formData.value
+    if (formType.value === 'create') {
+      message.success(t('common.createSuccess'))
+    } else {
+      message.success(t('common.updateSuccess'))
+    }
+    dialogVisible.value = false
+    // 发送操作成功的事件
+    emit('success')
+  } finally {
+    formLoading.value = false
+  }
+}
+
+/** 重置表单 */
+const resetForm = (bizType: number, bizId: number) => {
+  formData.value = {
+    userId: undefined, // 用户编号
+    bizType, // Crm 类型
+    bizId, // Crm 类型数据编号
+    level: undefined // 权限级别
+  }
+  formRef.value?.resetFields()
+}
+</script>
diff --git a/src/views/crm/components/CrmTeamList.vue b/src/views/crm/components/CrmTeamList.vue
new file mode 100644
index 00000000..824409b8
--- /dev/null
+++ b/src/views/crm/components/CrmTeamList.vue
@@ -0,0 +1,116 @@
+<template>
+  <!-- 操作栏 -->
+  <el-row justify="end">
+    <el-button type="primary" @click="handleAdd">
+      <Icon class="mr-5px" icon="ep:plus" />
+      新增
+    </el-button>
+    <el-button @click="handleEdit">
+      <Icon class="mr-5px" icon="ep:edit" />
+      编辑
+    </el-button>
+    <el-button @click="handleRemove">
+      <Icon class="mr-5px" icon="ep:delete" />
+      移除
+    </el-button>
+    <el-button type="danger" @click="handleQuit"> 退出团队</el-button>
+  </el-row>
+  <!--  团队成员展示 -->
+  <el-table
+    v-loading="loading"
+    :data="list"
+    :show-overflow-tooltip="true"
+    :stripe="true"
+    class="mt-20px"
+    @selection-change="handleSelectionChange"
+  >
+    <el-table-column type="selection" width="55" />
+    <el-table-column align="center" label="姓名" prop="mobile" />
+    <el-table-column align="center" label="部门" prop="detailAddress" />
+    <el-table-column align="center" label="岗位" prop="detailAddress" />
+    <el-table-column align="center" label="权限级别" prop="creatorName" />
+    <el-table-column :formatter="dateFormatter" align="center" label="加入时间" prop="createTime" />
+  </el-table>
+  <CrmPermissionForm ref="crmPermissionFormRef" />
+</template>
+<script lang="ts" setup>
+import { dateFormatter } from '@/utils/formatTime'
+import { ElTable } from 'element-plus'
+import * as PermissionApi from '@/api/crm/permission'
+import { useUserStoreWithOut } from '@/store/modules/user'
+import CrmPermissionForm from './CrmPermissionForm.vue'
+
+defineOptions({ name: 'CrmTeam' })
+const props = defineProps<{
+  bizType: number
+  bizId: number
+}>()
+const loading = ref(true) // 列表的加载中
+const list = ref<PermissionApi.PermissionVO[]>([]) // 列表的数据
+const getList = async () => {
+  loading.value = true
+  try {
+    const res = await PermissionApi.getPermissionList({
+      bizType: props.bizType,
+      bizId: props.bizId
+    })
+    list.value = res
+  } finally {
+    loading.value = false
+  }
+}
+
+const multipleSelection = ref<PermissionApi.PermissionVO[]>([])
+const handleSelectionChange = (val: PermissionApi.PermissionVO[]) => {
+  multipleSelection.value = val
+}
+const message = useMessage()
+const crmPermissionFormRef = ref<InstanceType<typeof CrmPermissionForm | null>>(null)
+const handleEdit = () => {
+  if (multipleSelection.value?.length === 0) {
+    message.warning('请先选择团队成员后操作!')
+    return
+  }
+  const ids = multipleSelection.value?.map((item) => item.id)
+  crmPermissionFormRef.value?.open('update', props.bizType, props.bizId, ids[0])
+}
+const handleRemove = async () => {
+  if (multipleSelection.value?.length === 0) {
+    message.warning('请先选择团队成员后操作!')
+    return
+  }
+  await message.delConfirm()
+  const ids = multipleSelection.value?.map((item) => item.id)
+  ids?.forEach((id) => {
+    // TODO 还不确定要不要搞个批量删除,还是一次只能删除一个,先用循环弄一下
+    PermissionApi.deletePermission({
+      bizType: props.bizType,
+      bizId: props.bizId,
+      id
+    })
+  })
+}
+const handleAdd = () => {
+  crmPermissionFormRef.value?.open('create', props.bizType, props.bizId)
+}
+
+const userStore = useUserStoreWithOut()
+const handleQuit = () => {
+  const permission = list.value.find(
+    (item) => item.userId === userStore.getUser.id && item.level === 1
+  )
+  if (permission) {
+    message.warning('负责人不能退出团队!')
+    return
+  }
+}
+
+watch(
+  () => props.bizId,
+  () => {
+    getList()
+  },
+  { immediate: true, deep: true }
+)
+</script>
+<style lang="scss" scoped></style>
diff --git a/src/views/crm/components/index.ts b/src/views/crm/components/index.ts
new file mode 100644
index 00000000..b0bf3e42
--- /dev/null
+++ b/src/views/crm/components/index.ts
@@ -0,0 +1,11 @@
+import CrmTeam from './CrmTeamList.vue'
+
+enum CrmBizTypeEnum {
+  CRM_LEADS = 1, // 线索
+  CRM_CUSTOMER = 2, // 客户
+  CRM_CONTACTS = 3, // 联系人
+  CRM_BUSINESS = 5, // 商机
+  CRM_CONTRACT = 6 // 合同
+}
+
+export { CrmTeam, CrmBizTypeEnum }
diff --git a/src/views/crm/customer/index.vue b/src/views/crm/customer/index.vue
index 073bf8cb..b214d7c1 100644
--- a/src/views/crm/customer/index.vue
+++ b/src/views/crm/customer/index.vue
@@ -2,36 +2,36 @@
   <ContentWrap>
     <!-- 搜索工作栏 -->
     <el-form
-      class="-mb-15px"
-      :model="queryParams"
       ref="queryFormRef"
       :inline="true"
+      :model="queryParams"
+      class="-mb-15px"
       label-width="68px"
     >
       <el-form-item label="客户名称" prop="name">
         <el-input
           v-model="queryParams.name"
-          placeholder="请输入客户名称"
-          clearable
-          @keyup.enter="handleQuery"
           class="!w-240px"
+          clearable
+          placeholder="请输入客户名称"
+          @keyup.enter="handleQuery"
         />
       </el-form-item>
       <el-form-item label="手机" prop="mobile">
         <el-input
           v-model="queryParams.mobile"
-          placeholder="请输入手机"
-          clearable
-          @keyup.enter="handleQuery"
           class="!w-240px"
+          clearable
+          placeholder="请输入手机"
+          @keyup.enter="handleQuery"
         />
       </el-form-item>
       <el-form-item label="所属行业" prop="industryId">
         <el-select
           v-model="queryParams.industryId"
-          placeholder="请选择所属行业"
-          clearable
           class="!w-240px"
+          clearable
+          placeholder="请选择所属行业"
         >
           <el-option
             v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_INDUSTRY)"
@@ -44,9 +44,9 @@
       <el-form-item label="客户等级" prop="level">
         <el-select
           v-model="queryParams.level"
-          placeholder="请选择客户等级"
-          clearable
           class="!w-240px"
+          clearable
+          placeholder="请选择客户等级"
         >
           <el-option
             v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_LEVEL)"
@@ -59,9 +59,9 @@
       <el-form-item label="客户来源" prop="source">
         <el-select
           v-model="queryParams.source"
-          placeholder="请选择客户来源"
-          clearable
           class="!w-240px"
+          clearable
+          placeholder="请选择客户来源"
         >
           <el-option
             v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_SOURCE)"
@@ -72,19 +72,27 @@
         </el-select>
       </el-form-item>
       <el-form-item>
-        <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
-        <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
-        <el-button type="primary" @click="openForm('create')" v-hasPermi="['crm:customer:create']">
-          <Icon icon="ep:plus" class="mr-5px" /> 新增
+        <el-button @click="handleQuery">
+          <Icon class="mr-5px" icon="ep:search" />
+          搜索
+        </el-button>
+        <el-button @click="resetQuery">
+          <Icon class="mr-5px" icon="ep:refresh" />
+          重置
+        </el-button>
+        <el-button v-hasPermi="['crm:customer:create']" type="primary" @click="openForm('create')">
+          <Icon class="mr-5px" icon="ep:plus" />
+          新增
         </el-button>
         <el-button
-          type="success"
-          plain
-          @click="handleExport"
-          :loading="exportLoading"
           v-hasPermi="['crm:customer:export']"
+          :loading="exportLoading"
+          plain
+          type="success"
+          @click="handleExport"
         >
-          <Icon icon="ep:download" class="mr-5px" /> 导出
+          <Icon class="mr-5px" icon="ep:download" />
+          导出
         </el-button>
       </el-form-item>
     </el-form>
@@ -92,77 +100,77 @@
 
   <!-- 列表 -->
   <ContentWrap>
-    <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
-      <el-table-column label="编号" align="center" prop="id" />
-      <el-table-column label="客户名称" align="center" prop="name" width="160" />
-      <el-table-column label="所属行业" align="center" prop="industryId" width="120">
+    <el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
+      <el-table-column align="center" label="编号" prop="id" />
+      <el-table-column align="center" label="客户名称" prop="name" width="160" />
+      <el-table-column align="center" label="所属行业" prop="industryId" width="120">
         <template #default="scope">
           <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_INDUSTRY" :value="scope.row.industryId" />
         </template>
       </el-table-column>
-      <el-table-column label="客户来源" align="center" prop="source" width="100">
+      <el-table-column align="center" label="客户来源" prop="source" width="100">
         <template #default="scope">
           <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_SOURCE" :value="scope.row.source" />
         </template>
       </el-table-column>
-      <el-table-column label="客户等级" align="center" prop="level" width="120">
+      <el-table-column align="center" label="客户等级" prop="level" width="120">
         <template #default="scope">
           <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="scope.row.level" />
         </template>
       </el-table-column>
-      <el-table-column label="手机" align="center" prop="mobile" width="120" />
-      <el-table-column label="详细地址" align="center" prop="detailAddress" width="200" />
-      <el-table-column label="负责人" align="center" prop="ownerUserName" />
-      <el-table-column label="所属部门" align="center" prop="ownerUserDept" />
-      <el-table-column label="创建人" align="center" prop="creatorName" />
+      <el-table-column align="center" label="手机" prop="mobile" width="120" />
+      <el-table-column align="center" label="详细地址" prop="detailAddress" width="200" />
+      <el-table-column align="center" label="负责人" prop="ownerUserName" />
+      <el-table-column align="center" label="所属部门" prop="ownerUserDept" />
+      <el-table-column align="center" label="创建人" prop="creatorName" />
       <el-table-column
-        label="创建时间"
-        align="center"
-        prop="createTime"
         :formatter="dateFormatter"
+        align="center"
+        label="创建时间"
+        prop="createTime"
         width="180px"
       />
-      <el-table-column label="成交状态" align="center" prop="dealStatus">
+      <el-table-column align="center" label="成交状态" prop="dealStatus">
         <template #default="scope">
           <dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.dealStatus" />
         </template>
       </el-table-column>
       <el-table-column
-        label="下次联系时间"
-        align="center"
-        prop="contactNextTime"
         :formatter="dateFormatter"
+        align="center"
+        label="下次联系时间"
+        prop="contactNextTime"
         width="180px"
       />
       <el-table-column
-        label="最后跟进时间"
-        align="center"
-        prop="contactLastTime"
         :formatter="dateFormatter"
+        align="center"
+        label="最后跟进时间"
+        prop="contactLastTime"
         width="180px"
       />
-      <el-table-column label="锁定状态" align="center" prop="lockStatus">
+      <el-table-column align="center" label="锁定状态" prop="lockStatus">
         <template #default="scope">
           <dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.lockStatus" />
         </template>
       </el-table-column>
       <!--  TODO @wanwan 距进入公海天数    -->
-      <el-table-column label="操作" align="center" min-width="150" fixed="right">
+      <el-table-column align="center" fixed="right" label="操作" min-width="150">
         <template #default="scope">
           <el-button link type="primary" @click="openDetail(scope.row.id)">详情</el-button>
           <el-button
+            v-hasPermi="['crm:customer:update']"
             link
             type="primary"
             @click="openForm('update', scope.row.id)"
-            v-hasPermi="['crm:customer:update']"
           >
             编辑
           </el-button>
           <el-button
+            v-hasPermi="['crm:customer:delete']"
             link
             type="danger"
             @click="handleDelete(scope.row.id)"
-            v-hasPermi="['crm:customer:delete']"
           >
             删除
           </el-button>
@@ -171,23 +179,26 @@
     </el-table>
     <!-- 分页 -->
     <Pagination
-      :total="total"
-      v-model:page="queryParams.pageNo"
       v-model:limit="queryParams.pageSize"
+      v-model:page="queryParams.pageNo"
+      :total="total"
       @pagination="getList"
     />
   </ContentWrap>
+  <!-- TODO 方便查看效果 -->
+  <CrmTeam :biz-id="1" :biz-type="CrmBizTypeEnum.CRM_CUSTOMER" />
 
   <!-- 表单弹窗:添加/修改 -->
   <CustomerForm ref="formRef" @success="getList" />
 </template>
 
-<script setup lang="ts">
-import { DICT_TYPE, getBoolDictOptions, getIntDictOptions } from '@/utils/dict'
+<script lang="ts" setup>
+import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
 import { dateFormatter } from '@/utils/formatTime'
 import download from '@/utils/download'
 import * as CustomerApi from '@/api/crm/customer'
 import CustomerForm from './CustomerForm.vue'
+import { CrmBizTypeEnum, CrmTeam } from '@/views/crm/components'
 
 defineOptions({ name: 'CrmCustomer' })