diff --git a/src/components/Table/src/components/TableImg.vue b/src/components/Table/src/components/TableImg.vue
index c5fda75..b8d347b 100644
--- a/src/components/Table/src/components/TableImg.vue
+++ b/src/components/Table/src/components/TableImg.vue
@@ -43,6 +43,7 @@ const props = defineProps({
   srcPrefix: propTypes.string.def(''),
   // fallback,加载失败显示图像占位符。
   fallback: propTypes.string.def(
+    // eslint-disable-next-line max-len
     'data:image/png;base64,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'
   )
 })
diff --git a/src/components/Table/src/types/table.ts b/src/components/Table/src/types/table.ts
index bcc380d..29b4aca 100644
--- a/src/components/Table/src/types/table.ts
+++ b/src/components/Table/src/types/table.ts
@@ -1,4 +1,4 @@
-import type { VNodeChild } from 'vue'
+import type { Ref, VNodeChild } from 'vue'
 import type { PaginationProps } from './pagination'
 import type { FormProps } from '@/components/Form'
 import type { TableRowSelection as ITableRowSelection } from 'ant-design-vue/lib/table/interface'
@@ -94,7 +94,7 @@ export interface TableActionType {
   getSelectRowKeys: () => string[]
   deleteSelectRowByKey: (key: string) => void
   setPagination: (info: Partial<PaginationProps>) => void
-  setTableData: <T = Recordable>(values: T[]) => void
+  setTableData: <T extends Ref<Recordable<any>[]>>(values: T[]) => void
   updateTableDataRecord: (rowKey: string | number, record: Recordable) => Recordable | void
   deleteTableDataRecord: (rowKey: string | number | string[] | number[]) => void
   insertTableDataRecord: (record: Recordable | Recordable[], index?: number) => Recordable[] | void
diff --git a/src/settings/componentSetting.ts b/src/settings/componentSetting.ts
index f2f8b93..24bc7d5 100644
--- a/src/settings/componentSetting.ts
+++ b/src/settings/componentSetting.ts
@@ -9,11 +9,11 @@ export default {
     // 支持 xxx.xxx.xxx格式
     fetchSetting: {
       // 传给后台的当前页字段
-      pageField: 'page',
+      pageField: 'pageNo',
       // 传给后台的每页显示多少条的字段
       sizeField: 'pageSize',
       // 接口返回表格数据的字段
-      listField: 'items',
+      listField: 'list',
       // 接口返回表格总数的字段
       totalField: 'total'
     },
diff --git a/src/views/system/post/PostModel.vue b/src/views/system/post/PostModel.vue
new file mode 100644
index 0000000..a20d7da
--- /dev/null
+++ b/src/views/system/post/PostModel.vue
@@ -0,0 +1,84 @@
+<template>
+  <BasicModal v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit">
+    <BasicForm @register="registerForm" />
+  </BasicModal>
+</template>
+<script lang="ts" setup name="PostModal">
+import { ref, computed, unref } from 'vue'
+import { BasicModal, useModalInner } from '@/components/Modal'
+import { BasicForm, FormSchema, useForm } from '@/components/Form'
+
+const formSchema: FormSchema[] = [
+  {
+    field: 'name',
+    label: '岗位名称',
+    required: true,
+    component: 'Input'
+  },
+  {
+    field: 'code',
+    label: '岗位编码',
+    required: true,
+    component: 'Input'
+  },
+  {
+    field: 'status',
+    label: '状态',
+    component: 'RadioButtonGroup',
+    defaultValue: '0',
+    componentProps: {
+      options: [
+        { label: '启用', value: '0' },
+        { label: '停用', value: '1' }
+      ]
+    }
+  },
+  {
+    label: '备注',
+    field: 'remark',
+    component: 'InputTextArea'
+  }
+]
+
+const emit = defineEmits(['success', 'register'])
+const isUpdate = ref(true)
+const rowId = ref('')
+
+const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({
+  labelWidth: 100,
+  baseColProps: { span: 24 },
+  schemas: formSchema,
+  showActionButtonGroup: false,
+  actionColOptions: {
+    span: 23
+  }
+})
+
+const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
+  resetFields()
+  setModalProps({ confirmLoading: false })
+  isUpdate.value = !!data?.isUpdate
+
+  if (unref(isUpdate)) {
+    rowId.value = data.record.id
+    setFieldsValue({
+      ...data.record
+    })
+  }
+})
+
+const getTitle = computed(() => (!unref(isUpdate) ? '新增账号' : '编辑账号'))
+
+async function handleSubmit() {
+  try {
+    const values = await validate()
+    setModalProps({ confirmLoading: true })
+    // TODO custom api
+    console.log(values)
+    closeModal()
+    emit('success', { isUpdate: unref(isUpdate), values: { ...values, id: rowId.value } })
+  } finally {
+    setModalProps({ confirmLoading: false })
+  }
+}
+</script>
diff --git a/src/views/system/post/index.vue b/src/views/system/post/index.vue
index 83cefa1..d72c932 100644
--- a/src/views/system/post/index.vue
+++ b/src/views/system/post/index.vue
@@ -1,3 +1,144 @@
 <template>
