This commit is contained in:
Air 2025-03-04 17:41:25 +08:00
parent 0ef0ffbaf9
commit 8b16d07971
14 changed files with 1527 additions and 354 deletions

2
auto-imports.d.ts vendored
View File

@ -1,5 +1,5 @@
// Generated by 'unplugin-auto-import'
export {}
declare global {
const layer: typeof import('@layui/layer-vue')['layer']
}

5
components.d.ts vendored
View File

@ -19,6 +19,7 @@ declare module 'vue' {
LayConfigProvider: typeof import('@layui/layui-vue')['LayConfigProvider']
LayContainer: typeof import('@layui/layui-vue')['LayContainer']
LayCountUp: typeof import('@layui/layui-vue')['LayCountUp']
LayDate: typeof import('@layui/layui-vue')['LayDate']
LayDatePicker: typeof import('@layui/layui-vue')['LayDatePicker']
LayDescriptions: typeof import('@layui/layui-vue')['LayDescriptions']
LayDescriptionsItem: typeof import('@layui/layui-vue')['LayDescriptionsItem']
@ -40,6 +41,7 @@ declare module 'vue' {
LayLogo: typeof import('@layui/layui-vue')['LayLogo']
LayMenu: typeof import('@layui/layui-vue')['LayMenu']
LayMenuItem: typeof import('@layui/layui-vue')['LayMenuItem']
LayPage: typeof import('@layui/layui-vue')['LayPage']
LayPopconfirm: typeof import('@layui/layui-vue')['LayPopconfirm']
LayProgress: typeof import('@layui/layui-vue')['LayProgress']
LayRadio: typeof import('@layui/layui-vue')['LayRadio']
@ -58,11 +60,10 @@ declare module 'vue' {
LayTable: typeof import('@layui/layui-vue')['LayTable']
LayTag: typeof import('@layui/layui-vue')['LayTag']
LayTextarea: typeof import('@layui/layui-vue')['LayTextarea']
LayTimeline: typeof import('@layui/layui-vue')['LayTimeline']
LayTimelineItem: typeof import('@layui/layui-vue')['LayTimelineItem']
LayTree: typeof import('@layui/layui-vue')['LayTree']
LayUpload: typeof import('@layui/layui-vue')['LayUpload']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
WangEditor: typeof import('./src/components/WangEditor/index.vue')['default']
}
}

BIN
dist.zip

Binary file not shown.

930
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -11,6 +11,8 @@
},
"dependencies": {
"@layui/layui-vue": "2.21.1",
"@wangeditor/editor": "^5.1.23",
"@wangeditor/editor-for-vue": "^5.1.12",
"axios": "^1.5.1",
"echarts": "^5.4.3",
"js-base64": "^3.7.2",

View File

@ -7,7 +7,7 @@ type TAxiosOption = {
timeout: number;
baseURL: string;
}
//记得修改上传路径
//记得修改上传路径/api/common/upload
//const baseURL = 'http://yfyd.hschool.com.cn' // 设置基础URL前缀
const baseURL="/api";

View File

@ -322,6 +322,26 @@ export const getAdditionIndexManageExamine= function(date: any) {
return Http.post('/api/backend/addition_and_subtraction_records/examine', date)
}
// 获取通知公告列表
export function noticeList(data: any) {
return Http.post('/api/backend/public_announcement/getPublicAnnouncementData', data)
}
// 新增通知公告
export function noticeAdd(data: any) {
return Http.post('/api/backend/public_announcement/create', data)
}
// 编辑通知公告
export function noticeEdit(data: any) {
return Http.post('/api/backend/public_announcement/update', data)
}
// 删除通知公告
export function noticeDelete(data: any) {
return Http.post('/api/backend/public_announcement/delete', data)
}

View File

@ -39,32 +39,32 @@ export default [
path: '/system/index',
name: 'systemIndex',
component: () => import('../../views/system/index.vue'),
meta: {
title: '人员管理',
requireAuth: true,
closable: true,
permissions: ['sys:user:add']
},
},{
meta: { title: '人员管理', requireAuth: true, closable: true, permissions: ['sys:user:add'] },
}, {
path: '/system/department',
name: 'systemDepartment',
component: () => import('../../views/system/department.vue'),
meta: {title: '部门管理', requireAuth: true, closable: true},
},{
meta: { title: '部门管理', requireAuth: true, closable: true },
}, {
path: '/system/party',
name: 'systemParty',
component: () => import('../../views/system/party.vue'),
meta: {title: '党支部管理', requireAuth: true, closable: true},
},{
meta: { title: '党支部管理', requireAuth: true, closable: true },
}, {
path: '/system/notice',
name: 'systemNotice',
component: () => import('../../views/system/notice.vue'),
meta: { title: '通知公告', requireAuth: true, closable: true },
}, {
path: '/system/permission',
name: 'systemPermission',
component: () => import('../../views/system/permission.vue'),
meta: {title: '权限管理', requireAuth: true, closable: true},
},{
meta: { title: '权限管理', requireAuth: true, closable: true },
}, {
path: '/system/menu',
name: 'systemMenu',
component: () => import('../../views/system/menu.vue'),
meta: {title: '菜单管理', requireAuth: true, closable: true},
meta: { title: '菜单管理', requireAuth: true, closable: true },
}
]
},
@ -77,10 +77,10 @@ export default [
path: '/complaint/index',
name: 'Complaint',
component: () => import('../../views/complaint/index.vue'),
meta: { title: '投诉管理', requireAuth: true, closable: true },
meta: { title: '投诉管理', requireAuth: true, closable: true },
},
]
},{
}, {
path: '/packet',
redirect: '/packet/index',
component: BasicLayout,
@ -89,189 +89,189 @@ export default [
path: '/packet/index',
name: 'Packet',
component: () => import('../../views/packet/index.vue'),
meta: { title: '拒收红包', requireAuth: true, closable: true },
meta: { title: '拒收红包', requireAuth: true, closable: true },
},
]
},{
}, {
path: '/day_evaluation',
redirect: '/day_evaluation/index',
component: BasicLayout,
meta: {title: '日常考评'},
meta: { title: '日常考评' },
children: [
{
path: '/day_evaluation/index',
name: 'dayEvaluationIndex',
component: () => import('../../views/day_evaluation/index.vue'),
meta: {title: '加减分管理', requireAuth: true, closable: true},
},{
meta: { title: '加减分管理', requireAuth: true, closable: true },
}, {
path: '/day_evaluation/examine',
name: 'dayEvaluationExamine',
component: () => import('../../views/day_evaluation/examine.vue'),
meta: {title: '加减分审核', requireAuth: true, closable: true},
meta: { title: '加减分审核', requireAuth: true, closable: true },
}
]
},{
}, {
path: '/month_evaluation',
redirect: '/month_evaluation/index',
component: BasicLayout,
meta: {title: '月度考评'},
meta: { title: '月度考评' },
children: [
{
path: '/month_evaluation/index',
name: 'monthEvaluationIndex',
component: () => import('../../views/month_evaluation/index.vue'),
meta: {title: '月度考评填报', requireAuth: true, closable: true},
},{
meta: { title: '月度考评填报', requireAuth: true, closable: true },
}, {
path: '/month_evaluation/examine',
name: 'monthEvaluationExamine',
component: () => import('../../views/month_evaluation/examine.vue'),
meta: {title: '月度考评管理', requireAuth: true, closable: true},
meta: { title: '月度考评管理', requireAuth: true, closable: true },
}
]
},{
}, {
path: '/season_evaluation',
redirect: '/season_evaluation/index',
component: BasicLayout,
meta: {title: '季度考评'},
meta: { title: '季度考评' },
children: [
{
path: '/season_evaluation/index',
name: 'seasonEvaluationIndex',
component: () => import('../../views/season_evaluation/index.vue'),
meta: {title: '季度考评', requireAuth: true, closable: true},
},{
meta: { title: '季度考评', requireAuth: true, closable: true },
}, {
path: '/season_evaluation/examine',
name: 'seasonEvaluationExamine',
component: () => import('../../views/season_evaluation/examine.vue'),
meta: {title: '季度考评管理', requireAuth: true, closable: true},
meta: { title: '季度考评管理', requireAuth: true, closable: true },
}
]
},{
}, {
path: '/outside_evaluation',
redirect: '/outside_evaluation/index',
component: BasicLayout,
meta: {title: '院外考评'},
meta: { title: '院外考评' },
children: [
{
path: '/outside_evaluation/index',
name: 'outsideEvaluationIndex',
component: () => import('../../views/day_evaluation/index.vue'),
meta: {title: '我的院外考评', requireAuth: true, closable: true},
},{
meta: { title: '我的院外考评', requireAuth: true, closable: true },
}, {
path: '/outside_evaluation/examine',
name: 'outsideEvaluationExamine',
component: () => import('../../views/day_evaluation/examine.vue'),
meta: {title: '院外考评管理', requireAuth: true, closable: true},
meta: { title: '院外考评管理', requireAuth: true, closable: true },
}
]
},{
}, {
path: '/year_evaluation',
redirect: '/year_evaluation/index',
component: BasicLayout,
meta: {title: '年度考评'},
meta: { title: '年度考评' },
children: [
{
path: '/year_evaluation/index',
name: 'yearEvaluationIndex',
component: () => import('../../views/year_evaluation/index.vue'),
meta: {title: '年度考评', requireAuth: true, closable: true},
},{
meta: { title: '年度考评', requireAuth: true, closable: true },
}, {
path: '/year_evaluation/examine',
name: 'yearEvaluationExamine',
component: () => import('../../views/year_evaluation/examine.vue'),
meta: {title: '年度考评管理', requireAuth: true, closable: true},
meta: { title: '年度考评管理', requireAuth: true, closable: true },
}
]
},{
}, {
path: '/file_bag',
redirect: '/file_bag/index',
component: BasicLayout,
meta: {title: '医德医风档案'},
meta: { title: '医德医风档案' },
children: [
{
path: '/file_bag/index',
name: 'fileBagIndex',
component: () => import('../../views/day_evaluation/index.vue'),
meta: {title: '我的档案', requireAuth: true, closable: true},
},{
meta: { title: '我的档案', requireAuth: true, closable: true },
}, {
path: '/file_bag/examine',
name: 'fileBagExamine',
component: () => import('../../views/day_evaluation/examine.vue'),
meta: {title: '员工档案', requireAuth: true, closable: true},
meta: { title: '员工档案', requireAuth: true, closable: true },
}
]
},{
}, {
path: '/census',
redirect: '/census/index',
component: BasicLayout,
meta: {title: '统计报表分析'},
meta: { title: '统计报表分析' },
children: [
{
path: '/census/index',
name: 'censusIndex',
component: () => import('../../views/census/red.vue'),
meta: {title: '拒收红包报表统计', requireAuth: true, closable: true},
},{
meta: { title: '拒收红包报表统计', requireAuth: true, closable: true },
}, {
path: '/census/day',
name: 'censusDay',
component: () => import('../../views/census/day.vue'),
meta: {title: '日常考评报表统计', requireAuth: true, closable: true},
},{
meta: { title: '日常考评报表统计', requireAuth: true, closable: true },
}, {
path: '/census/month',
name: 'censusMonth',
component: () => import('../../views/census/month.vue'),
meta: {title: '月度考评报表统计', requireAuth: true, closable: true},
},{
meta: { title: '月度考评报表统计', requireAuth: true, closable: true },
}, {
path: '/census/season',
name: 'censusSeason',
component: () => import('../../views/census/season.vue'),
meta: {title: '季度考评报表统计', requireAuth: true, closable: true},
},{
meta: { title: '季度考评报表统计', requireAuth: true, closable: true },
}, {
path: '/census/year',
name: 'censusYear',
component: () => import('../../views/census/year.vue'),
meta: {title: '年度考评报表统计', requireAuth: true, closable: true},
meta: { title: '年度考评报表统计', requireAuth: true, closable: true },
}
]
},{
}, {
path: '/configuration',
redirect: '/configuration/index',
component: BasicLayout,
meta: {title: '规则配置中心'},
meta: { title: '规则配置中心' },
children: [
{
path: '/configuration/index',
name: 'configurationIndex',
component: () => import('../../views/configuration/index.vue'),
meta: {title: '登陆日志管理', requireAuth: true, closable: true},
},{
meta: { title: '登陆日志管理', requireAuth: true, closable: true },
}, {
path: '/configuration/foundation',
name: 'configurationFoundation',
component: () => import('../../views/configuration/foundation.vue'),
meta: {title: '基础评分项管理', requireAuth: true, closable: true},
},{
meta: { title: '基础评分项管理', requireAuth: true, closable: true },
}, {
path: '/configuration/add',
name: 'configurationAdd',
component: () => import('../../views/configuration/add.vue'),
meta: {title: '加减分项管理', requireAuth: true, closable: true},
},{
meta: { title: '加减分项管理', requireAuth: true, closable: true },
}, {
path: '/configuration/time',
name: 'configurationTime',
component: () => import('../../views/configuration/time.vue'),
meta: {title: '考评时间管理', requireAuth: true, closable: true},
},{
meta: { title: '考评时间管理', requireAuth: true, closable: true },
}, {
path: '/configuration/level',
name: 'configurationLevel',
component: () => import('../../views/configuration/level.vue'),
meta: {title: '考评级别管理', requireAuth: true, closable: true},
},{
meta: { title: '考评级别管理', requireAuth: true, closable: true },
}, {
path: '/configuration/opinion',
name: 'configurationOpinion',
component: () => import('../../views/configuration/opinion.vue'),
meta: {title: '医德征求意见管理', requireAuth: true, closable: true},
meta: { title: '医德征求意见管理', requireAuth: true, closable: true },
}
]
},{
}, {
path: '/error',
component: BasicLayout,
meta: { title: '错误页面' },

View File

@ -5,9 +5,9 @@
<span style="font-size: 18px;vertical-align: center;margin-right: 20px">登录日志列表</span>
</div>
<lay-table size="lg" ref="tableRef" :columns="columns" :data-source="dataSource">
<template v-slot:login_status="{ data }">
<span :style="{ color: data.login_status ? '#67C23A' : '#F56C6C' }">
{{ data.login_status ? '成功' : '失败' }}
<template v-slot:event_type="{ data }">
<span :style="{ color: data.event_type === '登录' ? '#67C23A' : '#409EFF' }">
{{ data.event_type }}
</span>
</template>
</lay-table>
@ -22,11 +22,14 @@ import { layer } from '@layui/layer-vue'
//
interface LoginLog {
id: number
username: string
ip_address: string
login_time: string
login_status: boolean
device_info: string
department: string //
record_time: string //
login_name: string //
username: string //
ip_address: string // IP
event_type: string // /
event_content: string //
device_info: string //
}
//
@ -34,30 +37,45 @@ const dataSource = ref<LoginLog[]>([])
//
const columns = [
{
title: "科室",
width: "120px",
key: "department"
},
{
title: "记录时间",
width: "180px",
key: "record_time"
},
{
title: "登录名",
width: "120px",
key: "login_name"
},
{
title: "用户名",
width: "150px",
width: "120px",
key: "username"
},
{
title: "IP地址",
title: "登录IP",
width: "150px",
key: "ip_address"
},
{
title: "登录时间",
width: "180px",
key: "login_time"
title: "事件类型",
width: "100px",
key: "event_type",
customSlot: 'event_type'
},
{
title: "登录状态",
width: "100px",
key: "login_status",
customSlot: 'login_status'
title: "事件内容",
width: "200px",
key: "event_content"
},
{
title: "设备信息",
width: "300px",
width: "250px",
key: "device_info"
}
]
@ -81,18 +99,24 @@ const getLoginLogs = () => {
dataSource.value = [
{
id: 1,
username: 'admin',
department: '内科',
record_time: '2024-03-20 10:30:45',
login_name: 'admin',
username: '管理员',
ip_address: '192.168.1.100',
login_time: '2024-03-20 10:30:45',
login_status: true,
event_type: '登录',
event_content: '用户登录成功',
device_info: 'Chrome 122.0.0.0 / Windows 10'
},
{
id: 2,
username: 'user1',
department: '外科',
record_time: '2024-03-20 09:15:22',
login_name: 'user1',
username: '张医生',
ip_address: '192.168.1.101',
login_time: '2024-03-20 09:15:22',
login_status: false,
event_type: '登出',
event_content: '用户主动登出',
device_info: 'Firefox 123.0 / MacOS'
}
]

View File

@ -94,7 +94,7 @@
</lay-form-item>
<lay-form-item label="附件" mode="block">
<lay-upload ref="uploadRef" :number="1" field="file" :size="1000"
:headers="{ token: userStore.token }" url="/api/api/common/upload" @cutdone="getCutDone"
:headers="{ token: userStore.token }" url="/api/common/upload" @cutdone="getCutDone"
v-model="file1" :auto="true" :cut="false" :cutOptions="cutOptions" @done="getFileDone">
<template #preview>
<a v-if="formData.fj_url!=''" style="color: #009688" :href="formData.fj_url" target="_blank">

View File

@ -1,227 +1,118 @@
<template>
<lay-container :fluid="true" style="padding: 10px">
<lay-row :space="10">
<lay-col :md="6" :sm="6" :xs="12">
<lay-card class="statistics">
<template #title>今日访问</template>
<template #extra>
<lay-badge theme="green">Hot</lay-badge>
</template>
<div class="statistics-body">
<lay-count-up :startVal="0" :endVal="3600" :decimalPlaces="2"></lay-count-up>
</div>
<template #footer>
访问趋势1
</template>
</lay-card>
</lay-col>
<lay-col :md="6" :sm="6" :xs="12">
<lay-card class="statistics">
<template #title>提交次数</template>
<template #extra>
<lay-badge type="rim">Hot</lay-badge>
</template>
<div class="statistics-body">
<lay-count-up :startVal="0" :endVal="3600" :decimalPlaces="2"></lay-count-up>
</div>
<template #footer>
最近一月
</template>
</lay-card>
</lay-col>
<lay-col :md="6" :sm="6" :xs="12">
<lay-card class="statistics">
<template #title>下载数量</template>
<template #extra>
<lay-badge type="rim">Hot</lay-badge>
</template>
<div class="statistics-body">
<lay-count-up :startVal="0" :endVal="3600" :decimalPlaces="2"></lay-count-up>
</div>
<template #footer>
总下载量
</template>
</lay-card>
</lay-col>
<lay-col :md="6" :sm="6" :xs="12">
<lay-card class="statistics">
<template #title>流量统计</template>
<template #extra>
<lay-badge type="rim">Hot</lay-badge>
</template>
<div class="statistics-body">
<lay-count-up :startVal="0" :endVal="3600" :decimalPlaces="2"></lay-count-up>
</div>
<template #footer>
最近一年
</template>
</lay-card>
</lay-col>
<lay-col :md="24" :sm="24" :xs="24">
<lay-card>
<template #title>我的觉悟</template>
<template #extra>
<lay-badge type="rim">昨日</lay-badge>
<lay-badge type="rim">今日</lay-badge>
<template #title>
<div style="font-size: 16px; font-weight: bold;">通知公告</div>
</template>
<lay-row>
<lay-col :md="18">
<div id="main" ref="mainRef"></div>
</lay-col>
<lay-col :md="6">
<div style="padding-top:42px;padding-left: 42px;padding-right: 42px;padding-bottom: 10px;">
<lay-timeline>
<lay-timeline-item title="工专路 0 号店" simple>
<template #dot>
<lay-icon type="layui-icon-face-smile" color="#009688"></lay-icon>
</template>
</lay-timeline-item>
<lay-timeline-item title="工专路 1 号店" simple></lay-timeline-item>
<lay-timeline-item title="工专路 2 号店" simple></lay-timeline-item>
<lay-timeline-item title="工专路 3 号店" simple></lay-timeline-item>
<lay-timeline-item title="工专路 4 号店" simple></lay-timeline-item>
<lay-timeline-item title="工专路 5 号店" simple></lay-timeline-item>
<lay-timeline-item title="工专路 5 号店" simple></lay-timeline-item>
</lay-timeline>
</div>
</lay-col>
</lay-row>
</lay-card>
</lay-col>
<lay-col :md="8" :sm="8" :xs="24">
<lay-card>
<template #title>留言面板</template>
<ul class="leaving-messages">
<li>
<h3>张爱玲</h3>
<p>于千万人之中遇到你所要遇到的人于千万年之中时间的无涯的荒野中没有早一步也没有晚一步刚巧赶上了那也没有别的话好说唯有轻轻的问一声原来你也在这里</p>
<span>5月30日 00:00</span>
</li>
<li>
<h3>王羲之</h3>
<p>但我只要够快就行了对不对你就算有无限量的子弹你换弹匣也需要时间我只有那么一瞬间把你打翻然后就拍屁股走人</p>
<span>5月30日 00:00</span>
</li>
<li>
<h3>诸葛亮</h3>
<p>皓首匹夫苍髯老贼你枉活九十有六一生未立寸功只会摇唇鼓舌助曹为虐一条断脊之犬还敢在我军阵前狺狺狂吠我从未见过有如此厚颜无耻之人</p>
<span>5月30日 00:00</span>
</li>
</ul>
</lay-card>
</lay-col>
<lay-col :md="8" :sm="8" :xs="24">
<lay-card>
<template #title>签到统计</template>
<lay-table :columns="columns21" :data-source="dataSource21">
<template #state="{ data }">
<span v-if="data.state == 0" style="color:#FFB800">进行中</span>
<span v-else-if="data.state == 1" style="color:#5FB878">已完成</span>
<span v-else style="color:#FF5722">已预期</span>
<lay-table :page="page" size="lg" height="600px" :columns="columns" :data-source="dataSource" @row-click="handleRowClick">
<template #operation="{ data }">
<span style="color: #00A394;cursor: pointer" @click.stop="handleViewDetail(data)">查看详情</span>
</template>
</lay-table>
</lay-card>
</lay-col>
<lay-col :md="8" :sm="8" :xs="24">
<lay-card>
<template #title>本月目标</template>
<div class="target">
<lay-progress :percent="90" circle :circleWidth="15" :show-text="true" text="已完成">
<template v-slot:text="{}">
<span></span>
</template>
</lay-progress>
<p class="target-title">{{ 100 > 70 ? '恭喜,本月目标已达标!' : '加油, 就快达标了!' }}</p>
</div>
</lay-card>
</lay-col>
</lay-row>
<!-- 详情弹窗 -->
<lay-layer v-model="showDetail" :type="4" :title="null" :area="['700px', '100%']">
<div class="notice-detail">
<h2>{{ currentNotice?.title }}</h2>
<div class="notice-info">
<span>发布时间{{ currentNotice?.publishTime }}</span>
<span>发布部门{{ currentNotice?.department }}</span>
</div>
<div class="notice-content">
{{ currentNotice?.content }}
</div>
</div>
</lay-layer>
</lay-container>
</template>
<script lang="ts">
import { defineComponent, ref, onMounted } from "vue";
import * as echarts from 'echarts';
<script setup lang="ts">
import { defineComponent, reactive, ref } from "vue";
export default defineComponent({
name: 'Analysis',
setup() {
const mainRef = ref()
onMounted(() => {
var chartDom = mainRef.value;
// @ts-ignore
var myChart = echarts.init(chartDom);
var option = {
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun', 'Bai', 'Fan', 'Yue', 'Qian']
},
yAxis: {
type: 'value'
},
grid: {
x: '50px',
y: '50px',
x2: '50px',
y2: '50px',
},
series: [
{
data: [120, 200, 150, 80, 70, 110, 130, 50, 40, 70, 100],
type: 'bar',
showBackground: true,
backgroundStyle: {
color: 'rgba(180, 180, 180, 0.2)'
},
itemStyle: {
normal: {
color: '#009688'
},
}
}
]
};
option && myChart.setOption(option);
})
const columns21 = [
interface Notice {
id: number;
title: string;
department: string;
publishTime: string;
content: string;
}
//
const page = reactive({
current: 1,
limit: 10,
total: 1
})
//
const columns = [
{
type: "number",
title: "标题",
key: "title",
width: "40%"
},
{
title: "任务内容",
key: "task",
}, {
title: "计划时间",
key: "time"
}, {
title: "完成情况",
key: "state",
customSlot: "state"
title: "发布部门",
key: "department",
},
{
title: "发布时间",
key: "publishTime"
},
{
title: "操作",
key: "operation",
width: "120px",
customSlot: "operation"
}
]
];
const dataSource21 = [
{ task: "睡觉", time: "两小时", state: "1" },
{ task: "吃饭", time: "两小时", state: "2" },
{ task: "吃饭", time: "两小时", state: "1" },
{ task: "睡觉", time: "两小时", state: "1" },
{ task: "睡觉", time: "两小时", state: "2" },
{ task: "上班", time: "两小时", state: "1" },
{ task: "上班", time: "两小时", state: "1" },
{ task: "上班", time: "两小时", state: "0" },
{ task: "睡觉", time: "两小时", state: "0" },
{ task: "睡觉", time: "两小时", state: "0" }
]
//
const dataSource = ref<Notice[]>([
{
id: 1,
title: "关于开展2024年第二季度医德医风考核的通知",
department: "医务科",
publishTime: "2024-03-15",
content: "根据医院年度工作计划定于2024年第二季度开展医德医风考核工作。请各科室做好相关准备工作具体考核细则详见附件。考核时间2024年4月1日至4月15日..."
},
{
id: 2,
title: "医院感染防控培训通知",
department: "感染管理科",
publishTime: "2024-03-14",
content: "为进一步加强医院感染防控工作提高全院医务人员防控意识和操作规范性定于2024年3月20日下午14:00在第一会议室开展感染防控培训..."
},
{
id: 3,
title: "关于调整门诊工作时间的通知",
department: "院办公室",
publishTime: "2024-03-13",
content: "为更好地服务患者经医院研究决定自2024年4月1日起调整门诊工作时间。调整后的工作时间为周一至周五 8:00-17:30周六、周日 8:30-12:00..."
}
]);
return {
mainRef,
columns21,
dataSource21
//
const showDetail = ref(false);
//
const currentNotice = ref<Notice | null>(null);
//
const detailTitle = ref('');
//
const handleViewDetail = (row: Notice) => {
currentNotice.value = row;
detailTitle.value = row.title;
showDetail.value = true;
};
//
const handleRowClick = (row: Notice) => {
handleViewDetail(row);
};
},
});
</script>
<style lang="less" scoped>
@ -272,4 +163,27 @@ export default defineComponent({
.statistics-body {
padding: 14px 0;
}
.notice-detail {
padding: 20px;
h2 {
text-align: center;
margin-bottom: 20px;
}
.notice-info {
display: flex;
justify-content: space-between;
color: #666;
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 1px solid #eee;
}
.notice-content {
line-height: 1.8;
text-align: justify;
}
}
</style>

View File

@ -152,7 +152,7 @@
</lay-form-item>
<lay-form-item label="附件" mode="block">
<lay-upload ref="uploadRef" :number="1" field="file" :size="1000"
:headers="{ token: userStore.token }" url="/api/api/common/upload" @cutdone="getCutDone"
:headers="{ token: userStore.token }" url="/api/common/upload" @cutdone="getCutDone"
v-model="file1" :auto="true" :cut="false" :cutOptions="cutOptions" @done="getFileDone">
<template #preview>
<a v-if="form.fj_url" style="color: #009688" :href="form.fj_url" target="_blank">

View File

@ -7,7 +7,7 @@
科室列表
</div>
<lay-tree v-show="!isFold" style="margin-top: 10px" :data="data" v-model:selectedKey="leftId"
:showLine="false" :default-expand-all="true" @node-click="handleClick">
:showLine="false" @node-click="handleClick">
<template #title="{ data }">
<span :class="leftId == data.id ? 'isChecked' : ''">
{{ data.name }}
@ -57,7 +57,7 @@
</lay-row>
</lay-form>
</lay-card>
<lay-table :page="page" :height="500" :columns="columns" :loading="loading" :default-toolbar="true"
<lay-table :page="page" height="600px" :columns="columns" :loading="loading" :default-toolbar="true"
:data-source="dataSource">
<template #status="{ row }">
<lay-tag type="danger" v-if="row.status == 0">已禁用</lay-tag>
@ -231,6 +231,9 @@ const getLeftList = () => {
console.log(res)
if (res.code == 1) {
data.value = res.data;
if(userStore.userInfo.level == 1){
data.value.unshift({id: 0,name: '全部',children: []})
}
leftId.value=res.data[0].id;
getUserList();
} else {
@ -344,54 +347,54 @@ const addButton = ref([
console.log(model11);
//return;
//
// if (!model11.username) {
// layer.msg('', {icon: 2});
// return;
// }
// if (!model11.nickname) {
// layer.msg('', {icon: 2});
// return;
// }
// if (!model11.mobile) {
// layer.msg('', {icon: 2});
// return;
// }
// if (!model11.email) {
// layer.msg('', {icon: 2});
// return;
// }
// if (!model11.member_code) {
// layer.msg('', {icon: 2});
// return;
// }
// if (!model11.birthday) {
// layer.msg('', {icon: 2});
// return;
// }
// if (!model11.work_number) {
// layer.msg('', {icon: 2});
// return;
// }
// if (!model11.gender) {
// layer.msg('', {icon: 2});
// return;
// }
// if (!model11.auth_group_id) {
// layer.msg('', {icon: 2});
// return;
// }
// if (!model11.status) {
// layer.msg('', {icon: 2});
// return;
// }
// if (!model11.group_id) {
// layer.msg('', {icon: 2});
// return;
// }
// if (!model11.party_id) {
// layer.msg('', {icon: 2});
// return;
// }
if (!model11.username) {
layer.msg('用户名不能为空!', {icon: 2});
return;
}
if (!model11.nickname) {
layer.msg('姓名不能为空!', {icon: 2});
return;
}
if (!model11.mobile) {
layer.msg('手机号不能为空!', {icon: 2});
return;
}
if (!model11.email) {
layer.msg('邮箱不能为空!', {icon: 2});
return;
}
if (!model11.member_code) {
layer.msg('身份证号不能为空!', {icon: 2});
return;
}
if (!model11.birthday) {
layer.msg('请选择生日!', {icon: 2});
return;
}
if (!model11.work_number) {
layer.msg('工号不能为空!', {icon: 2});
return;
}
if (!model11.gender) {
layer.msg('性别不能为空!', {icon: 2});
return;
}
if (!model11.auth_group_id) {
layer.msg('角色组不能为空!', {icon: 2});
return;
}
if (!model11.status) {
layer.msg('状态不能为空!', {icon: 2});
return;
}
if (!model11.group_id) {
layer.msg('科室不能为空!', {icon: 2});
return;
}
if (!model11.party_id) {
layer.msg('党支部不能为空!', {icon: 2});
return;
}
model11.group_level = JSON.stringify(model11.group_id);
model11.group_id = model11.group_id[model11.group_id.length - 1];
console.log(model11.group_id)

279
src/views/system/notice.vue Normal file
View File

@ -0,0 +1,279 @@
<template>
<lay-container style="padding: 20px">
<lay-card>
<div style="padding: 10px">
<span style="font-size: 18px;vertical-align: center;margin-right: 20px">通知公告</span>
<lay-button type="primary" @click="openNew()" size="sm">新增公告</lay-button>
</div>
<lay-table :page="page" height="600px" size="lg" :columns="columns" :data-source="dataSource">
<template v-slot:status="{ data }">
<span v-if="data.status == 1">已发布</span>
<span v-if="data.status == 0">未发布</span>
</template>
<template v-slot:operator="{ data }">
<lay-space size="lg">
<span style="color: #00A394;cursor: pointer" @click="editShowMsd(data)">编辑</span>
<lay-popconfirm trigger="click" content="确定要删除吗?" @confirm="delShowMsd(data)">
<span style="color: #00A394;cursor: pointer">删除</span>
</lay-popconfirm>
</lay-space>
</template>
</lay-table>
</lay-card>
<lay-layer v-model="addShow" :title="addIsEdit == 1 ? '新增公告' : '编辑公告'" :type="4" :shade="true"
:area="['950px', '100%']" :btn="addButton">
<lay-container fluid="true" style="padding: 20px">
<lay-form :model="addData">
<lay-form-item required label="公告标题" prop="title">
<lay-input v-model="addData.title" placeholder="请输入公告标题"></lay-input>
</lay-form-item>
<lay-form-item required label="作者" prop="author">
<lay-input v-model="addData.author" placeholder="请输入作者"></lay-input>
</lay-form-item>
<lay-form-item required label="公告内容" prop="content">
<div style="border: 1px solid #ccc">
<Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef" :defaultConfig="toolbarConfig"
mode="default" />
<Editor style="height: 500px; " @onCreated="(e) => onCreated(e)" v-model="valueHtml" :defaultConfig="editorConfig" mode="default" />
</div>
</lay-form-item>
<lay-form-item required label="状态" prop="status">
<lay-select v-model="addData.status" placeholder="请选择">
<lay-select-option :value="0" label="隐藏"></lay-select-option>
<lay-select-option :value="1" label="显示"></lay-select-option>
</lay-select>
</lay-form-item>
</lay-form>
</lay-container>
</lay-layer>
</lay-container>
</template>
<script setup lang="ts">
import {
noticeAdd,
noticeList,
noticeEdit,
noticeDelete
} from '../../api/module/home'
import { ref, onMounted, reactive, shallowRef, watch } from 'vue'
import { layer } from '@layui/layer-vue'
import {Editor, Toolbar} from '@wangeditor/editor-for-vue';
// Update editor configuration
const toolbarConfig = {
showLinkImg: false,
uploadImgShowBase64: true,
excludeKeys: [
'insertVideo',
'uploadVideo',
'group-video',
'insertLink',
'insertTable',
'codeBlock',
]
}
const editorConfig = {
placeholder: '',
readOnly: false,
autoFocus: true,
MENU_CONF: {
uploadImage: {
maxFileSize: 50 * 1024 * 1024, // 50MB
server: '/api/common/upload',
fieldName: 'file',
meta: {
association_id: 0,
},
customInsert(res: any, insertFn: any) {
console.log(res);
insertFn(res.data.fullurl, '', '')
},
}
}
}
// Add valueHtml for editor content
const valueHtml = ref('')
interface NoticeData {
id?: number;
title: string;
author: string;
content: string;
status: number;
}
//
const dataSource = ref<NoticeData[]>([]);
const addShow = ref(false);
// 1 add 2 edit
const addIsEdit = ref(1);
//
const page = reactive({
current: 1,
limit: 10,
total: 1
});
const addData = reactive<NoticeData>({
title: '',
author: '',
content: '',
status: 1
});
const editorRef = shallowRef()
onMounted(() => {
getNoticeList()
});
const openNew = () => {
addData.id = undefined;
addData.title = '';
addData.author = '';
addData.content = '';
valueHtml.value = '';
addData.status = 1;
addIsEdit.value = 1;
addShow.value = true;
}
const getNoticeList = () => {
noticeList({ page: page.current, size: page.limit }).then((res) => {
if (res.code == 1) {
dataSource.value = res.data.list;
page.total = res.data.count;
} else {
layer.msg(res.msg, { icon: 2 })
}
})
}
const editShowMsd = (data: NoticeData) => {
addShow.value = true;
addData.id = data.id;
addData.title = data.title;
addData.author = data.author;
addData.content = data.content;
valueHtml.value = data.content;
addData.status = parseInt(data.status.toString());
addIsEdit.value = 2;
}
// Watch for changes in valueHtml and update addData.content
watch(valueHtml, (newValue) => {
addData.content = newValue;
})
const delShowMsd = async (data: NoticeData) => {
const res = await noticeDelete({ id: data.id });
if (res.code == 1) {
layer.msg('删除成功!', { icon: 1 })
getNoticeList();
} else {
layer.msg(res.msg, { icon: 2 })
}
}
const changePage = (currentPage: number) => {
page.current = currentPage;
getNoticeList();
}
const columns = [
{
title: "公告标题",
width: "180px",
key: "title"
},
{
title: "作者",
width: "120px",
key: "author"
},
{
title: "公告内容",
width: "280px",
key: "content"
},
{
title: "发布时间",
width: "180px",
key: "create_time"
},
{
title: "状态",
width: "100px",
customSlot: 'status',
key: "status"
},
{
title: '操作',
width: '120px',
customSlot: 'operator',
key: 'operator',
align: 'center',
fixed: 'right'
}
]
const onCreated = (editor: any) => {
editorRef.value = Object.seal(editor);
}
const addButton = ref([
{
text: "确认",
callback: async () => {
if (addData.title == '') {
layer.msg('公告标题不能为空!', { icon: 2 })
return;
}
if (addData.author == '') {
layer.msg('作者不能为空!', { icon: 2 })
return;
}
if (addData.content == '') {
layer.msg('公告内容不能为空!', { icon: 2 })
return;
}
const res = addIsEdit.value == 1
? await noticeAdd(addData)
: await noticeEdit(addData);
if (res.code == 1) {
layer.msg('提交成功!', { icon: 1 })
addShow.value = false;
getNoticeList();
} else {
layer.msg(res.msg, { icon: 2 })
}
}
},
{
text: "取消",
callback: () => {
addShow.value = false;
}
}
])
</script>
<style src="@wangeditor/editor/dist/css/style.css"></style>
<style scoped>
:deep(.w-e-text-container) {
min-height: 400px !important;
}
:deep(.w-e-toolbar) {
border: 1px solid #ddd !important;
border-bottom: none !important;
}
:deep(.w-e-text-container) {
border: 1px solid #ddd !important;
border-top: none !important;
}
</style>