Browse Source

1. 操作手册 2. BUG修复

master
wxc 2 years ago
parent
commit
b713aab4db
  1. BIN
      public/imgs/support.png
  2. 1
      src/assets/icons/rotate-left.svg
  3. 1
      src/assets/icons/rotate-right.svg
  4. 89
      src/components/FileList.vue
  5. 3
      src/components/LeaderSelect.vue
  6. 6
      src/components/Message.vue
  7. 28
      src/components/PoliceSelect.vue
  8. 37
      src/layout/components/Header.vue
  9. 6
      src/layout/components/NoticeMessage.vue
  10. 22
      src/style/public.scss
  11. 2
      src/utils/request.ts
  12. 5
      src/views/error/404.vue
  13. 6
      src/views/home/components/DataStatistics.vue
  14. 15
      src/views/setting/OperatingManual.vue
  15. 63
      src/views/work/components/MailReturnDetail.vue
  16. 6
      src/views/work/components/templates/ThreeHandling.vue

BIN
public/imgs/support.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

1
src/assets/icons/rotate-left.svg

@ -0,0 +1 @@
<?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="1710476192729" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1635" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M541.226667 66.517333L393.045333 217.685333a21.333333 21.333333 0 0 0 0 29.866667l147.84 150.826667a21.333333 21.333333 0 0 0 28.16 2.090666l2.346667-2.090666 27.050667-27.605334a21.333333 21.333333 0 0 0 0-29.866666l-69.888-71.338667a304.64 304.64 0 1 1-318.421334 352.682667l-1.024-6.826667a176.554667 176.554667 0 0 1-0.64-5.632 21.333333 21.333333 0 0 0-22.314666-19.114667l-42.666667 2.261334a21.333333 21.333333 0 0 0-20.224 22.4l0.085333 1.024 1.194667 10.496A389.973333 389.973333 0 1 0 539.178667 184.746667l59.306666-60.458667a21.333333 21.333333 0 0 0 0-29.866667l-27.093333-27.605333a21.333333 21.333333 0 0 0-30.165333-0.298667z" p-id="1636"></path></svg>

After

Width:  |  Height:  |  Size: 976 B

1
src/assets/icons/rotate-right.svg

@ -0,0 +1 @@
<?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="1710476185031" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1494" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M482.773333 66.517333l148.181334 151.168a21.333333 21.333333 0 0 1 0 29.866667l-147.84 150.826667a21.333333 21.333333 0 0 1-28.16 2.090666l-2.346667-2.090666-27.050667-27.605334a21.333333 21.333333 0 0 1 0-29.866666l69.888-71.338667a304.64 304.64 0 1 0 318.421334 352.682667l1.024-6.826667c0.170667-1.408 0.426667-3.285333 0.64-5.632a21.333333 21.333333 0 0 1 22.314666-19.114667l42.666667 2.261334a21.333333 21.333333 0 0 1 20.224 22.4l-0.085333 1.024-1.194667 10.496A389.973333 389.973333 0 1 1 484.821333 184.746667l-59.306666-60.458667a21.333333 21.333333 0 0 1 0-29.866667l27.093333-27.605333a21.333333 21.333333 0 0 1 30.165333-0.298667z" p-id="1495"></path></svg>

After

Width:  |  Height:  |  Size: 978 B

89
src/components/FileList.vue

