我們對接過了菜單清單,這次來對接使用者,和之前一樣
@RestController
@RequestMapping("/sys/user")
public class SysUserController {
@Autowired
SysUserService sysUserService;
@GetMapping("page")
public JSObject<PageData<SysUserDTO>> page(@ApiIgnore @RequestParam Map<String, Object> params){
PageData<SysUserDTO> page = sysUserService.page(params);
return new JSObject<PageData<SysUserDTO>>().ok(page);
}
}
對應的前端代碼
<template>
<div class="xjl-sys__user">
<el-form
:inline="true"
:model="state.dataForm"
@keyup.enter="state.getDataList()"
>
<el-form-item>
<el-input
v-model="state.dataForm.username"
placeholder="使用者名"
clearable
/>
</el-form-item>
<el-form-item>
<el-button @click="query">查詢</el-button>
</el-form-item>
</el-form>
<el-table
v-loading="state.dataListLoading"
:data="state.dataList"
border
@selection-change="dataListSelectionChangeHandle"
@sort-change="dataListSortChangeHandle"
style="width: 100%"
>
<el-table-column
type="selection"
header-align="center"
align="center"
width="50"
/>
<el-table-column
prop="username"
label="使用者名"
sortable="custom"
header-align="center"
align="center"
/>
<el-table-column
prop="deptName"
label="部門名稱"
header-align="center"
align="center"
/>
<el-table-column
prop="email"
label="郵箱"
header-align="center"
align="center"
/>
<el-table-column
prop="mobile"
label="手機号"
sortable="custom"
header-align="center"
align="center"
/>
<el-table-column
prop="gender"
label="性别"
sortable="custom"
header-align="center"
align="center"
/>
<el-table-column
prop="status"
label="使用者狀态"
sortable="custom"
header-align="center"
align="center"
>
<template v-slot="scope">
<el-tag v-if="scope.row.status === 0" size="small" type="danger">正常</el-tag>
<el-tag v-else size="small" type="success">停用</el-tag>
</template>
</el-table-column>
<el-table-column
prop="createDate"
label="建立日期"
sortable="custom"
header-align="center"
align="center"
width="180"
/>
</el-table>
<el-pagination
:current-page="state.page"
:page-sizes="[10, 20, 50, 100]"
:page-size="state.limit"
:total="state.total"
layout="total, sizes, prev, pager, next, jumper"
@size-change="pageSizeChangeHandle"
@current-change="pageCurrentChangeHandle"
/>
</div>
</template>
<script setup lang="ts">
import { onMounted, reactive } from "vue";
import { http } from "@/utils/http";
defineOptions({
name: "User"
});
const state = reactive({
getDataListURL: "/sys/user/page",
dataListLoading: false,
dataForm: {},
dataList: [],
order: "",
orderField: "",
page: 1,
limit: 10,
total: 0
});
// 擷取資料清單
function query() {
if (!state.getDataListURL) {
return;
}
state.dataListLoading = true;
http
.get(state.getDataListURL, {
order: state.order,
orderField: state.orderField,
page: state.page,
limit: state.limit,
...state.dataForm
})
.then(res => {
state.dataListLoading = false;
state.dataList = res.data.list;
state.total = res.data.total;
})
.catch(() => {
state.dataListLoading = false;
});
}
// 分頁, 每頁條數
function pageSizeChangeHandle(val: number) {
state.page = 1;
state.limit = val;
query();
}
// 分頁, 目前頁
function pageCurrentChangeHandle(val: number) {
state.page = val;
query();
}
onMounted(() => {
query();
});
</script>
<style lang="scss" scoped>
.tableBox {
:deep .cell {
height: 40px !important;
}
}
</style>
我們發現這樣寫代碼,有好多共同點,後端我們已經用了代碼生成,可以一鍵生成,但是前端還要每次都寫一次,有些不優雅,是以這邊定義了一個hook
import { IObject, IViewHooks, IViewHooksOptions } from "@/../types/interface";
import { http } from "@/utils/http";
import { onMounted } from "vue";
const useView = (props: IViewHooksOptions | IObject): IViewHooks => {
const defaultOptions: IViewHooksOptions = {
createdIsNeed: true,
activatedIsNeed: false,
getDataListURL: "",
getDataListIsPage: false,
deleteURL: "",
deleteIsBatch: false,
deleteIsBatchKey: "id",
exportURL: "",
dataForm: {},
dataList: [],
order: "",
orderField: "",
page: 1,
limit: 10,
total: 0,
dataListLoading: false,
dataListSelections: [],
elTable: {}
};
const mergeDefaultStateToPageState = (
options: IObject,
props: IObject
): IViewHooksOptions => {
for (const key in options) {
if (!Object.getOwnPropertyDescriptor(props, key)) {
props[key] = options[key];
}
}
return props;
};
const state = mergeDefaultStateToPageState(defaultOptions, props);
onMounted(() => {
if (state.createdIsNeed && !state.activatedIsNeed) {
viewFns.query();
}
});
//
const viewFns = {
// 擷取資料清單
query() {
if (!state.getDataListURL) {
return;
}
state.dataListLoading = true;
http
.get(state.getDataListURL, {
order: state.order,
orderField: state.orderField,
page: state.getDataListIsPage ? state.page : null,
limit: state.getDataListIsPage ? state.limit : null,
...state.dataForm
})
.then((res: any) => {
state.dataListLoading = false;
state.dataList = state.getDataListIsPage ? res.data.list : res.data;
state.total = state.getDataListIsPage ? res.data.total : 0;
})
.catch(() => {
state.dataListLoading = false;
});
},
// 多選
dataListSelectionChangeHandle(val: IObject[]) {
state.dataListSelections = val;
},
// 排序
dataListSortChangeHandle(data: IObject) {
if (!data.order || !data.prop) {
state.order = "";
state.orderField = "";
return false;
}
state.order = data.order.replace(/ending$/, "");
state.orderField = data.prop.replace(/([A-Z])/g, "_$1").toLowerCase();
viewFns.query();
},
// 分頁, 每頁條數
pageSizeChangeHandle(val: number) {
state.page = 1;
state.limit = val;
viewFns.query();
},
// 分頁, 目前頁
pageCurrentChangeHandle(val: number) {
state.page = val;
viewFns.query();
},
//搜尋
getDataList() {
state.page = 1;
viewFns.query();
},
};
return {
...viewFns
};
};
export default useView;
在user上面代碼中引入hook
import useView from "@/hooks/useView";
import { reactive, toRefs } from "vue";
defineOptions({
name: "User"
});
const view = reactive({
getDataListURL: "/sys/user/page",
getDataListIsPage: true,
deleteURL: "/sys/user",
deleteIsBatch: true,
exportURL: "/sys/user/export",
dataForm: {
username: "",
deptId: "",
postId: "",
gender: ""
}
});
const state = reactive({ ...useView(view), ...toRefs(view) });