Compare commits

...

12 Commits

Author SHA1 Message Date
08917db45b feat: 扩展问卷问题管理权限,支持问卷管理员权限
- 后端:PrisonQuestionController 接口增加 prison:questionnaire:update 和 prison:questionnaire:query 权限判断
- 前端:QuestionList.vue 按钮增加 prison:questionnaire:update 权限判断
- 允许拥有问卷模板管理权限的用户也能管理问卷问题
2026-01-28 11:50:34 +08:00
5b41d2b23d fix: 导入缺失的ElMessage组件
修复 EvaluationTemplateForm.vue 中 message 未定义的问题
2026-01-28 10:46:15 +08:00
44fa196bd7 fix(frontend): 修复刑期总天数显示错误
- 前端使用后端返回的 sentenceDays 字段而非 servedDays
- 修复后刑期总天数显示正确(1276天而非错误的743天)
2026-01-27 12:11:53 +08:00
13d86f4707 优化 InfoCard 刑期显示:将'刑期起/止日'改为'刑期'并突出显示总天数 2026-01-27 12:05:52 +08:00
0ba25e3492 Revert "fix(dashboard): 修复剩余刑期天数计算逻辑不一致问题"
This reverts commit ae0493428efbb553fa9573cd632187bf2d013a0b.
2026-01-27 11:57:32 +08:00
ae0493428e fix(dashboard): 修复剩余刑期天数计算逻辑不一致问题
- 前端直接使用后端返回的remainingDays,不再重新计算
- 添加TypeScript接口missing的remainingDays字段定义
- 修复前后端数据不一致问题(差异可达25天)

分析发现:前端用"总刑期-已服刑"计算,后端用"当前日期到释放日期"计算
2026-01-27 11:55:56 +08:00
4e65bb4300 refactor(dashboard): 移除RecentRewardsPunishments组件的过滤筛选功能
- 移除filter-tabs过滤标签UI
- 移除filterTabs、activeFilter、filteredList逻辑
- 直接显示所有数据,不再按类型过滤
- 简化组件功能

参考用户要求:不需要进行过滤筛选
2026-01-27 11:26:19 +08:00
3793d64d3c style(dashboard): 调整Dashboard为半透明背景样式
- 左侧区域、右侧区域、底部模块改为半透明背景
- 使用 rgba(45, 65, 131, 0.6) 实现半透明效果
- 保持原有的边框和文字样式

参考计划: .sisyphus/plans/dashboard-center-update.md 布局调整要求
2026-01-27 11:20:44 +08:00
a65d4e9280 fix(dashboard): 修改中间区域为对称布局(上1下2排列)
- 左侧:累计服刑天数(上1)+ 累计违规次数、累计表扬次数(下2)
- 右侧:剩余刑期天数(上1)+ 累计扣分次数、累计加分次数(下2)
- 调整CSS样式(top-field高度50%)
- 确保左右布局对称美观

参考计划: .sisyphus/plans/dashboard-center-update.md 布局要求
2026-01-27 11:13:39 +08:00
9a3044147b feat(dashboard): 修改中间区域为纵向3字段布局
- 左侧区域:累计服刑天数、累计违规次数、累计表扬次数
- 右侧区域:剩余刑期天数、累计扣分次数、累计加分次数
- 底部模块:显示占位符 '-'
- 添加CSS样式适配纵向布局(info-field-item, field-label, field-value)
- 遵循Element Plus设计规范

参考计划: .sisyphus/plans/dashboard-center-update.md Tasks 2-5
2026-01-27 10:50:21 +08:00
4bff154317 feat(dashboard): 新增累计表扬次数字段类型定义
- 在 PrisonerDashboardStatsRespVO 接口中添加 praiseCount: number
- 新增累计数据分组(violationCount, praiseDays, praiseCount, penaltyCount, rewardCount)

参考计划: .sisyphus/plans/dashboard-center-update.md Task 1
2026-01-27 10:27:54 +08:00
77b78ac64d feat(dashboard): 优化大帐统计展示
- 大帐统计改为显示账户余额,移除出入库卡片
- 柱状图展示收入和支出数据,按月份正序排列
- 奖惩记录从数据库真实查询,区分奖励和惩罚
- 修复惩罚记录显示问题(类型匹配)
- 账户余额显示在图例右侧
- 修复ESLint变量重复声明警告
2026-01-26 18:16:37 +08:00
9 changed files with 201 additions and 228 deletions

