31
0
Fork 0

feat: 完成接口联调(用户、部门)

develop
JINGYJ 2 years ago
parent 35ca8e393c
commit 3d3a6788e6

@ -12,10 +12,10 @@ type Data = {
};
export const getHomeList = (params?: object) => {
return http.request<Result>("get", baseUrlApi(""), { params });
return http.request<Result>("get", baseUrlApi("tps"), { params });
};
export const getEvents = (params?: object) => {
return http.request<Data>("get", baseUrlApi("events"), { params });
return http.request<Data>("get", baseUrlApi("tps/events"), { params });
};
export const updateHomeList = (params?: object) => {
return http.request<Data>("put", baseUrlApi(""), { params });

@ -0,0 +1,84 @@
import { http } from "@/utils/http";
import { baseUrlApi } from "./utils";
type deptResult = {
data: Array<any>;
};
/** 部门列表查询 */
export const getDeptList = (params?: object) => {
return http.request<deptResult>("get", baseUrlApi("departments/"), {
params
});
};
type deptStatus = {
success: boolean;
msg: any;
};
/** 新增部门 */
export const addDept = (data?: object) => {
return http.request<deptStatus>("post", baseUrlApi("departments/"), {
data
});
};
/** 更新部门 */
export const updateDept = (data?: object | any) => {
return http.request<deptStatus>(
"put",
baseUrlApi(`departments/${data.id}/`),
{
data
}
);
};
/** 删除部门 */
export const deleteDept = (data?: object | any) => {
return http.request<deptStatus>(
"delete",
baseUrlApi(`departments/${data}/`),
{
data
}
);
};
type userList = {
count: number;
next: any;
previous: any;
results?: Array<any>;
};
/** 用户列表查询 */
export const getUserList = (params?: object) => {
return http.request<userList>("get", baseUrlApi("user/"), {
params
});
};
type userStatus = {
success: boolean;
msg: any;
};
/** 新增用户 */
export const addUser = (data?: object) => {
return http.request<userStatus>("post", baseUrlApi("user/"), { data });
};
/** 更新用户 */
export const updateUser = (data?: object | any) => {
return http.request<userStatus>("put", baseUrlApi(`user/${data.id}/`), {
data
});
};
/** 删除用户 */
export const deleteUser = (data?: object | any) => {
return http.request<userStatus>("delete", baseUrlApi(`user/${data}/`), {
data
});
};

@ -37,7 +37,7 @@ export type RefreshTokenResult = {
// return http.request<UserResult>("post", "/login", { data });
// };
export const getLogin = (data?: object) => {
return http.request<UserResult>("post", baseUrlApi("login"), { data });
return http.request<UserResult>("post", baseUrlApi("user/login/"), { data });
};
// export const getLogin = (data?: object) => {

@ -4,7 +4,7 @@ export default {
meta: {
icon: "informationLine",
title: "异常页面",
// showLink: false,
showLink: false,
rank: 9
},
children: [

@ -4,7 +4,7 @@ export default {
meta: {
icon: "lollipop",
title: "权限管理",
// showLink: false,
showLink: false,
rank: 2
},
children: [

@ -3,7 +3,7 @@ import { ref } from "vue";
import ReCol from "@/components/ReCol";
import { formRules } from "./utils/rule";
import { FormProps } from "./utils/types";
import { usePublicHooks } from "../hooks";
// import { usePublicHooks } from "../hooks";
const props = withDefaults(defineProps<FormProps>(), {
formInline: () => ({
@ -15,12 +15,13 @@ const props = withDefaults(defineProps<FormProps>(), {
email: "",
sort: 0,
status: 1,
remark: ""
remark: "",
id: ""
})
});
const ruleFormRef = ref();
const { switchStyle } = usePublicHooks();
// const { switchStyle } = usePublicHooks();
const newFormInline = ref(props.formInline);
function getRef() {
@ -71,7 +72,7 @@ defineExpose({ getRef });
/>
</el-form-item>
</re-col>
<re-col :value="12" :xs="24" :sm="24">
<!-- <re-col :value="12" :xs="24" :sm="24">
<el-form-item label="部门负责人">
<el-input
v-model="newFormInline.principal"
@ -132,7 +133,7 @@ defineExpose({ getRef });
type="textarea"
/>
</el-form-item>
</re-col>
</re-col> -->
</el-row>
</el-form>
</template>

@ -28,6 +28,7 @@ const {
handleDelete,
handleSelectionChange
} = useDept();
console.log(dataList);
</script>
<template>
@ -73,7 +74,7 @@ const {
</el-form>
<PureTableBar
title="部门列表(仅演示,操作后不生效)"
title="部门列表"
:columns="columns"
:tableRef="tableRef?.getTableRef()"
@refresh="onSearch"

@ -1,8 +1,8 @@
import dayjs from "dayjs";
import editForm from "../form.vue";
import { handleTree } from "@/utils/tree";
// import { handleTree } from "@/utils/tree";
import { message } from "@/utils/message";
// import { getDeptList } from "@/api/system";
import { getDeptList, addDept, updateDept, deleteDept } from "@/api/system";
import { usePublicHooks } from "../../hooks";
import { addDialog } from "@/components/ReDialog";
import { reactive, ref, onMounted, h } from "vue";
@ -27,11 +27,11 @@ export function useDept() {
width: 180,
align: "left"
},
{
label: "排序",
prop: "sort",
minWidth: 70
},
// {
// label: "排序",
// prop: "sort",
// minWidth: 70
// },
{
label: "状态",
prop: "status",
@ -72,161 +72,44 @@ export function useDept() {
onSearch();
}
const deptList = reactive({
data: [
{
name: "杭州总公司",
parentId: 0,
id: 100,
sort: 0,
phone: "15888888888",
principal: "@cname()",
email: "@email",
status: 1, // 状态 1 启用 0 停用
type: 1, // 1 公司 2 分公司 3 部门
createTime: 1605456000000,
remark: "@cparagraph(1, 3)"
},
{
name: "郑州分公司",
parentId: 100,
id: 101,
sort: 1,
phone: "15888888888",
principal: "@cname()",
email: "@email",
status: 1,
type: 2,
createTime: 1605456000000,
remark: "@cparagraph(1, 3)"
},
{
name: "研发部门",
parentId: 101,
id: 103,
sort: 1,
phone: "15888888888",
principal: "@cname()",
email: "@email",
status: 1,
type: 3,
createTime: 1605456000000,
remark: "@cparagraph(1, 3)"
},
{
name: "市场部门",
parentId: 102,
id: 108,
sort: 1,
phone: "15888888888",
principal: "@cname()",
email: "@email",
status: 1,
type: 3,
createTime: 1605456000000,
remark: "@cparagraph(1, 3)"
},
{
name: "深圳分公司",
parentId: 100,
id: 102,
sort: 2,
phone: "15888888888",
principal: "@cname()",
email: "@email",
status: 1,
type: 2,
createTime: 1605456000000,
remark: "@cparagraph(1, 3)"
},
{
name: "市场部门",
parentId: 101,
id: 104,
sort: 2,
phone: "15888888888",
principal: "@cname()",
email: "@email",
status: 1,
type: 3,
createTime: 1605456000000,
remark: "@cparagraph(1, 3)"
},
{
name: "财务部门",
parentId: 102,
id: 109,
sort: 2,
phone: "15888888888",
principal: "@cname()",
email: "@email",
status: 1,
type: 3,
createTime: 1605456000000,
remark: "@cparagraph(1, 3)"
},
{
name: "测试部门",
parentId: 101,
id: 105,
sort: 3,
phone: "15888888888",
principal: "@cname()",
email: "@email",
status: 0,
type: 3,
createTime: 1605456000000,
remark: "@cparagraph(1, 3)"
},
{
name: "财务部门",
parentId: 101,
id: 106,
sort: 4,
phone: "15888888888",
principal: "@cname()",
email: "@email",
status: 1,
type: 3,
createTime: 1605456000000,
remark: "@cparagraph(1, 3)"
},
{
name: "运维部门",
parentId: 101,
id: 107,
sort: 5,
phone: "15888888888",
principal: "@cname()",
email: "@email",
status: 0,
type: 3,
createTime: 1605456000000,
remark: "@cparagraph(1, 3)"
}
]
});
// function getDeptList() {
// // http.request("post", "/login")
// return deptList;
// }
function getDeptList() {
// http.request("post", "/login")
return deptList;
// 递归函数用于在多维数组中过滤包含嵌套子级
function filterNested(arr, filterFn) {
return arr.filter(item => {
if (filterFn(item)) {
return true;
}
if (item.children && item.children.length > 0) {
item.children = filterNested(item.children, filterFn);
return item.children.length > 0;
}
return false;
});
}
async function onSearch() {
loading.value = true;
// const { data } = await getDeptList(); // 这里是返回一维数组结构前端自行处理成树结构返回格式要求唯一id加父节点parentIdparentId取父节点id
const data = getDeptList();
let newData = data.data;
const { data } = await getDeptList();
console.log(data);
let newData = data;
console.log(newData, "newData");
if (!isAllEmpty(form.name)) {
// 前端搜索部门名称
newData = newData.filter(item => item.name.includes(form.name));
// newData = newData.filter(item => item.name.includes(form.name));
newData = filterNested(newData, item => item.name.includes(form.name));
}
if (!isAllEmpty(form.status)) {
// 前端搜索状态
newData = newData.filter(item => item.status === form.status);
// newData = newData.filter(item => item.status === form.status);
newData = filterNested(newData, item => item.status === form.status);
}
dataList.value = handleTree(newData); // 处理成树结构
// dataList.value = handleTree(newData); // 处理成树结构
dataList.value = newData; // 处理成树结构
setTimeout(() => {
loading.value = false;
}, 500);
@ -250,14 +133,15 @@ export function useDept() {
props: {
formInline: {
higherDeptOptions: formatHigherDeptOptions(cloneDeep(dataList.value)),
parentId: row?.parentId ?? 0,
parentId: row?.id ?? "",
name: row?.name ?? "",
principal: row?.principal ?? "",
phone: row?.phone ?? "",
email: row?.email ?? "",
sort: row?.sort ?? 0,
status: row?.status ?? 1,
remark: row?.remark ?? ""
remark: row?.remark ?? "",
id: row?.id ?? ""
}
},
width: "40%",
@ -281,26 +165,53 @@ export function useDept() {
// 表单规则校验通过
if (title === "新增") {
// 实际开发先调用新增接口,再进行下面操作
const addItem: any = curData;
// const addItem = {
// name: "运维部门",
// parentId: 101,
// id: 110,
// sort: 5,
// phone: "15888888888",
// principal: "@cname()",
// email: "@email",
// status: 0,
// type: 3,
// createTime: 1605456000000,
// remark: "@cparagraph(1, 3)"
// };
// const { addItem } = curData;
deptList.data.push(addItem);
chores();
// const addItem: any = curData;
// // const addItem = {
// // name: "运维部门",
// // parentId: 101,
// // id: 110,
// // sort: 5,
// // phone: "15888888888",
// // principal: "@cname()",
// // email: "@email",
// // status: 0,
// // type: 3,
// // createTime: 1605456000000,
// // remark: "@cparagraph(1, 3)"
// // };
// // const { addItem } = curData;
// deptList.data.push(addItem);
const params = {
department_name: curData.name,
department_id: curData.parentId
};
addDept(params).then(res => {
if (res.success) {
chores();
}
});
} else {
const params = {
name: curData.name,
id: curData.id
};
updateDept(params)
.then(res => {
if (res.success) {
chores();
} else {
message(`${res.msg}`, {
type: "warning"
});
}
})
.catch(error => {
message(`${error}`, {
type: "warning"
});
});
// 实际开发先调用编辑接口,再进行下面操作
chores();
}
}
});
@ -309,8 +220,16 @@ export function useDept() {
}
function handleDelete(row) {
message(`您删除了部门名称为${row.name}的这条数据`, { type: "success" });
onSearch();
deleteDept(row.id).then(res => {
if (!res.success) {
message(`${res.msg}`, {
type: "warning"
});
} else {
message(`您删除了部门名称为${row.name}的这条数据`, { type: "success" });
onSearch();
}
});
}
onMounted(() => {

@ -8,6 +8,7 @@ interface FormItemProps {
sort: number;
status: number;
remark: string;
id: string | number;
}
interface FormProps {
formInline: FormItemProps;

@ -1,175 +1,24 @@
<script setup lang="ts">
import { ref } from "vue";
import ReCol from "@/components/ReCol";
import { formRules } from "./utils/rule";
import { FormProps } from "./utils/types";
const props = withDefaults(defineProps<FormProps>(), {
formInline: () => ({
/** 角色名称 */
higherDeptOptions: [],
department_id: "",
username: "",
/** 角色编号 */
code: "",
/** 备注 */
remark: "",
/** 手机号 */
mobile: "",
/** 性别 */
sex: null,
/** 状态 */
status: null,
/** 组织 */
deptId: null
phone_number: "",
status: 1,
gender: null,
id: ""
})
});
const ruleFormRef = ref();
const newFormInline = ref(props.formInline);
// const deptList = reactive([
// {
// name: "",
// parentId: 0,
// id: 100,
// sort: 0,
// phone: "15888888888",
// principal: "@cname()",
// email: "@email",
// status: 1, // 1 0
// type: 1, // 1 2 3
// createTime: 1605456000000,
// remark: "@cparagraph(1, 3)"
// },
// {
// name: "",
// parentId: 100,
// id: 101,
// sort: 1,
// phone: "15888888888",
// principal: "@cname()",
// email: "@email",
// status: 1,
// type: 2,
// createTime: 1605456000000,
// remark: "@cparagraph(1, 3)"
// },
// {
// name: "",
// parentId: 101,
// id: 103,
// sort: 1,
// phone: "15888888888",
// principal: "@cname()",
// email: "@email",
// status: 1,
// type: 3,
// createTime: 1605456000000,
// remark: "@cparagraph(1, 3)"
// },
// {
// name: "",
// parentId: 102,
// id: 108,
// sort: 1,
// phone: "15888888888",
// principal: "@cname()",
// email: "@email",
// status: 1,
// type: 3,
// createTime: 1605456000000,
// remark: "@cparagraph(1, 3)"
// },
// {
// name: "",
// parentId: 100,
// id: 102,
// sort: 2,
// phone: "15888888888",
// principal: "@cname()",
// email: "@email",
// status: 1,
// type: 2,
// createTime: 1605456000000,
// remark: "@cparagraph(1, 3)"
// },
// {
// name: "",
// parentId: 101,
// id: 104,
// sort: 2,
// phone: "15888888888",
// principal: "@cname()",
// email: "@email",
// status: 1,
// type: 3,
// createTime: 1605456000000,
// remark: "@cparagraph(1, 3)"
// },
// {
// name: "",
// parentId: 102,
// id: 109,
// sort: 2,
// phone: "15888888888",
// principal: "@cname()",
// email: "@email",
// status: 1,
// type: 3,
// createTime: 1605456000000,
// remark: "@cparagraph(1, 3)"
// },
// {
// name: "",
// parentId: 101,
// id: 105,
// sort: 3,
// phone: "15888888888",
// principal: "@cname()",
// email: "@email",
// status: 0,
// type: 3,
// createTime: 1605456000000,
// remark: "@cparagraph(1, 3)"
// },
// {
// name: "",
// parentId: 101,
// id: 106,
// sort: 4,
// phone: "15888888888",
// principal: "@cname()",
// email: "@email",
// status: 1,
// type: 3,
// createTime: 1605456000000,
// remark: "@cparagraph(1, 3)"
// },
// {
// name: "",
// parentId: 101,
// id: 107,
// sort: 5,
// phone: "15888888888",
// principal: "@cname()",
// email: "@email",
// status: 0,
// type: 3,
// createTime: 1605456000000,
// remark: "@cparagraph(1, 3)"
// }
// ]);
// const buildTree = (data: any, parentId: number) => {
// const children = data.filter(
// (node: { parentId: number }) => node.parentId === parentId
// );
// return children.map((node: { id: any; name: any }) => {
// const { id, name } = node;
// return {
// value: id,
// label: name,
// children: buildTree(data, id)
// };
// });
// };
function getRef() {
return ruleFormRef.value;
}
@ -184,47 +33,79 @@ defineExpose({ getRef });
:rules="formRules"
label-width="82px"
>
<el-form-item label="用户名称" prop="username">
<el-input
v-model="newFormInline.username"
clearable
placeholder="请输入用户名称"
/>
</el-form-item>
<el-form-item label="手机号">
<el-input
v-model="newFormInline.mobile"
clearable
placeholder="请输入手机号"
/>
</el-form-item>
<el-form-item label="状态">
<el-switch
v-model="newFormInline.status"
class="ml-2"
inline-prompt
:active-value="1"
:inactive-value="0"
active-text="已开启"
inactive-text="已关闭"
/>
</el-form-item>
<el-form-item label="性别" prop="sex">
<el-select v-model="newFormInline.sex" placeholder="请选择">
<el-option label="未知" :value="2" />
<el-option label="男" :value="0" />
<el-option label="女" :value="1" />
</el-select>
</el-form-item>
<!-- <el-form-item label="所属部门" prop="deptId">
<el-tree-select
v-model="newFormInline.deptId"
placeholder="请选择所属部门"
:data="buildTree(deptList, 0)"
filterable
check-strictly
:render-after-expand="false"
/>
</el-form-item> -->
<el-row :gutter="30">
<re-col>
<el-form-item label="部门" prop="department_id">
<el-cascader
class="w-full"
v-model="newFormInline.department_id"
:options="newFormInline.higherDeptOptions"
:props="{
value: 'id',
label: 'name',
emitPath: false,
checkStrictly: true,
disabled: function (data) {
if (data.children && data.children.length > 0) {
return true;
} else {
return false;
}
}
}"
:show-all-levels="false"
clearable
filterable
placeholder="请选择部门"
>
<template #default="{ node, data }">
<span>{{ data.name }}</span>
<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
</template>
</el-cascader>
</el-form-item>
</re-col>
<re-col :value="12" :xs="24" :sm="24">
<el-form-item label="用户名称" prop="username">
<el-input
v-model="newFormInline.username"
clearable
placeholder="请输入用户名称"
/>
</el-form-item>
</re-col>
<re-col :value="12" :xs="24" :sm="24">
<el-form-item label="手机号" prop="phone_number">
<el-input
v-model="newFormInline.phone_number"
clearable
placeholder="请输入手机号"
/>
</el-form-item>
</re-col>
<re-col :value="12" :xs="24" :sm="24">
<el-form-item label="用户状态">
<el-switch
v-model="newFormInline.status"
inline-prompt
:active-value="1"
:inactive-value="0"
active-text="已开用"
inactive-text="已关闭"
/>
</el-form-item>
</re-col>
<re-col :value="12" :xs="24" :sm="24">
<el-form-item label="性别" prop="gender">
<el-select v-model="newFormInline.gender" placeholder="请选择">
<el-option label="未知" :value="2" />
<el-option label="男" :value="1" />
<el-option label="女" :value="0" />
</el-select>
</el-form-item>
</re-col>
</el-row>
</el-form>
</template>

@ -4,6 +4,7 @@ import { useUser } from "./utils/hook";
import { PureTableBar } from "@/components/RePureTableBar";
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import { PureTable } from "@pureadmin/table";
import tree from "./tree.vue";
import Role from "@iconify-icons/ri/admin-line";
import Password from "@iconify-icons/ri/lock-password-line";
@ -47,13 +48,12 @@ const {
handleCurrentChange,
handleSelectionChange
} = useUser();
console.log(allRole);
</script>
<template>
<div class="main">
<!-- <tree class="w-[17%] float-left" />-->
<div class="float-right w-[100%]">
<tree class="w-[17%] float-left" />
<div class="float-right w-[82%]">
<el-form
ref="formRef"
:inline="true"
@ -62,15 +62,15 @@ console.log(allRole);
>
<el-form-item label="用户名称:" prop="username">
<el-input
v-model="form.username"
v-model.trim="form.username"
placeholder="请输入用户名称"
clearable
class="!w-[160px]"
/>
</el-form-item>
<el-form-item label="手机号码:" prop="mobile">
<el-form-item label="手机号码:" prop="phone_number">
<el-input
v-model="form.mobile"
v-model.trim="form.phone_number"
placeholder="请输入手机号码"
clearable
class="!w-[160px]"
@ -143,7 +143,7 @@ console.log(allRole);
>
修改
</el-button>
<el-popconfirm title="是否确认删除?">
<el-popconfirm title="是否确认删除?" @confirm="handleDelete(row)">
<template #reference>
<el-button
class="reset-margin"
@ -151,7 +151,6 @@ console.log(allRole);
type="primary"
:size="size"
:icon="useRenderIcon(Delete)"
@click="handleDelete(row)"
>
删除
</el-button>

@ -0,0 +1,211 @@
<script setup lang="ts">
// import { handleTree } from "@/utils/tree";
import { getDeptList } from "@/api/system";
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import { ref, computed, watch, onMounted, getCurrentInstance } from "vue";
import { useUser } from "./utils/hook";
import Dept from "@iconify-icons/ri/git-branch-line";
import Reset from "@iconify-icons/ri/restart-line";
import Search from "@iconify-icons/ep/search";
import More2Fill from "@iconify-icons/ri/more-2-fill";
import OfficeBuilding from "@iconify-icons/ep/office-building";
import LocationCompany from "@iconify-icons/ep/add-location";
import ExpandIcon from "./svg/expand.svg?component";
import UnExpandIcon from "./svg/unexpand.svg?component";
interface Tree {
id: number;
name: string;
highlight?: boolean;
children?: Tree[];
}
const { form, onSearch } = useUser();
const treeRef = ref();
const treeData = ref([]);
const isExpand = ref(true);
const searchValue = ref("");
const highlightMap = ref({});
const { proxy } = getCurrentInstance();
const defaultProps = {
children: "children",
label: "name"
};
const buttonClass = computed(() => {
return [
"!h-[20px]",
"reset-margin",
"!text-gray-500",
"dark:!text-white",
"dark:hover:!text-primary"
];
});
const filterNode = (value: string, data: Tree) => {
if (!value) return true;
return data.name.includes(value);
};
function nodeClick(value) {
const nodeId = value.$treeNodeId;
highlightMap.value[nodeId] = highlightMap.value[nodeId]?.highlight
? Object.assign({ id: nodeId }, highlightMap.value[nodeId], {
highlight: false
})
: Object.assign({ id: nodeId }, highlightMap.value[nodeId], {
highlight: true
});
Object.values(highlightMap.value).forEach((v: Tree) => {
if (v.id !== nodeId) {
v.highlight = false;
}
});
form.department_id = value.id;
onSearch();
}
function toggleRowExpansionAll(status) {
isExpand.value = status;
const nodes = (proxy.$refs["treeRef"] as any).store._getAllNodes();
for (let i = 0; i < nodes.length; i++) {
nodes[i].expanded = status;
}
}
/** 重置状态(选中状态、搜索框值、树初始化) */
function onReset() {
highlightMap.value = {};
searchValue.value = "";
toggleRowExpansionAll(true);
form.department_id = searchValue.value;
onSearch();
}
watch(searchValue, val => {
treeRef.value!.filter(val);
});
// const deptList = reactive({});
// function getDeptList() {
// // http.request("post", "/login")
// return deptList;
// }
onMounted(async () => {
const { data } = await getDeptList();
// treeData.value = handleTree(data.data);
treeData.value = data;
});
</script>
<template>
<div
class="h-full bg-bg_color overflow-auto"
:style="{ minHeight: `calc(100vh - 133px)` }"
>
<div class="flex items-center h-[34px]">
<p class="flex-1 ml-2 font-bold text-base truncate" title="部门列表">
部门列表
</p>
<el-input
style="flex: 2"
size="small"
v-model="searchValue"
placeholder="请输入部门名称"
clearable
>
<template #suffix>
<el-icon class="el-input__icon">
<IconifyIconOffline
v-show="searchValue.length === 0"
:icon="Search"
/>
</el-icon>
</template>
</el-input>
<el-dropdown :hide-on-click="false">
<IconifyIconOffline
class="w-[28px] cursor-pointer"
width="18px"
:icon="More2Fill"
/>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>
<el-button
:class="buttonClass"
link
type="primary"
:icon="useRenderIcon(isExpand ? ExpandIcon : UnExpandIcon)"
@click="toggleRowExpansionAll(isExpand ? false : true)"
>
{{ isExpand ? "折叠全部" : "展开全部" }}
</el-button>
</el-dropdown-item>
<el-dropdown-item>
<el-button
:class="buttonClass"
link
type="primary"
:icon="useRenderIcon(Reset)"
@click="onReset"
>
重置状态
</el-button>
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
<el-divider />
<el-tree
ref="treeRef"
:data="treeData"
node-key="id"
size="small"
:props="defaultProps"
default-expand-all
:expand-on-click-node="false"
:filter-node-method="filterNode"
@node-click="nodeClick"
>
<template #default="{ node, data }">
<span
:class="[
'pl-1',
'pr-1',
'rounded',
'flex',
'items-center',
'select-none',
searchValue.trim().length > 0 &&
node.label.includes(searchValue) &&
'text-red-500',
highlightMap[node.id]?.highlight ? 'dark:text-primary' : ''
]"
:style="{
background: highlightMap[node.id]?.highlight
? 'var(--el-color-primary-light-7)'
: 'transparent'
}"
>
<IconifyIconOffline
:icon="
data.type === 1
? OfficeBuilding
: data.type === 2
? LocationCompany
: Dept
"
/>
{{ node.label }}
</span>
</template>
</el-tree>
</div>
</template>
<style lang="scss" scoped>
:deep(.el-divider) {
margin: 0;
}
</style>

@ -1,35 +1,49 @@
import dayjs from "dayjs";
// import dayjs from "dayjs";
import { message } from "@/utils/message";
import editForm from "../form.vue";
import { addDialog } from "@/components/ReDialog";
import { type FormItemProps } from "../utils/types";
// import { getUserList } from "@/api/system";
import {
getUserList,
getDeptList,
addUser,
updateUser,
deleteUser
} from "@/api/system";
import { ElMessageBox } from "element-plus";
import { type PaginationProps } from "@pureadmin/table";
import { reactive, ref, computed, h, onMounted } from "vue";
// import { http } from "@/utils/http";
import { number } from "echarts";
import { string } from "vue-types";
import { cloneDeep } from "@pureadmin/utils";
// 共享列表数据
const dataList = ref([]);
// 共享表格页码
const pagination = reactive<PaginationProps>({
total: 0,
pageSize: 10,
currentPage: 1,
background: true
});
export function useUser() {
const form = reactive({
/** 角色名称 */
username: "",
/** 手机号 */
mobile: "",
phone_number: "",
/** 状态 */
status: number
status: "",
/** 部门 */
department_id: ""
});
const formRef = ref();
const dataList = ref([]);
const loading = ref(true);
const switchLoadMap = ref({});
const pagination = reactive<PaginationProps>({
total: 0,
pageSize: 10,
currentPage: 1,
background: true
});
const columns: TableColumnList = [
{
label: "序号",
@ -54,27 +68,27 @@ export function useUser() {
// },
{
label: "性别",
prop: "sex",
prop: "gender",
minWidth: 90,
cellRenderer: ({ row, props }) => (
<el-tag
size={props.size}
type={row.sex === 1 ? "danger" : ""}
type={row.gender === 1 ? "" : "danger"}
effect="plain"
>
{row.sex === 1 ? "女" : "男"}
{row.gender === 1 ? "男" : "女"}
</el-tag>
)
},
{
label: "组织",
prop: "dept",
minWidth: 90,
formatter: ({ dept }) => dept.name
label: "部门",
prop: "department_name",
minWidth: 90
// formatter: ({ dept }) => dept.name
},
{
label: "手机号码",
prop: "mobile",
prop: "phone_number",
minWidth: 90
},
{
@ -98,9 +112,7 @@ export function useUser() {
{
label: "创建时间",
minWidth: 90,
prop: "createTime",
formatter: ({ createTime }) =>
dayjs(createTime).format("YYYY-MM-DD HH:mm:ss")
prop: "date_joined"
},
{
label: "操作",
@ -167,107 +179,54 @@ export function useUser() {
}
function handleDelete(row) {
message(`您删除了角色名称为${row.username}的这条数据`, { type: "success" });
const deleteListData = userList.value.list.filter(
item => item.id !== row.id
);
userList.value.list = deleteListData;
onSearch();
// const deleteListData = userList.value.list.filter(
// item => item.id !== row.id
// );
// userList.value.list = deleteListData;
deleteUser(row.id).then(res => {
if (!res.success) {
message(`${res.msg}`, {
type: "warning"
});
} else {
message(`您删除了角色名称为${row.username}的这条数据`, {
type: "success"
});
onSearch();
}
});
}
function handleSizeChange(val: number) {
console.log(`${val} items per page`);
function handleSizeChange() {
onSearch();
}
function handleCurrentChange(val: number) {
console.log(`current page: ${val}`);
function handleCurrentChange() {
onSearch();
}
function handleSelectionChange(val) {
console.log("handleSelectionChange", val);
}
const userList = ref({
list: [
{
username: "admin",
nickname: "admin",
remark: "管理员",
deptId: 103,
postIds: [1],
mobile: "15888888888",
sex: 0,
id: 1,
status: 0,
createTime: 1605456000000,
dept: {
id: 103,
name: "研发部门"
}
},
{
username: "pure",
nickname: "pure",
remark: "不要吓我",
deptId: 104,
postIds: [1],
mobile: "15888888888",
sex: 0,
id: 100,
status: 1,
createTime: 1605456000000,
dept: {
id: 104,
name: "市场部门"
}
},
{
username: "lucy",
nickname: "girl",
remark: null,
deptId: 106,
postIds: null,
mobile: "15888888888",
sex: 1,
id: 103,
status: 1,
createTime: 1605456000000,
dept: {
id: 106,
name: "财务部门"
}
},
{
username: "mike",
nickname: "boy",
remark: null,
deptId: 107,
postIds: [],
mobile: "15888888888",
sex: 0,
id: 104,
status: 0,
createTime: 1605456000000,
dept: {
id: 107,
name: "运维部门"
}
}
],
total: 4
});
function getUserList() {
// http.request("post", "/login")
return userList;
}
// function getUserList() {
// // http.request("post", "/login")
// return userList;
// }
const deptList = ref([]);
async function onSearch() {
loading.value = true;
const data = getUserList();
console.log(data);
dataList.value = data.value.list;
pagination.total = data.value.total;
const params = {
...form,
page: pagination.currentPage || undefined,
page_size: pagination.pageSize || undefined
};
const data = await getUserList(params);
await getDeptList().then(res => {
deptList.value = res.data;
});
dataList.value = data.results;
pagination.total = data.count;
setTimeout(() => {
loading.value = false;
}, 500);
@ -283,10 +242,13 @@ export function useUser() {
title: `${title}用户`,
props: {
formInline: {
higherDeptOptions: cloneDeep(deptList.value),
department_id: row?.department_id ?? "",
username: row?.username ?? "",
mobile: row?.mobile ?? "",
status: row?.status ?? "",
sex: row?.sex ?? ""
phone_number: row?.phone_number ?? "",
status: row?.status ?? 1,
gender: row?.gender ?? null,
id: row?.id ?? ""
}
},
width: "40%",
@ -298,7 +260,7 @@ export function useUser() {
const FormRef = formRef.value.getRef();
const curData = options.props.formInline as FormItemProps;
function chores() {
message(`${title}角色名称为${curData.username}的这条数据`, {
message(`${title}用户名称为${curData.username}的这条数据`, {
type: "success"
});
done(); // 关闭弹框
@ -310,27 +272,42 @@ export function useUser() {
// 表单规则校验通过
if (title === "新增") {
// 实际开发先调用新增接口,再进行下面操作
const addItem = {
addUser(curData).then(res => {
console.log(res);
if (res.success) {
chores();
} else {
message(`${res.msg}`, {
type: "warning"
});
}
});
} else {
const params = {
department_id: curData.department_id,
username: curData.username,
mobile: "15888888888",
phone_number: curData.phone_number,
status: curData.status,
nickname: "boy",
remark: null,
deptId: 107,
postIds: [],
sex: 0,
id: 105,
createTime: 1605456000000,
dept: {
id: 107,
name: "运维部门"
}
gender: curData.gender,
id: curData.id
};
userList.value.list.push(addItem);
chores();
} else {
updateUser(params)
.then(res => {
console.log(res);
if (res.success) {
chores();
} else {
message(`${res.msg}`, {
type: "warning"
});
}
})
.catch(error => {
message(`${error}`, {
type: "warning"
});
});
// 实际开发先调用编辑接口,再进行下面操作
chores();
}
}
});
@ -382,8 +359,8 @@ export function useUser() {
const isIndeterminate = ref(true);
//顶部的全部复选框的change事件
function handleCheckAllChange(val: boolean) {
console.log(val);
console.log(allRole.value);
// console.log(val);
// console.log(allRole.value);
//val:true(全选)|false(没有全选)
userRole.value = val ? allRole.value : [];
//不确定的样式(确定样式)

@ -1,8 +1,25 @@
import { reactive } from "vue";
import type { FormRules } from "element-plus";
import { isPhone } from "@pureadmin/utils";
/** 自定义表单规则校验 */
export const formRules = reactive(<FormRules>{
username: [{ required: true, message: "角色名称为必填项", trigger: "blur" }],
code: [{ required: true, message: "角色标识为必填项", trigger: "blur" }]
department_id: [{ required: true, message: "部门为必填项", trigger: "blur" }],
phone_number: [
{
validator: (rule, value, callback) => {
if (value === "") {
callback();
} else if (!isPhone(value)) {
callback(new Error("请输入正确的手机号码格式"));
} else {
callback();
}
},
trigger: "click"
// trigger: "click" // 如果想在点击确定按钮时触发这个校验trigger 设置成 click 即可
}
],
gender: [{ required: true, message: "性别为必填项", trigger: "blur" }]
});

@ -1,16 +1,11 @@
// 虽然字段很少 但是抽离出来 后续有扩展字段需求就很方便了
interface FormItemProps {
/** 角色名称 */
higherDeptOptions: Record<string, unknown>[];
username: string;
/** 状态 */
phone_number: string | number;
status: number;
/** 手机 */
mobile: string;
/** 性别 */
sex: number;
/** 性别 */
deptId: number;
department_id: string | number;
gender: string | number;
id: string | number;
}
interface FormProps {
formInline: FormItemProps;

@ -0,0 +1,41 @@
import { addDialog } from "@/components/ReDialog";
import { ref, h } from "vue";
// import { http } from "@/utils/http";
export function welcomeUtil() {
const currentPlayingIndex = ref(-1);
function openDialog(title = "视频", row, index: number) {
console.log(row.video_dir, "row.video_dir");
addDialog({
title: `${title}用户`,
width: "40%",
draggable: true,
fullscreenIcon: true,
closeOnClickModal: false,
contentRenderer: () => {
return h(
"video",
{
controls: true,
id: "video-" + index,
onPlay: () => playVideo(row, index)
},
[h("source", { src: row.video_dir, type: "video/mp4" })]
);
}
});
}
function playVideo(row, index) {
if (currentPlayingIndex.value !== -1) {
const videoElement = document.getElementById(
"video-" + currentPlayingIndex.value
);
videoElement.pause(); // 暂停当前正在播放的视频
}
currentPlayingIndex.value = index;
}
return {
openDialog
};
}

@ -10,16 +10,14 @@ import { ElMessageBox } from "element-plus";
// import { getConfig } from "@/config";
// import { getToken, formatToken } from "@/utils/auth";
import { getHomeList, getEvents } from "@/api/home";
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import Delete from "@iconify-icons/ep/delete";
import EditPen from "@iconify-icons/ep/edit-pen";
import { welcomeUtil } from "./hook";
defineOptions({
name: "Welcome"
});
// const AdminHostUrl = getConfig().AdminHostUrl;
const { openDialog } = welcomeUtil();
const formInline = reactive({
date: "",
policeId: "",
@ -44,20 +42,28 @@ const violationMap = ref({
: "0",
所有: "2"
});
// function playVideo(data) {
// data = JSON.parse(JSON.stringify(data));
// // console.log(AdminHostUrl)
// dialogVisible.value = true;
// const highlights = [
// //
// {
// text: data.event_type,
// time: data.relative_time
// }
// ];
// sessionStorage.setItem("video_url", data.video_dir);
// sessionStorage.setItem("highlights", JSON.stringify(highlights));
// const currentPlayingIndex = ref(-1); //
// function playVideo(index) {
// // data = JSON.parse(JSON.stringify(data));
// // // console.log(AdminHostUrl)
// // dialogVisible.value = true;
// // const highlights = [
// // //
// // {
// // text: data.event_type,
// // time: data.relative_time
// // }
// // ];
// // sessionStorage.setItem("video_url", data.video_dir);
// // sessionStorage.setItem("highlights", JSON.stringify(highlights));
// if (currentPlayingIndex.value !== -1) {
// const videoElement = document.getElementById(
// "video-" + currentPlayingIndex.value
// );
// videoElement.pause(); //
// }
// currentPlayingIndex.value = index;
// }
function onSearch() {
@ -230,16 +236,16 @@ const columns: TableColumnList = [
prop: "car_number",
minWidth: 100
},
// {
// label: "",
// slot: "video"
// },
{
label: "视频",
slot: "video"
label: "操作",
fixed: "right",
width: 180,
slot: "operation"
}
// {
// label: "",
// fixed: "right",
// width: 180,
// slot: "operation"
// }
];
const loading = ref(true);
const pagination = reactive<PaginationProps>({
@ -248,12 +254,13 @@ const pagination = reactive<PaginationProps>({
currentPage: currentPage.value,
background: true
});
function handleUpdate(row) {
console.log(row);
}
function handleDelete(row) {
function handleUpdate(row, index) {
openDialog("我的", row, index);
console.log(row);
}
// function handleDelete(row) {
// console.log(row);
// }
onMounted(() => {
onSearch();
});
@ -380,23 +387,28 @@ onMounted(() => {
class="w-[100px] h-[100px]"
/>
</template>
<template #video="{ row }">
<video width="180" height="180" controls>
<!-- <template #video="{ row, index }">
<video
width="180"
height="180"
controls
:id="'video-' + index"
@play="playVideo(row, index)"
>
<source :src="row.video_dir" type="video/mp4" />
</video>
</template>
<template #operation="{ row }">
</template> -->
<template #operation="{ row, index }">
<el-button
class="reset-margin"
link
type="primary"
:size="size"
@click="handleUpdate(row)"
:icon="useRenderIcon(EditPen)"
@click="handleUpdate(row, index)"
>
修改
播放视频
</el-button>
<el-popconfirm title="是否确认删除?" @confirm="handleDelete(row)">
<!-- <el-popconfirm title="是否确认删除?" @confirm="handleDelete(row)">
<template #reference>
<el-button
class="reset-margin"
@ -408,7 +420,7 @@ onMounted(() => {
删除
</el-button>
</template>
</el-popconfirm>
</el-popconfirm> -->
</template>
</pure-table>
</template>

Loading…
Cancel
Save