Compare commits
2 Commits
master
...
lm/feat/da
| Author | SHA1 | Date | |
|---|---|---|---|
| 2cc61a524d | |||
| 5883d98f51 |
@ -1,17 +1,5 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
plugins: {
|
plugins: {
|
||||||
autoprefixer: {}
|
autoprefixer: {}
|
||||||
// postcss-pxtorem 插件已禁用
|
|
||||||
// 如需响应式设计,可重新启用
|
|
||||||
// 'postcss-pxtorem': {
|
|
||||||
// rootValue: 16,
|
|
||||||
// unitPrecision: 5,
|
|
||||||
// propList: ['*'],
|
|
||||||
// selectorBlackList: [],
|
|
||||||
// replace: true,
|
|
||||||
// mediaQuery: false,
|
|
||||||
// minPixelValue: 0,
|
|
||||||
// exclude: /node_modules/i
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -535,65 +535,3 @@ export const subString = (str: string, start: number, end: number) => {
|
|||||||
}
|
}
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* HTML转义 - 防止XSS攻击
|
|
||||||
* @param str 需要转义的HTML字符串
|
|
||||||
* @returns 转义后的字符串
|
|
||||||
*/
|
|
||||||
export const escapeHtml = (str: string): string => {
|
|
||||||
if (!str) return ''
|
|
||||||
const htmlEscapes: Record<string, string> = {
|
|
||||||
'&': '&',
|
|
||||||
'<': '<',
|
|
||||||
'>': '>',
|
|
||||||
'"': '"',
|
|
||||||
"'": ''',
|
|
||||||
'/': '/',
|
|
||||||
'`': '`',
|
|
||||||
'=': '='
|
|
||||||
}
|
|
||||||
return str.replace(/[&<>"'`=/]/g, (char) => htmlEscapes[char])
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 安全的HTML显示 - 仅允许安全的HTML标签和属性
|
|
||||||
* @param html 需要处理的HTML字符串
|
|
||||||
* @returns 处理后的安全HTML字符串
|
|
||||||
*/
|
|
||||||
export const sanitizeHtml = (html: string): string => {
|
|
||||||
if (!html) return ''
|
|
||||||
|
|
||||||
// 允许的标签(只保留文本格式化的基本标签)
|
|
||||||
const allowedTags = ['p', 'br', 'b', 'i', 'u', 'strong', 'em', 'span', 'div', 'ul', 'li', 'ol']
|
|
||||||
|
|
||||||
// 允许的标签及其属性
|
|
||||||
const allowedAttributes: Record<string, string[]> = {
|
|
||||||
span: ['style'],
|
|
||||||
div: ['style']
|
|
||||||
}
|
|
||||||
|
|
||||||
// 移除所有script标签和事件属性
|
|
||||||
let sanitized = html.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
|
|
||||||
sanitized = sanitized.replace(/\s*on\w+\s*=\s*(['"])[^'"]*\1/gi, '')
|
|
||||||
sanitized = sanitized.replace(/\s*on\w+\s*=\s*[^\s>]+/gi, '')
|
|
||||||
|
|
||||||
// 只保留允许的标签
|
|
||||||
allowedTags.forEach((tag) => {
|
|
||||||
// 移除不允许的标签,保留内容
|
|
||||||
const regex = new RegExp(`<${tag}[^>]*>|</${tag}>`, 'gi')
|
|
||||||
sanitized = sanitized.replace(regex, (match) => match.toLowerCase())
|
|
||||||
})
|
|
||||||
|
|
||||||
// 移除所有其他标签
|
|
||||||
sanitized = sanitized.replace(/<[^>]+>/g, (match) => {
|
|
||||||
// 检查是否是允许的标签
|
|
||||||
const tagMatch = match.match(/^<([a-z]+)/i)
|
|
||||||
if (tagMatch && allowedTags.includes(tagMatch[1].toLowerCase())) {
|
|
||||||
return match // 保留允许的标签
|
|
||||||
}
|
|
||||||
return '' // 移除不允许的标签
|
|
||||||
})
|
|
||||||
|
|
||||||
return sanitized
|
|
||||||
}
|
|
||||||
|
|||||||
@ -198,47 +198,57 @@ const basicInfo = ref({
|
|||||||
const interviewRecords = ref<{ date: string; content: string }[]>([])
|
const interviewRecords = ref<{ date: string; content: string }[]>([])
|
||||||
|
|
||||||
// 计分考核数据
|
// 计分考核数据
|
||||||
const scoreRecords = ref<{
|
const scoreRecords = ref<
|
||||||
date: string
|
{
|
||||||
score: string
|
date: string
|
||||||
scoreType: 'positive' | 'negative'
|
score: string
|
||||||
finalScore: number
|
scoreType: 'positive' | 'negative'
|
||||||
level: 'excellent' | 'good' | 'poor'
|
finalScore: number
|
||||||
levelText: string
|
level: 'excellent' | 'good' | 'poor'
|
||||||
}[]>([])
|
levelText: string
|
||||||
|
}[]
|
||||||
|
>([])
|
||||||
|
|
||||||
// 消费记录数据
|
// 消费记录数据
|
||||||
const consumptionRecords = ref<{
|
const consumptionRecords = ref<
|
||||||
date: string
|
{
|
||||||
name: string
|
date: string
|
||||||
nameColor: string
|
name: string
|
||||||
category: string
|
nameColor: string
|
||||||
amount: number
|
category: string
|
||||||
}[]>([])
|
amount: number
|
||||||
|
}[]
|
||||||
|
>([])
|
||||||
|
|
||||||
// 汇款记录数据
|
// 汇款记录数据
|
||||||
const remittanceRecords = ref<{
|
const remittanceRecords = ref<
|
||||||
date: string
|
{
|
||||||
name: string
|
date: string
|
||||||
nameColor: string
|
name: string
|
||||||
category: string
|
nameColor: string
|
||||||
amount: number
|
category: string
|
||||||
}[]>([])
|
amount: number
|
||||||
|
}[]
|
||||||
|
>([])
|
||||||
|
|
||||||
// 关系人数据
|
// 关系人数据
|
||||||
const relationships = ref<{
|
const relationships = ref<
|
||||||
name: string
|
{
|
||||||
relate: string
|
name: string
|
||||||
color: string
|
relate: string
|
||||||
}[]>([])
|
color: string
|
||||||
|
}[]
|
||||||
|
>([])
|
||||||
|
|
||||||
// 奖惩记录数据
|
// 奖惩记录数据
|
||||||
const rewardsPunishments = ref<{
|
const rewardsPunishments = ref<
|
||||||
date: string
|
{
|
||||||
type: string
|
date: string
|
||||||
typeText: string
|
type: string
|
||||||
content: string
|
typeText: string
|
||||||
}[]>([])
|
content: string
|
||||||
|
}[]
|
||||||
|
>([])
|
||||||
|
|
||||||
// 当前时间
|
// 当前时间
|
||||||
const currentTime = ref('')
|
const currentTime = ref('')
|
||||||
@ -431,23 +441,23 @@ onUnmounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.prison-name {
|
.prison-name {
|
||||||
position: absolute;
|
position: fixed;
|
||||||
top: 12px;
|
top: 18px;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
color: white;
|
color: white;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
font-size: 28px;
|
font-size: 26px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
text-shadow: 0 2px 4px rgba(0,0,0,0.5);
|
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.current-time {
|
.current-time {
|
||||||
position: absolute;
|
position: fixed;
|
||||||
top: 18px;
|
top: 12px;
|
||||||
right: 32px;
|
right: 50px;
|
||||||
color: white;
|
color: white;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
@ -510,15 +520,15 @@ onUnmounted(() => {
|
|||||||
background: #2d3d5f;
|
background: #2d3d5f;
|
||||||
border: 1px solid rgba(56, 102, 141, 0.5);
|
border: 1px solid rgba(56, 102, 141, 0.5);
|
||||||
display: flex;
|
display: flex;
|
||||||
padding-left: 15px;
|
padding-left: 18px;
|
||||||
justify-content: start;
|
justify-content: start;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.list-card-item-icon {
|
.list-card-item-icon {
|
||||||
width: 24px;
|
width: 26px;
|
||||||
height: 24px;
|
height: 26px;
|
||||||
margin-right: 12px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
.icon-location {
|
.icon-location {
|
||||||
background: url('@/assets/imgs/dashboard/icon-location.svg') no-repeat center center;
|
background: url('@/assets/imgs/dashboard/icon-location.svg') no-repeat center center;
|
||||||
@ -537,7 +547,7 @@ onUnmounted(() => {
|
|||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
}
|
}
|
||||||
.list-card-item-value {
|
.list-card-item-value {
|
||||||
font-size: 18px;
|
font-size: 14px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
@ -563,8 +573,8 @@ onUnmounted(() => {
|
|||||||
|
|
||||||
// 信息卡片通用样式
|
// 信息卡片通用样式
|
||||||
.info-card-item {
|
.info-card-item {
|
||||||
border-radius: 4px;
|
border-radius: 2px;
|
||||||
padding: 12px 16px;
|
padding: 18px 20px;
|
||||||
box-shadow: inset 0 0 15px 0 #2b4183;
|
box-shadow: inset 0 0 15px 0 #2b4183;
|
||||||
border: 1px solid #2b4183;
|
border: 1px solid #2b4183;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -582,17 +592,17 @@ onUnmounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.card-number {
|
.card-number {
|
||||||
font-size: 20px;
|
font-size: 14px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
line-height: 1.3;
|
line-height: 1.3;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 10px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-label {
|
.card-label {
|
||||||
font-size: 14px;
|
font-size: 10px;
|
||||||
color: rgba(255, 255, 255, 0.85);
|
color: rgba(255, 255, 255, 0.65);
|
||||||
line-height: 1.3;
|
line-height: 1.3;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -637,7 +647,7 @@ onUnmounted(() => {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
.dashboard-content-bottom-right-title {
|
.dashboard-content-bottom-right-title {
|
||||||
font-size: 18px;
|
font-size: 14px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
|
|||||||
@ -155,7 +155,7 @@ watch(
|
|||||||
|
|
||||||
.consumption-records-title {
|
.consumption-records-title {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 16px;
|
font-size: 14px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
@ -186,7 +186,7 @@ watch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
.header-title {
|
.header-title {
|
||||||
font-size: 14px;
|
font-size: 13px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
@ -218,12 +218,12 @@ watch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
.record-date {
|
.record-date {
|
||||||
font-size: 12px;
|
font-size: 11px;
|
||||||
color: rgba(255, 255, 255, 0.9);
|
color: rgba(255, 255, 255, 0.9);
|
||||||
}
|
}
|
||||||
|
|
||||||
.record-name {
|
.record-name {
|
||||||
font-size: 12px;
|
font-size: 11px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
|
||||||
&.name-purple {
|
&.name-purple {
|
||||||
@ -252,12 +252,12 @@ watch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
.record-category {
|
.record-category {
|
||||||
font-size: 12px;
|
font-size: 11px;
|
||||||
color: rgba(255, 255, 255, 0.9);
|
color: rgba(255, 255, 255, 0.9);
|
||||||
}
|
}
|
||||||
|
|
||||||
.record-amount {
|
.record-amount {
|
||||||
font-size: 12px;
|
font-size: 11px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: white;
|
color: white;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
@ -268,8 +268,8 @@ watch(
|
|||||||
}
|
}
|
||||||
.relationship-item {
|
.relationship-item {
|
||||||
background: #422b1f;
|
background: #422b1f;
|
||||||
padding: 6px 12px;
|
padding: 6px 10px;
|
||||||
border-radius: 6px;
|
border-radius: 4px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
@ -296,8 +296,8 @@ watch(
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
svg {
|
svg {
|
||||||
width: 14px;
|
width: 12px;
|
||||||
height: 16px;
|
height: 13px;
|
||||||
}
|
}
|
||||||
&.icon-orange {
|
&.icon-orange {
|
||||||
color: #ffa500;
|
color: #ffa500;
|
||||||
@ -314,11 +314,9 @@ watch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
.relationship-name {
|
.relationship-name {
|
||||||
font-size: 13px;
|
font-size: 11px;
|
||||||
font-weight: 500;
|
|
||||||
}
|
}
|
||||||
.relationship-relate {
|
.relationship-relate {
|
||||||
font-size: 12px;
|
font-size: 11px;
|
||||||
opacity: 0.8;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -168,8 +168,8 @@ const props = withDefaults(
|
|||||||
}
|
}
|
||||||
|
|
||||||
.header-title {
|
.header-title {
|
||||||
font-size: 16px;
|
font-size: 14px;
|
||||||
margin-right: 6px;
|
margin-right: 2px;
|
||||||
color: white;
|
color: white;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
@ -193,8 +193,8 @@ const props = withDefaults(
|
|||||||
padding: 6px 10px;
|
padding: 6px 10px;
|
||||||
background: #3f6973;
|
background: #3f6973;
|
||||||
border: 1px solid rgba(56, 102, 141, 0.5);
|
border: 1px solid rgba(56, 102, 141, 0.5);
|
||||||
border-radius: 4px;
|
border-radius: 2px;
|
||||||
font-size: 12px;
|
font-size: 9px;
|
||||||
color: #d8f0ff;
|
color: #d8f0ff;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
@ -206,7 +206,7 @@ const props = withDefaults(
|
|||||||
}
|
}
|
||||||
|
|
||||||
.records-content-title {
|
.records-content-title {
|
||||||
font-size: 14px;
|
font-size: 10px;
|
||||||
color: #d8f0ff;
|
color: #d8f0ff;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
@ -220,7 +220,7 @@ const props = withDefaults(
|
|||||||
.info-item {
|
.info-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
font-size: 13px;
|
font-size: 10px;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,7 +268,7 @@ const props = withDefaults(
|
|||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
width: 2px;
|
width: 2px;
|
||||||
height: calc(100% + 6px);
|
height: calc(100% + 14px);
|
||||||
background: rgba(56, 102, 141, 0.5);
|
background: rgba(56, 102, 141, 0.5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -283,14 +283,14 @@ const props = withDefaults(
|
|||||||
}
|
}
|
||||||
|
|
||||||
.record-date {
|
.record-date {
|
||||||
font-size: 12px;
|
font-size: 10px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: white;
|
color: white;
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.record-text {
|
.record-text {
|
||||||
font-size: 12px;
|
font-size: 10px;
|
||||||
color: #d8f0ff;
|
color: #d8f0ff;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -113,7 +113,7 @@ watch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
.header-title {
|
.header-title {
|
||||||
font-size: 16px;
|
font-size: 14px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
@ -124,8 +124,8 @@ watch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
.filter-tab {
|
.filter-tab {
|
||||||
padding: 6px 12px;
|
padding: 4px 6px;
|
||||||
font-size: 12px;
|
font-size: 11px;
|
||||||
color: rgba(255, 255, 255, 0.85);
|
color: rgba(255, 255, 255, 0.85);
|
||||||
background: rgba(56, 102, 141, 0.2);
|
background: rgba(56, 102, 141, 0.2);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
@ -179,11 +179,11 @@ watch(
|
|||||||
// 时间线标记点
|
// 时间线标记点
|
||||||
.timeline-dot {
|
.timeline-dot {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: -6px;
|
left: -8px;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
width: 10px;
|
width: 11px;
|
||||||
height: 10px;
|
height: 11px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
border: 2px solid rgba(13, 30, 50, 0.8);
|
border: 2px solid rgba(13, 30, 50, 0.8);
|
||||||
background: rgba(13, 30, 50, 0.8);
|
background: rgba(13, 30, 50, 0.8);
|
||||||
@ -205,13 +205,12 @@ watch(
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
background: rgba(56, 102, 141, 0.15);
|
background: rgba(56, 102, 141, 0.15);
|
||||||
border: 1px solid rgba(56, 102, 141, 0.3);
|
border: 1px solid rgba(56, 102, 141, 0.3);
|
||||||
border-radius: 4px;
|
border-radius: 2px;
|
||||||
padding: 8px 12px;
|
padding: 6px 14px;
|
||||||
margin-left: 8px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-type {
|
.card-type {
|
||||||
font-size: 13px;
|
font-size: 11px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
color: rgba(255, 255, 255, 0.9);
|
color: rgba(255, 255, 255, 0.9);
|
||||||
@ -226,7 +225,7 @@ watch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
.card-description {
|
.card-description {
|
||||||
font-size: 12px;
|
font-size: 8px;
|
||||||
color: rgba(255, 255, 255, 0.7);
|
color: rgba(255, 255, 255, 0.7);
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -101,8 +101,8 @@ watch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
.header-title {
|
.header-title {
|
||||||
font-size: 16px;
|
font-size: 14px;
|
||||||
margin-right: 6px;
|
margin-right: 2px;
|
||||||
color: white;
|
color: white;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
@ -132,8 +132,8 @@ watch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
.header-cell {
|
.header-cell {
|
||||||
font-size: 13px;
|
font-size: 11px;
|
||||||
color: rgba(255, 255, 255, 0.9);
|
color: rgba(255, 255, 255, 0.85);
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -144,7 +144,7 @@ watch(
|
|||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
width: 10px;
|
width: 10px;
|
||||||
height: 10px;
|
height: 10px;
|
||||||
margin-right: 4px;
|
margin-right: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 表格主体
|
// 表格主体
|
||||||
@ -169,11 +169,11 @@ watch(
|
|||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
width: 10px;
|
width: 10px;
|
||||||
height: 10px;
|
height: 10px;
|
||||||
margin-right: 4px;
|
margin-right: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.row-cell {
|
.row-cell {
|
||||||
font-size: 13px;
|
font-size: 11px;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user