-  <div>index</div>
+  <div>
+    <BasicTable @register="registerTable">
+      <template #toolbar>
+        <a-button type="primary" @click="handleCreate"> 新增 </a-button>
+      </template>
+      <template #bodyCell="{ column, record }">
+        <template v-if="column.key === 'action'">
+          <TableAction
+            :actions="[
+              {
+                icon: 'clarity:note-edit-line',
+                onClick: handleEdit.bind(null, record)
+              },
+              {
+                icon: 'ant-design:delete-outlined',
+                color: 'error',
+                popConfirm: {
+                  title: '是否确认删除',
+                  placement: 'left',
+                  confirm: handleDelete.bind(null, record)
+                }
+              }
+            ]"
+          />
+        </template>
+      </template>
+    </BasicTable>
+    <PostModel @register="registerModal" @success="handleSuccess" />
+  </div>
 </template>
+<script lang="ts" setup name="Post">
+import { BasicTable, useTable, TableAction, BasicColumn, FormSchema } from '@/components/Table'
+import { getPostPageApi } from '@/api/system/post'
+import { useModal } from '@/components/Modal'
+import PostModel from './PostModel.vue'
+import dayjs from 'dayjs'
+
+const columns: BasicColumn[] = [
+  {
+    title: '岗位编号',
+    dataIndex: 'id',
+    width: 100
+  },
+  {
+    title: '岗位名称',
+    dataIndex: 'name',
+    width: 180
+  },
+  {
+    title: '岗位编码',
+    dataIndex: 'code',
+    width: 100
+  },
+  {
+    title: '岗位顺序',
+    dataIndex: 'sort',
+    width: 120
+  },
+  {
+    title: '状态',
+    dataIndex: 'status',
+    width: 180
+  },
+  {
+    title: '备注',
+    dataIndex: 'remark'
+  },
+  {
+    title: '创建时间',
+    dataIndex: 'createTime',
+    customRender: ({ text }) => {
+      return dayjs(text).format('YYYY-MM-DD HH:mm:ss')
+    }
+  }
+]
+
+const searchFormSchema: FormSchema[] = [
+  {
+    field: 'name',
+    label: '岗位名称',
+    component: 'Input',
+    colProps: { span: 8 }
+  },
+  {
+    field: 'code',
+    label: '岗位编码',
+    component: 'Input'
+  },
+  {
+    field: 'status',
+    label: '状态',
+    component: 'Select',
+    componentProps: {
+      options: [
+        { label: '启用', value: '0' },
+        { label: '停用', value: '1' }
+      ]
+    },
+    colProps: { span: 8 }
+  }
+]
+const [registerModal, { openModal }] = useModal()
+const [registerTable, { reload }] = useTable({
+  title: '岗位列表',
+  api: getPostPageApi,
+  columns,
+  formConfig: {
+    labelWidth: 120,
+    schemas: searchFormSchema
+  },
+  useSearchForm: true,
+  showTableSetting: true,
+  // bordered: true,
+  // showIndexColumn: false,
+  actionColumn: {
+    width: 120,
+    title: '操作',
+    dataIndex: 'action',
+    fixed: 'right'
+  }
+})
+
+function handleCreate() {
+  openModal(true, {
+    isUpdate: false
+  })
+}
+
+function handleEdit(record: Recordable) {
+  openModal(true, {
+    record,
+    isUpdate: true
+  })
+}
+
+function handleDelete(record: Recordable) {
+  console.log(record)
+}
+
+function handleSuccess() {
+  reload()
+}
+</script>