12 Commits
Author SHA1 Message Date
lianlonggang 2241b6873f fix(healthMonitor): 修复健康监测模块中的组织机构数据显示和绑定功能
- 在sectoralData.data.ts中添加单位名称列的颜色渲染,三级单位显示为红色
- 在sectoralDataList.vue中添加组织代码长度限制,小于6位时禁用明细和导出功能
- 修复toolManagement组件中bindModal.vue的参数传递问题
- 修改toolManagement.data.ts中部门选择器的默认值和禁用状态
- 移除重复的单位名称表单项并优化搜索表单的组织机构选择逻辑
- 添加单位名称列到员工表格中并调整搜索表单的字段映射
2026-05-06 15:04:28 +08:00
lianlonggang eeb1496483 feat(upload): 配置文件上传组件的业务路径和文本提示
- 在 JImageUpload 组件中添加 bizPath 属性以指定上传路径
- 为头像上传功能统一设置 bizPath: 'avatar'
- 为图片上传功能设置 bizPath: 'img'
- 为视频上传功能设置 bizPath: 'video'
- 为PDF文件上传设置 bizPath: 'bizfile'
- 为APP文件上传设置 bizPath: 'appfile'
- 添加 text 属性统一显示 '上传头像' 提示文本
- 在系统横幅管理中配置图片上传的业务路径
- 为新资源管理模块添加完整的数据结构定义
2026-04-30 08:56:14 +08:00
lianlonggang 3da41ae2d3 fix(emergency): 解决消息解析异常问题
- 添加了对消息数据的类型检查
- 添加了JSON解析的异常捕获处理
- 防止非字符串数据导致的解析错误
- 确保消息处理的健壮性
2026-04-10 14:43:29 +08:00
lianlonggang 7106e99a7b fix(chat): 修复消息气泡组件头像加载及位置服务地图链接
- 实现头像加载失败处理机制,添加默认头像回退方案
- 使用 ref 状态追踪头像加载失败情况,避免 watchEffect 重置问题
- 更新位置服务地图链接,从腾讯地图切换到高德地图服务
- 配置 Vue 构建依赖转译,解决 element-plus 兼容性问题
- 移除多个无用的 SVG 图标文件,精简项目资源
2026-04-10 14:43:08 +08:00
lianlonggang c1a56aefd9 style(UserSelectByDepModal): 优化部门选择用户弹窗样式
- 将左侧部门树卡片的 minHeight 改为固定 height: 613px
- 将 overflow: auto 改为 overflowY: auto,避免横向滚动条
2026-04-01 15:31:19 +08:00
lianlonggang 4f848e7ce9 fix(emergency,healthMonitor): 修复通知消息弹窗重复提交问题并优化页面细节
- 为通知消息弹窗的\"保存并发送\"和\"保存\"按钮添加 loading 状态和 disabled 禁用,防止重复提交
- 优化应急管理列表页面和 AED 设备地图页面的代码格式
2026-04-01 14:48:34 +08:00
lianlonggang a9db38e5e1 修复手表数据日历展示问题,屏蔽非当前月的日期,切换日期发生年份变化时获取新年份月数据 2026-03-30 18:53:07 +08:00
weixin 80627d24c0 update 2026-03-24 10:14:26 +08:00
weixin a24c936cde update
1.修改健康银行访问链接,测试环境截取掉:+端口
2026-03-24 10:03:33 +08:00
weixin 5db0c7effc update
1.修改健康银行访问链接
2026-03-24 09:21:27 +08:00
weixin 28707b346e update
1.修改员工工号正则,emp_sysno为EMP_SYSNO
2026-03-19 16:09:23 +08:00
lianlonggang 8eff9119c7 信创改造,处理写死的表名 2026-03-16 17:37:48 +08:00
62 changed files with 367 additions and 296 deletions
@@ -6,8 +6,7 @@
<!-- onerror="this.src='https://web.sdk.qcloud.com/component/TUIKit/assets/avatar_21.png'"-->
<!-- alt=""-->
<!-- />-->
<img class="avatar" v-if="getSrc(message)" :src="getSrc(message)" alt="" />
<img class="avatar" v-else src="@/assets/image/default_avatar.png" alt="" />
<img class="avatar" :src="avatarError ? defaultAvatar : (message?.avatar || defaultAvatar)" @error="onAvatarError" alt="" />
<main class="message-area">
<label class="name" v-if="message.flow === 'in' && message.conversationType === 'GROUP'">
{{ message.nameCard || message.nick || message.from }}
@@ -86,6 +85,7 @@
import MessageReference from './message-reference.vue';
import { Message } from '../interface';
import { TUIEnv } from '../../../../../TUIKit/TUIPlugin';
import defaultAvatar from '@/assets/image/default_avatar.png';
import MessageEmojiReact from './message-emoji-react.vue';
import TIM from '../../../../TUICore/tim/index';
@@ -145,6 +145,15 @@
needEmojiReact: false,
});
// 追踪头像加载失败状态,避免 watchEffect 重置时覆盖 @error 的修复
const avatarError = ref(false);
watch(() => (props.data as any)?.ID, () => {
avatarError.value = false;
});
const onAvatarError = () => {
avatarError.value = true;
};
watchEffect(() => {
data.type = constant;
data.messagesList = props.messagesList;
@@ -376,6 +385,9 @@
return {
getSrc,
defaultAvatar,
avatarError,
onAvatarError,
...toRefs(data),
toggleDialog,
htmlRefHook,
@@ -269,14 +269,16 @@ export function handleLocationMessageShowContext(item: any) {
};
location.lon = item.payload.longitude.toFixed(6);
location.lat = item.payload.latitude.toFixed(6);
// 跳转高德地图标记点页面
location.href =
'https://map.qq.com/?type=marker&isopeninfowin=1&markertype=1&' +
`pointx=${location.lon}&pointy=${location.lat}&name=${item.payload.description}`;
'https://uri.amap.com/marker?' +
`position=${location.lon},${location.lat}&name=${item.payload.description}&src=mypage&coordinate=gaode&callnative=0`;
// 高德静态地图图片
location.url =
'https://apis.map.qq.com/ws/staticmap/v2/?' +
`center=${location.lat},${location.lon}&zoom=10&size=300*150&maptype=roadmap&` +
`markers=size:large|color:0xFFCCFF|label:k|${location.lat},${location.lon}&` +
'key=UBNBZ-PTP3P-TE7DB-LHRTI-Y4YLE-VWBBD';
'https://restapi.amap.com/v3/staticmap?' +
`location=${location.lon},${location.lat}&zoom=10&size=300*150&` +
`markers=large,,A:${location.lon},${location.lat}&` +
'key=8498ba3ba280654a7f6891b617f7d6ef';
location.description = item.payload.description;
return location;
}
+1
View File
@@ -9,6 +9,7 @@ module.exports = {
outputDir: '../public/static/im-web',
productionSourceMap: false,
lintOnSave: false,
transpileDependencies: ['element-plus', 'vue-router', '@ctrl/tinycolor'],
chainWebpack: (config) => {
config.resolve.alias.set('@', resolve('src')).set('tim', resolve('src/tim.js'));
// 删除预加载
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 731 B

After

Width:  |  Height:  |  Size: 731 B

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="48px" height="48px" viewBox="0 0 48 48" version="1.1">
<title>ic_back_white</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="02.-查看信息-示例好友" transform="translate(-32.000000, -200.000000)">
<g id="编组-6" transform="translate(0.000000, 176.000000)">
<g id="ic_back_white" transform="translate(32.000000, 24.000000)">
<g id="ic_back_black" fill="#444444" fill-rule="nonzero">
<path d="M9.51231071,24 L23.5198286,38.7290411 C23.785378,39.0082689 23.7753168,39.4496082 23.4973187,39.7164448 L21.6255915,41.5130226 C21.3466827,41.7807332 20.9035602,41.7716553 20.6358496,41.4927466 C20.6351032,41.491969 20.6343586,41.4911896 20.6336157,41.4904085 L4.45876399,24.4823948 C4.2017544,24.2121467 4.2017544,23.7878533 4.45876399,23.5176052 L20.6336157,6.50959152 C20.900035,6.22944906 21.3431109,6.21832422 21.6232533,6.48474351 C21.6240344,6.48548634 21.6248138,6.48623097 21.6255915,6.48697741 L23.4973187,8.28355524 C23.7753168,8.55039175 23.785378,8.99173114 23.5198286,9.27095893 L9.51231071,24 L9.51231071,24 Z" id="Path-2"></path>
</g>
<rect id="矩形" x="0" y="0" width="48" height="48"></rect>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16px" height="16px" viewBox="0 0 16 16" version="1.1">
<title>清除</title>
<g id="页面-2备份" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="创建群聊" transform="translate(-1243.000000, -413.000000)">
<g id="Group-1364" transform="translate(650.000000, 343.000000)">
<g id="Group-1363" transform="translate(290.000000, 46.000000)">
<g id="Group-1358" transform="translate(0.000000, 24.000000)">
<g id="清除" transform="translate(303.000000, 0.000000)">
<path d="M0,0 L16,0 L16,16 L0,16 L0,0 Z" id="矩形"></path>
<path d="M1,8 C1,11.8659999 4.13400006,15 8,15 C11.8659999,15 15,11.8659999 15,8 C15,4.13400006 11.8659999,1 8,1 L8,1 C4.13400006,1 1,4.13400006 1,8 Z" fill="#999999"></path>
<g id="编组" transform="translate(8.000000, 8.000000) rotate(-315.000000) translate(-8.000000, -8.000000) translate(4.000000, 4.000000)" fill="#FFFFFF">
<rect id="矩形备份" transform="translate(4.000000, 4.000000) rotate(-90.000000) translate(-4.000000, -4.000000) " x="1.8189894e-12" y="3.5" width="8" height="1" rx="0.5"></rect>
<rect id="矩形备份" transform="translate(4.000000, 4.000000) rotate(-360.000000) translate(-4.000000, -4.000000) " x="0" y="3.5" width="8" height="1" rx="0.5"></rect>
</g>
<rect id="矩形" x="0" y="0" width="16" height="16"></rect>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

Before

Width:  |  Height:  |  Size: 536 B

After

Width:  |  Height:  |  Size: 536 B

Before

Width:  |  Height:  |  Size: 520 B

After

Width:  |  Height:  |  Size: 520 B

Before

Width:  |  Height:  |  Size: 783 B

After

Width:  |  Height:  |  Size: 783 B

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Before

Width:  |  Height:  |  Size: 801 B

After

Width:  |  Height:  |  Size: 801 B

Before

Width:  |  Height:  |  Size: 711 B

After

Width:  |  Height:  |  Size: 711 B

Before

Width:  |  Height:  |  Size: 513 B

After

Width:  |  Height:  |  Size: 513 B

Before

Width:  |  Height:  |  Size: 517 B

After

Width:  |  Height:  |  Size: 517 B

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before

Width:  |  Height:  |  Size: 937 B

After

Width:  |  Height:  |  Size: 937 B

Before

Width:  |  Height:  |  Size: 647 B

After

Width:  |  Height:  |  Size: 647 B

@@ -1,27 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16px" height="16px" viewBox="0 0 16 16" version="1.1">
<title>编组 14</title>
<defs>
<filter x="-10.6%" y="-5.4%" width="121.2%" height="110.9%" filterUnits="objectBoundingBox" id="filter-1">
<feOffset dx="0" dy="7" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="10" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0" type="matrix" in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix>
<feMerge>
<feMergeNode in="shadowMatrixOuter1"></feMergeNode>
<feMergeNode in="SourceGraphic"></feMergeNode>
</feMerge>
</filter>
</defs>
<g id="new" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="自定义消息" transform="translate(-458.000000, -318.000000)">
<g id="编组-32" filter="url(#filter-1)" transform="translate(44.000000, 60.000000)">
<g id="编组-24" transform="translate(30.000000, 250.000000)">
<g id="编组-14" transform="translate(384.000000, 8.000000)">
<circle id="椭圆形" fill="#006EFF" fill-rule="nonzero" cx="8" cy="8" r="8"></circle>
<polyline id="路径-4" stroke="#FFFFFF" stroke-width="2" transform="translate(8.042641, 6.242641) rotate(-315.000000) translate(-8.042641, -6.242641) " points="6.04264069 10.2426407 10.0426407 10.2426407 10.0426407 2.24264069"></polyline>
</g>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 281 B

After

Width:  |  Height:  |  Size: 281 B

+2 -2
View File
@@ -1,4 +1,4 @@
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0"><link rel="icon" href="faviconnew.png"><title>即时通信</title><link href="css/vendors~app.03806786.css" rel="stylesheet"><link href="css/app.0de947d6.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but 腾讯云即时通信 Web-IM doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="./TCaptcha.js"></script><script src="./aegis.min.js"></script><script>/**
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0"><link rel="icon" href="faviconnew.png"><title>即时通信</title><link href="css/vendors~app.28a73048.css" rel="stylesheet"><link href="css/app.7113887a.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but 腾讯云即时通信 Web-IM doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="./TCaptcha.js"></script><script src="./aegis.min.js"></script><script>/**
* 根据基础字体大小 和 效果图宽度设置 根节点字体大小
* @param baseFontSize 浏览器默认字体大小 [注]浏览器最小字体为12像素,所以该值必需大于等于12
* @param baseWidth 设计稿的尺寸
@@ -53,4 +53,4 @@
},
false
);
};</script><script src="js/vendors~app.de88239f.js"></script><script src="js/app.8ff38855.js"></script></body></html>
};</script><script src="js/vendors~app.b38bf4ff.js"></script><script src="js/app.2f662ea4.js"></script></body></html>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -3,7 +3,7 @@
<BasicModal v-bind="$attrs" @register="register" :title="modalTitle" width="1200px" @ok="handleOk" destroyOnClose @visible-change="visibleChange">
<a-row :gutter="10">
<a-col :md="7" :sm="24">
<a-card :style="{ minHeight: '613px', overflow: 'auto' }">
<a-card :style="{ height: '613px', overflowY: 'auto' }">
<!--组织机构-->
<BasicTree
ref="treeRef"
+6 -6
View File
@@ -45,7 +45,7 @@
import { getToken } from '/@/utils/auth';
import { useLoading } from '/@/components/Loading';
import { useGlobSetting } from '/@/hooks/setting';
const { viteOutUrl } = useGlobSetting();
const { viteOutUrl, apiUrl } = useGlobSetting();
export default defineComponent({
name: 'BasicMenu',
@@ -130,16 +130,16 @@
async function handleMenuClick({ item, key }: { item: any; key: string; keyPath: string[] }) {
if (item.title === '健康银行') {
open();
const url = viteOutUrl;
console.log(url);
console.log(useGlobSetting());
await defHttp
.get({
url: '/health-system/api/sys/encryptInfo',
params: {
str: {
scheme: url.split('://')[0],
host: url.split('://')[1],
scheme: apiUrl.split('://')[0],
host:
apiUrl.split('://')[1].indexOf(':') !== -1
? apiUrl.split('://')[1].substring(0, apiUrl.split('://')[1].indexOf(':'))
: apiUrl.split('://')[1],
tokenF: getToken(),
},
},
+1 -1
View File
@@ -20,7 +20,7 @@
fontSize: props.size ?? '30px',
opacity: 0.5,
transition: 'opacity 0.5s',
display: 'none',
display: 'block',
});
const bodyStyle = ref({
@@ -102,6 +102,7 @@ export const formSchema: FormSchema[] = [
field: 'image',
component: 'JImageUpload',
componentProps: {
bizPath: 'img',
fileMax: 1,
},
},
@@ -266,6 +266,8 @@ export const formSchema: FormSchema[] = [
component: 'JImageUpload',
// rules: [{ required: true, message: '请选择头像' }],
componentProps: {
text: '上传头像',
bizPath: 'avatar',
//@ts-ignore
maxCount: 1,
},
@@ -190,6 +190,8 @@ export const formSchema: FormSchema[] = [
label: '头像',
component: 'JImageUpload',
componentProps: {
text: '上传头像',
bizPath: 'avatar',
// @ts-ignore
maxCount: 1,
},
@@ -169,6 +169,7 @@ export const formSchema: FormSchema[] = [
field: 'img',
component: 'JImageUpload',
componentProps: {
bizPath: 'img',
fileMax: 1,
},
rules: [{ required: false }],
+12 -1
View File
@@ -40,7 +40,7 @@
/>
<div class="bottom-top">
<div class="top-title"> <img :src="aedP" alt="" /> {{ showWindowInfo?.name }} </div>
<div class="top-title-bottom"> 距离{{ showWindowInfo?.dis ? showWindowInfo?.dis : 0 }}m </div>
<div class="top-title-bottom"> 距离{{ formatDistance(showWindowInfo?.dis) }} </div>
<div class="top-title-describe"> {{ showWindowInfo?.installAddress ? showWindowInfo?.installAddress : '无' }} </div>
<div class="table-list">
<div class="label-d"> 设备厂家 </div>
@@ -411,6 +411,17 @@
window.open(getFileAccessHttpUrl(v), '_blank');
}
/**
* 格式化距离:超过1000米换算为千米,保留两位小数
*/
function formatDistance(dis) {
if (!dis) return '0m';
if (dis >= 1000) {
return (dis / 1000).toFixed(2) + 'km';
}
return dis + 'm';
}
function getName(val, list) {
if (!val && val !== 0) return '';
for (let i = 0; i < list.length; i++) {
@@ -306,6 +306,7 @@ export const getFormSchema = () => {
component: 'JUpload',
componentProps: () => {
return {
bizPath: 'video',
maxCount: 1,
accept: '.mp4,video/mp4',
tipText: '支持MP4格式,最大200M',
@@ -319,6 +320,7 @@ export const getFormSchema = () => {
component: 'JUpload',
componentProps: () => {
return {
bizPath: 'bizfile',
maxCount: 1,
accept: 'application/pdf',
tipText: '仅支持PDF格式文件,最大200M',
@@ -212,17 +212,17 @@
const [registerTable, { reload, getForm, getDataSource, setTableData }] = tableContext;
</script>
<style scoped lang="less">
:deep(.ant-table-cell-fix-left, .ant-table-cell-fix-right) {
position: relative;
border-bottom: none !important;
&:after {
position: absolute;
content: '';
width: 100%;
top: 0;
left: 0;
border-bottom: 1px solid #f0f0f0;
}
}
//:deep(.ant-table-cell-fix-left, .ant-table-cell-fix-right) {
// position: relative;
// //border-bottom: none !important;
// border-bottom: 2px solid #f0f0f0 !important;
// &:after {
// position: absolute;
// content: '';
// width: 100%;
// top: 0;
// left: 0;
// border-bottom: 1px solid #f0f0f0;
// }
//}
</style>
+7 -1
View File
@@ -172,7 +172,13 @@
loadingVisible.value = false;
};
window.onmessage = async (msg) => {
const result = JSON.parse(msg.data);
if (!msg.data || typeof msg.data !== 'string') return;
let result: any;
try {
result = JSON.parse(msg.data);
} catch (e) {
return;
}
switch (result.code) {
case 'closeLoading':
closeLoading();
@@ -141,6 +141,8 @@ export const formSchema = function (showGoodAt: boolean): FormSchema[] {
component: 'JImageUpload',
required: true,
componentProps: () => ({
text: '上传头像',
bizPath: 'avatar',
maxCount: 1,
}),
},
@@ -7,8 +7,8 @@
</BasicForm>
<template #footer v-if="title !== '查看'">
<a-button @click="handleCanel">取消</a-button>
<a-button type="primary" @click="handleSubmit(1)">保存并发送</a-button>
<a-button type="primary" @click="handleSubmit(2)">保存</a-button>
<a-button type="primary" :loading="submitting" :disabled="submitting" @click="handleSubmit(1)">保存并发送</a-button>
<a-button type="primary" :loading="submitting" :disabled="submitting" @click="handleSubmit(2)">保存</a-button>
</template>
</BasicModal>
<ChooseSome
@@ -35,6 +35,7 @@
// Emits声明
const emit = defineEmits(['register', 'success', 'userData']);
const isUpdate = ref(true);
const submitting = ref(false);
const [examinationModal, { openDrawer }] = useDrawer();
//设置标题
const title = ref(String);
@@ -100,6 +101,7 @@
//表单提交事件
async function handleSubmit(type: number) {
try {
submitting.value = true;
let values = await validate();
setModalProps({ confirmLoading: true });
//提交表单
@@ -109,6 +111,7 @@
//刷新列表
emit('success');
} finally {
submitting.value = false;
setModalProps({ confirmLoading: false });
}
}
@@ -23,6 +23,7 @@
format="YYYY-MM-DD"
@change="changeValue"
:allow-clear="false"
dropdownClassName="personal-data-no-other-month"
style="opacity: 0; z-index: 99; position: absolute; top: 0; left: 0"
>
<template #dateRender="{ current }">
@@ -47,7 +48,7 @@
</BasicModal>
</template>
<script setup lang="ts" name="personalDataModal">
import { computed, ref, watch } from 'vue';
import { computed, ref, watch, onMounted, onUnmounted, nextTick } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import AllLook from '/@/views/healthMonitor/healMonitorManage/monitorToll/userInfo/componets/allLook.vue';
import { getDetail, userDataDayByMonth } from '/@/views/healthMonitor/healMonitorManage/monitorToll/personalData/personalData.api';
@@ -59,11 +60,14 @@
const userId = ref('');
const haveInfo = ref('');
const nowDate = ref(dayjs());
const loadedYear = ref(dayjs().format('YYYY'));
const isRight = computed(() => dayjs(nowDate.value).format('YYYY-MM-DD') != dayjs().format('YYYY-MM-DD'));
//表单赋值
const [registerModal, { setModalProps }] = useModalInner(async (data) => {
userInfo.value = data.record;
userId.value = data.record.userId;
// 重置已加载年份,避免上次切换年份的残留状态
loadedYear.value = dayjs().format('YYYY');
await userDataDayByMonth({ userId: data.record.userId, year: dayjs().format('YYYY') }).then((res) => {
let year = dayjs().format('YYYY');
let month = '';
@@ -94,6 +98,8 @@
function getDisabled(current) {
let flag = false;
// 年份不匹配时不渲染 bgc
if (dayjs(current).format('YYYY') !== loadedYear.value) return false;
for (let i = 0; i < Object.keys(haveInfo.value).length; i++) {
if (Object.keys(haveInfo.value)[i] == dayjs(current).format('MM') * 1) {
@@ -148,6 +154,31 @@
function changeValue() {
getInfo();
}
// 加载指定年份的 bgc 标记数据
async function loadYearData(year: string) {
if (year === loadedYear.value) return;
await userDataDayByMonth({ userId: userId.value, year }).then((res) => {
haveInfo.value = res;
loadedYear.value = year;
});
}
// 监听面板内点击,DOM 更新后从年份按钮读取当前展示的年份
function onPickerPanelClick(e: MouseEvent) {
const panel = document.querySelector('.personal-data-no-other-month');
if (!panel?.contains(e.target as Node)) return;
nextTick(() => {
const yearBtn = panel.querySelector('.ant-picker-year-btn');
if (!yearBtn) return;
// 按钮文本可能为 "2024年" 或 "2024",提取4位数字
const year = yearBtn.textContent?.replace(/[^0-9]/g, '').slice(0, 4) || '';
if (year.length === 4) loadYearData(year);
});
}
onMounted(() => document.addEventListener('click', onPickerPanelClick));
onUnmounted(() => document.removeEventListener('click', onPickerPanelClick));
</script>
<style scoped lang="less">
@@ -185,3 +216,11 @@
cursor: pointer !important;
}
</style>
<style>
/* 隐藏日历面板中非当前月份的日期格,仅对该 picker 生效 */
.personal-data-no-other-month .ant-picker-cell:not(.ant-picker-cell-in-view) {
visibility: hidden;
pointer-events: none;
}
</style>
@@ -3,6 +3,7 @@ import { message } from 'ant-design-vue';
import { allSecondaryDepartsNew, getThirdDepartsNew } from '/@/utils/system/api';
import moment from 'moment';
import dayjs from 'dayjs';
import { h } from 'vue';
export const columns: BasicColumn[] = [
{
@@ -133,6 +134,10 @@ export const columnsNew: BasicColumn[] = [
{
title: '单位名称',
dataIndex: ['orgCodeName'],
customRender: ({ text, record }) => {
const isRed = record?.orgCode?.length === 3;
return h('span', { style: isRed ? { color: 'red' } : {} }, text);
},
},
{
title: '部门名称',
@@ -88,20 +88,23 @@
const [registerTable, { reload, getForm }] = tableContext;
function getTableAction(record: any) {
let orgCodeLenth = record?.orgCode?.length;
let flag = record?.orgCodeLeafName == '-';
return [
{
label: '明细',
onClick: handleDetail.bind(null, record),
disabled: orgCodeLenth < 6,
},
{
label: '明细导出',
onClick: handleExport.bind(null, record),
disabled: orgCodeLenth < 6,
},
{
label: '周报',
onClick: handleWeekReport.bind(null, record),
disabled: !flag,
disabled: !flag || orgCodeLenth < 6,
},
];
}
@@ -105,7 +105,7 @@
// orgCodeSecond:data.record?.orgCode
});
bindUserId.value = data.record?.bindUserId;
paramsInfo.value = { orgCode: data.record?.orgCode };
paramsInfo.value = { orgCode: 'A01' };
await clearValidate();
// 隐藏底部时禁用整个表单
await setProps({ disabled: !data?.showFooter });
@@ -211,21 +211,16 @@ export const formSchema: FormSchema[] = [
field: 'deptId',
required: true,
component: 'ApiSelect',
componentProps: ({ formModel }) => {
const { getVal: getVal1, disabled: disabled1 } = initD();
getVal1('id');
defaultValue: '1683768826307096578',
show: false,
componentProps: () => {
return {
api: allSecondaryDepartsNew,
resultField: 'result',
labelField: 'departName',
immediate: true,
valueField: 'id',
disabled: disabled1,
afterFetch: (res: any) => {
if (res.length === 1) {
formModel.deptId = res[0].id;
}
},
disabled: true,
getPopupContainer: () => document.body,
showSearch: true,
filterOption: (input: string, option: any): boolean => {
@@ -326,40 +321,40 @@ export const rkFormSchema: FormSchema[] = [
required: true,
slot: 'file',
},
{
label: '单位名称',
field: 'deptId',
component: 'ApiSelect',
required: true,
componentProps: ({ formModel, schema }) => {
const { getVal, disabled } = initD();
getVal('id');
return {
api: allSecondaryDepartsNew,
resultField: 'list',
labelField: 'departName',
valueField: 'id',
immediate: true,
onChange: (val: any) => {
if (val) {
formModel['orgId'] = '';
}
},
onDeselect: () => {
formModel.deptId = '';
formModel['orgId'] = '';
},
showSearch: true,
filterOption: (input: string, option: any): boolean => {
const str: string = input.toLowerCase();
return option.label.toLowerCase().indexOf(str) >= 0;
},
disabled: disabled,
getPopupContainer: () => document.body,
};
},
},
{
// {
// label: '单位名称',
// field: 'deptId',
// component: 'ApiSelect',
// required: true,
// componentProps: ({ formModel, schema }) => {
// const { getVal, disabled } = initD();
// getVal('id');
// return {
// api: allSecondaryDepartsNew,
// resultField: 'list',
// labelField: 'departName',
// valueField: 'id',
// immediate: true,
// onChange: (val: any) => {
// if (val) {
// formModel['orgId'] = '';
// }
// },
// onDeselect: () => {
// formModel.deptId = '';
// formModel['orgId'] = '';
// },
// showSearch: true,
// filterOption: (input: string, option: any): boolean => {
// const str: string = input.toLowerCase();
// return option.label.toLowerCase().indexOf(str) >= 0;
// },
// disabled: disabled,
// getPopupContainer: () => document.body,
// };
// },
// },
/*{
label: '部门名称',
field: 'orgId',
component: 'ApiSelect',
@@ -390,7 +385,7 @@ export const rkFormSchema: FormSchema[] = [
};
},
show: false,
},
},*/
];
// 绑定导入
export const bindUserFormSchema: FormSchema[] = [
@@ -726,6 +721,11 @@ export const mColumns: BasicColumn[] = [
dataIndex: 'realname',
align: 'center',
},
{
title: '单位名称',
dataIndex: ['secondDepart', 'departName'],
align: 'center',
},
{
title: '部门名称',
dataIndex: ['depart', 'departName'],
@@ -737,7 +737,7 @@ export const mColumns: BasicColumn[] = [
align: 'center',
},
];
export const mSearchFormSchema = (orgCode) => {
export const mSearchFormSchema = (orgCode = 'orgCode', orgCode1 = 'orgCode1', threeOrgCode = 'threeOrgCode') => {
const schemaInfo: FormSchema[] = [
{
label: '员工姓名',
@@ -746,33 +746,66 @@ export const mSearchFormSchema = (orgCode) => {
},
{
label: '单位',
field: 'orgCode',
component: 'Input',
defaultValue: orgCode,
show: false,
label: '单位名称',
field: orgCode1,
component: 'ApiSelect',
componentProps: ({ formModel, schema }) => {
return {
api: allSecondaryDepartsNew,
resultField: 'list',
labelField: 'departName',
valueField: 'orgCode',
placeholder: '请选择单位',
showSearch: true,
filterOption: (input: string, option: any): boolean => {
const str: string = input.trim().toLowerCase();
return option.departName.toLowerCase().indexOf(str) >= 0;
},
onChange: (val) => {
// 选中单位时,orgCode 赋值为单位的 orgCode,并清空部门
formModel[orgCode] = val || '';
formModel[threeOrgCode] = '';
},
onDeselect: () => {
formModel[orgCode] = '';
formModel[orgCode1] = '';
formModel[threeOrgCode] = '';
},
};
},
},
{
label: '部门名称',
field: 'threeOrgCode',
field: threeOrgCode,
component: 'ApiSelect',
componentProps: ({ formModel }) => {
console.log(formModel, '11111111111');
return {
api: getThirdDepartsNew,
resultField: 'list',
labelField: 'departName',
params: {
idOrCode: formModel?.orgCode || '12313',
},
valueField: 'orgCode',
placeholder: '请选择部门',
showSearch: true,
params: {
idOrCode: formModel[orgCode1] || '12313',
},
immediate: true,
style: {
width: '195px',
},
onChange: (val) => {
// 选中部门时覆盖 orgCode,清空时回退到单位的 orgCode
formModel[orgCode] = val || formModel[orgCode1] || '';
},
};
},
},
{
label: '',
field: orgCode,
component: 'Input',
show: false,
},
{
label: '员工编号',
field: 'workNo',
+1 -1
View File
@@ -73,7 +73,7 @@ export const formSchema: FormSchema[] = [
dynamicDisabled: ({ values }) => {
return !!values.id;
},
dynamicRules: ({ model, schema }) => rules.duplicateCheckRule('sys_dict', 'dict_code', model, schema, true),
dynamicRules: ({ model, schema }) => rules.duplicateCheckRule('QH_SYS_DICT', 'dict_code', model, schema, true),
},
{
label: '描述',
@@ -77,7 +77,7 @@ export const formSchemas: FormSchema[] = [
field: 'templateCode',
component: 'Input',
dynamicRules: ({ model, schema }) => {
return [...rules.duplicateCheckRule('sys_sms_template', 'template_code', model, schema, true)];
return [...rules.duplicateCheckRule('QH_SYS_SMS_TEMPLATE', 'template_code', model, schema, true)];
},
// 编辑模式下不可修改编码
dynamicDisabled: (params) => !!params.values.id,
@@ -74,6 +74,8 @@ export const searchFormSchema: FormSchema[] = [
},
];
//表单数据
// @ts-ignore
// @ts-ignore
export const formSchema: FormSchema[] = [
{
label: '序号',
@@ -91,6 +93,10 @@ export const formSchema: FormSchema[] = [
label: '图片',
field: 'photoUrl',
component: 'JImageUpload',
componentProps: {
bizPath: 'img',
maxCount: 1,
},
rules: [{ required: true, message: '请上传图片' }],
},
{
@@ -311,7 +311,7 @@ export const formSchema: (isUpdate: boolean) => FormSchema[] = (isUpdate) => {
};
},
dynamicRules: ({ model, schema }) => {
let rule = rules.duplicateCheckRuleAndDelFlag('health_user_employee_ex', 'emp_sysno', 'false', model, schema, false);
let rule = rules.duplicateCheckRuleAndDelFlag('QH_HLT_USER_EMPLOYEE_EX', 'EMP_SYSNO', 'false', model, schema, false);
rule[0] = { ...rule[0], required: false };
return rule;
},
@@ -330,6 +330,8 @@ export const formSchema: (isUpdate: boolean) => FormSchema[] = (isUpdate) => {
field: 'avatar',
component: 'JImageUpload',
componentProps: {
text: '上传头像',
bizPath: 'avatar',
maxCount: 1,
},
},
@@ -207,6 +207,8 @@ export const formSchema: FormSchema[] = [
label: '头像',
component: 'JImageUpload',
componentProps: {
text: '上传头像',
bizPath: 'avatar',
maxCount: 1,
},
},
@@ -141,6 +141,8 @@ export const formSchema = function (showGoodAt: boolean): FormSchema[] {
component: 'JImageUpload',
required: true,
componentProps: () => ({
text: '上传头像',
bizPath: 'avatar',
maxCount: 1,
}),
},
+4 -4
View File
@@ -219,7 +219,7 @@ export const formSchema: FormSchema[] = [
},
dynamicRules: ({ model, schema }) => {
if (model.id) {
return rules.duplicateCheckRule('sys_user', 'username', model, schema, true);
return rules.duplicateCheckRule('QH_SYS_USER', 'username', model, schema, true);
} else {
return Promise.resolve();
}
@@ -266,7 +266,7 @@ export const formSchema: FormSchema[] = [
field: 'workNo',
required: true,
component: 'Input',
dynamicRules: ({ model, schema }) => rules.duplicateCheckRule('sys_user', 'work_no', model, schema, true),
dynamicRules: ({ model, schema }) => rules.duplicateCheckRule('QH_SYS_USER', 'work_no', model, schema, true),
},
{
label: '职务',
@@ -379,7 +379,7 @@ export const formSchema: FormSchema[] = [
field: 'email',
component: 'Input',
dynamicRules: ({ model, schema }) => {
return [{ ...rules.duplicateCheckRule('sys_user', 'email', model, schema, true)[0] }, { ...rules.rule('email', false)[0] }];
return [{ ...rules.duplicateCheckRule('QH_SYS_USER', 'email', model, schema, true)[0] }, { ...rules.rule('email', false)[0] }];
},
},
{
@@ -388,7 +388,7 @@ export const formSchema: FormSchema[] = [
component: 'Input',
dynamicRules: ({ model, schema }) => {
return [
{ ...rules.duplicateCheckRule('sys_user', 'phone', model, schema, true)[0] },
{ ...rules.duplicateCheckRule('QH_SYS_USER', 'phone', model, schema, true)[0] },
{ pattern: /^1[3456789]\d{9}$/, message: '手机号码格式有误' },
];
},
@@ -35,7 +35,7 @@
const validatorRules: Record<string, Rule[]> = {
email: [
{ ...rules.duplicateCheckRule('sys_user', 'email', formState, { label: '邮箱' })[0] },
{ ...rules.duplicateCheckRule('QH_SYS_USER', 'email', formState, { label: '邮箱' })[0] },
{ required: true, type: 'email', message: '邮箱格式不正确' },
],
};
@@ -40,7 +40,7 @@
const validatorRules: Record<string, Rule[]> = {
phone: [
{ ...rules.duplicateCheckRule('sys_user', 'phone', formState, { label: '手机号' })[0] },
{ ...rules.duplicateCheckRule('QH_SYS_USER', 'phone', formState, { label: '手机号' })[0] },
{ pattern: /^1[3456789]\d{9}$/, message: '手机号码格式有误' },
],
smscode: [{ required: true, message: '请输入验证码' }],
@@ -154,6 +154,7 @@ export const itemFormSchema: FormSchema[] = [
component: 'JUpload',
componentProps: () => {
return {
bizPath: 'appfile',
maxCount: 1,
};
},