21819 2 years ago
parent
commit
5df90cdaa9
  1. 1
      .gitignore
  2. BIN
      public/imgs/login_logo.png
  3. 5
      src/api/perms/admin.ts
  4. 18
      src/components/MailCategorySelect.vue
  5. 117
      src/layout/components/Header.vue
  6. 155
      src/layout/components/edit.vue
  7. 3
      src/views/permission/admin/edit.vue
  8. 3
      src/views/permission/admin/index.vue
  9. 16
      src/views/work/components/AddMail.vue
  10. 2
      src/views/work/components/ConfirmedCompletion.vue
  11. 37
      src/views/work/components/templates/MailTypeForm.vue

1
.gitignore vendored

@ -12,5 +12,6 @@ dist
*.map
*.rar
*.zip
*.d.ts

BIN
public/imgs/login_logo.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 47 KiB

5
src/api/perms/admin.ts

@ -44,4 +44,9 @@ export function getLeaderList(type) {
export function listByCurrentDept(query) {
return request.get({ url: '/system/admin/listByCurrentDept', query})
}
// 重置密码
export function resetPassword(params: any) {
return request.post({ url: '/system/resetPassword', params })
}

18
src/components/MailCategorySelect.vue

@ -1,9 +1,8 @@
<template>
<el-tree-select
v-model="val"
node-key="label"
:data="mailStore.mailCategorys"
filterable
@current-change="handleCategoryChange"
placeholder="请选择信件分类"
/>
</template>
@ -13,21 +12,6 @@ const mailStore = useMailStore();
//
mailStore.getMailCategorys();
const val = ref('');
const props = defineProps({
value: {
type: String,
default: ''
}
})
const emit = defineEmits(['update:value', 'change'])
const handleCategoryChange = (data, node) => {
emit('update:value', data.label)
emit('change', data, node)
}
</script>
<style lang="scss" scoped>
</style>

117
src/layout/components/Header.vue

@ -4,37 +4,46 @@
<a href="/">
<img src="/logo.png" alt="" />
</a>
<span>长沙公安局长信箱即接即办系统</span>
<span>长沙公安局长信箱即接即办系统</span>
</div>
<NoticeMessage />
<section class="flex gap userinfo v-center pointer" @click.stop="dropdownShow = true">
<icon name="el-icon-UserFilled" :size="29" color="#586EFF" />
<span>{{ userStore.userInfo.fullName }}</span>
</section>
<div class="flex v-center gap-16">
<section class="flex gap" :title="userStore.userInfo.roleName">
<icon name="el-icon-UserFilled" :size="29" color="#586EFF" />
<span>{{
userStore.userInfo.deptName + " " + userStore.userInfo.name
}}</span>
<div class="dropdown-content">
<div><img src="/imgs/lock.png" style="width: 1.2vw;">&nbsp;&nbsp;&nbsp;<a @click="handleEdit">重置密码</a></div>
<div><img src="/imgs/goout.png" style="width: 1.2vw;">&nbsp;&nbsp;&nbsp;<a @click="logout">退出登录</a></div>
</div>
</section>
<el-button type="primary" @click="logout" style=""
>退出
<template #icon
><icon name="local-icon-logout" color="#586EFF"
/></template>
</el-button>
</div>
<edit-popup v-if="showEdit" ref="editRef" @success="getLists" @close="showEdit = false" />
</header>
<ul class="userinfo-dropdown" v-if="dropdownShow">
<li class="flex gap v-center" >
<icon name="el-icon-Lock" :size="22" />
<span>修改密码</span>
</li>
<li class="flex gap v-center" @click="handleLogout">
<icon name="local-icon-logout" :size="22" />
<span>退出登录</span>
</li>
</ul>
</template>
<script setup>
<script lang="ts" setup>
import NoticeMessage from "./NoticeMessage.vue";
import useUserStore from "@/stores/modules/user";
import NoticeMessageVue from "./NoticeMessage.vue";
import EditPopup from './edit.vue'
const userStore = useUserStore();
const dropdownShow = ref(false)
document.addEventListener("click", () => {
dropdownShow.value = false;
})
function handleLogout() {
const editRef = shallowRef<InstanceType<typeof EditPopup>>();
const showEdit = ref(false)
const handleEdit = async () => {
showEdit.value = true
await nextTick()
editRef.value?.open('edit')
}
function logout() {
userStore.logout();
}
</script>
@ -49,6 +58,7 @@ header {
font-size: 3.89vh;
font-weight: 700;
letter-spacing: 4px;
a {
text-decoration: none;
color: inherit;
@ -58,28 +68,49 @@ header {
}
}
}
.userinfo {
margin-right: 8px;
}
.gap{
position: relative;/* 设置相对定位 */
display: inline-block;/* 让元素具有块级元素和行内元素的特性,即将块级元素转化为内联元素 */
.dropdown-content {
border-radius: 20px 20px 20px 20px;
display: none;
position: absolute;
background-color: #f9f9f9;
z-index: 100;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
padding: 12px 16px;
a{
display: inline-block;
z-index: 289;
color: black;
font-size: 2.4vh;
cursor:pointer;
}
}
}
.gap:hover .dropdown-content {
display: block;
}
.nav2 a {
color: black;
padding: 12px 16px;
display: block;/* 将a标签设置为块级标签 */
}
.gap:hover .nav2 {
display: block;
}
.userinfo-dropdown {
position: fixed;
right: 16px;
top: calc(var(--header-height) - 8px);
background: #FFFFFF;
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;
z-index: 999;
overflow: hidden;
li {
padding: 12px 16px;
font-size: 16px;
.el-button {
--el-font-size-base: 18px;
--el-button-bg-color: #283aac;
--el-button-border-color: #586eff;
height: 36px;
&:hover {
cursor: pointer;
font-weight: 700;
color: var(--primary-color);
--el-button-hover-bg-color: var(--el-button-bg-color);
--el-button-hover-border-color: #fff;
}
}
}

155
src/layout/components/edit.vue

@ -0,0 +1,155 @@
<template>
<div class="edit-popup">
<popup
ref="popupRef"
:title="popupTitle"
:async="true"
width="550px"
@confirm="handleSubmit"
@close="handleClose"
>
<el-form ref="formRef" :model="formData" label-width="84px" :rules="formRules">
<el-form-item label="旧密码" prop="oldpassword">
<el-input
v-model.trim="formData.oldpassword"
show-password
clearable
placeholder="请输入旧密码"
/>
</el-form-item>
<el-form-item label="新密码" prop="password">
<el-input
v-model.trim="formData.password"
show-password
clearable
placeholder="请输入密码"
/>
</el-form-item>
<el-form-item label="确认密码" prop="passwordConfirm">
<el-input
v-model.trim="formData.passwordConfirm"
show-password
clearable
placeholder="请输入确认密码"
/>
</el-form-item>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup>
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { adminAdd, adminEdit, adminDetail, resetPassword } from '@/api/perms/admin'
import { useDictOptions } from '@/hooks/useDictOptions'
import { roleAll } from '@/api/perms/role'
import { postAll } from '@/api/org/post'
import { deptLists } from '@/api/org/department'
import feedback from '@/utils/feedback'
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
const popupTitle = computed(() => {
return '修改密码'
})
const formData = reactive({
oldpassword: '',
password: '',
passwordConfirm: '',
})
const popupTrue = computed(() => {
return mode.value == 'edit' ? true: false
})
const password = (rule: object, value: string, callback: any) => {
if (formData.oldpassword) {
if (value == formData.oldpassword) callback(new Error('旧密码和原密码相同!'))
}
callback()
}
const passwordConfirmValidator = (rule: object, value: string, callback: any) => {
if (formData.password) {
if (!value) callback(new Error('请再次输入密码'))
if (value !== formData.password) callback(new Error('两次输入密码不一致!'))
}
callback()
}
const formRules = reactive({
oldpassword: [
{
required: true,
message: '请输入旧密码',
trigger: 'blur'
}
] as any[],
password: [
{
required: true,
message: '请输入密码',
trigger: 'blur'
},
{
validator: password,
trigger: 'blur'
}
] as any[],
passwordConfirm: [
{
required: true,
message: '请再次输入密码',
trigger: 'blur'
},
{
validator: passwordConfirmValidator,
trigger: 'blur'
}
] as any[]
})
const handleSubmit = async () => {
await formRef.value?.validate()
await resetPassword(formData)
popupRef.value?.close()
feedback.msgSuccess('操作成功')
emit('success')
}
const open = (type = 'add') => {
mode.value = type
popupRef.value?.open()
}
const setFormData = async (row: any) => {
formRules.password = [
{
validator: password,
trigger: 'blur'
}
]
formRules.passwordConfirm = [
{
validator: passwordConfirmValidator,
trigger: 'blur'
}
]
}
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData
})
</script>

3
src/views/permission/admin/edit.vue

@ -49,12 +49,13 @@
:data="optionsData.dept"
:default-expanded-keys="getExpandedKeys()"
clearable
check-strictly
node-key="id"
:props="{
value: 'id',
label: 'name'
}"
placeholder="请选择上级部门"
placeholder="请选择归属部门"
filterable
/>
</el-form-item>

