Commit 6decb858 authored by 沈翠玲's avatar 沈翠玲

法务专员和风控专员

parent 5c5357dd
......@@ -11,3 +11,14 @@ export const getUserPage = (params) => {
export const deleteUsers = (ids) => {
return request.get('/login/batchDeleteByIds', { ids });
};
export const saveLeaderGroup = (data) => {
return request.post(`/leaderGroup/add?username=${data.username}&password=${data.password}&phone=${data.phone}&status=${data.status}&role=${data.role}`);
};
export const getleaderGroupPage = (params) => {
return request.get('/leaderGroup/page', params);
};
export const batchDeleteByIds = (ids) => {
return request.get('/leaderGroup/batchDeleteByIds', { ids });
};
\ No newline at end of file
......@@ -2,17 +2,20 @@
<!-- 中国地图 -->
<div class="map-ball"></div>
<div id="mapChart" class="echarts">
<ECharts :option="option" :resize="false" />
<ECharts :option="option" ref="EChartsRef" :resize="false" />
</div>
</template>
<script setup>
import echarts from "@/components/ECharts/config";
import { computed } from "vue";
import Decimal from 'decimal.js';
import ECharts from "@/components/ECharts/index.vue";
import mapJson from "../assets/china.json";
import { getMapByTenant } from '@/api/dataScreen';
import { reactive, ref } from 'vue';
const mapData = ref([]);
const EChartsRef = ref();
echarts.registerMap("china", mapJson);
getMapByTenant().then(res => {
......@@ -22,11 +25,19 @@ getMapByTenant().then(res => {
const findindex = mapData.value.findIndex(item => item.name === element.province)
if (findindex === -1) {
mapData.value.push({
name: element.province
name: element.province,
value: element.commissionAmount,
tenants: [{tenantName: element.tenantName, borrowNum: element.borrowNum, commissionAmount: element.commissionAmount, caseNum: element.caseNum}],
})
} else {
const item = mapData.value[findindex]
item.value = Decimal(item.value || 0).add(Decimal(element.commissionAmount || 0));
item.tenants.push({tenantName: element.tenantName, borrowNum: element.borrowNum, commissionAmount: element.commissionAmount, caseNum: element.caseNum})
}
});
}
console.log('mapData.value', mapData.value)
EChartsRef.value.draw()
}).catch(() => {
mapData.value = []
})
......@@ -79,371 +90,106 @@ getMapByTenant().then(res => {
// return res;
// };
var mapData = [{
name: "北京",
devicesCount: 100, //总数
feiyue1: 40, //肺悦1个数
feiyue2: 60, //肺悦2个数
value: 10, //使用个数
devicesUseLv: '40%', //使用率
},
{
name: "天津",
devicesCount: 50,
feiyue1: 40,
feiyue2: 60,
value: 20,
devicesUseLv: '20%',
},
{
name: "上海",
devicesCount: 80,
feiyue1: 40,
feiyue2: 60,
value: 30,
devicesUseLv: '20%',
},
{
name: "重庆",
devicesCount: 90,
feiyue1: 40,
feiyue2: 60,
value: 40,
devicesUseLv: '20%',
},
{
name: "河北",
devicesCount: 130,
feiyue1: 40,
feiyue2: 60,
value: 50,
devicesUseLv: '20%',
},
{
name: "河南",
devicesCount: 160,
feiyue1: 40,
feiyue2: 60,
value: 80,
devicesUseLv: '20%',
},
{
name: "云南",
devicesCount: 110,
feiyue1: 40,
feiyue2: 60,
value: 40,
devicesUseLv: '20%',
},
{
name: "辽宁",
devicesCount: 320,
feiyue1: 40,
feiyue2: 60,
value: 120,
devicesUseLv: '20%',
},
{
name: "黑龙江",
devicesCount: 80,
feiyue1: 40,
feiyue2: 60,
value: 40,
devicesUseLv: '20%',
},
{
name: "湖南",
devicesCount: 60,
feiyue1: 40,
feiyue2: 60,
value: 10,
devicesUseLv: '20%',
},
{
name: "安徽",
devicesCount: 300,
feiyue1: 40,
feiyue2: 60,
value: 270,
devicesUseLv: '20%',
},
{
name: "山东",
devicesCount: 50,
feiyue1: 40,
feiyue2: 60,
value: 9,
devicesUseLv: '20%',
},
{
name: "新疆",
devicesCount: 40,
feiyue1: 40,
feiyue2: 60,
value: 0,
devicesUseLv: '20%',
},
{
name: "江苏",
devicesCount: 240,
feiyue1: 40,
feiyue2: 60,
value: 40,
devicesUseLv: '20%',
},
{
name: "浙江",
devicesCount: 450,
feiyue1: 40,
feiyue2: 60,
value: 300,
devicesUseLv: '20%',
},
{
name: "江西",
devicesCount: 20,
feiyue1: 40,
feiyue2: 60,
value: 4,
devicesUseLv: '20%',
},
{
name: "湖北",
devicesCount: 50,
feiyue1: 40,
feiyue2: 60,
value: 40,
devicesUseLv: '20%',
},
{
name: "广西",
devicesCount: 10,
feiyue1: 40,
feiyue2: 60,
value: 0,
devicesUseLv: '20%',
},
{
name: "甘肃",
devicesCount: 20,
feiyue1: 40,
feiyue2: 60,
value: 1,
devicesUseLv: '20%',
},
{
name: "山西",
devicesCount: 230,
feiyue1: 40,
feiyue2: 60,
value: 140,
devicesUseLv: '20%',
},
{
name: "内蒙古",
devicesCount: 200,
feiyue1: 40,
feiyue2: 60,
value: 0,
devicesUseLv: '20%',
},
{
name: "陕西",
devicesCount: 30,
feiyue1: 40,
feiyue2: 60,
value: 40,
devicesUseLv: '20%',
},
{
name: "吉林",
devicesCount: 77,
feiyue1: 40,
feiyue2: 60,
value: 40,
devicesUseLv: '20%',
},
{
name: "福建",
devicesCount: 55,
feiyue1: 40,
feiyue2: 60,
value: 8,
devicesUseLv: '20%',
},
{
name: "贵州",
devicesCount: 55,
feiyue1: 40,
feiyue2: 60,
value: 7,
devicesUseLv: '20%',
},
{
name: "广东省",
devicesCount: 44,
feiyue1: 40,
feiyue2: 60,
value: 6,
devicesUseLv: '20%',
},
{
name: "青海",
devicesCount: 33,
feiyue1: 40,
feiyue2: 60,
value: 5,
devicesUseLv: '20%',
},
{
name: "西藏",
devicesCount: 10,
feiyue1: 40,
feiyue2: 60,
value: 4,
devicesUseLv: '20%',
},
{
name: "四川",
devicesCount: 99,
feiyue1: 40,
feiyue2: 60,
value: 20,
devicesUseLv: '20%',
},
{
name: "宁夏",
devicesCount: 145,
feiyue1: 40,
feiyue2: 60,
value: 40,
devicesUseLv: '20%',
},
{
name: "海南",
devicesCount: 122,
feiyue1: 40,
feiyue2: 60,
value: 90,
devicesUseLv: '20%',
},
{
name: "台湾",
devicesCount: 10,
feiyue1: 4,
feiyue2: 6,
value: 0,
devicesUseLv: '20%',
},
{
name: "香港",
devicesCount: 0,
feiyue1: 0,
feiyue2: 0,
value: 0,
devicesUseLv: '0%',
},
{
name: "澳门",
devicesCount: 0,
feiyue1: 0,
feiyue2: 0,
value: 0,
devicesUseLv: '0%',
}
];
const option = {
tooltip: {
show: true,
formatter: function(params) {
if(params.value){
return '&nbsp;&nbsp;' + params.name + '&nbsp;&nbsp;&nbsp;' + params.value + '个&nbsp;&nbsp;';
}else{
return '&nbsp;&nbsp;' + params.name + '&nbsp;&nbsp;&nbsp;0个&nbsp;&nbsp;';
const option = computed(() => {
return {
tooltip: {
show: true,
formatter: function(params) {
console.log('params', params)
let html = ''
html = html + params.name + '<br />案件总金额:' + (isNaN(params.value) ? 0 : params.value) + '元'
if (params.data.tenants) {
params.data.tenants.forEach(ele => {
html = html + '<br /><br />' + ele.tenantName + '<br />案件金额:' + ele.commissionAmount
html = html + '<br />' + '案件数:' + ele.caseNum
html = html + '<br />' + '案人数:' + ele.borrowNum
})
}
return html
}
}
},
visualMap: {
min: 0,
left: 26,
bottom: 40,
showLabel: !0,
text: ["高", "低"],
textStyle: {
color: '#fff'
},
pieces: [{
gt: 200,
label: "1 - 9 人",
color: "#8616fe"
}, {
gt: 0,
lt: 200,
label: "疑似",
color: "#6b1dfd"
}, {
value: 0,
color: "rbga(255, 255, 255, 0.5)"
}],
show: !0
},
geo: {
map: 'china',
show: false,
roam: false,
label: {
emphasis: {
show: false
},
normal: {
show: false
}
},
itemStyle: {
normal: {
show: false
}
}
},
series: [
{
name: "确诊病例",
type: "map",
visualMap: {
min: 0,
left: 26,
bottom: 40,
showLabel: !0,
text: ["高", "低"],
textStyle: {
color: '#fff'
},
pieces: [{
gt: 5000,
label: "5000以上",
color: "#8616fe"
}, {
gt: 0,
lt: 5000,
label: "0-5000",
color: "#6b1dfd"
}, {
value: 0,
color: "rbga(255, 255, 255, 0.5)"
}],
show: !0
},
geo: {
map: 'china',
aspectScale: 0.75,
selectedMode: false,
top: 125,
zoom:1.53,
show: false,
roam: false,
label: {
normal: {
show: false,
fontSize: "14",
color: "rgba(0,0,0,0.7)"
},
emphasis: {
show: true,
fontSize: "14",
color: "rgba(255,255,255,1)"
show: false
},
normal: {
show: false
}
},
itemStyle: {
normal: {
areaColor: 'rgba(255,255,255,0.1)',
borderWidth: 2,
//shadowColor: 'rgba(0, 0, 0, 0.2)',
borderColor: "rgba(255,255,255,0.3)"
},
emphasis: {
areaColor: "#0196fa",
// shadowOffsetX: 0,
// shadowOffsetY: 0,
// borderWidth: 0
show: false
}
},
data: mapData
}
]
};
}
},
series: [
{
name: "确诊病例",
type: "map",
map: 'china',
aspectScale: 0.75,
selectedMode: false,
top: 145,
zoom:1.53,
label: {
normal: {
show: false,
fontSize: "14",
color: "rgba(0,0,0,0.7)"
},
emphasis: {
show: true,
fontSize: "14",
color: "rgba(255,255,255,1)"
}
},
itemStyle: {
normal: {
areaColor: 'rgba(255,255,255,0.1)',
borderWidth: 2,
//shadowColor: 'rgba(0, 0, 0, 0.2)',
borderColor: "rgba(255,255,255,0.3)"
},
emphasis: {
areaColor: "#0196fa",
// shadowOffsetX: 0,
// shadowOffsetY: 0,
// borderWidth: 0
}
},
data: mapData.value
}
]
}
})
</script>
<style lang="scss" scoped>
......
......@@ -243,10 +243,20 @@
}
.dataScreen-main-title {
position: absolute;
top: 1px;
top: 10px;
left: 0;
z-index: 99;
box-sizing: border-box;
display: flex;
flex-direction: column;
align-items: center;
width: 270px;
height: 25px;
padding-left: 30px;
font-size: 14px;
color: #ffffff;
letter-spacing: 5px;
background: url("./images/map-title-bg.png") no-repeat;
background-size: 100% 100%;
span {
margin-bottom: 12px;
font-family: YouSheBiaoTiHei;
......@@ -255,10 +265,6 @@
color: #ffffff;
letter-spacing: 1px;
}
img {
width: 68px;
height: 7px;
}
}
.dataScreen-main-chart {
width: 100%;
......
......@@ -18,26 +18,23 @@
<div class="dataScreen-lf">
<div class="dataScreen-top">
<div class="dataScreen-main-title">
<span>实时在案案人统计</span>
<img src="./images/dataScreen-title.png" alt="" />
实时在案案人统计
</div>
<div class="dataScreen-main-chart">
<RealTimeAccessChart />
<!-- <RealTimeAccessChart /> -->
</div>
</div>
<div class="dataScreen-center">
<div class="dataScreen-main-title">
<span>案人性别比例</span>
<img src="./images/dataScreen-title.png" alt="" />
案人性别比例
</div>
<div class="dataScreen-main-chart">
<MaleFemaleRatioChart />
<!-- <MaleFemaleRatioChart /> -->
</div>
</div>
<div class="dataScreen-bottom">
<div class="dataScreen-main-title">
<span>案人年龄比例</span>
<img src="./images/dataScreen-title.png" alt="" />
案人年龄比例
</div>
<div class="dataScreen-main-chart">
<AgeRatioChart />
......@@ -71,8 +68,7 @@
</div>
<div class="dataScreen-cb">
<div class="dataScreen-main-title">
<span>历史30天调解催记趋势</span>
<img src="./images/dataScreen-title.png" alt="" />
历史30天调解催记趋势
</div>
<div class="dataScreen-main-chart">
<OverNext30Chart />
......@@ -82,8 +78,7 @@
<div class="dataScreen-rg">
<div class="dataScreen-top">
<div class="dataScreen-main-title">
<span>调解中心案件量排名</span>
<img src="./images/dataScreen-title.png" alt="" />
调解中心案件量排名
</div>
<div class="dataScreen-main-chart">
<HotPlateChart />
......@@ -91,8 +86,7 @@
</div>
<div class="dataScreen-center">
<div class="dataScreen-main-title">
<span>年度案件量对比</span>
<img src="./images/dataScreen-title.png" alt="" />
年度案件量对比
</div>
<div class="dataScreen-main-chart">
<AnnualUseChart />
......@@ -100,8 +94,7 @@
</div>
<div class="dataScreen-bottom">
<div class="dataScreen-main-title">
<span>案源数据统计</span>
<img src="./images/dataScreen-title.png" alt="" />
案源数据统计
</div>
<div class="dataScreen-main-chart">
<PlatformSourceChart />
......
......@@ -109,9 +109,10 @@
import addModel from './components/addModel.vue';
import { useDict } from '@/hooks/useDict';
import { useAuthStore } from '@/stores/modules/auth';
import { useUserStore } from '@/stores/modules/user';
const activeName = ref('created');
const userStore = useUserStore();
const { authButtonListGet } = useAuthStore(); // 获取用户权限列表
const { PaymentForm, ContractStatus, FlowStatus } = useDict("PaymentForm", "ContractStatus", "FlowStatus");
const addModelRef = ref()
......@@ -294,7 +295,7 @@
default({ row }) {
return (
<>
<ElButton type="primary" link onClick={() => addConstant(row, true)} disabled={row.legalFlowStatus=== 'pass' && row.financeFlowStatus === 'pass'}>
<ElButton type="primary" link onClick={() => addConstant(row, true)} v-show={row.createBy === userStore.userInfo.id} disabled={row.legalFlowStatus=== 'pass' && row.financeFlowStatus === 'pass'}>
修改
</ElButton>
<ElButton type="primary" link onClick={() => apply(row, 'finance')} v-show={authButtonListGet.includes('finance_apply')} disabled={row.legalFlowStatus || row.financeFlowStatus === 'pass'}>
......
......@@ -128,17 +128,15 @@
</td>
</tr>
<tr>
<td class="label" rowspan="2">个人及夫妻名下车辆</td>
<td class="label">数量</td>
<td ><el-input class="line-input" v-model="form.carNum" placeholder="" /></td>
<td class="label" rowspan="2">个人及夫妻名下房产</td>
<td class="label">数量</td>
<td ><el-input class="line-input" v-model="form.houseNum" placeholder="" /></td>
<td class="label">个人及夫妻名下车辆数量</td>
<td colspan="2"><el-input class="line-input" v-model="form.carNum" placeholder="" /></td>
<td class="label">个人及夫妻名下房产数量</td>
<td colspan="2"><el-input class="line-input" v-model="form.houseNum" placeholder="" /></td>
</tr>
<tr>
<td class="label">总价值</td>
<td><el-input class="line-input" v-model="form.carPrice" placeholder="" /></td>
<td class="label">总价值</td>
<td class="label">个人及夫妻名下车辆总价值</td>
<td colspan="2"><el-input class="line-input" v-model="form.carPrice" placeholder="" /></td>
<td class="label">个人及夫妻名下房产总价值</td>
<td colspan="2"><el-input class="line-input" v-model="form.housePrice" placeholder="" /></td>
</tr>
<tr>
......@@ -438,8 +436,8 @@ const handleQuery = () => {
}
getDebtInfo(form.value.idCard).then(res => {
if(res.result) {
res.result.creditCard = res.result.creditCard || []
res.result.lending = res.result.lending || []
res.result.creditCard = []
res.result.lending = []
form.value = res.result
cardConfig.data = res.result.creditCard
creditArr.value = res.result.lending
......
......@@ -26,9 +26,11 @@
import { reactive, ref } from 'vue';
import { ElButton, ElMessageBox, ElMessage, ElTag } from 'element-plus';
import { getUserPage, saveUser, deleteUsers } from '@/api/user';
import { useDict } from '@/hooks/useDict';
import { onMounted } from 'vue';
import { getTenantPage } from '@/api/tenant';
import { getRolePage } from '@/api/role';
const { Status } = useDict("Status");
const proTable = ref();
const accountFormModalRef = ref();
......@@ -78,6 +80,7 @@
field: 'status',
title: '状态',
width: 100,
enum: Status,
search: { el: 'select', props: { clearable: true }, labelWidth: 85 },
slots: {
default: ({ row }) => {
......
<template>
<vxe-modal
resize
v-model="showModal"
:title="modalTitle"
@hide="onHide"
width="400px"
show-footer
esc-closable
>
<el-form ref="formRef" inline :model="form" :rules="rules" label-width="80px">
<el-row :gutter="10">
<el-col :span="24">
<el-form-item class="w-full" label="手机号" prop="phone">
<el-input v-model="form.phone" placeholder="请输入手机号" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item class="w-full" label="密码" prop="password">
<el-input v-model="form.password" placeholder="请输入密码" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item class="w-full" label="用户名称" prop="username">
<el-input v-model="form.username" placeholder="请输入用户名称" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item class="w-full" label="状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio value="enable">启用</el-radio>
<el-radio value="disable">禁用</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<el-button type="default" @click="showModal = false">取消</el-button>
<el-button type="primary" @click="submitForm">提交</el-button>
</template>
</vxe-modal>
</template>
<script setup>
import { computed } from 'vue';
import { ref } from 'vue';
import { saveLeaderGroup } from '@/api/user';
import { getDefualtRoles } from '@/api/role';
import { ElMessage } from 'element-plus';
const emits = defineEmits(['success']);
const formRef = ref();
const showModal = ref(false);
const loading = ref(false);
const form = ref({
username: '',
password: '',
phone: '',
status: 'enable',
});
const options = ref([]);
const validatePhone = (rule, value, callback) => {
const reg = /^1[3-9]\d{9}$/;
if (!value) {
callback(new Error('请输入手机号'));
} else if (!reg.test(value)) {
callback(new Error('请输入正确的手机号'));
} else {
callback();
}
};
const rules = ref({
username: { required: true, message: '请输入用户名称', trigger: 'blur' },
password: { required: true, message: '请输入密码', trigger: 'blur' },
phone: [
{ required: true, message: '请输入手机号', trigger: 'blur' },
{ validator: validatePhone, trigger: 'blur' },
],
});
const currentAccount = ref(null);
const isEdit = computed(() => !!currentAccount.value);
const modalTitle = computed(() => (isEdit.value ? '编辑账号' : '新增账号'));
const submitForm = async () => {
try {
await formRef.value.validate();
loading.value = true;
await saveLeaderGroup({...form.value, role: 'legal_affairs_commissioner'});
ElMessage({
type: 'success',
message: isEdit.value ? '修改成功!' : '添加成功!',
plain: true,
});
emits('success');
showModal.value = false;
} catch {}
loading.value = false;
};
const onHide = () => {
form.value = {
username: '',
roles: [],
password: '',
phone: '',
status: 'enable',
};
formRef.value.clearValidate();
currentAccount.value = null;
showModal.value = false;
};
const openModal = (account) => {
account && (form.value = account);
getDefualtRoles().then((res) => {
options.value = res.result;
});
currentAccount.value = account;
showModal.value = true;
};
defineExpose({
openModal,
});
</script>
<style lang="scss" scoped></style>
<template>
<div class="table-box">
<ProTable ref="proTable" :config="config" :api="getleaderGroupPage" :paramCallback="paramCallback">
<template #left_buttons>
<el-button
v-permission="'legal_member_add'"
type="primary"
:icon="Plus"
@click="accountFormModalRef?.openModal()"
>新增</el-button
>
<el-button v-permission="'legal_member_del'" type="danger" :icon="Delete" @click="handleDelete"
>删除</el-button
>
</template>
</ProTable>
<AccountFormModal ref="accountFormModalRef" @success="query" />
</div>
</template>
<script setup lang="jsx" name="accountManage">
import ProTable from '@/components/ProTable/index.vue';
import AccountFormModal from './components/AccountFormModal.vue';
import { Delete, Edit, Plus } from '@element-plus/icons-vue';
import { reactive, ref } from 'vue';
import { ElButton, ElMessageBox, ElMessage, ElTag } from 'element-plus';
import { getleaderGroupPage, saveLeaderGroup, batchDeleteByIds } from '@/api/user';
import { useDict } from '@/hooks/useDict';
import { onMounted } from 'vue';
import { getTenantPage } from '@/api/tenant';
import { getRolePage } from '@/api/role';
const { Status } = useDict("Status");
const proTable = ref();
const accountFormModalRef = ref();
const Rolelist = ref([]);
const Tenantlist = ref([]);
const paramCallback = (param) => {
const obj = JSON.parse(JSON.stringify(param));
obj['staffRole'] = 'legal_affairs_commissioner'
return obj;
};
const config = reactive({
columns: [
{ type: 'checkbox', width: 60, fixed: 'left' },
{ field: 'leader.username', width: 110, title: '领导用户名称', search: { el: 'input', labelWidth: 85 } },
{ field: 'staff.username', width: 110, title: '员工用户名称', search: { el: 'input', labelWidth: 85 } },
{
showOverflow: 'tooltip',
slots: {
default: ({ row }) => {
return (
<>{Array.from(new Set(row.staff.tenantNames)).join(',')}</>
);
},
},
field: 'tenantNames',
enum: Tenantlist,
search: { el: 'select', props: { filterable: true }, key: 'tenantId', labelWidth: 85 },
fieldNames: { label: 'name', value: 'id' },
title: '员工调解中心'
},
{
showOverflow: 'tooltip',
slots: {
default: ({ row }) => {
return (
<>{Array.from(new Set(row.staff.roleNames)).join(',')}</>
);
},
},
field: 'role',
enum: Rolelist,
search: { el: 'select', props: { filterable: true }, key: 'roleCode', labelWidth: 85 },
fieldNames: { label: 'roleName', value: 'roleCode' },
title: '员工角色'
},
{
field: 'staff.phone',
title: '员工手机号',
width: 160,
search: { el: 'input', props: { clearable: true }, labelWidth: 85 },
},
{
field: 'staff.status',
title: '员工状态',
width: 100,
enum: Status,
search: { el: 'select', props: { clearable: true }, labelWidth: 85 },
slots: {
default: ({ row }) => {
return (
<ElTag type={row.status == 'enable' ? 'primary' : 'danger'}>
{row.status == 'enable' ? '启用' : '禁用'}
</ElTag>
);
},
},
},
{
field: 'staff.createTime',
title: '员工创建时间',
width: 170,
},
{
field: 'staff.updateTime',
title: '员工更新时间',
width: 170,
},
{
field: 'action',
title: '操作',
width: 200,
fixed: 'right',
slots: {
default: ({ row }) => {
return (
<>
<ElButton link type="primary" icon={Edit} onClick={() => editAccount(row)}>
编辑
</ElButton>
<ElButton link type="primary" icon={Edit} onClick={() => handleDisable(row)}>
{row.status == 'enable' ? '禁用' : '启用'}
</ElButton>
</>
);
},
},
},
],
});
const handleDelete = async () => {
const list = proTable.value.element.getCheckboxRecords();
if (list.length) {
await ElMessageBox.confirm('是否确认删除选中账户?', '提示', {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
});
const ids = list.map((v) => v.id).join(',');
await batchDeleteByIds(ids);
ElMessage({
type: 'success',
message: '删除成功!',
plain: true,
});
query();
}
};
const editAccount = (row) => accountFormModalRef.value.openModal(JSON.parse(JSON.stringify(row)));
const handleDisable = async (row) => {
await ElMessageBox.confirm(
`是否确认${row.status == 'enable' ? '禁用' : '启用'}该用户?`,
'提示',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
}
);
// 修改的状态
const status = row.status === 'enable' ? 'disable' : 'enable';
await saveLeaderGroup({
...row,
status,
});
row.status = status;
ElMessage({
type: 'success',
message: `${status == 'enable' ? '启用' : '禁用'}成功!`,
plain: true,
});
};
const query = () => proTable.value?.search();
onMounted(() => {
query();
getRolePage({ current: 1, size: 9999999 }).then(res => {
if (res.success) {
Rolelist.value = res.result.content
}
})
getTenantPage({ current: 1, size: 9999999, status: 'enable' }).then(res => {
if (res.success) {
Tenantlist.value = res.result.content
console.log('Tenantlist.value', Tenantlist.value)
}
})
});
</script>
<style lang="scss" scoped></style>
<template>
<vxe-modal
resize
v-model="showModal"
:title="modalTitle"
@hide="onHide"
width="400px"
show-footer
esc-closable
>
<el-form ref="formRef" inline :model="form" :rules="rules" label-width="80px">
<el-row :gutter="10">
<el-col :span="24">
<el-form-item class="w-full" label="手机号" prop="phone">
<el-input v-model="form.phone" placeholder="请输入手机号" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item class="w-full" label="密码" prop="password">
<el-input v-model="form.password" placeholder="请输入密码" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item class="w-full" label="用户名称" prop="username">
<el-input v-model="form.username" placeholder="请输入用户名称" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item class="w-full" label="状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio value="enable">启用</el-radio>
<el-radio value="disable">禁用</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<el-button type="default" @click="showModal = false">取消</el-button>
<el-button type="primary" @click="submitForm">提交</el-button>
</template>
</vxe-modal>
</template>
<script setup>
import { computed } from 'vue';
import { ref } from 'vue';
import { saveLeaderGroup } from '@/api/user';
import { getDefualtRoles } from '@/api/role';
import { ElMessage } from 'element-plus';
const emits = defineEmits(['success']);
const formRef = ref();
const showModal = ref(false);
const loading = ref(false);
const form = ref({
username: '',
password: '',
phone: '',
status: 'enable',
});
const options = ref([]);
const validatePhone = (rule, value, callback) => {
const reg = /^1[3-9]\d{9}$/;
if (!value) {
callback(new Error('请输入手机号'));
} else if (!reg.test(value)) {
callback(new Error('请输入正确的手机号'));
} else {
callback();
}
};
const rules = ref({
username: { required: true, message: '请输入用户名称', trigger: 'blur' },
password: { required: true, message: '请输入密码', trigger: 'blur' },
phone: [
{ required: true, message: '请输入手机号', trigger: 'blur' },
{ validator: validatePhone, trigger: 'blur' },
],
});
const currentAccount = ref(null);
const isEdit = computed(() => !!currentAccount.value);
const modalTitle = computed(() => (isEdit.value ? '编辑账号' : '新增账号'));
const submitForm = async () => {
try {
await formRef.value.validate();
loading.value = true;
await saveLeaderGroup({...form.value, role: 'risk_control_commissioner'});
ElMessage({
type: 'success',
message: isEdit.value ? '修改成功!' : '添加成功!',
plain: true,
});
emits('success');
showModal.value = false;
} catch {}
loading.value = false;
};
const onHide = () => {
form.value = {
username: '',
roles: [],
password: '',
phone: '',
status: 'enable',
};
formRef.value.clearValidate();
currentAccount.value = null;
showModal.value = false;
};
const openModal = (account) => {
account && (form.value = account);
getDefualtRoles().then((res) => {
options.value = res.result;
});
currentAccount.value = account;
showModal.value = true;
};
defineExpose({
openModal,
});
</script>
<style lang="scss" scoped></style>
<template>
<div class="table-box">
<ProTable ref="proTable" :config="config" :api="getleaderGroupPage" :paramCallback="paramCallback">
<template #left_buttons>
<el-button
v-permission="'risk_member_add'"
type="primary"
:icon="Plus"
@click="accountFormModalRef?.openModal()"
>新增</el-button
>
<el-button v-permission="'risk_member_del'" type="danger" :icon="Delete" @click="handleDelete"
>删除</el-button
>
</template>
</ProTable>
<AccountFormModal ref="accountFormModalRef" @success="query" />
</div>
</template>
<script setup lang="jsx" name="accountManage">
import ProTable from '@/components/ProTable/index.vue';
import AccountFormModal from './components/AccountFormModal.vue';
import { Delete, Edit, Plus } from '@element-plus/icons-vue';
import { reactive, ref } from 'vue';
import { ElButton, ElMessageBox, ElMessage, ElTag } from 'element-plus';
import { getleaderGroupPage, saveLeaderGroup, batchDeleteByIds } from '@/api/user';
import { useDict } from '@/hooks/useDict';
import { onMounted } from 'vue';
import { getTenantPage } from '@/api/tenant';
import { getRolePage } from '@/api/role';
const { Status } = useDict("Status");
const proTable = ref();
const accountFormModalRef = ref();
const Rolelist = ref([]);
const Tenantlist = ref([]);
const paramCallback = (param) => {
const obj = JSON.parse(JSON.stringify(param));
obj['staffRole'] = 'risk_control_commissioner'
return obj;
};
const config = reactive({
columns: [
{ type: 'checkbox', width: 60, fixed: 'left' },
{ field: 'leader.username', width: 110, title: '领导用户名称', search: { el: 'input', labelWidth: 85 } },
{ field: 'staff.username', width: 110, title: '员工用户名称', search: { el: 'input', labelWidth: 85 } },
{
showOverflow: 'tooltip',
slots: {
default: ({ row }) => {
return (
<>{Array.from(new Set(row.staff.tenantNames)).join(',')}</>
);
},
},
field: 'tenantNames',
enum: Tenantlist,
search: { el: 'select', props: { filterable: true }, key: 'tenantId', labelWidth: 85 },
fieldNames: { label: 'name', value: 'id' },
title: '员工调解中心'
},
{
showOverflow: 'tooltip',
slots: {
default: ({ row }) => {
return (
<>{Array.from(new Set(row.staff.roleNames)).join(',')}</>
);
},
},
field: 'role',
enum: Rolelist,
search: { el: 'select', props: { filterable: true }, key: 'roleCode', labelWidth: 85 },
fieldNames: { label: 'roleName', value: 'roleCode' },
title: '员工角色'
},
{
field: 'staff.phone',
title: '员工手机号',
width: 160,
search: { el: 'input', props: { clearable: true }, labelWidth: 85 },
},
{
field: 'staff.status',
title: '员工状态',
width: 100,
enum: Status,
search: { el: 'select', props: { clearable: true }, labelWidth: 85 },
slots: {
default: ({ row }) => {
return (
<ElTag type={row.status == 'enable' ? 'primary' : 'danger'}>
{row.status == 'enable' ? '启用' : '禁用'}
</ElTag>
);
},
},
},
{
field: 'staff.createTime',
title: '员工创建时间',
width: 170,
},
{
field: 'staff.updateTime',
title: '员工更新时间',
width: 170,
},
{
field: 'action',
title: '操作',
width: 200,
fixed: 'right',
slots: {
default: ({ row }) => {
return (
<>
<ElButton link type="primary" icon={Edit} onClick={() => editAccount(row)}>
编辑
</ElButton>
<ElButton link type="primary" icon={Edit} onClick={() => handleDisable(row)}>
{row.status == 'enable' ? '禁用' : '启用'}
</ElButton>
</>
);
},
},
},
],
});
const handleDelete = async () => {
const list = proTable.value.element.getCheckboxRecords();
if (list.length) {
await ElMessageBox.confirm('是否确认删除选中账户?', '提示', {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
});
const ids = list.map((v) => v.id).join(',');
await batchDeleteByIds(ids);
ElMessage({
type: 'success',
message: '删除成功!',
plain: true,
});
query();
}
};
const editAccount = (row) => accountFormModalRef.value.openModal(JSON.parse(JSON.stringify(row)));
const handleDisable = async (row) => {
await ElMessageBox.confirm(
`是否确认${row.status == 'enable' ? '禁用' : '启用'}该用户?`,
'提示',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
}
);
// 修改的状态
const status = row.status === 'enable' ? 'disable' : 'enable';
await saveLeaderGroup({
...row,
status,
});
row.status = status;
ElMessage({
type: 'success',
message: `${status == 'enable' ? '启用' : '禁用'}成功!`,
plain: true,
});
};
const query = () => proTable.value?.search();
onMounted(() => {
query();
getRolePage({ current: 1, size: 9999999 }).then(res => {
if (res.success) {
Rolelist.value = res.result.content
}
})
getTenantPage({ current: 1, size: 9999999, status: 'enable' }).then(res => {
if (res.success) {
Tenantlist.value = res.result.content
console.log('Tenantlist.value', Tenantlist.value)
}
})
});
</script>
<style lang="scss" scoped></style>
......@@ -9,7 +9,7 @@
<RoleFormModal ref="roleModalRef" @success="query" />
<AllocationMenuModal ref="allocationMenuModalRef" @success="query" />
<AllocationUserModal ref="allocationUserModalRef" />
<AllocationUserModal ref="allocationUserModalRef" @success="query" />
</div>
</template>
......
......@@ -55,8 +55,9 @@ export default defineConfig(({ command, mode }) => {
port: VITE_PORT,
proxy: {
'/api': {
// target: 'http://192.168.31.128:8080',
target: 'http://8.152.205.9:8080',
// target: 'http://192.168.31.189:8080',
target: 'http://192.168.31.128:8080',
// target: 'http://8.152.205.9:8080',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
},
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment