index.vue 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. <script setup lang="tsx">
  2. import { nextTick, ref } from 'vue';
  3. import { NButton, NPopconfirm, NTag } from 'naive-ui';
  4. import type { InternalRowData } from 'naive-ui/es/data-table/src/interface';
  5. import { enableStatusRecord } from '@/constants/business';
  6. import {
  7. fetchAddDepartment,
  8. fetchDeleteDepartment,
  9. fetchEditDepartment,
  10. fetchGetDepartmentList
  11. } from '@/service/api/system-department';
  12. import { useAppStore } from '@/store/modules/app';
  13. import { $t } from '@/locales';
  14. import { useForm } from '@/components/zt/Form/hooks/useForm';
  15. import { useModal } from '@/components/zt/Modal/hooks/useModal';
  16. import { formSchems, searchSchems } from './department.data';
  17. const appStore = useAppStore();
  18. const checkedRowKeys = ref([]);
  19. const wrapperRef = ref<HTMLElement | null>(null);
  20. const deptData = ref<Api.SystemManage.DepartmentModel[]>([]);
  21. const loading = ref(false);
  22. const [registerForm, { setFieldsValue, validate, getFieldsValue, updateSchema }] = useForm({
  23. schemas: formSchems,
  24. showSubmitButton: false,
  25. showAdvancedButton: false,
  26. showResetButton: false,
  27. labelWidth: 120,
  28. showActionButtonGroup: false,
  29. layout: 'horizontal',
  30. gridProps: {
  31. cols: 1,
  32. itemResponsive: true
  33. },
  34. collapsedRows: 1
  35. });
  36. const [registerSearchForm, { getFieldsValue: getSeachForm }] = useForm({
  37. labelWidth: 120,
  38. layout: 'horizontal',
  39. gridProps: {
  40. cols: '1 xl:4 s:1 l:3',
  41. itemResponsive: true
  42. },
  43. collapsedRows: 1,
  44. schemas: searchSchems
  45. });
  46. const colums: NaiveUI.TableColumn<InternalRowData>[] = [
  47. {
  48. key: 'deptId',
  49. title: '部门ID',
  50. align: 'center'
  51. },
  52. {
  53. key: 'deptName',
  54. title: '部门名称',
  55. align: 'center',
  56. minWidth: 120
  57. },
  58. {
  59. key: 'leaderUserName',
  60. title: '部门负责人',
  61. align: 'center'
  62. },
  63. {
  64. key: 'phone',
  65. title: '负责人电话',
  66. align: 'center'
  67. },
  68. {
  69. key: 'seq',
  70. title: '排序',
  71. align: 'center'
  72. },
  73. {
  74. key: 'status',
  75. title: '状态',
  76. align: 'center',
  77. width: 60,
  78. render: (row: InternalRowData) => {
  79. const tagMap: Record<Api.Common.EnableStatus, NaiveUI.ThemeColor> = {
  80. 1: 'success',
  81. 0: 'warning'
  82. };
  83. const status = row.status as Api.Common.EnableStatus;
  84. const label = $t(enableStatusRecord[status]);
  85. return <NTag type={tagMap[status]}>{label}</NTag>;
  86. }
  87. },
  88. {
  89. key: 'createTime',
  90. title: '创建时间',
  91. align: 'center',
  92. width: 160
  93. },
  94. {
  95. key: 'operate',
  96. title: $t('common.operate'),
  97. align: 'center',
  98. width: 130,
  99. fixed: 'right',
  100. render: (row: any) => (
  101. <div class="flex-center justify-end gap-8px">
  102. <NButton type="primary" ghost size="small" onClick={() => handleEdit(row)}>
  103. {$t('common.edit')}
  104. </NButton>
  105. {row.deptId != 1 && (
  106. <NPopconfirm onPositiveClick={() => handleDelete(row)}>
  107. {{
  108. default: () => $t('common.confirmDelete'),
  109. trigger: () => (
  110. <NButton type="error" ghost size="small">
  111. {$t('common.delete')}
  112. </NButton>
  113. )
  114. }}
  115. </NPopconfirm>
  116. )}
  117. </div>
  118. )
  119. }
  120. ];
  121. const [registerModal, { openModal, setModalProps, setSubLoading, closeModal }] = useModal({
  122. title: '部门',
  123. width: 800,
  124. isShowHeaderText: false
  125. });
  126. // const { checkedRowKeys, onBatchDeleted, onDeleted } = useTableOperate(data, 'id', getData);
  127. function handleAdd() {
  128. setModalProps({
  129. title: '新增部门'
  130. });
  131. openModal();
  132. }
  133. async function handleBatchDelete() {
  134. // request
  135. console.log(checkedRowKeys.value);
  136. }
  137. async function handleDelete(row: Recordable) {
  138. // request
  139. loading.value = true;
  140. await fetchDeleteDepartment(row.deptId);
  141. getDepartment({});
  142. loading.value = false;
  143. }
  144. function handleEdit(item: Api.SystemManage.DepartmentModel) {
  145. setModalProps({
  146. title: '编辑部门'
  147. });
  148. openModal(item);
  149. nextTick(async () => {
  150. await setFieldsValue(item);
  151. if (item.level == 1 && item.deptId == 1) {
  152. updateSchema([{ field: 'parentId', componentProps: { disabled: true } }]);
  153. }
  154. });
  155. }
  156. async function getDepartment(seachForm: Recordable) {
  157. console.log(seachForm);
  158. loading.value = true;
  159. const { data } = await fetchGetDepartmentList(seachForm as Recordable);
  160. deptData.value = data as Api.SystemManage.DepartmentModel[];
  161. loading.value = false;
  162. }
  163. // init
  164. getDepartment({});
  165. async function handleSubmit() {
  166. setSubLoading(false);
  167. await validate();
  168. setSubLoading(true);
  169. const form = getFieldsValue();
  170. const { error } = form.deptId ? await fetchEditDepartment(form) : await fetchAddDepartment(form);
  171. if (!error) {
  172. closeModal();
  173. getDepartment({});
  174. }
  175. }
  176. </script>
  177. <template>
  178. <div ref="wrapperRef" class="flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
  179. <NCard :bordered="false" size="small">
  180. <NCollapse display-directive="show" :default-expanded-names="['dept-search']">
  181. <NCollapseItem title="搜索" name="dept-search">
  182. <BasicForm
  183. @register-form="registerSearchForm"
  184. @submit="getDepartment(getSeachForm())"
  185. @reset="getDepartment({})"
  186. />
  187. </NCollapseItem>
  188. </NCollapse>
  189. </NCard>
  190. <NCard title="部门列表" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
  191. <template #header-extra>
  192. <TableHeaderOperation
  193. :disabled-delete="checkedRowKeys.length === 0"
  194. :loading="loading"
  195. is-add
  196. @add="handleAdd"
  197. @delete="handleBatchDelete"
  198. @refresh="getDepartment({})"
  199. />
  200. </template>
  201. <NDataTable
  202. v-model:checked-row-keys="checkedRowKeys"
  203. :columns="colums"
  204. :data="deptData"
  205. size="small"
  206. :flex-height="!appStore.isMobile"
  207. :scroll-x="1088"
  208. :loading="loading"
  209. :row-key="row => row.deptId"
  210. remote
  211. class="sm:h-full"
  212. />
  213. <BasicModal @register="registerModal" @ok="handleSubmit">
  214. <BasicForm @register-form="registerForm">
  215. <template #parentId="{ model, field }">
  216. <NTreeSelect
  217. v-model:value="model[field]"
  218. :options="deptData"
  219. label-field="deptName"
  220. key-field="deptId"
  221. ></NTreeSelect>
  222. </template>
  223. </BasicForm>
  224. </BasicModal>
  225. </NCard>
  226. </div>
  227. </template>
  228. <style scoped></style>