View File

@ -231,6 +231,13 @@ export interface PrisonerDashboardStatsRespVO {
riskScore: number // 风险评估分
riskLevel: number // 风险等级
// 累计数据
violationCount: number // 累计违规次数
praiseDays: string // 累计表扬天数
praiseCount: number // 累计表扬次数
penaltyCount: number // 累计扣分次数
rewardCount: number // 累计加分次数
// 中心数据
centerLeftData: CenterLeftData
centerRightData: CenterRightData

View File

@ -70,10 +70,9 @@ service.interceptors.request.use(
}
}
// 监狱系统:即使 tenantEnable 为 false也尝试获取并设置租户 ID
const tenantId = getTenantId()
if (tenantId) {
config.headers['tenant-id'] = tenantId
}
// 如果缓存中没有租户 ID使用默认值 1
const tenantId = getTenantId() || 1
config.headers['tenant-id'] = tenantId
const method = config.method?.toUpperCase()
// 防止 GET 请求缓存
if (method === 'GET') {

View File

@ -10,20 +10,19 @@
<div class="dashboard-content-top-center">
<div class="gauge-container">
<div class="dashboard-content-top-center-data">
<!-- 左侧第一个卡片 -->
<div class="info-card-item">
<div class="card-number">{{ centerLeftData.top.value }}</div>
<div class="card-label">{{ centerLeftData.top.label }}</div>
<!-- 左侧区域上1下2排列 -->
<div class="info-field-item top-field">
<div class="field-label">累计服刑天数</div>
<div class="field-value">{{ servedDays }}</div>
</div>
<!-- 左侧第二个卡片 -->
<div class="card-row">
<div class="info-card-item center-right-card-item">
<div class="card-number">{{ centerLeftData.middle.left.value }}</div>
<div class="card-label">{{ centerLeftData.middle.left.label }}</div>
<div class="info-field-item">
<div class="field-label">累计违规次数</div>
<div class="field-value">{{ violationCount }}</div>
</div>
<div class="info-card-item center-right-card-item">
<div class="card-number">{{ centerLeftData.middle.right.value }}</div>
<div class="card-label">{{ centerLeftData.middle.right.label }}</div>
<div class="info-field-item">
<div class="field-label">累计表扬次数</div>
<div class="field-value">{{ praiseCount }}</div>
</div>
</div>
</div>
@ -31,20 +30,19 @@
<GaugeChart :height="'240px'" :value="gaugeValue" :name="gaugeName" />
</div>
<div class="dashboard-content-top-center-data">
<!-- 右侧第一个卡片 -->
<div class="info-card-item">
<div class="card-number">{{ centerRightData.top.value }}</div>
<div class="card-label">{{ centerRightData.top.label }}</div>
<!-- 右侧区域上1下2排列 -->
<div class="info-field-item top-field">
<div class="field-label">剩余刑期天数</div>
<div class="field-value">{{ remainingDays }}</div>
</div>
<!-- 右侧第二个卡片 -->
<div class="card-row">
<div class="info-card-item center-right-card-item">
<div class="card-number">{{ centerRightData.middle.left.value }}</div>
<div class="card-label">{{ centerRightData.middle.left.label }}</div>
<div class="info-field-item">
<div class="field-label">累计扣分次数</div>
<div class="field-value">{{ penaltyCount }}</div>
</div>
<div class="info-card-item center-right-card-item">
<div class="card-number">{{ centerRightData.middle.right.value }}</div>
<div class="card-label">{{ centerRightData.middle.right.label }}</div>
<div class="info-field-item">
<div class="field-label">累计加分次数</div>
<div class="field-value">{{ rewardCount }}</div>
</div>
</div>
</div>
@ -85,7 +83,7 @@
</div>
<div class="dashboard-content-bottom-right">
<div class="dashboard-content-bottom-right-title">大帐统计</div>
<BarChart :height="'200px'" :data="barChartData" :card-data="barCardData" />
<BarChart :data="barChartData" :balance="balance" />
</div>
</div>
</div>
@ -171,12 +169,8 @@ const centerRightData = ref({
//
const barChartData = ref<{ category: string; monthlyStandard: number; perCapita: number }[]>([])
//
const barCardData = ref({
inProgress: 0,
toWarehouse: 0,
outWarehouse: 0
})
//
const balance = ref(0)
//
const basicInfo = ref({
@ -246,6 +240,16 @@ const rewardsPunishments = ref<{
const currentTime = ref('')
const prisonerName = ref('加载中...')
//
const servedDays = ref(0)
const violationCount = ref(0)
const praiseCount = ref(0)
//
const remainingDays = ref(0)
const penaltyCount = ref(0)
const rewardCount = ref(0)
//
const formatTime = () => {
const now = new Date()
@ -279,13 +283,14 @@ const loadData = async (prisonerId: number) => {
gaugeName.value = ''
//
const servedDays = res.servedDays || 0;
let remainingDays = 0;
const servedDaysValue = res.servedDays || 0;
servedDays.value = servedDaysValue
remainingDays.value = 0;
if (res.imprisonmentDate && res.releaseDate) {
const startDate = new Date(res.imprisonmentDate);
const endDate = new Date(res.releaseDate);
const totalDays = Math.floor((endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24));
remainingDays = Math.max(0, totalDays - servedDays);
remainingDays.value = Math.max(0, totalDays - servedDaysValue);
}
// -
@ -305,6 +310,10 @@ const loadData = async (prisonerId: number) => {
console.error('获取计分考核数据失败:', error)
}
//
penaltyCount.value = totalPenaltyCount
rewardCount.value = totalRewardCount
// -
let totalViolationCount = 0
try {
@ -319,6 +328,10 @@ const loadData = async (prisonerId: number) => {
console.error('获取狱情收集数据失败:', error)
}
//
violationCount.value = totalViolationCount
praiseCount.value = res.praiseCount || 0
//
if (res.centerLeftData) {
centerLeftData.value = {
@ -374,14 +387,8 @@ const loadData = async (prisonerId: number) => {
//
barChartData.value = res.consumptionMonthlyData || []
//
if (res.consumptionSummary) {
barCardData.value = {
inProgress: res.consumptionSummary.inProgress || 0,
toWarehouse: res.consumptionSummary.toWarehouse || 0,
outWarehouse: res.consumptionSummary.outWarehouse || 0
}
}
//
balance.value = res.balance || 0
//
basicInfo.value = {
@ -389,7 +396,7 @@ const loadData = async (prisonerId: number) => {
prisonNumber: res.prisonerNo || '',
sentenceStart: res.imprisonmentDate || '',
sentenceEnd: res.releaseDate || '',
sentenceDays: res.servedDays || 0,
sentenceDays: res.sentenceDays || 0,
age: res.age || 0,
hometown: res.nativePlace || '',
education: res.education || '',
@ -550,7 +557,7 @@ onUnmounted(() => {
.list-card-item {
width: 25%;
height: 90%;
background: #2d3d5f;
background: rgba(45, 65, 131, 0.6);
border: 1px solid rgba(56, 102, 141, 0.5);
display: flex;
padding-left: 15px;
@ -593,6 +600,55 @@ onUnmounted(() => {
justify-content: space-between;
}
//
.info-field-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 12px 16px;
background: rgba(45, 65, 131, 0.6);
border: 1px solid rgba(56, 102, 141, 0.5);
border-radius: 6px;
box-shadow: inset 0 0 10px 0 rgba(43, 65, 131, 0.3);
transition: all 0.3s ease;
&:hover {
border-color: rgba(56, 102, 141, 0.8);
box-shadow: inset 0 0 15px 0 rgba(43, 65, 131, 0.5);
}
}
// 12
.top-field {
height: 50%;
width: 100%;
}
//
.field-label {
font-size: 14px;
color: rgba(255, 255, 255, 0.85);
line-height: 1.5;
text-align: center;
white-space: nowrap;
margin-bottom: 8px;
font-weight: 500;
}
//
.field-value {
font-size: 20px;
font-weight: bold;
color: #ffffff;
line-height: 1.3;
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}
.dashboard-content-top-center-center {
width: 40%;
height: 220px;

View File

@ -1,22 +1,7 @@
<template>
<div class="supply-chart-container">
<!-- 卡片统计 -->
<div class="chart-cards">
<div class="chart-card-item">
<div class="card-value">{{ cardData.inProgress }}</div>
<div class="card-label">进行中</div>
</div>
<div class="chart-card-item">
<div class="card-value">{{ cardData.toWarehouse }}</div>
<div class="card-label">待入库</div>
</div>
<div class="chart-card-item">
<div class="card-value">{{ cardData.outWarehouse }}</div>
<div class="card-label">已出库</div>
</div>
</div>
<div class="supply-chart-container" ref="containerRef">
<!-- 柱状图 -->
<EChart :options="barOption" :height="height" />
<EChart ref="chartRef" :options="barOption" :height="height" />
</div>
</template>
@ -24,7 +9,7 @@
import type { EChartsOption } from 'echarts'
// @ts-ignore
import EChart from '@/components/Echart/src/Echart.vue'
import { computed, watch } from 'vue'
import { computed, ref, onMounted, watch } from 'vue'
defineOptions({ name: 'BarChart' })
@ -34,49 +19,45 @@ interface ChartDataItem {
perCapita: number
}
interface CardData {
inProgress: number
toWarehouse: number
outWarehouse: number
}
const props = withDefaults(
defineProps<{
width?: number
width?: number | string
height?: string
data?: ChartDataItem[]
cardData?: CardData
balance?: number
}>(),
{
width: 400,
height: '300px',
width: '100%',
data: () => [],
cardData: () => ({
inProgress: 5,
toWarehouse: 5,
outWarehouse: 5
})
balance: () => 0
}
)
const containerRef = ref<HTMLElement>()
const chartRef = ref()
//
const createChartOption = (): EChartsOption => {
const categories = props.data.map((item) => item.category)
const monthlyStandardData = props.data.map((item) => item.monthlyStandard ?? 0)
const perCapitaData = props.data.map((item) => item.perCapita ?? 0)
// 50
const maxValue = 50
const monthlyStandardBgData = categories.map((_, index) => maxValue - monthlyStandardData[index])
const perCapitaBgData = categories.map((_, index) => maxValue - perCapitaData[index])
//
const maxDataValue = Math.max(...monthlyStandardData, ...perCapitaData, 100)
// 20%
const maxValue = Math.ceil(maxDataValue * 1.2 / 100) * 100
// maxValue
const monthlyStandardBgData = categories.map((_, index) => Math.max(0, maxValue - monthlyStandardData[index]))
const perCapitaBgData = categories.map((_, index) => Math.max(0, maxValue - perCapitaData[index]))
return {
backgroundColor: 'transparent',
grid: {
left: '10%',
right: '15%',
top: '20%',
bottom: '15%',
left: '8%',
right: '8%',
top: '25%',
bottom: '18%',
containLabel: false
},
xAxis: {
@ -100,8 +81,8 @@ const createChartOption = (): EChartsOption => {
yAxis: {
type: 'value',
min: 0,
max: 50,
interval: 10,
max: maxValue,
interval: Math.ceil(maxValue / 5 / 100) * 100,
axisLine: {
show: false
},
@ -110,7 +91,8 @@ const createChartOption = (): EChartsOption => {
},
axisLabel: {
color: '#D8F0FF',
fontSize: 10
fontSize: 10,
formatter: (value: number) => value.toString()
},
splitLine: {
lineStyle: {
@ -119,17 +101,33 @@ const createChartOption = (): EChartsOption => {
}
}
},
//
legend: {
data: ['支出', '收入'],
top: '5%',
right: '10%',
data: [
{ name: '支出', icon: 'rect' },
{ name: '收入', icon: 'rect' }
],
top: '3%',
left: '8%',
textStyle: {
color: '#6D869A',
fontSize: 9
fontSize: 10
},
itemWidth: 9,
itemHeight: 9,
itemGap: 25
itemWidth: 12,
itemHeight: 8,
itemGap: 15
},
// 使 title
title: {
text: `账户余额: ${props.balance}`,
left: 'auto',
right: '8%',
top: '3%',
textStyle: {
color: '#00d4ff',
fontSize: 14,
fontWeight: 'bold'
}
},
tooltip: {
trigger: 'axis',
@ -144,7 +142,6 @@ const createChartOption = (): EChartsOption => {
},
formatter: function (params: any) {
let result = params[0].name + '<br/>'
//
params.forEach((param: any) => {
if (param.seriesName === '支出' || param.seriesName === '收入') {
result += param.marker + param.seriesName + ': ' + param.value + '<br/>'
@ -154,7 +151,7 @@ const createChartOption = (): EChartsOption => {
}
},
series: [
// -
//
{
name: '支出',
type: 'bar',
@ -165,40 +162,36 @@ const createChartOption = (): EChartsOption => {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
x2: 1,
y2: 0,
colorStops: [
{
offset: 0,
color: '#10A0F2'
},
{
offset: 1,
color: 'rgba(0, 82, 184, 0)'
}
{ offset: 0, color: '#10A0F2' },
{ offset: 0.5, color: '#0D8BD9' },
{ offset: 1, color: '#0A6EB0' }
]
}
},
borderRadius: [2, 2, 0, 0]
},
barWidth: '20%',
barGap: '20%'
barWidth: '25%',
barGap: '30%'
},
// -
//
{
name: '支出底色',
type: 'bar',
stack: 'monthly',
data: monthlyStandardBgData,
itemStyle: {
color: '#38668D70'
color: 'rgba(56, 102, 141, 0.3)'
},
barWidth: '20%',
barGap: '20%',
barWidth: '25%',
barGap: '30%',
silent: true,
tooltip: {
show: false
}
},
//
//
{
name: '收入',
type: 'bar',
@ -209,33 +202,30 @@ const createChartOption = (): EChartsOption => {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
x2: 1,
y2: 0,
colorStops: [
{
offset: 0,
color: '#FFA58D'
},
{
offset: 1,
color: 'rgba(87, 140, 205, 0)'
}
{ offset: 0, color: '#FFA58D' },
{ offset: 0.5, color: '#E88F5A' },
{ offset: 1, color: '#D07530' }
]
}
},
borderRadius: [2, 2, 0, 0]
},
barWidth: '20%',
barGap: '80%'
barWidth: '25%',
barGap: '30%'
},
//
{
name: '收入底色',
type: 'bar',
stack: 'perCapita',
data: perCapitaBgData,
itemStyle: {
color: '#38668D70'
color: 'rgba(56, 102, 141, 0.3)'
},
barWidth: '20%',
barGap: '80%',
barWidth: '25%',
barGap: '30%',
silent: true,
tooltip: {
show: false
@ -247,15 +237,6 @@ const createChartOption = (): EChartsOption => {
//
const barOption = computed(() => createChartOption())
//
watch(
() => [props.data, props.cardData],
() => {
// computed
},
{ deep: true }
)
</script>
<style scoped lang="scss">
@ -265,30 +246,4 @@ watch(
display: flex;
flex-direction: column;
}
.chart-cards {
display: flex;
justify-content: space-around;
flex-shrink: 0;
}
.chart-card-item {
text-align: center;
padding: 4px;
background: rgba(56, 102, 141, 0.3);
border-radius: 8px;
min-width: 100px;
.card-value {
font-size: 1.6vh;
font-weight: bold;
color: #00d4ff;
margin-bottom: 4px;
}
.card-label {
font-size: 1.5vh;
color: rgba(255, 255, 255, 0.8);
}
}
</style>

View File

@ -11,7 +11,7 @@
<div class="info-tag">{{ basicInfo.district }}</div>
<div class="info-tag">狱政编号: {{ basicInfo.prisonNumber }}</div>
<div class="info-tag">
刑期/止日{{ basicInfo.sentenceStart }}---{{ basicInfo.sentenceEnd }} {{
刑期{{ basicInfo.sentenceStart }} --- {{ basicInfo.sentenceEnd }} 总天数{{
basicInfo.sentenceDays
}}
</div>

View File

@ -2,18 +2,7 @@
<div class="rewards-punishments-container">
<!-- 标题栏 -->
<div class="rewards-header">
<span class="header-title">近期奖惩</span>
<div class="filter-tabs">
<div
v-for="tab in filterTabs"
:key="tab.value"
class="filter-tab"
:class="{ active: activeFilter === tab.value }"
@click="activeFilter = tab.value"
>
{{ tab.label }}
</div>
</div>
<span class="header-title">风险评估</span>
</div>
<!-- 时间线列表 -->
@ -21,7 +10,7 @@
<div class="timeline-content">
<div class="timeline-line"></div>
<div class="timeline-items">
<div v-for="(item, index) in filteredList" :key="index" class="timeline-item">
<div v-for="(item, index) in listData" :key="index" class="timeline-item">
<div class="timeline-dot" :class="item.type"></div>
<div class="timeline-card">
<div class="card-type" :class="item.type">{{ item.typeText }}</div>
@ -35,7 +24,7 @@
</template>
<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { ref, watch } from 'vue'
defineOptions({ name: 'RecentRewardsPunishments' })
@ -46,29 +35,9 @@ interface RewardPunishmentItem {
content: string //
}
//
const filterTabs = [
{ label: '全部', value: 'all' },
{ label: '奖励记录', value: 'reward' },
{ label: '惩罚记录', value: 'punishment' }
]
const activeFilter = ref<string>('all')
// - 使 ref
const listData = ref<RewardPunishmentItem[]>([])
//
const filteredList = computed(() => {
if (activeFilter.value === 'all') {
return listData.value
} else if (activeFilter.value === 'reward') {
return listData.value.filter((item) => item.type === 'reward')
} else {
return listData.value.filter((item) => item.type === 'danger')
}
})
// props
const props = withDefaults(
defineProps<{
@ -118,24 +87,6 @@ watch(
color: #ffffff;
}
.filter-tabs {
display: flex;
gap: 8px;
}
.filter-tab {
padding: 6px 12px;
font-size: 12px;
color: rgba(255, 255, 255, 0.85);
background: rgba(56, 102, 141, 0.2);
border-radius: 4px;
&.active {
background: #37599d;
color: #ffffff;
}
}
// 线
.timeline-container {
flex: 1 1 0;

View File

@ -351,6 +351,10 @@ watch(
onMounted(() => {
getLoginFormCache()
getTenantByWebsite()
// ID - ID
if (!authUtil.getTenantId()) {
authUtil.setTenantId(Number(loginData.loginForm.tenantName) || 1)
}
})
</script>

View File

@ -77,6 +77,7 @@
<script lang="ts" setup>
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { EvaluationTemplateApi } from '@/api/prison/evaluation'
import { ElMessage } from 'element-plus'
defineOptions({ name: 'EvaluationTemplateForm' })

View File

@ -7,7 +7,7 @@
type="primary"
plain
@click="openForm('create')"
v-hasPermi="['prison:question:create']"
v-hasPermi="['prison:question:create', 'prison:questionnaire:update']"
>
<Icon icon="ep:plus" class="mr-5px" /> 新建问题
</el-button>
@ -15,7 +15,7 @@
type="success"
plain
@click="openPartDialog"
v-hasPermi="['prison:question:create']"
v-hasPermi="['prison:question:create', 'prison:questionnaire:update']"
>
<Icon icon="ep:folder" class="mr-5px" /> 分区管理
</el-button>
@ -24,7 +24,7 @@
plain
:disabled="checkedIds.length === 0"
@click="handleDeleteBatch"
v-hasPermi="['prison:question:delete']"
v-hasPermi="['prison:question:delete', 'prison:questionnaire:update']"
>
<Icon icon="ep:delete" class="mr-5px" /> 批量删除
</el-button>
@ -135,7 +135,7 @@
link
size="small"
@click="openForm('update', question.id)"
v-hasPermi="['prison:question:update']"
v-hasPermi="['prison:question:update', 'prison:questionnaire:update']"
>
<Icon icon="ep:edit" /> 修改
</el-button>
@ -144,7 +144,7 @@
link
size="small"
@click="handleDelete(question.id)"
v-hasPermi="['prison:question:delete']"
v-hasPermi="['prison:question:delete', 'prison:questionnaire:update']"
>
<Icon icon="ep:delete" /> 删除
</el-button>
@ -193,11 +193,11 @@
</div>
</el-form-item>
<el-form-item>
<el-button type="primary" plain :icon="Plus" @click="addPartition" v-hasPermi="['prison:question:create']">添加分区</el-button>
<el-button type="primary" plain :icon="Plus" @click="addPartition" v-hasPermi="['prison:question:create', 'prison:questionnaire:update']">添加分区</el-button>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="savePartitions" type="primary" v-hasPermi="['prison:question:update']">保存设置</el-button>
<el-button @click="savePartitions" type="primary" v-hasPermi="['prison:question:update', 'prison:questionnaire:update']">保存设置</el-button>
<el-button @click="partDialogVisible = false">取消</el-button>
</template>
</Dialog>