3
src/views/permission/admin/index.vue

@ -28,7 +28,7 @@
</el-form-item>
<el-form-item label="角色">
<el-select v-model="formData.role" style="width: 180px">
<el-select v-model="formData.role" clearable style="width: 180px">
<el-option label="全部" value="" />
<el-option
v-for="(item, index) in optionsData.role"
@ -47,6 +47,7 @@
clearable
node-key="id"
filterable
check-strictly
:props="{
value: 'id',
label: 'name'

16
src/views/work/components/AddMail.vue

@ -226,21 +226,11 @@ const form = ref({
content: "",
fileList: [],
});
const validateName = (rule: any, value: string, callback: any) => {
if (!value) {
callback(new Error("请输入姓名"));
} else if (value.length < 2) {
callback(new Error("姓名长度不能少于2位"));
} else if (!/^[a-zA-Z\u4e00-\u9fa5]+$/.test(value)) {
callback(new Error("请输入中文姓名"));
} else {
callback();
}
};
const rules = reactive<FormRules<FormData>>({
source: [{ required: true, message: "请选择途径来源" }],
contactName: [
{ required: true, validator: validateName },
{ required: true, message: "请输入姓名" },
],
contactIdCard: [
{ required: true, validator: validatorIdCard },
@ -253,7 +243,7 @@ const rules = reactive<FormRules<FormData>>({
required: true,
message:
"请您尽量完整的描述您的信件内容,如发生事件、涉及单位、设计对象姓名、警号以及具体事项",
trigger: "blur",
trigger: "blur"
},
],
});

2
src/views/work/components/ConfirmedCompletion.vue

@ -94,7 +94,7 @@
</el-form-item>
<el-divider />
<h2>认定办结意见</h2>
<h2>认定办结意见*</h2>
<el-form-item
prop="completionComment"
class="mb-40 label-position-top"

37
src/views/work/components/templates/MailTypeForm.vue

@ -6,8 +6,8 @@
<div style="width: 50%">
<el-form-item label="信件分类" prop="mailCategory">
<mail-category-select
v-model="form.mailCategoryName"
@change="handleCategoryChange"
v-model="form.mailCategory"
@current-change="handleCategoryChange"
/>
</el-form-item>
</div>
@ -39,7 +39,10 @@
<el-form-item
label="处理流程"
prop="simpleFlowFlag"
v-if="form.mailFirstCategory === '工作建议类' || form.mailFirstCategory === '咨询求助类'"
v-if="
form.mailFirstCategory === '工作建议类' ||
form.mailFirstCategory === '咨询求助类'
"
>
<el-radio-group v-model="form.simpleFlowFlag" class="ml-4">
<div>
@ -74,13 +77,13 @@
label="下发单位"
v-if="form.mailCategory === '感谢信'"
>
<div class="flex gap" style="width: 100%;">
<div class="flex gap" style="width: 100%">
<el-select
v-model="form.secondDeptId"
placeholder="请选择二级办理单位"
filterable
clearable
style="width: 50%;"
style="width: 50%"
@change="handleChangeDept"
>
<el-option
@ -95,7 +98,7 @@
placeholder="请选择三级办理单位"
filterable
clearable
style="width: 50%;"
style="width: 50%"
>
<el-option
v-for="item in threeDepts"
@ -121,14 +124,20 @@ const props = defineProps({
},
mailId: {
type: String,
default: '',
default: "",
},
});
let form = reactive({});
watch(() => props.mailId, (val) => {
form = reactive({});
})
watch(
() => props.mailId,
(val) => {
formRef.value.resetFields();
form.mailFirstCategory = null;
form.mailSecondCategory = null;
form.mailThreeCategory = null;
}
);
const formRef = ref();
@ -159,12 +168,9 @@ const rules = {
],
};
const emits = defineEmits(["update:data"]);
function handleCategoryChange(data, node) {
form.mailCategory = data.label;
if (node.level === 1) {
form.mailFirstCategory = data.label;
form.mailSecondCategory = null;
@ -195,7 +201,7 @@ function getSecondDepts() {
function getThreeDepts(secondDeptId) {
listThree({
secondDeptId
secondDeptId,
}).then((data) => {
threeDepts.value = data;
});
@ -203,7 +209,7 @@ function getThreeDepts(secondDeptId) {
function handleChangeDept(val) {
form.threeDeptId = null;
getThreeDepts(val)
getThreeDepts(val);
}
function validate() {
@ -211,6 +217,7 @@ function validate() {
formRef.value.validate((valid) => {
if (valid) {
emits("update:data", form);
resolve(true);
} else {
reject();

Loading…
Cancel
Save