refactor: 前端重构评估模块为答题模块
主要变更: - 删除 assessment 模块前端代码 - 消费记录模块表单和列表优化 - 问卷答题记录模块扩展测评执行和统计功能 - 更新字典配置 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
fdc6bf58e0
commit
2115e4aa52
73
src/api/prison/answer/index.ts
Normal file
73
src/api/prison/answer/index.ts
Normal file
@ -0,0 +1,73 @@
|
||||
import request from '@/config/axios'
|
||||
|
||||
/** 答题记录信息 */
|
||||
export interface Answer {
|
||||
id?: number // 记录ID
|
||||
assessmentRecordId?: number // 测评记录ID
|
||||
questionId?: number // 问题ID
|
||||
questionnaireId?: number // 问卷ID
|
||||
prisonerId?: number // 罪犯ID
|
||||
questionType?: number // 问题类型:1-单选 2-多选 3-填空 4-评分 5-日期 6-数字
|
||||
answerText?: string // 答案内容
|
||||
optionIds?: string // 选项ID列表
|
||||
score?: number // 得分
|
||||
isCorrect?: boolean // 是否正确
|
||||
duration?: number // 答题用时(秒)
|
||||
creator?: string // 创建者
|
||||
createTime?: string // 创建时间
|
||||
}
|
||||
|
||||
/** 答题记录分页参数 */
|
||||
export interface AnswerPageParams {
|
||||
pageNo: number
|
||||
pageSize: number
|
||||
assessmentRecordId?: number
|
||||
questionId?: number
|
||||
questionnaireId?: number
|
||||
prisonerId?: number
|
||||
questionType?: number
|
||||
createTime?: string[]
|
||||
}
|
||||
|
||||
// 答题记录 API
|
||||
export const AnswerApi = {
|
||||
// 查询答题记录分页
|
||||
getAnswerPage: async (params: AnswerPageParams) => {
|
||||
return await request.get({ url: `/prison/answer/page`, params })
|
||||
},
|
||||
|
||||
// 查询答题记录详情
|
||||
getAnswer: async (id: number) => {
|
||||
return await request.get<Answer>({ url: `/prison/answer/get`, params: { id } })
|
||||
},
|
||||
|
||||
// 新增答题记录
|
||||
createAnswer: async (data: Answer) => {
|
||||
return await request.post<number>({ url: `/prison/answer/create`, data })
|
||||
},
|
||||
|
||||
// 修改答题记录
|
||||
updateAnswer: async (data: Answer) => {
|
||||
return await request.put<boolean>({ url: `/prison/answer/update`, data })
|
||||
},
|
||||
|
||||
// 删除答题记录
|
||||
deleteAnswer: async (id: number) => {
|
||||
return await request.delete<boolean>({ url: `/prison/answer/delete`, params: { id } })
|
||||
},
|
||||
|
||||
/** 批量删除答题记录 */
|
||||
deleteAnswerList: async (ids: number[]) => {
|
||||
return await request.post<boolean>({ url: `/prison/answer/delete-list`, data: ids })
|
||||
},
|
||||
|
||||
// 根据测评记录ID查询答题列表
|
||||
getAnswersByAssessmentRecordId: async (assessmentRecordId: number) => {
|
||||
return await request.get<Answer[]>({ url: `/prison/answer/list-by-assessment-record`, params: { assessmentRecordId } })
|
||||
},
|
||||
|
||||
// 导出答题记录 Excel
|
||||
exportAnswer: async (params: AnswerPageParams) => {
|
||||
return await request.download({ url: `/prison/answer/export-excel`, params })
|
||||
}
|
||||
}
|
||||
@ -1,56 +1,80 @@
|
||||
import request from '@/config/axios'
|
||||
import type { Dayjs } from 'dayjs';
|
||||
|
||||
/** 消费记录信息 */
|
||||
/** 消费订单分页参数 */
|
||||
export interface ConsumptionPageParams {
|
||||
pageNo: number
|
||||
pageSize: number
|
||||
prisonerNo?: string
|
||||
type?: number
|
||||
status?: number
|
||||
totalAmount?: number
|
||||
orderNo?: string
|
||||
}
|
||||
|
||||
/** 消费明细信息 */
|
||||
export interface ConsumptionDetail {
|
||||
id?: number // 明细ID
|
||||
goodsName: string // 商品名称
|
||||
goodsCode?: string // 商品编码
|
||||
goodsPrice: number // 商品单价
|
||||
goodsCount: number // 商品数量
|
||||
subtotal?: number // 小计金额
|
||||
}
|
||||
|
||||
/** 消费订单信息 */
|
||||
export interface Consumption {
|
||||
id: number; // 记录ID
|
||||
prisonerId?: number; // 罪犯ID
|
||||
prisonerNo?: string; // 罪犯编号
|
||||
type?: number; // 类型:1-存款 2-消费 3-转账
|
||||
amount?: number; // 金额
|
||||
balance: number; // 账户余额
|
||||
goodsName: string; // 商品名称
|
||||
goodsCount: number; // 商品数量
|
||||
orderNo: string; // 订单号
|
||||
tradeTime?: string | Dayjs; // 交易时间
|
||||
status?: number; // 状态:1-成功 2-失败
|
||||
remark: string; // 备注
|
||||
}
|
||||
id: number // 订单ID
|
||||
prisonerId?: number // 罪犯ID
|
||||
prisonerNo?: string // 罪犯编号
|
||||
orderNo?: string // 订单号
|
||||
type?: number // 类型:1-购物 2-餐饮 3-医疗 4-通讯 5-其他
|
||||
totalAmount?: number // 订单总金额
|
||||
balance: number // 账户余额
|
||||
tradeTime?: string // 交易时间
|
||||
status?: number // 状态:1-成功 2-失败
|
||||
remark: string // 备注
|
||||
details?: ConsumptionDetail[] // 消费明细列表
|
||||
}
|
||||
|
||||
// 消费记录 API
|
||||
// 消费订单 API
|
||||
export const ConsumptionApi = {
|
||||
// 查询消费记录分页
|
||||
getConsumptionPage: async (params: any) => {
|
||||
// 查询消费订单分页
|
||||
getConsumptionPage: async (params: ConsumptionPageParams) => {
|
||||
return await request.get({ url: `/prison/consumption/page`, params })
|
||||
},
|
||||
|
||||
// 查询消费记录详情
|
||||
// 查询消费订单详情
|
||||
getConsumption: async (id: number) => {
|
||||
return await request.get({ url: `/prison/consumption/get?id=` + id })
|
||||
return await request.get({ url: `/prison/consumption/get`, params: { id } })
|
||||
},
|
||||
|
||||
// 新增消费记录
|
||||
// 新增消费订单
|
||||
createConsumption: async (data: Consumption) => {
|
||||
return await request.post({ url: `/prison/consumption/create`, data })
|
||||
},
|
||||
|
||||
// 修改消费记录
|
||||
// 修改消费订单
|
||||
updateConsumption: async (data: Consumption) => {
|
||||
return await request.put({ url: `/prison/consumption/update`, data })
|
||||
},
|
||||
|
||||
// 删除消费记录
|
||||
// 删除消费订单
|
||||
deleteConsumption: async (id: number) => {
|
||||
return await request.delete({ url: `/prison/consumption/delete?id=` + id })
|
||||
return await request.delete({ url: `/prison/consumption/delete`, params: { id } })
|
||||
},
|
||||
|
||||
/** 批量删除消费记录 */
|
||||
/** 批量删除消费订单 */
|
||||
deleteConsumptionList: async (ids: number[]) => {
|
||||
return await request.delete({ url: `/prison/consumption/delete-list?ids=${ids.join(',')}` })
|
||||
},
|
||||
|
||||
// 导出消费记录 Excel
|
||||
exportConsumption: async (params) => {
|
||||
// 查询消费明细列表
|
||||
getConsumptionDetailList: async (consumptionId: number) => {
|
||||
return await request.get({ url: `/prison/consumption/detail-list`, params: { consumptionId } })
|
||||
},
|
||||
|
||||
// 导出消费订单 Excel
|
||||
exportConsumption: async (params: ConsumptionPageParams) => {
|
||||
return await request.download({ url: `/prison/consumption/export-excel`, params })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,15 +1,32 @@
|
||||
import request from '@/config/axios'
|
||||
|
||||
/** 问卷答题记录信息 */
|
||||
// ========== 问卷答题记录/测评记录类型 ==========
|
||||
|
||||
/** 问卷答题记录/测评记录信息 */
|
||||
export interface QuestionnaireRecord {
|
||||
id?: number // 记录ID(创建时不需要)
|
||||
id?: number // 记录ID
|
||||
questionnaireId?: number // 问卷ID
|
||||
questionnaireName?: string // 问卷名称
|
||||
prisonerId?: number // 罪犯ID
|
||||
prisonerNo?: string // 罪犯编号
|
||||
totalScore?: number // 得分
|
||||
passStatus?: number // 是否及格:0-未及格 1-及格
|
||||
answerTime?: string // 答题时间
|
||||
status?: number // 状态:1-待评估 2-已完成
|
||||
prisonerName?: string // 罪犯姓名
|
||||
status?: number // 状态:1-待测评 2-测评中 3-已完成 4-已过期 5-已取消
|
||||
startTime?: string // 开始时间
|
||||
endTime?: string // 结束时间
|
||||
deadline?: string // 截止日期
|
||||
objectiveScore?: number // 客观题得分
|
||||
subjectiveScore?: number // 主观题得分
|
||||
totalScore?: number // 总分
|
||||
passScore?: number // 及格分数
|
||||
passStatus?: number // 及格状态:1-及格 2-不及格 3-待评阅
|
||||
riskLevel?: number // 风险等级:1-高风险 2-中风险 3-低风险
|
||||
evaluatorId?: number // 评阅人ID
|
||||
evaluatorName?: string // 评阅人姓名
|
||||
evaluateTime?: string // 评阅时间
|
||||
participantCount?: number // 参与人数
|
||||
completedCount?: number // 完成人数
|
||||
duration?: number // 答题用时(秒)
|
||||
remark?: string // 备注
|
||||
createTime?: string // 创建时间
|
||||
}
|
||||
|
||||
@ -18,49 +35,156 @@ export interface QuestionnaireRecordPageParams {
|
||||
pageNo: number
|
||||
pageSize: number
|
||||
questionnaireId?: number
|
||||
questionnaireName?: string
|
||||
prisonerId?: number
|
||||
prisonerNo?: string
|
||||
totalScore?: number
|
||||
passStatus?: number
|
||||
status?: number
|
||||
answerTime?: string[]
|
||||
passStatus?: number
|
||||
riskLevel?: number
|
||||
startTime?: string[]
|
||||
endTime?: string[]
|
||||
createTime?: string[]
|
||||
}
|
||||
|
||||
// 问卷答题记录 API
|
||||
/** 发起测评请求 */
|
||||
export interface AssessmentInitiateReq {
|
||||
questionnaireId: number // 问卷模板ID
|
||||
prisonerIds: number[] // 罪犯ID列表
|
||||
deadline?: string // 截止日期
|
||||
remark?: string // 备注
|
||||
}
|
||||
|
||||
/** 答题详情项 */
|
||||
export interface AnswerItem {
|
||||
questionId: number // 问题ID
|
||||
answer?: string // 答案
|
||||
optionIds?: number[] // 选择的选项ID列表
|
||||
}
|
||||
|
||||
/** 提交答卷请求 */
|
||||
export interface AssessmentAnswerSubmitReq {
|
||||
recordId: number // 测评记录ID
|
||||
prisonerId: number // 罪犯ID
|
||||
answers: AnswerItem[] // 答题详情列表
|
||||
}
|
||||
|
||||
/** 人工评分请求 */
|
||||
export interface AssessmentManualScoreReq {
|
||||
recordId: number // 测评记录ID
|
||||
subjectiveScore: number // 主观题得分
|
||||
comment?: string // 评语
|
||||
riskLevel?: number // 风险等级:1-高风险 2-中风险 3-低风险
|
||||
}
|
||||
|
||||
/** 分数分布数据 */
|
||||
export interface ScoreDistribution {
|
||||
'0-20'?: number
|
||||
'21-40'?: number
|
||||
'41-60'?: number
|
||||
'61-80'?: number
|
||||
'81-100'?: number
|
||||
}
|
||||
|
||||
/** 风险分布数据 */
|
||||
export interface RiskDistribution {
|
||||
high?: number
|
||||
medium?: number
|
||||
low?: number
|
||||
}
|
||||
|
||||
// ========== API 对象 ==========
|
||||
|
||||
export const QuestionnaireRecordApi = {
|
||||
// 查询问卷答题记录分页
|
||||
// ========== 基础 CRUD ==========
|
||||
|
||||
/** 查询问卷答题记录分页 */
|
||||
getQuestionnaireRecordPage: async (params: QuestionnaireRecordPageParams) => {
|
||||
return await request.get({ url: `/prison/questionnaire-record/page`, params })
|
||||
},
|
||||
|
||||
// 查询问卷答题记录详情
|
||||
/** 查询问卷答题记录详情 */
|
||||
getQuestionnaireRecord: async (id: number) => {
|
||||
return await request.get<QuestionnaireRecord>({ url: `/prison/questionnaire-record/get`, params: { id } })
|
||||
},
|
||||
|
||||
// 新增问卷答题记录
|
||||
/** 新增问卷答题记录 */
|
||||
createQuestionnaireRecord: async (data: QuestionnaireRecord) => {
|
||||
return await request.post<number>({ url: `/prison/questionnaire-record/create`, data })
|
||||
},
|
||||
|
||||
// 修改问卷答题记录
|
||||
/** 修改问卷答题记录 */
|
||||
updateQuestionnaireRecord: async (data: QuestionnaireRecord) => {
|
||||
return await request.put<boolean>({ url: `/prison/questionnaire-record/update`, data })
|
||||
},
|
||||
|
||||
// 删除问卷答题记录
|
||||
/** 删除问卷答题记录 */
|
||||
deleteQuestionnaireRecord: async (id: number) => {
|
||||
return await request.delete<boolean>({ url: `/prison/questionnaire-record/delete`, params: { id } })
|
||||
},
|
||||
|
||||
/** 批量删除问卷答题记录 */
|
||||
deleteQuestionnaireRecordList: async (ids: number[]) => {
|
||||
return await request.delete<boolean>({ url: `/prison/questionnaire-record/delete-list`, params: { ids: ids.join(',') } })
|
||||
return await request.post<boolean>({ url: `/prison/questionnaire-record/delete-list`, data: ids })
|
||||
},
|
||||
|
||||
// 导出问卷答题记录 Excel
|
||||
/** 导出问卷答题记录 Excel */
|
||||
exportQuestionnaireRecord: async (params: QuestionnaireRecordPageParams) => {
|
||||
return await request.download({ url: `/prison/questionnaire-record/export-excel`, params })
|
||||
},
|
||||
|
||||
// ========== 测评执行相关 ==========
|
||||
|
||||
/** 发起测评 */
|
||||
initiateAssessment: async (data: AssessmentInitiateReq) => {
|
||||
return await request.post<number>({ url: `/prison/questionnaire-record/initiate`, data })
|
||||
},
|
||||
|
||||
/** 开始测评 */
|
||||
startAssessment: async (id: number, prisonerId: number) => {
|
||||
return await request.post<boolean>({ url: `/prison/questionnaire-record/start`, params: { id, prisonerId } })
|
||||
},
|
||||
|
||||
/** 提交答卷 */
|
||||
submitAnswer: async (data: AssessmentAnswerSubmitReq) => {
|
||||
return await request.post<boolean>({ url: `/prison/questionnaire-record/submit`, data })
|
||||
},
|
||||
|
||||
/** 结束测评 */
|
||||
finishAssessment: async (id: number) => {
|
||||
return await request.post<boolean>({ url: `/prison/questionnaire-record/finish`, params: { id } })
|
||||
},
|
||||
|
||||
/** 取消测评 */
|
||||
cancelAssessment: async (id: number) => {
|
||||
return await request.post<boolean>({ url: `/prison/questionnaire-record/cancel`, params: { id } })
|
||||
},
|
||||
|
||||
// ========== 评分相关 ==========
|
||||
|
||||
/** 自动评分 */
|
||||
autoScore: async (id: number) => {
|
||||
return await request.post<boolean>({ url: `/prison/questionnaire-record/auto-score`, params: { id } })
|
||||
},
|
||||
|
||||
/** 人工评分 */
|
||||
manualScore: async (data: AssessmentManualScoreReq) => {
|
||||
return await request.post<boolean>({ url: `/prison/questionnaire-record/manual-score`, data })
|
||||
},
|
||||
|
||||
// ========== 统计相关 ==========
|
||||
|
||||
/** 获取完成率 */
|
||||
getCompletionRate: async (assessmentRecordId: number) => {
|
||||
return await request.get<number>({ url: `/prison/questionnaire-record/completion-rate`, params: { assessmentRecordId } })
|
||||
},
|
||||
|
||||
/** 获取分数分布 */
|
||||
getScoreDistribution: async (assessmentRecordId: number) => {
|
||||
return await request.get<ScoreDistribution>({ url: `/prison/questionnaire-record/score-distribution`, params: { assessmentRecordId } })
|
||||
},
|
||||
|
||||
/** 获取风险分布 */
|
||||
getRiskDistribution: async (assessmentRecordId: number) => {
|
||||
return await request.get<RiskDistribution>({ url: `/prison/questionnaire-record/risk-distribution`, params: { assessmentRecordId } })
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,31 +1,40 @@
|
||||
import request from '@/config/axios'
|
||||
import type { Dayjs } from 'dayjs';
|
||||
|
||||
/** 危险评估分页参数 */
|
||||
export interface RiskAssessmentPageParams {
|
||||
pageNo: number
|
||||
pageSize: number
|
||||
prisonerNo?: string
|
||||
assessmentType?: number
|
||||
riskLevel?: number
|
||||
status?: number
|
||||
}
|
||||
|
||||
/** 危险评估信息 */
|
||||
export interface RiskAssessment {
|
||||
id: number; // 评估ID
|
||||
prisonerId?: number; // 罪犯ID
|
||||
prisonerNo?: string; // 罪犯编号
|
||||
assessmentType?: number; // 评估类型:1-入狱评估 2-定期评估 3-专项评估
|
||||
assessmentDate?: string | Dayjs; // 评估日期
|
||||
violenceScore: number; // 暴力倾向得分
|
||||
escapeScore: number; // 脱逃倾向得分
|
||||
suicideScore: number; // 自杀倾向得分
|
||||
totalScore: number; // 综合得分
|
||||
riskLevel?: number; // 风险等级:1-低风险 2-中风险 3-高风险 4-极高风险
|
||||
riskFactors: string; // 风险因素
|
||||
suggestions: string; // 管控建议
|
||||
assessorId: number; // 评估人ID
|
||||
assessorName: string; // 评估人姓名
|
||||
nextAssessmentDate: string | Dayjs; // 下次评估日期
|
||||
status?: number; // 状态:1-待审核 2-已通过
|
||||
remark: string; // 备注
|
||||
}
|
||||
id: number // 评估ID
|
||||
prisonerId?: number // 罪犯ID
|
||||
prisonerNo?: string // 罪犯编号
|
||||
assessmentType?: number // 评估类型:1-入狱评估 2-定期评估 3-专项评估
|
||||
assessmentDate?: string // 评估日期
|
||||
violenceScore: number // 暴力倾向得分
|
||||
escapeScore: number // 脱逃倾向得分
|
||||
suicideScore: number // 自杀倾向得分
|
||||
totalScore: number // 综合得分
|
||||
riskLevel?: number // 风险等级:1-低风险 2-中风险 3-高风险 4-极高风险
|
||||
riskFactors: string // 风险因素
|
||||
suggestions: string // 管控建议
|
||||
assessorId: number // 评估人ID
|
||||
assessorName: string // 评估人姓名
|
||||
nextAssessmentDate: string // 下次评估日期
|
||||
status?: number // 状态:1-待审核 2-已通过
|
||||
remark: string // 备注
|
||||
}
|
||||
|
||||
// 危险评估 API
|
||||
export const RiskAssessmentApi = {
|
||||
// 查询危险评估分页
|
||||
getRiskAssessmentPage: async (params: any) => {
|
||||
getRiskAssessmentPage: async (params: RiskAssessmentPageParams) => {
|
||||
return await request.get({ url: `/prison/risk-assessment/page`, params })
|
||||
},
|
||||
|
||||
@ -55,7 +64,7 @@ export const RiskAssessmentApi = {
|
||||
},
|
||||
|
||||
// 导出危险评估 Excel
|
||||
exportRiskAssessment: async (params) => {
|
||||
exportRiskAssessment: async (params: RiskAssessmentPageParams) => {
|
||||
return await request.download({ url: `/prison/risk-assessment/export-excel`, params })
|
||||
}
|
||||
}
|
||||
@ -1,28 +1,38 @@
|
||||
import request from '@/config/axios'
|
||||
import type { Dayjs } from 'dayjs';
|
||||
|
||||
/** 计分考核分页参数 */
|
||||
export interface ScorePageParams {
|
||||
pageNo: number
|
||||
pageSize: number
|
||||
prisonerNo?: string
|
||||
year?: number
|
||||
month?: number
|
||||
level?: number
|
||||
status?: number
|
||||
}
|
||||
|
||||
/** 计分考核信息 */
|
||||
export interface Score {
|
||||
id: number; // 记录ID
|
||||
prisonerId?: number; // 罪犯ID
|
||||
prisonerNo?: string; // 罪犯编号
|
||||
year?: number; // 考核年份
|
||||
month?: number; // 考核月份
|
||||
baseScore: number; // 基础分
|
||||
rewardScore: number; // 加分
|
||||
penaltyScore: number; // 扣分
|
||||
totalScore: number; // 总分
|
||||
level: number; // 考核等级:1-优秀 2-良好 3-合格 4-不合格
|
||||
assessorId: number; // 考核人ID
|
||||
assessorName: string; // 考核人姓名
|
||||
status?: number; // 状态:1-待审核 2-已通过 3-已驳回
|
||||
remark: string; // 备注
|
||||
}
|
||||
id: number // 记录ID
|
||||
prisonerId?: number // 罪犯ID
|
||||
prisonerNo?: string // 罪犯编号
|
||||
year?: number // 考核年份
|
||||
month?: number // 考核月份
|
||||
baseScore: number // 基础分
|
||||
rewardScore: number // 加分
|
||||
penaltyScore: number // 扣分
|
||||
totalScore: number // 总分
|
||||
level: number // 考核等级:1-优秀 2-良好 3-合格 4-不合格
|
||||
assessorId: number // 考核人ID
|
||||
assessorName: string // 考核人姓名
|
||||
status?: number // 状态:1-待审核 2-已通过 3-已驳回
|
||||
remark: string // 备注
|
||||
}
|
||||
|
||||
// 计分考核 API
|
||||
export const ScoreApi = {
|
||||
// 查询计分考核分页
|
||||
getScorePage: async (params: any) => {
|
||||
getScorePage: async (params: ScorePageParams) => {
|
||||
return await request.get({ url: `/prison/score/page`, params })
|
||||
},
|
||||
|
||||
@ -52,7 +62,7 @@ export const ScoreApi = {
|
||||
},
|
||||
|
||||
// 导出计分考核 Excel
|
||||
exportScore: async (params) => {
|
||||
exportScore: async (params: ScorePageParams) => {
|
||||
return await request.download({ url: `/prison/score/export-excel`, params })
|
||||
}
|
||||
}
|
||||
@ -273,5 +273,8 @@ export enum DICT_TYPE {
|
||||
PRISON_SCORE_CATEGORY = 'prison_score_category', // 考核类别:1-劳动改造 2-教育改造 3-日常行为 4-卫生纪律 5-加分项 6-扣分项
|
||||
PRISON_SCORE_TYPE = 'prison_score_type', // 考核类型:1-加分 2-扣分
|
||||
PRISON_RELEASE_STATUS = 'prison_release_status', // 释放状态:1-待释放 2-已释放 3-已取消
|
||||
PRISON_CERTIFICATE_TYPE = 'prison_certificate_type' // 证件类型:1-身份证 2-户口簿 3-其他
|
||||
PRISON_CERTIFICATE_TYPE = 'prison_certificate_type', // 证件类型:1-身份证 2-户口簿 3-其他
|
||||
PRISON_ASSESSMENT_STATUS = 'prison_assessment_status', // 测评状态:1-待测评 2-测评中 3-已完成 4-已过期
|
||||
PRISON_ASSESSMENT_PASS_STATUS = 'prison_assessment_pass_status', // 测评及格状态:1-及格 2-不及格 3-待评分
|
||||
PRISON_ASSESSMENT_ANSWER_STATUS = 'prison_assessment_answer_status' // 测评答题状态:1-待评分 2-已评分
|
||||
}
|
||||
|
||||
@ -100,7 +100,7 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||
<template #default="scope">
|
||||
{{ formatDate(scope.row.createTime) }}
|
||||
{{ dateFormatter(scope.row.createTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="120">
|
||||
@ -138,6 +138,7 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||
import { dateFormatter } from '@/utils/formatTime'
|
||||
import download from '@/utils/download'
|
||||
import { CellApi } from '@/api/prison/cell'
|
||||
import { AreaApi } from '@/api/prison/area'
|
||||
@ -168,7 +169,6 @@ const areaTreeData = ref<any[]>([])
|
||||
// 使用字典获取选项
|
||||
const statusOptions = getIntDictOptions(DICT_TYPE.PRISON_CELL_STATUS)
|
||||
|
||||
/** 加载监区树形数据 */
|
||||
const loadAreaTree = async () => {
|
||||
try {
|
||||
areaTreeData.value = await AreaApi.getAreaTree()
|
||||
@ -177,12 +177,6 @@ const loadAreaTree = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
/** 日期格式化 */
|
||||
const formatDate = (date: string | Date | undefined) => {
|
||||
if (!date) return '-'
|
||||
return new Date(date).toLocaleString('zh-CN')
|
||||
}
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
|
||||
47
src/views/prison/consumption/ConsumptionDetailDialog.vue
Normal file
47
src/views/prison/consumption/ConsumptionDetailDialog.vue
Normal file
@ -0,0 +1,47 @@
|
||||
<template>
|
||||
<Dialog title="消费明细" v-model="dialogVisible" width="600px">
|
||||
<el-table :data="detailList" v-loading="loading">
|
||||
<el-table-column label="商品名称" prop="goodsName" align="center" />
|
||||
<el-table-column label="商品编码" prop="goodsCode" align="center" width="120" />
|
||||
<el-table-column label="单价" prop="goodsPrice" align="center" width="100">
|
||||
<template #default="{ row }">
|
||||
¥{{ row.goodsPrice?.toFixed(2) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="数量" prop="goodsCount" align="center" width="80" />
|
||||
<el-table-column label="小计" prop="subtotal" align="center" width="100">
|
||||
<template #default="{ row }">
|
||||
<span class="text-primary">¥{{ row.subtotal?.toFixed(2) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<template #footer>
|
||||
<el-button @click="dialogVisible = false">关闭</el-button>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ConsumptionApi, ConsumptionDetail } from '@/api/prison/consumption'
|
||||
|
||||
defineOptions({ name: 'ConsumptionDetailDialog' })
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const loading = ref(false)
|
||||
const detailList = ref<ConsumptionDetail[]>([])
|
||||
const consumptionId = ref<number>()
|
||||
|
||||
/** 打开弹窗 */
|
||||
const open = async (id: number) => {
|
||||
consumptionId.value = id
|
||||
dialogVisible.value = true
|
||||
loading.value = true
|
||||
try {
|
||||
detailList.value = await ConsumptionApi.getConsumptionDetailList(id)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||
<Dialog :title="dialogTitle" v-model="dialogVisible" width="800px">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
@ -7,57 +7,109 @@
|
||||
label-width="100px"
|
||||
v-loading="formLoading"
|
||||
>
|
||||
<el-form-item label="罪犯ID" prop="prisonerId">
|
||||
<el-input v-model="formData.prisonerId" placeholder="请输入罪犯ID" />
|
||||
</el-form-item>
|
||||
<el-form-item label="罪犯编号" prop="prisonerNo">
|
||||
<el-input v-model="formData.prisonerNo" placeholder="请输入罪犯编号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="类型" prop="type">
|
||||
<el-select v-model="formData.type" placeholder="请选择类型">
|
||||
<el-option
|
||||
v-for="dict in getIntDictOptions(DICT_TYPE.PRISON_CONSUMPTION_TYPE)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="金额" prop="amount">
|
||||
<el-input v-model="formData.amount" placeholder="请输入金额" />
|
||||
</el-form-item>
|
||||
<el-form-item label="账户余额" prop="balance">
|
||||
<el-input v-model="formData.balance" placeholder="请输入账户余额" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品名称" prop="goodsName">
|
||||
<el-input v-model="formData.goodsName" placeholder="请输入商品名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品数量" prop="goodsCount">
|
||||
<el-input v-model="formData.goodsCount" placeholder="请输入商品数量" />
|
||||
</el-form-item>
|
||||
<el-form-item label="订单号" prop="orderNo">
|
||||
<el-input v-model="formData.orderNo" placeholder="请输入订单号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="交易时间" prop="tradeTime">
|
||||
<el-date-picker
|
||||
v-model="formData.tradeTime"
|
||||
type="date"
|
||||
value-format="x"
|
||||
placeholder="选择交易时间"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-radio-group v-model="formData.status">
|
||||
<el-radio
|
||||
v-for="dict in getIntDictOptions(DICT_TYPE.PRISON_CONSUMPTION_STATUS)"
|
||||
:key="dict.value"
|
||||
:value="dict.value"
|
||||
>{{ dict.label }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="formData.remark" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="罪犯ID" prop="prisonerId">
|
||||
<el-input v-model="formData.prisonerId" placeholder="请输入罪犯ID" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="罪犯编号" prop="prisonerNo">
|
||||
<el-input v-model="formData.prisonerNo" placeholder="请输入罪犯编号" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="类型" prop="type">
|
||||
<el-select v-model="formData.type" placeholder="请选择类型" class="!w-full">
|
||||
<el-option
|
||||
v-for="dict in getIntDictOptions(DICT_TYPE.PRISON_CONSUMPTION_TYPE)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="订单总金额" prop="totalAmount">
|
||||
<el-input-number v-model="formData.totalAmount" :precision="2" :step="0.01" :min="0" :max="99999999.99" placeholder="请输入金额" class="!w-full" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="账户余额" prop="balance">
|
||||
<el-input-number v-model="formData.balance" :precision="2" :step="0.01" :min="0" :max="99999999.99" placeholder="请输入余额" class="!w-full" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="交易时间" prop="tradeTime">
|
||||
<el-date-picker
|
||||
v-model="formData.tradeTime"
|
||||
type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="选择交易时间"
|
||||
class="!w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-radio-group v-model="formData.status">
|
||||
<el-radio
|
||||
v-for="dict in getIntDictOptions(DICT_TYPE.PRISON_CONSUMPTION_STATUS)"
|
||||
:key="dict.value"
|
||||
:value="dict.value"
|
||||
>{{ dict.label }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="16">
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="formData.remark" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 消费明细列表 -->
|
||||
<el-divider content-position="left">消费明细</el-divider>
|
||||
<el-table :data="formData.details" border>
|
||||
<el-table-column label="商品名称" prop="goodsName" width="150">
|
||||
<template #default="{ row, $index }">
|
||||
<el-input v-model="row.goodsName" placeholder="商品名称" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品编码" prop="goodsCode" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-input v-model="row.goodsCode" placeholder="商品编码" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="单价" prop="goodsPrice" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-input-number v-model="row.goodsPrice" :precision="2" :step="0.01" :min="0" controls-position="right" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="数量" prop="goodsCount" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-input-number v-model="row.goodsCount" :min="1" controls-position="right" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="小计" prop="subtotal" width="100">
|
||||
<template #default="{ row }">
|
||||
{{ formatPrice((row.goodsPrice || 0) * (row.goodsCount || 0)) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="80">
|
||||
<template #default="{ row, $index }">
|
||||
<el-button type="danger" link @click="removeDetail($index)" :disabled="formData.details.length <= 1">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-button type="primary" plain class="!w-full mt-10px" @click="addDetail">
|
||||
<Icon icon="ep:plus" class="mr-5px" /> 添加商品
|
||||
</el-button>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||
@ -65,43 +117,65 @@
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||
import { ConsumptionApi, Consumption } from '@/api/prison/consumption'
|
||||
import { ConsumptionApi, Consumption, ConsumptionDetail } from '@/api/prison/consumption'
|
||||
|
||||
/** 消费记录 表单 */
|
||||
/** 消费订单 表单 */
|
||||
defineOptions({ name: 'ConsumptionForm' })
|
||||
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
const { t } = useI18n()
|
||||
const message = useMessage()
|
||||
|
||||
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||
const dialogTitle = ref('') // 弹窗的标题
|
||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||
const dialogVisible = ref(false)
|
||||
const dialogTitle = ref('')
|
||||
const formLoading = ref(false)
|
||||
const formType = ref('')
|
||||
const formData = ref({
|
||||
id: undefined,
|
||||
prisonerId: undefined,
|
||||
prisonerNo: undefined,
|
||||
type: undefined,
|
||||
amount: undefined,
|
||||
balance: undefined,
|
||||
goodsName: undefined,
|
||||
goodsCount: undefined,
|
||||
orderNo: undefined,
|
||||
type: undefined,
|
||||
totalAmount: undefined,
|
||||
balance: undefined,
|
||||
tradeTime: undefined,
|
||||
status: undefined,
|
||||
remark: undefined
|
||||
remark: undefined,
|
||||
details: [] as ConsumptionDetail[]
|
||||
})
|
||||
const formRules = reactive({
|
||||
|
||||
const formRules = {
|
||||
prisonerId: [{ required: true, message: '罪犯ID不能为空', trigger: 'blur' }],
|
||||
prisonerNo: [{ required: true, message: '罪犯编号不能为空', trigger: 'blur' }],
|
||||
type: [{ required: true, message: '类型不能为空', trigger: 'change' }],
|
||||
amount: [{ required: true, message: '金额不能为空', trigger: 'blur' }],
|
||||
totalAmount: [{ required: true, message: '订单总金额不能为空', trigger: 'blur' }],
|
||||
tradeTime: [{ required: true, message: '交易时间不能为空', trigger: 'blur' }],
|
||||
status: [{ required: true, message: '状态不能为空', trigger: 'blur' }]
|
||||
})
|
||||
const formRef = ref() // 表单 Ref
|
||||
status: [{ required: true, message: '状态不能为空', trigger: 'change' }]
|
||||
}
|
||||
|
||||
const formRef = ref()
|
||||
|
||||
/** 添加明细行 */
|
||||
const addDetail = () => {
|
||||
formData.value.details.push({
|
||||
goodsName: '',
|
||||
goodsCode: '',
|
||||
goodsPrice: 0,
|
||||
goodsCount: 1
|
||||
})
|
||||
}
|
||||
|
||||
/** 删除明细行 */
|
||||
const removeDetail = (index: number) => {
|
||||
formData.value.details.splice(index, 1)
|
||||
}
|
||||
|
||||
/** 格式化价格 */
|
||||
const formatPrice = (price: number) => {
|
||||
return '¥' + price.toFixed(2)
|
||||
}
|
||||
|
||||
/** 打开弹窗 */
|
||||
const open = async (type: string, id?: number) => {
|
||||
@ -109,24 +183,30 @@ const open = async (type: string, id?: number) => {
|
||||
dialogTitle.value = t('action.' + type)
|
||||
formType.value = type
|
||||
resetForm()
|
||||
// 修改时,设置数据
|
||||
if (id) {
|
||||
formLoading.value = true
|
||||
try {
|
||||
formData.value = await ConsumptionApi.getConsumption(id)
|
||||
const data = await ConsumptionApi.getConsumption(id)
|
||||
formData.value = data
|
||||
// 确保details是数组
|
||||
if (!formData.value.details) {
|
||||
formData.value.details = []
|
||||
}
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
} else {
|
||||
// 新增时默认添加一个明细行
|
||||
addDetail()
|
||||
}
|
||||
}
|
||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
|
||||
/** 提交表单 */
|
||||
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||
defineExpose({ open })
|
||||
|
||||
const emit = defineEmits(['success'])
|
||||
|
||||
const submitForm = async () => {
|
||||
// 校验表单
|
||||
await formRef.value.validate()
|
||||
// 提交请求
|
||||
formLoading.value = true
|
||||
try {
|
||||
const data = formData.value as unknown as Consumption
|
||||
@ -138,29 +218,26 @@ const submitForm = async () => {
|
||||
message.success(t('common.updateSuccess'))
|
||||
}
|
||||
dialogVisible.value = false
|
||||
// 发送操作成功的事件
|
||||
emit('success')
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 重置表单 */
|
||||
const resetForm = () => {
|
||||
formData.value = {
|
||||
id: undefined,
|
||||
prisonerId: undefined,
|
||||
prisonerNo: undefined,
|
||||
type: undefined,
|
||||
amount: undefined,
|
||||
balance: undefined,
|
||||
goodsName: undefined,
|
||||
goodsCount: undefined,
|
||||
orderNo: undefined,
|
||||
type: undefined,
|
||||
totalAmount: undefined,
|
||||
balance: undefined,
|
||||
tradeTime: undefined,
|
||||
status: undefined,
|
||||
remark: undefined
|
||||
remark: undefined,
|
||||
details: []
|
||||
}
|
||||
formRef.value?.resetFields()
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
class="!w-100px"
|
||||
>
|
||||
<el-option
|
||||
v-for="dict in typeOptions"
|
||||
v-for="dict in getIntDictOptions(DICT_TYPE.PRISON_CONSUMPTION_TYPE)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
@ -40,7 +40,7 @@
|
||||
class="!w-90px"
|
||||
>
|
||||
<el-option
|
||||
v-for="dict in statusOptions"
|
||||
v-for="dict in getIntDictOptions(DICT_TYPE.PRISON_CONSUMPTION_STATUS)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
@ -88,21 +88,19 @@
|
||||
@selection-change="handleRowCheckboxChange"
|
||||
>
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column label="记录ID" align="center" prop="id" width="80" />
|
||||
<el-table-column label="订单ID" align="center" prop="id" width="80" />
|
||||
<el-table-column label="订单号" align="center" prop="orderNo" width="180" />
|
||||
<el-table-column label="罪犯编号" align="center" prop="prisonerNo" width="120" />
|
||||
<el-table-column label="类型" align="center" prop="type" width="100">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.PRISON_CONSUMPTION_TYPE" :value="scope.row.type" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="金额" align="center" prop="amount" width="100" />
|
||||
<el-table-column label="订单总金额" align="center" prop="totalAmount" width="100" />
|
||||
<el-table-column label="账户余额" align="center" prop="balance" width="100" />
|
||||
<el-table-column label="商品名称" align="center" prop="goodsName" width="150" />
|
||||
<el-table-column label="商品数量" align="center" prop="goodsCount" width="90" />
|
||||
<el-table-column label="订单号" align="center" prop="orderNo" width="180" />
|
||||
<el-table-column label="交易时间" align="center" prop="tradeTime" width="180">
|
||||
<template #default="scope">
|
||||
{{ formatDate(scope.row.tradeTime) }}
|
||||
{{ formatDateTime(scope.row.tradeTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" align="center" prop="status" width="90">
|
||||
@ -112,10 +110,10 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||
<template #default="scope">
|
||||
{{ formatDate(scope.row.createTime) }}
|
||||
{{ formatDateTime(scope.row.createTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="120">
|
||||
<el-table-column label="操作" align="center" width="150">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
@ -125,6 +123,13 @@
|
||||
>
|
||||
修改
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
@click="handleViewDetail(scope.row.id)"
|
||||
>
|
||||
明细
|
||||
</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
link
|
||||
@ -146,13 +151,18 @@
|
||||
|
||||
<!-- 表单弹窗:添加/修改 -->
|
||||
<ConsumptionForm ref="formRef" @success="getList" />
|
||||
|
||||
<!-- 明细查看弹窗 -->
|
||||
<ConsumptionDetailDialog ref="detailDialogRef" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||
import { formatDateTime } from '@/utils/formatTime'
|
||||
import download from '@/utils/download'
|
||||
import { ConsumptionApi, Consumption } from '@/api/prison/consumption'
|
||||
import ConsumptionForm from './ConsumptionForm.vue'
|
||||
import ConsumptionDetailDialog from './ConsumptionDetailDialog.vue'
|
||||
|
||||
defineOptions({ name: 'Consumption' })
|
||||
|
||||
@ -171,16 +181,8 @@ const queryParams = reactive({
|
||||
})
|
||||
const queryFormRef = ref()
|
||||
const exportLoading = ref(false)
|
||||
|
||||
// 使用字典获取选项
|
||||
const typeOptions = getIntDictOptions(DICT_TYPE.PRISON_CONSUMPTION_TYPE)
|
||||
const statusOptions = getIntDictOptions(DICT_TYPE.PRISON_CONSUMPTION_STATUS)
|
||||
|
||||
/** 日期格式化 */
|
||||
const formatDate = (date: string | Date | undefined) => {
|
||||
if (!date) return '-'
|
||||
return new Date(date).toLocaleString('zh-CN')
|
||||
}
|
||||
const checkedIds = ref<number[]>([])
|
||||
const detailDialogRef = ref()
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
@ -203,6 +205,9 @@ const handleQuery = () => {
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields()
|
||||
// 重置分页参数
|
||||
queryParams.pageNo = 1
|
||||
queryParams.pageSize = 10
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
@ -212,6 +217,11 @@ const openForm = (type: string, id?: number) => {
|
||||
formRef.value.open(type, id)
|
||||
}
|
||||
|
||||
/** 查看明细操作 */
|
||||
const handleViewDetail = (id: number) => {
|
||||
detailDialogRef.value.open(id)
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (id: number) => {
|
||||
try {
|
||||
@ -223,7 +233,6 @@ const handleDelete = async (id: number) => {
|
||||
}
|
||||
|
||||
/** 批量删除按钮操作 */
|
||||
const checkedIds = ref<number[]>([])
|
||||
const handleRowCheckboxChange = (rows: Consumption[]) => {
|
||||
checkedIds.value = rows.map((row) => row.id!)
|
||||
}
|
||||
@ -244,7 +253,7 @@ const handleExport = async () => {
|
||||
await message.exportConfirm()
|
||||
exportLoading.value = true
|
||||
const data = await ConsumptionApi.exportConsumption(queryParams)
|
||||
download.excel(data, '消费记录.xls')
|
||||
download.excel(data, '消费订单.xls')
|
||||
} catch {
|
||||
} finally {
|
||||
exportLoading.value = false
|
||||
|
||||
@ -0,0 +1,167 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="title"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<el-form ref="formRef" :model="formData" :rules="rules" label-width="100px">
|
||||
<el-form-item label="选择问卷" prop="questionnaireId">
|
||||
<el-select
|
||||
v-model="formData.questionnaireId"
|
||||
placeholder="请选择问卷"
|
||||
class="!w-100%"
|
||||
filterable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in questionnaireList"
|
||||
:key="item.id"
|
||||
:label="item.title"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="选择罪犯" prop="prisonerIds">
|
||||
<el-select
|
||||
v-model="formData.prisonerIds"
|
||||
placeholder="请选择罪犯"
|
||||
class="!w-100%"
|
||||
multiple
|
||||
filterable
|
||||
remote
|
||||
:remote-method="searchPrisoners"
|
||||
:loading="prisonerLoading"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in prisonerList"
|
||||
:key="item.id"
|
||||
:label="`${item.prisonerNo} - ${item.name}`"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="截止日期" prop="deadline">
|
||||
<el-date-picker
|
||||
v-model="formData.deadline"
|
||||
type="datetime"
|
||||
placeholder="请选择截止日期"
|
||||
class="!w-100%"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input
|
||||
v-model="formData.remark"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="handleSubmit">
|
||||
确认发起
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { QuestionnaireApi } from '@/api/prison/questionnaire'
|
||||
import { QuestionnaireRecordApi } from '@/api/prison/questionnairerecord'
|
||||
import { PrisonerApi, type PrisonerVO } from '@/api/prison/prisoner'
|
||||
|
||||
defineOptions({ name: 'InitiateAssessmentDialog' })
|
||||
|
||||
const emit = defineEmits(['success'])
|
||||
|
||||
const message = useMessage()
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const title = ref('发起测评')
|
||||
const formRef = ref()
|
||||
const submitLoading = ref(false)
|
||||
const questionnaireList = ref<any[]>([])
|
||||
const prisonerList = ref<PrisonerVO[]>([])
|
||||
const prisonerLoading = ref(false)
|
||||
|
||||
const formData = reactive({
|
||||
questionnaireId: undefined as number | undefined,
|
||||
prisonerIds: [] as number[],
|
||||
deadline: '',
|
||||
remark: ''
|
||||
})
|
||||
|
||||
const rules = {
|
||||
questionnaireId: [{ required: true, message: '请选择问卷', trigger: 'change' }],
|
||||
prisonerIds: [{ required: true, message: '请选择罪犯', trigger: 'change' }]
|
||||
}
|
||||
|
||||
/** 获取问卷列表 */
|
||||
const getQuestionnaireList = async () => {
|
||||
try {
|
||||
const data = await QuestionnaireApi.getQuestionnairePage({ pageNo: 1, pageSize: 1000 })
|
||||
questionnaireList.value = data.list
|
||||
} catch {}
|
||||
}
|
||||
|
||||
/** 搜索罪犯 */
|
||||
const searchPrisoners = async (keyword: string) => {
|
||||
if (!keyword) {
|
||||
prisonerList.value = []
|
||||
return
|
||||
}
|
||||
prisonerLoading.value = true
|
||||
try {
|
||||
const data = await PrisonerApi.getPrisonerPage({
|
||||
pageNo: 1,
|
||||
pageSize: 20,
|
||||
prisonerNo: keyword
|
||||
})
|
||||
prisonerList.value = data.list
|
||||
} catch {
|
||||
prisonerList.value = []
|
||||
} finally {
|
||||
prisonerLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 打开弹窗 */
|
||||
const open = () => {
|
||||
dialogVisible.value = true
|
||||
title.value = '发起测评'
|
||||
// 重置表单
|
||||
formData.questionnaireId = undefined
|
||||
formData.prisonerIds = []
|
||||
formData.deadline = ''
|
||||
formData.remark = ''
|
||||
// 加载问卷列表
|
||||
getQuestionnaireList()
|
||||
// 清空罪犯列表,等待用户搜索
|
||||
prisonerList.value = []
|
||||
}
|
||||
|
||||
/** 提交 */
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
await formRef.value.validate()
|
||||
submitLoading.value = true
|
||||
await QuestionnaireRecordApi.initiateAssessment({
|
||||
questionnaireId: formData.questionnaireId!,
|
||||
prisonerIds: formData.prisonerIds,
|
||||
deadline: formData.deadline || undefined,
|
||||
remark: formData.remark || undefined
|
||||
})
|
||||
message.success('测评发起成功')
|
||||
dialogVisible.value = false
|
||||
emit('success')
|
||||
} catch {
|
||||
// Validation error or API error
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
113
src/views/prison/questionnairerecord/ManualScoreDialog.vue
Normal file
113
src/views/prison/questionnairerecord/ManualScoreDialog.vue
Normal file
@ -0,0 +1,113 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="title"
|
||||
width="500px"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<el-form ref="formRef" :model="formData" :rules="rules" label-width="100px">
|
||||
<el-form-item label="罪犯信息">
|
||||
<span>{{ currentRecord?.prisonerName || currentRecord?.prisonerNo }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="客观分">
|
||||
<span>{{ currentRecord?.objectiveScore || 0 }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="主观题得分" prop="subjectiveScore">
|
||||
<el-input-number
|
||||
v-model="formData.subjectiveScore"
|
||||
:min="0"
|
||||
:max="100"
|
||||
:precision="2"
|
||||
class="!w-200px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="风险等级" prop="riskLevel">
|
||||
<el-select v-model="formData.riskLevel" placeholder="请选择风险等级" class="!w-200px">
|
||||
<el-option
|
||||
v-for="dict in riskLevelOptions"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="评语" prop="comment">
|
||||
<el-input
|
||||
v-model="formData.comment"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入评语"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="handleSubmit">
|
||||
确认评分
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||
import { QuestionnaireRecordApi, type QuestionnaireRecord } from '@/api/prison/questionnairerecord'
|
||||
|
||||
defineOptions({ name: 'ManualScoreDialog' })
|
||||
|
||||
const emit = defineEmits(['success'])
|
||||
|
||||
const message = useMessage()
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const title = ref('人工评分')
|
||||
const formRef = ref()
|
||||
const submitLoading = ref(false)
|
||||
const currentRecord = ref<QuestionnaireRecord | null>(null)
|
||||
|
||||
const riskLevelOptions = getIntDictOptions(DICT_TYPE.PRISON_RISK_LEVEL)
|
||||
|
||||
const formData = reactive({
|
||||
subjectiveScore: 0,
|
||||
riskLevel: undefined as number | undefined,
|
||||
comment: ''
|
||||
})
|
||||
|
||||
const rules = {
|
||||
subjectiveScore: [{ required: true, message: '请输入主观题得分', trigger: 'blur' }]
|
||||
}
|
||||
|
||||
/** 打开弹窗 */
|
||||
const open = (record: QuestionnaireRecord) => {
|
||||
dialogVisible.value = true
|
||||
title.value = '人工评分'
|
||||
currentRecord.value = record
|
||||
// 重置表单
|
||||
formData.subjectiveScore = 0
|
||||
formData.riskLevel = undefined
|
||||
formData.comment = ''
|
||||
}
|
||||
|
||||
/** 提交 */
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
await formRef.value.validate()
|
||||
submitLoading.value = true
|
||||
await QuestionnaireRecordApi.manualScore({
|
||||
recordId: currentRecord.value.id!,
|
||||
subjectiveScore: formData.subjectiveScore,
|
||||
comment: formData.comment || undefined,
|
||||
riskLevel: formData.riskLevel
|
||||
})
|
||||
message.success('评分成功')
|
||||
dialogVisible.value = false
|
||||
emit('success')
|
||||
} catch {
|
||||
// Validation error or API error
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
@ -8,23 +8,21 @@
|
||||
:inline="true"
|
||||
label-width="68px"
|
||||
>
|
||||
<el-form-item label="问卷ID" prop="questionnaireId">
|
||||
<el-input
|
||||
<el-form-item label="问卷" prop="questionnaireId">
|
||||
<el-select
|
||||
v-model="queryParams.questionnaireId"
|
||||
placeholder="请输入问卷ID"
|
||||
placeholder="请选择问卷"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="罪犯ID" prop="prisonerId">
|
||||
<el-input
|
||||
v-model="queryParams.prisonerId"
|
||||
placeholder="请输入罪犯ID"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
filterable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in questionnaireList"
|
||||
:key="item.id"
|
||||
:label="item.title"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="罪犯编号" prop="prisonerNo">
|
||||
<el-input
|
||||
@ -35,42 +33,7 @@
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="得分" prop="totalScore">
|
||||
<el-input
|
||||
v-model="queryParams.totalScore"
|
||||
placeholder="请输入得分"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否及格" prop="passStatus">
|
||||
<el-select
|
||||
v-model="queryParams.passStatus"
|
||||
placeholder="请选择是否及格"
|
||||
clearable
|
||||
class="!w-240px"
|
||||
>
|
||||
<el-option
|
||||
v-for="dict in passStatusOptions"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="答题时间" prop="answerTime">
|
||||
<el-date-picker
|
||||
v-model="queryParams.answerTime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
type="daterange"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||
class="!w-220px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-form-item label="测评状态" prop="status">
|
||||
<el-select
|
||||
v-model="queryParams.status"
|
||||
placeholder="请选择状态"
|
||||
@ -85,30 +48,49 @@
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间" prop="createTime">
|
||||
<el-date-picker
|
||||
v-model="queryParams.createTime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
type="daterange"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||
class="!w-220px"
|
||||
/>
|
||||
<el-form-item label="及格状态" prop="passStatus">
|
||||
<el-select
|
||||
v-model="queryParams.passStatus"
|
||||
placeholder="请选择及格状态"
|
||||
clearable
|
||||
class="!w-240px"
|
||||
>
|
||||
<el-option
|
||||
v-for="dict in passStatusOptions"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="风险等级" prop="riskLevel">
|
||||
<el-select
|
||||
v-model="queryParams.riskLevel"
|
||||
placeholder="请选择风险等级"
|
||||
clearable
|
||||
class="!w-240px"
|
||||
>
|
||||
<el-option
|
||||
v-for="dict in riskLevelOptions"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
type="success"
|
||||
plain
|
||||
@click="openForm('create')"
|
||||
v-hasPermi="['prison:questionnaire-record:create']"
|
||||
@click="handleInitiate"
|
||||
v-hasPermi="['prison:questionnaire-record:initiate']"
|
||||
>
|
||||
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||
<Icon icon="ep:promotion" class="mr-5px" /> 发起测评
|
||||
</el-button>
|
||||
<el-button
|
||||
type="success"
|
||||
type="primary"
|
||||
plain
|
||||
@click="handleExport"
|
||||
:loading="exportLoading"
|
||||
@ -117,11 +99,11 @@
|
||||
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||
</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
:disabled="isEmpty(checkedIds)"
|
||||
@click="handleDeleteBatch"
|
||||
v-hasPermi="['prison:questionnaire-record:delete']"
|
||||
type="danger"
|
||||
plain
|
||||
:disabled="isEmpty(checkedIds)"
|
||||
@click="handleDeleteBatch"
|
||||
v-hasPermi="['prison:questionnaire-record:delete']"
|
||||
>
|
||||
<Icon icon="ep:delete" class="mr-5px" /> 批量删除
|
||||
</el-button>
|
||||
@ -132,34 +114,39 @@
|
||||
<!-- 列表 -->
|
||||
<ContentWrap>
|
||||
<el-table
|
||||
row-key="id"
|
||||
v-loading="loading"
|
||||
:data="list"
|
||||
:stripe="true"
|
||||
:show-overflow-tooltip="true"
|
||||
@selection-change="handleRowCheckboxChange"
|
||||
row-key="id"
|
||||
v-loading="loading"
|
||||
:data="list"
|
||||
:stripe="true"
|
||||
:show-overflow-tooltip="true"
|
||||
@selection-change="handleRowCheckboxChange"
|
||||
>
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column label="记录ID" align="center" prop="id" />
|
||||
<el-table-column label="问卷ID" align="center" prop="questionnaireId" />
|
||||
<el-table-column label="罪犯ID" align="center" prop="prisonerId" />
|
||||
<el-table-column label="罪犯编号" align="center" prop="prisonerNo" />
|
||||
<el-table-column label="得分" align="center" prop="totalScore" />
|
||||
<el-table-column label="是否及格" align="center" prop="passStatus">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column label="记录ID" align="center" prop="id" width="80" />
|
||||
<el-table-column label="问卷名称" align="center" prop="questionnaireName" min-width="150" />
|
||||
<el-table-column label="罪犯编号" align="center" prop="prisonerNo" width="120" />
|
||||
<el-table-column label="罪犯姓名" align="center" prop="prisonerName" width="100" />
|
||||
<el-table-column label="测评状态" align="center" prop="status" width="100">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.PRISON_RECORD_STATUS" :value="scope.row.status" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="客观分" align="center" prop="objectiveScore" width="80" />
|
||||
<el-table-column label="主观分" align="center" prop="subjectiveScore" width="80" />
|
||||
<el-table-column label="总分" align="center" prop="totalScore" width="80" />
|
||||
<el-table-column label="及格状态" align="center" prop="passStatus" width="100">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.PRISON_RECORD_PASS_STATUS" :value="scope.row.passStatus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="答题时间"
|
||||
align="center"
|
||||
prop="answerTime"
|
||||
:formatter="dateFormatter"
|
||||
width="180px"
|
||||
/>
|
||||
<el-table-column label="状态" align="center" prop="status">
|
||||
<el-table-column label="风险等级" align="center" prop="riskLevel" width="100">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.PRISON_RECORD_STATUS" :value="scope.row.status" />
|
||||
<dict-tag :type="DICT_TYPE.PRISON_RISK_LEVEL" :value="scope.row.riskLevel" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="答题用时" align="center" prop="duration" width="100">
|
||||
<template #default="scope">
|
||||
{{ scope.row.duration ? formatDuration(scope.row.duration) : '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
@ -167,10 +154,46 @@
|
||||
align="center"
|
||||
prop="createTime"
|
||||
:formatter="dateFormatter"
|
||||
width="180px"
|
||||
width="160"
|
||||
/>
|
||||
<el-table-column label="操作" align="center" min-width="120px">
|
||||
<el-table-column label="操作" align="center" min-width="200px">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="scope.row.status === 1"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleStart(scope.row)"
|
||||
v-hasPermi="['prison:questionnaire-record:start']"
|
||||
>
|
||||
开始
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="scope.row.status === 2"
|
||||
link
|
||||
type="success"
|
||||
@click="handleFinish(scope.row)"
|
||||
v-hasPermi="['prison:questionnaire-record:finish']"
|
||||
>
|
||||
结束
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="scope.row.status === 1"
|
||||
link
|
||||
type="danger"
|
||||
@click="handleCancel(scope.row)"
|
||||
v-hasPermi="['prison:questionnaire-record:cancel']"
|
||||
>
|
||||
取消
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="scope.row.status === 3 && scope.row.passStatus === 3"
|
||||
link
|
||||
type="warning"
|
||||
@click="handleManualScore(scope.row)"
|
||||
v-hasPermi="['prison:questionnaire-record:score']"
|
||||
>
|
||||
人工评分
|
||||
</el-button>
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@ -201,6 +224,12 @@
|
||||
|
||||
<!-- 表单弹窗:添加/修改 -->
|
||||
<QuestionnaireRecordForm ref="formRef" @success="getList" />
|
||||
|
||||
<!-- 发起测评弹窗 -->
|
||||
<InitiateAssessmentDialog ref="initiateDialogRef" @success="getList" />
|
||||
|
||||
<!-- 人工评分弹窗 -->
|
||||
<ManualScoreDialog ref="manualScoreDialogRef" @success="getList" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -208,10 +237,13 @@ import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||
import { isEmpty } from '@/utils/is'
|
||||
import { dateFormatter } from '@/utils/formatTime'
|
||||
import download from '@/utils/download'
|
||||
import { QuestionnaireRecordApi, QuestionnaireRecord } from '@/api/prison/questionnairerecord'
|
||||
import { QuestionnaireRecordApi, QuestionnaireRecord, QuestionnaireRecordPageParams } from '@/api/prison/questionnairerecord'
|
||||
import { QuestionnaireApi } from '@/api/prison/questionnaire'
|
||||
import QuestionnaireRecordForm from './QuestionnaireRecordForm.vue'
|
||||
import InitiateAssessmentDialog from './InitiateAssessmentDialog.vue'
|
||||
import ManualScoreDialog from './ManualScoreDialog.vue'
|
||||
|
||||
/** 问卷答题记录 列表 */
|
||||
/** 问卷答题记录/测评记录 列表 */
|
||||
defineOptions({ name: 'QuestionnaireRecord' })
|
||||
|
||||
const message = useMessage() // 消息弹窗
|
||||
@ -220,24 +252,24 @@ const { t } = useI18n() // 国际化
|
||||
const loading = ref(true) // 列表的加载中
|
||||
const list = ref<QuestionnaireRecord[]>([]) // 列表的数据
|
||||
const total = ref(0) // 列表的总页数
|
||||
const queryParams = reactive({
|
||||
const questionnaireList = ref<any[]>([]) // 问卷列表
|
||||
|
||||
const queryParams = reactive<QuestionnaireRecordPageParams>({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
questionnaireId: undefined,
|
||||
prisonerId: undefined,
|
||||
prisonerNo: undefined,
|
||||
totalScore: undefined,
|
||||
passStatus: undefined,
|
||||
answerTime: [],
|
||||
status: undefined,
|
||||
createTime: []
|
||||
passStatus: undefined,
|
||||
riskLevel: undefined
|
||||
})
|
||||
const queryFormRef = ref() // 搜索的表单
|
||||
const exportLoading = ref(false) // 导出的加载中
|
||||
|
||||
// 使用字典获取选项
|
||||
const passStatusOptions = getIntDictOptions(DICT_TYPE.PRISON_RECORD_PASS_STATUS)
|
||||
const statusOptions = getIntDictOptions(DICT_TYPE.PRISON_RECORD_STATUS)
|
||||
const passStatusOptions = getIntDictOptions(DICT_TYPE.PRISON_RECORD_PASS_STATUS)
|
||||
const riskLevelOptions = getIntDictOptions(DICT_TYPE.PRISON_RISK_LEVEL)
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
@ -251,6 +283,14 @@ const getList = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
/** 获取问卷列表 */
|
||||
const getQuestionnaireList = async () => {
|
||||
try {
|
||||
const data = await QuestionnaireApi.getQuestionnairePage({ pageNo: 1, pageSize: 1000 })
|
||||
questionnaireList.value = data.list
|
||||
} catch {}
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNo = 1
|
||||
@ -269,42 +309,78 @@ const openForm = (type: string, id?: number) => {
|
||||
formRef.value.open(type, id)
|
||||
}
|
||||
|
||||
/** 发起测评 */
|
||||
const initiateDialogRef = ref()
|
||||
const handleInitiate = () => {
|
||||
initiateDialogRef.value.open()
|
||||
}
|
||||
|
||||
/** 开始测评 */
|
||||
const handleStart = async (row: QuestionnaireRecord) => {
|
||||
try {
|
||||
await message.confirm(`确定要开始对罪犯 ${row.prisonerName || row.prisonerNo} 的测评吗?`)
|
||||
await QuestionnaireRecordApi.startAssessment(row.id!, row.prisonerId!)
|
||||
message.success('已开始测评')
|
||||
getList()
|
||||
} catch {}
|
||||
}
|
||||
|
||||
/** 结束测评 */
|
||||
const handleFinish = async (row: QuestionnaireRecord) => {
|
||||
try {
|
||||
await message.confirm(`确定要结束该测评吗?`)
|
||||
await QuestionnaireRecordApi.finishAssessment(row.id!)
|
||||
message.success('已结束测评')
|
||||
getList()
|
||||
} catch {}
|
||||
}
|
||||
|
||||
/** 取消测评 */
|
||||
const handleCancel = async (row: QuestionnaireRecord) => {
|
||||
try {
|
||||
await message.confirm(`确定要取消该测评吗?取消后将无法继续测评。`)
|
||||
await QuestionnaireRecordApi.cancelAssessment(row.id!)
|
||||
message.success('已取消测评')
|
||||
getList()
|
||||
} catch {}
|
||||
}
|
||||
|
||||
/** 人工评分 */
|
||||
const manualScoreDialogRef = ref()
|
||||
const handleManualScore = (row: QuestionnaireRecord) => {
|
||||
manualScoreDialogRef.value.open(row)
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (id: number) => {
|
||||
try {
|
||||
// 删除的二次确认
|
||||
await message.delConfirm()
|
||||
// 发起删除
|
||||
await QuestionnaireRecordApi.deleteQuestionnaireRecord(id)
|
||||
message.success(t('common.delSuccess'))
|
||||
// 刷新列表
|
||||
await getList()
|
||||
} catch {}
|
||||
}
|
||||
|
||||
/** 批量删除问卷答题记录 */
|
||||
/** 批量删除 */
|
||||
const handleDeleteBatch = async () => {
|
||||
try {
|
||||
// 删除的二次确认
|
||||
await message.delConfirm()
|
||||
await QuestionnaireRecordApi.deleteQuestionnaireRecordList(checkedIds.value);
|
||||
checkedIds.value = [];
|
||||
await QuestionnaireRecordApi.deleteQuestionnaireRecordList(checkedIds.value)
|
||||
checkedIds.value = []
|
||||
message.success(t('common.delSuccess'))
|
||||
await getList();
|
||||
await getList()
|
||||
} catch {}
|
||||
}
|
||||
|
||||
const checkedIds = ref<number[]>([])
|
||||
const handleRowCheckboxChange = (records: QuestionnaireRecord[]) => {
|
||||
checkedIds.value = records.map((item) => item.id!);
|
||||
checkedIds.value = records.map((item) => item.id!)
|
||||
}
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
// 导出的二次确认
|
||||
await message.exportConfirm()
|
||||
// 发起导出
|
||||
exportLoading.value = true
|
||||
const data = await QuestionnaireRecordApi.exportQuestionnaireRecord(queryParams)
|
||||
download.excel(data, '问卷答题记录.xls')
|
||||
@ -314,8 +390,17 @@ const handleExport = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
/** 格式化时长 */
|
||||
const formatDuration = (seconds: number): string => {
|
||||
if (!seconds) return '-'
|
||||
const minutes = Math.floor(seconds / 60)
|
||||
const secs = seconds % 60
|
||||
return `${minutes}分${secs}秒`
|
||||
}
|
||||
|
||||
/** 初始化 **/
|
||||
onMounted(() => {
|
||||
getList()
|
||||
getQuestionnaireList()
|
||||
})
|
||||
</script>
|
||||
</script>
|
||||
|
||||
@ -129,7 +129,7 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||
<template #default="scope">
|
||||
{{ formatDate(scope.row.createTime) }}
|
||||
{{ dateFormatter(scope.row.createTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="120">
|
||||
@ -167,6 +167,7 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||
import { dateFormatter } from '@/utils/formatTime'
|
||||
import download from '@/utils/download'
|
||||
import { RiskAssessmentApi, RiskAssessment } from '@/api/prison/riskassessment'
|
||||
import RiskAssessmentForm from './RiskAssessmentForm.vue'
|
||||
@ -195,12 +196,6 @@ const assessmentTypeOptions = getIntDictOptions(DICT_TYPE.PRISON_ASSESSMENT_TYPE
|
||||
const riskLevelOptions = getIntDictOptions(DICT_TYPE.PRISON_RISK_LEVEL)
|
||||
const statusOptions = getIntDictOptions(DICT_TYPE.PRISON_SCORE_STATUS)
|
||||
|
||||
/** 日期格式化 */
|
||||
const formatDate = (date: string | Date | undefined) => {
|
||||
if (!date) return '-'
|
||||
return new Date(date).toLocaleString('zh-CN')
|
||||
}
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
|
||||
@ -118,7 +118,7 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||
<template #default="scope">
|
||||
{{ formatDate(scope.row.createTime) }}
|
||||
{{ dateFormatter(scope.row.createTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="120">
|
||||
@ -156,6 +156,7 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||
import { dateFormatter } from '@/utils/formatTime'
|
||||
import download from '@/utils/download'
|
||||
import { ScoreApi, Score } from '@/api/prison/score'
|
||||
import ScoreForm from './ScoreForm.vue'
|
||||
@ -183,12 +184,6 @@ const exportLoading = ref(false)
|
||||
const levelOptions = getIntDictOptions(DICT_TYPE.PRISON_SCORE_LEVEL)
|
||||
const statusOptions = getIntDictOptions(DICT_TYPE.PRISON_SCORE_STATUS)
|
||||
|
||||
/** 日期格式化 */
|
||||
const formatDate = (date: string | Date | undefined) => {
|
||||
if (!date) return '-'
|
||||
return new Date(date).toLocaleString('zh-CN')
|
||||
}
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user