@ -39,23 +39,22 @@
</div>
</div>
</div>
<div class="file-preview-wrapper flex" v-if="preview">
<div class="file-list">
<section
v-for="(item, index) in fileList"
:key="index"
class="flex gap v-center pointer"
:active="fileList.indexOf(activeFile) === index"
@click="filePreview(item)"
>
<icon :name="getIconName(item.type)" :size="24" />
<span>{{ item.orgiinFilename }}</span>
</section>
</div>
<div
class="file-content flex center v-center"
@click="preview = false"
>
<div class="file-preview-wrapper flex overlay" v-if="preview">
<el-scrollbar height="100vh">
<div class="file-list">
<section
v-for="(item, index) in fileList"
:key="index"
class="flex gap v-center pointer"
:active="fileList.indexOf(activeFile) === index"
@click="filePreview(item)"
>
<icon :name="getIconName(item.type)" :size="24" />
<span>{{ item.orgiinFilename }}</span>
</section>
</div>
</el-scrollbar>
<div class="file-content flex center v-center" @click="preview = false" @wheel="wheel">
<div
class="img-container flex center"
v-if="activeFile.type.indexOf('image') > -1"
@ -64,18 +63,23 @@
:src="`${VITE_API_URL}/api/file/stream/${activeFile.filepath}`"
ref="imgRef"
@click.stop
:style="{transform: `rotate(${rotate}deg) scale(${scale})`}"
/>
<button
class="rotate-left-btn pointer"
@click.stop="rotateLeft"
size="small"
title="左旋转"
>
<icon name="el-icon-Back" :size="28" />
<icon name="local-icon-rotate-left" :size="28" />
</button>
<button
class="rotate-right-btn pointer"
@click.stop="rotateRight"
size="small"
title="右旋转"
>
<icon name="el-icon-Right" :size="28" />
<icon name="local-icon-rotate-right" :size="28" />
</button>
</div>
<template v-else-if="activeFile.type.indexOf('audio') > -1">
@ -165,6 +169,7 @@ import "@vue-office/excel/lib/index.css";
import VueOfficeDocx from "@vue-office/docx";
import VueOfficeExcel from "@vue-office/excel";
import { nextTick, onMounted } from "vue";
const { VITE_API_URL } = process.env;
const router = useRouter();
@ -193,39 +198,51 @@ watch(
const preview = ref(false);
const activeFile = ref({});
const fileRrror = ref(false);
const imgRef = ref();
let rotate = 0;
const rotate = ref(0);
const scale = ref(0);
function prev() {
const index = fileList.value.indexOf(activeFile.value);
if (index === 0) {
filePreview(fileList.value[fileList.value.length - 1])
filePreview(fileList.value[fileList.value.length - 1]);
} else {
filePreview(fileList.value[index - 1])
filePreview(fileList.value[index - 1]);
}
}
function next() {
const index = fileList.value.indexOf(activeFile.value);
if (index === fileList.value.length - 1) {
filePreview(fileList.value[0])
filePreview(fileList.value[0]);
} else {
filePreview(fileList.value[index + 1])
filePreview(fileList.value[index + 1]);
}
}
function filePreview(file) {
preview.value = true;
fileRrror.value = false;
activeFile.value = file;
rotate = 0
imgRef.value.style.transform = `rotate(0deg)`;
rotate.value = 0;
scale.value = 1;
}
function wheel(event) {
if (activeFile.value.type.indexOf('image') === -1) {
return
}
if (event.deltaY > 0) {
scale.value += 0.08;
}
if (event.deltaY < 0 && scale.value > 0.2) {
scale.value -= 0.08;
}
}
function rotateLeft() {
imgRef.value.style.transform = `rotate(${(rotate += 90)}deg)`;
rotate.value += 90
console.log(rotate.value)
}
function rotateRight() {
imgRef.value.style.transform = `rotate(${(rotate -= 90)}deg)`;
rotate.value -= 90
}
function getIconName(filetype) {
@ -323,18 +340,12 @@ function getDocFilepath() {
}
}
.file-preview-wrapper {
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.7);
z-index: 999;
.file-list {
width: 14vw;
width: 15vw;
height: 100vh;
padding: 16px 8px;
background-color: #fff;
box-sizing: border-box;
section {
padding: 8px 16px;
border: 2px solid transparent;
@ -385,7 +396,7 @@ function getDocFilepath() {
.rotate-left-btn {
position: absolute;
top: 12px;
right: 108px;
right: 118px;
background-color: transparent;
border: none;
color: #fff;

3
src/components/LeaderSelect.vue

@ -12,7 +12,6 @@
<script setup>
import { getLeaderList } from "@/api/perms/admin";
const selectVal = ref("");
const props = defineProps({
modelValue: {
type: String,
@ -23,6 +22,8 @@ const props = defineProps({
default: 'all',
},
});
const selectVal = ref(props.modelValue);
const emit = defineEmits(["update:modelValue", "change"]);
function handleSelect(val) {

6
src/components/Message.vue

@ -1,6 +1,6 @@
<template>
<div class="message-wrapper" v-if="show" @click="show = false">
<div class="message flex v-center gap">
<div class="message flex v-center gap position-center">
<icon name="el-icon-SuccessFilled" :size="32" />
<span>{{ message }}</span>
</div>
@ -32,10 +32,6 @@ defineExpose({
z-index: 9999;
background-color: rgba(0, 0, 0, 0.17);
.message {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #fff;
box-shadow: 0px 4px 12px 0px rgba(0, 0, 0, 0.15);
border-radius: 4px;

28
src/components/PoliceSelect.vue

@ -1,12 +1,10 @@
<template>
<el-select remote
<el-select
v-model="value"
filterable
:remote-method="remoteMethod"
placeholder="请输入姓名搜索"
placeholder="请选择"
:loading="loading"
remote-show-suffix
@change="handleChange" clearable>
@change="handleChange">
<el-option
v-for="item in options"
:key="item.id"
@ -19,7 +17,6 @@
import { listByCurrentDept } from '@/api/perms/admin'
const loading = ref(false)
const value = ref('')
const options = ref([])
const props = defineProps({
data: {
@ -27,17 +24,18 @@ const props = defineProps({
default: null
}
})
console.log('props', props.data)
const value = ref(props.data ? props.data.empNo : '')
watch(() => props.data, () => {
console.log('watch', props.data)
})
const emit = defineEmits(['update:data', 'select'])
function remoteMethod(query) {
const chinesePattern = /[\u4e00-\u9fa5]/;
if (!query || !chinesePattern.test(query)) {
return
}
loading.value = true
listByCurrentDept({
name: query
}).then(data => {
getList();
function getList() {
listByCurrentDept().then(data => {
loading.value = false
options.value = data
})

37
src/layout/components/Header.vue

@ -13,6 +13,10 @@
</section>
</header>
<ul class="userinfo-dropdown" v-if="dropdownShow">
<li class="flex gap v-center" @click="supportShow = true">
<icon name="el-icon-Star" :size="22" />
<span>服务支持</span>
</li>
<li class="flex gap v-center" @click="handleEdit">
<icon name="el-icon-Lock" :size="22" />
<span>修改密码</span>
@ -23,6 +27,18 @@
</li>
</ul>
<edit-popup v-if="showEdit" ref="editRef" @success="getLists" @close="showEdit = false" />
<div class="overlay" v-if="supportShow" @click="supportShow = false">
<div class="position-center support-box">
<div>
<img src="/imgs/support.png" alt="" />
</div>
<div class="support-content" @click.stop>
<p>业务服务热线0731 - 82587735周警官 </p>
<p>技术服务热线13787166867李经理 18867391894 杨姣</p>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import NoticeMessage from "./NoticeMessage.vue";
@ -33,6 +49,7 @@ const userStore = useUserStore();
const dropdownShow = ref(false)
const editRef = shallowRef<InstanceType<typeof EditPopup>>();
const showEdit = ref(false);
const supportShow = ref(false)
const handleEdit = async () => {
showEdit.value = true
@ -80,12 +97,13 @@ header {
box-shadow: 0px 9px 28px 8px rgba(0,0,0,0.05), 0px 6px 16px 0px rgba(0,0,0,0.08), 0px 3px 6px -4px rgba(0,0,0,0.12);
border-radius: 8px;
margin: 0;
padding: 12px 0;
padding: 8px 0;
z-index: 999;
overflow: hidden;
li {
padding: 12px 16px;
padding: 8px 16px;
font-size: 16px;
width: 120px;
&:hover {
cursor: pointer;
font-weight: 700;
@ -93,4 +111,19 @@ header {
}
}
}
.support-box {
img {
width: 500px;
height: 160px;
}
.support-content {
padding: 20px 16px;
background-color: #fff;
font-size: 14px;
font-weight: 700;
color: #333;
}
}
</style>

6
src/layout/components/NoticeMessage.vue

@ -1,8 +1,9 @@
<template>
<div class="notice flex gap v-center">
<el-badge :value="total">
<el-badge :value="total" v-if="total">
<icon name="el-icon-BellFilled" :size="32" />
</el-badge>
<icon name="el-icon-BellFilled" :size="32" v-else />
<div class="ml-20">{{ notice.content }}</div>
<audio src="/mp3/todo.mp3" ref="todoAudioRef" ></audio>
@ -40,7 +41,6 @@ const notice = ref({});
function getNoticeTotal() {
noticeTotal().then((data) => {
total.value = data.total;
if (data.notice) {
notice.value = data.notice;
} else {
@ -62,7 +62,7 @@ watch(newMailAudio, (val) => {
}).catch(() => {
console.log("播放失败")
ElMessageBox.confirm('需要获取浏览器的声音播放权限!', '温馨提示', {
confirmButtonText: '确',
confirmButtonText: '确认授权',
showCancelButton: false,
type: 'warning',
showClose: false,

22
src/style/public.scss

@ -78,6 +78,7 @@ svg+span {
.flex.gap-10 {
gap: 10px;
}
.flex.gap-12 {
gap: 12px;
}
@ -288,7 +289,7 @@ svg+span {
color: #888;
}
> span {
>span {
color: #222;
}
}
@ -298,11 +299,28 @@ svg+span {
text-decoration: none;
display: inline;
padding: 12px;
&:hover {
font-weight: 700;
font-weight: 700;
}
}
.table-container {
border: 1px solid rgba(198, 208, 251, 1);
}
.overlay {
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.7);
z-index: 999;
}
.position-center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}

2
src/utils/request.ts

@ -92,7 +92,7 @@ function ajax(url: string, options: Options) {
ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '温馨提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => {
isRelogin = false;
// 调整登录
location.href = process.env.VITE_BASE + "login";
location.href = process.env.VITE_BASE + "#/login";
}).catch(() => {
isRelogin = false;
});

5
src/views/error/404.vue

@ -1,5 +1,5 @@
<template>
<div class="text-center">
<div class="text-center position-center">
<img src="/imgs/404.png" alt="">
<a href="/">返回首页</a>
</div>
@ -10,9 +10,6 @@
<style lang="scss" scoped>
div {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding-bottom: 20vh;
img {
display: block;

6
src/views/home/components/DataStatistics.vue

@ -12,7 +12,7 @@
>
<label>{{ item.name }}</label>
<div class="bar-box">
<div :style="{ width: item.rate }" class="bar">
<div :style="{ width: item.rate, background: getColor(item.ratenumber) }" class="bar">
<span>{{ item.rate }}</span>
</div>
</div>
@ -29,7 +29,7 @@
>
<label>{{ item.name }}</label>
<div class="bar-box">
<div :style="{ width: item.rate }" class="bar">
<div :style="{ width: item.rate, background: getColor(item.ratenumber) }" class="bar">
<span>{{ item.rate }}</span>
</div>
</div>
@ -49,7 +49,7 @@
<div
:style="{
width: item.rate,
background: getColor(item.ratenumber),
background: getColor(item.ratenumber)
}"
class="bar"
>

15
src/views/setting/OperatingManual.vue

@ -0,0 +1,15 @@
<template>
<iframe :src="`${VITE_API_URL}/api/file/pdf/template/长沙市公安局局长信箱即接即办系统平台-操作手册V1.3.pdf`"></iframe>
</template>
<script setup>
const { VITE_API_URL } = process.env;
</script>
<style lang="scss" scoped>
iframe {
display: block;
width: 100%;
height: 100%;
border: none;
}
</style>

63
src/views/work/components/MailReturnDetail.vue

@ -1,23 +1,37 @@
<template>
<div v-if="mailReturns.length" class="box">
<div class="flex mb-10">
<div class="danger flex v-center">
<icon name="el-icon-Warning" :size="20" />
<span class="ml-4">信件已退回</span>
<div class="relative mb-20" v-if="mailReturns.length">
<div class="box" v-for="item in expand ? mailReturns : mailReturns.slice(0, 1)" :key="item.id">
<div class="flex mb-10">
<div class="danger flex v-center">
<icon name="el-icon-Warning" :size="20" />
<span class="ml-4">信件已退回</span>
</div>
<div class="col">
<label class="ml-20">退回单位</label>
<span>{{ item.handlerDeptName }}</span>
</div>
</div>
<div class="col">
<label class="ml-20">退回单位</label>
<span>{{ mailReturns[0].handlerDeptName }}</span>
<label class="mt-8">退回理由</label>
<div class="content">{{ item.reason }}</div>
</div>
<div
class="col mt-16"
v-if="JSON.parse(item.attachments)?.length"
>
<label class="mt-8">附件</label>
<FileList :files="JSON.parse(item.attachments)" />
</div>
</div>
<div class="col">
<label class="mt-8">退回理由</label>
<div class="content">{{ mailReturns[0].reason }}</div>
</div>
<div class="col mt-16" v-if="JSON.parse(mailReturns[0].attachments)">
<label class="mt-8">附件</label>
<FileList :files="JSON.parse(mailReturns[0].attachments)" />
</div>
<el-button
type="primary"
plain
size="small"
class="more-btn"
v-if="mailReturns.length > 1"
@click="expand = !expand"
>{{ expand ? '收起' : '查看更多...' }}</el-button
>
</div>
</template>
<script setup>
@ -27,13 +41,7 @@ const props = defineProps({
default: () => [],
},
});
watch(
() => props.mailReturns,
() => {
console.log("watch", props.mailReturns);
}
);
const expand = ref(false);
</script>
<style lang="scss" scoped>
.col label {
@ -42,17 +50,20 @@ watch(
.box {
border: 1px solid #ffe3e3;
padding: 16px;
margin-bottom: 20px;
margin-bottom: 12px;
.danger {
color: #ff1414;
font-weight: bold;
}
.content {
background-color: #FEEDED;
background-color: #feeded;
width: calc(100% - 100px);
}
}
.col {
width: auto;
.more-btn {
position: absolute;
bottom: -12px;
right: 8px;
}
</style>

6
src/views/work/components/templates/ThreeHandling.vue

@ -683,7 +683,11 @@ const form = ref({});
initForm();
function initForm() {
form.value = {
contactPolice: props.mail.contactPolice,
contactPolice: {
empNo: props.mail.contactPoliceEmpNo,
name: props.mail.contactPoliceName,
post: props.mail.contactPolicePost
},
contactFlag: props.mail.contactFlag,
contactTime: props.mail.contactTime,
contactDuration: props.mail.contactDuration,

Loading…
Cancel
Save