index.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. <template>
  2. <CollapseContainer
  3. class="sys-container"
  4. title="账户管理"
  5. :canExpan="false"
  6. helpMessage="账户管理"
  7. >
  8. <BasicTable
  9. ref="tableRef"
  10. @register="registerTable"
  11. rowKey="id"
  12. @selectionChange="selectionChange"
  13. @rowClick="rowClick"
  14. @rowDbClick="handleEdit"
  15. showTableSetting
  16. :canResize="true"
  17. :pagination="{
  18. pageSize: 10,
  19. defaultPageSize: 10,
  20. showSizeChanger: false,
  21. }"
  22. >
  23. <template #toolbar>
  24. <div class="tool-btn-wrap">
  25. <a-button type="primary" @click="handleAdd"> 添加 </a-button>
  26. <a-button color="error" :disabled="disable_btn" @click="deleteBatches"> 删除 </a-button>
  27. <a-button @click="openModal"> 导出 </a-button>
  28. </div>
  29. </template>
  30. <template #form-custom> custom-slot </template>
  31. <template #action="{ record }">
  32. <TableAction :actions="createActions(record)" stopButtonPropagation />
  33. </template>
  34. </BasicTable>
  35. <ExpExcelModel @register="register" @success="defaultHeader" />
  36. <Popup @register="addRegister" :popupData="popupData" @saveData="saveData" />
  37. <Info @register="infoRegister" />
  38. </CollapseContainer>
  39. </template>
  40. <script lang="ts">
  41. import { defineComponent, reactive, ref, toRefs, unref, createVNode } from 'vue';
  42. import { CollapseContainer } from '/@/components/Container/index';
  43. import Popup from './popup.vue';
  44. import Info from './info.vue';
  45. import { useMessage } from '/@/hooks/web/useMessage';
  46. import { useModal } from '/@/components/Modal';
  47. import { jsonToSheetXlsx, ExpExcelModel, ExportModalResult } from '/@/components/Excel';
  48. import { Modal } from 'ant-design-vue';
  49. import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
  50. import { getFormConfig, columns } from './data';
  51. import moment from 'moment';
  52. import {
  53. getAccountList,
  54. addAccount,
  55. deleteBatchesAccount,
  56. getAccount,
  57. getAccountRecordList,
  58. editAccount,
  59. deleteAccount,
  60. } from '/@/api/sys/money';
  61. import {
  62. BasicTable,
  63. useTable,
  64. TableAction,
  65. ActionItem,
  66. EditRecordRow,
  67. TableActionType,
  68. } from '/@/components/Table';
  69. interface PopupData {
  70. title: string;
  71. }
  72. interface Btn {
  73. disable_btn: boolean;
  74. }
  75. export default defineComponent({
  76. name: 'Account',
  77. components: { CollapseContainer, BasicTable, TableAction, Popup, Info, ExpExcelModel },
  78. setup() {
  79. const { createMessage } = useMessage();
  80. const { success /*, error*/ } = createMessage;
  81. const tableRef = ref<Nullable<TableActionType>>(null);
  82. const popupData = reactive<PopupData>({
  83. title: '添加',
  84. });
  85. const btn = reactive<Btn>({
  86. disable_btn: true,
  87. });
  88. const [registerTable] = useTable({
  89. rowSelection: { type: 'checkbox' },
  90. columns: columns,
  91. // clickToRowSelect: false, // 点击行不勾选
  92. api: getAccountList,
  93. useSearchForm: true,
  94. tableSetting: {
  95. redo: false,
  96. size: false,
  97. },
  98. beforeFetch: beforeFetch,
  99. afterFetch: afterFetch,
  100. formConfig: getFormConfig(),
  101. actionColumn: {
  102. width: 160,
  103. title: '操作',
  104. dataIndex: 'action',
  105. slots: { customRender: 'action' },
  106. fixed: undefined,
  107. },
  108. showIndexColumn: false,
  109. bordered: true,
  110. });
  111. const [register, { openModal }] = useModal();
  112. const [addRegister, { openModal: openPopup }] = useModal();
  113. const [infoRegister, { openModal: openInfo }] = useModal();
  114. function getTableAction() {
  115. // 获取组件
  116. const tableAction = unref(tableRef);
  117. if (!tableAction) {
  118. throw new Error('tableAction is null');
  119. }
  120. return tableAction;
  121. }
  122. // 请求之前处理
  123. function beforeFetch(params) {
  124. for (let k in params) {
  125. if (
  126. k !== 'page' &&
  127. k !== 'pageSize' &&
  128. k !== 'field' &&
  129. k !== 'order' &&
  130. k !== 'createdate'
  131. ) {
  132. if (params[k] === '') {
  133. delete params[k];
  134. } else {
  135. if (!params.filter) {
  136. params.filter = {};
  137. }
  138. if (params.createdate) {
  139. params.createdate = moment(params.createdate).format('YYYY-MM-DD');
  140. } else {
  141. delete params.createdate;
  142. }
  143. params.filter[k] = params[k];
  144. delete params[k];
  145. }
  146. }
  147. }
  148. params.filter = JSON.stringify(params.filter);
  149. params.offset = params.page;
  150. params.limit = params.pageSize;
  151. delete params.page;
  152. delete params.pageSize;
  153. }
  154. function afterFetch(result) {
  155. console.log(`result`, result);
  156. // tableData.result = result;
  157. }
  158. function handleAdd() {
  159. popupData.title = '添加';
  160. openPopup(true, {});
  161. }
  162. async function handleEdit(record: EditRecordRow) {
  163. popupData.title = '编辑';
  164. getAccount({ id: record.id }).then((res) => {
  165. const data = res.row;
  166. openPopup(true, data);
  167. });
  168. }
  169. async function handleInfo(record: Recordable) {
  170. popupData.title = '详情';
  171. getAccountRecordList({ id: record.id }).then((res) => {
  172. const data = res.list;
  173. openInfo(true, { info: data });
  174. });
  175. }
  176. async function handleDelete(record: Recordable) {
  177. console.log(record);
  178. await deleteAccount({ id: record.id }).then((res) => {
  179. console.log(res);
  180. getTableAction().reload();
  181. success('删除成功!');
  182. });
  183. }
  184. function selectionChange() {
  185. const keys = getTableAction().getSelectRowKeys();
  186. if (keys.length) {
  187. btn.disable_btn = false;
  188. } else {
  189. btn.disable_btn = true;
  190. }
  191. }
  192. function rowClick() {
  193. const keys = getTableAction().getSelectRowKeys();
  194. if (keys.length) {
  195. btn.disable_btn = false;
  196. } else {
  197. btn.disable_btn = true;
  198. }
  199. }
  200. async function deleteBatches() {
  201. const keys = await getTableAction().getSelectRowKeys();
  202. const count = keys.length;
  203. const ids = keys.toString();
  204. if (!ids) {
  205. return;
  206. }
  207. Modal.confirm({
  208. title: '删除提示',
  209. icon: createVNode(ExclamationCircleOutlined),
  210. content: '确定删除选中的' + count + '项?',
  211. okText: '确定',
  212. okType: 'danger',
  213. cancelText: '取消',
  214. maskClosable: true,
  215. async onOk() {
  216. await deleteBatchesAccount({ ids }).then((res) => {
  217. console.log(res);
  218. getTableAction().reload();
  219. success('删除成功!');
  220. getTableAction().setSelectedRowKeys([]);
  221. });
  222. },
  223. onCancel() {
  224. console.log('Cancel');
  225. },
  226. });
  227. }
  228. async function saveData(params: any) {
  229. const data = params.data;
  230. const closeModel = params.closeModal;
  231. console.log(`data`, data);
  232. if (!data.id) {
  233. await addAccount(data).then((res) => {
  234. console.log(res);
  235. getTableAction().reload();
  236. closeModel();
  237. success('创建成功!');
  238. });
  239. console.log('----------add---');
  240. } else {
  241. await editAccount(data).then((res) => {
  242. console.log(res);
  243. getTableAction().reload();
  244. closeModel();
  245. success('修改成功!');
  246. });
  247. console.log('----------edit---');
  248. }
  249. }
  250. function defaultHeader({ filename, bookType }: ExportModalResult) {
  251. // 默认Object.keys(data[0])作为header
  252. const jsondata = getTableAction().getDataSource();
  253. const excelData: object[] = [];
  254. jsondata.map((item, i) => {
  255. let data = {
  256. No: 0,
  257. id: '',
  258. name: '',
  259. amount: '',
  260. remark: '',
  261. createtime: '',
  262. };
  263. data.No = i + 1;
  264. data.id = item.id;
  265. data.name = item.name;
  266. data.amount = item.amount.toFixed(2);
  267. data.remark = item.remark;
  268. data.createtime = moment(item.createtime * 1000).format('YYYY-MM-DD');
  269. excelData.push(data);
  270. });
  271. jsonToSheetXlsx({
  272. data: excelData,
  273. header: {
  274. No: 'No.',
  275. id: 'ID',
  276. name: '账户名称',
  277. amount: '余额',
  278. remark: '备注',
  279. createtime: '创建日期',
  280. },
  281. filename,
  282. write2excelOpts: {
  283. bookType,
  284. },
  285. });
  286. }
  287. function createActions(record: EditRecordRow): ActionItem[] {
  288. return [
  289. {
  290. label: '详情',
  291. icon: 'ant-design:info-outlined',
  292. onClick: handleInfo.bind(null, record),
  293. },
  294. {
  295. label: '编辑',
  296. icon: 'ant-design:edit-outlined',
  297. color: 'warning',
  298. onClick: handleEdit.bind(null, record),
  299. },
  300. {
  301. label: '删除',
  302. color: 'error',
  303. icon: 'ic:outline-delete-outline',
  304. popConfirm: {
  305. title: '是否确认删除',
  306. confirm: handleDelete.bind(null, record),
  307. },
  308. },
  309. ];
  310. }
  311. return {
  312. popupData,
  313. tableRef,
  314. registerTable,
  315. handleAdd,
  316. handleEdit,
  317. deleteBatches,
  318. createActions,
  319. getTableAction,
  320. rowClick,
  321. selectionChange,
  322. addRegister,
  323. infoRegister,
  324. saveData,
  325. defaultHeader,
  326. openModal,
  327. register,
  328. ...toRefs(btn),
  329. };
  330. },
  331. });
  332. </script>
  333. <style scoped>
  334. .ant-calendar-picker {
  335. width: 100%;
  336. }
  337. /* @media (max-width: 639px) {
  338. .sys-container .vben-basic-table-header__toolbar > * {
  339. padding: 6px !important;
  340. margin-right: 3px;
  341. font-size: 12px !important;
  342. }
  343. .sys-container .vben-basic-table .ant-table-wrapper {
  344. padding: 3px;
  345. }
  346. } */
  347. .vben-basic-table-header__toolbar {
  348. justify-content: space-between;
  349. }
  350. .tool-btn-wrap {
  351. flex: 1;
  352. }
  353. .tool-btn-wrap button {
  354. margin-right: 5px;
  355. }
  356. </style>