diff --git a/src/api/category_business.ts b/src/api/category_business.ts
new file mode 100644
index 0000000..3ffcc57
--- /dev/null
+++ b/src/api/category_business.ts
@@ -0,0 +1,26 @@
+import request from '@/utils/request'
+
+// 商机分类表列表
+export function apiCategoryBusinessLists(params: any) {
+    return request.get({ url: '/category_business.category_business/lists', params })
+}
+
+// 添加商机分类表
+export function apiCategoryBusinessAdd(params: any) {
+    return request.post({ url: '/category_business.category_business/add', params })
+}
+
+// 编辑商机分类表
+export function apiCategoryBusinessEdit(params: any) {
+    return request.post({ url: '/category_business.category_business/edit', params })
+}
+
+// 删除商机分类表
+export function apiCategoryBusinessDelete(params: any) {
+    return request.post({ url: '/category_business.category_business/delete', params })
+}
+
+// 商机分类表详情
+export function apiCategoryBusinessDetail(params: any) {
+    return request.get({ url: '/category_business.category_business/detail', params })
+}
\ No newline at end of file
diff --git a/src/api/perms/admin.ts b/src/api/perms/admin.ts
index 6f82a55..027b1c3 100644
--- a/src/api/perms/admin.ts
+++ b/src/api/perms/admin.ts
@@ -35,3 +35,7 @@ export function generateGontract(params: any) {
 export function sendMsgApi(params: any) {
     return request.get({ url: '/auth.admin/postsms', params })
 }
+// 废除合同
+export function abolition(params: any) {
+    return request.get({ url: '/auth.admin/abolition', params })
+}
diff --git a/src/views/category_business/edit.vue b/src/views/category_business/edit.vue
new file mode 100644
index 0000000..8ec1589
--- /dev/null
+++ b/src/views/category_business/edit.vue
@@ -0,0 +1,175 @@
+<template>
+    <div class="edit-popup">
+        <popup
+            ref="popupRef"
+            :title="popupTitle"
+            :async="true"
+            width="550px"
+            @confirm="handleSubmit"
+            @close="handleClose"
+        >
+            <el-form ref="formRef" :model="formData" label-width="90px" :rules="formRules">
+                <el-form-item label="名称" prop="name">
+                    <el-input v-model="formData.name" clearable placeholder="请输入名称" />
+                </el-form-item>
+                <el-form-item label="顶级分类" prop="pid">
+                    <el-select
+                        class="flex-1"
+                        v-model="formData.pid"
+                        clearable
+                        placeholder="请选择上级分类"
+                    >
+                        <el-option
+                            v-for="(item, index) in List.value"
+                            :key="index"
+                            :label="item.name"
+                            :value="parseInt(item.id)"
+                        />
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="排序" prop="sort">
+                    <el-input v-model="formData.sort" clearable placeholder="请输入排序" />
+                </el-form-item>
+                <el-form-item label="状态" prop="status">
+                    <el-radio-group v-model="formData.status" placeholder="请选择状态">
+                        <el-radio
+                            v-for="(item, index) in dictData.show_status"
+                            :key="index"
+                            :label="parseInt(item.value)"
+                        >
+                            {{ item.name }}
+                        </el-radio>
+                    </el-radio-group>
+                </el-form-item>
+            </el-form>
+        </popup>
+    </div>
+</template>
+
+<script lang="ts" setup name="categoryBusinessEdit">
+import type { FormInstance } from 'element-plus'
+import Popup from '@/components/popup/index.vue'
+import {
+    apiCategoryBusinessAdd,
+    apiCategoryBusinessEdit,
+    apiCategoryBusinessDetail,
+    apiCategoryBusinessLists
+} from '@/api/category_business'
+import { timeFormat } from '@/utils/util'
+import { computed, reactive, ref, shallowRef, type PropType } from 'vue'
+defineProps({
+    dictData: {
+        type: Object as PropType<Record<string, any[]>>,
+        default: () => ({})
+    }
+})
+const emit = defineEmits(['success', 'close'])
+const formRef = shallowRef<FormInstance>()
+const popupRef = shallowRef<InstanceType<typeof Popup>>()
+const mode = ref('add')
+
+// 弹窗标题
+const popupTitle = computed(() => {
+    return mode.value == 'edit' ? '编辑商机分类表' : '新增商机分类表'
+})
+
+// 表单数据
+const formData = reactive({
+    id: '',
+    name: '',
+    pid: '',
+    sort: '99',
+    status: ''
+})
+const List = reactive([])
+// 表单验证
+const formRules = reactive<any>({
+    name: [
+        {
+            required: true,
+            message: '请输入名称',
+            trigger: ['blur']
+        }
+    ],
+    pid: [
+        {
+            required: true,
+            message: '请选择上级id',
+            trigger: ['blur']
+        }
+    ],
+    sort: [
+        {
+            required: true,
+            message: '请输入排序',
+            trigger: ['blur']
+        }
+    ],
+    status: [
+        {
+            required: true,
+            message: '请选择状态(0停用 1正常)',
+            trigger: ['blur']
+        }
+    ]
+})
+
+// 获取详情
+const setFormData = async (data: Record<any, any>) => {
+    for (const key in formData) {
+        if (data[key] != null && data[key] != undefined) {
+            //@ts-ignore
+            formData[key] = data[key]
+        }
+    }
+}
+
+const getDetail = async (row: Record<string, any>) => {
+    const data = await apiCategoryBusinessDetail({
+        id: row.id
+    })
+    setFormData(data)
+}
+
+const getList = async () => {
+    const data = await apiCategoryBusinessLists({
+        page: 1,
+        limit: 1000,
+        pid: 0
+    })
+    List.value = [
+        {
+            id: 0,
+            name: '顶级分类'
+        },
+        ...data.lists
+    ]
+    console.log(List)
+}
+
+// 提交按钮
+const handleSubmit = async () => {
+    await formRef.value?.validate()
+    const data = { ...formData }
+    mode.value == 'edit' ? await apiCategoryBusinessEdit(data) : await apiCategoryBusinessAdd(data)
+    popupRef.value?.close()
+    emit('success')
+}
+
+//打开弹窗
+const open = (type = 'add') => {
+    mode.value = type
+    popupRef.value?.open()
+}
+
+// 关闭回调
+const handleClose = () => {
+    emit('close')
+}
+getList()
+defineExpose({
+    open,
+    setFormData,
+    getDetail
+})
+</script>
diff --git a/src/views/category_business/index.vue b/src/views/category_business/index.vue
new file mode 100644
index 0000000..bb5ba81
--- /dev/null
+++ b/src/views/category_business/index.vue
@@ -0,0 +1,172 @@
+<template>
+    <div>
+        <el-card class="!border-none mb-4" shadow="never">
+            <el-form class="mb-[-16px]" :model="queryParams" inline>
+                <el-form-item label="名称" prop="name">
+                    <el-input
+                        class="w-[280px]"
+                        v-model="queryParams.name"
+                        clearable
+                        placeholder="请输入名称"
+                    />
+                </el-form-item>
+                <el-form-item label="排序" prop="sort">
+                    <el-input
+                        class="w-[280px]"
+                        v-model="queryParams.sort"
+                        clearable
+                        placeholder="请输入排序"
+                    />
+                </el-form-item>
+                <el-form-item label="状态" prop="status">
+                    <el-select
+                        class="w-[280px]"
+                        v-model="queryParams.status"
+                        clearable
+                        placeholder="请选择状态"
+                    >
+                        <el-option label="全部" value=""></el-option>
+                        <el-option
+                            v-for="(item, index) in dictData.show_status"
+                            :key="index"
+                            :label="item.name"
+                            :value="item.value"
+                        />
+                    </el-select>
+                </el-form-item>
+                <el-form-item>
+                    <el-button type="primary" @click="resetPage">查询</el-button>
+                    <el-button @click="resetParams">重置</el-button>
+                </el-form-item>
+            </el-form>
+        </el-card>
+        <el-card class="!border-none" v-loading="pager.loading" shadow="never">
+            <el-button
+                v-perms="['category_business.category_business/add']"
+                type="primary"
+                @click="handleAdd"
+            >
+                <template #icon>
+                    <icon name="el-icon-Plus" />
+                </template>
+                新增
+            </el-button>
+            <el-button
+                v-perms="['category_business.category_business/delete']"
+                :disabled="!selectData.length"
+                @click="handleDelete(selectData)"
+            >
+                删除
+            </el-button>
+            <div class="mt-4">
+                <el-table :data="pager.lists" @selection-change="handleSelectionChange">
+                    <el-table-column type="selection" width="55" />
+                    <el-table-column label="id" prop="id" show-overflow-tooltip />
+                    <el-table-column label="名称" prop="name" show-overflow-tooltip />
+                    <el-table-column label="上级id" prop="pid">
+                        <template #default="{ row }">
+                            <dict-value :options="dictData.pid" :value="row.pid" />
+                        </template>
+                    </el-table-column>
+                    <el-table-column label="排序" prop="sort" show-overflow-tooltip />
+                    <el-table-column label="状态" prop="status">
+                        <template #default="{ row }">
+                            <dict-value :options="dictData.show_status" :value="row.status" />
+                        </template>
+                    </el-table-column>
+                    <el-table-column label="操作" width="120" fixed="right">
+                        <template #default="{ row }">
+                            <el-button
+                                v-perms="['category_business.category_business/edit']"
+                                type="primary"
+                                link
+                                @click="handleEdit(row)"
+                            >
+                                编辑
+                            </el-button>
+                            <el-button
+                                v-perms="['category_business.category_business/delete']"
+                                type="danger"
+                                link
+                                @click="handleDelete(row.id)"
+                            >
+                                删除
+                            </el-button>
+                        </template>
+                    </el-table-column>
+                </el-table>
+            </div>
+            <div class="flex mt-4 justify-end">
+                <pagination v-model="pager" @change="getLists" />
+            </div>
+        </el-card>
+        <edit-popup
+            v-if="showEdit"
+            ref="editRef"
+            :dict-data="dictData"
+            @success="getLists"
+            @close="showEdit = false"
+        />
+    </div>
+</template>
+
+<script lang="ts" setup name="categoryBusinessLists">
+import { usePaging } from '@/hooks/usePaging'
+import { useDictData } from '@/hooks/useDictOptions'
+import { apiCategoryBusinessLists, apiCategoryBusinessDelete } from '@/api/category_business'
+import { timeFormat } from '@/utils/util'
+import feedback from '@/utils/feedback'
+import EditPopup from './edit.vue'
+
+const editRef = shallowRef<InstanceType<typeof EditPopup>>()
+// 是否显示编辑框
+const showEdit = ref(false)
+
+// 查询条件
+const queryParams = reactive({
+    name: '',
+    sort: '',
+    status: ''
+})
+
+// 选中数据
+const selectData = ref<any[]>([])
+
+// 表格选择后回调事件
+const handleSelectionChange = (val: any[]) => {
+    selectData.value = val.map(({ id }) => id)
+}
+
+// 获取字典数据
+const { dictData } = useDictData('show_status')
+
+// 分页相关
+const { pager, getLists, resetParams, resetPage } = usePaging({
+    fetchFun: apiCategoryBusinessLists,
+    params: queryParams
+})
+
+// 添加
+const handleAdd = async () => {
+    showEdit.value = true
+    await nextTick()
+    editRef.value?.open('add')
+}
+
+// 编辑
+const handleEdit = async (data: any) => {
+    showEdit.value = true
+    await nextTick()
+    editRef.value?.open('edit')
+    editRef.value?.setFormData(data)
+}
+
+// 删除
+const handleDelete = async (id: number | any[]) => {
+    await feedback.confirm('确定要删除?')
+    await apiCategoryBusinessDelete({ id })
+    getLists()
+}
+
+getLists()
+</script>
diff --git a/src/views/permission/admin/index.vue b/src/views/permission/admin/index.vue
index 2759dec..3a2e3c0 100644
--- a/src/views/permission/admin/index.vue
+++ b/src/views/permission/admin/index.vue
@@ -118,6 +118,14 @@
                                     @click="handleDelete(row.id)"
                                     >删除</el-button
                                 >
+                                <el-button
+                                    v-if="row.is_contract == 1"
+                                    v-perms="['auth.admin/abolition']"
+                                    type="danger"
+                                    link
+                                    @click="handleAbolition(row.id)"
+                                    >废除合同</el-button
+                                >
                                 <template v-if="row.company_id != 0 && row.is_contract == 0">
                                     <el-button
                                         v-perms="['auth.admin/Draftingcontracts']"
@@ -174,7 +182,14 @@
 </template>
 
 <script lang="ts" setup name="admin">
-import { adminEdit, adminLists, adminDelete, generateGontract, sendMsgApi } from '@/api/perms/admin'
+import {
+    adminEdit,
+    adminLists,
+    adminDelete,
+    generateGontract,
+    sendMsgApi,
+    abolition
+} from '@/api/perms/admin'
 import { roleAll } from '@/api/perms/role'
 import { useDictOptions } from '@/hooks/useDictOptions'
 import { usePaging } from '@/hooks/usePaging'
@@ -263,6 +278,11 @@ const handleDelete = async (id: number) => {
     await adminDelete({ id })
     getLists()
 }
+const handleAbolition = async (id: number) => {
+    await feedback.confirm('确定要废除合同?')
+    await abolition({ id })
+    getLists()
+}
 
 const { optionsData } = useDictOptions<{
     role: any[]