数字督察一体化平台-前端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

646 lines
23 KiB

<template>
<div class="container">
<header>
<el-form :label-width="114">
<el-row>
<el-col :span="6">
<el-form-item label="警员姓名">
<el-input
placeholder="请输入警员姓名"
v-model="query.name"
clearable
style="width: 220px"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="警号">
<el-input
placeholder="请输入"
v-model="query.empNo"
clearable
style="width: 220px"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="身份证">
<el-input
placeholder="请输入身份证号码"
v-model="query.idCode"
clearable
style="width: 220px"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="电话">
<el-input
placeholder="请输入电话"
v-model="query.phone"
clearable
style="width: 220px"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所属单位">
<div class="flex gap v-center" style="width: 100%">
<div style="width: 220px">
<depart-tree-select
v-model="query.departId"
/>
</div>
<el-checkbox
v-model="query.departBranch"
label="当前单位及所有子单位"
size="large"
/>
</div>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="权限角色">
<el-select
v-model="query.roleId"
placeholder="请选择角色"
clearable
>
<el-option
v-for="item in roles"
:key="item.roleId"
:value="item.roleId"
:label="item.roleName"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="mb-25 flex between">
<div class="flex gap">
<el-button
type="primary"
@click="handleAdd"
v-perms="['police:add']"
>
<template #icon>
<icon name="el-icon-Plus" />
</template>
新增警员</el-button
>
<el-upload
:multiple="false"
:show-file-list="false"
:action="`${BASE_PATH}/police/import`"
:headers="{ Authorization: getToken() }"
:before-upload="beforeUpload"
@success="handleSuccess"
@error="handleError"
accept="application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
v-perms="['police:import']"
>
<el-button
type="primary"
>
<template #icon>
<icon name="el-icon-Upload" />
</template>
导入警员</el-button
>
</el-upload>
<a
class="link"
:href="`${BASE_PATH}/templates/数字督察警员权限导入模板.xlsx`"
target="__blank"
style="padding: 8px"
v-perms="['police:import']"
>数字督察警员权限导入模板</a
>
</div>
<div>
<el-button type="primary" @click="getList">
<template #icon>
<icon name="el-icon-Search" />
</template>
查询</el-button
>
<el-button @click="reset">重置</el-button>
</div>
</div>
</header>
<div class="table-container" v-loading="loading">
<el-table :data="polices" row-key="id">
<el-table-column type="expand">
<template #default="{ row }">
<div class="row mt-10">
<div class="col col-6">
<label>角色</label>
<span>{{
getDictLable(
dict.policeRole,
row.policeRole
)
}}</span>
</div>
<div class="col col-6">
<label>备注</label>
<span>{{ row.job }}</span>
</div>
</div>
<div class="row mt-10">
<div class="col col-6">
<label>电话</label>
<span>{{ row.mobile }}</span>
</div>
<div class="col col-6">
<label>入职时间</label>
<span>{{ row.employmentDate }}</span>
</div>
<div class="col col-6" v-if="row.employmentDate">
<label>工龄</label>
<span>{{
getWorkYear(row.employmentDate)
}}</span>
</div>
<div class="col col-6">
<label>年龄</label>
<span>{{ getAge(row.idCode) }}</span>
</div>
</div>
<div class="row mt-10">
<div class="col col-6">
<label>创建时间</label>
<span>{{ row.createdAt || "/" }}</span>
</div>
<div class="col col-6">
<label>更新时间</label>
<span>{{ row.updatedAt }}</span>
</div>
</div>
</template>
</el-table-column>
<el-table-column label="姓名" prop="name" width="90" />
<el-table-column
label="警号"
prop="empNo"
width="100"
show-overflow-tooltip
/>
<el-table-column label="所属机构" show-overflow-tooltip>
<template #default="{ row }">
<div class="flex gap-4">
<span v-if="row.parentDepartShortName"
>{{ row.parentDepartShortName }}/</span
><span>{{ row.departShortName }}</span>
</div>
</template>
</el-table-column>
<el-table-column label="人员属性" width="120" align="center">
<template #default="{ row }">
<span>{{
getDictLable(dict.personType, row.personType)
}}</span>
</template>
</el-table-column>
<el-table-column label="职位" width="120" align="center">
<template #default="{ row }">
<span v-if="row.position">
<span v-if="row.level === 0"
>局领导{{ row.position }}</span
>
<span v-if="row.level === 2"
>二级机构{{ row.position }}</span
>
<span v-if="row.level === 3"
>三机机构{{ row.position }}</span
>
<span v-if="row.level === 4"
>四机机构{{ row.position }}</span
>
</span>
</template>
</el-table-column>
<el-table-column label="身份证" prop="idCode" width="200" />
<el-table-column label="角色" show-overflow-tooltip>
<template #default="{ row }">
<div class="flex gap" v-if="row.role">
<el-tag v-for="item in row.role.split(',')">{{
item
}}</el-tag>
</div>
</template>
</el-table-column>
<el-table-column label="操作" width="220">
<template #default="{ row }">
<el-button
type="primary"
link
@click="handleEdit(row)"
v-perms="['police:add']"
>编辑</el-button
>
<el-button
type="primary"
link
@click="handleEditAuth(row)"
v-perms="['police:auth']"
v-if="row.idCode"
>权限设置</el-button
>
<el-button
type="danger"
link
@click="handleDel(row)"
v-perms="['police:del']"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
</div>
<div class="flex end mt-8">
<el-pagination
@size-change="getList"
@current-change="getList"
:current-page="query.current"
:page-sizes="[10, 20, 50]"
v-model:page-size="query.size"
v-model:current-page="query.current"
layout="total, sizes, prev, pager, next"
:total="total"
>
</el-pagination>
</div>
</div>
<el-dialog
title="权限设置"
v-model="authShow"
width="800"
:lock-scroll="false"
>
<el-form :label-width="160">
<el-form-item label="机构权限">
<depart-tree-select
v-model="authForm.departs"
multiple
check-strictly
:show-root="true"
/>
</el-form-item>
<el-form-item label="业务权限(问题来源)">
<el-tree-select
:data="dictProblemSources"
:props="{ value: 'id' }"
node-key="id"
clearable
filterable
v-model="authForm.sources"
multiple
/>
</el-form-item>
</el-form>
<footer class="flex end">
<el-button @click="authShow = false">取消</el-button>
<el-button type="primary" @click="authSubmit">确定</el-button>
</footer>
</el-dialog>
<el-dialog
:title="mode === 'add' ? '新增警员' : '编辑警员'"
v-model="show"
width="600"
>
<el-form :model="form" :label-width="120" ref="fomrRef">
<!-- <el-form-item label="头像" prop="avatarUrl">
<el-avatar
shape="square"
:size="50"
:src="form.avatarUrl"
:icon="UserFilled"
/>
</el-form-item> -->
<el-form-item
label="姓名"
prop="name"
:rules="{
required: true,
message: '请输入姓名',
}"
>
<el-input
placeholder="请输入"
v-model="form.name"
style="width: 280px"
/>
</el-form-item>
<el-form-item
label="警号"
prop="empNo"
:rules="{
required: true,
message: '请输入警号',
}"
>
<el-input
placeholder="请输入"
v-model="form.empNo"
style="width: 280px"
/>
</el-form-item>
<el-form-item
label="身份证"
prop="idCode"
:rules="{
required: true,
message: '请输入身份证',
}"
>
<el-input
placeholder="请输入"
v-model="form.idCode"
style="width: 280px"
/>
</el-form-item>
<el-form-item
label="所属单位"
prop="orgId"
:rules="{
required: true,
message: '请选择所属单位',
}"
>
<div style="width: 280px">
<depart-tree-select v-model="form.orgId" :showRoot="true" />
</div>
</el-form-item>
<el-form-item label="人员属性">
<el-radio-group v-model="form.personType">
<el-radio
v-for="item in dict.personType"
:key="item.dictCode"
:value="item.dictValue"
>{{ item.dictLabel }}</el-radio
>
</el-radio-group>
</el-form-item>
<el-form-item
label="职位"
prop="position"
v-if="form.personType === PersonType.POLICE"
>
<el-select
v-model="form.position"
clearable
style="width: 280px"
>
<el-option value="正职">正职</el-option>
<el-option value="副职">副职</el-option>
</el-select>
</el-form-item>
<el-form-item label="角色" prop="policeRole">
<el-select
clearable
v-model="form.policeRole"
style="width: 280px"
>
<el-option
v-for="item in dict.policeRole"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/>
</el-select>
</el-form-item>
<el-form-item label="电话" prop="mobile">
<el-input
placeholder="请输入"
v-model="form.mobile"
style="width: 280px"
/>
</el-form-item>
<el-form-item label="入职时间">
<div>
<el-date-picker
v-model="form.employmentDate"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择"
:disabled-date="
(time) => time.getTime() > new Date().getTime()
"
style="width: 280px"
/>
<span class="ml-10" v-if="form.employmentDate"
>工龄:{{ getWorkYear(form.employmentDate) }}</span
>
</div>
</el-form-item>
<!-- <el-form-item label="婚姻状况">
<el-radio-group v-model="form.maritalStatus">
<el-radio
v-for="item in dict.maritalStatus"
:key="item.dictCode"
:value="item.dictValue"
>{{ item.dictLabel }}</el-radio
>
</el-radio-group>
</el-form-item>
<el-form-item label="子女">
<el-radio-group v-model="form.personType">
<el-radio value="无子女">无</el-radio>
<el-radio value="有子女">有</el-radio>
</el-radio-group>
</el-form-item> -->
<!-- <el-form-item label="学历">
<el-select v-model="form.education">
<el-option
v-for="item in dict.education"
:key="item.dictCode"
:value="item.dictValue"
:label="item.dictLabel"
/>
</el-select>
</el-form-item> -->
</el-form>
<footer class="flex end">
<el-button @click="show = false">取消</el-button>
<el-button type="primary" @click="submit">确定</el-button>
</footer>
</el-dialog>
</template>
<script setup>
import { BASE_PATH } from "@/api/request";
import { getToken } from "@/utils/token";
import { UserFilled } from "@element-plus/icons-vue";
import {
listPolice,
getPoliceAuths,
addPolice,
updatePolice,
delPolice,
updatePoliceAuths,
} from "@/api/system/police";
import { listRole } from "@/api/system/role";
import { PersonType } from "@/enums/dictEnums";
import useCatchStore from "@/stores/modules/catch";
import feedback from "@/utils/feedback";
import { getDictLable } from "@/utils/util";
import moment from "moment";
const catchStore = useCatchStore();
const dict = catchStore.getDicts([
"problemSources",
"personType",
"education",
"maritalStatus",
"policeRole",
]);
const dictProblemSources = catchStore.getDictProblemSources();
const polices = ref([]);
const query = ref({
current: 1,
size: 10,
});
const total = ref(0);
const loading = ref(false);
function getList() {
loading.value = true;
listPolice(query.value).then((data) => {
loading.value = false;
polices.value = data.records;
total.value = data.total;
});
}
const roles = ref([]);
onMounted(() => {
getList();
listRole().then((data) => {
roles.value = data;
});
});
function reset() {
query.value = {
current: 1,
size: 10,
};
getList();
}
const authShow = ref(false);
const authForm = ref({});
let activeIdCode = "";
function handleEditAuth(row) {
getPoliceAuths(row.idCode).then((data) => {
activeIdCode = row.idCode;
authShow.value = true;
authForm.value = data;
});
}
function authSubmit() {
updatePoliceAuths(activeIdCode, authForm.value).then(() => {
authShow.value = false;
feedback.msgSuccess("操作成功");
});
}
const mode = ref("add");
const form = ref({});
const fomrRef = ref(null);
const show = ref(false);
function handleAdd() {
show.value = true;
if (mode.value === "edit") {
form.value = {};
}
mode.value = "add";
}
function handleEdit(row) {
show.value = true;
form.value = { ...row };
mode.value = "edit";
}
async function submit() {
await fomrRef.value.validate();
if (mode.value === "add") {
await addPolice(form.value);
form.value = {};
} else {
await updatePolice(form.value);
}
feedback.msgSuccess("操作成功");
show.value = false;
getList();
}
function getAge(idCode) {
if (!idCode || idCode.length !== 18) {
return "";
}
return new Date().getFullYear() - parseInt(idCode.substr(6, 4));
}
function getWorkYear(employmentDate) {
if (!employmentDate) {
return "";
}
const year =
new Date().getFullYear() - parseInt(employmentDate.substr(0, 4));
if (year > 0) {
return year + "年";
}
const days = moment().diff(moment(employmentDate), "days");
if (days < 30) {
return days + "天";
}
return moment().diff(moment(employmentDate), "month") + "个月";
}
async function handleDel(row) {
await feedback.confirm(`确定要删除 ${row.name}`);
await delPolice(row.id);
feedback.msgSuccess("操作成功");
getList();
}
import { ElLoading } from "element-plus";
let importLoading;
function beforeUpload() {
importLoading = ElLoading.service({
lock: true,
text: "数据导入中",
background: "rgba(0, 0, 0, 0.7)",
});
}
function handleSuccess(result) {
console.log('handleSuccess', result)
importLoading.close();
if (result.code !== 200) {
feedback.msgError(result.message);
return
}
getList()
}
function handleError(result) {
console.log(result)
importLoading.close();
feedback.msgError(result.message || "上传失败!");
}
</script>
<style lang="scss" scoped>
</style>