作者 xiaoqiu

增加了首页统计图标

... ... @@ -7,7 +7,7 @@
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" href="/favicon.ico">
<title>若依管理系统</title>
<title>广西保险行业协会车险投保登记平台</title>
<!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
<style>
html,
... ...
... ... @@ -20,7 +20,7 @@
"@vueuse/core": "9.5.0",
"axios": "0.27.2",
"compressorjs": "^1.2.1",
"echarts": "5.4.0",
"echarts": "^5.5.1",
"element-plus": "2.2.21",
"file-saver": "2.0.5",
"fuse.js": "6.6.2",
... ... @@ -30,7 +30,8 @@
"pinia": "2.0.22",
"vue": "3.2.45",
"vue-cropper": "1.0.3",
"vue-router": "4.1.4"
"vue-router": "4.1.4",
"vue3-count-to": "^1.1.2"
},
"devDependencies": {
"@vitejs/plugin-vue": "3.1.0",
... ...
import request from '@/utils/request'
// 获取统计信息
export function getStatistics(data) {
return request({
url: '/registration/monitor/statistics',
method: 'get',
params: data
})
}
\ No newline at end of file
... ...
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1729153352026" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="13540" xmlns:xlink="http://www.w3.org/1999/xlink" width="256" height="256"><path d="M625.728 57.472c16.512 0 30.208 4.992 42.24 14.848l5.888 5.312 208.96 207.04c12.224 11.2 19.328 24.96 21.12 41.024l0.448 8.256v232.32a287.104 287.104 0 0 0-76.8-39.424V374.016H687.36A96 96 0 0 1 592 287.36l-0.448-9.216V134.208l-339.328 0.064c-27.84 0-48.384 18.176-51.392 43.904l-0.384 6.528v653.824c0 27.136 18.624 47.616 44.992 50.56l6.784 0.384h210.048c9.024 27.712 22.144 53.568 38.656 76.864H252.16c-68.8 0-123.392-50.816-128.192-118.08l-0.384-9.728V184.704c0-68.48 51.2-122.112 118.784-126.912L252.16 57.472h373.568z m63.04 620.736l81.472 81.408 81.408-81.408a38.4 38.4 0 0 1 54.336 54.272l-81.408 81.408 81.408 81.536a38.4 38.4 0 0 1-54.336 54.272l-81.408-81.536-81.472 81.536a38.4 38.4 0 1 1-54.336-54.272l81.472-81.536-81.472-81.408a38.4 38.4 0 1 1 54.336-54.272zM393.088 704a38.4 38.4 0 0 1 0 76.8H294.4a38.4 38.4 0 0 1 0-76.8h98.688zM665.6 512a38.4 38.4 0 0 1 0 76.8H294.4a38.4 38.4 0 0 1 0-76.8h371.2z m-192-192a38.4 38.4 0 1 1 0 76.8H294.4a38.4 38.4 0 1 1 0-76.8h179.2z m325.76-9.984L655.36 167.488v110.592a32 32 0 0 0 26.24 31.488l5.76 0.512h111.872z" p-id="13541"></path></svg>
\ No newline at end of file
... ...
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1729153214328" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6614" xmlns:xlink="http://www.w3.org/1999/xlink" width="256" height="256"><path d="M544.65616 960A272 272 0 0 1 799.95216 491.968V128a64 64 0 0 0-64-64H159.95216a64 64 0 0 0-64 64v768a64 64 0 0 0 64 64h384.704zM863.95216 521.216a272 272 0 0 1-128 502.336V1024H159.95216a128 128 0 0 1-128-128V128a128 128 0 0 1 128-128h576a128 128 0 0 1 128 128v393.216zM719.95216 960a208 208 0 1 0 0-416 208 208 0 0 0 0 416zM255.95216 192h384a32 32 0 0 1 0 64H255.95216a32 32 0 0 1 0-64z m0 160h192a32 32 0 0 1 0 64H255.95216a32 32 0 0 1 0-64z m352 368h224a32 32 0 0 1 0 64h-224a32 32 0 0 1 0-64z" p-id="6615"></path></svg>
\ No newline at end of file
... ...
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1729149317544" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7294" xmlns:xlink="http://www.w3.org/1999/xlink" width="256" height="256"><path d="M384 896 160 896c-52.9 0-96-43.1-96-96L64 160c0-52.9 43.1-96 96-96l512 0c52.9 0 96 43.1 96 96l0 192c0 17.7-14.3 32-32 32s-32-14.3-32-32L704 160c0-17.6-14.4-32-32-32L160 128c-17.6 0-32 14.4-32 32l0 640c0 17.6 14.4 32 32 32l224 0c17.7 0 32 14.3 32 32S401.7 896 384 896z" p-id="7295"></path><path d="M688 960c-72.7 0-141-28.3-192.3-79.7C444.3 829 416 760.7 416 688c0-72.7 28.3-141 79.7-192.3C547 444.3 615.3 416 688 416c72.7 0 141 28.3 192.3 79.7S960 615.4 960 688c0 72.7-28.3 141-79.7 192.3S760.7 960 688 960zM688 480c-114.7 0-208 93.3-208 208s93.3 208 208 208 208-93.3 208-208S802.7 480 688 480z" p-id="7296"></path><path d="M608 320 224 320c-17.7 0-32-14.3-32-32s14.3-32 32-32l384 0c17.7 0 32 14.3 32 32S625.7 320 608 320z" p-id="7297"></path><path d="M384 512 224 512c-17.7 0-32-14.3-32-32s14.3-32 32-32l160 0c17.7 0 32 14.3 32 32S401.7 512 384 512z" p-id="7298"></path><path d="M320 704l-96 0c-17.7 0-32-14.3-32-32s14.3-32 32-32l96 0c17.7 0 32 14.3 32 32S337.7 704 320 704z" p-id="7299"></path><path d="M704 800c-6.3 0-12.5-1.8-17.8-5.4l-96-64c-14.7-9.8-18.7-29.7-8.9-44.4 9.8-14.7 29.7-18.7 44.4-8.9l68.1 45.4 78.7-131.2c9.1-15.2 28.8-20.1 43.9-11 15.2 9.1 20.1 28.7 11 43.9l-96 160c-4.5 7.5-11.9 12.8-20.4 14.8C708.7 799.8 706.3 800 704 800z" p-id="7300"></path></svg>
\ No newline at end of file
... ...
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1729153319768" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="12517" xmlns:xlink="http://www.w3.org/1999/xlink" width="256" height="256"><path d="M102.4 51.2a51.2 51.2 0 0 0-51.2 51.2v819.2a51.2 51.2 0 0 0 51.2 51.2h819.2a51.2 51.2 0 0 0 51.2-51.2V102.4a51.2 51.2 0 0 0-51.2-51.2H102.4z m0-51.2h819.2a102.4 102.4 0 0 1 102.4 102.4v819.2a102.4 102.4 0 0 1-102.4 102.4H102.4a102.4 102.4 0 0 1-102.4-102.4V102.4a102.4 102.4 0 0 1 102.4-102.4zM51.2 204.8h921.6v51.2H51.2V204.8z m392.192 525.4656L712.0384 481.28a25.6 25.6 0 0 1 34.816 37.5808l-286.464 265.4208a25.6 25.6 0 0 1-35.1744-0.3072l-158.1056-151.9616a25.6 25.6 0 1 1 35.4304-36.864l140.8 135.168z" p-id="12518"></path></svg>
\ No newline at end of file
... ...
<template>
<el-row :gutter="40" class="panel-group">
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('newVisitis')">
<div class="card-panel-icon-wrapper icon-people">
<svg-icon icon-class="notaccepted" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">未承接</div>
<count-to
:start-val="0"
:end-val="102400"
:duration="2600"
class="card-panel-num"
/>
</div>
</div>
</el-col>
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('messages')">
<div class="card-panel-icon-wrapper icon-message">
<svg-icon icon-class="undertaken" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">已承接</div>
<count-to
:start-val="0"
:end-val="81212"
:duration="3000"
class="card-panel-num"
/>
</div>
</div>
</el-col>
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('purchases')">
<div class="card-panel-icon-wrapper icon-money">
<svg-icon icon-class="incomplete" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">未完成</div>
<count-to
:start-val="0"
:end-val="9280"
:duration="3200"
class="card-panel-num"
/>
</div>
</div>
</el-col>
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('shoppings')">
<div class="card-panel-icon-wrapper icon-shopping">
<svg-icon icon-class="success" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">已完成</div>
<count-to
:start-val="0"
:end-val="13600"
:duration="3600"
class="card-panel-num"
/>
</div>
</div>
</el-col>
</el-row>
</template>
<script setup>
import { CountTo } from "vue3-count-to";
const $emit = defineEmits(["handleSetLineChartData"]);
const handleSetLineChartData = (type) => {
$emit("handleSetLineChartData", type);
};
</script>
<style lang="scss" scoped>
.panel-group {
margin-top: 18px;
.card-panel-col {
margin-bottom: 32px;
}
.card-panel {
height: 108px;
cursor: pointer;
font-size: 12px;
position: relative;
overflow: hidden;
color: #666;
background: #fff;
box-shadow: 4px 4px 40px rgba(0, 0, 0, 0.05);
border-color: rgba(0, 0, 0, 0.05);
&:hover {
.card-panel-icon-wrapper {
color: #fff;
}
.icon-people {
background: #7f36fe;
}
.icon-message {
background: #36a3f7;
}
.icon-money {
background: #f4516c;
}
.icon-shopping {
background: #34bfa3;
}
}
.icon-people {
color: #7f36fe;
}
.icon-message {
color: #36a3f7;
}
.icon-money {
color: #f4516c;
}
.icon-shopping {
color: #34bfa3;
}
.card-panel-icon-wrapper {
float: left;
margin: 14px 0 0 14px;
padding: 16px;
transition: all 0.38s ease-out;
border-radius: 6px;
}
.card-panel-icon {
float: left;
font-size: 48px;
}
.card-panel-description {
float: right;
font-weight: bold;
margin: 26px;
margin-left: 0px;
.card-panel-text {
line-height: 18px;
color: rgba(0, 0, 0, 0.45);
font-size: 16px;
margin-bottom: 12px;
}
.card-panel-num {
font-size: 20px;
}
}
}
}
@media (max-width: 550px) {
.card-panel-description {
display: none;
}
.card-panel-icon-wrapper {
float: none !important;
width: 100%;
height: 100%;
margin: 0 !important;
.svg-icon {
display: block;
margin: 14px auto !important;
float: none !important;
}
}
}
</style>
... ...
import { createApp } from 'vue'
import Cookies from 'js-cookie'
import * as echarts from 'echarts'
import ElementPlus from 'element-plus'
import locale from 'element-plus/lib/locale/lang/zh-cn' // 中文语言
... ... @@ -55,6 +55,7 @@ app.config.globalProperties.handleTree = handleTree
app.config.globalProperties.addDateRange = addDateRange
app.config.globalProperties.selectDictLabel = selectDictLabel
app.config.globalProperties.selectDictLabels = selectDictLabels
app.config.globalProperties.echarts = echarts
// 全局组件挂载
app.component('DictTag', DictTag)
... ...
... ... @@ -60,7 +60,15 @@ export const constantRoutes = [
{
path: '',
component: Layout,
redirect: '/policy/pending'
redirect: '/index',
children: [
{
path: '/index',
component: () => import('@/views/index'),
name: 'Index',
meta: { title: '首页', icon: 'dashboard', affix: true }
}
]
},
{
path: '/user',
... ...
<template>
<div class="index-page">
<div class="card-list">
<el-card class="box-card">
<template #header>
<span>流程</span>
<el-tag style="float: right" size="small" effect="dark">月</el-tag>
</template>
<h2>3</h2>
<span>总流程数</span>
<span style="color: #1890ff; float: right">
<span>98%</span>
<span class="el-icon-top"></span>
</span>
</el-card>
<el-card class="box-card">
<template #header>
<span>运行</span>
<el-tag style="float: right" type="success" size="small" effect="dark"
>全年</el-tag
<div class="app-container">
<el-row :gutter="20">
<el-col :span="6" :xs="24">
<el-card class="box-card">
<template v-slot:header>
<div class="clearfix">
<span>个人信息</span>
</div>
</template>
<div>
<div class="text-center">
<img
:src="userStore.avatar"
style="width: 120px; height: 120px; border-radius: 50%"
/>
</div>
<ul class="list-group list-group-striped">
<li class="list-group-item">
<svg-icon icon-class="user" />用户昵称
<div class="pull-right">{{ state.user.nickName }}</div>
</li>
<li class="list-group-item">
<svg-icon icon-class="phone" />手机号码
<div class="pull-right">{{ state.user.phonenumber }}</div>
</li>
<li class="list-group-item">
<svg-icon icon-class="email" />用户邮箱
<div class="pull-right">{{ state.user.email }}</div>
</li>
<li class="list-group-item">
<svg-icon icon-class="tree" />所属部门
<div class="pull-right" v-if="state.user.dept">
{{ state.user.dept.deptName }} / {{ state.postGroup }}
</div>
</li>
<li class="list-group-item">
<svg-icon icon-class="peoples" />所属角色
<div class="pull-right">{{ state.roleGroup }}</div>
</li>
<li class="list-group-item">
<svg-icon icon-class="date" />创建日期
<div class="pull-right">{{ state.user.createTime }}</div>
</li>
</ul>
</div>
</el-card>
</el-col>
<el-col :span="18" :xs="24">
<PanelGroup :listData="listData" />
<!-- 统计柱状图 -->
<div class="echarts_box">
<div
v-hasRole="['admin', 'associationemployee']"
class="select_company"
>
</template>
<h2>89</h2>
<span>流程实例数</span>
<span style="color: #13ce66; float: right">
<span>20%</span>
<span class="el-icon-top"></span>
</span>
</el-card>
<el-card class="box-card">
<template #header>
<span>执行</span>
<el-tag style="float: right" type="success" size="small" effect="dark"
>今天</el-tag
>
</template>
<h2>105</h2>
<span>执行实例数</span>
<span style="color: #13ce66; float: right">
<span>44%</span>
<span class="el-icon-top"></span>
</span>
</el-card>
<el-card class="box-card">
<template #header>
<span>待办任务数</span>
<el-tag style="float: right" type="danger" size="small" effect="dark"
>历史记录</el-tag
>
</template>
<h2>451</h2>
<span>12月</span>
<span style="color: red; float: right">
<span>38%</span>
<span class="el-icon-bottom"></span>
</span>
</el-card>
</div>
<p>选择保险公司</p>
<el-select
v-model="queryParams.deptIds[0]"
placeholder="请选择保险公司"
style="width: 240px"
@change="getList"
>
<el-option
v-for="item in deptOptions"
:key="item.deptId"
:label="item.deptName"
:value="item.deptId"
/>
</el-select>
</div>
<div ref="chartRef" style="width: 100%; height: 400px"></div>
</div>
</el-col>
</el-row>
</div>
</template>
<script setup></script>
<script setup>
import useUserStore from "@/store/modules/user";
import { getUserProfile } from "@/api/system/user";
import { getStatistics } from "@/api/index";
import PanelGroup from "@/components/PanelGroup";
import { listDept } from "@/api/system/dept";
import { onMounted } from "vue";
const { proxy } = getCurrentInstance();
const userStore = useUserStore();
const chartRef = ref(null);
const listData = ref([]);
const xList = ref([]);
const company = ref("");
const option = ref({});
const deptOptions = ref([]);
const queryParams = reactive({
deptIds: [""],
type: 1,
startTime: proxy.parseTime(
new Date().setFullYear(new Date().getFullYear() - 1)
),
endTime: proxy.parseTime(new Date()),
});
const state = reactive({
user: {},
roleGroup: {},
postGroup: {},
});
<style>
.index-page {
background-color: #f3f3f4;
height: calc(100vh - 88px);
padding: 20px;
onMounted(() => {
getList();
if (proxy.$auth.hasRoleOr(["admin", "common"])) {
getDeptList();
}
});
/** 查询部门列表 */
const getDeptList = () => {
listDept().then((response) => {
deptOptions.value = response.data.filter((item) => item.parentId === 100);
});
};
function getUser() {
getUserProfile().then((response) => {
state.user = response.data;
state.roleGroup = response.roleGroup;
state.postGroup = response.postGroup;
});
}
.card-list {
font-size: 14px;
const showText = (index) => {
let obj = {
0: "未承接",
1: "已承接",
2: "未完成",
3: "已完成",
};
return obj[index];
};
// 获取统计数据
const getList = async () => {
const { data } = await getStatistics(queryParams);
xList.value = data?.map((item) => item.month);
let newData = data?.map((data) => data.statisticsVo[0]);
let newArr = newData?.map((item) => {
return [
item.toBeUndertaken,
item.undertaken,
item.notCompleted,
item.completed,
];
});
const arrList = [[], [], [], []];
for (let i = 0; i < 4; i++) {
for (let j = 0; j < 13; j++) {
arrList[i]?.push(newArr[j][i]);
}
}
listData.value = arrList.map((child, index) => {
return {
name: showText(index),
type: "bar",
emphasis: {
focus: "series",
},
data: child,
};
});
company.value = data[0]?.statisticsVo[0]?.deptName;
init();
};
const init = () => {
const myChart = proxy.echarts.init(chartRef.value);
option.value = {
color: ["#7f36fe", "#36a3f7", "#f4516c", "#34bfa3"],
title: {
text: company.value + `一年内数据统计`,
x: "center",
},
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow",
},
},
legend: {
x: "right",
data: ["未承接", "已承接", "未完成", "已完成"],
},
xAxis: [
{
type: "category",
axisTick: { show: false },
data: xList.value,
},
],
yAxis: [
{
type: "value",
},
],
series: listData.value,
};
myChart.setOption(option.value);
};
getUser();
</script>
<style lang="scss" scoped>
.select_company {
display: flex;
justify-content: space-between;
}
.card-list > * {
width: 20%;
}
.chart,
.table {
margin-top: 20px;
}
.index-page table {
width: 100% !important;
align-items: center;
gap: 20px;
font-size: 18px;
color: #666;
}
</style>
... ...
<template>
<div class="login">
<el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
<h3 class="title">若依后台管理系统</h3>
<el-form
ref="loginRef"
:model="loginForm"
:rules="loginRules"
class="login-form"
>
<h3 class="title">广西保险行业协会车险投保登记平台</h3>
<el-form-item prop="username">
<el-input
v-model="loginForm.username"
... ... @@ -10,7 +15,9 @@
auto-complete="off"
placeholder="账号"
>
<template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template>
<template #prefix
><svg-icon icon-class="user" class="el-input__icon input-icon"
/></template>
</el-input>
</el-form-item>
<el-form-item prop="password">
... ... @@ -22,7 +29,9 @@
placeholder="密码"
@keyup.enter="handleLogin"
>
<template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
<template #prefix
><svg-icon icon-class="password" class="el-input__icon input-icon"
/></template>
</el-input>
</el-form-item>
<el-form-item prop="code" v-if="captchaEnabled">
... ... @@ -34,26 +43,34 @@
style="width: 63%"
@keyup.enter="handleLogin"
>
<template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template>
<template #prefix
><svg-icon icon-class="validCode" class="el-input__icon input-icon"
/></template>
</el-input>
<div class="login-code">
<img :src="codeUrl" @click="getCode" class="login-code-img"/>
<img :src="codeUrl" @click="getCode" class="login-code-img" />
</div>
</el-form-item>
<el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox>
<el-form-item style="width:100%;">
<el-checkbox
v-model="loginForm.rememberMe"
style="margin: 0px 0px 25px 0px"
>记住密码</el-checkbox
>
<el-form-item style="width: 100%">
<el-button
:loading="loading"
size="large"
type="primary"
style="width:100%;"
style="width: 100%"
@click.prevent="handleLogin"
>
<span v-if="!loading">登 录</span>
<span v-else>登 录 中...</span>
</el-button>
<div style="float: right;" v-if="register">
<router-link class="link-type" :to="'/register'">立即注册</router-link>
<div style="float: right" v-if="register">
<router-link class="link-type" :to="'/register'"
>立即注册</router-link
>
</div>
</el-form-item>
</el-form>
... ... @@ -68,24 +85,24 @@
import { getCodeImg } from "@/api/login";
import Cookies from "js-cookie";
import { encrypt, decrypt } from "@/utils/jsencrypt";
import useUserStore from '@/store/modules/user'
import useUserStore from "@/store/modules/user";
const userStore = useUserStore()
const userStore = useUserStore();
const router = useRouter();
const { proxy } = getCurrentInstance();
const loginForm = ref({
username: "admin",
password: "admin123",
username: "",
password: "",
rememberMe: false,
code: "",
uuid: ""
uuid: "",
});
const loginRules = {
username: [{ required: true, trigger: "blur", message: "请输入您的账号" }],
password: [{ required: true, trigger: "blur", message: "请输入您的密码" }],
code: [{ required: true, trigger: "change", message: "请输入验证码" }]
code: [{ required: true, trigger: "change", message: "请输入验证码" }],
};
const codeUrl = ref("");
... ... @@ -97,13 +114,15 @@ const register = ref(false);
const redirect = ref(undefined);
function handleLogin() {
proxy.$refs.loginRef.validate(valid => {
proxy.$refs.loginRef.validate((valid) => {
if (valid) {
loading.value = true;
// 勾选了需要记住密码设置在 cookie 中设置记住用户名和密码
if (loginForm.value.rememberMe) {
Cookies.set("username", loginForm.value.username, { expires: 30 });
Cookies.set("password", encrypt(loginForm.value.password), { expires: 30 });
Cookies.set("password", encrypt(loginForm.value.password), {
expires: 30,
});
Cookies.set("rememberMe", loginForm.value.rememberMe, { expires: 30 });
} else {
// 否则移除
... ... @@ -112,22 +131,26 @@ function handleLogin() {
Cookies.remove("rememberMe");
}
// 调用action的登录方法
userStore.login(loginForm.value).then(() => {
router.push({ path: redirect.value || "/" });
}).catch(() => {
loading.value = false;
// 重新获取验证码
if (captchaEnabled.value) {
getCode();
}
});
userStore
.login(loginForm.value)
.then(() => {
router.push({ path: redirect.value || "/" });
})
.catch(() => {
loading.value = false;
// 重新获取验证码
if (captchaEnabled.value) {
getCode();
}
});
}
});
}
function getCode() {
getCodeImg().then(res => {
captchaEnabled.value = res.captchaEnabled === undefined ? true : res.captchaEnabled;
getCodeImg().then((res) => {
captchaEnabled.value =
res.captchaEnabled === undefined ? true : res.captchaEnabled;
if (captchaEnabled.value) {
codeUrl.value = "data:image/gif;base64," + res.img;
loginForm.value.uuid = res.uuid;
... ... @@ -141,8 +164,9 @@ function getCookie() {
const rememberMe = Cookies.get("rememberMe");
loginForm.value = {
username: username === undefined ? loginForm.value.username : username,
password: password === undefined ? loginForm.value.password : decrypt(password),
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
password:
password === undefined ? loginForm.value.password : decrypt(password),
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe),
};
}
... ... @@ -150,7 +174,7 @@ getCode();
getCookie();
</script>
<style lang='scss' scoped>
<style lang="scss" scoped>
.login {
display: flex;
justify-content: center;
... ...
... ... @@ -2,77 +2,37 @@
<div class="app-container">
<!-- 表格数据 -->
<el-table v-loading="loading" :data="policyList" @row-click="handleUpdate">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="序号" width="55" type="index" />
<el-table-column
label="登记时间"
prop="createTime"
width="160"
align="center"
/>
<el-table-column label="登记时间" prop="createTime" align="center" />
<el-table-column
label="车牌号"
prop="licensePlateNumber"
width="150"
align="center"
/>
<el-table-column
label="车架号"
width="180"
prop="frameNumber"
align="center"
:show-overflow-tooltip="true"
/>
<el-table-column label="车主姓名" prop="name" align="center" />
<el-table-column label="联系电话" prop="phone" align="center" />
<el-table-column label="上年承保公司" prop="sysDeptName" align="center" />
<el-table-column
label="车主姓名"
prop="name"
width="100"
align="center"
/>
<el-table-column
label="联系电话"
prop="phone"
width="180"
align="center"
/>
<el-table-column
label="上年承保公司"
prop="sysDeptName"
width="150"
align="center"
/>
<el-table-column
v-show="hasCompanyadmin"
label="分配机制"
prop="distributionMechanism"
width="150"
align="center"
/>
<el-table-column
label="订单分配时间"
prop="distributionTime"
width="150"
align="center"
/>
<el-table-column
label="保单进度"
prop="orderProgress"
width="150"
align="center"
/>
<el-table-column
label="承接时间"
prop="companyEmployeeUndertakeTime"
width="150"
label="操作"
align="center"
/>
<el-table-column
v-show="hasCompanyadmin"
label="承接人"
prop="associationEmployeeUserName"
width="150"
align="center"
/>
min-width="120"
fixed="right"
>
<template #default="{ row }">
<el-button
type="primary"
v-hasRole="['companyadmin']"
@click.stop="handleSharing(row.taskId)"
>分配</el-button
>
</template>
</el-table-column>
</el-table>
<pagination
... ... @@ -83,55 +43,28 @@
@pagination="getList"
/>
<!-- 表单作废对话框 -->
<el-dialog
v-model="deprecatedShow"
title="温馨提示:该保单作废后车牌号、车架号在本自然年度无法重新提交"
width="500"
append-to-body
>
<QuillEditor
:value="deprecatedForm.deprecatedReason"
@updateValue="getMsg"
/>
<template #footer>
<div class="dialog-footer">
<el-button @click="deprecatedShow = false">取消</el-button>
<el-button type="primary" @click="sunmitDeprecated">确定</el-button>
</div>
</template>
</el-dialog>
<!-- 分配承保公司对话框 -->
<!-- 转办分配对话框 -->
<el-dialog
v-model="companyShow"
title="分配承保公司:"
v-model="transferShow"
title="请选择人员:"
width="500"
append-to-body
>
<div class="company_box">
<div class="header_top">
<el-input
v-model="companyQueryParams.deptName"
style="width: 380px"
placeholder="请输入承保公司名称(支持模糊查询)"
prefix-icon="Search"
/>
<el-button type="primary" @click="getDeptList">查询</el-button>
</div>
<el-radio-group v-model="companyForm.deptId" @change="handleDeptChange">
<el-radio-group v-model="transferForm.username">
<el-radio
v-for="item in deptOptions"
:key="item.deptId"
:label="item.deptId"
>{{ item.deptName }}</el-radio
v-for="item in transferOptions"
:key="item.userName"
:label="item.userName"
>{{ item.userName }}</el-radio
>
</el-radio-group>
<div v-show="transferOptions.length === 0">暂无其他员工</div>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="companyShow = false">取消</el-button>
<el-button type="primary" @click="submitForm">确定</el-button>
<el-button type="primary" @click="submitTransfer">确定</el-button>
</div>
</template>
</el-dialog>
... ... @@ -141,18 +74,18 @@
<el-form :model="form" :rules="rules" ref="policyRef" label-width="100px">
<el-row>
<el-col :span="12">
<el-form-item label="车牌号" prop="carNum">
<el-form-item label="车牌号" prop="licensePlateNumber">
<el-input
v-model="form.carNum"
v-model="form.licensePlateNumber"
placeholder="请输入车牌号"
maxlength="30"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="车架号" prop="frameNum">
<el-form-item label="车架号" prop="frameNumber">
<el-input
v-model="form.frameNum"
v-model="form.frameNumber"
placeholder="请输入车架号"
maxlength="30"
/>
... ... @@ -189,9 +122,9 @@
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="上年承保公司" prop="company">
<el-form-item label="上年承保公司" prop="sysDeptName">
<el-input
v-model="form.company"
v-model="form.sysDeptName"
placeholder="请输入上年承保公司"
maxlength="50"
/>
... ... @@ -199,34 +132,21 @@
</el-col>
</el-row>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="open = false">取消</el-button>
<el-button type="primary" @click="open = false">确定</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { queryPengdingList, disposeUser } from "@/api/policy/index";
import { listDept } from "@/api/system/dept";
import { onMounted, ref } from "vue";
const { proxy } = getCurrentInstance();
import { queryPengdingList, getUserList } from "@/api/policy/index";
const loading = ref(false);
const { proxy } = getCurrentInstance();
const total = ref(0);
const title = ref("保单信息");
const open = ref(false);
const timerReason = ref(null);
const transferShow = ref(false);
const form = ref({});
const hasRole = computed(() => {
return proxy.$auth.hasRole("associationemployee");
});
const hasCompanyadmin = computed(() => {
return proxy.$auth.hasRole("companyadmin");
});
const transferForm = ref({});
const transferOptions = ref([]);
const rules = ref({
carNum: [{ required: true, message: "车牌号不能为空", trigger: "blur" }],
frameNum: [{ required: true, message: "车架号不能为空", trigger: "blur" }],
... ... @@ -241,21 +161,18 @@ const rules = ref({
],
});
const companyShow = ref(false);
const deptOptions = ref([]);
const company = ref(2);
const deprecatedShow = ref(false);
const deprecatedForm = ref({});
const companyForm = ref({});
const queryParams = reactive({
pageNum: 1,
pageSize: 10,
});
const companyQueryParams = reactive({
deptName: undefined,
status: undefined,
});
const policyList = ref([]);
/** 重置操作表单 */
function reset() {
proxy.resetForm("policyRef");
}
// 获取处理的列表
const getList = async () => {
loading.value = true;
const { rows, total: all } = await queryPengdingList(queryParams);
... ... @@ -263,117 +180,38 @@ const getList = async () => {
total.value = all;
loading.value = false;
};
// 通过保单
const handleSuccess = (associationapprove, taskId) => {
ElMessageBox.confirm("是否通过该保单?", {
confirmButtonText: "确认通过",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
disposeUser({ associationapprove }, taskId).then((res) => {
proxy.$modal.msgSuccess("保单已通过");
});
})
.catch(() => {
proxy.$modal.msg("取消通过");
});
};
// 退回保单
const handleFallback = (associationapprove, taskId) => {
ElMessageBox.confirm("是否退回该保单?", {
confirmButtonText: "确认退回",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
disposeUser({ associationapprove }, taskId).then((res) => {
proxy.$modal.msgSuccess("保单已退回");
});
})
.catch(() => {
proxy.$modal.msg("已取消");
});
};
// 作废保单
const handleVoid = (associationapprove, taskId) => {
deprecatedForm.value = {
associationapprove,
taskId,
};
deprecatedShow.value = true;
};
// 提交作废表单
const sunmitDeprecated = () => {
const data = {
associationapprove: deprecatedForm.value.associationapprove,
comment: deprecatedForm.value.deprecatedReason,
};
const taskId = deprecatedForm.value.taskId;
disposeUser(data, taskId).then((res) => {
proxy.$modal.msgSuccess("保单已退回");
});
};
// 分配承保公司
const handleAuthCompany = (associationapprove, taskId) => {
companyForm.value = {
associationapprove,
taskId,
};
companyShow.value = true;
getDeptList();
// 转办或分配
const handleSharing = (id) => {
transferForm.value.taskId = id;
getUser();
transferShow.value = true;
};
/** 查询部门列表 */
const getDeptList = () => {
loading.value = true;
listDept(companyQueryParams).then((response) => {
deptOptions.value = response.data.filter((item) => item.parentId === 100);
loading.value = false;
});
// 获取人员列表
const getUser = async () => {
const { data } = await getUserList();
transferOptions.value = data;
};
/** 重置操作表单 */
function reset() {
form.value = {
policyId: undefined,
createTime: undefined,
carNum: undefined,
frameNum: undefined,
name: undefined,
phone: undefined,
company: undefined,
};
proxy.resetForm("policyRef");
}
/** 修改按钮操作 */
function handleUpdate(row) {
reset();
form.value = row;
open.value = true;
}
/** 提交通过分配承保公司 */
function submitForm() {
/** 提交通过分配转办人员 */
function submitTransfer() {
const data = {
associationapprove: companyForm.value.associationapprove,
deptId: companyForm.value.deptId.toString(),
username: transferForm.value.username,
};
const taskId = companyForm.value.taskId;
disposeUser(data, taskId).then((res) => {
companyShow.value = true;
const taskId = transferForm.value.taskId;
transfer(data, taskId).then((res) => {
transferShow.value = false;
getList();
proxy.$modal.msgSuccess("保单已分配成功");
});
}
const getMsg = (val) => {
clearTimeout(timerReason.value);
timerReason.value = setTimeout(() => {
deprecatedForm.value.deprecatedReaso = val;
}, 1000);
const handleUpdate = (row) => {
reset();
form.value = row;
// isCustom.value = data.isCustomizeBrandAndModel == "0";
open.value = true;
};
getList();
</script>
... ...
... ... @@ -98,27 +98,53 @@
<el-table-column label="序号" type="index" width="55" />
<el-table-column
label="登记时间"
prop="initialRegistrationTime"
prop="createTime"
width="160"
align="center"
/>
<el-table-column
label="车牌号"
prop="licensePlateNumber"
width="150"
align="center"
/>
<el-table-column
label="车架号"
prop="frameNumber"
width="240"
align="center"
/>
<el-table-column
label="车主姓名"
prop="name"
width="100"
align="center"
/>
<el-table-column
label="联系电话"
prop="phone"
width="180"
align="center"
/>
<el-table-column label="车牌号" prop="licensePlateNumber" width="150" />
<el-table-column label="车架号" prop="frameNumber" width="240" />
<el-table-column label="车主姓名" prop="name" width="100" />
<el-table-column label="联系电话" prop="phone" width="180" />
<el-table-column
label="分配机制"
width="120"
prop="distributionMechanism"
/>
<el-table-column label="承保公司" prop="companyName" width="150" />
<el-table-column label="操作人员" width="150">
<el-table-column
label="承保公司"
prop="companyName"
width="180"
align="center"
/>
<el-table-column label="操作人员" width="150" align="center">
<template #default="{ row }">
<span>{{
row.associationEmployeeUserName || row.companyEmployeeUserName
}}</span>
</template>
</el-table-column>
<el-table-column label="操作时间" width="170">
<el-table-column label="操作时间" width="160" align="center">
<template #default="{ row }">
<span>{{
row.companyEmployeeUndertakeTime || row.distributionTime
... ... @@ -128,11 +154,16 @@
<el-table-column
label="办理人"
prop="handler"
prop="companyEmployeeUserName"
width="100"
align="center"
/>
<el-table-column label="保单进度" width="100" prop="orderProgress" />
<el-table-column
label="保单进度"
width="100"
prop="orderProgress"
align="center"
/>
</el-table>
<pagination
... ... @@ -168,6 +199,22 @@
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="发动机号" prop="engineNumber">
<el-input v-model="form.engineNumber" placeholder="无" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="排放毫升量" prop="emissions">
<el-input
v-model="form.emissions"
disabled
placeholder="请输入车架号"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="车主姓名" prop="name">
<el-input
v-model="form.name"
... ... @@ -188,9 +235,9 @@
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="登记时间" prop="initialRegistrationTime">
<el-form-item label="登记时间" prop="createTime">
<el-input
v-model="form.initialRegistrationTime"
v-model="form.createTime"
disabled
placeholder="请输入登记时间"
/>
... ... @@ -208,25 +255,17 @@
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="操作时间" prop="authTime">
<el-form-item label="核定载质量" prop="passengerCapacity">
<el-input
v-model="form.authTime"
v-model="form.passengerCapacity"
disabled
:placeholder="
form.companyEmployeeUndertakeTime || form.distributionTime
"
placeholder="无"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="操作人员" prop="editAuth">
<el-input
disabled
:placeholder="
form.associationEmployeeUserName ||
form.companyEmployeeUserName
"
/>
<el-form-item label="核定载人数" prop="passengersNumber">
<el-input v-model="form.passengersNumber" disabled />
</el-form-item>
</el-col>
</el-row>
... ... @@ -236,27 +275,65 @@
<el-input
v-model="form.distributionMechanism"
disabled
placeholder="请输入登记时间"
placeholder=""
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="承保公司" prop="companyName">
<el-input v-model="form.companyName" disabled placeholder="无" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="车辆品牌" prop="vehicleBrand">
<el-input
v-model="form.companyName"
v-model="form.vehicleBrand"
disabled
placeholder="请输入承保公司"
placeholder="车辆品牌"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="车辆型号" prop="vehicleModel">
<el-input v-model="form.vehicleModel" disabled placeholder="无" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="保险需求" prop="requirements">
<el-input v-model="form.requirements" disabled placeholder="无" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="号牌种类" prop="lincensePlateType">
<el-input
v-model="form.lincensePlateType"
disabled
placeholder="无"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="使用性质" prop="vehicleNature">
<el-input
v-model="form.vehicleNature"
disabled
placeholder="无"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="车辆类型" prop="vehicleType">
<el-input v-model="form.vehicleType" disabled placeholder="无" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="open = false">取消</el-button>
<el-button type="primary" @click="open = false">确定</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
... ...
... ... @@ -150,6 +150,7 @@
</el-table-column>
</el-table>
<!-- 页码 -->
<pagination
v-show="total > 0"
:total="total"
... ... @@ -227,6 +228,7 @@
>{{ item.userName }}</el-radio
>
</el-radio-group>
<div v-show="transferOptions.length === 0">暂无其他员工</div>
</div>
<template #footer>
<div class="dialog-footer">
... ... @@ -244,7 +246,14 @@
append-to-body
>
<el-form :model="FeedbackForm" ref="policyRef" label-width="100px">
<el-form-item label="保单回馈" prop="progress">
<el-form-item label="商险单号" prop="progress">
<el-input
v-model="FeedbackForm.shoppolicynumber"
placeholder="请输入保单号"
:disabled="hasRole"
/>
</el-form-item>
<el-form-item label="交强险单号" prop="progress">
<el-input
v-model="FeedbackForm.policynumber"
placeholder="请输入保单号"
... ... @@ -488,7 +497,11 @@ const form = ref({});
const showFeedback = ref(false);
const transferShow = ref(false);
const transferForm = ref({});
const FeedbackForm = ref({});
const FeedbackForm = ref({
shoppolicynumber: "",
policynumber: "",
message: "",
});
const getParams = reactive({
pageNum: 1,
pageSize: 100,
... ...