feat: 用户模块和部门模块接口联调

develop
JINGYJ 2 years ago
parent afe9e1e162
commit 6688672ea0

@ -8,4 +8,4 @@ VITE_PUBLIC_PATH = /
VITE_ROUTER_HISTORY = "hash"
# 开发环境后端地址
VITE_APP_BASE_URL = 'http://192.168.10.13:8000'
VITE_APP_BASE_URL = 'http://192.168.10.14:8008'

@ -8,14 +8,20 @@ type Result = {
type Data = {
success: boolean;
msg: any;
results?: Array<any>;
data?: Array<any>;
};
export const getHomeList = (params?: object) => {
return http.request<Result>("get", baseUrlApi("tps"), { params });
return http.request<Result>("get", baseUrlApi(""), { params });
};
export const getEvents = (params?: object) => {
return http.request<Data>("get", baseUrlApi("tps/events"), { params });
return http.request<Data>("get", baseUrlApi("events"), { params });
};
export const getScenes = (params?: object) => {
return http.request<Data>("get", baseUrlApi("scenes"), { params });
};
export const getReasons = (params?: object) => {
return http.request<Data>("get", baseUrlApi("violation_reasons"), { params });
};
export const updateHomeList = (params?: object) => {
return http.request<Data>("put", baseUrlApi(""), { params });

@ -7,7 +7,7 @@ type deptResult = {
/** 部门列表查询 */
export const getDeptList = (params?: object) => {
return http.request<deptResult>("get", baseUrlApi("departments/"), {
return http.request<deptResult>("get", baseUrlApi("organization/trees/"), {
params
});
};
@ -19,16 +19,20 @@ type deptStatus = {
/** 新增部门 */
export const addDept = (data?: object) => {
return http.request<deptStatus>("post", baseUrlApi("departments/"), {
data
});
return http.request<deptStatus>(
"post",
baseUrlApi("organization/departments/"),
{
data
}
);
};
/** 更新部门 */
export const updateDept = (data?: object | any) => {
return http.request<deptStatus>(
"put",
baseUrlApi(`departments/${data.id}/`),
baseUrlApi(`organization/departments/${data.id}/`),
{
data
}
@ -39,7 +43,7 @@ export const updateDept = (data?: object | any) => {
export const deleteDept = (data?: object | any) => {
return http.request<deptStatus>(
"delete",
baseUrlApi(`departments/${data}/`),
baseUrlApi(`organization/departments/${data}/`),
{
data
}
@ -55,7 +59,7 @@ type userList = {
/** 用户列表查询 */
export const getUserList = (params?: object) => {
return http.request<userList>("get", baseUrlApi("user/"), {
return http.request<userList>("get", baseUrlApi("organization/users/"), {
params
});
};
@ -66,19 +70,29 @@ type userStatus = {
};
/** 新增用户 */
export const addUser = (data?: object) => {
return http.request<userStatus>("post", baseUrlApi("user/"), { data });
return http.request<userStatus>("post", baseUrlApi("organization/users/"), {
data
});
};
/** 更新用户 */
export const updateUser = (data?: object | any) => {
return http.request<userStatus>("put", baseUrlApi(`user/${data.id}/`), {
data
});
return http.request<userStatus>(
"put",
baseUrlApi(`organization/users/${data.id}/`),
{
data
}
);
};
/** 删除用户 */
export const deleteUser = (data?: object | any) => {
return http.request<userStatus>("delete", baseUrlApi(`user/${data}/`), {
data
});
return http.request<userStatus>(
"delete",
baseUrlApi(`organization/users/${data}/`),
{
data
}
);
};

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

@ -51,6 +51,7 @@ defineExpose({ getRef });
emitPath: false,
checkStrictly: true
}"
:disabled="newFormInline.id ? true : false"
clearable
filterable
placeholder="请选择上级部门"

@ -189,6 +189,10 @@ export function useDept() {
addDept(params).then(res => {
if (res.success) {
chores();
} else {
message(`${res.msg}`, {
type: "warning"
});
}
});
} else {

@ -10,9 +10,10 @@ const props = withDefaults(defineProps<FormProps>(), {
department_id: "",
username: "",
phone_number: "",
status: 1,
is_active: true,
gender: null,
id: ""
// password: ""
})
});
@ -46,7 +47,7 @@ defineExpose({ getRef });
emitPath: false,
checkStrictly: true,
disabled: function (data) {
if (data.children && data.children.length > 0) {
if (!data.parent_id) {
return true;
} else {
return false;
@ -75,7 +76,16 @@ defineExpose({ getRef });
/>
</el-form-item>
</re-col>
<!-- <re-col>
<el-form-item label="密码" prop="password">
<el-input
clearable
show-password
v-model="newFormInline.password"
placeholder="密码"
/>
</el-form-item>
</re-col> -->
<re-col :value="12" :xs="24" :sm="24">
<el-form-item label="手机号" prop="phone_number">
<el-input
@ -85,18 +95,7 @@ defineExpose({ getRef });
/>
</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="请选择">
@ -106,6 +105,18 @@ defineExpose({ getRef });
</el-select>
</el-form-item>
</re-col>
<re-col :value="12" :xs="24" :sm="24">
<el-form-item label="用户状态">
<el-switch
v-model="newFormInline.is_active"
inline-prompt
:active-value="true"
:inactive-value="false"
active-text="已开用"
inactive-text="已关闭"
/>
</el-form-item>
</re-col>
</el-row>
</el-form>
</template>

@ -76,15 +76,15 @@ const {
class="!w-[160px]"
/>
</el-form-item>
<el-form-item label="状态:" prop="status">
<el-form-item label="状态:" prop="is_active">
<el-select
v-model="form.status"
v-model="form.is_active"
placeholder="请选择"
clearable
class="!w-[160px]"
>
<el-option label="已开启" value="1" />
<el-option label="已关闭" value="0" />
<el-option label="已开启" :value="true" />
<el-option label="已关闭" :value="false" />
</el-select>
</el-form-item>
<el-form-item>

@ -35,7 +35,7 @@ export function useUser() {
/** 手机号 */
phone_number: "",
/** 状态 */
status: "",
is_active: null,
/** 部门 */
department_id: ""
});
@ -93,15 +93,15 @@ export function useUser() {
},
{
label: "状态",
prop: "status",
prop: "is_active",
minWidth: 90,
cellRenderer: scope => (
<el-switch
size={scope.props.size === "small" ? "small" : "default"}
loading={switchLoadMap.value[scope.index]?.loading}
v-model={scope.row.status}
active-value={1}
inactive-value={0}
v-model={scope.row.is_active}
active-value={true}
inactive-value={false}
active-text="已开启"
inactive-text="已关闭"
inline-prompt
@ -246,8 +246,8 @@ export function useUser() {
department_id: row?.department_id ?? "",
username: row?.username ?? "",
phone_number: row?.phone_number ?? "",
status: row?.status ?? 1,
gender: row?.gender ?? null,
is_active: row?.is_active ?? true,
id: row?.id ?? ""
}
},
@ -272,7 +272,11 @@ export function useUser() {
// 表单规则校验通过
if (title === "新增") {
// 实际开发先调用新增接口,再进行下面操作
addUser(curData).then(res => {
const params = {
...curData,
password: "test1234"
};
addUser(params).then(res => {
console.log(res);
if (res.success) {
chores();
@ -287,7 +291,7 @@ export function useUser() {
department_id: curData.department_id,
username: curData.username,
phone_number: curData.phone_number,
status: curData.status,
is_active: curData.is_active,
gender: curData.gender,
id: curData.id
};
@ -376,13 +380,24 @@ export function useUser() {
isIndeterminate.value = value.length !== allRole.value.length;
}
/** 密码正则密码格式应为8-18位数字、字母、符号的任意两种组合 */
const REGEXP_PWD =
/^(?![0-9]+$)(?![a-z]+$)(?![A-Z]+$)(?!([^(0-9a-zA-Z)]|[()])+$)(?!^.*[\u4E00-\u9FA5].*$)([^(0-9a-zA-Z)]|[()]|[a-z]|[A-Z]|[0-9]){8,18}$/;
function resetPassword(row: { username: string; id: any }) {
ElMessageBox.prompt(
"请输入用户「" + row.username + "」的新密码",
"重置密码",
{
confirmButtonText: "确定",
cancelButtonText: "取消"
cancelButtonText: "取消",
inputValidator: val => {
if (val === null) {
return true; //初始化的值为null不做处理的话刚打开MessageBox就会校验出错影响用户体验
}
return REGEXP_PWD.test(val);
},
inputErrorMessage: "密码格式应为8-18位数字、字母、符号的任意两种组合"
}
)
.then(({ value }) => {
@ -391,6 +406,30 @@ export function useUser() {
type: "warning"
});
return false;
} else {
console.log(value);
const params = {
id: row.id,
password: value
};
updateUser(params)
.then(res => {
console.log(res);
if (res.success) {
message(`${res.msg}`, {
type: "success"
});
} else {
message(`${res.msg}`, {
type: "warning"
});
}
})
.catch(error => {
message(`${error}`, {
type: "warning"
});
});
}
})
.catch(() => {});

@ -2,6 +2,10 @@ import { reactive } from "vue";
import type { FormRules } from "element-plus";
import { isPhone } from "@pureadmin/utils";
/** 密码正则密码格式应为8-18位数字、字母、符号的任意两种组合 */
export const REGEXP_PWD =
/^(?![0-9]+$)(?![a-z]+$)(?![A-Z]+$)(?!([^(0-9a-zA-Z)]|[()])+$)(?!^.*[\u4E00-\u9FA5].*$)([^(0-9a-zA-Z)]|[()]|[a-z]|[A-Z]|[0-9]){8,18}$/;
/** 自定义表单规则校验 */
export const formRules = reactive(<FormRules>{
username: [{ required: true, message: "角色名称为必填项", trigger: "blur" }],
@ -9,9 +13,7 @@ export const formRules = reactive(<FormRules>{
phone_number: [
{
validator: (rule, value, callback) => {
if (value === "") {
callback();
} else if (!isPhone(value)) {
if (!isPhone(value)) {
callback(new Error("请输入正确的手机号码格式"));
} else {
callback();
@ -21,5 +23,21 @@ export const formRules = reactive(<FormRules>{
// trigger: "click" // 如果想在点击确定按钮时触发这个校验trigger 设置成 click 即可
}
],
gender: [{ required: true, message: "性别为必填项", trigger: "blur" }]
gender: [{ required: true, message: "性别为必填项", trigger: "blur" }],
password: [
{
validator: (rule, value, callback) => {
if (value === "") {
callback(new Error("请输入密码"));
} else if (!REGEXP_PWD.test(value)) {
callback(
new Error("密码格式应为8-18位数字、字母、符号的任意两种组合")
);
} else {
callback();
}
},
trigger: "blur"
}
]
});

@ -2,10 +2,11 @@ interface FormItemProps {
higherDeptOptions: Record<string, unknown>[];
username: string;
phone_number: string | number;
status: number;
is_active: boolean;
department_id: string | number;
gender: string | number;
id: string | number;
// password: string | number;
}
interface FormProps {
formInline: FormItemProps;

@ -5,7 +5,7 @@ import { ref, h } from "vue";
export function welcomeUtil() {
const currentPlayingIndex = ref(-1);
function openDialog(title = "视频", row, index: number) {
console.log(row.video_dir, "row.video_dir");
console.log(row.video_path, "row.video_path");
addDialog({
title: `${title}用户`,
width: "40%",
@ -20,7 +20,7 @@ export function welcomeUtil() {
id: "video-" + index,
onPlay: () => playVideo(row, index)
},
[h("source", { src: row.video_dir, type: "video/mp4" })]
[h("source", { src: row.video_path, type: "video/mp4" })]
);
}
});

@ -9,7 +9,7 @@ import { type PaginationProps } from "@pureadmin/table";
import { ElMessageBox } from "element-plus";
// import { getConfig } from "@/config";
// import { getToken, formatToken } from "@/utils/auth";
import { getHomeList, getEvents } from "@/api/home";
import { getHomeList, getEvents, getScenes, getReasons } from "@/api/home";
import { welcomeUtil } from "./hook";
defineOptions({
@ -20,10 +20,10 @@ defineOptions({
const { openDialog } = welcomeUtil();
const formInline = reactive({
date: "",
policeId: "",
event: "",
violation: "",
violationType: ""
violationReason: "",
scene: ""
});
const currentPage = ref(1);
@ -37,6 +37,10 @@ const tableData = ref([]);
const eventMap = ref({});
const sceneMap = ref({});
const vioReasonMap = ref({});
const violationMap = ref({
: "1",
: "0",
@ -70,10 +74,10 @@ function onSearch() {
const params = {
start_time: formInline.date === null ? undefined : formInline.date[0],
end_time: formInline.date === null ? undefined : formInline.date[1],
police_id: formInline.policeId || undefined,
scene: formInline.scene || undefined,
event_type: formInline.event || undefined,
violation: violationMap.value[formInline.violation] || undefined,
violation_type: formInline.violationType || undefined,
violation_type: formInline.violationReason || undefined,
page: currentPage.value || undefined,
page_size: pageSize.value || undefined
};
@ -165,25 +169,18 @@ const handleClose = (done: () => void) => {
};
async function getEvent() {
// axios({
// url: AdminHostUrl + "events",
// headers: {
// token: formatToken(getToken().accessToken)
// }
// })
// .then(response => {
// eventMap.value = response.data.data;
// // console.log(eventMap.value);
// })
// .catch(error => {
// ElMessage({
// message: "",
// type: "warning"
// });
// console.log(error);
// });
const { results } = await getEvents();
eventMap.value = results;
const { data } = await getEvents();
eventMap.value = data;
}
async function getScene() {
const { data } = await getScenes();
sceneMap.value = data;
}
async function getReason() {
const { data } = await getReasons();
vioReasonMap.value = data;
}
function pickerOptions(time) {
@ -202,12 +199,12 @@ const columns: TableColumnList = [
sortable: true
},
{
label: "警号",
prop: "police_id",
label: "场景",
prop: "scene",
minWidth: 100
},
{
label: "违法行为",
label: "事件类型",
prop: "event_type",
minWidth: 100
},
@ -218,24 +215,19 @@ const columns: TableColumnList = [
slot: "violation"
},
{
label: "违规行为",
prop: "ai_analysis",
minWidth: 100
},
{
label: "时间点",
prop: "relative_time",
label: "违规原因",
prop: "violation_reason",
minWidth: 100
},
{
label: "缩率图",
slot: "image"
},
{
label: "车牌号",
prop: "car_number",
minWidth: 100
},
// {
// label: "",
// prop: "car_number",
// minWidth: 100
// },
// {
// label: "",
// slot: "video"
@ -294,7 +286,7 @@ onMounted(() => {
:default-value="lastMonth"
/>
</el-form-item>
<!--
<el-form-item label="警号:">
<el-input
v-model="formInline.policeId"
@ -302,15 +294,28 @@ onMounted(() => {
clearable
style="width: 198px"
/>
</el-form-item> -->
<el-form-item label="场景:">
<el-select
v-model="formInline.scene"
placeholder="场景"
clearable
@click="getScene()"
>
<el-option
v-for="(scene, type) in sceneMap"
:key="type"
:label="scene"
:value="scene"
/>
</el-select>
</el-form-item>
<el-form-item label="违法行为:">
<!-- <el-input v-model="formInline.event" placeholder="事件"/>-->
<el-form-item label="事件类型:">
<el-select
v-model="formInline.event"
placeholder="违法行为"
placeholder="事件类型"
clearable
@click="getEvent"
@click="getEvent()"
>
<el-option
v-for="(event, type) in eventMap"
@ -336,13 +341,20 @@ onMounted(() => {
</el-select>
</el-form-item>
<el-form-item label="违规行为:">
<el-input
v-model="formInline.violationType"
placeholder="违规行为"
<el-form-item label="违规原因:">
<el-select
v-model="formInline.violationReason"
placeholder="违规原因"
clearable
style="width: 198px"
/>
@click="getReason()"
>
<el-option
v-for="(reason, type) in vioReasonMap"
:key="type"
:label="reason"
:value="reason"
/>
</el-select>
</el-form-item>
<el-form-item>
@ -380,8 +392,8 @@ onMounted(() => {
<el-image
preview-teleported
loading="lazy"
:src="row.small_image"
:preview-src-list="[row.small_image]"
:src="row.thumbnail"
:preview-src-list="[row.thumbnail]"
:initial-index="index"
fit="cover"
class="w-[100px] h-[100px]"

@ -45,7 +45,7 @@ export default ({ command, mode }: ConfigEnv): UserConfigExport => {
// 本地跨域代理 https://cn.vitejs.dev/config/server-options.html#server-proxy
proxy: {
"/api": {
target: "http://192.168.10.13:8000",
target: "http://192.168.10.14:8008",
changeOrigin: true,
rewrite: path => path.replace(/^\/api/, "")
}

Loading…
Cancel
Save