Browse Source

接口

wangzeyan
李双庆 11 months ago
parent
commit
ecd975f312
  1. 2
      admin/auto-imports.d.ts
  2. 25
      admin/src/app/api/attendance.ts
  3. 23
      admin/src/app/api/campus.ts
  4. 43
      admin/src/app/api/campus_person_role.ts
  5. 21
      admin/src/app/api/class.ts
  6. 22
      admin/src/app/api/communication_records.ts
  7. 21
      admin/src/app/api/contract.ts
  8. 21
      admin/src/app/api/course.ts
  9. 23
      admin/src/app/api/course_schedule.ts
  10. 27
      admin/src/app/api/customer_resource_changes.ts
  11. 32
      admin/src/app/api/customer_resources.ts
  12. 23
      admin/src/app/api/departments.ts
  13. 21
      admin/src/app/api/exam_answers.ts
  14. 21
      admin/src/app/api/exam_papers.ts
  15. 21
      admin/src/app/api/exam_questions.ts
  16. 21
      admin/src/app/api/exam_records.ts
  17. 29
      admin/src/app/api/market_performance.ts
  18. 21
      admin/src/app/api/order_table.ts
  19. 22
      admin/src/app/api/performance_records.ts
  20. 24
      admin/src/app/api/person_course_schedule.ts
  21. 23
      admin/src/app/api/physical_test.ts
  22. 21
      admin/src/app/api/reimbursement.ts
  23. 21
      admin/src/app/api/resource_sharing.ts
  24. 21
      admin/src/app/api/salary.ts
  25. 23
      admin/src/app/api/service.ts
  26. 21
      admin/src/app/api/six_speed.ts
  27. 38
      admin/src/app/api/six_speed_modification_log.ts
  28. 21
      admin/src/app/api/stat_hour.ts
  29. 22
      admin/src/app/api/student_course_usage.ts
  30. 21
      admin/src/app/api/student_courses.ts
  31. 21
      admin/src/app/api/user_feedback.ts
  32. 10
      admin/src/app/api/venue.ts
  33. 56
      admin/src/app/lang/zh-cn/attendance.attendance.json
  34. 38
      admin/src/app/lang/zh-cn/campus.campus.json
  35. 32
      admin/src/app/lang/zh-cn/campus_person_role.campus_person_role.json
  36. 68
      admin/src/app/lang/zh-cn/class.class.json
  37. 60
      admin/src/app/lang/zh-cn/communication_records.communication_records.json
  38. 48
      admin/src/app/lang/zh-cn/contract.contract.json
  39. 52
      admin/src/app/lang/zh-cn/course.course.json
  40. 56
      admin/src/app/lang/zh-cn/course_schedule.course_schedule.json
  41. 40
      admin/src/app/lang/zh-cn/customer_resource_changes.customer_resource_changes.json
  42. 74
      admin/src/app/lang/zh-cn/customer_resources.customer_resources.json
  43. 26
      admin/src/app/lang/zh-cn/departments.departments.json
  44. 36
      admin/src/app/lang/zh-cn/exam_answers.exam_answers.json
  45. 28
      admin/src/app/lang/zh-cn/exam_papers.exam_papers.json
  46. 4
      admin/src/app/lang/zh-cn/exam_questions.exam_questions.json
  47. 2
      admin/src/app/lang/zh-cn/exam_questions.exam_questions_edit.json
  48. 44
      admin/src/app/lang/zh-cn/exam_records.exam_records.json
  49. 24
      admin/src/app/lang/zh-cn/market_performance.market_performance.json
  50. 68
      admin/src/app/lang/zh-cn/order_table.order_table.json
  51. 44
      admin/src/app/lang/zh-cn/performance_records.performance_records.json
  52. 36
      admin/src/app/lang/zh-cn/person_course_schedule.person_course_schedule.json
  53. 84
      admin/src/app/lang/zh-cn/physical_test.physical_test.json
  54. 40
      admin/src/app/lang/zh-cn/reimbursement.reimbursement.json
  55. 36
      admin/src/app/lang/zh-cn/resource_sharing.resource_sharing.json
  56. 64
      admin/src/app/lang/zh-cn/salary.salary.json
  57. 56
      admin/src/app/lang/zh-cn/service.service.json
  58. 68
      admin/src/app/lang/zh-cn/six_speed.six_speed.json
  59. 36
      admin/src/app/lang/zh-cn/six_speed_modification_log.six_speed_modification_log.json
  60. 144
      admin/src/app/lang/zh-cn/stat_hour.stat_hour.json
  61. 28
      admin/src/app/lang/zh-cn/student_course_usage.student_course_usage.json
  62. 40
      admin/src/app/lang/zh-cn/student_courses.student_courses.json
  63. 28
      admin/src/app/lang/zh-cn/user_feedback.user_feedback.json
  64. 18
      admin/src/app/lang/zh-cn/venue.venue.json
  65. 531
      admin/src/app/views/attendance/attendance.vue
  66. 529
      admin/src/app/views/attendance/components/attendance-edit.vue
  67. 446
      admin/src/app/views/campus/campus.vue
  68. 34
      admin/src/app/views/campus/components/campus-edit.vue
  69. 539
      admin/src/app/views/campus_person_role/campus_person_role.vue
  70. 493
      admin/src/app/views/campus_person_role/components/campus-person-role-edit.vue
  71. 591
      admin/src/app/views/class/class.vue
  72. 590
      admin/src/app/views/class/components/class-edit.vue
  73. 570
      admin/src/app/views/communication_records/communication_records.vue
  74. 565
      admin/src/app/views/communication_records/components/communication-records-edit.vue
  75. 487
      admin/src/app/views/contract/components/contract-edit.vue
  76. 491
      admin/src/app/views/contract/contract.vue
  77. 513
      admin/src/app/views/course/components/course-edit.vue
  78. 514
      admin/src/app/views/course/course.vue
  79. 529
      admin/src/app/views/course_schedule/components/course-schedule-edit.vue
  80. 539
      admin/src/app/views/course_schedule/course_schedule.vue
  81. 446
      admin/src/app/views/customer_resource_changes/components/customer-resource-changes-edit.vue
  82. 466
      admin/src/app/views/customer_resource_changes/customer_resource_changes.vue
  83. 960
      admin/src/app/views/customer_resources/components/customer-resources-edit.vue
  84. 537
      admin/src/app/views/customer_resources/customer_resources.vue
  85. 242
      admin/src/app/views/departments/components/departments-edit.vue
  86. 292
      admin/src/app/views/departments/departments.vue
  87. 406
      admin/src/app/views/exam_answers/components/exam-answers-edit.vue
  88. 431
      admin/src/app/views/exam_answers/exam_answers.vue
  89. 368
      admin/src/app/views/exam_papers/components/exam-papers-edit.vue
  90. 391
      admin/src/app/views/exam_papers/exam_papers.vue
  91. 583
      admin/src/app/views/exam_questions/exam_questions.vue
  92. 599
      admin/src/app/views/exam_questions/exam_questions_edit.vue
  93. 452
      admin/src/app/views/exam_records/components/exam-records-edit.vue
  94. 471
      admin/src/app/views/exam_records/exam_records.vue
  95. 420
      admin/src/app/views/market_performance/components/market-performance-edit.vue
  96. 426
      admin/src/app/views/market_performance/market_performance.vue
  97. 606
      admin/src/app/views/order_table/components/order-table-edit.vue
  98. 600
      admin/src/app/views/order_table/order_table.vue
  99. 462
      admin/src/app/views/performance_records/components/performance-records-edit.vue
  100. 479
      admin/src/app/views/performance_records/performance_records.vue

2
admin/auto-imports.d.ts

@ -1,5 +1,5 @@
// Generated by 'unplugin-auto-import' // Generated by 'unplugin-auto-import'
export {} export {}
declare global { declare global {
const ElNotification: typeof import('element-plus/es')['ElNotification']
} }

25
admin/src/app/api/attendance.ts

@ -1,9 +1,5 @@
import request from '@/utils/request' import request from '@/utils/request'
// USER_CODE_BEGIN -- attendance // USER_CODE_BEGIN -- attendance
/** /**
* *
@ -11,7 +7,7 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getAttendanceList(params: Record<string, any>) { export function getAttendanceList(params: Record<string, any>) {
return request.get(`attendance/attendance`, {params}) return request.get(`attendance/attendance`, { params })
} }
/** /**
@ -20,7 +16,7 @@ export function getAttendanceList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getAttendanceInfo(id: number) { export function getAttendanceInfo(id: number) {
return request.get(`attendance/attendance/${id}`); return request.get(`attendance/attendance/${id}`)
} }
/** /**
@ -29,7 +25,10 @@ export function getAttendanceInfo(id: number) {
* @returns * @returns
*/ */
export function addAttendance(params: Record<string, any>) { export function addAttendance(params: Record<string, any>) {
return request.post('attendance/attendance', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post('attendance/attendance', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -39,7 +38,10 @@ export function addAttendance(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editAttendance(params: Record<string, any>) { export function editAttendance(params: Record<string, any>) {
return request.put(`attendance/attendance/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(`attendance/attendance/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -48,9 +50,10 @@ export function editAttendance(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deleteAttendance(id: number) { export function deleteAttendance(id: number) {
return request.delete(`attendance/attendance/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(`attendance/attendance/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
// USER_CODE_END -- attendance // USER_CODE_END -- attendance

23
admin/src/app/api/campus.ts

@ -1,7 +1,5 @@
import request from '@/utils/request' import request from '@/utils/request'
// USER_CODE_BEGIN -- campus // USER_CODE_BEGIN -- campus
/** /**
* *
@ -9,7 +7,7 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getCampusList(params: Record<string, any>) { export function getCampusList(params: Record<string, any>) {
return request.get(`campus/campus`, {params}) return request.get(`campus/campus`, { params })
} }
/** /**
@ -18,7 +16,7 @@ export function getCampusList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getCampusInfo(id: number) { export function getCampusInfo(id: number) {
return request.get(`campus/campus/${id}`); return request.get(`campus/campus/${id}`)
} }
/** /**
@ -27,7 +25,10 @@ export function getCampusInfo(id: number) {
* @returns * @returns
*/ */
export function addCampus(params: Record<string, any>) { export function addCampus(params: Record<string, any>) {
return request.post('campus/campus', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post('campus/campus', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -37,7 +38,10 @@ export function addCampus(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editCampus(params: Record<string, any>) { export function editCampus(params: Record<string, any>) {
return request.put(`campus/campus/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(`campus/campus/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -46,9 +50,10 @@ export function editCampus(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deleteCampus(id: number) { export function deleteCampus(id: number) {
return request.delete(`campus/campus/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(`campus/campus/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
// USER_CODE_END -- campus // USER_CODE_END -- campus

43
admin/src/app/api/campus_person_role.ts

@ -1,9 +1,5 @@
import request from '@/utils/request' import request from '@/utils/request'
// USER_CODE_BEGIN -- campus_person_role // USER_CODE_BEGIN -- campus_person_role
/** /**
* *
@ -11,7 +7,7 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getCampusPersonRoleList(params: Record<string, any>) { export function getCampusPersonRoleList(params: Record<string, any>) {
return request.get(`campus_person_role/campus_person_role`, {params}) return request.get(`campus_person_role/campus_person_role`, { params })
} }
/** /**
@ -20,7 +16,7 @@ export function getCampusPersonRoleList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getCampusPersonRoleInfo(id: number) { export function getCampusPersonRoleInfo(id: number) {
return request.get(`campus_person_role/campus_person_role/${id}`); return request.get(`campus_person_role/campus_person_role/${id}`)
} }
/** /**
@ -29,7 +25,10 @@ export function getCampusPersonRoleInfo(id: number) {
* @returns * @returns
*/ */
export function addCampusPersonRole(params: Record<string, any>) { export function addCampusPersonRole(params: Record<string, any>) {
return request.post('campus_person_role/campus_person_role', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post('campus_person_role/campus_person_role', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -39,7 +38,11 @@ export function addCampusPersonRole(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editCampusPersonRole(params: Record<string, any>) { export function editCampusPersonRole(params: Record<string, any>) {
return request.put(`campus_person_role/campus_person_role/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(
`campus_person_role/campus_person_role/${params.id}`,
params,
{ showErrorMessage: true, showSuccessMessage: true }
)
} }
/** /**
@ -48,17 +51,23 @@ export function editCampusPersonRole(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deleteCampusPersonRole(id: number) { export function deleteCampusPersonRole(id: number) {
return request.delete(`campus_person_role/campus_person_role/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(`campus_person_role/campus_person_role/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
export function getWithCampusList(params: Record<string,any>){ export function getWithCampusList(params: Record<string, any>) {
return request.get('campus_person_role/campus_all', {params}) return request.get('campus_person_role/campus_all', { params })
}export function getWithPersonnelList(params: Record<string,any>){ }
return request.get('campus_person_role/personnel_all', {params}) export function getWithPersonnelList(params: Record<string, any>) {
}export function getWithSysRoleList(params: Record<string,any>){ return request.get('campus_person_role/personnel_all', { params })
return request.get('campus_person_role/sys_role_all', {params}) }
}export function getWithDepartmentsList(params: Record<string,any>){ export function getWithSysRoleList(params: Record<string, any>) {
return request.get('campus_person_role/departments_all', {params}) return request.get('campus_person_role/sys_role_all', { params })
}
export function getWithDepartmentsList(params: Record<string, any>) {
return request.get('campus_person_role/departments_all', { params })
} }
// USER_CODE_END -- campus_person_role // USER_CODE_END -- campus_person_role

21
admin/src/app/api/class.ts

@ -7,7 +7,7 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getClassList(params: Record<string, any>) { export function getClassList(params: Record<string, any>) {
return request.get(`class/class`, {params}) return request.get(`class/class`, { params })
} }
/** /**
@ -16,7 +16,7 @@ export function getClassList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getClassInfo(id: number) { export function getClassInfo(id: number) {
return request.get(`class/class/${id}`); return request.get(`class/class/${id}`)
} }
/** /**
@ -25,7 +25,10 @@ export function getClassInfo(id: number) {
* @returns * @returns
*/ */
export function addClass(params: Record<string, any>) { export function addClass(params: Record<string, any>) {
return request.post('class/class', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post('class/class', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -35,7 +38,10 @@ export function addClass(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editClass(params: Record<string, any>) { export function editClass(params: Record<string, any>) {
return request.put(`class/class/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(`class/class/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -44,9 +50,10 @@ export function editClass(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deleteClass(id: number) { export function deleteClass(id: number) {
return request.delete(`class/class/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(`class/class/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
// USER_CODE_END -- class // USER_CODE_END -- class

22
admin/src/app/api/communication_records.ts

@ -7,7 +7,7 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getCommunicationRecordsList(params: Record<string, any>) { export function getCommunicationRecordsList(params: Record<string, any>) {
return request.get(`communication_records/communication_records`, {params}) return request.get(`communication_records/communication_records`, { params })
} }
/** /**
@ -16,7 +16,7 @@ export function getCommunicationRecordsList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getCommunicationRecordsInfo(id: number) { export function getCommunicationRecordsInfo(id: number) {
return request.get(`communication_records/communication_records/${id}`); return request.get(`communication_records/communication_records/${id}`)
} }
/** /**
@ -25,7 +25,10 @@ export function getCommunicationRecordsInfo(id: number) {
* @returns * @returns
*/ */
export function addCommunicationRecords(params: Record<string, any>) { export function addCommunicationRecords(params: Record<string, any>) {
return request.post('communication_records/communication_records', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post('communication_records/communication_records', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -35,7 +38,11 @@ export function addCommunicationRecords(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editCommunicationRecords(params: Record<string, any>) { export function editCommunicationRecords(params: Record<string, any>) {
return request.put(`communication_records/communication_records/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(
`communication_records/communication_records/${params.id}`,
params,
{ showErrorMessage: true, showSuccessMessage: true }
)
} }
/** /**
@ -44,9 +51,10 @@ export function editCommunicationRecords(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deleteCommunicationRecords(id: number) { export function deleteCommunicationRecords(id: number) {
return request.delete(`communication_records/communication_records/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(`communication_records/communication_records/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
// USER_CODE_END -- communication_records // USER_CODE_END -- communication_records

21
admin/src/app/api/contract.ts

@ -7,7 +7,7 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getContractList(params: Record<string, any>) { export function getContractList(params: Record<string, any>) {
return request.get(`contract/contract`, {params}) return request.get(`contract/contract`, { params })
} }
/** /**
@ -16,7 +16,7 @@ export function getContractList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getContractInfo(id: number) { export function getContractInfo(id: number) {
return request.get(`contract/contract/${id}`); return request.get(`contract/contract/${id}`)
} }
/** /**
@ -25,7 +25,10 @@ export function getContractInfo(id: number) {
* @returns * @returns
*/ */
export function addContract(params: Record<string, any>) { export function addContract(params: Record<string, any>) {
return request.post('contract/contract', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post('contract/contract', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -35,7 +38,10 @@ export function addContract(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editContract(params: Record<string, any>) { export function editContract(params: Record<string, any>) {
return request.put(`contract/contract/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(`contract/contract/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -44,9 +50,10 @@ export function editContract(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deleteContract(id: number) { export function deleteContract(id: number) {
return request.delete(`contract/contract/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(`contract/contract/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
// USER_CODE_END -- contract // USER_CODE_END -- contract

21
admin/src/app/api/course.ts

@ -7,7 +7,7 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getCourseList(params: Record<string, any>) { export function getCourseList(params: Record<string, any>) {
return request.get(`course/course`, {params}) return request.get(`course/course`, { params })
} }
/** /**
@ -16,7 +16,7 @@ export function getCourseList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getCourseInfo(id: number) { export function getCourseInfo(id: number) {
return request.get(`course/course/${id}`); return request.get(`course/course/${id}`)
} }
/** /**
@ -25,7 +25,10 @@ export function getCourseInfo(id: number) {
* @returns * @returns
*/ */
export function addCourse(params: Record<string, any>) { export function addCourse(params: Record<string, any>) {
return request.post('course/course', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post('course/course', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -35,7 +38,10 @@ export function addCourse(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editCourse(params: Record<string, any>) { export function editCourse(params: Record<string, any>) {
return request.put(`course/course/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(`course/course/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -44,9 +50,10 @@ export function editCourse(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deleteCourse(id: number) { export function deleteCourse(id: number) {
return request.delete(`course/course/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(`course/course/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
// USER_CODE_END -- course // USER_CODE_END -- course

23
admin/src/app/api/course_schedule.ts

@ -1,7 +1,5 @@
import request from '@/utils/request' import request from '@/utils/request'
// USER_CODE_BEGIN -- course_schedule // USER_CODE_BEGIN -- course_schedule
/** /**
* *
@ -9,7 +7,7 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getCourseScheduleList(params: Record<string, any>) { export function getCourseScheduleList(params: Record<string, any>) {
return request.get(`course_schedule/course_schedule`, {params}) return request.get(`course_schedule/course_schedule`, { params })
} }
/** /**
@ -18,7 +16,7 @@ export function getCourseScheduleList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getCourseScheduleInfo(id: number) { export function getCourseScheduleInfo(id: number) {
return request.get(`course_schedule/course_schedule/${id}`); return request.get(`course_schedule/course_schedule/${id}`)
} }
/** /**
@ -27,7 +25,10 @@ export function getCourseScheduleInfo(id: number) {
* @returns * @returns
*/ */
export function addCourseSchedule(params: Record<string, any>) { export function addCourseSchedule(params: Record<string, any>) {
return request.post('course_schedule/course_schedule', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post('course_schedule/course_schedule', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -37,7 +38,10 @@ export function addCourseSchedule(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editCourseSchedule(params: Record<string, any>) { export function editCourseSchedule(params: Record<string, any>) {
return request.put(`course_schedule/course_schedule/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(`course_schedule/course_schedule/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -46,9 +50,10 @@ export function editCourseSchedule(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deleteCourseSchedule(id: number) { export function deleteCourseSchedule(id: number) {
return request.delete(`course_schedule/course_schedule/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(`course_schedule/course_schedule/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
// USER_CODE_END -- course_schedule // USER_CODE_END -- course_schedule

27
admin/src/app/api/customer_resource_changes.ts

@ -7,7 +7,9 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getCustomerResourceChangesList(params: Record<string, any>) { export function getCustomerResourceChangesList(params: Record<string, any>) {
return request.get(`customer_resource_changes/customer_resource_changes`, {params}) return request.get(`customer_resource_changes/customer_resource_changes`, {
params,
})
} }
/** /**
@ -16,7 +18,9 @@ export function getCustomerResourceChangesList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getCustomerResourceChangesInfo(id: number) { export function getCustomerResourceChangesInfo(id: number) {
return request.get(`customer_resource_changes/customer_resource_changes/${id}`); return request.get(
`customer_resource_changes/customer_resource_changes/${id}`
)
} }
/** /**
@ -25,7 +29,11 @@ export function getCustomerResourceChangesInfo(id: number) {
* @returns * @returns
*/ */
export function addCustomerResourceChanges(params: Record<string, any>) { export function addCustomerResourceChanges(params: Record<string, any>) {
return request.post('customer_resource_changes/customer_resource_changes', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post(
'customer_resource_changes/customer_resource_changes',
params,
{ showErrorMessage: true, showSuccessMessage: true }
)
} }
/** /**
@ -35,7 +43,11 @@ export function addCustomerResourceChanges(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editCustomerResourceChanges(params: Record<string, any>) { export function editCustomerResourceChanges(params: Record<string, any>) {
return request.put(`customer_resource_changes/customer_resource_changes/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(
`customer_resource_changes/customer_resource_changes/${params.id}`,
params,
{ showErrorMessage: true, showSuccessMessage: true }
)
} }
/** /**
@ -44,9 +56,10 @@ export function editCustomerResourceChanges(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deleteCustomerResourceChanges(id: number) { export function deleteCustomerResourceChanges(id: number) {
return request.delete(`customer_resource_changes/customer_resource_changes/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(
`customer_resource_changes/customer_resource_changes/${id}`,
{ showErrorMessage: true, showSuccessMessage: true }
)
} }
// USER_CODE_END -- customer_resource_changes // USER_CODE_END -- customer_resource_changes

32
admin/src/app/api/customer_resources.ts

@ -1,13 +1,5 @@
import request from '@/utils/request' import request from '@/utils/request'
// USER_CODE_BEGIN -- customer_resources // USER_CODE_BEGIN -- customer_resources
/** /**
* *
@ -15,7 +7,7 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getCustomerResourcesList(params: Record<string, any>) { export function getCustomerResourcesList(params: Record<string, any>) {
return request.get(`customer_resources/customer_resources`, {params}) return request.get(`customer_resources/customer_resources`, { params })
} }
/** /**
@ -24,7 +16,7 @@ export function getCustomerResourcesList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getCustomerResourcesInfo(id: number) { export function getCustomerResourcesInfo(id: number) {
return request.get(`customer_resources/customer_resources/${id}`); return request.get(`customer_resources/customer_resources/${id}`)
} }
/** /**
@ -33,7 +25,10 @@ export function getCustomerResourcesInfo(id: number) {
* @returns * @returns
*/ */
export function addCustomerResources(params: Record<string, any>) { export function addCustomerResources(params: Record<string, any>) {
return request.post('customer_resources/customer_resources', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post('customer_resources/customer_resources', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -43,7 +38,11 @@ export function addCustomerResources(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editCustomerResources(params: Record<string, any>) { export function editCustomerResources(params: Record<string, any>) {
return request.put(`customer_resources/customer_resources/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(
`customer_resources/customer_resources/${params.id}`,
params,
{ showErrorMessage: true, showSuccessMessage: true }
)
} }
/** /**
@ -52,11 +51,14 @@ export function editCustomerResources(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deleteCustomerResources(id: number) { export function deleteCustomerResources(id: number) {
return request.delete(`customer_resources/customer_resources/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(`customer_resources/customer_resources/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
export function getWithCampusList(params: Record<string,any>){ export function getWithCampusList(params: Record<string, any>) {
return request.get('customer_resources/campus_all', {params}) return request.get('customer_resources/campus_all', { params })
} }
// USER_CODE_END -- customer_resources // USER_CODE_END -- customer_resources

23
admin/src/app/api/departments.ts

@ -7,7 +7,7 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getDepartmentsList(params: Record<string, any>) { export function getDepartmentsList(params: Record<string, any>) {
return request.get(`departments/departments`, {params}) return request.get(`departments/departments`, { params })
} }
/** /**
@ -16,7 +16,7 @@ export function getDepartmentsList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getDepartmentsInfo(id: number) { export function getDepartmentsInfo(id: number) {
return request.get(`departments/departments/${id}`); return request.get(`departments/departments/${id}`)
} }
/** /**
@ -25,7 +25,10 @@ export function getDepartmentsInfo(id: number) {
* @returns * @returns
*/ */
export function addDepartments(params: Record<string, any>) { export function addDepartments(params: Record<string, any>) {
return request.post('departments/departments', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post('departments/departments', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -35,7 +38,10 @@ export function addDepartments(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editDepartments(params: Record<string, any>) { export function editDepartments(params: Record<string, any>) {
return request.put(`departments/departments/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(`departments/departments/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -44,11 +50,14 @@ export function editDepartments(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deleteDepartments(id: number) { export function deleteDepartments(id: number) {
return request.delete(`departments/departments/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(`departments/departments/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
export function getWithDepartmentsList(params: Record<string,any>){ export function getWithDepartmentsList(params: Record<string, any>) {
return request.get('departments/departments_all', {params}) return request.get('departments/departments_all', { params })
} }
// USER_CODE_END -- departments // USER_CODE_END -- departments

21
admin/src/app/api/exam_answers.ts

@ -7,7 +7,7 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getExamAnswersList(params: Record<string, any>) { export function getExamAnswersList(params: Record<string, any>) {
return request.get(`exam_answers/exam_answers`, {params}) return request.get(`exam_answers/exam_answers`, { params })
} }
/** /**
@ -16,7 +16,7 @@ export function getExamAnswersList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getExamAnswersInfo(id: number) { export function getExamAnswersInfo(id: number) {
return request.get(`exam_answers/exam_answers/${id}`); return request.get(`exam_answers/exam_answers/${id}`)
} }
/** /**
@ -25,7 +25,10 @@ export function getExamAnswersInfo(id: number) {
* @returns * @returns
*/ */
export function addExamAnswers(params: Record<string, any>) { export function addExamAnswers(params: Record<string, any>) {
return request.post('exam_answers/exam_answers', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post('exam_answers/exam_answers', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -35,7 +38,10 @@ export function addExamAnswers(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editExamAnswers(params: Record<string, any>) { export function editExamAnswers(params: Record<string, any>) {
return request.put(`exam_answers/exam_answers/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(`exam_answers/exam_answers/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -44,9 +50,10 @@ export function editExamAnswers(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deleteExamAnswers(id: number) { export function deleteExamAnswers(id: number) {
return request.delete(`exam_answers/exam_answers/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(`exam_answers/exam_answers/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
// USER_CODE_END -- exam_answers // USER_CODE_END -- exam_answers

21
admin/src/app/api/exam_papers.ts

@ -7,7 +7,7 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getExamPapersList(params: Record<string, any>) { export function getExamPapersList(params: Record<string, any>) {
return request.get(`exam_papers/exam_papers`, {params}) return request.get(`exam_papers/exam_papers`, { params })
} }
/** /**
@ -16,7 +16,7 @@ export function getExamPapersList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getExamPapersInfo(id: number) { export function getExamPapersInfo(id: number) {
return request.get(`exam_papers/exam_papers/${id}`); return request.get(`exam_papers/exam_papers/${id}`)
} }
/** /**
@ -25,7 +25,10 @@ export function getExamPapersInfo(id: number) {
* @returns * @returns
*/ */
export function addExamPapers(params: Record<string, any>) { export function addExamPapers(params: Record<string, any>) {
return request.post('exam_papers/exam_papers', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post('exam_papers/exam_papers', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -35,7 +38,10 @@ export function addExamPapers(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editExamPapers(params: Record<string, any>) { export function editExamPapers(params: Record<string, any>) {
return request.put(`exam_papers/exam_papers/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(`exam_papers/exam_papers/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -44,9 +50,10 @@ export function editExamPapers(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deleteExamPapers(id: number) { export function deleteExamPapers(id: number) {
return request.delete(`exam_papers/exam_papers/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(`exam_papers/exam_papers/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
// USER_CODE_END -- exam_papers // USER_CODE_END -- exam_papers

21
admin/src/app/api/exam_questions.ts

@ -7,7 +7,7 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getExamQuestionsList(params: Record<string, any>) { export function getExamQuestionsList(params: Record<string, any>) {
return request.get(`exam_questions/exam_questions`, {params}) return request.get(`exam_questions/exam_questions`, { params })
} }
/** /**
@ -16,7 +16,7 @@ export function getExamQuestionsList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getExamQuestionsInfo(id: number) { export function getExamQuestionsInfo(id: number) {
return request.get(`exam_questions/exam_questions/${id}`); return request.get(`exam_questions/exam_questions/${id}`)
} }
/** /**
@ -25,7 +25,10 @@ export function getExamQuestionsInfo(id: number) {
* @returns * @returns
*/ */
export function addExamQuestions(params: Record<string, any>) { export function addExamQuestions(params: Record<string, any>) {
return request.post('exam_questions/exam_questions', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post('exam_questions/exam_questions', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -35,7 +38,10 @@ export function addExamQuestions(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editExamQuestions(params: Record<string, any>) { export function editExamQuestions(params: Record<string, any>) {
return request.put(`exam_questions/exam_questions/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(`exam_questions/exam_questions/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -44,9 +50,10 @@ export function editExamQuestions(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deleteExamQuestions(id: number) { export function deleteExamQuestions(id: number) {
return request.delete(`exam_questions/exam_questions/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(`exam_questions/exam_questions/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
// USER_CODE_END -- exam_questions // USER_CODE_END -- exam_questions

21
admin/src/app/api/exam_records.ts

@ -7,7 +7,7 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getExamRecordsList(params: Record<string, any>) { export function getExamRecordsList(params: Record<string, any>) {
return request.get(`exam_records/exam_records`, {params}) return request.get(`exam_records/exam_records`, { params })
} }
/** /**
@ -16,7 +16,7 @@ export function getExamRecordsList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getExamRecordsInfo(id: number) { export function getExamRecordsInfo(id: number) {
return request.get(`exam_records/exam_records/${id}`); return request.get(`exam_records/exam_records/${id}`)
} }
/** /**
@ -25,7 +25,10 @@ export function getExamRecordsInfo(id: number) {
* @returns * @returns
*/ */
export function addExamRecords(params: Record<string, any>) { export function addExamRecords(params: Record<string, any>) {
return request.post('exam_records/exam_records', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post('exam_records/exam_records', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -35,7 +38,10 @@ export function addExamRecords(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editExamRecords(params: Record<string, any>) { export function editExamRecords(params: Record<string, any>) {
return request.put(`exam_records/exam_records/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(`exam_records/exam_records/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -44,9 +50,10 @@ export function editExamRecords(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deleteExamRecords(id: number) { export function deleteExamRecords(id: number) {
return request.delete(`exam_records/exam_records/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(`exam_records/exam_records/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
// USER_CODE_END -- exam_records // USER_CODE_END -- exam_records

29
admin/src/app/api/market_performance.ts

@ -7,7 +7,7 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getMarketPerformanceList(params: Record<string, any>) { export function getMarketPerformanceList(params: Record<string, any>) {
return request.get(`market_performance/market_performance`, {params}) return request.get(`market_performance/market_performance`, { params })
} }
/** /**
@ -16,7 +16,7 @@ export function getMarketPerformanceList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getMarketPerformanceInfo(id: number) { export function getMarketPerformanceInfo(id: number) {
return request.get(`market_performance/market_performance/${id}`); return request.get(`market_performance/market_performance/${id}`)
} }
/** /**
@ -25,7 +25,10 @@ export function getMarketPerformanceInfo(id: number) {
* @returns * @returns
*/ */
export function addMarketPerformance(params: Record<string, any>) { export function addMarketPerformance(params: Record<string, any>) {
return request.post('market_performance/market_performance', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post('market_performance/market_performance', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -35,7 +38,11 @@ export function addMarketPerformance(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editMarketPerformance(params: Record<string, any>) { export function editMarketPerformance(params: Record<string, any>) {
return request.put(`market_performance/market_performance/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(
`market_performance/market_performance/${params.id}`,
params,
{ showErrorMessage: true, showSuccessMessage: true }
)
} }
/** /**
@ -44,13 +51,17 @@ export function editMarketPerformance(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deleteMarketPerformance(id: number) { export function deleteMarketPerformance(id: number) {
return request.delete(`market_performance/market_performance/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(`market_performance/market_performance/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
export function getWithPersonnelList(params: Record<string,any>){ export function getWithPersonnelList(params: Record<string, any>) {
return request.get('market_performance/personnel_all', {params}) return request.get('market_performance/personnel_all', { params })
}export function getWithCampusList(params: Record<string,any>){ }
return request.get('market_performance/campus_all', {params}) export function getWithCampusList(params: Record<string, any>) {
return request.get('market_performance/campus_all', { params })
} }
// USER_CODE_END -- market_performance // USER_CODE_END -- market_performance

21
admin/src/app/api/order_table.ts

@ -7,7 +7,7 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getOrderTableList(params: Record<string, any>) { export function getOrderTableList(params: Record<string, any>) {
return request.get(`order_table/order_table`, {params}) return request.get(`order_table/order_table`, { params })
} }
/** /**
@ -16,7 +16,7 @@ export function getOrderTableList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getOrderTableInfo(id: number) { export function getOrderTableInfo(id: number) {
return request.get(`order_table/order_table/${id}`); return request.get(`order_table/order_table/${id}`)
} }
/** /**
@ -25,7 +25,10 @@ export function getOrderTableInfo(id: number) {
* @returns * @returns
*/ */
export function addOrderTable(params: Record<string, any>) { export function addOrderTable(params: Record<string, any>) {
return request.post('order_table/order_table', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post('order_table/order_table', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -35,7 +38,10 @@ export function addOrderTable(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editOrderTable(params: Record<string, any>) { export function editOrderTable(params: Record<string, any>) {
return request.put(`order_table/order_table/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(`order_table/order_table/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -44,9 +50,10 @@ export function editOrderTable(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deleteOrderTable(id: number) { export function deleteOrderTable(id: number) {
return request.delete(`order_table/order_table/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(`order_table/order_table/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
// USER_CODE_END -- order_table // USER_CODE_END -- order_table

22
admin/src/app/api/performance_records.ts

@ -7,7 +7,7 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getPerformanceRecordsList(params: Record<string, any>) { export function getPerformanceRecordsList(params: Record<string, any>) {
return request.get(`performance_records/performance_records`, {params}) return request.get(`performance_records/performance_records`, { params })
} }
/** /**
@ -16,7 +16,7 @@ export function getPerformanceRecordsList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getPerformanceRecordsInfo(id: number) { export function getPerformanceRecordsInfo(id: number) {
return request.get(`performance_records/performance_records/${id}`); return request.get(`performance_records/performance_records/${id}`)
} }
/** /**
@ -25,7 +25,10 @@ export function getPerformanceRecordsInfo(id: number) {
* @returns * @returns
*/ */
export function addPerformanceRecords(params: Record<string, any>) { export function addPerformanceRecords(params: Record<string, any>) {
return request.post('performance_records/performance_records', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post('performance_records/performance_records', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -35,7 +38,11 @@ export function addPerformanceRecords(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editPerformanceRecords(params: Record<string, any>) { export function editPerformanceRecords(params: Record<string, any>) {
return request.put(`performance_records/performance_records/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(
`performance_records/performance_records/${params.id}`,
params,
{ showErrorMessage: true, showSuccessMessage: true }
)
} }
/** /**
@ -44,9 +51,10 @@ export function editPerformanceRecords(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deletePerformanceRecords(id: number) { export function deletePerformanceRecords(id: number) {
return request.delete(`performance_records/performance_records/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(`performance_records/performance_records/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
// USER_CODE_END -- performance_records // USER_CODE_END -- performance_records

24
admin/src/app/api/person_course_schedule.ts

@ -7,7 +7,9 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getPersonCourseScheduleList(params: Record<string, any>) { export function getPersonCourseScheduleList(params: Record<string, any>) {
return request.get(`person_course_schedule/person_course_schedule`, {params}) return request.get(`person_course_schedule/person_course_schedule`, {
params,
})
} }
/** /**
@ -16,7 +18,7 @@ export function getPersonCourseScheduleList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getPersonCourseScheduleInfo(id: number) { export function getPersonCourseScheduleInfo(id: number) {
return request.get(`person_course_schedule/person_course_schedule/${id}`); return request.get(`person_course_schedule/person_course_schedule/${id}`)
} }
/** /**
@ -25,7 +27,10 @@ export function getPersonCourseScheduleInfo(id: number) {
* @returns * @returns
*/ */
export function addPersonCourseSchedule(params: Record<string, any>) { export function addPersonCourseSchedule(params: Record<string, any>) {
return request.post('person_course_schedule/person_course_schedule', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post('person_course_schedule/person_course_schedule', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -35,7 +40,11 @@ export function addPersonCourseSchedule(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editPersonCourseSchedule(params: Record<string, any>) { export function editPersonCourseSchedule(params: Record<string, any>) {
return request.put(`person_course_schedule/person_course_schedule/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(
`person_course_schedule/person_course_schedule/${params.id}`,
params,
{ showErrorMessage: true, showSuccessMessage: true }
)
} }
/** /**
@ -44,9 +53,10 @@ export function editPersonCourseSchedule(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deletePersonCourseSchedule(id: number) { export function deletePersonCourseSchedule(id: number) {
return request.delete(`person_course_schedule/person_course_schedule/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(`person_course_schedule/person_course_schedule/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
// USER_CODE_END -- person_course_schedule // USER_CODE_END -- person_course_schedule

23
admin/src/app/api/physical_test.ts

@ -1,7 +1,5 @@
import request from '@/utils/request' import request from '@/utils/request'
// USER_CODE_BEGIN -- physical_test // USER_CODE_BEGIN -- physical_test
/** /**
* *
@ -9,7 +7,7 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getPhysicalTestList(params: Record<string, any>) { export function getPhysicalTestList(params: Record<string, any>) {
return request.get(`physical_test/physical_test`, {params}) return request.get(`physical_test/physical_test`, { params })
} }
/** /**
@ -18,7 +16,7 @@ export function getPhysicalTestList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getPhysicalTestInfo(id: number) { export function getPhysicalTestInfo(id: number) {
return request.get(`physical_test/physical_test/${id}`); return request.get(`physical_test/physical_test/${id}`)
} }
/** /**
@ -27,7 +25,10 @@ export function getPhysicalTestInfo(id: number) {
* @returns * @returns
*/ */
export function addPhysicalTest(params: Record<string, any>) { export function addPhysicalTest(params: Record<string, any>) {
return request.post('physical_test/physical_test', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post('physical_test/physical_test', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -37,7 +38,10 @@ export function addPhysicalTest(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editPhysicalTest(params: Record<string, any>) { export function editPhysicalTest(params: Record<string, any>) {
return request.put(`physical_test/physical_test/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(`physical_test/physical_test/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -46,9 +50,10 @@ export function editPhysicalTest(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deletePhysicalTest(id: number) { export function deletePhysicalTest(id: number) {
return request.delete(`physical_test/physical_test/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(`physical_test/physical_test/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
// USER_CODE_END -- physical_test // USER_CODE_END -- physical_test

21
admin/src/app/api/reimbursement.ts

@ -7,7 +7,7 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getReimbursementList(params: Record<string, any>) { export function getReimbursementList(params: Record<string, any>) {
return request.get(`reimbursement/reimbursement`, {params}) return request.get(`reimbursement/reimbursement`, { params })
} }
/** /**
@ -16,7 +16,7 @@ export function getReimbursementList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getReimbursementInfo(id: number) { export function getReimbursementInfo(id: number) {
return request.get(`reimbursement/reimbursement/${id}`); return request.get(`reimbursement/reimbursement/${id}`)
} }
/** /**
@ -25,7 +25,10 @@ export function getReimbursementInfo(id: number) {
* @returns * @returns
*/ */
export function addReimbursement(params: Record<string, any>) { export function addReimbursement(params: Record<string, any>) {
return request.post('reimbursement/reimbursement', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post('reimbursement/reimbursement', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -35,7 +38,10 @@ export function addReimbursement(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editReimbursement(params: Record<string, any>) { export function editReimbursement(params: Record<string, any>) {
return request.put(`reimbursement/reimbursement/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(`reimbursement/reimbursement/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -44,9 +50,10 @@ export function editReimbursement(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deleteReimbursement(id: number) { export function deleteReimbursement(id: number) {
return request.delete(`reimbursement/reimbursement/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(`reimbursement/reimbursement/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
// USER_CODE_END -- reimbursement // USER_CODE_END -- reimbursement

21
admin/src/app/api/resource_sharing.ts

@ -7,7 +7,7 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getResourceSharingList(params: Record<string, any>) { export function getResourceSharingList(params: Record<string, any>) {
return request.get(`resource_sharing/resource_sharing`, {params}) return request.get(`resource_sharing/resource_sharing`, { params })
} }
/** /**
@ -16,7 +16,7 @@ export function getResourceSharingList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getResourceSharingInfo(id: number) { export function getResourceSharingInfo(id: number) {
return request.get(`resource_sharing/resource_sharing/${id}`); return request.get(`resource_sharing/resource_sharing/${id}`)
} }
/** /**
@ -25,7 +25,10 @@ export function getResourceSharingInfo(id: number) {
* @returns * @returns
*/ */
export function addResourceSharing(params: Record<string, any>) { export function addResourceSharing(params: Record<string, any>) {
return request.post('resource_sharing/resource_sharing', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post('resource_sharing/resource_sharing', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -35,7 +38,10 @@ export function addResourceSharing(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editResourceSharing(params: Record<string, any>) { export function editResourceSharing(params: Record<string, any>) {
return request.put(`resource_sharing/resource_sharing/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(`resource_sharing/resource_sharing/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -44,9 +50,10 @@ export function editResourceSharing(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deleteResourceSharing(id: number) { export function deleteResourceSharing(id: number) {
return request.delete(`resource_sharing/resource_sharing/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(`resource_sharing/resource_sharing/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
// USER_CODE_END -- resource_sharing // USER_CODE_END -- resource_sharing

21
admin/src/app/api/salary.ts

@ -7,7 +7,7 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getSalaryList(params: Record<string, any>) { export function getSalaryList(params: Record<string, any>) {
return request.get(`salary/salary`, {params}) return request.get(`salary/salary`, { params })
} }
/** /**
@ -16,7 +16,7 @@ export function getSalaryList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getSalaryInfo(id: number) { export function getSalaryInfo(id: number) {
return request.get(`salary/salary/${id}`); return request.get(`salary/salary/${id}`)
} }
/** /**
@ -25,7 +25,10 @@ export function getSalaryInfo(id: number) {
* @returns * @returns
*/ */
export function addSalary(params: Record<string, any>) { export function addSalary(params: Record<string, any>) {
return request.post('salary/salary', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post('salary/salary', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -35,7 +38,10 @@ export function addSalary(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editSalary(params: Record<string, any>) { export function editSalary(params: Record<string, any>) {
return request.put(`salary/salary/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(`salary/salary/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -44,9 +50,10 @@ export function editSalary(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deleteSalary(id: number) { export function deleteSalary(id: number) {
return request.delete(`salary/salary/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(`salary/salary/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
// USER_CODE_END -- salary // USER_CODE_END -- salary

23
admin/src/app/api/service.ts

@ -1,7 +1,5 @@
import request from '@/utils/request' import request from '@/utils/request'
// USER_CODE_BEGIN -- service // USER_CODE_BEGIN -- service
/** /**
* *
@ -9,7 +7,7 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getServiceList(params: Record<string, any>) { export function getServiceList(params: Record<string, any>) {
return request.get(`service/service`, {params}) return request.get(`service/service`, { params })
} }
/** /**
@ -18,7 +16,7 @@ export function getServiceList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getServiceInfo(id: number) { export function getServiceInfo(id: number) {
return request.get(`service/service/${id}`); return request.get(`service/service/${id}`)
} }
/** /**
@ -27,7 +25,10 @@ export function getServiceInfo(id: number) {
* @returns * @returns
*/ */
export function addService(params: Record<string, any>) { export function addService(params: Record<string, any>) {
return request.post('service/service', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post('service/service', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -37,7 +38,10 @@ export function addService(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editService(params: Record<string, any>) { export function editService(params: Record<string, any>) {
return request.put(`service/service/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(`service/service/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -46,9 +50,10 @@ export function editService(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deleteService(id: number) { export function deleteService(id: number) {
return request.delete(`service/service/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(`service/service/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
// USER_CODE_END -- service // USER_CODE_END -- service

21
admin/src/app/api/six_speed.ts

@ -7,7 +7,7 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getSixSpeedList(params: Record<string, any>) { export function getSixSpeedList(params: Record<string, any>) {
return request.get(`six_speed/six_speed`, {params}) return request.get(`six_speed/six_speed`, { params })
} }
/** /**
@ -16,7 +16,7 @@ export function getSixSpeedList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getSixSpeedInfo(id: number) { export function getSixSpeedInfo(id: number) {
return request.get(`six_speed/six_speed/${id}`); return request.get(`six_speed/six_speed/${id}`)
} }
/** /**
@ -25,7 +25,10 @@ export function getSixSpeedInfo(id: number) {
* @returns * @returns
*/ */
export function addSixSpeed(params: Record<string, any>) { export function addSixSpeed(params: Record<string, any>) {
return request.post('six_speed/six_speed', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post('six_speed/six_speed', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -35,7 +38,10 @@ export function addSixSpeed(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editSixSpeed(params: Record<string, any>) { export function editSixSpeed(params: Record<string, any>) {
return request.put(`six_speed/six_speed/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(`six_speed/six_speed/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -44,9 +50,10 @@ export function editSixSpeed(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deleteSixSpeed(id: number) { export function deleteSixSpeed(id: number) {
return request.delete(`six_speed/six_speed/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(`six_speed/six_speed/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
// USER_CODE_END -- six_speed // USER_CODE_END -- six_speed

38
admin/src/app/api/six_speed_modification_log.ts

@ -1,9 +1,5 @@
import request from '@/utils/request' import request from '@/utils/request'
// USER_CODE_BEGIN -- six_speed_modification_log // USER_CODE_BEGIN -- six_speed_modification_log
/** /**
* *
@ -11,7 +7,9 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getSixSpeedModificationLogList(params: Record<string, any>) { export function getSixSpeedModificationLogList(params: Record<string, any>) {
return request.get(`six_speed_modification_log/six_speed_modification_log`, {params}) return request.get(`six_speed_modification_log/six_speed_modification_log`, {
params,
})
} }
/** /**
@ -20,7 +18,9 @@ export function getSixSpeedModificationLogList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getSixSpeedModificationLogInfo(id: number) { export function getSixSpeedModificationLogInfo(id: number) {
return request.get(`six_speed_modification_log/six_speed_modification_log/${id}`); return request.get(
`six_speed_modification_log/six_speed_modification_log/${id}`
)
} }
/** /**
@ -29,7 +29,11 @@ export function getSixSpeedModificationLogInfo(id: number) {
* @returns * @returns
*/ */
export function addSixSpeedModificationLog(params: Record<string, any>) { export function addSixSpeedModificationLog(params: Record<string, any>) {
return request.post('six_speed_modification_log/six_speed_modification_log', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post(
'six_speed_modification_log/six_speed_modification_log',
params,
{ showErrorMessage: true, showSuccessMessage: true }
)
} }
/** /**
@ -39,7 +43,11 @@ export function addSixSpeedModificationLog(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editSixSpeedModificationLog(params: Record<string, any>) { export function editSixSpeedModificationLog(params: Record<string, any>) {
return request.put(`six_speed_modification_log/six_speed_modification_log/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(
`six_speed_modification_log/six_speed_modification_log/${params.id}`,
params,
{ showErrorMessage: true, showSuccessMessage: true }
)
} }
/** /**
@ -48,13 +56,17 @@ export function editSixSpeedModificationLog(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deleteSixSpeedModificationLog(id: number) { export function deleteSixSpeedModificationLog(id: number) {
return request.delete(`six_speed_modification_log/six_speed_modification_log/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(
`six_speed_modification_log/six_speed_modification_log/${id}`,
{ showErrorMessage: true, showSuccessMessage: true }
)
} }
export function getWithCampusList(params: Record<string,any>){ export function getWithCampusList(params: Record<string, any>) {
return request.get('six_speed_modification_log/campus_all', {params}) return request.get('six_speed_modification_log/campus_all', { params })
}export function getWithPersonnelList(params: Record<string,any>){ }
return request.get('six_speed_modification_log/personnel_all', {params}) export function getWithPersonnelList(params: Record<string, any>) {
return request.get('six_speed_modification_log/personnel_all', { params })
} }
// USER_CODE_END -- six_speed_modification_log // USER_CODE_END -- six_speed_modification_log

21
admin/src/app/api/stat_hour.ts

@ -7,7 +7,7 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getStatHourList(params: Record<string, any>) { export function getStatHourList(params: Record<string, any>) {
return request.get(`stat_hour/stat_hour`, {params}) return request.get(`stat_hour/stat_hour`, { params })
} }
/** /**
@ -16,7 +16,7 @@ export function getStatHourList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getStatHourInfo(id: number) { export function getStatHourInfo(id: number) {
return request.get(`stat_hour/stat_hour/${id}`); return request.get(`stat_hour/stat_hour/${id}`)
} }
/** /**
@ -25,7 +25,10 @@ export function getStatHourInfo(id: number) {
* @returns * @returns
*/ */
export function addStatHour(params: Record<string, any>) { export function addStatHour(params: Record<string, any>) {
return request.post('stat_hour/stat_hour', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post('stat_hour/stat_hour', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -35,7 +38,10 @@ export function addStatHour(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editStatHour(params: Record<string, any>) { export function editStatHour(params: Record<string, any>) {
return request.put(`stat_hour/stat_hour/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(`stat_hour/stat_hour/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -44,9 +50,10 @@ export function editStatHour(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deleteStatHour(id: number) { export function deleteStatHour(id: number) {
return request.delete(`stat_hour/stat_hour/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(`stat_hour/stat_hour/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
// USER_CODE_END -- stat_hour // USER_CODE_END -- stat_hour

22
admin/src/app/api/student_course_usage.ts

@ -7,7 +7,7 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getStudentCourseUsageList(params: Record<string, any>) { export function getStudentCourseUsageList(params: Record<string, any>) {
return request.get(`student_course_usage/student_course_usage`, {params}) return request.get(`student_course_usage/student_course_usage`, { params })
} }
/** /**
@ -16,7 +16,7 @@ export function getStudentCourseUsageList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getStudentCourseUsageInfo(id: number) { export function getStudentCourseUsageInfo(id: number) {
return request.get(`student_course_usage/student_course_usage/${id}`); return request.get(`student_course_usage/student_course_usage/${id}`)
} }
/** /**
@ -25,7 +25,10 @@ export function getStudentCourseUsageInfo(id: number) {
* @returns * @returns
*/ */
export function addStudentCourseUsage(params: Record<string, any>) { export function addStudentCourseUsage(params: Record<string, any>) {
return request.post('student_course_usage/student_course_usage', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post('student_course_usage/student_course_usage', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -35,7 +38,11 @@ export function addStudentCourseUsage(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editStudentCourseUsage(params: Record<string, any>) { export function editStudentCourseUsage(params: Record<string, any>) {
return request.put(`student_course_usage/student_course_usage/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(
`student_course_usage/student_course_usage/${params.id}`,
params,
{ showErrorMessage: true, showSuccessMessage: true }
)
} }
/** /**
@ -44,9 +51,10 @@ export function editStudentCourseUsage(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deleteStudentCourseUsage(id: number) { export function deleteStudentCourseUsage(id: number) {
return request.delete(`student_course_usage/student_course_usage/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(`student_course_usage/student_course_usage/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
// USER_CODE_END -- student_course_usage // USER_CODE_END -- student_course_usage

21
admin/src/app/api/student_courses.ts

@ -7,7 +7,7 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getStudentCoursesList(params: Record<string, any>) { export function getStudentCoursesList(params: Record<string, any>) {
return request.get(`student_courses/student_courses`, {params}) return request.get(`student_courses/student_courses`, { params })
} }
/** /**
@ -16,7 +16,7 @@ export function getStudentCoursesList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getStudentCoursesInfo(id: number) { export function getStudentCoursesInfo(id: number) {
return request.get(`student_courses/student_courses/${id}`); return request.get(`student_courses/student_courses/${id}`)
} }
/** /**
@ -25,7 +25,10 @@ export function getStudentCoursesInfo(id: number) {
* @returns * @returns
*/ */
export function addStudentCourses(params: Record<string, any>) { export function addStudentCourses(params: Record<string, any>) {
return request.post('student_courses/student_courses', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post('student_courses/student_courses', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -35,7 +38,10 @@ export function addStudentCourses(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editStudentCourses(params: Record<string, any>) { export function editStudentCourses(params: Record<string, any>) {
return request.put(`student_courses/student_courses/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(`student_courses/student_courses/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -44,9 +50,10 @@ export function editStudentCourses(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deleteStudentCourses(id: number) { export function deleteStudentCourses(id: number) {
return request.delete(`student_courses/student_courses/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(`student_courses/student_courses/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
// USER_CODE_END -- student_courses // USER_CODE_END -- student_courses

21
admin/src/app/api/user_feedback.ts

@ -7,7 +7,7 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getUserFeedbackList(params: Record<string, any>) { export function getUserFeedbackList(params: Record<string, any>) {
return request.get(`user_feedback/user_feedback`, {params}) return request.get(`user_feedback/user_feedback`, { params })
} }
/** /**
@ -16,7 +16,7 @@ export function getUserFeedbackList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getUserFeedbackInfo(id: number) { export function getUserFeedbackInfo(id: number) {
return request.get(`user_feedback/user_feedback/${id}`); return request.get(`user_feedback/user_feedback/${id}`)
} }
/** /**
@ -25,7 +25,10 @@ export function getUserFeedbackInfo(id: number) {
* @returns * @returns
*/ */
export function addUserFeedback(params: Record<string, any>) { export function addUserFeedback(params: Record<string, any>) {
return request.post('user_feedback/user_feedback', params, { showErrorMessage: true, showSuccessMessage: true }) return request.post('user_feedback/user_feedback', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -35,7 +38,10 @@ export function addUserFeedback(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editUserFeedback(params: Record<string, any>) { export function editUserFeedback(params: Record<string, any>) {
return request.put(`user_feedback/user_feedback/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true }) return request.put(`user_feedback/user_feedback/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -44,9 +50,10 @@ export function editUserFeedback(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deleteUserFeedback(id: number) { export function deleteUserFeedback(id: number) {
return request.delete(`user_feedback/user_feedback/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(`user_feedback/user_feedback/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
} }
// USER_CODE_END -- user_feedback // USER_CODE_END -- user_feedback

10
admin/src/app/api/venue.ts

@ -1,5 +1,11 @@
import request from '@/utils/request' import request from '@/utils/request'
// USER_CODE_BEGIN -- venue // USER_CODE_BEGIN -- venue
/** /**
* *
@ -47,6 +53,8 @@ export function deleteVenue(id: number) {
return request.delete(`venue/venue/${id}`, { showErrorMessage: true, showSuccessMessage: true }) return request.delete(`venue/venue/${id}`, { showErrorMessage: true, showSuccessMessage: true })
} }
export function getWithCampusList(params: Record<string,any>){
return request.get('venue/campus_all', {params})
}
// USER_CODE_END -- venue // USER_CODE_END -- venue

56
admin/src/app/lang/zh-cn/attendance.attendance.json

@ -1,29 +1,29 @@
{ {
"id":"考勤编号", "id": "考勤编号",
"idPlaceholder":"请输入考勤编号", "idPlaceholder": "请输入考勤编号",
"campusId":"校区ID", "campusId": "校区ID",
"campusIdPlaceholder":"请输入校区ID", "campusIdPlaceholder": "请输入校区ID",
"staffId":"人员ID", "staffId": "人员ID",
"staffIdPlaceholder":"请输入人员ID", "staffIdPlaceholder": "请输入人员ID",
"attendanceDate":"考勤日期", "attendanceDate": "考勤日期",
"attendanceDatePlaceholder":"请输入考勤日期", "attendanceDatePlaceholder": "请输入考勤日期",
"checkInTime":"签到时间", "checkInTime": "签到时间",
"checkInTimePlaceholder":"请输入签到时间", "checkInTimePlaceholder": "请输入签到时间",
"checkOutTime":"签退时间", "checkOutTime": "签退时间",
"checkOutTimePlaceholder":"请输入签退时间", "checkOutTimePlaceholder": "请输入签退时间",
"status":"考勤状态", "status": "考勤状态",
"statusPlaceholder":"请输入考勤状态", "statusPlaceholder": "请输入考勤状态",
"remarks":"备注", "remarks": "备注",
"remarksPlaceholder":"请输入备注", "remarksPlaceholder": "请输入备注",
"createdAt":"创建时间", "createdAt": "创建时间",
"createdAtPlaceholder":"请输入创建时间", "createdAtPlaceholder": "请输入创建时间",
"updatedAt":"修改时间", "updatedAt": "修改时间",
"updatedAtPlaceholder":"请输入修改时间", "updatedAtPlaceholder": "请输入修改时间",
"coordinate":"坐标", "coordinate": "坐标",
"coordinatePlaceholder":"请输入坐标", "coordinatePlaceholder": "请输入坐标",
"addAttendance":"添加考勤", "addAttendance": "添加考勤",
"updateAttendance":"编辑考勤", "updateAttendance": "编辑考勤",
"attendanceDeleteTips":"确定要删除该数据吗?", "attendanceDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

38
admin/src/app/lang/zh-cn/campus.campus.json

@ -1,20 +1,20 @@
{ {
"campusName":"校区名称", "campusName": "校区名称",
"campusNamePlaceholder":"请输入校区名称", "campusNamePlaceholder": "请输入校区名称",
"campusAddress":"校区地址", "campusAddress": "校区地址",
"campusAddressPlaceholder":"请输入校区地址", "campusAddressPlaceholder": "请输入校区地址",
"campusPreviewImage":"校区banner", "campusPreviewImage": "校区banner",
"campusPreviewImagePlaceholder":"请选择图片", "campusPreviewImagePlaceholder": "请选择图片",
"campusCoordinates":"校区位置", "campusCoordinates": "校区位置",
"campusCoordinatesPlaceholder":"请选择校区位置", "campusCoordinatesPlaceholder": "请选择校区位置",
"campusIntroduction":"校区介绍", "campusIntroduction": "校区介绍",
"campusIntroductionPlaceholder":"请输入校区介绍", "campusIntroductionPlaceholder": "请输入校区介绍",
"campusStatus":"校区状态", "campusStatus": "校区状态",
"campusStatusPlaceholder":"请输入校区状态", "campusStatusPlaceholder": "请输入校区状态",
"createTime":"校区创建时间", "createTime": "校区创建时间",
"addCampus":"添加校区", "addCampus": "添加校区",
"updateCampus":"编辑校区", "updateCampus": "编辑校区",
"campusDeleteTips":"确定要删除该数据吗?", "campusDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

32
admin/src/app/lang/zh-cn/campus_person_role.campus_person_role.json

@ -1,17 +1,17 @@
{ {
"id":"关系编号", "id": "关系编号",
"idPlaceholder":"请输入关系编号", "idPlaceholder": "请输入关系编号",
"campusId":"校区", "campusId": "校区",
"campusIdPlaceholder":"全部", "campusIdPlaceholder": "全部",
"personId":"人员", "personId": "人员",
"personIdPlaceholder":"全部", "personIdPlaceholder": "全部",
"roleId":"角色", "roleId": "角色",
"roleIdPlaceholder":"全部", "roleIdPlaceholder": "全部",
"deptId":"部门表", "deptId": "部门表",
"deptIdPlaceholder":"全部", "deptIdPlaceholder": "全部",
"addCampusPersonRole":"添加角色关系", "addCampusPersonRole": "添加角色关系",
"updateCampusPersonRole":"编辑角色关系", "updateCampusPersonRole": "编辑角色关系",
"campusPersonRoleDeleteTips":"确定要删除该数据吗?", "campusPersonRoleDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

68
admin/src/app/lang/zh-cn/class.class.json

@ -1,35 +1,35 @@
{ {
"id":"班级编号", "id": "班级编号",
"idPlaceholder":"请输入班级编号", "idPlaceholder": "请输入班级编号",
"campusId":"校区ID", "campusId": "校区ID",
"campusIdPlaceholder":"请输入校区ID", "campusIdPlaceholder": "请输入校区ID",
"campusName":"校区名称", "campusName": "校区名称",
"campusNamePlaceholder":"请输入校区名称", "campusNamePlaceholder": "请输入校区名称",
"className":"班级名称", "className": "班级名称",
"classNamePlaceholder":"请输入班级名称", "classNamePlaceholder": "请输入班级名称",
"headCoach":"班级主教练", "headCoach": "班级主教练",
"headCoachPlaceholder":"请输入班级主教练", "headCoachPlaceholder": "请输入班级主教练",
"ageGroup":"班级授课年龄段", "ageGroup": "班级授课年龄段",
"ageGroupPlaceholder":"请输入班级授课年龄段", "ageGroupPlaceholder": "请输入班级授课年龄段",
"classType":"班级类型", "classType": "班级类型",
"classTypePlaceholder":"请输入班级类型", "classTypePlaceholder": "请输入班级类型",
"assistantCoach":"班级助教", "assistantCoach": "班级助教",
"assistantCoachPlaceholder":"请输入班级助教", "assistantCoachPlaceholder": "请输入班级助教",
"createdAt":"创建时间", "createdAt": "创建时间",
"createdAtPlaceholder":"请输入创建时间", "createdAtPlaceholder": "请输入创建时间",
"updatedAt":"修改时间", "updatedAt": "修改时间",
"updatedAtPlaceholder":"请输入修改时间", "updatedAtPlaceholder": "请输入修改时间",
"deletedAt":"逻辑删除时间", "deletedAt": "逻辑删除时间",
"deletedAtPlaceholder":"请输入逻辑删除时间", "deletedAtPlaceholder": "请输入逻辑删除时间",
"status":"班级状态", "status": "班级状态",
"statusPlaceholder":"请输入班级状态", "statusPlaceholder": "请输入班级状态",
"sortOrder":"班级排序", "sortOrder": "班级排序",
"sortOrderPlaceholder":"请输入班级排序", "sortOrderPlaceholder": "请输入班级排序",
"remarks":"班级备注", "remarks": "班级备注",
"remarksPlaceholder":"请输入班级备注", "remarksPlaceholder": "请输入班级备注",
"addClass":"添加班级", "addClass": "添加班级",
"updateClass":"编辑班级", "updateClass": "编辑班级",
"classDeleteTips":"确定要删除该数据吗?", "classDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

60
admin/src/app/lang/zh-cn/communication_records.communication_records.json

@ -1,31 +1,31 @@
{ {
"id":"沟通记录编号", "id": "沟通记录编号",
"idPlaceholder":"请输入沟通记录编号", "idPlaceholder": "请输入沟通记录编号",
"staffId":"员工ID", "staffId": "员工ID",
"staffIdPlaceholder":"请输入员工ID", "staffIdPlaceholder": "请输入员工ID",
"resourceId":"资源ID", "resourceId": "资源ID",
"resourceIdPlaceholder":"请输入资源ID", "resourceIdPlaceholder": "请输入资源ID",
"resourceType":"资源类型(如设备、文件、系统等)", "resourceType": "资源类型(如设备、文件、系统等)",
"resourceTypePlaceholder":"请输入资源类型(如设备、文件、系统等)", "resourceTypePlaceholder": "请输入资源类型(如设备、文件、系统等)",
"communicationType":"沟通类型: phone-电话, email-邮件, meeting-会议, other-其他", "communicationType": "沟通类型: phone-电话, email-邮件, meeting-会议, other-其他",
"communicationTypePlaceholder":"请输入沟通类型: phone-电话, email-邮件, meeting-会议, other-其他", "communicationTypePlaceholder": "请输入沟通类型: phone-电话, email-邮件, meeting-会议, other-其他",
"communicationResult":"沟通结果: success-成功, failure-失败, pending-待定", "communicationResult": "沟通结果: success-成功, failure-失败, pending-待定",
"communicationResultPlaceholder":"请输入沟通结果: success-成功, failure-失败, pending-待定", "communicationResultPlaceholder": "请输入沟通结果: success-成功, failure-失败, pending-待定",
"communicationTime":"沟通时间", "communicationTime": "沟通时间",
"communicationTimePlaceholder":"请输入沟通时间", "communicationTimePlaceholder": "请输入沟通时间",
"remarks":"备注", "remarks": "备注",
"remarksPlaceholder":"请输入备注", "remarksPlaceholder": "请输入备注",
"tag":"标签: high-高, medium-中, low-低", "tag": "标签: high-高, medium-中, low-低",
"tagPlaceholder":"请输入标签: high-高, medium-中, low-低", "tagPlaceholder": "请输入标签: high-高, medium-中, low-低",
"businessId":"关联的业务ID", "businessId": "关联的业务ID",
"businessIdPlaceholder":"请输入关联的业务ID", "businessIdPlaceholder": "请输入关联的业务ID",
"createdAt":"创建时间", "createdAt": "创建时间",
"createdAtPlaceholder":"请输入创建时间", "createdAtPlaceholder": "请输入创建时间",
"updatedAt":"修改时间", "updatedAt": "修改时间",
"updatedAtPlaceholder":"请输入修改时间", "updatedAtPlaceholder": "请输入修改时间",
"addCommunicationRecords":"添加沟通记录", "addCommunicationRecords": "添加沟通记录",
"updateCommunicationRecords":"编辑沟通记录", "updateCommunicationRecords": "编辑沟通记录",
"communicationRecordsDeleteTips":"确定要删除该数据吗?", "communicationRecordsDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

48
admin/src/app/lang/zh-cn/contract.contract.json

@ -1,25 +1,25 @@
{ {
"id":"合同编号", "id": "合同编号",
"idPlaceholder":"请输入合同编号", "idPlaceholder": "请输入合同编号",
"contractName":"合同名称", "contractName": "合同名称",
"contractNamePlaceholder":"请输入合同名称", "contractNamePlaceholder": "请输入合同名称",
"contractTemplate":"合同模板", "contractTemplate": "合同模板",
"contractTemplatePlaceholder":"请输入合同模板", "contractTemplatePlaceholder": "请输入合同模板",
"contractStatus":"合同状态", "contractStatus": "合同状态",
"contractStatusPlaceholder":"请输入合同状态", "contractStatusPlaceholder": "请输入合同状态",
"contractType":"合同类型", "contractType": "合同类型",
"contractTypePlaceholder":"请输入合同类型", "contractTypePlaceholder": "请输入合同类型",
"remarks":"合同备注", "remarks": "合同备注",
"remarksPlaceholder":"请输入合同备注", "remarksPlaceholder": "请输入合同备注",
"createdAt":"创建时间", "createdAt": "创建时间",
"createdAtPlaceholder":"请输入创建时间", "createdAtPlaceholder": "请输入创建时间",
"updatedAt":"修改时间", "updatedAt": "修改时间",
"updatedAtPlaceholder":"请输入修改时间", "updatedAtPlaceholder": "请输入修改时间",
"deletedAt":"逻辑删除时间", "deletedAt": "逻辑删除时间",
"deletedAtPlaceholder":"请输入逻辑删除时间", "deletedAtPlaceholder": "请输入逻辑删除时间",
"addContract":"添加合同", "addContract": "添加合同",
"updateContract":"编辑合同", "updateContract": "编辑合同",
"contractDeleteTips":"确定要删除该数据吗?", "contractDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

52
admin/src/app/lang/zh-cn/course.course.json

@ -1,27 +1,27 @@
{ {
"id":"课程编号", "id": "课程编号",
"idPlaceholder":"请输入课程编号", "idPlaceholder": "请输入课程编号",
"courseName":"课程名称", "courseName": "课程名称",
"courseNamePlaceholder":"请输入课程名称", "courseNamePlaceholder": "请输入课程名称",
"courseType":"课程类型", "courseType": "课程类型",
"courseTypePlaceholder":"请输入课程类型", "courseTypePlaceholder": "请输入课程类型",
"duration":"课程时长", "duration": "课程时长",
"durationPlaceholder":"请输入课程时长", "durationPlaceholder": "请输入课程时长",
"sessionCount":"课时数量", "sessionCount": "课时数量",
"sessionCountPlaceholder":"请输入课时数量", "sessionCountPlaceholder": "请输入课时数量",
"singleSessionCount":"单次逍客数量", "singleSessionCount": "单次逍客数量",
"singleSessionCountPlaceholder":"请输入单次逍客数量", "singleSessionCountPlaceholder": "请输入单次逍客数量",
"price":"课程价格", "price": "课程价格",
"pricePlaceholder":"请输入课程价格", "pricePlaceholder": "请输入课程价格",
"internalReminder":"内部提醒课时", "internalReminder": "内部提醒课时",
"internalReminderPlaceholder":"请输入内部提醒课时", "internalReminderPlaceholder": "请输入内部提醒课时",
"customerReminder":"客户提醒课时", "customerReminder": "客户提醒课时",
"customerReminderPlaceholder":"请输入客户提醒课时", "customerReminderPlaceholder": "请输入客户提醒课时",
"remarks":"课程备注", "remarks": "课程备注",
"remarksPlaceholder":"请输入课程备注", "remarksPlaceholder": "请输入课程备注",
"addCourse":"添加课程", "addCourse": "添加课程",
"updateCourse":"编辑课程", "updateCourse": "编辑课程",
"courseDeleteTips":"确定要删除该数据吗?", "courseDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

56
admin/src/app/lang/zh-cn/course_schedule.course_schedule.json

@ -1,29 +1,29 @@
{ {
"id":"课程安排编号", "id": "课程安排编号",
"idPlaceholder":"请输入课程安排编号", "idPlaceholder": "请输入课程安排编号",
"campusId":"校区ID", "campusId": "校区ID",
"campusIdPlaceholder":"请输入校区ID", "campusIdPlaceholder": "请输入校区ID",
"venueId":"场地ID", "venueId": "场地ID",
"venueIdPlaceholder":"请输入场地ID", "venueIdPlaceholder": "请输入场地ID",
"courseDate":"上课日期", "courseDate": "上课日期",
"courseDatePlaceholder":"请输入上课日期", "courseDatePlaceholder": "请输入上课日期",
"timeSlot":"上课时段", "timeSlot": "上课时段",
"timeSlotPlaceholder":"请输入上课时段", "timeSlotPlaceholder": "请输入上课时段",
"courseId":"课程ID", "courseId": "课程ID",
"courseIdPlaceholder":"请输入课程ID", "courseIdPlaceholder": "请输入课程ID",
"coachId":"上课教练ID", "coachId": "上课教练ID",
"coachIdPlaceholder":"请输入上课教练ID", "coachIdPlaceholder": "请输入上课教练ID",
"participants":"参与人员列表", "participants": "参与人员列表",
"participantsPlaceholder":"请输入参与人员列表", "participantsPlaceholder": "请输入参与人员列表",
"studentIds":"上课学生列表", "studentIds": "上课学生列表",
"studentIdsPlaceholder":"请输入上课学生列表", "studentIdsPlaceholder": "请输入上课学生列表",
"availableCapacity":"根据场地容量判断的可安排学员位置数量", "availableCapacity": "根据场地容量判断的可安排学员位置数量",
"availableCapacityPlaceholder":"请输入根据场地容量判断的可安排学员位置数量", "availableCapacityPlaceholder": "请输入根据场地容量判断的可安排学员位置数量",
"status":"课程状态:", "status": "课程状态:",
"statusPlaceholder":"请输入课程状态:", "statusPlaceholder": "请输入课程状态:",
"addCourseSchedule":"添加课程安排", "addCourseSchedule": "添加课程安排",
"updateCourseSchedule":"编辑课程安排", "updateCourseSchedule": "编辑课程安排",
"courseScheduleDeleteTips":"确定要删除该数据吗?", "courseScheduleDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

40
admin/src/app/lang/zh-cn/customer_resource_changes.customer_resource_changes.json

@ -1,21 +1,21 @@
{ {
"id":"修改编号", "id": "修改编号",
"idPlaceholder":"请输入修改编号", "idPlaceholder": "请输入修改编号",
"customerResourceId":"客户资源的ID", "customerResourceId": "客户资源的ID",
"customerResourceIdPlaceholder":"请输入客户资源的ID", "customerResourceIdPlaceholder": "请输入客户资源的ID",
"operatorId":"操作人的ID", "operatorId": "操作人的ID",
"operatorIdPlaceholder":"请输入操作人的ID", "operatorIdPlaceholder": "请输入操作人的ID",
"campusId":"操作校区的ID", "campusId": "操作校区的ID",
"campusIdPlaceholder":"请输入操作校区的ID", "campusIdPlaceholder": "请输入操作校区的ID",
"modifiedFields":"修改的哪些字段", "modifiedFields": "修改的哪些字段",
"modifiedFieldsPlaceholder":"请输入修改的哪些字段", "modifiedFieldsPlaceholder": "请输入修改的哪些字段",
"oldValues":"修改前的值", "oldValues": "修改前的值",
"oldValuesPlaceholder":"请输入修改前的值", "oldValuesPlaceholder": "请输入修改前的值",
"newValues":"修改后的值", "newValues": "修改后的值",
"newValuesPlaceholder":"请输入修改后的值", "newValuesPlaceholder": "请输入修改后的值",
"addCustomerResourceChanges":"添加客户资源表变更记录", "addCustomerResourceChanges": "添加客户资源表变更记录",
"updateCustomerResourceChanges":"编辑客户资源表变更记录", "updateCustomerResourceChanges": "编辑客户资源表变更记录",
"customerResourceChangesDeleteTips":"确定要删除该数据吗?", "customerResourceChangesDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

74
admin/src/app/lang/zh-cn/customer_resources.customer_resources.json

@ -1,38 +1,38 @@
{ {
"source":"来源", "source": "来源",
"sourcePlaceholder":"请输入来源", "sourcePlaceholder": "请输入来源",
"sourceChannel":"来源渠道", "sourceChannel": "来源渠道",
"sourceChannelPlaceholder":"请输入来源渠道", "sourceChannelPlaceholder": "请输入来源渠道",
"consultant":"顾问", "consultant": "顾问",
"name":"姓名", "name": "姓名",
"namePlaceholder":"请输入姓名", "namePlaceholder": "请输入姓名",
"age":"年龄", "age": "年龄",
"agePlaceholder":"请输入年龄", "agePlaceholder": "请输入年龄",
"gender":"性别", "gender": "性别",
"genderPlaceholder":"请输入性别", "genderPlaceholder": "请输入性别",
"phoneNumber":"联系电话", "phoneNumber": "联系电话",
"phoneNumberPlaceholder":"请输入联系电话", "phoneNumberPlaceholder": "请输入联系电话",
"demand":"需求", "demand": "需求",
"demandPlaceholder":"请输入需求", "demandPlaceholder": "请输入需求",
"purchasingPower":"购买力", "purchasingPower": "购买力",
"purchasingPowerPlaceholder":"请输入购买力", "purchasingPowerPlaceholder": "请输入购买力",
"cognitiveIdea":"认知理念", "cognitiveIdea": "认知理念",
"cognitiveIdeaPlaceholder":"请输入认知理念", "cognitiveIdeaPlaceholder": "请输入认知理念",
"optionalClassTime":"可选上课时间", "optionalClassTime": "可选上课时间",
"optionalClassTimePlaceholder":"请输入可选上课时间", "optionalClassTimePlaceholder": "请输入可选上课时间",
"distance":"距离", "distance": "距离",
"distancePlaceholder":"请输入距离", "distancePlaceholder": "请输入距离",
"decisionMaker":"决策人", "decisionMaker": "决策人",
"decisionMakerPlaceholder":"请输入决策人", "decisionMakerPlaceholder": "请输入决策人",
"initialIntent":"客户初步意向度", "initialIntent": "客户初步意向度",
"initialIntentPlaceholder":"请输入客户初步意向度", "initialIntentPlaceholder": "请输入客户初步意向度",
"campus":"所属校区", "campus": "所属校区",
"campusPlaceholder":"请输入所属校区", "campusPlaceholder": "请输入所属校区",
"status":"客户状态", "status": "客户状态",
"statusPlaceholder":"请输入客户状态", "statusPlaceholder": "请输入客户状态",
"addCustomerResources":"添加客户资源", "addCustomerResources": "添加客户资源",
"updateCustomerResources":"编辑客户资源", "updateCustomerResources": "编辑客户资源",
"customerResourcesDeleteTips":"确定要删除该数据吗?", "customerResourcesDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

26
admin/src/app/lang/zh-cn/departments.departments.json

@ -1,15 +1,13 @@
{ {
"id":"部门编号", "id": "部门编号",
"idPlaceholder":"请输入部门编号", "idPlaceholder": "请输入部门编号",
"departmentName":"部门名称", "departmentName": "部门名称",
"departmentNamePlaceholder":"请输入部门名称", "departmentNamePlaceholder": "请输入部门名称",
"parentDepartmentId":"上级部门ID", "parentDepartmentId": "上级部门ID",
"parentDepartmentIdPlaceholder":"全部", "parentDepartmentIdPlaceholder": "全部",
"createdAt":"创建时间", "addDepartments": "添加部门",
"updatedAt":"修改时间", "updateDepartments": "编辑部门",
"addDepartments":"添加部门", "departmentsDeleteTips": "确定要删除该数据吗?",
"updateDepartments":"编辑部门", "startDate": "请选择开始时间",
"departmentsDeleteTips":"确定要删除该数据吗?", "endDate": "请选择结束时间"
"startDate":"请选择开始时间", }
"endDate":"请选择结束时间"
}

36
admin/src/app/lang/zh-cn/exam_answers.exam_answers.json

@ -1,19 +1,19 @@
{ {
"id":"答题记录编号", "id": "答题记录编号",
"idPlaceholder":"请输入答题记录编号", "idPlaceholder": "请输入答题记录编号",
"campusId":"校区ID", "campusId": "校区ID",
"campusIdPlaceholder":"请输入校区ID", "campusIdPlaceholder": "请输入校区ID",
"userId":"人员ID", "userId": "人员ID",
"userIdPlaceholder":"请输入人员ID", "userIdPlaceholder": "请输入人员ID",
"questionId":"试题ID", "questionId": "试题ID",
"questionIdPlaceholder":"请输入试题ID", "questionIdPlaceholder": "请输入试题ID",
"answer":"用户答案", "answer": "用户答案",
"answerPlaceholder":"请输入用户答案", "answerPlaceholder": "请输入用户答案",
"isCorrect":"是否正确", "isCorrect": "是否正确",
"isCorrectPlaceholder":"请输入是否正确", "isCorrectPlaceholder": "请输入是否正确",
"addExamAnswers":"添加答题记录", "addExamAnswers": "添加答题记录",
"updateExamAnswers":"编辑答题记录", "updateExamAnswers": "编辑答题记录",
"examAnswersDeleteTips":"确定要删除该数据吗?", "examAnswersDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

28
admin/src/app/lang/zh-cn/exam_papers.exam_papers.json

@ -1,15 +1,15 @@
{ {
"id":"试卷编号", "id": "试卷编号",
"idPlaceholder":"请输入试卷编号", "idPlaceholder": "请输入试卷编号",
"selectionMode":"题目选择模式: random-随机主题, manual-自选题目", "selectionMode": "题目选择模式: random-随机主题, manual-自选题目",
"selectionModePlaceholder":"请输入题目选择模式: random-随机主题, manual-自选题目", "selectionModePlaceholder": "请输入题目选择模式: random-随机主题, manual-自选题目",
"totalScore":"总分", "totalScore": "总分",
"totalScorePlaceholder":"请输入总分", "totalScorePlaceholder": "请输入总分",
"passingScore":"合格分数", "passingScore": "合格分数",
"passingScorePlaceholder":"请输入合格分数", "passingScorePlaceholder": "请输入合格分数",
"addExamPapers":"添加试卷", "addExamPapers": "添加试卷",
"updateExamPapers":"编辑试卷", "updateExamPapers": "编辑试卷",
"examPapersDeleteTips":"确定要删除该数据吗?", "examPapersDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

4
admin/src/app/lang/zh-cn/exam_questions.exam_questions.json

@ -23,8 +23,8 @@
"optionDContentTypePlaceholder":"请输入选项D类型: text-文本, image-图片", "optionDContentTypePlaceholder":"请输入选项D类型: text-文本, image-图片",
"optionDContent":"选项D内容(如果是图片则存储URL)", "optionDContent":"选项D内容(如果是图片则存储URL)",
"optionDContentPlaceholder":"请输入选项D内容(如果是图片则存储URL)", "optionDContentPlaceholder":"请输入选项D内容(如果是图片则存储URL)",
"correctAnswer":"正确答案(如果是多选,答案格式为如"A,B,D")", "correctAnswer":"正确答案(如果是多选,答案格式为如A,B,D)",
"correctAnswerPlaceholder":"请输入正确答案(如果是多选,答案格式为如"A,B,D")", "correctAnswerPlaceholder":"请输入正确答案(如果是多选,答案格式为如A,B,D)",
"addExamQuestions":"添加试题", "addExamQuestions":"添加试题",
"updateExamQuestions":"编辑试题", "updateExamQuestions":"编辑试题",
"examQuestionsDeleteTips":"确定要删除该数据吗?", "examQuestionsDeleteTips":"确定要删除该数据吗?",

2
admin/src/app/lang/zh-cn/exam_questions.exam_questions_edit.json

@ -10,7 +10,7 @@
"optionCContent":"选项C内容(如果是图片则存储URL)", "optionCContent":"选项C内容(如果是图片则存储URL)",
"optionDContentType":"选项D类型: text-文本, image-图片", "optionDContentType":"选项D类型: text-文本, image-图片",
"optionDContent":"选项D内容(如果是图片则存储URL)", "optionDContent":"选项D内容(如果是图片则存储URL)",
"correctAnswer":"正确答案(如果是多选,答案格式为如"A,B,D")", "correctAnswer":"正确答案(如果是多选,答案格式为如A,B,D)",
"questionTypePlaceholder":"请输入题型: single_choice-单选, multiple_choice-多选, true_false-判断", "questionTypePlaceholder":"请输入题型: single_choice-单选, multiple_choice-多选, true_false-判断",
"questionContentTypePlaceholder":"请输入题干类型: text-文本, image-图片", "questionContentTypePlaceholder":"请输入题干类型: text-文本, image-图片",
"questionContentPlaceholder":"请输入题干内容(如果是图片则存储URL)", "questionContentPlaceholder":"请输入题干内容(如果是图片则存储URL)",

44
admin/src/app/lang/zh-cn/exam_records.exam_records.json

@ -1,23 +1,23 @@
{ {
"id":"记录编号", "id": "记录编号",
"idPlaceholder":"请输入记录编号", "idPlaceholder": "请输入记录编号",
"campusId":"校区ID", "campusId": "校区ID",
"campusIdPlaceholder":"请输入校区ID", "campusIdPlaceholder": "请输入校区ID",
"userId":"人员ID", "userId": "人员ID",
"userIdPlaceholder":"请输入人员ID", "userIdPlaceholder": "请输入人员ID",
"paperId":"试卷ID", "paperId": "试卷ID",
"paperIdPlaceholder":"请输入试卷ID", "paperIdPlaceholder": "请输入试卷ID",
"score":"得分", "score": "得分",
"scorePlaceholder":"请输入得分", "scorePlaceholder": "请输入得分",
"status":"考试状态: in_progress-进行中, completed-已完成", "status": "考试状态: in_progress-进行中, completed-已完成",
"statusPlaceholder":"请输入考试状态: in_progress-进行中, completed-已完成", "statusPlaceholder": "请输入考试状态: in_progress-进行中, completed-已完成",
"startTime":"考试开始时间", "startTime": "考试开始时间",
"startTimePlaceholder":"请输入考试开始时间", "startTimePlaceholder": "请输入考试开始时间",
"endTime":"考试结束时间", "endTime": "考试结束时间",
"endTimePlaceholder":"请输入考试结束时间", "endTimePlaceholder": "请输入考试结束时间",
"addExamRecords":"添加考试记录", "addExamRecords": "添加考试记录",
"updateExamRecords":"编辑考试记录", "updateExamRecords": "编辑考试记录",
"examRecordsDeleteTips":"确定要删除该数据吗?", "examRecordsDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

24
admin/src/app/lang/zh-cn/market_performance.market_performance.json

@ -1,13 +1,13 @@
{ {
"personnelId":"人员", "personnelId": "人员",
"personnelIdPlaceholder":"请输入人员", "personnelIdPlaceholder": "请输入人员",
"campusId":"校区", "campusId": "校区",
"campusIdPlaceholder":"全部", "campusIdPlaceholder": "全部",
"performanceAmount":"绩效金额", "performanceAmount": "绩效金额",
"performanceAmountPlaceholder":"请输入绩效金额", "performanceAmountPlaceholder": "请输入绩效金额",
"addMarketPerformance":"添加市场绩效", "addMarketPerformance": "添加市场绩效",
"updateMarketPerformance":"编辑市场绩效", "updateMarketPerformance": "编辑市场绩效",
"marketPerformanceDeleteTips":"确定要删除该数据吗?", "marketPerformanceDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

68
admin/src/app/lang/zh-cn/order_table.order_table.json

@ -1,35 +1,35 @@
{ {
"id":"订单编号", "id": "订单编号",
"idPlaceholder":"请输入订单编号", "idPlaceholder": "请输入订单编号",
"paymentId":"支付编号", "paymentId": "支付编号",
"paymentIdPlaceholder":"请输入支付编号", "paymentIdPlaceholder": "请输入支付编号",
"orderStatus":"订单状态: pending-待支付, paid-已支付", "orderStatus": "订单状态: pending-待支付, paid-已支付",
"orderStatusPlaceholder":"请输入订单状态: pending-待支付, paid-已支付", "orderStatusPlaceholder": "请输入订单状态: pending-待支付, paid-已支付",
"paymentType":"付款类型: cash-现金支付, scan_code-扫码支付, subscription-订阅支付", "paymentType": "付款类型: cash-现金支付, scan_code-扫码支付, subscription-订阅支付",
"paymentTypePlaceholder":"请输入付款类型: cash-现金支付, scan_code-扫码支付, subscription-订阅支付", "paymentTypePlaceholder": "请输入付款类型: cash-现金支付, scan_code-扫码支付, subscription-订阅支付",
"orderAmount":"订单金额", "orderAmount": "订单金额",
"orderAmountPlaceholder":"请输入订单金额", "orderAmountPlaceholder": "请输入订单金额",
"courseId":"课程ID", "courseId": "课程ID",
"courseIdPlaceholder":"请输入课程ID", "courseIdPlaceholder": "请输入课程ID",
"classId":"班级ID", "classId": "班级ID",
"classIdPlaceholder":"请输入班级ID", "classIdPlaceholder": "请输入班级ID",
"staffId":"人员ID", "staffId": "人员ID",
"staffIdPlaceholder":"请输入人员ID", "staffIdPlaceholder": "请输入人员ID",
"resourceId":"资源ID", "resourceId": "资源ID",
"resourceIdPlaceholder":"请输入资源ID", "resourceIdPlaceholder": "请输入资源ID",
"afterSalesStatus":"售后状态", "afterSalesStatus": "售后状态",
"afterSalesStatusPlaceholder":"请输入售后状态", "afterSalesStatusPlaceholder": "请输入售后状态",
"afterSalesReason":"售后原因", "afterSalesReason": "售后原因",
"afterSalesReasonPlaceholder":"请输入售后原因", "afterSalesReasonPlaceholder": "请输入售后原因",
"afterSalesTime":"售后时间", "afterSalesTime": "售后时间",
"afterSalesTimePlaceholder":"请输入售后时间", "afterSalesTimePlaceholder": "请输入售后时间",
"paymentTime":"支付时间", "paymentTime": "支付时间",
"paymentTimePlaceholder":"请输入支付时间", "paymentTimePlaceholder": "请输入支付时间",
"subscriptionPaymentTime":"订阅支付生成时间", "subscriptionPaymentTime": "订阅支付生成时间",
"subscriptionPaymentTimePlaceholder":"请输入订阅支付生成时间", "subscriptionPaymentTimePlaceholder": "请输入订阅支付生成时间",
"addOrderTable":"添加订单", "addOrderTable": "添加订单",
"updateOrderTable":"编辑订单", "updateOrderTable": "编辑订单",
"orderTableDeleteTips":"确定要删除该数据吗?", "orderTableDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

44
admin/src/app/lang/zh-cn/performance_records.performance_records.json

@ -1,23 +1,23 @@
{ {
"id":"绩效编号", "id": "绩效编号",
"idPlaceholder":"请输入绩效编号", "idPlaceholder": "请输入绩效编号",
"staffId":"员工ID", "staffId": "员工ID",
"staffIdPlaceholder":"请输入员工ID", "staffIdPlaceholder": "请输入员工ID",
"resourceId":"资源ID", "resourceId": "资源ID",
"resourceIdPlaceholder":"请输入资源ID", "resourceIdPlaceholder": "请输入资源ID",
"orderId":"订单ID", "orderId": "订单ID",
"orderIdPlaceholder":"请输入订单ID", "orderIdPlaceholder": "请输入订单ID",
"orderStatus":"订单状态: pending-待处理, completed-已完成, cancelled-已取消", "orderStatus": "订单状态: pending-待处理, completed-已完成, cancelled-已取消",
"orderStatusPlaceholder":"请输入订单状态: pending-待处理, completed-已完成, cancelled-已取消", "orderStatusPlaceholder": "请输入订单状态: pending-待处理, completed-已完成, cancelled-已取消",
"performanceType":"绩效类型: sales-销售绩效, marketing-市场绩效, other-其他", "performanceType": "绩效类型: sales-销售绩效, marketing-市场绩效, other-其他",
"performanceTypePlaceholder":"请输入绩效类型: sales-销售绩效, marketing-市场绩效, other-其他", "performanceTypePlaceholder": "请输入绩效类型: sales-销售绩效, marketing-市场绩效, other-其他",
"performanceValue":"绩效金额或分值", "performanceValue": "绩效金额或分值",
"performanceValuePlaceholder":"请输入绩效金额或分值", "performanceValuePlaceholder": "请输入绩效金额或分值",
"remarks":"备注", "remarks": "备注",
"remarksPlaceholder":"请输入备注", "remarksPlaceholder": "请输入备注",
"addPerformanceRecords":"添加绩效记录", "addPerformanceRecords": "添加绩效记录",
"updatePerformanceRecords":"编辑绩效记录", "updatePerformanceRecords": "编辑绩效记录",
"performanceRecordsDeleteTips":"确定要删除该数据吗?", "performanceRecordsDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

36
admin/src/app/lang/zh-cn/person_course_schedule.person_course_schedule.json

@ -1,19 +1,19 @@
{ {
"id":"关系编号", "id": "关系编号",
"idPlaceholder":"请输入关系编号", "idPlaceholder": "请输入关系编号",
"personId":"人员或资源ID", "personId": "人员或资源ID",
"personIdPlaceholder":"请输入人员或资源ID", "personIdPlaceholder": "请输入人员或资源ID",
"personType":"人员类型: student-正式学员, customer_resource-客户资源", "personType": "人员类型: student-正式学员, customer_resource-客户资源",
"personTypePlaceholder":"请输入人员类型: student-正式学员, customer_resource-客户资源", "personTypePlaceholder": "请输入人员类型: student-正式学员, customer_resource-客户资源",
"scheduleId":"课程安排ID", "scheduleId": "课程安排ID",
"scheduleIdPlaceholder":"请输入课程安排ID", "scheduleIdPlaceholder": "请输入课程安排ID",
"courseDate":"上课日期", "courseDate": "上课日期",
"courseDatePlaceholder":"请输入上课日期", "courseDatePlaceholder": "请输入上课日期",
"timeSlot":"上课时段", "timeSlot": "上课时段",
"timeSlotPlaceholder":"请输入上课时段", "timeSlotPlaceholder": "请输入上课时段",
"addPersonCourseSchedule":"添加人员与课程安排关系", "addPersonCourseSchedule": "添加人员与课程安排关系",
"updatePersonCourseSchedule":"编辑人员与课程安排关系", "updatePersonCourseSchedule": "编辑人员与课程安排关系",
"personCourseScheduleDeleteTips":"确定要删除该数据吗?", "personCourseScheduleDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

84
admin/src/app/lang/zh-cn/physical_test.physical_test.json

@ -1,43 +1,43 @@
{ {
"id":"体测编号", "id": "体测编号",
"idPlaceholder":"请输入体测编号", "idPlaceholder": "请输入体测编号",
"resourceId":"资源ID", "resourceId": "资源ID",
"resourceIdPlaceholder":"请输入资源ID", "resourceIdPlaceholder": "请输入资源ID",
"studentId":"学员ID", "studentId": "学员ID",
"studentIdPlaceholder":"请输入学员ID", "studentIdPlaceholder": "请输入学员ID",
"height":"身高", "height": "身高",
"heightPlaceholder":"请输入身高", "heightPlaceholder": "请输入身高",
"weight":"体重", "weight": "体重",
"weightPlaceholder":"请输入体重", "weightPlaceholder": "请输入体重",
"coachId":"教练ID", "coachId": "教练ID",
"coachIdPlaceholder":"请输入教练ID", "coachIdPlaceholder": "请输入教练ID",
"createdAt":"创建时间", "createdAt": "创建时间",
"createdAtPlaceholder":"请输入创建时间", "createdAtPlaceholder": "请输入创建时间",
"updatedAt":"修改时间", "updatedAt": "修改时间",
"updatedAtPlaceholder":"请输入修改时间", "updatedAtPlaceholder": "请输入修改时间",
"seatedForwardBend":"坐位体前屈", "seatedForwardBend": "坐位体前屈",
"seatedForwardBendPlaceholder":"请输入坐位体前屈", "seatedForwardBendPlaceholder": "请输入坐位体前屈",
"sitUps":"仰卧卷腹", "sitUps": "仰卧卷腹",
"sitUpsPlaceholder":"请输入仰卧卷腹", "sitUpsPlaceholder": "请输入仰卧卷腹",
"pushUps":"九十度仰卧撑", "pushUps": "九十度仰卧撑",
"pushUpsPlaceholder":"请输入九十度仰卧撑", "pushUpsPlaceholder": "请输入九十度仰卧撑",
"flamingoBalance":"火烈鸟平衡测试", "flamingoBalance": "火烈鸟平衡测试",
"flamingoBalancePlaceholder":"请输入火烈鸟平衡测试", "flamingoBalancePlaceholder": "请输入火烈鸟平衡测试",
"thirtySecJump":"三十秒双脚连续跳", "thirtySecJump": "三十秒双脚连续跳",
"thirtySecJumpPlaceholder":"请输入三十秒双脚连续跳", "thirtySecJumpPlaceholder": "请输入三十秒双脚连续跳",
"standingLongJump":"立定跳远", "standingLongJump": "立定跳远",
"standingLongJumpPlaceholder":"请输入立定跳远", "standingLongJumpPlaceholder": "请输入立定跳远",
"agilityRun":"4乘10m灵敏折返跑", "agilityRun": "4乘10m灵敏折返跑",
"agilityRunPlaceholder":"请输入4乘10m灵敏折返跑", "agilityRunPlaceholder": "请输入4乘10m灵敏折返跑",
"balanceBeam":"走平衡木", "balanceBeam": "走平衡木",
"balanceBeamPlaceholder":"请输入走平衡木", "balanceBeamPlaceholder": "请输入走平衡木",
"tennisThrow":"网球掷远", "tennisThrow": "网球掷远",
"tennisThrowPlaceholder":"请输入网球掷远", "tennisThrowPlaceholder": "请输入网球掷远",
"tenMeterShuttleRun":"十米往返跑", "tenMeterShuttleRun": "十米往返跑",
"tenMeterShuttleRunPlaceholder":"请输入十米往返跑", "tenMeterShuttleRunPlaceholder": "请输入十米往返跑",
"addPhysicalTest":"添加体测", "addPhysicalTest": "添加体测",
"updatePhysicalTest":"编辑体测", "updatePhysicalTest": "编辑体测",
"physicalTestDeleteTips":"确定要删除该数据吗?", "physicalTestDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

40
admin/src/app/lang/zh-cn/reimbursement.reimbursement.json

@ -1,21 +1,21 @@
{ {
"id":"报销编号", "id": "报销编号",
"idPlaceholder":"请输入报销编号", "idPlaceholder": "请输入报销编号",
"applicantId":"申请人ID", "applicantId": "申请人ID",
"applicantIdPlaceholder":"请输入申请人ID", "applicantIdPlaceholder": "请输入申请人ID",
"amount":"报销金额", "amount": "报销金额",
"amountPlaceholder":"请输入报销金额", "amountPlaceholder": "请输入报销金额",
"description":"报销描述", "description": "报销描述",
"descriptionPlaceholder":"请输入报销描述", "descriptionPlaceholder": "请输入报销描述",
"receiptUrl":"发票或收据URL", "receiptUrl": "发票或收据URL",
"receiptUrlPlaceholder":"请输入发票或收据URL", "receiptUrlPlaceholder": "请输入发票或收据URL",
"status":"状态", "status": "状态",
"statusPlaceholder":"请输入状态", "statusPlaceholder": "请输入状态",
"processId":"关联的审批流程ID", "processId": "关联的审批流程ID",
"processIdPlaceholder":"请输入关联的审批流程ID", "processIdPlaceholder": "请输入关联的审批流程ID",
"addReimbursement":"添加报销记录", "addReimbursement": "添加报销记录",
"updateReimbursement":"编辑报销记录", "updateReimbursement": "编辑报销记录",
"reimbursementDeleteTips":"确定要删除该数据吗?", "reimbursementDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

36
admin/src/app/lang/zh-cn/resource_sharing.resource_sharing.json

@ -1,19 +1,19 @@
{ {
"id":"共享记录编号", "id": "共享记录编号",
"idPlaceholder":"请输入共享记录编号", "idPlaceholder": "请输入共享记录编号",
"resourceId":"资源ID", "resourceId": "资源ID",
"resourceIdPlaceholder":"请输入资源ID", "resourceIdPlaceholder": "请输入资源ID",
"userId":"用户ID(可为空)", "userId": "用户ID(可为空)",
"userIdPlaceholder":"请输入用户ID(可为空)", "userIdPlaceholder": "请输入用户ID(可为空)",
"roleId":"角色ID(可为空)", "roleId": "角色ID(可为空)",
"roleIdPlaceholder":"请输入角色ID(可为空)", "roleIdPlaceholder": "请输入角色ID(可为空)",
"sharedBy":"共享人ID", "sharedBy": "共享人ID",
"sharedByPlaceholder":"请输入共享人ID", "sharedByPlaceholder": "请输入共享人ID",
"sharedAt":"共享时间", "sharedAt": "共享时间",
"sharedAtPlaceholder":"请输入共享时间", "sharedAtPlaceholder": "请输入共享时间",
"addResourceSharing":"添加资源共享", "addResourceSharing": "添加资源共享",
"updateResourceSharing":"编辑资源共享", "updateResourceSharing": "编辑资源共享",
"resourceSharingDeleteTips":"确定要删除该数据吗?", "resourceSharingDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

64
admin/src/app/lang/zh-cn/salary.salary.json

@ -1,33 +1,33 @@
{ {
"id":"工资编号", "id": "工资编号",
"idPlaceholder":"请输入工资编号", "idPlaceholder": "请输入工资编号",
"staffId":"员工ID", "staffId": "员工ID",
"staffIdPlaceholder":"请输入员工ID", "staffIdPlaceholder": "请输入员工ID",
"baseSalary":"底薪", "baseSalary": "底薪",
"baseSalaryPlaceholder":"请输入底薪", "baseSalaryPlaceholder": "请输入底薪",
"performanceBonus":"绩效", "performanceBonus": "绩效",
"performanceBonusPlaceholder":"请输入绩效", "performanceBonusPlaceholder": "请输入绩效",
"deductions":"扣款", "deductions": "扣款",
"deductionsPlaceholder":"请输入扣款", "deductionsPlaceholder": "请输入扣款",
"otherSubsidies":"其他补贴", "otherSubsidies": "其他补贴",
"otherSubsidiesPlaceholder":"请输入其他补贴", "otherSubsidiesPlaceholder": "请输入其他补贴",
"netSalary":"实发工资", "netSalary": "实发工资",
"netSalaryPlaceholder":"请输入实发工资", "netSalaryPlaceholder": "请输入实发工资",
"paymentStatus":"发放状态", "paymentStatus": "发放状态",
"paymentStatusPlaceholder":"请输入发放状态", "paymentStatusPlaceholder": "请输入发放状态",
"paymentMethod":"发放方式", "paymentMethod": "发放方式",
"paymentMethodPlaceholder":"请输入发放方式", "paymentMethodPlaceholder": "请输入发放方式",
"remarks":"备注", "remarks": "备注",
"remarksPlaceholder":"请输入备注", "remarksPlaceholder": "请输入备注",
"salaryMonth":"工资月份", "salaryMonth": "工资月份",
"salaryMonthPlaceholder":"请输入工资月份", "salaryMonthPlaceholder": "请输入工资月份",
"departmentId":"部门ID", "departmentId": "部门ID",
"departmentIdPlaceholder":"请输入部门ID", "departmentIdPlaceholder": "请输入部门ID",
"processId":"关联的审批流程ID", "processId": "关联的审批流程ID",
"processIdPlaceholder":"请输入关联的审批流程ID", "processIdPlaceholder": "请输入关联的审批流程ID",
"addSalary":"添加工资", "addSalary": "添加工资",
"updateSalary":"编辑工资", "updateSalary": "编辑工资",
"salaryDeleteTips":"确定要删除该数据吗?", "salaryDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

56
admin/src/app/lang/zh-cn/service.service.json

@ -1,29 +1,29 @@
{ {
"id":"服务编号", "id": "服务编号",
"idPlaceholder":"请输入服务编号", "idPlaceholder": "请输入服务编号",
"serviceName":"服务名称", "serviceName": "服务名称",
"serviceNamePlaceholder":"请输入服务名称", "serviceNamePlaceholder": "请输入服务名称",
"previewImageUrl":"服务预览图URL", "previewImageUrl": "服务预览图URL",
"previewImageUrlPlaceholder":"请输入服务预览图URL", "previewImageUrlPlaceholder": "请输入服务预览图URL",
"description":"服务描述", "description": "服务描述",
"descriptionPlaceholder":"请输入服务描述", "descriptionPlaceholder": "请输入服务描述",
"serviceType":"服务类型", "serviceType": "服务类型",
"serviceTypePlaceholder":"请输入服务类型", "serviceTypePlaceholder": "请输入服务类型",
"executionRules":"服务执行规则", "executionRules": "服务执行规则",
"executionRulesPlaceholder":"请输入服务执行规则", "executionRulesPlaceholder": "请输入服务执行规则",
"staffReminder":"是否员工提醒: 1-是, 0-否", "staffReminder": "是否员工提醒: 1-是, 0-否",
"staffReminderPlaceholder":"请输入是否员工提醒: 1-是, 0-否", "staffReminderPlaceholder": "请输入是否员工提醒: 1-是, 0-否",
"customerReminder":"是否客户提醒: 1-是, 0-否", "customerReminder": "是否客户提醒: 1-是, 0-否",
"customerReminderPlaceholder":"请输入是否客户提醒: 1-是, 0-否", "customerReminderPlaceholder": "请输入是否客户提醒: 1-是, 0-否",
"customerConfirmation":"是否客户确认: 1-是, 0-否", "customerConfirmation": "是否客户确认: 1-是, 0-否",
"customerConfirmationPlaceholder":"请输入是否客户确认: 1-是, 0-否", "customerConfirmationPlaceholder": "请输入是否客户确认: 1-是, 0-否",
"customerFeedback":"客户反馈内容", "customerFeedback": "客户反馈内容",
"customerFeedbackPlaceholder":"请输入客户反馈内容", "customerFeedbackPlaceholder": "请输入客户反馈内容",
"status":"状态", "status": "状态",
"statusPlaceholder":"请输入状态", "statusPlaceholder": "请输入状态",
"addService":"添加服务", "addService": "添加服务",
"updateService":"编辑服务", "updateService": "编辑服务",
"serviceDeleteTips":"确定要删除该数据吗?", "serviceDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

68
admin/src/app/lang/zh-cn/six_speed.six_speed.json

@ -1,35 +1,35 @@
{ {
"id":"编号", "id": "编号",
"idPlaceholder":"请输入编号", "idPlaceholder": "请输入编号",
"purchasePower":"需求购买力", "purchasePower": "需求购买力",
"purchasePowerPlaceholder":"请输入需求购买力", "purchasePowerPlaceholder": "请输入需求购买力",
"conceptAwareness":"认知理念", "conceptAwareness": "认知理念",
"conceptAwarenessPlaceholder":"请输入认知理念", "conceptAwarenessPlaceholder": "请输入认知理念",
"preferredClassTime":"可选上课时间", "preferredClassTime": "可选上课时间",
"preferredClassTimePlaceholder":"请输入可选上课时间", "preferredClassTimePlaceholder": "请输入可选上课时间",
"distance":"距离", "distance": "距离",
"distancePlaceholder":"请输入距离", "distancePlaceholder": "请输入距离",
"communication":"沟通备注", "communication": "沟通备注",
"communicationPlaceholder":"请输入沟通备注", "communicationPlaceholder": "请输入沟通备注",
"promisedVisitTime":"承诺到访时间", "promisedVisitTime": "承诺到访时间",
"promisedVisitTimePlaceholder":"请输入承诺到访时间", "promisedVisitTimePlaceholder": "请输入承诺到访时间",
"actualVisitTime":"实际到访时间", "actualVisitTime": "实际到访时间",
"actualVisitTimePlaceholder":"请输入实际到访时间", "actualVisitTimePlaceholder": "请输入实际到访时间",
"callIntent":"电话后的意向程度: low-低, medium-中, high-高", "callIntent": "电话后的意向程度: low-低, medium-中, high-高",
"callIntentPlaceholder":"请输入电话后的意向程度: low-低, medium-中, high-高", "callIntentPlaceholder": "请输入电话后的意向程度: low-低, medium-中, high-高",
"firstVisitStatus":"一访情况", "firstVisitStatus": "一访情况",
"firstVisitStatusPlaceholder":"请输入一访情况", "firstVisitStatusPlaceholder": "请输入一访情况",
"secondVisitStatus":"二访情况", "secondVisitStatus": "二访情况",
"secondVisitStatusPlaceholder":"请输入二访情况", "secondVisitStatusPlaceholder": "请输入二访情况",
"isClosed":"是否关单: 1-是, 0-否", "isClosed": "是否关单: 1-是, 0-否",
"isClosedPlaceholder":"请输入是否关单: 1-是, 0-否", "isClosedPlaceholder": "请输入是否关单: 1-是, 0-否",
"staffId":"人员ID", "staffId": "人员ID",
"staffIdPlaceholder":"请输入人员ID", "staffIdPlaceholder": "请输入人员ID",
"resourceId":"资源ID", "resourceId": "资源ID",
"resourceIdPlaceholder":"请输入资源ID", "resourceIdPlaceholder": "请输入资源ID",
"addSixSpeed":"添加六一速", "addSixSpeed": "添加六一速",
"updateSixSpeed":"编辑六一速", "updateSixSpeed": "编辑六一速",
"sixSpeedDeleteTips":"确定要删除该数据吗?", "sixSpeedDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

36
admin/src/app/lang/zh-cn/six_speed_modification_log.six_speed_modification_log.json

@ -1,19 +1,19 @@
{ {
"id":"编号", "id": "编号",
"idPlaceholder":"请输入编号", "idPlaceholder": "请输入编号",
"campusId":"校区", "campusId": "校区",
"campusIdPlaceholder":"全部", "campusIdPlaceholder": "全部",
"staffId":"人员", "staffId": "人员",
"staffIdPlaceholder":"请输入人员", "staffIdPlaceholder": "请输入人员",
"modifiedField":"修改的字段", "modifiedField": "修改的字段",
"modifiedFieldPlaceholder":"请输入修改的字段", "modifiedFieldPlaceholder": "请输入修改的字段",
"oldValue":"修改前的值", "oldValue": "修改前的值",
"oldValuePlaceholder":"请输入修改前的值", "oldValuePlaceholder": "请输入修改前的值",
"newValue":"修改后的值", "newValue": "修改后的值",
"newValuePlaceholder":"请输入修改后的值", "newValuePlaceholder": "请输入修改后的值",
"addSixSpeedModificationLog":"添加六一速修改记录", "addSixSpeedModificationLog": "添加六一速修改记录",
"updateSixSpeedModificationLog":"编辑六一速修改记录", "updateSixSpeedModificationLog": "编辑六一速修改记录",
"sixSpeedModificationLogDeleteTips":"确定要删除该数据吗?", "sixSpeedModificationLogDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

144
admin/src/app/lang/zh-cn/stat_hour.stat_hour.json

@ -1,73 +1,73 @@
{ {
"id":"", "id": "",
"idPlaceholder":"请输入", "idPlaceholder": "请输入",
"addon":"插件", "addon": "插件",
"addonPlaceholder":"请输入插件", "addonPlaceholder": "请输入插件",
"field":"统计字段", "field": "统计字段",
"fieldPlaceholder":"请输入统计字段", "fieldPlaceholder": "请输入统计字段",
"fieldTotal":"总计", "fieldTotal": "总计",
"fieldTotalPlaceholder":"请输入总计", "fieldTotalPlaceholder": "请输入总计",
"year":"年", "year": "年",
"yearPlaceholder":"请输入年", "yearPlaceholder": "请输入年",
"month":"月", "month": "月",
"monthPlaceholder":"请输入月", "monthPlaceholder": "请输入月",
"day":"天", "day": "天",
"dayPlaceholder":"请输入天", "dayPlaceholder": "请输入天",
"startTime":"当日开始时间戳", "startTime": "当日开始时间戳",
"startTimePlaceholder":"请输入当日开始时间戳", "startTimePlaceholder": "请输入当日开始时间戳",
"lastTime":"最后执行时间", "lastTime": "最后执行时间",
"lastTimePlaceholder":"请输入最后执行时间", "lastTimePlaceholder": "请输入最后执行时间",
"hour0":"", "hour0": "",
"hour0Placeholder":"请输入", "hour0Placeholder": "请输入",
"hour1":"", "hour1": "",
"hour1Placeholder":"请输入", "hour1Placeholder": "请输入",
"hour2":"", "hour2": "",
"hour2Placeholder":"请输入", "hour2Placeholder": "请输入",
"hour3":"", "hour3": "",
"hour3Placeholder":"请输入", "hour3Placeholder": "请输入",
"hour4":"", "hour4": "",
"hour4Placeholder":"请输入", "hour4Placeholder": "请输入",
"hour5":"", "hour5": "",
"hour5Placeholder":"请输入", "hour5Placeholder": "请输入",
"hour6":"", "hour6": "",
"hour6Placeholder":"请输入", "hour6Placeholder": "请输入",
"hour7":"", "hour7": "",
"hour7Placeholder":"请输入", "hour7Placeholder": "请输入",
"hour8":"", "hour8": "",
"hour8Placeholder":"请输入", "hour8Placeholder": "请输入",
"hour9":"", "hour9": "",
"hour9Placeholder":"请输入", "hour9Placeholder": "请输入",
"hour10":"", "hour10": "",
"hour10Placeholder":"请输入", "hour10Placeholder": "请输入",
"hour11":"", "hour11": "",
"hour11Placeholder":"请输入", "hour11Placeholder": "请输入",
"hour12":"", "hour12": "",
"hour12Placeholder":"请输入", "hour12Placeholder": "请输入",
"hour13":"", "hour13": "",
"hour13Placeholder":"请输入", "hour13Placeholder": "请输入",
"hour14":"", "hour14": "",
"hour14Placeholder":"请输入", "hour14Placeholder": "请输入",
"hour15":"", "hour15": "",
"hour15Placeholder":"请输入", "hour15Placeholder": "请输入",
"hour16":"", "hour16": "",
"hour16Placeholder":"请输入", "hour16Placeholder": "请输入",
"hour17":"", "hour17": "",
"hour17Placeholder":"请输入", "hour17Placeholder": "请输入",
"hour18":"", "hour18": "",
"hour18Placeholder":"请输入", "hour18Placeholder": "请输入",
"hour19":"", "hour19": "",
"hour19Placeholder":"请输入", "hour19Placeholder": "请输入",
"hour20":"", "hour20": "",
"hour20Placeholder":"请输入", "hour20Placeholder": "请输入",
"hour21":"", "hour21": "",
"hour21Placeholder":"请输入", "hour21Placeholder": "请输入",
"hour22":"", "hour22": "",
"hour22Placeholder":"请输入", "hour22Placeholder": "请输入",
"hour23":"", "hour23": "",
"hour23Placeholder":"请输入", "hour23Placeholder": "请输入",
"addStatHour":"添加小时统计", "addStatHour": "添加小时统计",
"updateStatHour":"编辑小时统计", "updateStatHour": "编辑小时统计",
"statHourDeleteTips":"确定要删除该数据吗?", "statHourDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

28
admin/src/app/lang/zh-cn/student_course_usage.student_course_usage.json

@ -1,15 +1,15 @@
{ {
"id":"记录编号", "id": "记录编号",
"idPlaceholder":"请输入记录编号", "idPlaceholder": "请输入记录编号",
"studentCourseId":"学员课程ID(关联到student_courses表)", "studentCourseId": "学员课程ID(关联到student_courses表)",
"studentCourseIdPlaceholder":"请输入学员课程ID(关联到student_courses表)", "studentCourseIdPlaceholder": "请输入学员课程ID(关联到student_courses表)",
"usedHours":"本次使用的课时数", "usedHours": "本次使用的课时数",
"usedHoursPlaceholder":"请输入本次使用的课时数", "usedHoursPlaceholder": "请输入本次使用的课时数",
"usageDate":"课时使用日期", "usageDate": "课时使用日期",
"usageDatePlaceholder":"请输入课时使用日期", "usageDatePlaceholder": "请输入课时使用日期",
"addStudentCourseUsage":"添加学员课时消费记录", "addStudentCourseUsage": "添加学员课时消费记录",
"updateStudentCourseUsage":"编辑学员课时消费记录", "updateStudentCourseUsage": "编辑学员课时消费记录",
"studentCourseUsageDeleteTips":"确定要删除该数据吗?", "studentCourseUsageDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

40
admin/src/app/lang/zh-cn/student_courses.student_courses.json

@ -1,21 +1,21 @@
{ {
"id":"记录编号", "id": "记录编号",
"idPlaceholder":"请输入记录编号", "idPlaceholder": "请输入记录编号",
"studentId":"学员ID", "studentId": "学员ID",
"studentIdPlaceholder":"请输入学员ID", "studentIdPlaceholder": "请输入学员ID",
"courseId":"课程ID", "courseId": "课程ID",
"courseIdPlaceholder":"请输入课程ID", "courseIdPlaceholder": "请输入课程ID",
"totalHours":"总正式课时数", "totalHours": "总正式课时数",
"totalHoursPlaceholder":"请输入总正式课时数", "totalHoursPlaceholder": "请输入总正式课时数",
"giftHours":"赠送课时数", "giftHours": "赠送课时数",
"giftHoursPlaceholder":"请输入赠送课时数", "giftHoursPlaceholder": "请输入赠送课时数",
"startDate":"课程开始日期", "startDate": "课程开始日期",
"startDatePlaceholder":"请输入课程开始日期", "startDatePlaceholder": "请输入课程开始日期",
"endDate":"课程结束日期", "endDate": "课程结束日期",
"endDatePlaceholder":"请输入课程结束日期", "endDatePlaceholder": "请输入课程结束日期",
"addStudentCourses":"添加学员课程", "addStudentCourses": "添加学员课程",
"updateStudentCourses":"编辑学员课程", "updateStudentCourses": "编辑学员课程",
"studentCoursesDeleteTips":"确定要删除该数据吗?", "studentCoursesDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

28
admin/src/app/lang/zh-cn/user_feedback.user_feedback.json

@ -1,15 +1,15 @@
{ {
"id":"反馈编号", "id": "反馈编号",
"idPlaceholder":"请输入反馈编号", "idPlaceholder": "请输入反馈编号",
"userId":"用户ID", "userId": "用户ID",
"userIdPlaceholder":"请输入用户ID", "userIdPlaceholder": "请输入用户ID",
"feedbackText":"反馈内容", "feedbackText": "反馈内容",
"feedbackTextPlaceholder":"请输入反馈内容", "feedbackTextPlaceholder": "请输入反馈内容",
"attachmentUrl":"附件URL(OSS对象存储)", "attachmentUrl": "附件URL(OSS对象存储)",
"attachmentUrlPlaceholder":"请输入附件URL(OSS对象存储)", "attachmentUrlPlaceholder": "请输入附件URL(OSS对象存储)",
"addUserFeedback":"添加用户反馈信息", "addUserFeedback": "添加用户反馈信息",
"updateUserFeedback":"编辑用户反馈信息", "updateUserFeedback": "编辑用户反馈信息",
"userFeedbackDeleteTips":"确定要删除该数据吗?", "userFeedbackDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

18
admin/src/app/lang/zh-cn/venue.venue.json

@ -1,8 +1,6 @@
{ {
"id":"场地编号", "campusId":"校区",
"idPlaceholder":"请输入场地编号", "campusIdPlaceholder":"全部",
"campusId":"校区ID",
"campusIdPlaceholder":"请输入校区ID",
"venueName":"场地名称", "venueName":"场地名称",
"venueNamePlaceholder":"请输入场地名称", "venueNamePlaceholder":"请输入场地名称",
"capacity":"场地可容纳人数上限", "capacity":"场地可容纳人数上限",
@ -11,12 +9,12 @@
"availabilityStatusPlaceholder":"请输入场地可用状态", "availabilityStatusPlaceholder":"请输入场地可用状态",
"timeRangeType":"场地可用时间范围类型", "timeRangeType":"场地可用时间范围类型",
"timeRangeTypePlaceholder":"请输入场地可用时间范围类型", "timeRangeTypePlaceholder":"请输入场地可用时间范围类型",
"timeRangeStart":"范围类型的开始时间", "fixedTimeRanges":"时间范围",
"timeRangeStartPlaceholder":"请输入范围类型的开始时间", "fixedTimeRangesPlaceholder":"请输入时间范围",
"timeRangeEnd":"范围类型的结束时间", "createdAt":"创建时间",
"timeRangeEndPlaceholder":"请输入范围类型的结束时间", "createdAtPlaceholder":"请输入创建时间",
"fixedTimeRanges":"固定时间范围类型的可用时间, 存储为JSON数组", "updatedAt":"修改时间",
"fixedTimeRangesPlaceholder":"请输入固定时间范围类型的可用时间, 存储为JSON数组", "updatedAtPlaceholder":"请输入修改时间",
"addVenue":"添加场地", "addVenue":"添加场地",
"updateVenue":"编辑场地", "updateVenue":"编辑场地",
"venueDeleteTips":"确定要删除该数据吗?", "venueDeleteTips":"确定要删除该数据吗?",

531
admin/src/app/views/attendance/attendance.vue

@ -1,213 +1,318 @@
<template> <template>
<div class="main-container"> <div class="main-container">
<el-card class="box-card !border-none" shadow="never"> <el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<div class="flex justify-between items-center"> <span class="text-lg">{{ pageName }}</span>
<span class="text-lg">{{pageName}}</span> <el-button type="primary" @click="addEvent">
<el-button type="primary" @click="addEvent"> {{ t('addAttendance') }}
{{ t('addAttendance') }} </el-button>
</el-button> </div>
</div>
<el-card
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> class="box-card !border-none my-[10px] table-search-wrap"
<el-form :inline="true" :model="attendanceTable.searchParam" ref="searchFormRef"> shadow="never"
<el-form-item :label="t('campusId')" prop="campus_id"> >
<el-input v-model="attendanceTable.searchParam.campus_id" :placeholder="t('campusIdPlaceholder')" /> <el-form
</el-form-item> :inline="true"
<el-form-item :label="t('staffId')" prop="staff_id"> :model="attendanceTable.searchParam"
<el-input v-model="attendanceTable.searchParam.staff_id" :placeholder="t('staffIdPlaceholder')" /> ref="searchFormRef"
</el-form-item> >
<el-form-item :label="t('attendanceDate')" prop="attendance_date"> <el-form-item :label="t('campusId')" prop="campus_id">
<el-input v-model="attendanceTable.searchParam.attendance_date" :placeholder="t('attendanceDatePlaceholder')" /> <el-input
</el-form-item> v-model="attendanceTable.searchParam.campus_id"
<el-form-item :label="t('checkInTime')" prop="check_in_time"> :placeholder="t('campusIdPlaceholder')"
<el-input v-model="attendanceTable.searchParam.check_in_time" :placeholder="t('checkInTimePlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('checkOutTime')" prop="check_out_time"> <el-form-item :label="t('staffId')" prop="staff_id">
<el-input v-model="attendanceTable.searchParam.check_out_time" :placeholder="t('checkOutTimePlaceholder')" /> <el-input
</el-form-item> v-model="attendanceTable.searchParam.staff_id"
<el-form-item :label="t('status')" prop="status"> :placeholder="t('staffIdPlaceholder')"
<el-input v-model="attendanceTable.searchParam.status" :placeholder="t('statusPlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('remarks')" prop="remarks"> <el-form-item :label="t('attendanceDate')" prop="attendance_date">
<el-input v-model="attendanceTable.searchParam.remarks" :placeholder="t('remarksPlaceholder')" /> <el-input
</el-form-item> v-model="attendanceTable.searchParam.attendance_date"
<el-form-item :label="t('createdAt')" prop="created_at"> :placeholder="t('attendanceDatePlaceholder')"
<el-input v-model="attendanceTable.searchParam.created_at" :placeholder="t('createdAtPlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('updatedAt')" prop="updated_at"> <el-form-item :label="t('checkInTime')" prop="check_in_time">
<el-input v-model="attendanceTable.searchParam.updated_at" :placeholder="t('updatedAtPlaceholder')" /> <el-input
</el-form-item> v-model="attendanceTable.searchParam.check_in_time"
<el-form-item :label="t('coordinate')" prop="coordinate"> :placeholder="t('checkInTimePlaceholder')"
<el-input v-model="attendanceTable.searchParam.coordinate" :placeholder="t('coordinatePlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item :label="t('checkOutTime')" prop="check_out_time">
<el-button type="primary" @click="loadAttendanceList()">{{ t('search') }}</el-button> <el-input
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> v-model="attendanceTable.searchParam.check_out_time"
</el-form-item> :placeholder="t('checkOutTimePlaceholder')"
</el-form> />
</el-card> </el-form-item>
<el-form-item :label="t('status')" prop="status">
<div class="mt-[10px]"> <el-input
<el-table :data="attendanceTable.data" size="large" v-loading="attendanceTable.loading"> v-model="attendanceTable.searchParam.status"
<template #empty> :placeholder="t('statusPlaceholder')"
<span>{{ !attendanceTable.loading ? t('emptyData') : '' }}</span> />
</template> </el-form-item>
<el-table-column prop="campus_id" :label="t('campusId')" min-width="120" :show-overflow-tooltip="true"/> <el-form-item :label="t('remarks')" prop="remarks">
<el-input
<el-table-column prop="staff_id" :label="t('staffId')" min-width="120" :show-overflow-tooltip="true"/> v-model="attendanceTable.searchParam.remarks"
:placeholder="t('remarksPlaceholder')"
<el-table-column prop="attendance_date" :label="t('attendanceDate')" min-width="120" :show-overflow-tooltip="true"/> />
</el-form-item>
<el-table-column prop="check_in_time" :label="t('checkInTime')" min-width="120" :show-overflow-tooltip="true"/> <el-form-item :label="t('createdAt')" prop="created_at">
<el-input
<el-table-column prop="check_out_time" :label="t('checkOutTime')" min-width="120" :show-overflow-tooltip="true"/> v-model="attendanceTable.searchParam.created_at"
:placeholder="t('createdAtPlaceholder')"
<el-table-column prop="status" :label="t('status')" min-width="120" :show-overflow-tooltip="true"/> />
</el-form-item>
<el-table-column prop="remarks" :label="t('remarks')" min-width="120" :show-overflow-tooltip="true"/> <el-form-item :label="t('updatedAt')" prop="updated_at">
<el-input
<el-table-column prop="created_at" :label="t('createdAt')" min-width="120" :show-overflow-tooltip="true"/> v-model="attendanceTable.searchParam.updated_at"
:placeholder="t('updatedAtPlaceholder')"
<el-table-column prop="updated_at" :label="t('updatedAt')" min-width="120" :show-overflow-tooltip="true"/> />
</el-form-item>
<el-table-column prop="coordinate" :label="t('coordinate')" min-width="120" :show-overflow-tooltip="true"/> <el-form-item :label="t('coordinate')" prop="coordinate">
<el-input
<el-table-column :label="t('operation')" fixed="right" min-width="120"> v-model="attendanceTable.searchParam.coordinate"
<template #default="{ row }"> :placeholder="t('coordinatePlaceholder')"
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button> />
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button> </el-form-item>
</template>
</el-table-column> <el-form-item>
<el-button type="primary" @click="loadAttendanceList()">{{
</el-table> t('search')
<div class="mt-[16px] flex justify-end"> }}</el-button>
<el-pagination v-model:current-page="attendanceTable.page" v-model:page-size="attendanceTable.limit" <el-button @click="resetForm(searchFormRef)">{{
layout="total, sizes, prev, pager, next, jumper" :total="attendanceTable.total" t('reset')
@size-change="loadAttendanceList()" @current-change="loadAttendanceList" /> }}</el-button>
</div> </el-form-item>
</div> </el-form>
</el-card>
<edit ref="editAttendanceDialog" @complete="loadAttendanceList" />
</el-card> <div class="mt-[10px]">
</div> <el-table
</template> :data="attendanceTable.data"
size="large"
<script lang="ts" setup> v-loading="attendanceTable.loading"
import { reactive, ref, watch } from 'vue' >
import { t } from '@/lang' <template #empty>
import { useDictionary } from '@/app/api/dict' <span>{{ !attendanceTable.loading ? t('emptyData') : '' }}</span>
import { getAttendanceList, deleteAttendance } from '@/app/api/attendance' </template>
import { img } from '@/utils/common' <el-table-column
import { ElMessageBox,FormInstance } from 'element-plus' prop="campus_id"
import Edit from '@/app/views/attendance/components/attendance-edit.vue' :label="t('campusId')"
import { useRoute } from 'vue-router' min-width="120"
const route = useRoute() :show-overflow-tooltip="true"
const pageName = route.meta.title; />
let attendanceTable = reactive({ <el-table-column
page: 1, prop="staff_id"
limit: 10, :label="t('staffId')"
total: 0, min-width="120"
loading: true, :show-overflow-tooltip="true"
data: [], />
searchParam:{
"campus_id":"", <el-table-column
"staff_id":"", prop="attendance_date"
"attendance_date":"", :label="t('attendanceDate')"
"check_in_time":"", min-width="120"
"check_out_time":"", :show-overflow-tooltip="true"
"status":"", />
"remarks":"",
"created_at":"", <el-table-column
"updated_at":"", prop="check_in_time"
"coordinate":"" :label="t('checkInTime')"
} min-width="120"
}) :show-overflow-tooltip="true"
/>
const searchFormRef = ref<FormInstance>()
<el-table-column
// prop="check_out_time"
const selectData = ref<any[]>([]) :label="t('checkOutTime')"
min-width="120"
// :show-overflow-tooltip="true"
/>
/** <el-table-column
* 获取考勤列表 prop="status"
*/ :label="t('status')"
const loadAttendanceList = (page: number = 1) => { min-width="120"
attendanceTable.loading = true :show-overflow-tooltip="true"
attendanceTable.page = page />
getAttendanceList({ <el-table-column
page: attendanceTable.page, prop="remarks"
limit: attendanceTable.limit, :label="t('remarks')"
...attendanceTable.searchParam min-width="120"
}).then(res => { :show-overflow-tooltip="true"
attendanceTable.loading = false />
attendanceTable.data = res.data.data
attendanceTable.total = res.data.total <el-table-column
}).catch(() => { prop="created_at"
attendanceTable.loading = false :label="t('createdAt')"
}) min-width="120"
} :show-overflow-tooltip="true"
loadAttendanceList() />
const editAttendanceDialog: Record<string, any> | null = ref(null) <el-table-column
prop="updated_at"
/** :label="t('updatedAt')"
* 添加考勤 min-width="120"
*/ :show-overflow-tooltip="true"
const addEvent = () => { />
editAttendanceDialog.value.setFormData()
editAttendanceDialog.value.showDialog = true <el-table-column
} prop="coordinate"
:label="t('coordinate')"
/** min-width="120"
* 编辑考勤 :show-overflow-tooltip="true"
* @param data />
*/
const editEvent = (data: any) => { <el-table-column
editAttendanceDialog.value.setFormData(data) :label="t('operation')"
editAttendanceDialog.value.showDialog = true fixed="right"
} min-width="120"
>
/** <template #default="{ row }">
* 删除考勤 <el-button type="primary" link @click="editEvent(row)">{{
*/ t('edit')
const deleteEvent = (id: number) => { }}</el-button>
ElMessageBox.confirm(t('attendanceDeleteTips'), t('warning'), <el-button type="primary" link @click="deleteEvent(row.id)">{{
{ t('delete')
confirmButtonText: t('confirm'), }}</el-button>
cancelButtonText: t('cancel'), </template>
type: 'warning', </el-table-column>
} </el-table>
).then(() => { <div class="mt-[16px] flex justify-end">
deleteAttendance(id).then(() => { <el-pagination
loadAttendanceList() v-model:current-page="attendanceTable.page"
}).catch(() => { v-model:page-size="attendanceTable.limit"
}) layout="total, sizes, prev, pager, next, jumper"
}) :total="attendanceTable.total"
} @size-change="loadAttendanceList()"
@current-change="loadAttendanceList"
/>
</div>
const resetForm = (formEl: FormInstance | undefined) => { </div>
if (!formEl) return
formEl.resetFields() <edit ref="editAttendanceDialog" @complete="loadAttendanceList" />
loadAttendanceList() </el-card>
} </div>
</script> </template>
<style lang="scss" scoped> <script lang="ts" setup>
/* 多行超出隐藏 */ import { reactive, ref, watch } from 'vue'
.multi-hidden { import { t } from '@/lang'
word-break: break-all; import { useDictionary } from '@/app/api/dict'
text-overflow: ellipsis; import { getAttendanceList, deleteAttendance } from '@/app/api/attendance'
overflow: hidden; import { img } from '@/utils/common'
display: -webkit-box; import { ElMessageBox, FormInstance } from 'element-plus'
-webkit-line-clamp: 2; import Edit from '@/app/views/attendance/components/attendance-edit.vue'
-webkit-box-orient: vertical; import { useRoute } from 'vue-router'
} const route = useRoute()
</style> const pageName = route.meta.title
let attendanceTable = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {
campus_id: '',
staff_id: '',
attendance_date: '',
check_in_time: '',
check_out_time: '',
status: '',
remarks: '',
created_at: '',
updated_at: '',
coordinate: '',
},
})
const searchFormRef = ref<FormInstance>()
//
const selectData = ref<any[]>([])
//
/**
* 获取考勤列表
*/
const loadAttendanceList = (page: number = 1) => {
attendanceTable.loading = true
attendanceTable.page = page
getAttendanceList({
page: attendanceTable.page,
limit: attendanceTable.limit,
...attendanceTable.searchParam,
})
.then((res) => {
attendanceTable.loading = false
attendanceTable.data = res.data.data
attendanceTable.total = res.data.total
})
.catch(() => {
attendanceTable.loading = false
})
}
loadAttendanceList()
const editAttendanceDialog: Record<string, any> | null = ref(null)
/**
* 添加考勤
*/
const addEvent = () => {
editAttendanceDialog.value.setFormData()
editAttendanceDialog.value.showDialog = true
}
/**
* 编辑考勤
* @param data
*/
const editEvent = (data: any) => {
editAttendanceDialog.value.setFormData(data)
editAttendanceDialog.value.showDialog = true
}
/**
* 删除考勤
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('attendanceDeleteTips'), t('warning'), {
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}).then(() => {
deleteAttendance(id)
.then(() => {
loadAttendanceList()
})
.catch(() => {})
})
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadAttendanceList()
}
</script>
<style lang="scss" scoped>
/* 多行超出隐藏 */
.multi-hidden {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
</style>

529
admin/src/app/views/attendance/components/attendance-edit.vue

@ -1,233 +1,296 @@
<template> <template>
<el-dialog v-model="showDialog" :title="formData.id ? t('updateAttendance') : t('addAttendance')" width="50%" class="diy-dialog-wrap" :destroy-on-close="true"> <el-dialog
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading"> v-model="showDialog"
<el-form-item :label="t('campusId')" prop="campus_id"> :title="formData.id ? t('updateAttendance') : t('addAttendance')"
<el-input v-model="formData.campus_id" clearable :placeholder="t('campusIdPlaceholder')" class="input-width" /> width="50%"
</el-form-item> class="diy-dialog-wrap"
:destroy-on-close="true"
<el-form-item :label="t('staffId')" prop="staff_id"> >
<el-input v-model="formData.staff_id" clearable :placeholder="t('staffIdPlaceholder')" class="input-width" /> <el-form
</el-form-item> :model="formData"
label-width="120px"
<el-form-item :label="t('attendanceDate')" prop="attendance_date"> ref="formRef"
<el-input v-model="formData.attendance_date" clearable :placeholder="t('attendanceDatePlaceholder')" class="input-width" /> :rules="formRules"
</el-form-item> class="page-form"
v-loading="loading"
<el-form-item :label="t('checkInTime')" > >
<el-input v-model="formData.check_in_time" clearable :placeholder="t('checkInTimePlaceholder')" class="input-width" /> <el-form-item :label="t('campusId')" prop="campus_id">
</el-form-item> <el-input
v-model="formData.campus_id"
<el-form-item :label="t('checkOutTime')" > clearable
<el-input v-model="formData.check_out_time" clearable :placeholder="t('checkOutTimePlaceholder')" class="input-width" /> :placeholder="t('campusIdPlaceholder')"
</el-form-item> class="input-width"
/>
<el-form-item :label="t('status')" prop="status"> </el-form-item>
<el-input v-model="formData.status" clearable :placeholder="t('statusPlaceholder')" class="input-width" />
</el-form-item> <el-form-item :label="t('staffId')" prop="staff_id">
<el-input
<el-form-item :label="t('remarks')" > v-model="formData.staff_id"
<el-input v-model="formData.remarks" clearable :placeholder="t('remarksPlaceholder')" class="input-width" /> clearable
</el-form-item> :placeholder="t('staffIdPlaceholder')"
class="input-width"
<el-form-item :label="t('createdAt')" > />
<el-input v-model="formData.created_at" clearable :placeholder="t('createdAtPlaceholder')" class="input-width" /> </el-form-item>
</el-form-item>
<el-form-item :label="t('attendanceDate')" prop="attendance_date">
<el-form-item :label="t('updatedAt')" > <el-input
<el-input v-model="formData.updated_at" clearable :placeholder="t('updatedAtPlaceholder')" class="input-width" /> v-model="formData.attendance_date"
</el-form-item> clearable
:placeholder="t('attendanceDatePlaceholder')"
<el-form-item :label="t('coordinate')" > class="input-width"
<el-input v-model="formData.coordinate" clearable :placeholder="t('coordinatePlaceholder')" class="input-width" /> />
</el-form-item> </el-form-item>
</el-form> <el-form-item :label="t('checkInTime')">
<el-input
<template #footer> v-model="formData.check_in_time"
<span class="dialog-footer"> clearable
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button> :placeholder="t('checkInTimePlaceholder')"
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{ class="input-width"
t('confirm') />
}}</el-button> </el-form-item>
</span>
</template> <el-form-item :label="t('checkOutTime')">
</el-dialog> <el-input
</template> v-model="formData.check_out_time"
clearable
<script lang="ts" setup> :placeholder="t('checkOutTimePlaceholder')"
import { ref, reactive, computed, watch } from 'vue' class="input-width"
import { useDictionary } from '@/app/api/dict' />
import { t } from '@/lang' </el-form-item>
import type { FormInstance } from 'element-plus'
import { addAttendance, editAttendance, getAttendanceInfo } from '@/app/api/attendance' <el-form-item :label="t('status')" prop="status">
<el-input
let showDialog = ref(false) v-model="formData.status"
const loading = ref(false) clearable
:placeholder="t('statusPlaceholder')"
/** class="input-width"
* 表单数据 />
*/ </el-form-item>
const initialFormData = {
id: '', <el-form-item :label="t('remarks')">
campus_id: '', <el-input
staff_id: '', v-model="formData.remarks"
attendance_date: '', clearable
check_in_time: '', :placeholder="t('remarksPlaceholder')"
check_out_time: '', class="input-width"
status: '', />
remarks: '', </el-form-item>
created_at: '',
updated_at: '', <el-form-item :label="t('createdAt')">
coordinate: '', <el-input
} v-model="formData.created_at"
const formData: Record<string, any> = reactive({ ...initialFormData }) clearable
:placeholder="t('createdAtPlaceholder')"
const formRef = ref<FormInstance>() class="input-width"
/>
// </el-form-item>
const formRules = computed(() => {
return { <el-form-item :label="t('updatedAt')">
campus_id: [ <el-input
{ required: true, message: t('campusIdPlaceholder'), trigger: 'blur' }, v-model="formData.updated_at"
clearable
] :placeholder="t('updatedAtPlaceholder')"
, class="input-width"
staff_id: [ />
{ required: true, message: t('staffIdPlaceholder'), trigger: 'blur' }, </el-form-item>
] <el-form-item :label="t('coordinate')">
, <el-input
attendance_date: [ v-model="formData.coordinate"
{ required: true, message: t('attendanceDatePlaceholder'), trigger: 'blur' }, clearable
:placeholder="t('coordinatePlaceholder')"
] class="input-width"
, />
check_in_time: [ </el-form-item>
{ required: true, message: t('checkInTimePlaceholder'), trigger: 'blur' }, </el-form>
] <template #footer>
, <span class="dialog-footer">
check_out_time: [ <el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
{ required: true, message: t('checkOutTimePlaceholder'), trigger: 'blur' }, <el-button
type="primary"
] :loading="loading"
, @click="confirm(formRef)"
status: [ >{{ t('confirm') }}</el-button
{ required: true, message: t('statusPlaceholder'), trigger: 'blur' }, >
</span>
] </template>
, </el-dialog>
remarks: [ </template>
{ required: true, message: t('remarksPlaceholder'), trigger: 'blur' },
<script lang="ts" setup>
] import { ref, reactive, computed, watch } from 'vue'
, import { useDictionary } from '@/app/api/dict'
created_at: [ import { t } from '@/lang'
{ required: true, message: t('createdAtPlaceholder'), trigger: 'blur' }, import type { FormInstance } from 'element-plus'
import {
] addAttendance,
, editAttendance,
updated_at: [ getAttendanceInfo,
{ required: true, message: t('updatedAtPlaceholder'), trigger: 'blur' }, } from '@/app/api/attendance'
] let showDialog = ref(false)
, const loading = ref(false)
coordinate: [
{ required: true, message: t('coordinatePlaceholder'), trigger: 'blur' }, /**
* 表单数据
] */
, const initialFormData = {
} id: '',
}) campus_id: '',
staff_id: '',
const emit = defineEmits(['complete']) attendance_date: '',
check_in_time: '',
/** check_out_time: '',
* 确认 status: '',
* @param formEl remarks: '',
*/ created_at: '',
const confirm = async (formEl: FormInstance | undefined) => { updated_at: '',
if (loading.value || !formEl) return coordinate: '',
let save = formData.id ? editAttendance : addAttendance }
const formData: Record<string, any> = reactive({ ...initialFormData })
await formEl.validate(async (valid) => {
if (valid) { const formRef = ref<FormInstance>()
loading.value = true
//
let data = formData const formRules = computed(() => {
return {
save(data).then(res => { campus_id: [
loading.value = false { required: true, message: t('campusIdPlaceholder'), trigger: 'blur' },
showDialog.value = false ],
emit('complete') staff_id: [
}).catch(err => { { required: true, message: t('staffIdPlaceholder'), trigger: 'blur' },
loading.value = false ],
}) attendance_date: [
} {
}) required: true,
} message: t('attendanceDatePlaceholder'),
trigger: 'blur',
// },
],
check_in_time: [
{ required: true, message: t('checkInTimePlaceholder'), trigger: 'blur' },
const setFormData = async (row: any = null) => { ],
Object.assign(formData, initialFormData) check_out_time: [
loading.value = true {
if(row){ required: true,
const data = await (await getAttendanceInfo(row.id)).data message: t('checkOutTimePlaceholder'),
if (data) Object.keys(formData).forEach((key: string) => { trigger: 'blur',
if (data[key] != undefined) formData[key] = data[key] },
}) ],
} status: [
loading.value = false { required: true, message: t('statusPlaceholder'), trigger: 'blur' },
} ],
remarks: [
// { required: true, message: t('remarksPlaceholder'), trigger: 'blur' },
const mobileVerify = (rule: any, value: any, callback: any) => { ],
if (value && !/^1[3-9]\d{9}$/.test(value)) { created_at: [
callback(new Error(t('generateMobile'))) { required: true, message: t('createdAtPlaceholder'), trigger: 'blur' },
} else { ],
callback() updated_at: [
} { required: true, message: t('updatedAtPlaceholder'), trigger: 'blur' },
} ],
coordinate: [
// { required: true, message: t('coordinatePlaceholder'), trigger: 'blur' },
const idCardVerify = (rule: any, value: any, callback: any) => { ],
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) { }
callback(new Error(t('generateIdCard'))) })
} else {
callback() const emit = defineEmits(['complete'])
}
} /**
* 确认
// * @param formEl
const emailVerify = (rule: any, value: any, callback: any) => { */
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) { const confirm = async (formEl: FormInstance | undefined) => {
callback(new Error(t('generateEmail'))) if (loading.value || !formEl) return
} else { let save = formData.id ? editAttendance : addAttendance
callback()
} await formEl.validate(async (valid) => {
} if (valid) {
loading.value = true
//
const numberVerify = (rule: any, value: any, callback: any) => { let data = formData
if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber'))) save(data)
} else { .then((res) => {
callback() loading.value = false
} showDialog.value = false
} emit('complete')
})
defineExpose({ .catch((err) => {
showDialog, loading.value = false
setFormData })
}) }
</script> })
}
<style lang="scss" scoped></style>
<style lang="scss"> //
.diy-dialog-wrap .el-form-item__label{
height: auto !important; const setFormData = async (row: any = null) => {
} Object.assign(formData, initialFormData)
</style> loading.value = true
if (row) {
const data = await (await getAttendanceInfo(row.id)).data
if (data)
Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key]
})
}
loading.value = false
}
//
const mobileVerify = (rule: any, value: any, callback: any) => {
if (value && !/^1[3-9]\d{9}$/.test(value)) {
callback(new Error(t('generateMobile')))
} else {
callback()
}
}
//
const idCardVerify = (rule: any, value: any, callback: any) => {
if (
value &&
!/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
value
)
) {
callback(new Error(t('generateIdCard')))
} else {
callback()
}
}
//
const emailVerify = (rule: any, value: any, callback: any) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail')))
} else {
callback()
}
}
//
const numberVerify = (rule: any, value: any, callback: any) => {
if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber')))
} else {
callback()
}
}
defineExpose({
showDialog,
setFormData,
})
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.diy-dialog-wrap .el-form-item__label {
height: auto !important;
}
</style>

446
admin/src/app/views/campus/campus.vue

@ -1,193 +1,253 @@
<template> <template>
<div class="main-container"> <div class="main-container">
<el-card class="box-card !border-none" shadow="never"> <el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<div class="flex justify-between items-center"> <span class="text-lg">{{ pageName }}</span>
<span class="text-lg">{{pageName}}</span> <el-button type="primary" @click="addEvent">
<el-button type="primary" @click="addEvent"> {{ t('addCampus') }}
{{ t('addCampus') }} </el-button>
</el-button> </div>
</div>
<el-card
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> class="box-card !border-none my-[10px] table-search-wrap"
<el-form :inline="true" :model="campusTable.searchParam" ref="searchFormRef"> shadow="never"
<el-form-item :label="t('campusName')" prop="campus_name"> >
<el-input v-model="campusTable.searchParam.campus_name" :placeholder="t('campusNamePlaceholder')" /> <el-form
</el-form-item> :inline="true"
<el-form-item :label="t('campusAddress')" prop="campus_address"> :model="campusTable.searchParam"
<el-input v-model="campusTable.searchParam.campus_address" :placeholder="t('campusAddressPlaceholder')" /> ref="searchFormRef"
</el-form-item> >
<el-form-item :label="t('campusName')" prop="campus_name">
<el-form-item :label="t('campusStatus')" prop="campus_status"> <el-input
<el-select class="w-[280px]" v-model="campusTable.searchParam.campus_status" clearable :placeholder="t('campusStatusPlaceholder')"> v-model="campusTable.searchParam.campus_name"
<el-option label="全部" value=""></el-option> :placeholder="t('campusNamePlaceholder')"
<el-option />
v-for="(item, index) in campus_statusList" </el-form-item>
:key="index" <el-form-item :label="t('campusAddress')" prop="campus_address">
:label="item.name" <el-input
:value="item.value" v-model="campusTable.searchParam.campus_address"
/> :placeholder="t('campusAddressPlaceholder')"
</el-select> />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item :label="t('campusStatus')" prop="campus_status">
<el-button type="primary" @click="loadCampusList()">{{ t('search') }}</el-button> <el-select
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> class="w-[280px]"
</el-form-item> v-model="campusTable.searchParam.campus_status"
</el-form> clearable
</el-card> :placeholder="t('campusStatusPlaceholder')"
>
<div class="mt-[10px]"> <el-option label="全部" value=""></el-option>
<el-table :data="campusTable.data" size="large" v-loading="campusTable.loading"> <el-option
<template #empty> v-for="(item, index) in campus_statusList"
<span>{{ !campusTable.loading ? t('emptyData') : '' }}</span> :key="index"
</template> :label="item.name"
<el-table-column prop="campus_name" :label="t('campusName')" min-width="120" :show-overflow-tooltip="true"/> :value="item.value"
/>
<el-table-column prop="campus_address" :label="t('campusAddress')" min-width="120" :show-overflow-tooltip="true"/> </el-select>
</el-form-item>
<el-table-column :label="t('campusStatus')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }"> <el-form-item>
<div v-for="(item, index) in campus_statusList"> <el-button type="primary" @click="loadCampusList()">{{
<div v-if="item.value == row.campus_status">{{ item.name }}</div> t('search')
</div> }}</el-button>
</template> <el-button @click="resetForm(searchFormRef)">{{
</el-table-column> t('reset')
}}</el-button>
<el-table-column prop="create_time" :label="t('createTime')" min-width="120" :show-overflow-tooltip="true"/> </el-form-item>
</el-form>
<el-table-column :label="t('operation')" fixed="right" min-width="120"> </el-card>
<template #default="{ row }">
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button> <div class="mt-[10px]">
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button> <el-table
</template> :data="campusTable.data"
</el-table-column> size="large"
v-loading="campusTable.loading"
</el-table> >
<div class="mt-[16px] flex justify-end"> <template #empty>
<el-pagination v-model:current-page="campusTable.page" v-model:page-size="campusTable.limit" <span>{{ !campusTable.loading ? t('emptyData') : '' }}</span>
layout="total, sizes, prev, pager, next, jumper" :total="campusTable.total" </template>
@size-change="loadCampusList()" @current-change="loadCampusList" /> <el-table-column
</div> prop="campus_name"
</div> :label="t('campusName')"
min-width="120"
<edit ref="editCampusDialog" @complete="loadCampusList" /> :show-overflow-tooltip="true"
</el-card> />
</div>
</template> <el-table-column
prop="campus_address"
<script lang="ts" setup> :label="t('campusAddress')"
import { reactive, ref, watch } from 'vue' min-width="120"
import { t } from '@/lang' :show-overflow-tooltip="true"
import { useDictionary } from '@/app/api/dict' />
import { getCampusList, deleteCampus } from '@/app/api/campus'
import { img } from '@/utils/common' <el-table-column
import { ElMessageBox,FormInstance } from 'element-plus' :label="t('campusStatus')"
import Edit from '@/app/views/campus/components/campus-edit.vue' min-width="180"
import { useRoute } from 'vue-router' align="center"
const route = useRoute() :show-overflow-tooltip="true"
const pageName = route.meta.title; >
<template #default="{ row }">
let campusTable = reactive({ <div v-for="(item, index) in campus_statusList">
page: 1, <div v-if="item.value == row.campus_status">
limit: 10, {{ item.name }}
total: 0, </div>
loading: true, </div>
data: [], </template>
searchParam:{ </el-table-column>
"campus_name":"",
"campus_address":"", <el-table-column
"campus_status":"" prop="create_time"
} :label="t('createTime')"
}) min-width="120"
:show-overflow-tooltip="true"
const searchFormRef = ref<FormInstance>() />
// <el-table-column
const selectData = ref<any[]>([]) :label="t('operation')"
fixed="right"
// min-width="120"
const campus_statusList = ref([] as any[]) >
const campus_statusDictList = async () => { <template #default="{ row }">
campus_statusList.value = await (await useDictionary('campus_status')).data.dictionary <el-button type="primary" link @click="editEvent(row)">{{
} t('edit')
campus_statusDictList(); }}</el-button>
<el-button type="primary" link @click="deleteEvent(row.id)">{{
/** t('delete')
* 获取校区列表 }}</el-button>
*/ </template>
const loadCampusList = (page: number = 1) => { </el-table-column>
campusTable.loading = true </el-table>
campusTable.page = page <div class="mt-[16px] flex justify-end">
<el-pagination
getCampusList({ v-model:current-page="campusTable.page"
page: campusTable.page, v-model:page-size="campusTable.limit"
limit: campusTable.limit, layout="total, sizes, prev, pager, next, jumper"
...campusTable.searchParam :total="campusTable.total"
}).then(res => { @size-change="loadCampusList()"
campusTable.loading = false @current-change="loadCampusList"
campusTable.data = res.data.data />
campusTable.total = res.data.total </div>
}).catch(() => { </div>
campusTable.loading = false
}) <edit ref="editCampusDialog" @complete="loadCampusList" />
} </el-card>
loadCampusList() </div>
</template>
const editCampusDialog: Record<string, any> | null = ref(null)
<script lang="ts" setup>
/** import { reactive, ref, watch } from 'vue'
* 添加校区 import { t } from '@/lang'
*/ import { useDictionary } from '@/app/api/dict'
const addEvent = () => { import { getCampusList, deleteCampus } from '@/app/api/campus'
editCampusDialog.value.setFormData() import { img } from '@/utils/common'
editCampusDialog.value.showDialog = true import { ElMessageBox, FormInstance } from 'element-plus'
} import Edit from '@/app/views/campus/components/campus-edit.vue'
import { useRoute } from 'vue-router'
/** const route = useRoute()
* 编辑校区 const pageName = route.meta.title
* @param data
*/ let campusTable = reactive({
const editEvent = (data: any) => { page: 1,
editCampusDialog.value.setFormData(data) limit: 10,
editCampusDialog.value.showDialog = true total: 0,
} loading: true,
data: [],
/** searchParam: {
* 删除校区 campus_name: '',
*/ campus_address: '',
const deleteEvent = (id: number) => { campus_status: '',
ElMessageBox.confirm(t('campusDeleteTips'), t('warning'), },
{ })
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'), const searchFormRef = ref<FormInstance>()
type: 'warning',
} //
).then(() => { const selectData = ref<any[]>([])
deleteCampus(id).then(() => {
loadCampusList() //
}).catch(() => { const campus_statusList = ref([] as any[])
}) const campus_statusDictList = async () => {
}) campus_statusList.value = await (
} await useDictionary('campus_status')
).data.dictionary
}
campus_statusDictList()
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return /**
formEl.resetFields() * 获取校区列表
loadCampusList() */
} const loadCampusList = (page: number = 1) => {
</script> campusTable.loading = true
campusTable.page = page
<style lang="scss" scoped>
/* 多行超出隐藏 */ getCampusList({
.multi-hidden { page: campusTable.page,
word-break: break-all; limit: campusTable.limit,
text-overflow: ellipsis; ...campusTable.searchParam,
overflow: hidden; })
display: -webkit-box; .then((res) => {
-webkit-line-clamp: 2; campusTable.loading = false
-webkit-box-orient: vertical; campusTable.data = res.data.data
} campusTable.total = res.data.total
</style> })
.catch(() => {
campusTable.loading = false
})
}
loadCampusList()
const editCampusDialog: Record<string, any> | null = ref(null)
/**
* 添加校区
*/
const addEvent = () => {
editCampusDialog.value.setFormData()
editCampusDialog.value.showDialog = true
}
/**
* 编辑校区
* @param data
*/
const editEvent = (data: any) => {
editCampusDialog.value.setFormData(data)
editCampusDialog.value.showDialog = true
}
/**
* 删除校区
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('campusDeleteTips'), t('warning'), {
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}).then(() => {
deleteCampus(id)
.then(() => {
loadCampusList()
})
.catch(() => {})
})
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadCampusList()
}
</script>
<style lang="scss" scoped>
/* 多行超出隐藏 */
.multi-hidden {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
</style>

34
admin/src/app/views/campus/components/campus-edit.vue

@ -23,21 +23,31 @@
/> />
</el-form-item> </el-form-item>
<el-form-item :label="t('campusAddress')"> <!-- <el-form-item :label="t('campusAddress')">-->
<el-input <!-- <el-input-->
v-model="formData.campus_address" <!-- v-model="formData.campus_address"-->
clearable <!-- clearable-->
:placeholder="t('campusAddressPlaceholder')" <!-- :placeholder="t('campusAddressPlaceholder')"-->
class="input-width" <!-- class="input-width"-->
/> <!-- />-->
</el-form-item> <!-- </el-form-item>-->
<el-form-item :label="t('campusPreviewImage')"> <el-form-item :label="t('campusPreviewImage')">
<upload-image v-model="formData.campus_preview_image" /> <upload-image v-model="formData.campus_preview_image" />
</el-form-item> </el-form-item>
<el-form-item :label="t('campusCoordinates')"> <el-form-item :label="t('campusCoordinates')">
<TencentMapPicker v-model="formData.campus_coordinates" /> <el-button @click="showMapPicker">
{{
formData.campus_coordinates?.address ||
t('campusCoordinatesPlaceholder')
}}</el-button
>
<TencentMapPicker
ref="mapPickerRef"
v-model="formData.campus_coordinates"
v-model:visible="showMapPickerVisible"
/>
</el-form-item> </el-form-item>
<el-form-item :label="t('campusIntroduction')"> <el-form-item :label="t('campusIntroduction')">
@ -99,7 +109,11 @@ const initialFormData = {
const formData: Record<string, any> = reactive({ ...initialFormData }) const formData: Record<string, any> = reactive({ ...initialFormData })
const formRef = ref<FormInstance>() const formRef = ref<FormInstance>()
const mapPickerRef = ref()
const showMapPickerVisible = ref(false)
const showMapPicker = () => {
showMapPickerVisible.value = true
}
// //
const formRules = computed(() => { const formRules = computed(() => {
return { return {

539
admin/src/app/views/campus_person_role/campus_person_role.vue

@ -1,233 +1,306 @@
<template> <template>
<div class="main-container"> <div class="main-container">
<el-card class="box-card !border-none" shadow="never"> <el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<div class="flex justify-between items-center"> <span class="text-lg">{{ pageName }}</span>
<span class="text-lg">{{pageName}}</span> <el-button type="primary" @click="addEvent">
<el-button type="primary" @click="addEvent"> {{ t('addCampusPersonRole') }}
{{ t('addCampusPersonRole') }} </el-button>
</el-button> </div>
</div>
<el-card
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> class="box-card !border-none my-[10px] table-search-wrap"
<el-form :inline="true" :model="campusPersonRoleTable.searchParam" ref="searchFormRef"> shadow="never"
>
<el-form-item :label="t('campusId')" prop="campus_id"> <el-form
<el-select class="w-[280px]" v-model="campusPersonRoleTable.searchParam.campus_id" clearable :placeholder="t('campusIdPlaceholder')"> :inline="true"
<el-option :model="campusPersonRoleTable.searchParam"
v-for="(item, index) in campusIdList" ref="searchFormRef"
:key="index" >
:label="item['campus_name']" <el-form-item :label="t('campusId')" prop="campus_id">
:value="item['id']" <el-select
/> class="w-[280px]"
</el-select> v-model="campusPersonRoleTable.searchParam.campus_id"
</el-form-item> clearable
:placeholder="t('campusIdPlaceholder')"
>
<el-form-item :label="t('personId')" prop="person_id"> <el-option
<el-select class="w-[280px]" v-model="campusPersonRoleTable.searchParam.person_id" clearable :placeholder="t('personIdPlaceholder')"> v-for="(item, index) in campusIdList"
<el-option :key="index"
v-for="(item, index) in personIdList" :label="item['campus_name']"
:key="index" :value="item['id']"
:label="item['name']" />
:value="item['id']" </el-select>
/> </el-form-item>
</el-select>
</el-form-item> <el-form-item :label="t('personId')" prop="person_id">
<el-select
class="w-[280px]"
<el-form-item :label="t('roleId')" prop="role_id"> v-model="campusPersonRoleTable.searchParam.person_id"
<el-select class="w-[280px]" v-model="campusPersonRoleTable.searchParam.role_id" clearable :placeholder="t('roleIdPlaceholder')"> clearable
<el-option :placeholder="t('personIdPlaceholder')"
v-for="(item, index) in roleIdList" >
:key="index" <el-option
:label="item['role_name']" v-for="(item, index) in personIdList"
:value="item['role_id']" :key="index"
/> :label="item['name']"
</el-select> :value="item['id']"
</el-form-item> />
</el-select>
</el-form-item>
<el-form-item :label="t('deptId')" prop="dept_id">
<el-select class="w-[280px]" v-model="campusPersonRoleTable.searchParam.dept_id" clearable :placeholder="t('deptIdPlaceholder')"> <el-form-item :label="t('roleId')" prop="role_id">
<el-option <el-select
v-for="(item, index) in deptIdList" class="w-[280px]"
:key="index" v-model="campusPersonRoleTable.searchParam.role_id"
:label="item['department_name']" clearable
:value="item['id']" :placeholder="t('roleIdPlaceholder')"
/> >
</el-select> <el-option
</el-form-item> v-for="(item, index) in roleIdList"
:key="index"
<el-form-item> :label="item['role_name']"
<el-button type="primary" @click="loadCampusPersonRoleList()">{{ t('search') }}</el-button> :value="item['role_id']"
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> />
</el-form-item> </el-select>
</el-form> </el-form-item>
</el-card>
<el-form-item :label="t('deptId')" prop="dept_id">
<div class="mt-[10px]"> <el-select
<el-table :data="campusPersonRoleTable.data" size="large" v-loading="campusPersonRoleTable.loading"> class="w-[280px]"
<template #empty> v-model="campusPersonRoleTable.searchParam.dept_id"
<span>{{ !campusPersonRoleTable.loading ? t('emptyData') : '' }}</span> clearable
</template> :placeholder="t('deptIdPlaceholder')"
<el-table-column prop="campus_id_name" :label="t('campusId')" min-width="120" :show-overflow-tooltip="true"/> >
<el-option
<el-table-column prop="person_id_name" :label="t('personId')" min-width="120" :show-overflow-tooltip="true"/> v-for="(item, index) in deptIdList"
:key="index"
<el-table-column prop="role_id_name" :label="t('roleId')" min-width="120" :show-overflow-tooltip="true"/> :label="item['department_name']"
:value="item['id']"
<el-table-column prop="dept_id_name" :label="t('deptId')" min-width="120" :show-overflow-tooltip="true"/> />
</el-select>
<el-table-column :label="t('operation')" fixed="right" min-width="120"> </el-form-item>
<template #default="{ row }">
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button> <el-form-item>
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button> <el-button type="primary" @click="loadCampusPersonRoleList()">{{
</template> t('search')
</el-table-column> }}</el-button>
<el-button @click="resetForm(searchFormRef)">{{
</el-table> t('reset')
<div class="mt-[16px] flex justify-end"> }}</el-button>
<el-pagination v-model:current-page="campusPersonRoleTable.page" v-model:page-size="campusPersonRoleTable.limit" </el-form-item>
layout="total, sizes, prev, pager, next, jumper" :total="campusPersonRoleTable.total" </el-form>
@size-change="loadCampusPersonRoleList()" @current-change="loadCampusPersonRoleList" /> </el-card>
</div>
</div> <div class="mt-[10px]">
<el-table
<edit ref="editCampusPersonRoleDialog" @complete="loadCampusPersonRoleList" /> :data="campusPersonRoleTable.data"
</el-card> size="large"
</div> v-loading="campusPersonRoleTable.loading"
</template> >
<template #empty>
<script lang="ts" setup> <span>{{
import { reactive, ref, watch } from 'vue' !campusPersonRoleTable.loading ? t('emptyData') : ''
import { t } from '@/lang' }}</span>
import { useDictionary } from '@/app/api/dict' </template>
import { getCampusPersonRoleList, deleteCampusPersonRole, getWithCampusList, getWithPersonnelList, getWithSysRoleList, getWithDepartmentsList } from '@/app/api/campus_person_role' <el-table-column
import { img } from '@/utils/common' prop="campus_id_name"
import { ElMessageBox,FormInstance } from 'element-plus' :label="t('campusId')"
import Edit from '@/app/views/campus_person_role/components/campus-person-role-edit.vue' min-width="120"
import { useRoute } from 'vue-router' :show-overflow-tooltip="true"
const route = useRoute() />
const pageName = route.meta.title;
<el-table-column
let campusPersonRoleTable = reactive({ prop="person_id_name"
page: 1, :label="t('personId')"
limit: 10, min-width="120"
total: 0, :show-overflow-tooltip="true"
loading: true, />
data: [],
searchParam:{ <el-table-column
"campus_id":"", prop="role_id_name"
"person_id":"", :label="t('roleId')"
"role_id":"", min-width="120"
"dept_id":"" :show-overflow-tooltip="true"
} />
})
<el-table-column
const searchFormRef = ref<FormInstance>() prop="dept_id_name"
:label="t('deptId')"
// min-width="120"
const selectData = ref<any[]>([]) :show-overflow-tooltip="true"
/>
//
<el-table-column
:label="t('operation')"
/** fixed="right"
* 获取角色关系列表 min-width="120"
*/ >
const loadCampusPersonRoleList = (page: number = 1) => { <template #default="{ row }">
campusPersonRoleTable.loading = true <el-button type="primary" link @click="editEvent(row)">{{
campusPersonRoleTable.page = page t('edit')
}}</el-button>
getCampusPersonRoleList({ <el-button type="primary" link @click="deleteEvent(row.id)">{{
page: campusPersonRoleTable.page, t('delete')
limit: campusPersonRoleTable.limit, }}</el-button>
...campusPersonRoleTable.searchParam </template>
}).then(res => { </el-table-column>
campusPersonRoleTable.loading = false </el-table>
campusPersonRoleTable.data = res.data.data <div class="mt-[16px] flex justify-end">
campusPersonRoleTable.total = res.data.total <el-pagination
}).catch(() => { v-model:current-page="campusPersonRoleTable.page"
campusPersonRoleTable.loading = false v-model:page-size="campusPersonRoleTable.limit"
}) layout="total, sizes, prev, pager, next, jumper"
} :total="campusPersonRoleTable.total"
loadCampusPersonRoleList() @size-change="loadCampusPersonRoleList()"
@current-change="loadCampusPersonRoleList"
const editCampusPersonRoleDialog: Record<string, any> | null = ref(null) />
</div>
/** </div>
* 添加角色关系
*/ <edit
const addEvent = () => { ref="editCampusPersonRoleDialog"
editCampusPersonRoleDialog.value.setFormData() @complete="loadCampusPersonRoleList"
editCampusPersonRoleDialog.value.showDialog = true />
} </el-card>
</div>
/** </template>
* 编辑角色关系
* @param data <script lang="ts" setup>
*/ import { reactive, ref, watch } from 'vue'
const editEvent = (data: any) => { import { t } from '@/lang'
editCampusPersonRoleDialog.value.setFormData(data) import { useDictionary } from '@/app/api/dict'
editCampusPersonRoleDialog.value.showDialog = true import {
} getCampusPersonRoleList,
deleteCampusPersonRole,
/** getWithCampusList,
* 删除角色关系 getWithPersonnelList,
*/ getWithSysRoleList,
const deleteEvent = (id: number) => { getWithDepartmentsList,
ElMessageBox.confirm(t('campusPersonRoleDeleteTips'), t('warning'), } from '@/app/api/campus_person_role'
{ import { img } from '@/utils/common'
confirmButtonText: t('confirm'), import { ElMessageBox, FormInstance } from 'element-plus'
cancelButtonText: t('cancel'), import Edit from '@/app/views/campus_person_role/components/campus-person-role-edit.vue'
type: 'warning', import { useRoute } from 'vue-router'
} const route = useRoute()
).then(() => { const pageName = route.meta.title
deleteCampusPersonRole(id).then(() => {
loadCampusPersonRoleList() let campusPersonRoleTable = reactive({
}).catch(() => { page: 1,
}) limit: 10,
}) total: 0,
} loading: true,
data: [],
searchParam: {
const campusIdList = ref([]) campus_id: '',
const setCampusIdList = async () => { person_id: '',
campusIdList.value = await (await getWithCampusList({})).data role_id: '',
} dept_id: '',
setCampusIdList() },
const personIdList = ref([]) })
const setPersonIdList = async () => {
personIdList.value = await (await getWithPersonnelList({})).data const searchFormRef = ref<FormInstance>()
}
setPersonIdList() //
const roleIdList = ref([]) const selectData = ref<any[]>([])
const setRoleIdList = async () => {
roleIdList.value = await (await getWithSysRoleList({})).data //
}
setRoleIdList() /**
const deptIdList = ref([]) * 获取角色关系列表
const setDeptIdList = async () => { */
deptIdList.value = await (await getWithDepartmentsList({})).data const loadCampusPersonRoleList = (page: number = 1) => {
} campusPersonRoleTable.loading = true
setDeptIdList() campusPersonRoleTable.page = page
const resetForm = (formEl: FormInstance | undefined) => { getCampusPersonRoleList({
if (!formEl) return page: campusPersonRoleTable.page,
formEl.resetFields() limit: campusPersonRoleTable.limit,
loadCampusPersonRoleList() ...campusPersonRoleTable.searchParam,
} })
</script> .then((res) => {
campusPersonRoleTable.loading = false
<style lang="scss" scoped> campusPersonRoleTable.data = res.data.data
/* 多行超出隐藏 */ campusPersonRoleTable.total = res.data.total
.multi-hidden { })
word-break: break-all; .catch(() => {
text-overflow: ellipsis; campusPersonRoleTable.loading = false
overflow: hidden; })
display: -webkit-box; }
-webkit-line-clamp: 2; loadCampusPersonRoleList()
-webkit-box-orient: vertical;
} const editCampusPersonRoleDialog: Record<string, any> | null = ref(null)
</style>
/**
* 添加角色关系
*/
const addEvent = () => {
editCampusPersonRoleDialog.value.setFormData()
editCampusPersonRoleDialog.value.showDialog = true
}
/**
* 编辑角色关系
* @param data
*/
const editEvent = (data: any) => {
editCampusPersonRoleDialog.value.setFormData(data)
editCampusPersonRoleDialog.value.showDialog = true
}
/**
* 删除角色关系
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('campusPersonRoleDeleteTips'), t('warning'), {
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}).then(() => {
deleteCampusPersonRole(id)
.then(() => {
loadCampusPersonRoleList()
})
.catch(() => {})
})
}
const campusIdList = ref([])
const setCampusIdList = async () => {
campusIdList.value = await (await getWithCampusList({})).data
}
setCampusIdList()
const personIdList = ref([])
const setPersonIdList = async () => {
personIdList.value = await (await getWithPersonnelList({})).data
}
setPersonIdList()
const roleIdList = ref([])
const setRoleIdList = async () => {
roleIdList.value = await (await getWithSysRoleList({})).data
}
setRoleIdList()
const deptIdList = ref([])
const setDeptIdList = async () => {
deptIdList.value = await (await getWithDepartmentsList({})).data
}
setDeptIdList()
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadCampusPersonRoleList()
}
</script>
<style lang="scss" scoped>
/* 多行超出隐藏 */
.multi-hidden {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
</style>

493
admin/src/app/views/campus_person_role/components/campus-person-role-edit.vue

@ -1,225 +1,268 @@
<template> <template>
<el-dialog v-model="showDialog" :title="formData.id ? t('updateCampusPersonRole') : t('addCampusPersonRole')" width="50%" class="diy-dialog-wrap" :destroy-on-close="true"> <el-dialog
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading"> v-model="showDialog"
<el-form-item :label="t('campusId')" prop="campus_id"> :title="
<el-select class="input-width" v-model="formData.campus_id" clearable :placeholder="t('campusIdPlaceholder')"> formData.id ? t('updateCampusPersonRole') : t('addCampusPersonRole')
<el-option label="请选择" value=""></el-option> "
<el-option width="50%"
v-for="(item, index) in campusIdList" class="diy-dialog-wrap"
:key="index" :destroy-on-close="true"
:label="item['campus_name']" >
:value="item['id']" <el-form
/> :model="formData"
</el-select> label-width="120px"
</el-form-item> ref="formRef"
:rules="formRules"
<el-form-item :label="t('personId')" prop="person_id"> class="page-form"
<el-select class="input-width" v-model="formData.person_id" clearable :placeholder="t('personIdPlaceholder')"> v-loading="loading"
<el-option label="请选择" value=""></el-option> >
<el-option <el-form-item :label="t('campusId')" prop="campus_id">
v-for="(item, index) in personIdList" <el-select
:key="index" class="input-width"
:label="item['name']" v-model="formData.campus_id"
:value="item['id']" clearable
/> :placeholder="t('campusIdPlaceholder')"
</el-select> >
</el-form-item> <el-option label="请选择" value=""></el-option>
<el-option
<el-form-item :label="t('roleId')" prop="role_id"> v-for="(item, index) in campusIdList"
<el-select class="input-width" v-model="formData.role_id" clearable :placeholder="t('roleIdPlaceholder')"> :key="index"
<el-option label="请选择" value=""></el-option> :label="item['campus_name']"
<el-option :value="item['id']"
v-for="(item, index) in roleIdList" />
:key="index" </el-select>
:label="item['role_name']" </el-form-item>
:value="item['role_id']"
/> <el-form-item :label="t('personId')" prop="person_id">
</el-select> <el-select
</el-form-item> class="input-width"
v-model="formData.person_id"
<el-form-item :label="t('deptId')" > clearable
<el-select class="input-width" v-model="formData.dept_id" clearable :placeholder="t('deptIdPlaceholder')"> :placeholder="t('personIdPlaceholder')"
<el-option label="请选择" value=""></el-option> >
<el-option <el-option label="请选择" value=""></el-option>
v-for="(item, index) in deptIdList" <el-option
:key="index" v-for="(item, index) in personIdList"
:label="item['department_name']" :key="index"
:value="item['id']" :label="item['name']"
/> :value="item['id']"
</el-select> />
</el-form-item> </el-select>
</el-form-item>
</el-form>
<el-form-item :label="t('roleId')" prop="role_id">
<template #footer> <el-select
<span class="dialog-footer"> class="input-width"
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button> v-model="formData.role_id"
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{ clearable
t('confirm') :placeholder="t('roleIdPlaceholder')"
}}</el-button> >
</span> <el-option label="请选择" value=""></el-option>
</template> <el-option
</el-dialog> v-for="(item, index) in roleIdList"
</template> :key="index"
:label="item['role_name']"
<script lang="ts" setup> :value="item['role_id']"
import { ref, reactive, computed, watch } from 'vue' />
import { useDictionary } from '@/app/api/dict' </el-select>
import { t } from '@/lang' </el-form-item>
import type { FormInstance } from 'element-plus'
import { addCampusPersonRole, editCampusPersonRole, getCampusPersonRoleInfo, getWithCampusList, getWithPersonnelList, getWithSysRoleList, getWithDepartmentsList } from '@/app/api/campus_person_role' <el-form-item :label="t('deptId')">
<el-select
let showDialog = ref(false) class="input-width"
const loading = ref(false) v-model="formData.dept_id"
clearable
/** :placeholder="t('deptIdPlaceholder')"
* 表单数据 >
*/ <el-option label="请选择" value=""></el-option>
const initialFormData = { <el-option
id: '', v-for="(item, index) in deptIdList"
campus_id: '', :key="index"
person_id: '', :label="item['department_name']"
role_id: '', :value="item['id']"
dept_id: '', />
} </el-select>
const formData: Record<string, any> = reactive({ ...initialFormData }) </el-form-item>
</el-form>
const formRef = ref<FormInstance>()
<template #footer>
// <span class="dialog-footer">
const formRules = computed(() => { <el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
return { <el-button
campus_id: [ type="primary"
{ required: true, message: t('campusIdPlaceholder'), trigger: 'blur' }, :loading="loading"
@click="confirm(formRef)"
] >{{ t('confirm') }}</el-button
, >
person_id: [ </span>
{ required: true, message: t('personIdPlaceholder'), trigger: 'blur' }, </template>
</el-dialog>
] </template>
,
role_id: [ <script lang="ts" setup>
{ required: true, message: t('roleIdPlaceholder'), trigger: 'blur' }, import { ref, reactive, computed, watch } from 'vue'
import { useDictionary } from '@/app/api/dict'
] import { t } from '@/lang'
, import type { FormInstance } from 'element-plus'
dept_id: [ import {
{ required: true, message: t('deptIdPlaceholder'), trigger: 'blur' }, addCampusPersonRole,
editCampusPersonRole,
] getCampusPersonRoleInfo,
, getWithCampusList,
} getWithPersonnelList,
}) getWithSysRoleList,
getWithDepartmentsList,
const emit = defineEmits(['complete']) } from '@/app/api/campus_person_role'
/** let showDialog = ref(false)
* 确认 const loading = ref(false)
* @param formEl
*/ /**
const confirm = async (formEl: FormInstance | undefined) => { * 表单数据
if (loading.value || !formEl) return */
let save = formData.id ? editCampusPersonRole : addCampusPersonRole const initialFormData = {
id: '',
await formEl.validate(async (valid) => { campus_id: '',
if (valid) { person_id: '',
loading.value = true role_id: '',
dept_id: '',
let data = formData }
const formData: Record<string, any> = reactive({ ...initialFormData })
save(data).then(res => {
loading.value = false const formRef = ref<FormInstance>()
showDialog.value = false
emit('complete') //
}).catch(err => { const formRules = computed(() => {
loading.value = false return {
}) campus_id: [
} { required: true, message: t('campusIdPlaceholder'), trigger: 'blur' },
}) ],
} person_id: [
{ required: true, message: t('personIdPlaceholder'), trigger: 'blur' },
// ],
role_id: [
{ required: true, message: t('roleIdPlaceholder'), trigger: 'blur' },
],
const campusIdList = ref([] as any[]) dept_id: [
const setCampusIdList = async () => { { required: true, message: t('deptIdPlaceholder'), trigger: 'blur' },
campusIdList.value = await (await getWithCampusList({})).data ],
} }
setCampusIdList() })
const personIdList = ref([] as any[])
const setPersonIdList = async () => { const emit = defineEmits(['complete'])
personIdList.value = await (await getWithPersonnelList({})).data
} /**
setPersonIdList() * 确认
const roleIdList = ref([] as any[]) * @param formEl
const setRoleIdList = async () => { */
roleIdList.value = await (await getWithSysRoleList({})).data const confirm = async (formEl: FormInstance | undefined) => {
} if (loading.value || !formEl) return
setRoleIdList() let save = formData.id ? editCampusPersonRole : addCampusPersonRole
const deptIdList = ref([] as any[])
const setDeptIdList = async () => { await formEl.validate(async (valid) => {
deptIdList.value = await (await getWithDepartmentsList({})).data if (valid) {
} loading.value = true
setDeptIdList()
const setFormData = async (row: any = null) => { let data = formData
Object.assign(formData, initialFormData)
loading.value = true save(data)
if(row){ .then((res) => {
const data = await (await getCampusPersonRoleInfo(row.id)).data loading.value = false
if (data) Object.keys(formData).forEach((key: string) => { showDialog.value = false
if (data[key] != undefined) formData[key] = data[key] emit('complete')
}) })
} .catch((err) => {
loading.value = false loading.value = false
} })
}
// })
const mobileVerify = (rule: any, value: any, callback: any) => { }
if (value && !/^1[3-9]\d{9}$/.test(value)) {
callback(new Error(t('generateMobile'))) //
} else {
callback() const campusIdList = ref([] as any[])
} const setCampusIdList = async () => {
} campusIdList.value = await (await getWithCampusList({})).data
}
// setCampusIdList()
const idCardVerify = (rule: any, value: any, callback: any) => { const personIdList = ref([] as any[])
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) { const setPersonIdList = async () => {
callback(new Error(t('generateIdCard'))) personIdList.value = await (await getWithPersonnelList({})).data
} else { }
callback() setPersonIdList()
} const roleIdList = ref([] as any[])
} const setRoleIdList = async () => {
roleIdList.value = await (await getWithSysRoleList({})).data
// }
const emailVerify = (rule: any, value: any, callback: any) => { setRoleIdList()
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) { const deptIdList = ref([] as any[])
callback(new Error(t('generateEmail'))) const setDeptIdList = async () => {
} else { deptIdList.value = await (await getWithDepartmentsList({})).data
callback() }
} setDeptIdList()
} const setFormData = async (row: any = null) => {
Object.assign(formData, initialFormData)
// loading.value = true
const numberVerify = (rule: any, value: any, callback: any) => { if (row) {
if (!Number.isInteger(value)) { const data = await (await getCampusPersonRoleInfo(row.id)).data
callback(new Error(t('generateNumber'))) if (data)
} else { Object.keys(formData).forEach((key: string) => {
callback() if (data[key] != undefined) formData[key] = data[key]
} })
} }
loading.value = false
defineExpose({ }
showDialog,
setFormData //
}) const mobileVerify = (rule: any, value: any, callback: any) => {
</script> if (value && !/^1[3-9]\d{9}$/.test(value)) {
callback(new Error(t('generateMobile')))
<style lang="scss" scoped></style> } else {
<style lang="scss"> callback()
.diy-dialog-wrap .el-form-item__label{ }
height: auto !important; }
}
</style> //
const idCardVerify = (rule: any, value: any, callback: any) => {
if (
value &&
!/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
value
)
) {
callback(new Error(t('generateIdCard')))
} else {
callback()
}
}
//
const emailVerify = (rule: any, value: any, callback: any) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail')))
} else {
callback()
}
}
//
const numberVerify = (rule: any, value: any, callback: any) => {
if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber')))
} else {
callback()
}
}
defineExpose({
showDialog,
setFormData,
})
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.diy-dialog-wrap .el-form-item__label {
height: auto !important;
}
</style>

591
admin/src/app/views/class/class.vue

@ -1,231 +1,360 @@
<template> <template>
<div class="main-container"> <div class="main-container">
<el-card class="box-card !border-none" shadow="never"> <el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<div class="flex justify-between items-center"> <span class="text-lg">{{ pageName }}</span>
<span class="text-lg">{{pageName}}</span> <el-button type="primary" @click="addEvent">
<el-button type="primary" @click="addEvent"> {{ t('addClass') }}
{{ t('addClass') }} </el-button>
</el-button> </div>
</div>
<el-card
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> class="box-card !border-none my-[10px] table-search-wrap"
<el-form :inline="true" :model="classTable.searchParam" ref="searchFormRef"> shadow="never"
<el-form-item :label="t('campusId')" prop="campus_id"> >
<el-input v-model="classTable.searchParam.campus_id" :placeholder="t('campusIdPlaceholder')" /> <el-form
</el-form-item> :inline="true"
<el-form-item :label="t('campusName')" prop="campus_name"> :model="classTable.searchParam"
<el-input v-model="classTable.searchParam.campus_name" :placeholder="t('campusNamePlaceholder')" /> ref="searchFormRef"
</el-form-item> >
<el-form-item :label="t('className')" prop="class_name"> <el-form-item :label="t('campusId')" prop="campus_id">
<el-input v-model="classTable.searchParam.class_name" :placeholder="t('classNamePlaceholder')" /> <el-input
</el-form-item> v-model="classTable.searchParam.campus_id"
<el-form-item :label="t('headCoach')" prop="head_coach"> :placeholder="t('campusIdPlaceholder')"
<el-input v-model="classTable.searchParam.head_coach" :placeholder="t('headCoachPlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('ageGroup')" prop="age_group"> <el-form-item :label="t('campusName')" prop="campus_name">
<el-input v-model="classTable.searchParam.age_group" :placeholder="t('ageGroupPlaceholder')" /> <el-input
</el-form-item> v-model="classTable.searchParam.campus_name"
<el-form-item :label="t('classType')" prop="class_type"> :placeholder="t('campusNamePlaceholder')"
<el-input v-model="classTable.searchParam.class_type" :placeholder="t('classTypePlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('assistantCoach')" prop="assistant_coach"> <el-form-item :label="t('className')" prop="class_name">
<el-input v-model="classTable.searchParam.assistant_coach" :placeholder="t('assistantCoachPlaceholder')" /> <el-input
</el-form-item> v-model="classTable.searchParam.class_name"
<el-form-item :label="t('createdAt')" prop="created_at"> :placeholder="t('classNamePlaceholder')"
<el-input v-model="classTable.searchParam.created_at" :placeholder="t('createdAtPlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('updatedAt')" prop="updated_at"> <el-form-item :label="t('headCoach')" prop="head_coach">
<el-input v-model="classTable.searchParam.updated_at" :placeholder="t('updatedAtPlaceholder')" /> <el-input
</el-form-item> v-model="classTable.searchParam.head_coach"
<el-form-item :label="t('deletedAt')" prop="deleted_at"> :placeholder="t('headCoachPlaceholder')"
<el-input v-model="classTable.searchParam.deleted_at" :placeholder="t('deletedAtPlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('status')" prop="status"> <el-form-item :label="t('ageGroup')" prop="age_group">
<el-input v-model="classTable.searchParam.status" :placeholder="t('statusPlaceholder')" /> <el-input
</el-form-item> v-model="classTable.searchParam.age_group"
<el-form-item :label="t('sortOrder')" prop="sort_order"> :placeholder="t('ageGroupPlaceholder')"
<el-input v-model="classTable.searchParam.sort_order" :placeholder="t('sortOrderPlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('remarks')" prop="remarks"> <el-form-item :label="t('classType')" prop="class_type">
<el-input v-model="classTable.searchParam.remarks" :placeholder="t('remarksPlaceholder')" /> <el-input
</el-form-item> v-model="classTable.searchParam.class_type"
<el-form-item> :placeholder="t('classTypePlaceholder')"
<el-button type="primary" @click="loadClassList()">{{ t('search') }}</el-button> />
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> </el-form-item>
</el-form-item> <el-form-item :label="t('assistantCoach')" prop="assistant_coach">
</el-form> <el-input
</el-card> v-model="classTable.searchParam.assistant_coach"
:placeholder="t('assistantCoachPlaceholder')"
<div class="mt-[10px]"> />
<el-table :data="classTable.data" size="large" v-loading="classTable.loading"> </el-form-item>
<template #empty> <el-form-item :label="t('createdAt')" prop="created_at">
<span>{{ !classTable.loading ? t('emptyData') : '' }}</span> <el-input
</template> v-model="classTable.searchParam.created_at"
<el-table-column prop="campus_id" :label="t('campusId')" min-width="120" :show-overflow-tooltip="true"/> :placeholder="t('createdAtPlaceholder')"
/>
<el-table-column prop="campus_name" :label="t('campusName')" min-width="120" :show-overflow-tooltip="true"/> </el-form-item>
<el-form-item :label="t('updatedAt')" prop="updated_at">
<el-table-column prop="class_name" :label="t('className')" min-width="120" :show-overflow-tooltip="true"/> <el-input
v-model="classTable.searchParam.updated_at"
<el-table-column prop="head_coach" :label="t('headCoach')" min-width="120" :show-overflow-tooltip="true"/> :placeholder="t('updatedAtPlaceholder')"
/>
<el-table-column prop="age_group" :label="t('ageGroup')" min-width="120" :show-overflow-tooltip="true"/> </el-form-item>
<el-form-item :label="t('deletedAt')" prop="deleted_at">
<el-table-column prop="class_type" :label="t('classType')" min-width="120" :show-overflow-tooltip="true"/> <el-input
v-model="classTable.searchParam.deleted_at"
<el-table-column prop="assistant_coach" :label="t('assistantCoach')" min-width="120" :show-overflow-tooltip="true"/> :placeholder="t('deletedAtPlaceholder')"
/>
<el-table-column prop="created_at" :label="t('createdAt')" min-width="120" :show-overflow-tooltip="true"/> </el-form-item>
<el-form-item :label="t('status')" prop="status">
<el-table-column prop="updated_at" :label="t('updatedAt')" min-width="120" :show-overflow-tooltip="true"/> <el-input
v-model="classTable.searchParam.status"
<el-table-column prop="deleted_at" :label="t('deletedAt')" min-width="120" :show-overflow-tooltip="true"/> :placeholder="t('statusPlaceholder')"
/>
<el-table-column prop="status" :label="t('status')" min-width="120" :show-overflow-tooltip="true"/> </el-form-item>
<el-form-item :label="t('sortOrder')" prop="sort_order">
<el-table-column prop="sort_order" :label="t('sortOrder')" min-width="120" :show-overflow-tooltip="true"/> <el-input
v-model="classTable.searchParam.sort_order"
<el-table-column prop="remarks" :label="t('remarks')" min-width="120" :show-overflow-tooltip="true"/> :placeholder="t('sortOrderPlaceholder')"
/>
<el-table-column :label="t('operation')" fixed="right" min-width="120"> </el-form-item>
<template #default="{ row }"> <el-form-item :label="t('remarks')" prop="remarks">
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button> <el-input
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button> v-model="classTable.searchParam.remarks"
</template> :placeholder="t('remarksPlaceholder')"
</el-table-column> />
</el-form-item>
</el-table>
<div class="mt-[16px] flex justify-end"> <el-form-item>
<el-pagination v-model:current-page="classTable.page" v-model:page-size="classTable.limit" <el-button type="primary" @click="loadClassList()">{{
layout="total, sizes, prev, pager, next, jumper" :total="classTable.total" t('search')
@size-change="loadClassList()" @current-change="loadClassList" /> }}</el-button>
</div> <el-button @click="resetForm(searchFormRef)">{{
</div> t('reset')
}}</el-button>
<edit ref="editClassDialog" @complete="loadClassList" /> </el-form-item>
</el-card> </el-form>
</div> </el-card>
</template>
<div class="mt-[10px]">
<script lang="ts" setup> <el-table
import { reactive, ref, watch } from 'vue' :data="classTable.data"
import { t } from '@/lang' size="large"
import { useDictionary } from '@/app/api/dict' v-loading="classTable.loading"
import { getClassList, deleteClass } from '@/app/api/class' >
import { img } from '@/utils/common' <template #empty>
import { ElMessageBox,FormInstance } from 'element-plus' <span>{{ !classTable.loading ? t('emptyData') : '' }}</span>
import Edit from '@/app/views/class/components/class-edit.vue' </template>
import { useRoute } from 'vue-router' <el-table-column
const route = useRoute() prop="campus_id"
const pageName = route.meta.title; :label="t('campusId')"
min-width="120"
let classTable = reactive({ :show-overflow-tooltip="true"
page: 1, />
limit: 10,
total: 0, <el-table-column
loading: true, prop="campus_name"
data: [], :label="t('campusName')"
searchParam:{ min-width="120"
"campus_id":"", :show-overflow-tooltip="true"
"campus_name":"", />
"class_name":"",
"head_coach":"", <el-table-column
"age_group":"", prop="class_name"
"class_type":"", :label="t('className')"
"assistant_coach":"", min-width="120"
"created_at":"", :show-overflow-tooltip="true"
"updated_at":"", />
"deleted_at":"",
"status":"", <el-table-column
"sort_order":"", prop="head_coach"
"remarks":"" :label="t('headCoach')"
} min-width="120"
}) :show-overflow-tooltip="true"
/>
const searchFormRef = ref<FormInstance>()
<el-table-column
// prop="age_group"
const selectData = ref<any[]>([]) :label="t('ageGroup')"
min-width="120"
// :show-overflow-tooltip="true"
/>
/** <el-table-column
* 获取班级列表 prop="class_type"
*/ :label="t('classType')"
const loadClassList = (page: number = 1) => { min-width="120"
classTable.loading = true :show-overflow-tooltip="true"
classTable.page = page />
getClassList({ <el-table-column
page: classTable.page, prop="assistant_coach"
limit: classTable.limit, :label="t('assistantCoach')"
...classTable.searchParam min-width="120"
}).then(res => { :show-overflow-tooltip="true"
classTable.loading = false />
classTable.data = res.data.data
classTable.total = res.data.total <el-table-column
}).catch(() => { prop="created_at"
classTable.loading = false :label="t('createdAt')"
}) min-width="120"
} :show-overflow-tooltip="true"
loadClassList() />
const editClassDialog: Record<string, any> | null = ref(null) <el-table-column
prop="updated_at"
/** :label="t('updatedAt')"
* 添加班级 min-width="120"
*/ :show-overflow-tooltip="true"
const addEvent = () => { />
editClassDialog.value.setFormData()
editClassDialog.value.showDialog = true <el-table-column
} prop="deleted_at"
:label="t('deletedAt')"
/** min-width="120"
* 编辑班级 :show-overflow-tooltip="true"
* @param data />
*/
const editEvent = (data: any) => { <el-table-column
editClassDialog.value.setFormData(data) prop="status"
editClassDialog.value.showDialog = true :label="t('status')"
} min-width="120"
:show-overflow-tooltip="true"
/** />
* 删除班级
*/ <el-table-column
const deleteEvent = (id: number) => { prop="sort_order"
ElMessageBox.confirm(t('classDeleteTips'), t('warning'), :label="t('sortOrder')"
{ min-width="120"
confirmButtonText: t('confirm'), :show-overflow-tooltip="true"
cancelButtonText: t('cancel'), />
type: 'warning',
} <el-table-column
).then(() => { prop="remarks"
deleteClass(id).then(() => { :label="t('remarks')"
loadClassList() min-width="120"
}).catch(() => { :show-overflow-tooltip="true"
}) />
})
} <el-table-column
:label="t('operation')"
fixed="right"
min-width="120"
const resetForm = (formEl: FormInstance | undefined) => { >
if (!formEl) return <template #default="{ row }">
formEl.resetFields() <el-button type="primary" link @click="editEvent(row)">{{
loadClassList() t('edit')
} }}</el-button>
</script> <el-button type="primary" link @click="deleteEvent(row.id)">{{
t('delete')
<style lang="scss" scoped> }}</el-button>
/* 多行超出隐藏 */ </template>
.multi-hidden { </el-table-column>
word-break: break-all; </el-table>
text-overflow: ellipsis; <div class="mt-[16px] flex justify-end">
overflow: hidden; <el-pagination
display: -webkit-box; v-model:current-page="classTable.page"
-webkit-line-clamp: 2; v-model:page-size="classTable.limit"
-webkit-box-orient: vertical; layout="total, sizes, prev, pager, next, jumper"
} :total="classTable.total"
</style> @size-change="loadClassList()"
@current-change="loadClassList"
/>
</div>
</div>
<edit ref="editClassDialog" @complete="loadClassList" />
</el-card>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref, watch } from 'vue'
import { t } from '@/lang'
import { useDictionary } from '@/app/api/dict'
import { getClassList, deleteClass } from '@/app/api/class'
import { img } from '@/utils/common'
import { ElMessageBox, FormInstance } from 'element-plus'
import Edit from '@/app/views/class/components/class-edit.vue'
import { useRoute } from 'vue-router'
const route = useRoute()
const pageName = route.meta.title
let classTable = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {
campus_id: '',
campus_name: '',
class_name: '',
head_coach: '',
age_group: '',
class_type: '',
assistant_coach: '',
created_at: '',
updated_at: '',
deleted_at: '',
status: '',
sort_order: '',
remarks: '',
},
})
const searchFormRef = ref<FormInstance>()
//
const selectData = ref<any[]>([])
//
/**
* 获取班级列表
*/
const loadClassList = (page: number = 1) => {
classTable.loading = true
classTable.page = page
getClassList({
page: classTable.page,
limit: classTable.limit,
...classTable.searchParam,
})
.then((res) => {
classTable.loading = false
classTable.data = res.data.data
classTable.total = res.data.total
})
.catch(() => {
classTable.loading = false
})
}
loadClassList()
const editClassDialog: Record<string, any> | null = ref(null)
/**
* 添加班级
*/
const addEvent = () => {
editClassDialog.value.setFormData()
editClassDialog.value.showDialog = true
}
/**
* 编辑班级
* @param data
*/
const editEvent = (data: any) => {
editClassDialog.value.setFormData(data)
editClassDialog.value.showDialog = true
}
/**
* 删除班级
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('classDeleteTips'), t('warning'), {
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}).then(() => {
deleteClass(id)
.then(() => {
loadClassList()
})
.catch(() => {})
})
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadClassList()
}
</script>
<style lang="scss" scoped>
/* 多行超出隐藏 */
.multi-hidden {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
</style>

590
admin/src/app/views/class/components/class-edit.vue

@ -1,263 +1,327 @@
<template> <template>
<el-dialog v-model="showDialog" :title="formData.id ? t('updateClass') : t('addClass')" width="50%" class="diy-dialog-wrap" :destroy-on-close="true"> <el-dialog
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading"> v-model="showDialog"
<el-form-item :label="t('campusId')" prop="campus_id"> :title="formData.id ? t('updateClass') : t('addClass')"
<el-input v-model="formData.campus_id" clearable :placeholder="t('campusIdPlaceholder')" class="input-width" /> width="50%"
</el-form-item> class="diy-dialog-wrap"
:destroy-on-close="true"
<el-form-item :label="t('campusName')" prop="campus_name"> >
<el-input v-model="formData.campus_name" clearable :placeholder="t('campusNamePlaceholder')" class="input-width" /> <el-form
</el-form-item> :model="formData"
label-width="120px"
<el-form-item :label="t('className')" prop="class_name"> ref="formRef"
<el-input v-model="formData.class_name" clearable :placeholder="t('classNamePlaceholder')" class="input-width" /> :rules="formRules"
</el-form-item> class="page-form"
v-loading="loading"
<el-form-item :label="t('headCoach')" prop="head_coach"> >
<el-input v-model="formData.head_coach" clearable :placeholder="t('headCoachPlaceholder')" class="input-width" /> <el-form-item :label="t('campusId')" prop="campus_id">
</el-form-item> <el-input
v-model="formData.campus_id"
<el-form-item :label="t('ageGroup')" prop="age_group"> clearable
<el-input v-model="formData.age_group" clearable :placeholder="t('ageGroupPlaceholder')" class="input-width" /> :placeholder="t('campusIdPlaceholder')"
</el-form-item> class="input-width"
/>
<el-form-item :label="t('classType')" prop="class_type"> </el-form-item>
<el-input v-model="formData.class_type" clearable :placeholder="t('classTypePlaceholder')" class="input-width" />
</el-form-item> <el-form-item :label="t('campusName')" prop="campus_name">
<el-input
<el-form-item :label="t('assistantCoach')" prop="assistant_coach"> v-model="formData.campus_name"
<el-input v-model="formData.assistant_coach" clearable :placeholder="t('assistantCoachPlaceholder')" class="input-width" /> clearable
</el-form-item> :placeholder="t('campusNamePlaceholder')"
class="input-width"
<el-form-item :label="t('createdAt')" > />
<el-input v-model="formData.created_at" clearable :placeholder="t('createdAtPlaceholder')" class="input-width" /> </el-form-item>
</el-form-item>
<el-form-item :label="t('className')" prop="class_name">
<el-form-item :label="t('updatedAt')" > <el-input
<el-input v-model="formData.updated_at" clearable :placeholder="t('updatedAtPlaceholder')" class="input-width" /> v-model="formData.class_name"
</el-form-item> clearable
:placeholder="t('classNamePlaceholder')"
<el-form-item :label="t('deletedAt')" > class="input-width"
<el-input v-model="formData.deleted_at" clearable :placeholder="t('deletedAtPlaceholder')" class="input-width" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('status')" prop="status"> <el-form-item :label="t('headCoach')" prop="head_coach">
<el-input v-model="formData.status" clearable :placeholder="t('statusPlaceholder')" class="input-width" /> <el-input
</el-form-item> v-model="formData.head_coach"
clearable
<el-form-item :label="t('sortOrder')" prop="sort_order"> :placeholder="t('headCoachPlaceholder')"
<el-input v-model="formData.sort_order" clearable :placeholder="t('sortOrderPlaceholder')" class="input-width" /> class="input-width"
</el-form-item> />
</el-form-item>
<el-form-item :label="t('remarks')" >
<el-input v-model="formData.remarks" clearable :placeholder="t('remarksPlaceholder')" class="input-width" /> <el-form-item :label="t('ageGroup')" prop="age_group">
</el-form-item> <el-input
v-model="formData.age_group"
</el-form> clearable
:placeholder="t('ageGroupPlaceholder')"
<template #footer> class="input-width"
<span class="dialog-footer"> />
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button> </el-form-item>
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{
t('confirm') <el-form-item :label="t('classType')" prop="class_type">
}}</el-button> <el-input
</span> v-model="formData.class_type"
</template> clearable
</el-dialog> :placeholder="t('classTypePlaceholder')"
</template> class="input-width"
/>
<script lang="ts" setup> </el-form-item>
import { ref, reactive, computed, watch } from 'vue'
import { useDictionary } from '@/app/api/dict' <el-form-item :label="t('assistantCoach')" prop="assistant_coach">
import { t } from '@/lang' <el-input
import type { FormInstance } from 'element-plus' v-model="formData.assistant_coach"
import { addClass, editClass, getClassInfo } from '@/app/api/class' clearable
:placeholder="t('assistantCoachPlaceholder')"
let showDialog = ref(false) class="input-width"
const loading = ref(false) />
</el-form-item>
/**
* 表单数据 <el-form-item :label="t('createdAt')">
*/ <el-input
const initialFormData = { v-model="formData.created_at"
id: '', clearable
campus_id: '', :placeholder="t('createdAtPlaceholder')"
campus_name: '', class="input-width"
class_name: '', />
head_coach: '', </el-form-item>
age_group: '',
class_type: '', <el-form-item :label="t('updatedAt')">
assistant_coach: '', <el-input
created_at: '', v-model="formData.updated_at"
updated_at: '', clearable
deleted_at: '', :placeholder="t('updatedAtPlaceholder')"
status: '', class="input-width"
sort_order: '', />
remarks: '', </el-form-item>
}
const formData: Record<string, any> = reactive({ ...initialFormData }) <el-form-item :label="t('deletedAt')">
<el-input
const formRef = ref<FormInstance>() v-model="formData.deleted_at"
clearable
// :placeholder="t('deletedAtPlaceholder')"
const formRules = computed(() => { class="input-width"
return { />
campus_id: [ </el-form-item>
{ required: true, message: t('campusIdPlaceholder'), trigger: 'blur' },
<el-form-item :label="t('status')" prop="status">
] <el-input
, v-model="formData.status"
campus_name: [ clearable
{ required: true, message: t('campusNamePlaceholder'), trigger: 'blur' }, :placeholder="t('statusPlaceholder')"
class="input-width"
] />
, </el-form-item>
class_name: [
{ required: true, message: t('classNamePlaceholder'), trigger: 'blur' }, <el-form-item :label="t('sortOrder')" prop="sort_order">
<el-input
] v-model="formData.sort_order"
, clearable
head_coach: [ :placeholder="t('sortOrderPlaceholder')"
{ required: true, message: t('headCoachPlaceholder'), trigger: 'blur' }, class="input-width"
/>
] </el-form-item>
,
age_group: [ <el-form-item :label="t('remarks')">
{ required: true, message: t('ageGroupPlaceholder'), trigger: 'blur' }, <el-input
v-model="formData.remarks"
] clearable
, :placeholder="t('remarksPlaceholder')"
class_type: [ class="input-width"
{ required: true, message: t('classTypePlaceholder'), trigger: 'blur' }, />
</el-form-item>
] </el-form>
,
assistant_coach: [ <template #footer>
{ required: true, message: t('assistantCoachPlaceholder'), trigger: 'blur' }, <span class="dialog-footer">
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
] <el-button
, type="primary"
created_at: [ :loading="loading"
{ required: true, message: t('createdAtPlaceholder'), trigger: 'blur' }, @click="confirm(formRef)"
>{{ t('confirm') }}</el-button
] >
, </span>
updated_at: [ </template>
{ required: true, message: t('updatedAtPlaceholder'), trigger: 'blur' }, </el-dialog>
</template>
]
, <script lang="ts" setup>
deleted_at: [ import { ref, reactive, computed, watch } from 'vue'
{ required: true, message: t('deletedAtPlaceholder'), trigger: 'blur' }, import { useDictionary } from '@/app/api/dict'
import { t } from '@/lang'
] import type { FormInstance } from 'element-plus'
, import { addClass, editClass, getClassInfo } from '@/app/api/class'
status: [
{ required: true, message: t('statusPlaceholder'), trigger: 'blur' }, let showDialog = ref(false)
const loading = ref(false)
]
, /**
sort_order: [ * 表单数据
{ required: true, message: t('sortOrderPlaceholder'), trigger: 'blur' }, */
const initialFormData = {
] id: '',
, campus_id: '',
remarks: [ campus_name: '',
{ required: true, message: t('remarksPlaceholder'), trigger: 'blur' }, class_name: '',
head_coach: '',
] age_group: '',
, class_type: '',
} assistant_coach: '',
}) created_at: '',
updated_at: '',
const emit = defineEmits(['complete']) deleted_at: '',
status: '',
/** sort_order: '',
* 确认 remarks: '',
* @param formEl }
*/ const formData: Record<string, any> = reactive({ ...initialFormData })
const confirm = async (formEl: FormInstance | undefined) => {
if (loading.value || !formEl) return const formRef = ref<FormInstance>()
let save = formData.id ? editClass : addClass
//
await formEl.validate(async (valid) => { const formRules = computed(() => {
if (valid) { return {
loading.value = true campus_id: [
{ required: true, message: t('campusIdPlaceholder'), trigger: 'blur' },
let data = formData ],
campus_name: [
save(data).then(res => { { required: true, message: t('campusNamePlaceholder'), trigger: 'blur' },
loading.value = false ],
showDialog.value = false class_name: [
emit('complete') { required: true, message: t('classNamePlaceholder'), trigger: 'blur' },
}).catch(err => { ],
loading.value = false head_coach: [
}) { required: true, message: t('headCoachPlaceholder'), trigger: 'blur' },
} ],
}) age_group: [
} { required: true, message: t('ageGroupPlaceholder'), trigger: 'blur' },
],
// class_type: [
{ required: true, message: t('classTypePlaceholder'), trigger: 'blur' },
],
assistant_coach: [
const setFormData = async (row: any = null) => { {
Object.assign(formData, initialFormData) required: true,
loading.value = true message: t('assistantCoachPlaceholder'),
if(row){ trigger: 'blur',
const data = await (await getClassInfo(row.id)).data },
if (data) Object.keys(formData).forEach((key: string) => { ],
if (data[key] != undefined) formData[key] = data[key] created_at: [
}) { required: true, message: t('createdAtPlaceholder'), trigger: 'blur' },
} ],
loading.value = false updated_at: [
} { required: true, message: t('updatedAtPlaceholder'), trigger: 'blur' },
],
// deleted_at: [
const mobileVerify = (rule: any, value: any, callback: any) => { { required: true, message: t('deletedAtPlaceholder'), trigger: 'blur' },
if (value && !/^1[3-9]\d{9}$/.test(value)) { ],
callback(new Error(t('generateMobile'))) status: [
} else { { required: true, message: t('statusPlaceholder'), trigger: 'blur' },
callback() ],
} sort_order: [
} { required: true, message: t('sortOrderPlaceholder'), trigger: 'blur' },
],
// remarks: [
const idCardVerify = (rule: any, value: any, callback: any) => { { required: true, message: t('remarksPlaceholder'), trigger: 'blur' },
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) { ],
callback(new Error(t('generateIdCard'))) }
} else { })
callback()
} const emit = defineEmits(['complete'])
}
/**
// * 确认
const emailVerify = (rule: any, value: any, callback: any) => { * @param formEl
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) { */
callback(new Error(t('generateEmail'))) const confirm = async (formEl: FormInstance | undefined) => {
} else { if (loading.value || !formEl) return
callback() let save = formData.id ? editClass : addClass
}
} await formEl.validate(async (valid) => {
if (valid) {
// loading.value = true
const numberVerify = (rule: any, value: any, callback: any) => {
if (!Number.isInteger(value)) { let data = formData
callback(new Error(t('generateNumber')))
} else { save(data)
callback() .then((res) => {
} loading.value = false
} showDialog.value = false
emit('complete')
defineExpose({ })
showDialog, .catch((err) => {
setFormData loading.value = false
}) })
</script> }
})
<style lang="scss" scoped></style> }
<style lang="scss">
.diy-dialog-wrap .el-form-item__label{ //
height: auto !important;
} const setFormData = async (row: any = null) => {
</style> Object.assign(formData, initialFormData)
loading.value = true
if (row) {
const data = await (await getClassInfo(row.id)).data
if (data)
Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key]
})
}
loading.value = false
}
//
const mobileVerify = (rule: any, value: any, callback: any) => {
if (value && !/^1[3-9]\d{9}$/.test(value)) {
callback(new Error(t('generateMobile')))
} else {
callback()
}
}
//
const idCardVerify = (rule: any, value: any, callback: any) => {
if (
value &&
!/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
value
)
) {
callback(new Error(t('generateIdCard')))
} else {
callback()
}
}
//
const emailVerify = (rule: any, value: any, callback: any) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail')))
} else {
callback()
}
}
//
const numberVerify = (rule: any, value: any, callback: any) => {
if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber')))
} else {
callback()
}
}
defineExpose({
showDialog,
setFormData,
})
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.diy-dialog-wrap .el-form-item__label {
height: auto !important;
}
</style>

570
admin/src/app/views/communication_records/communication_records.vue

@ -1,219 +1,351 @@
<template> <template>
<div class="main-container"> <div class="main-container">
<el-card class="box-card !border-none" shadow="never"> <el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<div class="flex justify-between items-center"> <span class="text-lg">{{ pageName }}</span>
<span class="text-lg">{{pageName}}</span> <el-button type="primary" @click="addEvent">
<el-button type="primary" @click="addEvent"> {{ t('addCommunicationRecords') }}
{{ t('addCommunicationRecords') }} </el-button>
</el-button> </div>
</div>
<el-card
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> class="box-card !border-none my-[10px] table-search-wrap"
<el-form :inline="true" :model="communicationRecordsTable.searchParam" ref="searchFormRef"> shadow="never"
<el-form-item :label="t('staffId')" prop="staff_id"> >
<el-input v-model="communicationRecordsTable.searchParam.staff_id" :placeholder="t('staffIdPlaceholder')" /> <el-form
</el-form-item> :inline="true"
<el-form-item :label="t('resourceId')" prop="resource_id"> :model="communicationRecordsTable.searchParam"
<el-input v-model="communicationRecordsTable.searchParam.resource_id" :placeholder="t('resourceIdPlaceholder')" /> ref="searchFormRef"
</el-form-item> >
<el-form-item :label="t('resourceType')" prop="resource_type"> <el-form-item :label="t('staffId')" prop="staff_id">
<el-input v-model="communicationRecordsTable.searchParam.resource_type" :placeholder="t('resourceTypePlaceholder')" /> <el-input
</el-form-item> v-model="communicationRecordsTable.searchParam.staff_id"
<el-form-item :label="t('communicationType')" prop="communication_type"> :placeholder="t('staffIdPlaceholder')"
<el-input v-model="communicationRecordsTable.searchParam.communication_type" :placeholder="t('communicationTypePlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('communicationResult')" prop="communication_result"> <el-form-item :label="t('resourceId')" prop="resource_id">
<el-input v-model="communicationRecordsTable.searchParam.communication_result" :placeholder="t('communicationResultPlaceholder')" /> <el-input
</el-form-item> v-model="communicationRecordsTable.searchParam.resource_id"
<el-form-item :label="t('communicationTime')" prop="communication_time"> :placeholder="t('resourceIdPlaceholder')"
<el-input v-model="communicationRecordsTable.searchParam.communication_time" :placeholder="t('communicationTimePlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('remarks')" prop="remarks"> <el-form-item :label="t('resourceType')" prop="resource_type">
<el-input v-model="communicationRecordsTable.searchParam.remarks" :placeholder="t('remarksPlaceholder')" /> <el-input
</el-form-item> v-model="communicationRecordsTable.searchParam.resource_type"
<el-form-item :label="t('tag')" prop="tag"> :placeholder="t('resourceTypePlaceholder')"
<el-input v-model="communicationRecordsTable.searchParam.tag" :placeholder="t('tagPlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('businessId')" prop="business_id"> <el-form-item
<el-input v-model="communicationRecordsTable.searchParam.business_id" :placeholder="t('businessIdPlaceholder')" /> :label="t('communicationType')"
</el-form-item> prop="communication_type"
<el-form-item :label="t('createdAt')" prop="created_at"> >
<el-input v-model="communicationRecordsTable.searchParam.created_at" :placeholder="t('createdAtPlaceholder')" /> <el-input
</el-form-item> v-model="communicationRecordsTable.searchParam.communication_type"
<el-form-item :label="t('updatedAt')" prop="updated_at"> :placeholder="t('communicationTypePlaceholder')"
<el-input v-model="communicationRecordsTable.searchParam.updated_at" :placeholder="t('updatedAtPlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item
<el-button type="primary" @click="loadCommunicationRecordsList()">{{ t('search') }}</el-button> :label="t('communicationResult')"
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> prop="communication_result"
</el-form-item> >
</el-form> <el-input
</el-card> v-model="
communicationRecordsTable.searchParam.communication_result
<div class="mt-[10px]"> "
<el-table :data="communicationRecordsTable.data" size="large" v-loading="communicationRecordsTable.loading"> :placeholder="t('communicationResultPlaceholder')"
<template #empty> />
<span>{{ !communicationRecordsTable.loading ? t('emptyData') : '' }}</span> </el-form-item>
</template> <el-form-item
<el-table-column prop="staff_id" :label="t('staffId')" min-width="120" :show-overflow-tooltip="true"/> :label="t('communicationTime')"
prop="communication_time"
<el-table-column prop="resource_id" :label="t('resourceId')" min-width="120" :show-overflow-tooltip="true"/> >
<el-input
<el-table-column prop="resource_type" :label="t('resourceType')" min-width="120" :show-overflow-tooltip="true"/> v-model="communicationRecordsTable.searchParam.communication_time"
:placeholder="t('communicationTimePlaceholder')"
<el-table-column prop="communication_type" :label="t('communicationType')" min-width="120" :show-overflow-tooltip="true"/> />
</el-form-item>
<el-table-column prop="communication_result" :label="t('communicationResult')" min-width="120" :show-overflow-tooltip="true"/> <el-form-item :label="t('remarks')" prop="remarks">
<el-input
<el-table-column prop="communication_time" :label="t('communicationTime')" min-width="120" :show-overflow-tooltip="true"/> v-model="communicationRecordsTable.searchParam.remarks"
:placeholder="t('remarksPlaceholder')"
<el-table-column prop="remarks" :label="t('remarks')" min-width="120" :show-overflow-tooltip="true"/> />
</el-form-item>
<el-table-column prop="tag" :label="t('tag')" min-width="120" :show-overflow-tooltip="true"/> <el-form-item :label="t('tag')" prop="tag">
<el-input
<el-table-column prop="business_id" :label="t('businessId')" min-width="120" :show-overflow-tooltip="true"/> v-model="communicationRecordsTable.searchParam.tag"
:placeholder="t('tagPlaceholder')"
<el-table-column prop="created_at" :label="t('createdAt')" min-width="120" :show-overflow-tooltip="true"/> />
</el-form-item>
<el-table-column prop="updated_at" :label="t('updatedAt')" min-width="120" :show-overflow-tooltip="true"/> <el-form-item :label="t('businessId')" prop="business_id">
<el-input
<el-table-column :label="t('operation')" fixed="right" min-width="120"> v-model="communicationRecordsTable.searchParam.business_id"
<template #default="{ row }"> :placeholder="t('businessIdPlaceholder')"
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button> />
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button> </el-form-item>
</template> <el-form-item :label="t('createdAt')" prop="created_at">
</el-table-column> <el-input
v-model="communicationRecordsTable.searchParam.created_at"
</el-table> :placeholder="t('createdAtPlaceholder')"
<div class="mt-[16px] flex justify-end"> />
<el-pagination v-model:current-page="communicationRecordsTable.page" v-model:page-size="communicationRecordsTable.limit" </el-form-item>
layout="total, sizes, prev, pager, next, jumper" :total="communicationRecordsTable.total" <el-form-item :label="t('updatedAt')" prop="updated_at">
@size-change="loadCommunicationRecordsList()" @current-change="loadCommunicationRecordsList" /> <el-input
</div> v-model="communicationRecordsTable.searchParam.updated_at"
</div> :placeholder="t('updatedAtPlaceholder')"
/>
<edit ref="editCommunicationRecordsDialog" @complete="loadCommunicationRecordsList" /> </el-form-item>
</el-card>
</div> <el-form-item>
</template> <el-button type="primary" @click="loadCommunicationRecordsList()">{{
t('search')
<script lang="ts" setup> }}</el-button>
import { reactive, ref, watch } from 'vue' <el-button @click="resetForm(searchFormRef)">{{
import { t } from '@/lang' t('reset')
import { useDictionary } from '@/app/api/dict' }}</el-button>
import { getCommunicationRecordsList, deleteCommunicationRecords } from '@/app/api/communication_records' </el-form-item>
import { img } from '@/utils/common' </el-form>
import { ElMessageBox,FormInstance } from 'element-plus' </el-card>
import Edit from '@/app/views/communication_records/components/communication-records-edit.vue'
import { useRoute } from 'vue-router' <div class="mt-[10px]">
const route = useRoute() <el-table
const pageName = route.meta.title; :data="communicationRecordsTable.data"
size="large"
let communicationRecordsTable = reactive({ v-loading="communicationRecordsTable.loading"
page: 1, >
limit: 10, <template #empty>
total: 0, <span>{{
loading: true, !communicationRecordsTable.loading ? t('emptyData') : ''
data: [], }}</span>
searchParam:{ </template>
"staff_id":"", <el-table-column
"resource_id":"", prop="staff_id"
"resource_type":"", :label="t('staffId')"
"communication_type":"", min-width="120"
"communication_result":"", :show-overflow-tooltip="true"
"communication_time":"", />
"remarks":"",
"tag":"", <el-table-column
"business_id":"", prop="resource_id"
"created_at":"", :label="t('resourceId')"
"updated_at":"" min-width="120"
} :show-overflow-tooltip="true"
}) />
const searchFormRef = ref<FormInstance>() <el-table-column
prop="resource_type"
// :label="t('resourceType')"
const selectData = ref<any[]>([]) min-width="120"
:show-overflow-tooltip="true"
// />
<el-table-column
/** prop="communication_type"
* 获取沟通记录列表 :label="t('communicationType')"
*/ min-width="120"
const loadCommunicationRecordsList = (page: number = 1) => { :show-overflow-tooltip="true"
communicationRecordsTable.loading = true />
communicationRecordsTable.page = page
<el-table-column
getCommunicationRecordsList({ prop="communication_result"
page: communicationRecordsTable.page, :label="t('communicationResult')"
limit: communicationRecordsTable.limit, min-width="120"
...communicationRecordsTable.searchParam :show-overflow-tooltip="true"
}).then(res => { />
communicationRecordsTable.loading = false
communicationRecordsTable.data = res.data.data <el-table-column
communicationRecordsTable.total = res.data.total prop="communication_time"
}).catch(() => { :label="t('communicationTime')"
communicationRecordsTable.loading = false min-width="120"
}) :show-overflow-tooltip="true"
} />
loadCommunicationRecordsList()
<el-table-column
const editCommunicationRecordsDialog: Record<string, any> | null = ref(null) prop="remarks"
:label="t('remarks')"
/** min-width="120"
* 添加沟通记录 :show-overflow-tooltip="true"
*/ />
const addEvent = () => {
editCommunicationRecordsDialog.value.setFormData() <el-table-column
editCommunicationRecordsDialog.value.showDialog = true prop="tag"
} :label="t('tag')"
min-width="120"
/** :show-overflow-tooltip="true"
* 编辑沟通记录 />
* @param data
*/ <el-table-column
const editEvent = (data: any) => { prop="business_id"
editCommunicationRecordsDialog.value.setFormData(data) :label="t('businessId')"
editCommunicationRecordsDialog.value.showDialog = true min-width="120"
} :show-overflow-tooltip="true"
/>
/**
* 删除沟通记录 <el-table-column
*/ prop="created_at"
const deleteEvent = (id: number) => { :label="t('createdAt')"
ElMessageBox.confirm(t('communicationRecordsDeleteTips'), t('warning'), min-width="120"
{ :show-overflow-tooltip="true"
confirmButtonText: t('confirm'), />
cancelButtonText: t('cancel'),
type: 'warning', <el-table-column
} prop="updated_at"
).then(() => { :label="t('updatedAt')"
deleteCommunicationRecords(id).then(() => { min-width="120"
loadCommunicationRecordsList() :show-overflow-tooltip="true"
}).catch(() => { />
})
}) <el-table-column
} :label="t('operation')"
fixed="right"
min-width="120"
>
const resetForm = (formEl: FormInstance | undefined) => { <template #default="{ row }">
if (!formEl) return <el-button type="primary" link @click="editEvent(row)">{{
formEl.resetFields() t('edit')
loadCommunicationRecordsList() }}</el-button>
} <el-button type="primary" link @click="deleteEvent(row.id)">{{
</script> t('delete')
}}</el-button>
<style lang="scss" scoped> </template>
/* 多行超出隐藏 */ </el-table-column>
.multi-hidden { </el-table>
word-break: break-all; <div class="mt-[16px] flex justify-end">
text-overflow: ellipsis; <el-pagination
overflow: hidden; v-model:current-page="communicationRecordsTable.page"
display: -webkit-box; v-model:page-size="communicationRecordsTable.limit"
-webkit-line-clamp: 2; layout="total, sizes, prev, pager, next, jumper"
-webkit-box-orient: vertical; :total="communicationRecordsTable.total"
} @size-change="loadCommunicationRecordsList()"
</style> @current-change="loadCommunicationRecordsList"
/>
</div>
</div>
<edit
ref="editCommunicationRecordsDialog"
@complete="loadCommunicationRecordsList"
/>
</el-card>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref, watch } from 'vue'
import { t } from '@/lang'
import { useDictionary } from '@/app/api/dict'
import {
getCommunicationRecordsList,
deleteCommunicationRecords,
} from '@/app/api/communication_records'
import { img } from '@/utils/common'
import { ElMessageBox, FormInstance } from 'element-plus'
import Edit from '@/app/views/communication_records/components/communication-records-edit.vue'
import { useRoute } from 'vue-router'
const route = useRoute()
const pageName = route.meta.title
let communicationRecordsTable = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {
staff_id: '',
resource_id: '',
resource_type: '',
communication_type: '',
communication_result: '',
communication_time: '',
remarks: '',
tag: '',
business_id: '',
created_at: '',
updated_at: '',
},
})
const searchFormRef = ref<FormInstance>()
//
const selectData = ref<any[]>([])
//
/**
* 获取沟通记录列表
*/
const loadCommunicationRecordsList = (page: number = 1) => {
communicationRecordsTable.loading = true
communicationRecordsTable.page = page
getCommunicationRecordsList({
page: communicationRecordsTable.page,
limit: communicationRecordsTable.limit,
...communicationRecordsTable.searchParam,
})
.then((res) => {
communicationRecordsTable.loading = false
communicationRecordsTable.data = res.data.data
communicationRecordsTable.total = res.data.total
})
.catch(() => {
communicationRecordsTable.loading = false
})
}
loadCommunicationRecordsList()
const editCommunicationRecordsDialog: Record<string, any> | null = ref(null)
/**
* 添加沟通记录
*/
const addEvent = () => {
editCommunicationRecordsDialog.value.setFormData()
editCommunicationRecordsDialog.value.showDialog = true
}
/**
* 编辑沟通记录
* @param data
*/
const editEvent = (data: any) => {
editCommunicationRecordsDialog.value.setFormData(data)
editCommunicationRecordsDialog.value.showDialog = true
}
/**
* 删除沟通记录
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('communicationRecordsDeleteTips'), t('warning'), {
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}).then(() => {
deleteCommunicationRecords(id)
.then(() => {
loadCommunicationRecordsList()
})
.catch(() => {})
})
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadCommunicationRecordsList()
}
</script>
<style lang="scss" scoped>
/* 多行超出隐藏 */
.multi-hidden {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
</style>

565
admin/src/app/views/communication_records/components/communication-records-edit.vue

@ -1,243 +1,322 @@
<template> <template>
<el-dialog v-model="showDialog" :title="formData.id ? t('updateCommunicationRecords') : t('addCommunicationRecords')" width="50%" class="diy-dialog-wrap" :destroy-on-close="true"> <el-dialog
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading"> v-model="showDialog"
<el-form-item :label="t('staffId')" prop="staff_id"> :title="
<el-input v-model="formData.staff_id" clearable :placeholder="t('staffIdPlaceholder')" class="input-width" /> formData.id
</el-form-item> ? t('updateCommunicationRecords')
: t('addCommunicationRecords')
<el-form-item :label="t('resourceId')" prop="resource_id"> "
<el-input v-model="formData.resource_id" clearable :placeholder="t('resourceIdPlaceholder')" class="input-width" /> width="50%"
</el-form-item> class="diy-dialog-wrap"
:destroy-on-close="true"
<el-form-item :label="t('resourceType')" prop="resource_type"> >
<el-input v-model="formData.resource_type" clearable :placeholder="t('resourceTypePlaceholder')" class="input-width" /> <el-form
</el-form-item> :model="formData"
label-width="120px"
<el-form-item :label="t('communicationType')" prop="communication_type"> ref="formRef"
<el-input v-model="formData.communication_type" clearable :placeholder="t('communicationTypePlaceholder')" class="input-width" /> :rules="formRules"
</el-form-item> class="page-form"
v-loading="loading"
<el-form-item :label="t('communicationResult')" prop="communication_result"> >
<el-input v-model="formData.communication_result" clearable :placeholder="t('communicationResultPlaceholder')" class="input-width" /> <el-form-item :label="t('staffId')" prop="staff_id">
</el-form-item> <el-input
v-model="formData.staff_id"
<el-form-item :label="t('communicationTime')" prop="communication_time"> clearable
<el-input v-model="formData.communication_time" clearable :placeholder="t('communicationTimePlaceholder')" class="input-width" /> :placeholder="t('staffIdPlaceholder')"
</el-form-item> class="input-width"
/>
<el-form-item :label="t('remarks')" > </el-form-item>
<el-input v-model="formData.remarks" clearable :placeholder="t('remarksPlaceholder')" class="input-width" />
</el-form-item> <el-form-item :label="t('resourceId')" prop="resource_id">
<el-input
<el-form-item :label="t('tag')" > v-model="formData.resource_id"
<el-input v-model="formData.tag" clearable :placeholder="t('tagPlaceholder')" class="input-width" /> clearable
</el-form-item> :placeholder="t('resourceIdPlaceholder')"
class="input-width"
<el-form-item :label="t('businessId')" > />
<el-input v-model="formData.business_id" clearable :placeholder="t('businessIdPlaceholder')" class="input-width" /> </el-form-item>
</el-form-item>
<el-form-item :label="t('resourceType')" prop="resource_type">
<el-form-item :label="t('createdAt')" > <el-input
<el-input v-model="formData.created_at" clearable :placeholder="t('createdAtPlaceholder')" class="input-width" /> v-model="formData.resource_type"
</el-form-item> clearable
:placeholder="t('resourceTypePlaceholder')"
<el-form-item :label="t('updatedAt')" > class="input-width"
<el-input v-model="formData.updated_at" clearable :placeholder="t('updatedAtPlaceholder')" class="input-width" /> />
</el-form-item> </el-form-item>
</el-form> <el-form-item :label="t('communicationType')" prop="communication_type">
<el-input
<template #footer> v-model="formData.communication_type"
<span class="dialog-footer"> clearable
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button> :placeholder="t('communicationTypePlaceholder')"
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{ class="input-width"
t('confirm') />
}}</el-button> </el-form-item>
</span>
</template> <el-form-item
</el-dialog> :label="t('communicationResult')"
</template> prop="communication_result"
>
<script lang="ts" setup> <el-input
import { ref, reactive, computed, watch } from 'vue' v-model="formData.communication_result"
import { useDictionary } from '@/app/api/dict' clearable
import { t } from '@/lang' :placeholder="t('communicationResultPlaceholder')"
import type { FormInstance } from 'element-plus' class="input-width"
import { addCommunicationRecords, editCommunicationRecords, getCommunicationRecordsInfo } from '@/app/api/communication_records' />
</el-form-item>
let showDialog = ref(false)
const loading = ref(false) <el-form-item :label="t('communicationTime')" prop="communication_time">
<el-input
/** v-model="formData.communication_time"
* 表单数据 clearable
*/ :placeholder="t('communicationTimePlaceholder')"
const initialFormData = { class="input-width"
id: '', />
staff_id: '', </el-form-item>
resource_id: '',
resource_type: '', <el-form-item :label="t('remarks')">
communication_type: '', <el-input
communication_result: '', v-model="formData.remarks"
communication_time: '', clearable
remarks: '', :placeholder="t('remarksPlaceholder')"
tag: '', class="input-width"
business_id: '', />
created_at: '', </el-form-item>
updated_at: '',
} <el-form-item :label="t('tag')">
const formData: Record<string, any> = reactive({ ...initialFormData }) <el-input
v-model="formData.tag"
const formRef = ref<FormInstance>() clearable
:placeholder="t('tagPlaceholder')"
// class="input-width"
const formRules = computed(() => { />
return { </el-form-item>
staff_id: [
{ required: true, message: t('staffIdPlaceholder'), trigger: 'blur' }, <el-form-item :label="t('businessId')">
<el-input
] v-model="formData.business_id"
, clearable
resource_id: [ :placeholder="t('businessIdPlaceholder')"
{ required: true, message: t('resourceIdPlaceholder'), trigger: 'blur' }, class="input-width"
/>
] </el-form-item>
,
resource_type: [ <el-form-item :label="t('createdAt')">
{ required: true, message: t('resourceTypePlaceholder'), trigger: 'blur' }, <el-input
v-model="formData.created_at"
] clearable
, :placeholder="t('createdAtPlaceholder')"
communication_type: [ class="input-width"
{ required: true, message: t('communicationTypePlaceholder'), trigger: 'blur' }, />
</el-form-item>
]
, <el-form-item :label="t('updatedAt')">
communication_result: [ <el-input
{ required: true, message: t('communicationResultPlaceholder'), trigger: 'blur' }, v-model="formData.updated_at"
clearable
] :placeholder="t('updatedAtPlaceholder')"
, class="input-width"
communication_time: [ />
{ required: true, message: t('communicationTimePlaceholder'), trigger: 'blur' }, </el-form-item>
</el-form>
]
, <template #footer>
remarks: [ <span class="dialog-footer">
{ required: true, message: t('remarksPlaceholder'), trigger: 'blur' }, <el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
<el-button
] type="primary"
, :loading="loading"
tag: [ @click="confirm(formRef)"
{ required: true, message: t('tagPlaceholder'), trigger: 'blur' }, >{{ t('confirm') }}</el-button
>
] </span>
, </template>
business_id: [ </el-dialog>
{ required: true, message: t('businessIdPlaceholder'), trigger: 'blur' }, </template>
] <script lang="ts" setup>
, import { ref, reactive, computed, watch } from 'vue'
created_at: [ import { useDictionary } from '@/app/api/dict'
{ required: true, message: t('createdAtPlaceholder'), trigger: 'blur' }, import { t } from '@/lang'
import type { FormInstance } from 'element-plus'
] import {
, addCommunicationRecords,
updated_at: [ editCommunicationRecords,
{ required: true, message: t('updatedAtPlaceholder'), trigger: 'blur' }, getCommunicationRecordsInfo,
} from '@/app/api/communication_records'
]
, let showDialog = ref(false)
} const loading = ref(false)
})
/**
const emit = defineEmits(['complete']) * 表单数据
*/
/** const initialFormData = {
* 确认 id: '',
* @param formEl staff_id: '',
*/ resource_id: '',
const confirm = async (formEl: FormInstance | undefined) => { resource_type: '',
if (loading.value || !formEl) return communication_type: '',
let save = formData.id ? editCommunicationRecords : addCommunicationRecords communication_result: '',
communication_time: '',
await formEl.validate(async (valid) => { remarks: '',
if (valid) { tag: '',
loading.value = true business_id: '',
created_at: '',
let data = formData updated_at: '',
}
save(data).then(res => { const formData: Record<string, any> = reactive({ ...initialFormData })
loading.value = false
showDialog.value = false const formRef = ref<FormInstance>()
emit('complete')
}).catch(err => { //
loading.value = false const formRules = computed(() => {
}) return {
} staff_id: [
}) { required: true, message: t('staffIdPlaceholder'), trigger: 'blur' },
} ],
resource_id: [
// { required: true, message: t('resourceIdPlaceholder'), trigger: 'blur' },
],
resource_type: [
{
const setFormData = async (row: any = null) => { required: true,
Object.assign(formData, initialFormData) message: t('resourceTypePlaceholder'),
loading.value = true trigger: 'blur',
if(row){ },
const data = await (await getCommunicationRecordsInfo(row.id)).data ],
if (data) Object.keys(formData).forEach((key: string) => { communication_type: [
if (data[key] != undefined) formData[key] = data[key] {
}) required: true,
} message: t('communicationTypePlaceholder'),
loading.value = false trigger: 'blur',
} },
],
// communication_result: [
const mobileVerify = (rule: any, value: any, callback: any) => { {
if (value && !/^1[3-9]\d{9}$/.test(value)) { required: true,
callback(new Error(t('generateMobile'))) message: t('communicationResultPlaceholder'),
} else { trigger: 'blur',
callback() },
} ],
} communication_time: [
{
// required: true,
const idCardVerify = (rule: any, value: any, callback: any) => { message: t('communicationTimePlaceholder'),
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) { trigger: 'blur',
callback(new Error(t('generateIdCard'))) },
} else { ],
callback() remarks: [
} { required: true, message: t('remarksPlaceholder'), trigger: 'blur' },
} ],
tag: [{ required: true, message: t('tagPlaceholder'), trigger: 'blur' }],
// business_id: [
const emailVerify = (rule: any, value: any, callback: any) => { { required: true, message: t('businessIdPlaceholder'), trigger: 'blur' },
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) { ],
callback(new Error(t('generateEmail'))) created_at: [
} else { { required: true, message: t('createdAtPlaceholder'), trigger: 'blur' },
callback() ],
} updated_at: [
} { required: true, message: t('updatedAtPlaceholder'), trigger: 'blur' },
],
// }
const numberVerify = (rule: any, value: any, callback: any) => { })
if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber'))) const emit = defineEmits(['complete'])
} else {
callback() /**
} * 确认
} * @param formEl
*/
defineExpose({ const confirm = async (formEl: FormInstance | undefined) => {
showDialog, if (loading.value || !formEl) return
setFormData let save = formData.id ? editCommunicationRecords : addCommunicationRecords
})
</script> await formEl.validate(async (valid) => {
if (valid) {
<style lang="scss" scoped></style> loading.value = true
<style lang="scss">
.diy-dialog-wrap .el-form-item__label{ let data = formData
height: auto !important;
} save(data)
</style> .then((res) => {
loading.value = false
showDialog.value = false
emit('complete')
})
.catch((err) => {
loading.value = false
})
}
})
}
//
const setFormData = async (row: any = null) => {
Object.assign(formData, initialFormData)
loading.value = true
if (row) {
const data = await (await getCommunicationRecordsInfo(row.id)).data
if (data)
Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key]
})
}
loading.value = false
}
//
const mobileVerify = (rule: any, value: any, callback: any) => {
if (value && !/^1[3-9]\d{9}$/.test(value)) {
callback(new Error(t('generateMobile')))
} else {
callback()
}
}
//
const idCardVerify = (rule: any, value: any, callback: any) => {
if (
value &&
!/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
value
)
) {
callback(new Error(t('generateIdCard')))
} else {
callback()
}
}
//
const emailVerify = (rule: any, value: any, callback: any) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail')))
} else {
callback()
}
}
//
const numberVerify = (rule: any, value: any, callback: any) => {
if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber')))
} else {
callback()
}
}
defineExpose({
showDialog,
setFormData,
})
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.diy-dialog-wrap .el-form-item__label {
height: auto !important;
}
</style>

487
admin/src/app/views/contract/components/contract-edit.vue

@ -1,213 +1,274 @@
<template> <template>
<el-dialog v-model="showDialog" :title="formData.id ? t('updateContract') : t('addContract')" width="50%" class="diy-dialog-wrap" :destroy-on-close="true"> <el-dialog
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading"> v-model="showDialog"
<el-form-item :label="t('contractName')" prop="contract_name"> :title="formData.id ? t('updateContract') : t('addContract')"
<el-input v-model="formData.contract_name" clearable :placeholder="t('contractNamePlaceholder')" class="input-width" /> width="50%"
</el-form-item> class="diy-dialog-wrap"
:destroy-on-close="true"
<el-form-item :label="t('contractTemplate')" prop="contract_template"> >
<el-input v-model="formData.contract_template" clearable :placeholder="t('contractTemplatePlaceholder')" class="input-width" /> <el-form
</el-form-item> :model="formData"
label-width="120px"
<el-form-item :label="t('contractStatus')" prop="contract_status"> ref="formRef"
<el-input v-model="formData.contract_status" clearable :placeholder="t('contractStatusPlaceholder')" class="input-width" /> :rules="formRules"
</el-form-item> class="page-form"
v-loading="loading"
<el-form-item :label="t('contractType')" prop="contract_type"> >
<el-input v-model="formData.contract_type" clearable :placeholder="t('contractTypePlaceholder')" class="input-width" /> <el-form-item :label="t('contractName')" prop="contract_name">
</el-form-item> <el-input
v-model="formData.contract_name"
<el-form-item :label="t('remarks')" > clearable
<el-input v-model="formData.remarks" clearable :placeholder="t('remarksPlaceholder')" class="input-width" /> :placeholder="t('contractNamePlaceholder')"
</el-form-item> class="input-width"
/>
<el-form-item :label="t('createdAt')" > </el-form-item>
<el-input v-model="formData.created_at" clearable :placeholder="t('createdAtPlaceholder')" class="input-width" />
</el-form-item> <el-form-item :label="t('contractTemplate')" prop="contract_template">
<el-input
<el-form-item :label="t('updatedAt')" > v-model="formData.contract_template"
<el-input v-model="formData.updated_at" clearable :placeholder="t('updatedAtPlaceholder')" class="input-width" /> clearable
</el-form-item> :placeholder="t('contractTemplatePlaceholder')"
class="input-width"
<el-form-item :label="t('deletedAt')" > />
<el-input v-model="formData.deleted_at" clearable :placeholder="t('deletedAtPlaceholder')" class="input-width" /> </el-form-item>
</el-form-item>
<el-form-item :label="t('contractStatus')" prop="contract_status">
</el-form> <el-input
v-model="formData.contract_status"
<template #footer> clearable
<span class="dialog-footer"> :placeholder="t('contractStatusPlaceholder')"
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button> class="input-width"
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{ />
t('confirm') </el-form-item>
}}</el-button>
</span> <el-form-item :label="t('contractType')" prop="contract_type">
</template> <el-input
</el-dialog> v-model="formData.contract_type"
</template> clearable
:placeholder="t('contractTypePlaceholder')"
<script lang="ts" setup> class="input-width"
import { ref, reactive, computed, watch } from 'vue' />
import { useDictionary } from '@/app/api/dict' </el-form-item>
import { t } from '@/lang'
import type { FormInstance } from 'element-plus' <el-form-item :label="t('remarks')">
import { addContract, editContract, getContractInfo } from '@/app/api/contract' <el-input
v-model="formData.remarks"
let showDialog = ref(false) clearable
const loading = ref(false) :placeholder="t('remarksPlaceholder')"
class="input-width"
/** />
* 表单数据 </el-form-item>
*/
const initialFormData = { <el-form-item :label="t('createdAt')">
id: '', <el-input
contract_name: '', v-model="formData.created_at"
contract_template: '', clearable
contract_status: '', :placeholder="t('createdAtPlaceholder')"
contract_type: '', class="input-width"
remarks: '', />
created_at: '', </el-form-item>
updated_at: '',
deleted_at: '', <el-form-item :label="t('updatedAt')">
} <el-input
const formData: Record<string, any> = reactive({ ...initialFormData }) v-model="formData.updated_at"
clearable
const formRef = ref<FormInstance>() :placeholder="t('updatedAtPlaceholder')"
class="input-width"
// />
const formRules = computed(() => { </el-form-item>
return {
contract_name: [ <el-form-item :label="t('deletedAt')">
{ required: true, message: t('contractNamePlaceholder'), trigger: 'blur' }, <el-input
v-model="formData.deleted_at"
] clearable
, :placeholder="t('deletedAtPlaceholder')"
contract_template: [ class="input-width"
{ required: true, message: t('contractTemplatePlaceholder'), trigger: 'blur' }, />
</el-form-item>
] </el-form>
,
contract_status: [ <template #footer>
{ required: true, message: t('contractStatusPlaceholder'), trigger: 'blur' }, <span class="dialog-footer">
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
] <el-button
, type="primary"
contract_type: [ :loading="loading"
{ required: true, message: t('contractTypePlaceholder'), trigger: 'blur' }, @click="confirm(formRef)"
>{{ t('confirm') }}</el-button
] >
, </span>
remarks: [ </template>
{ required: true, message: t('remarksPlaceholder'), trigger: 'blur' }, </el-dialog>
</template>
]
, <script lang="ts" setup>
created_at: [ import { ref, reactive, computed, watch } from 'vue'
{ required: true, message: t('createdAtPlaceholder'), trigger: 'blur' }, import { useDictionary } from '@/app/api/dict'
import { t } from '@/lang'
] import type { FormInstance } from 'element-plus'
, import { addContract, editContract, getContractInfo } from '@/app/api/contract'
updated_at: [
{ required: true, message: t('updatedAtPlaceholder'), trigger: 'blur' }, let showDialog = ref(false)
const loading = ref(false)
]
, /**
deleted_at: [ * 表单数据
{ required: true, message: t('deletedAtPlaceholder'), trigger: 'blur' }, */
const initialFormData = {
] id: '',
, contract_name: '',
} contract_template: '',
}) contract_status: '',
contract_type: '',
const emit = defineEmits(['complete']) remarks: '',
created_at: '',
/** updated_at: '',
* 确认 deleted_at: '',
* @param formEl }
*/ const formData: Record<string, any> = reactive({ ...initialFormData })
const confirm = async (formEl: FormInstance | undefined) => {
if (loading.value || !formEl) return const formRef = ref<FormInstance>()
let save = formData.id ? editContract : addContract
//
await formEl.validate(async (valid) => { const formRules = computed(() => {
if (valid) { return {
loading.value = true contract_name: [
{
let data = formData required: true,
message: t('contractNamePlaceholder'),
save(data).then(res => { trigger: 'blur',
loading.value = false },
showDialog.value = false ],
emit('complete') contract_template: [
}).catch(err => { {
loading.value = false required: true,
}) message: t('contractTemplatePlaceholder'),
} trigger: 'blur',
}) },
} ],
contract_status: [
// {
required: true,
message: t('contractStatusPlaceholder'),
trigger: 'blur',
const setFormData = async (row: any = null) => { },
Object.assign(formData, initialFormData) ],
loading.value = true contract_type: [
if(row){ {
const data = await (await getContractInfo(row.id)).data required: true,
if (data) Object.keys(formData).forEach((key: string) => { message: t('contractTypePlaceholder'),
if (data[key] != undefined) formData[key] = data[key] trigger: 'blur',
}) },
} ],
loading.value = false remarks: [
} { required: true, message: t('remarksPlaceholder'), trigger: 'blur' },
],
// created_at: [
const mobileVerify = (rule: any, value: any, callback: any) => { { required: true, message: t('createdAtPlaceholder'), trigger: 'blur' },
if (value && !/^1[3-9]\d{9}$/.test(value)) { ],
callback(new Error(t('generateMobile'))) updated_at: [
} else { { required: true, message: t('updatedAtPlaceholder'), trigger: 'blur' },
callback() ],
} deleted_at: [
} { required: true, message: t('deletedAtPlaceholder'), trigger: 'blur' },
],
// }
const idCardVerify = (rule: any, value: any, callback: any) => { })
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) {
callback(new Error(t('generateIdCard'))) const emit = defineEmits(['complete'])
} else {
callback() /**
} * 确认
} * @param formEl
*/
// const confirm = async (formEl: FormInstance | undefined) => {
const emailVerify = (rule: any, value: any, callback: any) => { if (loading.value || !formEl) return
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) { let save = formData.id ? editContract : addContract
callback(new Error(t('generateEmail')))
} else { await formEl.validate(async (valid) => {
callback() if (valid) {
} loading.value = true
}
let data = formData
//
const numberVerify = (rule: any, value: any, callback: any) => { save(data)
if (!Number.isInteger(value)) { .then((res) => {
callback(new Error(t('generateNumber'))) loading.value = false
} else { showDialog.value = false
callback() emit('complete')
} })
} .catch((err) => {
loading.value = false
defineExpose({ })
showDialog, }
setFormData })
}) }
</script>
//
<style lang="scss" scoped></style>
<style lang="scss"> const setFormData = async (row: any = null) => {
.diy-dialog-wrap .el-form-item__label{ Object.assign(formData, initialFormData)
height: auto !important; loading.value = true
} if (row) {
</style> const data = await (await getContractInfo(row.id)).data
if (data)
Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key]
})
}
loading.value = false
}
//
const mobileVerify = (rule: any, value: any, callback: any) => {
if (value && !/^1[3-9]\d{9}$/.test(value)) {
callback(new Error(t('generateMobile')))
} else {
callback()
}
}
//
const idCardVerify = (rule: any, value: any, callback: any) => {
if (
value &&
!/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
value
)
) {
callback(new Error(t('generateIdCard')))
} else {
callback()
}
}
//
const emailVerify = (rule: any, value: any, callback: any) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail')))
} else {
callback()
}
}
//
const numberVerify = (rule: any, value: any, callback: any) => {
if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber')))
} else {
callback()
}
}
defineExpose({
showDialog,
setFormData,
})
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.diy-dialog-wrap .el-form-item__label {
height: auto !important;
}
</style>

491
admin/src/app/views/contract/contract.vue

@ -1,201 +1,290 @@
<template> <template>
<div class="main-container"> <div class="main-container">
<el-card class="box-card !border-none" shadow="never"> <el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<div class="flex justify-between items-center"> <span class="text-lg">{{ pageName }}</span>
<span class="text-lg">{{pageName}}</span> <el-button type="primary" @click="addEvent">
<el-button type="primary" @click="addEvent"> {{ t('addContract') }}
{{ t('addContract') }} </el-button>
</el-button> </div>
</div>
<el-card
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> class="box-card !border-none my-[10px] table-search-wrap"
<el-form :inline="true" :model="contractTable.searchParam" ref="searchFormRef"> shadow="never"
<el-form-item :label="t('contractName')" prop="contract_name"> >
<el-input v-model="contractTable.searchParam.contract_name" :placeholder="t('contractNamePlaceholder')" /> <el-form
</el-form-item> :inline="true"
<el-form-item :label="t('contractTemplate')" prop="contract_template"> :model="contractTable.searchParam"
<el-input v-model="contractTable.searchParam.contract_template" :placeholder="t('contractTemplatePlaceholder')" /> ref="searchFormRef"
</el-form-item> >
<el-form-item :label="t('contractStatus')" prop="contract_status"> <el-form-item :label="t('contractName')" prop="contract_name">
<el-input v-model="contractTable.searchParam.contract_status" :placeholder="t('contractStatusPlaceholder')" /> <el-input
</el-form-item> v-model="contractTable.searchParam.contract_name"
<el-form-item :label="t('contractType')" prop="contract_type"> :placeholder="t('contractNamePlaceholder')"
<el-input v-model="contractTable.searchParam.contract_type" :placeholder="t('contractTypePlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('remarks')" prop="remarks"> <el-form-item :label="t('contractTemplate')" prop="contract_template">
<el-input v-model="contractTable.searchParam.remarks" :placeholder="t('remarksPlaceholder')" /> <el-input
</el-form-item> v-model="contractTable.searchParam.contract_template"
<el-form-item :label="t('createdAt')" prop="created_at"> :placeholder="t('contractTemplatePlaceholder')"
<el-input v-model="contractTable.searchParam.created_at" :placeholder="t('createdAtPlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('updatedAt')" prop="updated_at"> <el-form-item :label="t('contractStatus')" prop="contract_status">
<el-input v-model="contractTable.searchParam.updated_at" :placeholder="t('updatedAtPlaceholder')" /> <el-input
</el-form-item> v-model="contractTable.searchParam.contract_status"
<el-form-item :label="t('deletedAt')" prop="deleted_at"> :placeholder="t('contractStatusPlaceholder')"
<el-input v-model="contractTable.searchParam.deleted_at" :placeholder="t('deletedAtPlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item :label="t('contractType')" prop="contract_type">
<el-button type="primary" @click="loadContractList()">{{ t('search') }}</el-button> <el-input
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> v-model="contractTable.searchParam.contract_type"
</el-form-item> :placeholder="t('contractTypePlaceholder')"
</el-form> />
</el-card> </el-form-item>
<el-form-item :label="t('remarks')" prop="remarks">
<div class="mt-[10px]"> <el-input
<el-table :data="contractTable.data" size="large" v-loading="contractTable.loading"> v-model="contractTable.searchParam.remarks"
<template #empty> :placeholder="t('remarksPlaceholder')"
<span>{{ !contractTable.loading ? t('emptyData') : '' }}</span> />
</template> </el-form-item>
<el-table-column prop="contract_name" :label="t('contractName')" min-width="120" :show-overflow-tooltip="true"/> <el-form-item :label="t('createdAt')" prop="created_at">
<el-input
<el-table-column prop="contract_template" :label="t('contractTemplate')" min-width="120" :show-overflow-tooltip="true"/> v-model="contractTable.searchParam.created_at"
:placeholder="t('createdAtPlaceholder')"
<el-table-column prop="contract_status" :label="t('contractStatus')" min-width="120" :show-overflow-tooltip="true"/> />
</el-form-item>
<el-table-column prop="contract_type" :label="t('contractType')" min-width="120" :show-overflow-tooltip="true"/> <el-form-item :label="t('updatedAt')" prop="updated_at">
<el-input
<el-table-column prop="remarks" :label="t('remarks')" min-width="120" :show-overflow-tooltip="true"/> v-model="contractTable.searchParam.updated_at"
:placeholder="t('updatedAtPlaceholder')"
<el-table-column prop="created_at" :label="t('createdAt')" min-width="120" :show-overflow-tooltip="true"/> />
</el-form-item>
<el-table-column prop="updated_at" :label="t('updatedAt')" min-width="120" :show-overflow-tooltip="true"/> <el-form-item :label="t('deletedAt')" prop="deleted_at">
<el-input
<el-table-column prop="deleted_at" :label="t('deletedAt')" min-width="120" :show-overflow-tooltip="true"/> v-model="contractTable.searchParam.deleted_at"
:placeholder="t('deletedAtPlaceholder')"
<el-table-column :label="t('operation')" fixed="right" min-width="120"> />
<template #default="{ row }"> </el-form-item>
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button> <el-form-item>
</template> <el-button type="primary" @click="loadContractList()">{{
</el-table-column> t('search')
}}</el-button>
</el-table> <el-button @click="resetForm(searchFormRef)">{{
<div class="mt-[16px] flex justify-end"> t('reset')
<el-pagination v-model:current-page="contractTable.page" v-model:page-size="contractTable.limit" }}</el-button>
layout="total, sizes, prev, pager, next, jumper" :total="contractTable.total" </el-form-item>
@size-change="loadContractList()" @current-change="loadContractList" /> </el-form>
</div> </el-card>
</div>
<div class="mt-[10px]">
<edit ref="editContractDialog" @complete="loadContractList" /> <el-table
</el-card> :data="contractTable.data"
</div> size="large"
</template> v-loading="contractTable.loading"
>
<script lang="ts" setup> <template #empty>
import { reactive, ref, watch } from 'vue' <span>{{ !contractTable.loading ? t('emptyData') : '' }}</span>
import { t } from '@/lang' </template>
import { useDictionary } from '@/app/api/dict' <el-table-column
import { getContractList, deleteContract } from '@/app/api/contract' prop="contract_name"
import { img } from '@/utils/common' :label="t('contractName')"
import { ElMessageBox,FormInstance } from 'element-plus' min-width="120"
import Edit from '@/app/views/contract/components/contract-edit.vue' :show-overflow-tooltip="true"
import { useRoute } from 'vue-router' />
const route = useRoute()
const pageName = route.meta.title; <el-table-column
prop="contract_template"
let contractTable = reactive({ :label="t('contractTemplate')"
page: 1, min-width="120"
limit: 10, :show-overflow-tooltip="true"
total: 0, />
loading: true,
data: [], <el-table-column
searchParam:{ prop="contract_status"
"contract_name":"", :label="t('contractStatus')"
"contract_template":"", min-width="120"
"contract_status":"", :show-overflow-tooltip="true"
"contract_type":"", />
"remarks":"",
"created_at":"", <el-table-column
"updated_at":"", prop="contract_type"
"deleted_at":"" :label="t('contractType')"
} min-width="120"
}) :show-overflow-tooltip="true"
/>
const searchFormRef = ref<FormInstance>()
<el-table-column
// prop="remarks"
const selectData = ref<any[]>([]) :label="t('remarks')"
min-width="120"
// :show-overflow-tooltip="true"
/>
/** <el-table-column
* 获取合同列表 prop="created_at"
*/ :label="t('createdAt')"
const loadContractList = (page: number = 1) => { min-width="120"
contractTable.loading = true :show-overflow-tooltip="true"
contractTable.page = page />
getContractList({ <el-table-column
page: contractTable.page, prop="updated_at"
limit: contractTable.limit, :label="t('updatedAt')"
...contractTable.searchParam min-width="120"
}).then(res => { :show-overflow-tooltip="true"
contractTable.loading = false />
contractTable.data = res.data.data
contractTable.total = res.data.total <el-table-column
}).catch(() => { prop="deleted_at"
contractTable.loading = false :label="t('deletedAt')"
}) min-width="120"
} :show-overflow-tooltip="true"
loadContractList() />
const editContractDialog: Record<string, any> | null = ref(null) <el-table-column
:label="t('operation')"
/** fixed="right"
* 添加合同 min-width="120"
*/ >
const addEvent = () => { <template #default="{ row }">
editContractDialog.value.setFormData() <el-button type="primary" link @click="editEvent(row)">{{
editContractDialog.value.showDialog = true t('edit')
} }}</el-button>
<el-button type="primary" link @click="deleteEvent(row.id)">{{
/** t('delete')
* 编辑合同 }}</el-button>
* @param data </template>
*/ </el-table-column>
const editEvent = (data: any) => { </el-table>
editContractDialog.value.setFormData(data) <div class="mt-[16px] flex justify-end">
editContractDialog.value.showDialog = true <el-pagination
} v-model:current-page="contractTable.page"
v-model:page-size="contractTable.limit"
/** layout="total, sizes, prev, pager, next, jumper"
* 删除合同 :total="contractTable.total"
*/ @size-change="loadContractList()"
const deleteEvent = (id: number) => { @current-change="loadContractList"
ElMessageBox.confirm(t('contractDeleteTips'), t('warning'), />
{ </div>
confirmButtonText: t('confirm'), </div>
cancelButtonText: t('cancel'),
type: 'warning', <edit ref="editContractDialog" @complete="loadContractList" />
} </el-card>
).then(() => { </div>
deleteContract(id).then(() => { </template>
loadContractList()
}).catch(() => { <script lang="ts" setup>
}) import { reactive, ref, watch } from 'vue'
}) import { t } from '@/lang'
} import { useDictionary } from '@/app/api/dict'
import { getContractList, deleteContract } from '@/app/api/contract'
import { img } from '@/utils/common'
import { ElMessageBox, FormInstance } from 'element-plus'
const resetForm = (formEl: FormInstance | undefined) => { import Edit from '@/app/views/contract/components/contract-edit.vue'
if (!formEl) return import { useRoute } from 'vue-router'
formEl.resetFields() const route = useRoute()
loadContractList() const pageName = route.meta.title
}
</script> let contractTable = reactive({
page: 1,
<style lang="scss" scoped> limit: 10,
/* 多行超出隐藏 */ total: 0,
.multi-hidden { loading: true,
word-break: break-all; data: [],
text-overflow: ellipsis; searchParam: {
overflow: hidden; contract_name: '',
display: -webkit-box; contract_template: '',
-webkit-line-clamp: 2; contract_status: '',
-webkit-box-orient: vertical; contract_type: '',
} remarks: '',
</style> created_at: '',
updated_at: '',
deleted_at: '',
},
})
const searchFormRef = ref<FormInstance>()
//
const selectData = ref<any[]>([])
//
/**
* 获取合同列表
*/
const loadContractList = (page: number = 1) => {
contractTable.loading = true
contractTable.page = page
getContractList({
page: contractTable.page,
limit: contractTable.limit,
...contractTable.searchParam,
})
.then((res) => {
contractTable.loading = false
contractTable.data = res.data.data
contractTable.total = res.data.total
})
.catch(() => {
contractTable.loading = false
})
}
loadContractList()
const editContractDialog: Record<string, any> | null = ref(null)
/**
* 添加合同
*/
const addEvent = () => {
editContractDialog.value.setFormData()
editContractDialog.value.showDialog = true
}
/**
* 编辑合同
* @param data
*/
const editEvent = (data: any) => {
editContractDialog.value.setFormData(data)
editContractDialog.value.showDialog = true
}
/**
* 删除合同
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('contractDeleteTips'), t('warning'), {
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}).then(() => {
deleteContract(id)
.then(() => {
loadContractList()
})
.catch(() => {})
})
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadContractList()
}
</script>
<style lang="scss" scoped>
/* 多行超出隐藏 */
.multi-hidden {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
</style>

513
admin/src/app/views/course/components/course-edit.vue

@ -1,223 +1,290 @@
<template> <template>
<el-dialog v-model="showDialog" :title="formData.id ? t('updateCourse') : t('addCourse')" width="50%" class="diy-dialog-wrap" :destroy-on-close="true"> <el-dialog
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading"> v-model="showDialog"
<el-form-item :label="t('courseName')" prop="course_name"> :title="formData.id ? t('updateCourse') : t('addCourse')"
<el-input v-model="formData.course_name" clearable :placeholder="t('courseNamePlaceholder')" class="input-width" /> width="50%"
</el-form-item> class="diy-dialog-wrap"
:destroy-on-close="true"
<el-form-item :label="t('courseType')" prop="course_type"> >
<el-input v-model="formData.course_type" clearable :placeholder="t('courseTypePlaceholder')" class="input-width" /> <el-form
</el-form-item> :model="formData"
label-width="120px"
<el-form-item :label="t('duration')" prop="duration"> ref="formRef"
<el-input v-model="formData.duration" clearable :placeholder="t('durationPlaceholder')" class="input-width" /> :rules="formRules"
</el-form-item> class="page-form"
v-loading="loading"
<el-form-item :label="t('sessionCount')" prop="session_count"> >
<el-input v-model="formData.session_count" clearable :placeholder="t('sessionCountPlaceholder')" class="input-width" /> <el-form-item :label="t('courseName')" prop="course_name">
</el-form-item> <el-input
v-model="formData.course_name"
<el-form-item :label="t('singleSessionCount')" prop="single_session_count"> clearable
<el-input v-model="formData.single_session_count" clearable :placeholder="t('singleSessionCountPlaceholder')" class="input-width" /> :placeholder="t('courseNamePlaceholder')"
</el-form-item> class="input-width"
/>
<el-form-item :label="t('price')" prop="price"> </el-form-item>
<el-input v-model="formData.price" clearable :placeholder="t('pricePlaceholder')" class="input-width" />
</el-form-item> <el-form-item :label="t('courseType')" prop="course_type">
<el-input
<el-form-item :label="t('internalReminder')" prop="internal_reminder"> v-model="formData.course_type"
<el-input v-model="formData.internal_reminder" clearable :placeholder="t('internalReminderPlaceholder')" class="input-width" /> clearable
</el-form-item> :placeholder="t('courseTypePlaceholder')"
class="input-width"
<el-form-item :label="t('customerReminder')" prop="customer_reminder"> />
<el-input v-model="formData.customer_reminder" clearable :placeholder="t('customerReminderPlaceholder')" class="input-width" /> </el-form-item>
</el-form-item>
<el-form-item :label="t('duration')" prop="duration">
<el-form-item :label="t('remarks')" > <el-input
<el-input v-model="formData.remarks" clearable :placeholder="t('remarksPlaceholder')" class="input-width" /> v-model="formData.duration"
</el-form-item> clearable
:placeholder="t('durationPlaceholder')"
</el-form> class="input-width"
/>
<template #footer> </el-form-item>
<span class="dialog-footer">
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button> <el-form-item :label="t('sessionCount')" prop="session_count">
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{ <el-input
t('confirm') v-model="formData.session_count"
}}</el-button> clearable
</span> :placeholder="t('sessionCountPlaceholder')"
</template> class="input-width"
</el-dialog> />
</template> </el-form-item>
<script lang="ts" setup> <el-form-item
import { ref, reactive, computed, watch } from 'vue' :label="t('singleSessionCount')"
import { useDictionary } from '@/app/api/dict' prop="single_session_count"
import { t } from '@/lang' >
import type { FormInstance } from 'element-plus' <el-input
import { addCourse, editCourse, getCourseInfo } from '@/app/api/course' v-model="formData.single_session_count"
clearable
let showDialog = ref(false) :placeholder="t('singleSessionCountPlaceholder')"
const loading = ref(false) class="input-width"
/>
/** </el-form-item>
* 表单数据
*/ <el-form-item :label="t('price')" prop="price">
const initialFormData = { <el-input
id: '', v-model="formData.price"
course_name: '', clearable
course_type: '', :placeholder="t('pricePlaceholder')"
duration: '', class="input-width"
session_count: '', />
single_session_count: '', </el-form-item>
price: '',
internal_reminder: '', <el-form-item :label="t('internalReminder')" prop="internal_reminder">
customer_reminder: '', <el-input
remarks: '', v-model="formData.internal_reminder"
} clearable
const formData: Record<string, any> = reactive({ ...initialFormData }) :placeholder="t('internalReminderPlaceholder')"
class="input-width"
const formRef = ref<FormInstance>() />
</el-form-item>
//
const formRules = computed(() => { <el-form-item :label="t('customerReminder')" prop="customer_reminder">
return { <el-input
course_name: [ v-model="formData.customer_reminder"
{ required: true, message: t('courseNamePlaceholder'), trigger: 'blur' }, clearable
:placeholder="t('customerReminderPlaceholder')"
] class="input-width"
, />
course_type: [ </el-form-item>
{ required: true, message: t('courseTypePlaceholder'), trigger: 'blur' },
<el-form-item :label="t('remarks')">
] <el-input
, v-model="formData.remarks"
duration: [ clearable
{ required: true, message: t('durationPlaceholder'), trigger: 'blur' }, :placeholder="t('remarksPlaceholder')"
class="input-width"
] />
, </el-form-item>
session_count: [ </el-form>
{ required: true, message: t('sessionCountPlaceholder'), trigger: 'blur' },
<template #footer>
] <span class="dialog-footer">
, <el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
single_session_count: [ <el-button
{ required: true, message: t('singleSessionCountPlaceholder'), trigger: 'blur' }, type="primary"
:loading="loading"
] @click="confirm(formRef)"
, >{{ t('confirm') }}</el-button
price: [ >
{ required: true, message: t('pricePlaceholder'), trigger: 'blur' }, </span>
</template>
] </el-dialog>
, </template>
internal_reminder: [
{ required: true, message: t('internalReminderPlaceholder'), trigger: 'blur' }, <script lang="ts" setup>
import { ref, reactive, computed, watch } from 'vue'
] import { useDictionary } from '@/app/api/dict'
, import { t } from '@/lang'
customer_reminder: [ import type { FormInstance } from 'element-plus'
{ required: true, message: t('customerReminderPlaceholder'), trigger: 'blur' }, import { addCourse, editCourse, getCourseInfo } from '@/app/api/course'
] let showDialog = ref(false)
, const loading = ref(false)
remarks: [
{ required: true, message: t('remarksPlaceholder'), trigger: 'blur' }, /**
* 表单数据
] */
, const initialFormData = {
} id: '',
}) course_name: '',
course_type: '',
const emit = defineEmits(['complete']) duration: '',
session_count: '',
/** single_session_count: '',
* 确认 price: '',
* @param formEl internal_reminder: '',
*/ customer_reminder: '',
const confirm = async (formEl: FormInstance | undefined) => { remarks: '',
if (loading.value || !formEl) return }
let save = formData.id ? editCourse : addCourse const formData: Record<string, any> = reactive({ ...initialFormData })
await formEl.validate(async (valid) => { const formRef = ref<FormInstance>()
if (valid) {
loading.value = true //
const formRules = computed(() => {
let data = formData return {
course_name: [
save(data).then(res => { { required: true, message: t('courseNamePlaceholder'), trigger: 'blur' },
loading.value = false ],
showDialog.value = false course_type: [
emit('complete') { required: true, message: t('courseTypePlaceholder'), trigger: 'blur' },
}).catch(err => { ],
loading.value = false duration: [
}) { required: true, message: t('durationPlaceholder'), trigger: 'blur' },
} ],
}) session_count: [
} {
required: true,
// message: t('sessionCountPlaceholder'),
trigger: 'blur',
},
],
const setFormData = async (row: any = null) => { single_session_count: [
Object.assign(formData, initialFormData) {
loading.value = true required: true,
if(row){ message: t('singleSessionCountPlaceholder'),
const data = await (await getCourseInfo(row.id)).data trigger: 'blur',
if (data) Object.keys(formData).forEach((key: string) => { },
if (data[key] != undefined) formData[key] = data[key] ],
}) price: [
} { required: true, message: t('pricePlaceholder'), trigger: 'blur' },
loading.value = false ],
} internal_reminder: [
{
// required: true,
const mobileVerify = (rule: any, value: any, callback: any) => { message: t('internalReminderPlaceholder'),
if (value && !/^1[3-9]\d{9}$/.test(value)) { trigger: 'blur',
callback(new Error(t('generateMobile'))) },
} else { ],
callback() customer_reminder: [
} {
} required: true,
message: t('customerReminderPlaceholder'),
// trigger: 'blur',
const idCardVerify = (rule: any, value: any, callback: any) => { },
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) { ],
callback(new Error(t('generateIdCard'))) remarks: [
} else { { required: true, message: t('remarksPlaceholder'), trigger: 'blur' },
callback() ],
} }
} })
// const emit = defineEmits(['complete'])
const emailVerify = (rule: any, value: any, callback: any) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) { /**
callback(new Error(t('generateEmail'))) * 确认
} else { * @param formEl
callback() */
} const confirm = async (formEl: FormInstance | undefined) => {
} if (loading.value || !formEl) return
let save = formData.id ? editCourse : addCourse
//
const numberVerify = (rule: any, value: any, callback: any) => { await formEl.validate(async (valid) => {
if (!Number.isInteger(value)) { if (valid) {
callback(new Error(t('generateNumber'))) loading.value = true
} else {
callback() let data = formData
}
} save(data)
.then((res) => {
defineExpose({ loading.value = false
showDialog, showDialog.value = false
setFormData emit('complete')
}) })
</script> .catch((err) => {
loading.value = false
<style lang="scss" scoped></style> })
<style lang="scss"> }
.diy-dialog-wrap .el-form-item__label{ })
height: auto !important; }
}
</style> //
const setFormData = async (row: any = null) => {
Object.assign(formData, initialFormData)
loading.value = true
if (row) {
const data = await (await getCourseInfo(row.id)).data
if (data)
Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key]
})
}
loading.value = false
}
//
const mobileVerify = (rule: any, value: any, callback: any) => {
if (value && !/^1[3-9]\d{9}$/.test(value)) {
callback(new Error(t('generateMobile')))
} else {
callback()
}
}
//
const idCardVerify = (rule: any, value: any, callback: any) => {
if (
value &&
!/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
value
)
) {
callback(new Error(t('generateIdCard')))
} else {
callback()
}
}
//
const emailVerify = (rule: any, value: any, callback: any) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail')))
} else {
callback()
}
}
//
const numberVerify = (rule: any, value: any, callback: any) => {
if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber')))
} else {
callback()
}
}
defineExpose({
showDialog,
setFormData,
})
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.diy-dialog-wrap .el-form-item__label {
height: auto !important;
}
</style>

514
admin/src/app/views/course/course.vue

@ -1,207 +1,307 @@
<template> <template>
<div class="main-container"> <div class="main-container">
<el-card class="box-card !border-none" shadow="never"> <el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<div class="flex justify-between items-center"> <span class="text-lg">{{ pageName }}</span>
<span class="text-lg">{{pageName}}</span> <el-button type="primary" @click="addEvent">
<el-button type="primary" @click="addEvent"> {{ t('addCourse') }}
{{ t('addCourse') }} </el-button>
</el-button> </div>
</div>
<el-card
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> class="box-card !border-none my-[10px] table-search-wrap"
<el-form :inline="true" :model="courseTable.searchParam" ref="searchFormRef"> shadow="never"
<el-form-item :label="t('courseName')" prop="course_name"> >
<el-input v-model="courseTable.searchParam.course_name" :placeholder="t('courseNamePlaceholder')" /> <el-form
</el-form-item> :inline="true"
<el-form-item :label="t('courseType')" prop="course_type"> :model="courseTable.searchParam"
<el-input v-model="courseTable.searchParam.course_type" :placeholder="t('courseTypePlaceholder')" /> ref="searchFormRef"
</el-form-item> >
<el-form-item :label="t('duration')" prop="duration"> <el-form-item :label="t('courseName')" prop="course_name">
<el-input v-model="courseTable.searchParam.duration" :placeholder="t('durationPlaceholder')" /> <el-input
</el-form-item> v-model="courseTable.searchParam.course_name"
<el-form-item :label="t('sessionCount')" prop="session_count"> :placeholder="t('courseNamePlaceholder')"
<el-input v-model="courseTable.searchParam.session_count" :placeholder="t('sessionCountPlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('singleSessionCount')" prop="single_session_count"> <el-form-item :label="t('courseType')" prop="course_type">
<el-input v-model="courseTable.searchParam.single_session_count" :placeholder="t('singleSessionCountPlaceholder')" /> <el-input
</el-form-item> v-model="courseTable.searchParam.course_type"
<el-form-item :label="t('price')" prop="price"> :placeholder="t('courseTypePlaceholder')"
<el-input v-model="courseTable.searchParam.price" :placeholder="t('pricePlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('internalReminder')" prop="internal_reminder"> <el-form-item :label="t('duration')" prop="duration">
<el-input v-model="courseTable.searchParam.internal_reminder" :placeholder="t('internalReminderPlaceholder')" /> <el-input
</el-form-item> v-model="courseTable.searchParam.duration"
<el-form-item :label="t('customerReminder')" prop="customer_reminder"> :placeholder="t('durationPlaceholder')"
<el-input v-model="courseTable.searchParam.customer_reminder" :placeholder="t('customerReminderPlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('remarks')" prop="remarks"> <el-form-item :label="t('sessionCount')" prop="session_count">
<el-input v-model="courseTable.searchParam.remarks" :placeholder="t('remarksPlaceholder')" /> <el-input
</el-form-item> v-model="courseTable.searchParam.session_count"
<el-form-item> :placeholder="t('sessionCountPlaceholder')"
<el-button type="primary" @click="loadCourseList()">{{ t('search') }}</el-button> />
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> </el-form-item>
</el-form-item> <el-form-item
</el-form> :label="t('singleSessionCount')"
</el-card> prop="single_session_count"
>
<div class="mt-[10px]"> <el-input
<el-table :data="courseTable.data" size="large" v-loading="courseTable.loading"> v-model="courseTable.searchParam.single_session_count"
<template #empty> :placeholder="t('singleSessionCountPlaceholder')"
<span>{{ !courseTable.loading ? t('emptyData') : '' }}</span> />
</template> </el-form-item>
<el-table-column prop="course_name" :label="t('courseName')" min-width="120" :show-overflow-tooltip="true"/> <el-form-item :label="t('price')" prop="price">
<el-input
<el-table-column prop="course_type" :label="t('courseType')" min-width="120" :show-overflow-tooltip="true"/> v-model="courseTable.searchParam.price"
:placeholder="t('pricePlaceholder')"
<el-table-column prop="duration" :label="t('duration')" min-width="120" :show-overflow-tooltip="true"/> />
</el-form-item>
<el-table-column prop="session_count" :label="t('sessionCount')" min-width="120" :show-overflow-tooltip="true"/> <el-form-item :label="t('internalReminder')" prop="internal_reminder">
<el-input
<el-table-column prop="single_session_count" :label="t('singleSessionCount')" min-width="120" :show-overflow-tooltip="true"/> v-model="courseTable.searchParam.internal_reminder"
:placeholder="t('internalReminderPlaceholder')"
<el-table-column prop="price" :label="t('price')" min-width="120" :show-overflow-tooltip="true"/> />
</el-form-item>
<el-table-column prop="internal_reminder" :label="t('internalReminder')" min-width="120" :show-overflow-tooltip="true"/> <el-form-item :label="t('customerReminder')" prop="customer_reminder">
<el-input
<el-table-column prop="customer_reminder" :label="t('customerReminder')" min-width="120" :show-overflow-tooltip="true"/> v-model="courseTable.searchParam.customer_reminder"
:placeholder="t('customerReminderPlaceholder')"
<el-table-column prop="remarks" :label="t('remarks')" min-width="120" :show-overflow-tooltip="true"/> />
</el-form-item>
<el-table-column :label="t('operation')" fixed="right" min-width="120"> <el-form-item :label="t('remarks')" prop="remarks">
<template #default="{ row }"> <el-input
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button> v-model="courseTable.searchParam.remarks"
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button> :placeholder="t('remarksPlaceholder')"
</template> />
</el-table-column> </el-form-item>
</el-table> <el-form-item>
<div class="mt-[16px] flex justify-end"> <el-button type="primary" @click="loadCourseList()">{{
<el-pagination v-model:current-page="courseTable.page" v-model:page-size="courseTable.limit" t('search')
layout="total, sizes, prev, pager, next, jumper" :total="courseTable.total" }}</el-button>
@size-change="loadCourseList()" @current-change="loadCourseList" /> <el-button @click="resetForm(searchFormRef)">{{
</div> t('reset')
</div> }}</el-button>
</el-form-item>
<edit ref="editCourseDialog" @complete="loadCourseList" /> </el-form>
</el-card> </el-card>
</div>
</template> <div class="mt-[10px]">
<el-table
<script lang="ts" setup> :data="courseTable.data"
import { reactive, ref, watch } from 'vue' size="large"
import { t } from '@/lang' v-loading="courseTable.loading"
import { useDictionary } from '@/app/api/dict' >
import { getCourseList, deleteCourse } from '@/app/api/course' <template #empty>
import { img } from '@/utils/common' <span>{{ !courseTable.loading ? t('emptyData') : '' }}</span>
import { ElMessageBox,FormInstance } from 'element-plus' </template>
import Edit from '@/app/views/course/components/course-edit.vue' <el-table-column
import { useRoute } from 'vue-router' prop="course_name"
const route = useRoute() :label="t('courseName')"
const pageName = route.meta.title; min-width="120"
:show-overflow-tooltip="true"
let courseTable = reactive({ />
page: 1,
limit: 10, <el-table-column
total: 0, prop="course_type"
loading: true, :label="t('courseType')"
data: [], min-width="120"
searchParam:{ :show-overflow-tooltip="true"
"course_name":"", />
"course_type":"",
"duration":"", <el-table-column
"session_count":"", prop="duration"
"single_session_count":"", :label="t('duration')"
"price":"", min-width="120"
"internal_reminder":"", :show-overflow-tooltip="true"
"customer_reminder":"", />
"remarks":""
} <el-table-column
}) prop="session_count"
:label="t('sessionCount')"
const searchFormRef = ref<FormInstance>() min-width="120"
:show-overflow-tooltip="true"
// />
const selectData = ref<any[]>([])
<el-table-column
// prop="single_session_count"
:label="t('singleSessionCount')"
min-width="120"
/** :show-overflow-tooltip="true"
* 获取课程列表 />
*/
const loadCourseList = (page: number = 1) => { <el-table-column
courseTable.loading = true prop="price"
courseTable.page = page :label="t('price')"
min-width="120"
getCourseList({ :show-overflow-tooltip="true"
page: courseTable.page, />
limit: courseTable.limit,
...courseTable.searchParam <el-table-column
}).then(res => { prop="internal_reminder"
courseTable.loading = false :label="t('internalReminder')"
courseTable.data = res.data.data min-width="120"
courseTable.total = res.data.total :show-overflow-tooltip="true"
}).catch(() => { />
courseTable.loading = false
}) <el-table-column
} prop="customer_reminder"
loadCourseList() :label="t('customerReminder')"
min-width="120"
const editCourseDialog: Record<string, any> | null = ref(null) :show-overflow-tooltip="true"
/>
/**
* 添加课程 <el-table-column
*/ prop="remarks"
const addEvent = () => { :label="t('remarks')"
editCourseDialog.value.setFormData() min-width="120"
editCourseDialog.value.showDialog = true :show-overflow-tooltip="true"
} />
/** <el-table-column
* 编辑课程 :label="t('operation')"
* @param data fixed="right"
*/ min-width="120"
const editEvent = (data: any) => { >
editCourseDialog.value.setFormData(data) <template #default="{ row }">
editCourseDialog.value.showDialog = true <el-button type="primary" link @click="editEvent(row)">{{
} t('edit')
}}</el-button>
/** <el-button type="primary" link @click="deleteEvent(row.id)">{{
* 删除课程 t('delete')
*/ }}</el-button>
const deleteEvent = (id: number) => { </template>
ElMessageBox.confirm(t('courseDeleteTips'), t('warning'), </el-table-column>
{ </el-table>
confirmButtonText: t('confirm'), <div class="mt-[16px] flex justify-end">
cancelButtonText: t('cancel'), <el-pagination
type: 'warning', v-model:current-page="courseTable.page"
} v-model:page-size="courseTable.limit"
).then(() => { layout="total, sizes, prev, pager, next, jumper"
deleteCourse(id).then(() => { :total="courseTable.total"
loadCourseList() @size-change="loadCourseList()"
}).catch(() => { @current-change="loadCourseList"
}) />
}) </div>
} </div>
<edit ref="editCourseDialog" @complete="loadCourseList" />
</el-card>
const resetForm = (formEl: FormInstance | undefined) => { </div>
if (!formEl) return </template>
formEl.resetFields()
loadCourseList() <script lang="ts" setup>
} import { reactive, ref, watch } from 'vue'
</script> import { t } from '@/lang'
import { useDictionary } from '@/app/api/dict'
<style lang="scss" scoped> import { getCourseList, deleteCourse } from '@/app/api/course'
/* 多行超出隐藏 */ import { img } from '@/utils/common'
.multi-hidden { import { ElMessageBox, FormInstance } from 'element-plus'
word-break: break-all; import Edit from '@/app/views/course/components/course-edit.vue'
text-overflow: ellipsis; import { useRoute } from 'vue-router'
overflow: hidden; const route = useRoute()
display: -webkit-box; const pageName = route.meta.title
-webkit-line-clamp: 2;
-webkit-box-orient: vertical; let courseTable = reactive({
} page: 1,
</style> limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {
course_name: '',
course_type: '',
duration: '',
session_count: '',
single_session_count: '',
price: '',
internal_reminder: '',
customer_reminder: '',
remarks: '',
},
})
const searchFormRef = ref<FormInstance>()
//
const selectData = ref<any[]>([])
//
/**
* 获取课程列表
*/
const loadCourseList = (page: number = 1) => {
courseTable.loading = true
courseTable.page = page
getCourseList({
page: courseTable.page,
limit: courseTable.limit,
...courseTable.searchParam,
})
.then((res) => {
courseTable.loading = false
courseTable.data = res.data.data
courseTable.total = res.data.total
})
.catch(() => {
courseTable.loading = false
})
}
loadCourseList()
const editCourseDialog: Record<string, any> | null = ref(null)
/**
* 添加课程
*/
const addEvent = () => {
editCourseDialog.value.setFormData()
editCourseDialog.value.showDialog = true
}
/**
* 编辑课程
* @param data
*/
const editEvent = (data: any) => {
editCourseDialog.value.setFormData(data)
editCourseDialog.value.showDialog = true
}
/**
* 删除课程
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('courseDeleteTips'), t('warning'), {
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}).then(() => {
deleteCourse(id)
.then(() => {
loadCourseList()
})
.catch(() => {})
})
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadCourseList()
}
</script>
<style lang="scss" scoped>
/* 多行超出隐藏 */
.multi-hidden {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
</style>

529
admin/src/app/views/course_schedule/components/course-schedule-edit.vue

@ -1,233 +1,296 @@
<template> <template>
<el-dialog v-model="showDialog" :title="formData.id ? t('updateCourseSchedule') : t('addCourseSchedule')" width="50%" class="diy-dialog-wrap" :destroy-on-close="true"> <el-dialog
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading"> v-model="showDialog"
<el-form-item :label="t('campusId')" prop="campus_id"> :title="formData.id ? t('updateCourseSchedule') : t('addCourseSchedule')"
<el-input v-model="formData.campus_id" clearable :placeholder="t('campusIdPlaceholder')" class="input-width" /> width="50%"
</el-form-item> class="diy-dialog-wrap"
:destroy-on-close="true"
<el-form-item :label="t('venueId')" prop="venue_id"> >
<el-input v-model="formData.venue_id" clearable :placeholder="t('venueIdPlaceholder')" class="input-width" /> <el-form
</el-form-item> :model="formData"
label-width="120px"
<el-form-item :label="t('courseDate')" prop="course_date"> ref="formRef"
<el-input v-model="formData.course_date" clearable :placeholder="t('courseDatePlaceholder')" class="input-width" /> :rules="formRules"
</el-form-item> class="page-form"
v-loading="loading"
<el-form-item :label="t('timeSlot')" prop="time_slot"> >
<el-input v-model="formData.time_slot" clearable :placeholder="t('timeSlotPlaceholder')" class="input-width" /> <el-form-item :label="t('campusId')" prop="campus_id">
</el-form-item> <el-input
v-model="formData.campus_id"
<el-form-item :label="t('courseId')" prop="course_id"> clearable
<el-input v-model="formData.course_id" clearable :placeholder="t('courseIdPlaceholder')" class="input-width" /> :placeholder="t('campusIdPlaceholder')"
</el-form-item> class="input-width"
/>
<el-form-item :label="t('coachId')" prop="coach_id"> </el-form-item>
<el-input v-model="formData.coach_id" clearable :placeholder="t('coachIdPlaceholder')" class="input-width" />
</el-form-item> <el-form-item :label="t('venueId')" prop="venue_id">
<el-input
<el-form-item :label="t('participants')" prop="participants"> v-model="formData.venue_id"
<el-input v-model="formData.participants" clearable :placeholder="t('participantsPlaceholder')" class="input-width" /> clearable
</el-form-item> :placeholder="t('venueIdPlaceholder')"
class="input-width"
<el-form-item :label="t('studentIds')" prop="student_ids"> />
<el-input v-model="formData.student_ids" clearable :placeholder="t('studentIdsPlaceholder')" class="input-width" /> </el-form-item>
</el-form-item>
<el-form-item :label="t('courseDate')" prop="course_date">
<el-form-item :label="t('availableCapacity')" prop="available_capacity"> <el-input
<el-input v-model="formData.available_capacity" clearable :placeholder="t('availableCapacityPlaceholder')" class="input-width" /> v-model="formData.course_date"
</el-form-item> clearable
:placeholder="t('courseDatePlaceholder')"
<el-form-item :label="t('status')" prop="status"> class="input-width"
<el-input v-model="formData.status" clearable :placeholder="t('statusPlaceholder')" class="input-width" /> />
</el-form-item> </el-form-item>
</el-form> <el-form-item :label="t('timeSlot')" prop="time_slot">
<el-input
<template #footer> v-model="formData.time_slot"
<span class="dialog-footer"> clearable
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button> :placeholder="t('timeSlotPlaceholder')"
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{ class="input-width"
t('confirm') />
}}</el-button> </el-form-item>
</span>
</template> <el-form-item :label="t('courseId')" prop="course_id">
</el-dialog> <el-input
</template> v-model="formData.course_id"
clearable
<script lang="ts" setup> :placeholder="t('courseIdPlaceholder')"
import { ref, reactive, computed, watch } from 'vue' class="input-width"
import { useDictionary } from '@/app/api/dict' />
import { t } from '@/lang' </el-form-item>
import type { FormInstance } from 'element-plus'
import { addCourseSchedule, editCourseSchedule, getCourseScheduleInfo } from '@/app/api/course_schedule' <el-form-item :label="t('coachId')" prop="coach_id">
<el-input
let showDialog = ref(false) v-model="formData.coach_id"
const loading = ref(false) clearable
:placeholder="t('coachIdPlaceholder')"
/** class="input-width"
* 表单数据 />
*/ </el-form-item>
const initialFormData = {
id: '', <el-form-item :label="t('participants')" prop="participants">
campus_id: '', <el-input
venue_id: '', v-model="formData.participants"
course_date: '', clearable
time_slot: '', :placeholder="t('participantsPlaceholder')"
course_id: '', class="input-width"
coach_id: '', />
participants: '', </el-form-item>
student_ids: '',
available_capacity: '', <el-form-item :label="t('studentIds')" prop="student_ids">
status: '', <el-input
} v-model="formData.student_ids"
const formData: Record<string, any> = reactive({ ...initialFormData }) clearable
:placeholder="t('studentIdsPlaceholder')"
const formRef = ref<FormInstance>() class="input-width"
/>
// </el-form-item>
const formRules = computed(() => {
return { <el-form-item :label="t('availableCapacity')" prop="available_capacity">
campus_id: [ <el-input
{ required: true, message: t('campusIdPlaceholder'), trigger: 'blur' }, v-model="formData.available_capacity"
clearable
] :placeholder="t('availableCapacityPlaceholder')"
, class="input-width"
venue_id: [ />
{ required: true, message: t('venueIdPlaceholder'), trigger: 'blur' }, </el-form-item>
] <el-form-item :label="t('status')" prop="status">
, <el-input
course_date: [ v-model="formData.status"
{ required: true, message: t('courseDatePlaceholder'), trigger: 'blur' }, clearable
:placeholder="t('statusPlaceholder')"
] class="input-width"
, />
time_slot: [ </el-form-item>
{ required: true, message: t('timeSlotPlaceholder'), trigger: 'blur' }, </el-form>
] <template #footer>
, <span class="dialog-footer">
course_id: [ <el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
{ required: true, message: t('courseIdPlaceholder'), trigger: 'blur' }, <el-button
type="primary"
] :loading="loading"
, @click="confirm(formRef)"
coach_id: [ >{{ t('confirm') }}</el-button
{ required: true, message: t('coachIdPlaceholder'), trigger: 'blur' }, >
</span>
] </template>
, </el-dialog>
participants: [ </template>
{ required: true, message: t('participantsPlaceholder'), trigger: 'blur' },
<script lang="ts" setup>
] import { ref, reactive, computed, watch } from 'vue'
, import { useDictionary } from '@/app/api/dict'
student_ids: [ import { t } from '@/lang'
{ required: true, message: t('studentIdsPlaceholder'), trigger: 'blur' }, import type { FormInstance } from 'element-plus'
import {
] addCourseSchedule,
, editCourseSchedule,
available_capacity: [ getCourseScheduleInfo,
{ required: true, message: t('availableCapacityPlaceholder'), trigger: 'blur' }, } from '@/app/api/course_schedule'
] let showDialog = ref(false)
, const loading = ref(false)
status: [
{ required: true, message: t('statusPlaceholder'), trigger: 'blur' }, /**
* 表单数据
] */
, const initialFormData = {
} id: '',
}) campus_id: '',
venue_id: '',
const emit = defineEmits(['complete']) course_date: '',
time_slot: '',
/** course_id: '',
* 确认 coach_id: '',
* @param formEl participants: '',
*/ student_ids: '',
const confirm = async (formEl: FormInstance | undefined) => { available_capacity: '',
if (loading.value || !formEl) return status: '',
let save = formData.id ? editCourseSchedule : addCourseSchedule }
const formData: Record<string, any> = reactive({ ...initialFormData })
await formEl.validate(async (valid) => {
if (valid) { const formRef = ref<FormInstance>()
loading.value = true
//
let data = formData const formRules = computed(() => {
return {
save(data).then(res => { campus_id: [
loading.value = false { required: true, message: t('campusIdPlaceholder'), trigger: 'blur' },
showDialog.value = false ],
emit('complete') venue_id: [
}).catch(err => { { required: true, message: t('venueIdPlaceholder'), trigger: 'blur' },
loading.value = false ],
}) course_date: [
} { required: true, message: t('courseDatePlaceholder'), trigger: 'blur' },
}) ],
} time_slot: [
{ required: true, message: t('timeSlotPlaceholder'), trigger: 'blur' },
// ],
course_id: [
{ required: true, message: t('courseIdPlaceholder'), trigger: 'blur' },
],
const setFormData = async (row: any = null) => { coach_id: [
Object.assign(formData, initialFormData) { required: true, message: t('coachIdPlaceholder'), trigger: 'blur' },
loading.value = true ],
if(row){ participants: [
const data = await (await getCourseScheduleInfo(row.id)).data {
if (data) Object.keys(formData).forEach((key: string) => { required: true,
if (data[key] != undefined) formData[key] = data[key] message: t('participantsPlaceholder'),
}) trigger: 'blur',
} },
loading.value = false ],
} student_ids: [
{ required: true, message: t('studentIdsPlaceholder'), trigger: 'blur' },
// ],
const mobileVerify = (rule: any, value: any, callback: any) => { available_capacity: [
if (value && !/^1[3-9]\d{9}$/.test(value)) { {
callback(new Error(t('generateMobile'))) required: true,
} else { message: t('availableCapacityPlaceholder'),
callback() trigger: 'blur',
} },
} ],
status: [
// { required: true, message: t('statusPlaceholder'), trigger: 'blur' },
const idCardVerify = (rule: any, value: any, callback: any) => { ],
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) { }
callback(new Error(t('generateIdCard'))) })
} else {
callback() const emit = defineEmits(['complete'])
}
} /**
* 确认
// * @param formEl
const emailVerify = (rule: any, value: any, callback: any) => { */
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) { const confirm = async (formEl: FormInstance | undefined) => {
callback(new Error(t('generateEmail'))) if (loading.value || !formEl) return
} else { let save = formData.id ? editCourseSchedule : addCourseSchedule
callback()
} await formEl.validate(async (valid) => {
} if (valid) {
loading.value = true
//
const numberVerify = (rule: any, value: any, callback: any) => { let data = formData
if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber'))) save(data)
} else { .then((res) => {
callback() loading.value = false
} showDialog.value = false
} emit('complete')
})
defineExpose({ .catch((err) => {
showDialog, loading.value = false
setFormData })
}) }
</script> })
}
<style lang="scss" scoped></style>
<style lang="scss"> //
.diy-dialog-wrap .el-form-item__label{
height: auto !important; const setFormData = async (row: any = null) => {
} Object.assign(formData, initialFormData)
</style> loading.value = true
if (row) {
const data = await (await getCourseScheduleInfo(row.id)).data
if (data)
Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key]
})
}
loading.value = false
}
//
const mobileVerify = (rule: any, value: any, callback: any) => {
if (value && !/^1[3-9]\d{9}$/.test(value)) {
callback(new Error(t('generateMobile')))
} else {
callback()
}
}
//
const idCardVerify = (rule: any, value: any, callback: any) => {
if (
value &&
!/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
value
)
) {
callback(new Error(t('generateIdCard')))
} else {
callback()
}
}
//
const emailVerify = (rule: any, value: any, callback: any) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail')))
} else {
callback()
}
}
//
const numberVerify = (rule: any, value: any, callback: any) => {
if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber')))
} else {
callback()
}
}
defineExpose({
showDialog,
setFormData,
})
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.diy-dialog-wrap .el-form-item__label {
height: auto !important;
}
</style>

539
admin/src/app/views/course_schedule/course_schedule.vue

@ -1,213 +1,326 @@
<template> <template>
<div class="main-container"> <div class="main-container">
<el-card class="box-card !border-none" shadow="never"> <el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<div class="flex justify-between items-center"> <span class="text-lg">{{ pageName }}</span>
<span class="text-lg">{{pageName}}</span> <el-button type="primary" @click="addEvent">
<el-button type="primary" @click="addEvent"> {{ t('addCourseSchedule') }}
{{ t('addCourseSchedule') }} </el-button>
</el-button> </div>
</div>
<el-card
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> class="box-card !border-none my-[10px] table-search-wrap"
<el-form :inline="true" :model="courseScheduleTable.searchParam" ref="searchFormRef"> shadow="never"
<el-form-item :label="t('campusId')" prop="campus_id"> >
<el-input v-model="courseScheduleTable.searchParam.campus_id" :placeholder="t('campusIdPlaceholder')" /> <el-form
</el-form-item> :inline="true"
<el-form-item :label="t('venueId')" prop="venue_id"> :model="courseScheduleTable.searchParam"
<el-input v-model="courseScheduleTable.searchParam.venue_id" :placeholder="t('venueIdPlaceholder')" /> ref="searchFormRef"
</el-form-item> >
<el-form-item :label="t('courseDate')" prop="course_date"> <el-form-item :label="t('campusId')" prop="campus_id">
<el-input v-model="courseScheduleTable.searchParam.course_date" :placeholder="t('courseDatePlaceholder')" /> <el-input
</el-form-item> v-model="courseScheduleTable.searchParam.campus_id"
<el-form-item :label="t('timeSlot')" prop="time_slot"> :placeholder="t('campusIdPlaceholder')"
<el-input v-model="courseScheduleTable.searchParam.time_slot" :placeholder="t('timeSlotPlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('courseId')" prop="course_id"> <el-form-item :label="t('venueId')" prop="venue_id">
<el-input v-model="courseScheduleTable.searchParam.course_id" :placeholder="t('courseIdPlaceholder')" /> <el-input
</el-form-item> v-model="courseScheduleTable.searchParam.venue_id"
<el-form-item :label="t('coachId')" prop="coach_id"> :placeholder="t('venueIdPlaceholder')"
<el-input v-model="courseScheduleTable.searchParam.coach_id" :placeholder="t('coachIdPlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('participants')" prop="participants"> <el-form-item :label="t('courseDate')" prop="course_date">
<el-input v-model="courseScheduleTable.searchParam.participants" :placeholder="t('participantsPlaceholder')" /> <el-input
</el-form-item> v-model="courseScheduleTable.searchParam.course_date"
<el-form-item :label="t('studentIds')" prop="student_ids"> :placeholder="t('courseDatePlaceholder')"
<el-input v-model="courseScheduleTable.searchParam.student_ids" :placeholder="t('studentIdsPlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('availableCapacity')" prop="available_capacity"> <el-form-item :label="t('timeSlot')" prop="time_slot">
<el-input v-model="courseScheduleTable.searchParam.available_capacity" :placeholder="t('availableCapacityPlaceholder')" /> <el-input
</el-form-item> v-model="courseScheduleTable.searchParam.time_slot"
<el-form-item :label="t('status')" prop="status"> :placeholder="t('timeSlotPlaceholder')"
<el-input v-model="courseScheduleTable.searchParam.status" :placeholder="t('statusPlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item :label="t('courseId')" prop="course_id">
<el-button type="primary" @click="loadCourseScheduleList()">{{ t('search') }}</el-button> <el-input
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> v-model="courseScheduleTable.searchParam.course_id"
</el-form-item> :placeholder="t('courseIdPlaceholder')"
</el-form> />
</el-card> </el-form-item>
<el-form-item :label="t('coachId')" prop="coach_id">
<div class="mt-[10px]"> <el-input
<el-table :data="courseScheduleTable.data" size="large" v-loading="courseScheduleTable.loading"> v-model="courseScheduleTable.searchParam.coach_id"
<template #empty> :placeholder="t('coachIdPlaceholder')"
<span>{{ !courseScheduleTable.loading ? t('emptyData') : '' }}</span> />
</template> </el-form-item>
<el-table-column prop="campus_id" :label="t('campusId')" min-width="120" :show-overflow-tooltip="true"/> <el-form-item :label="t('participants')" prop="participants">
<el-input
<el-table-column prop="venue_id" :label="t('venueId')" min-width="120" :show-overflow-tooltip="true"/> v-model="courseScheduleTable.searchParam.participants"
:placeholder="t('participantsPlaceholder')"
<el-table-column prop="course_date" :label="t('courseDate')" min-width="120" :show-overflow-tooltip="true"/> />
</el-form-item>
<el-table-column prop="time_slot" :label="t('timeSlot')" min-width="120" :show-overflow-tooltip="true"/> <el-form-item :label="t('studentIds')" prop="student_ids">
<el-input
<el-table-column prop="course_id" :label="t('courseId')" min-width="120" :show-overflow-tooltip="true"/> v-model="courseScheduleTable.searchParam.student_ids"
:placeholder="t('studentIdsPlaceholder')"
<el-table-column prop="coach_id" :label="t('coachId')" min-width="120" :show-overflow-tooltip="true"/> />
</el-form-item>
<el-table-column prop="participants" :label="t('participants')" min-width="120" :show-overflow-tooltip="true"/> <el-form-item
:label="t('availableCapacity')"
<el-table-column prop="student_ids" :label="t('studentIds')" min-width="120" :show-overflow-tooltip="true"/> prop="available_capacity"
>
<el-table-column prop="available_capacity" :label="t('availableCapacity')" min-width="120" :show-overflow-tooltip="true"/> <el-input
v-model="courseScheduleTable.searchParam.available_capacity"
<el-table-column prop="status" :label="t('status')" min-width="120" :show-overflow-tooltip="true"/> :placeholder="t('availableCapacityPlaceholder')"
/>
<el-table-column :label="t('operation')" fixed="right" min-width="120"> </el-form-item>
<template #default="{ row }"> <el-form-item :label="t('status')" prop="status">
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button> <el-input
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button> v-model="courseScheduleTable.searchParam.status"
</template> :placeholder="t('statusPlaceholder')"
</el-table-column> />
</el-form-item>
</el-table>
<div class="mt-[16px] flex justify-end"> <el-form-item>
<el-pagination v-model:current-page="courseScheduleTable.page" v-model:page-size="courseScheduleTable.limit" <el-button type="primary" @click="loadCourseScheduleList()">{{
layout="total, sizes, prev, pager, next, jumper" :total="courseScheduleTable.total" t('search')
@size-change="loadCourseScheduleList()" @current-change="loadCourseScheduleList" /> }}</el-button>
</div> <el-button @click="resetForm(searchFormRef)">{{
</div> t('reset')
}}</el-button>
<edit ref="editCourseScheduleDialog" @complete="loadCourseScheduleList" /> </el-form-item>
</el-card> </el-form>
</div> </el-card>
</template>
<div class="mt-[10px]">
<script lang="ts" setup> <el-table
import { reactive, ref, watch } from 'vue' :data="courseScheduleTable.data"
import { t } from '@/lang' size="large"
import { useDictionary } from '@/app/api/dict' v-loading="courseScheduleTable.loading"
import { getCourseScheduleList, deleteCourseSchedule } from '@/app/api/course_schedule' >
import { img } from '@/utils/common' <template #empty>
import { ElMessageBox,FormInstance } from 'element-plus' <span>{{
import Edit from '@/app/views/course_schedule/components/course-schedule-edit.vue' !courseScheduleTable.loading ? t('emptyData') : ''
import { useRoute } from 'vue-router' }}</span>
const route = useRoute() </template>
const pageName = route.meta.title; <el-table-column
prop="campus_id"
let courseScheduleTable = reactive({ :label="t('campusId')"
page: 1, min-width="120"
limit: 10, :show-overflow-tooltip="true"
total: 0, />
loading: true,
data: [], <el-table-column
searchParam:{ prop="venue_id"
"campus_id":"", :label="t('venueId')"
"venue_id":"", min-width="120"
"course_date":"", :show-overflow-tooltip="true"
"time_slot":"", />
"course_id":"",
"coach_id":"", <el-table-column
"participants":"", prop="course_date"
"student_ids":"", :label="t('courseDate')"
"available_capacity":"", min-width="120"
"status":"" :show-overflow-tooltip="true"
} />
})
<el-table-column
const searchFormRef = ref<FormInstance>() prop="time_slot"
:label="t('timeSlot')"
// min-width="120"
const selectData = ref<any[]>([]) :show-overflow-tooltip="true"
/>
//
<el-table-column
prop="course_id"
/** :label="t('courseId')"
* 获取课程安排列表 min-width="120"
*/ :show-overflow-tooltip="true"
const loadCourseScheduleList = (page: number = 1) => { />
courseScheduleTable.loading = true
courseScheduleTable.page = page <el-table-column
prop="coach_id"
getCourseScheduleList({ :label="t('coachId')"
page: courseScheduleTable.page, min-width="120"
limit: courseScheduleTable.limit, :show-overflow-tooltip="true"
...courseScheduleTable.searchParam />
}).then(res => {
courseScheduleTable.loading = false <el-table-column
courseScheduleTable.data = res.data.data prop="participants"
courseScheduleTable.total = res.data.total :label="t('participants')"
}).catch(() => { min-width="120"
courseScheduleTable.loading = false :show-overflow-tooltip="true"
}) />
}
loadCourseScheduleList() <el-table-column
prop="student_ids"
const editCourseScheduleDialog: Record<string, any> | null = ref(null) :label="t('studentIds')"
min-width="120"
/** :show-overflow-tooltip="true"
* 添加课程安排 />
*/
const addEvent = () => { <el-table-column
editCourseScheduleDialog.value.setFormData() prop="available_capacity"
editCourseScheduleDialog.value.showDialog = true :label="t('availableCapacity')"
} min-width="120"
:show-overflow-tooltip="true"
/** />
* 编辑课程安排
* @param data <el-table-column
*/ prop="status"
const editEvent = (data: any) => { :label="t('status')"
editCourseScheduleDialog.value.setFormData(data) min-width="120"
editCourseScheduleDialog.value.showDialog = true :show-overflow-tooltip="true"
} />
/** <el-table-column
* 删除课程安排 :label="t('operation')"
*/ fixed="right"
const deleteEvent = (id: number) => { min-width="120"
ElMessageBox.confirm(t('courseScheduleDeleteTips'), t('warning'), >
{ <template #default="{ row }">
confirmButtonText: t('confirm'), <el-button type="primary" link @click="editEvent(row)">{{
cancelButtonText: t('cancel'), t('edit')
type: 'warning', }}</el-button>
} <el-button type="primary" link @click="deleteEvent(row.id)">{{
).then(() => { t('delete')
deleteCourseSchedule(id).then(() => { }}</el-button>
loadCourseScheduleList() </template>
}).catch(() => { </el-table-column>
}) </el-table>
}) <div class="mt-[16px] flex justify-end">
} <el-pagination
v-model:current-page="courseScheduleTable.page"
v-model:page-size="courseScheduleTable.limit"
layout="total, sizes, prev, pager, next, jumper"
const resetForm = (formEl: FormInstance | undefined) => { :total="courseScheduleTable.total"
if (!formEl) return @size-change="loadCourseScheduleList()"
formEl.resetFields() @current-change="loadCourseScheduleList"
loadCourseScheduleList() />
} </div>
</script> </div>
<style lang="scss" scoped> <edit ref="editCourseScheduleDialog" @complete="loadCourseScheduleList" />
/* 多行超出隐藏 */ </el-card>
.multi-hidden { </div>
word-break: break-all; </template>
text-overflow: ellipsis;
overflow: hidden; <script lang="ts" setup>
display: -webkit-box; import { reactive, ref, watch } from 'vue'
-webkit-line-clamp: 2; import { t } from '@/lang'
-webkit-box-orient: vertical; import { useDictionary } from '@/app/api/dict'
} import {
</style> getCourseScheduleList,
deleteCourseSchedule,
} from '@/app/api/course_schedule'
import { img } from '@/utils/common'
import { ElMessageBox, FormInstance } from 'element-plus'
import Edit from '@/app/views/course_schedule/components/course-schedule-edit.vue'
import { useRoute } from 'vue-router'
const route = useRoute()
const pageName = route.meta.title
let courseScheduleTable = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {
campus_id: '',
venue_id: '',
course_date: '',
time_slot: '',
course_id: '',
coach_id: '',
participants: '',
student_ids: '',
available_capacity: '',
status: '',
},
})
const searchFormRef = ref<FormInstance>()
//
const selectData = ref<any[]>([])
//
/**
* 获取课程安排列表
*/
const loadCourseScheduleList = (page: number = 1) => {
courseScheduleTable.loading = true
courseScheduleTable.page = page
getCourseScheduleList({
page: courseScheduleTable.page,
limit: courseScheduleTable.limit,
...courseScheduleTable.searchParam,
})
.then((res) => {
courseScheduleTable.loading = false
courseScheduleTable.data = res.data.data
courseScheduleTable.total = res.data.total
})
.catch(() => {
courseScheduleTable.loading = false
})
}
loadCourseScheduleList()
const editCourseScheduleDialog: Record<string, any> | null = ref(null)
/**
* 添加课程安排
*/
const addEvent = () => {
editCourseScheduleDialog.value.setFormData()
editCourseScheduleDialog.value.showDialog = true
}
/**
* 编辑课程安排
* @param data
*/
const editEvent = (data: any) => {
editCourseScheduleDialog.value.setFormData(data)
editCourseScheduleDialog.value.showDialog = true
}
/**
* 删除课程安排
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('courseScheduleDeleteTips'), t('warning'), {
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}).then(() => {
deleteCourseSchedule(id)
.then(() => {
loadCourseScheduleList()
})
.catch(() => {})
})
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadCourseScheduleList()
}
</script>
<style lang="scss" scoped>
/* 多行超出隐藏 */
.multi-hidden {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
</style>

446
admin/src/app/views/customer_resource_changes/components/customer-resource-changes-edit.vue

@ -1,193 +1,253 @@
<template> <template>
<el-dialog v-model="showDialog" :title="formData.id ? t('updateCustomerResourceChanges') : t('addCustomerResourceChanges')" width="50%" class="diy-dialog-wrap" :destroy-on-close="true"> <el-dialog
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading"> v-model="showDialog"
<el-form-item :label="t('customerResourceId')" prop="customer_resource_id"> :title="
<el-input v-model="formData.customer_resource_id" clearable :placeholder="t('customerResourceIdPlaceholder')" class="input-width" /> formData.id
</el-form-item> ? t('updateCustomerResourceChanges')
: t('addCustomerResourceChanges')
<el-form-item :label="t('operatorId')" prop="operator_id"> "
<el-input v-model="formData.operator_id" clearable :placeholder="t('operatorIdPlaceholder')" class="input-width" /> width="50%"
</el-form-item> class="diy-dialog-wrap"
:destroy-on-close="true"
<el-form-item :label="t('campusId')" prop="campus_id"> >
<el-input v-model="formData.campus_id" clearable :placeholder="t('campusIdPlaceholder')" class="input-width" /> <el-form
</el-form-item> :model="formData"
label-width="120px"
<el-form-item :label="t('modifiedFields')" prop="modified_fields"> ref="formRef"
<el-input v-model="formData.modified_fields" clearable :placeholder="t('modifiedFieldsPlaceholder')" class="input-width" /> :rules="formRules"
</el-form-item> class="page-form"
v-loading="loading"
<el-form-item :label="t('oldValues')" prop="old_values"> >
<el-input v-model="formData.old_values" clearable :placeholder="t('oldValuesPlaceholder')" class="input-width" /> <el-form-item
</el-form-item> :label="t('customerResourceId')"
prop="customer_resource_id"
<el-form-item :label="t('newValues')" prop="new_values"> >
<el-input v-model="formData.new_values" clearable :placeholder="t('newValuesPlaceholder')" class="input-width" /> <el-input
</el-form-item> v-model="formData.customer_resource_id"
clearable
</el-form> :placeholder="t('customerResourceIdPlaceholder')"
class="input-width"
<template #footer> />
<span class="dialog-footer"> </el-form-item>
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{ <el-form-item :label="t('operatorId')" prop="operator_id">
t('confirm') <el-input
}}</el-button> v-model="formData.operator_id"
</span> clearable
</template> :placeholder="t('operatorIdPlaceholder')"
</el-dialog> class="input-width"
</template> />
</el-form-item>
<script lang="ts" setup>
import { ref, reactive, computed, watch } from 'vue' <el-form-item :label="t('campusId')" prop="campus_id">
import { useDictionary } from '@/app/api/dict' <el-input
import { t } from '@/lang' v-model="formData.campus_id"
import type { FormInstance } from 'element-plus' clearable
import { addCustomerResourceChanges, editCustomerResourceChanges, getCustomerResourceChangesInfo } from '@/app/api/customer_resource_changes' :placeholder="t('campusIdPlaceholder')"
class="input-width"
let showDialog = ref(false) />
const loading = ref(false) </el-form-item>
/** <el-form-item :label="t('modifiedFields')" prop="modified_fields">
* 表单数据 <el-input
*/ v-model="formData.modified_fields"
const initialFormData = { clearable
id: '', :placeholder="t('modifiedFieldsPlaceholder')"
customer_resource_id: '', class="input-width"
operator_id: '', />
campus_id: '', </el-form-item>
modified_fields: '',
old_values: '', <el-form-item :label="t('oldValues')" prop="old_values">
new_values: '', <el-input
} v-model="formData.old_values"
const formData: Record<string, any> = reactive({ ...initialFormData }) clearable
:placeholder="t('oldValuesPlaceholder')"
const formRef = ref<FormInstance>() class="input-width"
/>
// </el-form-item>
const formRules = computed(() => {
return { <el-form-item :label="t('newValues')" prop="new_values">
customer_resource_id: [ <el-input
{ required: true, message: t('customerResourceIdPlaceholder'), trigger: 'blur' }, v-model="formData.new_values"
clearable
] :placeholder="t('newValuesPlaceholder')"
, class="input-width"
operator_id: [ />
{ required: true, message: t('operatorIdPlaceholder'), trigger: 'blur' }, </el-form-item>
</el-form>
]
, <template #footer>
campus_id: [ <span class="dialog-footer">
{ required: true, message: t('campusIdPlaceholder'), trigger: 'blur' }, <el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
<el-button
] type="primary"
, :loading="loading"
modified_fields: [ @click="confirm(formRef)"
{ required: true, message: t('modifiedFieldsPlaceholder'), trigger: 'blur' }, >{{ t('confirm') }}</el-button
>
] </span>
, </template>
old_values: [ </el-dialog>
{ required: true, message: t('oldValuesPlaceholder'), trigger: 'blur' }, </template>
] <script lang="ts" setup>
, import { ref, reactive, computed, watch } from 'vue'
new_values: [ import { useDictionary } from '@/app/api/dict'
{ required: true, message: t('newValuesPlaceholder'), trigger: 'blur' }, import { t } from '@/lang'
import type { FormInstance } from 'element-plus'
] import {
, addCustomerResourceChanges,
} editCustomerResourceChanges,
}) getCustomerResourceChangesInfo,
} from '@/app/api/customer_resource_changes'
const emit = defineEmits(['complete'])
let showDialog = ref(false)
/** const loading = ref(false)
* 确认
* @param formEl /**
*/ * 表单数据
const confirm = async (formEl: FormInstance | undefined) => { */
if (loading.value || !formEl) return const initialFormData = {
let save = formData.id ? editCustomerResourceChanges : addCustomerResourceChanges id: '',
customer_resource_id: '',
await formEl.validate(async (valid) => { operator_id: '',
if (valid) { campus_id: '',
loading.value = true modified_fields: '',
old_values: '',
let data = formData new_values: '',
}
save(data).then(res => { const formData: Record<string, any> = reactive({ ...initialFormData })
loading.value = false
showDialog.value = false const formRef = ref<FormInstance>()
emit('complete')
}).catch(err => { //
loading.value = false const formRules = computed(() => {
}) return {
} customer_resource_id: [
}) {
} required: true,
message: t('customerResourceIdPlaceholder'),
// trigger: 'blur',
},
],
operator_id: [
const setFormData = async (row: any = null) => { { required: true, message: t('operatorIdPlaceholder'), trigger: 'blur' },
Object.assign(formData, initialFormData) ],
loading.value = true campus_id: [
if(row){ { required: true, message: t('campusIdPlaceholder'), trigger: 'blur' },
const data = await (await getCustomerResourceChangesInfo(row.id)).data ],
if (data) Object.keys(formData).forEach((key: string) => { modified_fields: [
if (data[key] != undefined) formData[key] = data[key] {
}) required: true,
} message: t('modifiedFieldsPlaceholder'),
loading.value = false trigger: 'blur',
} },
],
// old_values: [
const mobileVerify = (rule: any, value: any, callback: any) => { { required: true, message: t('oldValuesPlaceholder'), trigger: 'blur' },
if (value && !/^1[3-9]\d{9}$/.test(value)) { ],
callback(new Error(t('generateMobile'))) new_values: [
} else { { required: true, message: t('newValuesPlaceholder'), trigger: 'blur' },
callback() ],
} }
} })
// const emit = defineEmits(['complete'])
const idCardVerify = (rule: any, value: any, callback: any) => {
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) { /**
callback(new Error(t('generateIdCard'))) * 确认
} else { * @param formEl
callback() */
} const confirm = async (formEl: FormInstance | undefined) => {
} if (loading.value || !formEl) return
let save = formData.id
// ? editCustomerResourceChanges
const emailVerify = (rule: any, value: any, callback: any) => { : addCustomerResourceChanges
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail'))) await formEl.validate(async (valid) => {
} else { if (valid) {
callback() loading.value = true
}
} let data = formData
// save(data)
const numberVerify = (rule: any, value: any, callback: any) => { .then((res) => {
if (!Number.isInteger(value)) { loading.value = false
callback(new Error(t('generateNumber'))) showDialog.value = false
} else { emit('complete')
callback() })
} .catch((err) => {
} loading.value = false
})
defineExpose({ }
showDialog, })
setFormData }
})
</script> //
<style lang="scss" scoped></style> const setFormData = async (row: any = null) => {
<style lang="scss"> Object.assign(formData, initialFormData)
.diy-dialog-wrap .el-form-item__label{ loading.value = true
height: auto !important; if (row) {
} const data = await (await getCustomerResourceChangesInfo(row.id)).data
</style> if (data)
Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key]
})
}
loading.value = false
}
//
const mobileVerify = (rule: any, value: any, callback: any) => {
if (value && !/^1[3-9]\d{9}$/.test(value)) {
callback(new Error(t('generateMobile')))
} else {
callback()
}
}
//
const idCardVerify = (rule: any, value: any, callback: any) => {
if (
value &&
!/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
value
)
) {
callback(new Error(t('generateIdCard')))
} else {
callback()
}
}
//
const emailVerify = (rule: any, value: any, callback: any) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail')))
} else {
callback()
}
}
//
const numberVerify = (rule: any, value: any, callback: any) => {
if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber')))
} else {
callback()
}
}
defineExpose({
showDialog,
setFormData,
})
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.diy-dialog-wrap .el-form-item__label {
height: auto !important;
}
</style>

466
admin/src/app/views/customer_resource_changes/customer_resource_changes.vue

@ -1,189 +1,277 @@
<template> <template>
<div class="main-container"> <div class="main-container">
<el-card class="box-card !border-none" shadow="never"> <el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<div class="flex justify-between items-center"> <span class="text-lg">{{ pageName }}</span>
<span class="text-lg">{{pageName}}</span> <el-button type="primary" @click="addEvent">
<el-button type="primary" @click="addEvent"> {{ t('addCustomerResourceChanges') }}
{{ t('addCustomerResourceChanges') }} </el-button>
</el-button> </div>
</div>
<el-card
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> class="box-card !border-none my-[10px] table-search-wrap"
<el-form :inline="true" :model="customerResourceChangesTable.searchParam" ref="searchFormRef"> shadow="never"
<el-form-item :label="t('customerResourceId')" prop="customer_resource_id"> >
<el-input v-model="customerResourceChangesTable.searchParam.customer_resource_id" :placeholder="t('customerResourceIdPlaceholder')" /> <el-form
</el-form-item> :inline="true"
<el-form-item :label="t('operatorId')" prop="operator_id"> :model="customerResourceChangesTable.searchParam"
<el-input v-model="customerResourceChangesTable.searchParam.operator_id" :placeholder="t('operatorIdPlaceholder')" /> ref="searchFormRef"
</el-form-item> >
<el-form-item :label="t('campusId')" prop="campus_id"> <el-form-item
<el-input v-model="customerResourceChangesTable.searchParam.campus_id" :placeholder="t('campusIdPlaceholder')" /> :label="t('customerResourceId')"
</el-form-item> prop="customer_resource_id"
<el-form-item :label="t('modifiedFields')" prop="modified_fields"> >
<el-input v-model="customerResourceChangesTable.searchParam.modified_fields" :placeholder="t('modifiedFieldsPlaceholder')" /> <el-input
</el-form-item> v-model="
<el-form-item :label="t('oldValues')" prop="old_values"> customerResourceChangesTable.searchParam.customer_resource_id
<el-input v-model="customerResourceChangesTable.searchParam.old_values" :placeholder="t('oldValuesPlaceholder')" /> "
</el-form-item> :placeholder="t('customerResourceIdPlaceholder')"
<el-form-item :label="t('newValues')" prop="new_values"> />
<el-input v-model="customerResourceChangesTable.searchParam.new_values" :placeholder="t('newValuesPlaceholder')" /> </el-form-item>
</el-form-item> <el-form-item :label="t('operatorId')" prop="operator_id">
<el-form-item> <el-input
<el-button type="primary" @click="loadCustomerResourceChangesList()">{{ t('search') }}</el-button> v-model="customerResourceChangesTable.searchParam.operator_id"
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> :placeholder="t('operatorIdPlaceholder')"
</el-form-item> />
</el-form> </el-form-item>
</el-card> <el-form-item :label="t('campusId')" prop="campus_id">
<el-input
<div class="mt-[10px]"> v-model="customerResourceChangesTable.searchParam.campus_id"
<el-table :data="customerResourceChangesTable.data" size="large" v-loading="customerResourceChangesTable.loading"> :placeholder="t('campusIdPlaceholder')"
<template #empty> />
<span>{{ !customerResourceChangesTable.loading ? t('emptyData') : '' }}</span> </el-form-item>
</template> <el-form-item :label="t('modifiedFields')" prop="modified_fields">
<el-table-column prop="customer_resource_id" :label="t('customerResourceId')" min-width="120" :show-overflow-tooltip="true"/> <el-input
v-model="customerResourceChangesTable.searchParam.modified_fields"
<el-table-column prop="operator_id" :label="t('operatorId')" min-width="120" :show-overflow-tooltip="true"/> :placeholder="t('modifiedFieldsPlaceholder')"
/>
<el-table-column prop="campus_id" :label="t('campusId')" min-width="120" :show-overflow-tooltip="true"/> </el-form-item>
<el-form-item :label="t('oldValues')" prop="old_values">
<el-table-column prop="modified_fields" :label="t('modifiedFields')" min-width="120" :show-overflow-tooltip="true"/> <el-input
v-model="customerResourceChangesTable.searchParam.old_values"
<el-table-column prop="old_values" :label="t('oldValues')" min-width="120" :show-overflow-tooltip="true"/> :placeholder="t('oldValuesPlaceholder')"
/>
<el-table-column prop="new_values" :label="t('newValues')" min-width="120" :show-overflow-tooltip="true"/> </el-form-item>
<el-form-item :label="t('newValues')" prop="new_values">
<el-table-column :label="t('operation')" fixed="right" min-width="120"> <el-input
<template #default="{ row }"> v-model="customerResourceChangesTable.searchParam.new_values"
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button> :placeholder="t('newValuesPlaceholder')"
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button> />
</template> </el-form-item>
</el-table-column>
<el-form-item>
</el-table> <el-button
<div class="mt-[16px] flex justify-end"> type="primary"
<el-pagination v-model:current-page="customerResourceChangesTable.page" v-model:page-size="customerResourceChangesTable.limit" @click="loadCustomerResourceChangesList()"
layout="total, sizes, prev, pager, next, jumper" :total="customerResourceChangesTable.total" >{{ t('search') }}</el-button
@size-change="loadCustomerResourceChangesList()" @current-change="loadCustomerResourceChangesList" /> >
</div> <el-button @click="resetForm(searchFormRef)">{{
</div> t('reset')
}}</el-button>
<edit ref="editCustomerResourceChangesDialog" @complete="loadCustomerResourceChangesList" /> </el-form-item>
</el-card> </el-form>
</div> </el-card>
</template>
<div class="mt-[10px]">
<script lang="ts" setup> <el-table
import { reactive, ref, watch } from 'vue' :data="customerResourceChangesTable.data"
import { t } from '@/lang' size="large"
import { useDictionary } from '@/app/api/dict' v-loading="customerResourceChangesTable.loading"
import { getCustomerResourceChangesList, deleteCustomerResourceChanges } from '@/app/api/customer_resource_changes' >
import { img } from '@/utils/common' <template #empty>
import { ElMessageBox,FormInstance } from 'element-plus' <span>{{
import Edit from '@/app/views/customer_resource_changes/components/customer-resource-changes-edit.vue' !customerResourceChangesTable.loading ? t('emptyData') : ''
import { useRoute } from 'vue-router' }}</span>
const route = useRoute() </template>
const pageName = route.meta.title; <el-table-column
prop="customer_resource_id"
let customerResourceChangesTable = reactive({ :label="t('customerResourceId')"
page: 1, min-width="120"
limit: 10, :show-overflow-tooltip="true"
total: 0, />
loading: true,
data: [], <el-table-column
searchParam:{ prop="operator_id"
"customer_resource_id":"", :label="t('operatorId')"
"operator_id":"", min-width="120"
"campus_id":"", :show-overflow-tooltip="true"
"modified_fields":"", />
"old_values":"",
"new_values":"" <el-table-column
} prop="campus_id"
}) :label="t('campusId')"
min-width="120"
const searchFormRef = ref<FormInstance>() :show-overflow-tooltip="true"
/>
//
const selectData = ref<any[]>([]) <el-table-column
prop="modified_fields"
// :label="t('modifiedFields')"
min-width="120"
:show-overflow-tooltip="true"
/** />
* 获取客户资源表变更记录列表
*/ <el-table-column
const loadCustomerResourceChangesList = (page: number = 1) => { prop="old_values"
customerResourceChangesTable.loading = true :label="t('oldValues')"
customerResourceChangesTable.page = page min-width="120"
:show-overflow-tooltip="true"
getCustomerResourceChangesList({ />
page: customerResourceChangesTable.page,
limit: customerResourceChangesTable.limit, <el-table-column
...customerResourceChangesTable.searchParam prop="new_values"
}).then(res => { :label="t('newValues')"
customerResourceChangesTable.loading = false min-width="120"
customerResourceChangesTable.data = res.data.data :show-overflow-tooltip="true"
customerResourceChangesTable.total = res.data.total />
}).catch(() => {
customerResourceChangesTable.loading = false <el-table-column
}) :label="t('operation')"
} fixed="right"
loadCustomerResourceChangesList() min-width="120"
>
const editCustomerResourceChangesDialog: Record<string, any> | null = ref(null) <template #default="{ row }">
<el-button type="primary" link @click="editEvent(row)">{{
/** t('edit')
* 添加客户资源表变更记录 }}</el-button>
*/ <el-button type="primary" link @click="deleteEvent(row.id)">{{
const addEvent = () => { t('delete')
editCustomerResourceChangesDialog.value.setFormData() }}</el-button>
editCustomerResourceChangesDialog.value.showDialog = true </template>
} </el-table-column>
</el-table>
/** <div class="mt-[16px] flex justify-end">
* 编辑客户资源表变更记录 <el-pagination
* @param data v-model:current-page="customerResourceChangesTable.page"
*/ v-model:page-size="customerResourceChangesTable.limit"
const editEvent = (data: any) => { layout="total, sizes, prev, pager, next, jumper"
editCustomerResourceChangesDialog.value.setFormData(data) :total="customerResourceChangesTable.total"
editCustomerResourceChangesDialog.value.showDialog = true @size-change="loadCustomerResourceChangesList()"
} @current-change="loadCustomerResourceChangesList"
/>
/** </div>
* 删除客户资源表变更记录 </div>
*/
const deleteEvent = (id: number) => { <edit
ElMessageBox.confirm(t('customerResourceChangesDeleteTips'), t('warning'), ref="editCustomerResourceChangesDialog"
{ @complete="loadCustomerResourceChangesList"
confirmButtonText: t('confirm'), />
cancelButtonText: t('cancel'), </el-card>
type: 'warning', </div>
} </template>
).then(() => {
deleteCustomerResourceChanges(id).then(() => { <script lang="ts" setup>
loadCustomerResourceChangesList() import { reactive, ref, watch } from 'vue'
}).catch(() => { import { t } from '@/lang'
}) import { useDictionary } from '@/app/api/dict'
}) import {
} getCustomerResourceChangesList,
deleteCustomerResourceChanges,
} from '@/app/api/customer_resource_changes'
import { img } from '@/utils/common'
const resetForm = (formEl: FormInstance | undefined) => { import { ElMessageBox, FormInstance } from 'element-plus'
if (!formEl) return import Edit from '@/app/views/customer_resource_changes/components/customer-resource-changes-edit.vue'
formEl.resetFields() import { useRoute } from 'vue-router'
loadCustomerResourceChangesList() const route = useRoute()
} const pageName = route.meta.title
</script>
let customerResourceChangesTable = reactive({
<style lang="scss" scoped> page: 1,
/* 多行超出隐藏 */ limit: 10,
.multi-hidden { total: 0,
word-break: break-all; loading: true,
text-overflow: ellipsis; data: [],
overflow: hidden; searchParam: {
display: -webkit-box; customer_resource_id: '',
-webkit-line-clamp: 2; operator_id: '',
-webkit-box-orient: vertical; campus_id: '',
} modified_fields: '',
</style> old_values: '',
new_values: '',
},
})
const searchFormRef = ref<FormInstance>()
//
const selectData = ref<any[]>([])
//
/**
* 获取客户资源表变更记录列表
*/
const loadCustomerResourceChangesList = (page: number = 1) => {
customerResourceChangesTable.loading = true
customerResourceChangesTable.page = page
getCustomerResourceChangesList({
page: customerResourceChangesTable.page,
limit: customerResourceChangesTable.limit,
...customerResourceChangesTable.searchParam,
})
.then((res) => {
customerResourceChangesTable.loading = false
customerResourceChangesTable.data = res.data.data
customerResourceChangesTable.total = res.data.total
})
.catch(() => {
customerResourceChangesTable.loading = false
})
}
loadCustomerResourceChangesList()
const editCustomerResourceChangesDialog: Record<string, any> | null = ref(null)
/**
* 添加客户资源表变更记录
*/
const addEvent = () => {
editCustomerResourceChangesDialog.value.setFormData()
editCustomerResourceChangesDialog.value.showDialog = true
}
/**
* 编辑客户资源表变更记录
* @param data
*/
const editEvent = (data: any) => {
editCustomerResourceChangesDialog.value.setFormData(data)
editCustomerResourceChangesDialog.value.showDialog = true
}
/**
* 删除客户资源表变更记录
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('customerResourceChangesDeleteTips'), t('warning'), {
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}).then(() => {
deleteCustomerResourceChanges(id)
.then(() => {
loadCustomerResourceChangesList()
})
.catch(() => {})
})
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadCustomerResourceChangesList()
}
</script>
<style lang="scss" scoped>
/* 多行超出隐藏 */
.multi-hidden {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
</style>

960
admin/src/app/views/customer_resources/components/customer-resources-edit.vue

@ -1,409 +1,553 @@
<template> <template>
<el-dialog v-model="showDialog" :title="formData.id ? t('updateCustomerResources') : t('addCustomerResources')" width="50%" class="diy-dialog-wrap" :destroy-on-close="true"> <el-dialog
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading"> v-model="showDialog"
<el-form-item :label="t('source')" prop="source"> :title="
<el-select class="input-width" v-model="formData.source" clearable :placeholder="t('sourcePlaceholder')"> formData.id ? t('updateCustomerResources') : t('addCustomerResources')
<el-option label="请选择" value=""></el-option> "
<el-option width="50%"
v-for="(item, index) in sourceList" class="diy-dialog-wrap"
:key="index" :destroy-on-close="true"
:label="item.name" >
:value="item.value" <el-form
/> :model="formData"
</el-select> label-width="120px"
</el-form-item> ref="formRef"
:rules="formRules"
<el-form-item :label="t('sourceChannel')" v-if="formData.source == 1"> class="page-form"
<el-select class="input-width" v-model="formData.source_channel" clearable :placeholder="t('sourceChannelPlaceholder')"> v-loading="loading"
<el-option label="请选择" value=""></el-option> >
<el-option <el-form-item :label="t('source')" prop="source">
v-for="(item, index) in source_channelList" <el-select
:key="index" class="input-width"
:label="item.name" v-model="formData.source"
:value="item.value" clearable
/> :placeholder="t('sourcePlaceholder')"
</el-select> >
</el-form-item> <el-option label="请选择" value=""></el-option>
<el-option
<el-form-item :label="t('name')" prop="name"> v-for="(item, index) in sourceList"
<el-input v-model="formData.name" clearable :placeholder="t('namePlaceholder')" class="input-width" /> :key="index"
</el-form-item> :label="item.name"
:value="item.value"
<el-form-item :label="t('age')" prop="age"> />
<el-input-number v-model="formData.age" clearable :placeholder="t('agePlaceholder')" class="input-width" :min = "3" :max = "80" /> </el-select>
</el-form-item> </el-form-item>
<el-form-item :label="t('gender')" prop="gender"> <el-form-item :label="t('sourceChannel')" v-if="formData.source == 1">
<el-select class="input-width" v-model="formData.gender" clearable :placeholder="t('genderPlaceholder')"> <el-select
<el-option label="请选择" value=""></el-option> class="input-width"
<el-option v-model="formData.source_channel"
v-for="(item, index) in genderList" clearable
:key="index" :placeholder="t('sourceChannelPlaceholder')"
:label="item.name" >
:value="item.value" <el-option label="请选择" value=""></el-option>
/> <el-option
</el-select> v-for="(item, index) in source_channelList"
</el-form-item> :key="index"
:label="item.name"
<el-form-item :label="t('phoneNumber')" prop="phone_number"> :value="item.value"
<el-input v-model="formData.phone_number" clearable :placeholder="t('phoneNumberPlaceholder')" class="input-width" /> />
</el-form-item> </el-select>
</el-form-item>
<el-form-item :label="t('demand')" prop="demand">
<el-input v-model="formData.demand" type="textarea" rows="4" clearable :placeholder="t('demandPlaceholder')" class="input-width"/> <el-form-item :label="t('name')" prop="name">
</el-form-item> <el-input
<el-form-item :label="t('purchasingPower')" prop="purchasing_power"> v-model="formData.name"
<el-select class="input-width" v-model="formData.purchasing_power" clearable :placeholder="t('purchasingPowerPlaceholder')"> clearable
<el-option label="请选择" value=""></el-option> :placeholder="t('namePlaceholder')"
<el-option class="input-width"
v-for="(item, index) in purchasing_powerList" />
:key="index" </el-form-item>
:label="item.name"
:value="item.value" <el-form-item :label="t('age')" prop="age">
/> <el-input-number
</el-select> v-model="formData.age"
</el-form-item> clearable
:placeholder="t('agePlaceholder')"
<el-form-item :label="t('cognitiveIdea')" prop="cognitive_idea"> class="input-width"
<el-select class="input-width" v-model="formData.cognitive_idea" clearable :placeholder="t('cognitiveIdeaPlaceholder')"> :min="3"
<el-option label="请选择" value=""></el-option> :max="80"
<el-option />
v-for="(item, index) in cognitive_ideaList" </el-form-item>
:key="index"
:label="item.name" <el-form-item :label="t('gender')" prop="gender">
:value="item.value" <el-select
/> class="input-width"
</el-select> v-model="formData.gender"
</el-form-item> clearable
:placeholder="t('genderPlaceholder')"
<el-form-item :label="t('optionalClassTime')" prop="optional_class_time" class="input-width"> >
<el-date-picker <el-option label="请选择" value=""></el-option>
class="flex-1 !flex" <el-option
v-model="formData.optional_class_time" v-for="(item, index) in genderList"
clearable :key="index"
type="datetime" :label="item.name"
value-format="YYYY-MM-DD HH:mm:ss" :value="item.value"
:placeholder="t('optionalClassTimePlaceholder')"> />
</el-date-picker> </el-select>
</el-form-item> </el-form-item>
<el-form-item :label="t('distance')" prop="distance">
<el-input v-model="formData.distance" clearable :placeholder="t('distancePlaceholder')" class="input-width" /> <el-form-item :label="t('phoneNumber')" prop="phone_number">
</el-form-item> <el-input
v-model="formData.phone_number"
<el-form-item :label="t('decisionMaker')" prop="decision_maker"> clearable
<el-input v-model="formData.decision_maker" clearable :placeholder="t('decisionMakerPlaceholder')" class="input-width" /> :placeholder="t('phoneNumberPlaceholder')"
</el-form-item> class="input-width"
/>
<el-form-item :label="t('initialIntent')" prop="initial_intent"> </el-form-item>
<el-select class="input-width" v-model="formData.initial_intent" clearable :placeholder="t('initialIntentPlaceholder')">
<el-option label="请选择" value=""></el-option> <el-form-item :label="t('demand')" prop="demand">
<el-option <el-input
v-for="(item, index) in initial_intentList" v-model="formData.demand"
:key="index" type="textarea"
:label="item.name" rows="4"
:value="item.value" clearable
/> :placeholder="t('demandPlaceholder')"
</el-select> class="input-width"
</el-form-item> />
</el-form-item>
<el-form-item :label="t('campus')" prop="campus"> <el-form-item :label="t('purchasingPower')" prop="purchasing_power">
<el-select class="input-width" v-model="formData.campus" clearable :placeholder="t('campusPlaceholder')"> <el-select
<el-option label="请选择" value=""></el-option> class="input-width"
<el-option v-model="formData.purchasing_power"
v-for="(item, index) in campusList" clearable
:key="index" :placeholder="t('purchasingPowerPlaceholder')"
:label="item['campus_name']" >
:value="item['campus_name']" <el-option label="请选择" value=""></el-option>
/> <el-option
</el-select> v-for="(item, index) in purchasing_powerList"
</el-form-item> :key="index"
:label="item.name"
<el-form-item :label="t('status')" prop="status"> :value="item.value"
<el-select class="input-width" v-model="formData.status" clearable :placeholder="t('statusPlaceholder')"> />
<el-option label="请选择" value=""></el-option> </el-select>
<el-option </el-form-item>
v-for="(item, index) in statusList"
:key="index" <el-form-item :label="t('cognitiveIdea')" prop="cognitive_idea">
:label="item.name" <el-select
:value="item.value" class="input-width"
/> v-model="formData.cognitive_idea"
</el-select> clearable
</el-form-item> :placeholder="t('cognitiveIdeaPlaceholder')"
>
</el-form> <el-option label="请选择" value=""></el-option>
<el-option
<template #footer> v-for="(item, index) in cognitive_ideaList"
<span class="dialog-footer"> :key="index"
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button> :label="item.name"
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{ :value="item.value"
t('confirm') />
}}</el-button> </el-select>
</span> </el-form-item>
</template>
</el-dialog> <el-form-item
</template> :label="t('optionalClassTime')"
prop="optional_class_time"
<script lang="ts" setup> class="input-width"
import { ref, reactive, computed, watch } from 'vue' >
import { useDictionary } from '@/app/api/dict' <el-date-picker
import { t } from '@/lang' class="flex-1 !flex"
import type { FormInstance } from 'element-plus' v-model="formData.optional_class_time"
import { addCustomerResources, editCustomerResources, getCustomerResourcesInfo, getWithCampusList } from '@/app/api/customer_resources' clearable
type="datetime"
let showDialog = ref(false) value-format="YYYY-MM-DD HH:mm:ss"
const loading = ref(false) :placeholder="t('optionalClassTimePlaceholder')"
>
/** </el-date-picker>
* 表单数据 </el-form-item>
*/ <el-form-item :label="t('distance')" prop="distance">
const initialFormData = { <el-input
id: '', v-model="formData.distance"
source: '', clearable
source_channel: '', :placeholder="t('distancePlaceholder')"
name: '', class="input-width"
age: '', />
gender: '', </el-form-item>
phone_number: '',
demand: '', <el-form-item :label="t('decisionMaker')" prop="decision_maker">
purchasing_power: '', <el-input
cognitive_idea: '', v-model="formData.decision_maker"
optional_class_time: '', clearable
distance: '', :placeholder="t('decisionMakerPlaceholder')"
decision_maker: '', class="input-width"
initial_intent: '', />
campus: '', </el-form-item>
status: '',
} <el-form-item :label="t('initialIntent')" prop="initial_intent">
const formData: Record<string, any> = reactive({ ...initialFormData }) <el-select
class="input-width"
const formRef = ref<FormInstance>() v-model="formData.initial_intent"
clearable
// :placeholder="t('initialIntentPlaceholder')"
const formRules = computed(() => { >
return { <el-option label="请选择" value=""></el-option>
source: [ <el-option
{ required: true, message: t('sourcePlaceholder'), trigger: 'blur' }, v-for="(item, index) in initial_intentList"
:key="index"
] :label="item.name"
, :value="item.value"
source_channel: [ />
{ required: true, message: t('sourceChannelPlaceholder'), trigger: 'blur' }, </el-select>
</el-form-item>
]
, <el-form-item :label="t('campus')" prop="campus">
name: [ <el-select
{ required: true, message: t('namePlaceholder'), trigger: 'blur' }, class="input-width"
v-model="formData.campus"
] clearable
, :placeholder="t('campusPlaceholder')"
age: [ >
{ required: true, message: t('agePlaceholder'), trigger: 'blur' }, <el-option label="请选择" value=""></el-option>
{ <el-option
validator: (rule: any, value: number, callback: any) => { v-for="(item, index) in campusList"
if (value === undefined || value === null || value === '') { :key="index"
callback(); :label="item['campus_name']"
} else if (value < 3 || value > 80) { :value="item['campus_name']"
callback(new Error(t('generateBetween'))); />
} else { </el-select>
callback(); </el-form-item>
}
}, <el-form-item :label="t('status')" prop="status">
trigger: 'blur' <el-select
class="input-width"
v-model="formData.status"
clearable
:placeholder="t('statusPlaceholder')"
>
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in statusList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
<el-button
type="primary"
:loading="loading"
@click="confirm(formRef)"
>{{ t('confirm') }}</el-button
>
</span>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import { ref, reactive, computed, watch } from 'vue'
import { useDictionary } from '@/app/api/dict'
import { t } from '@/lang'
import type { FormInstance } from 'element-plus'
import {
addCustomerResources,
editCustomerResources,
getCustomerResourcesInfo,
getWithCampusList,
} from '@/app/api/customer_resources'
let showDialog = ref(false)
const loading = ref(false)
/**
* 表单数据
*/
const initialFormData = {
id: '',
source: '',
source_channel: '',
name: '',
age: '',
gender: '',
phone_number: '',
demand: '',
purchasing_power: '',
cognitive_idea: '',
optional_class_time: '',
distance: '',
decision_maker: '',
initial_intent: '',
campus: '',
status: '',
}
const formData: Record<string, any> = reactive({ ...initialFormData })
const formRef = ref<FormInstance>()
//
const formRules = computed(() => {
return {
source: [
{ required: true, message: t('sourcePlaceholder'), trigger: 'blur' },
],
source_channel: [
{
required: true,
message: t('sourceChannelPlaceholder'),
trigger: 'blur',
},
],
name: [{ required: true, message: t('namePlaceholder'), trigger: 'blur' }],
age: [
{ required: true, message: t('agePlaceholder'), trigger: 'blur' },
{
validator: (rule: any, value: number, callback: any) => {
if (value === undefined || value === null || value === '') {
callback()
} else if (value < 3 || value > 80) {
callback(new Error(t('generateBetween')))
} else {
callback()
}
},
trigger: 'blur',
},
],
gender: [
{ required: true, message: t('genderPlaceholder'), trigger: 'blur' },
],
phone_number: [
{ required: true, message: t('phoneNumberPlaceholder'), trigger: 'blur' },
],
demand: [
{ required: true, message: t('demandPlaceholder'), trigger: 'blur' },
],
purchasing_power: [
{
required: true,
message: t('purchasingPowerPlaceholder'),
trigger: 'blur',
},
],
cognitive_idea: [
{
required: true,
message: t('cognitiveIdeaPlaceholder'),
trigger: 'blur',
},
],
optional_class_time: [
{
required: true,
message: t('optionalClassTimePlaceholder'),
trigger: 'blur',
},
],
distance: [
{ required: true, message: t('distancePlaceholder'), trigger: 'blur' },
],
decision_maker: [
{
required: true,
message: t('decisionMakerPlaceholder'),
trigger: 'blur',
},
],
initial_intent: [
{
required: true,
message: t('initialIntentPlaceholder'),
trigger: 'blur',
},
],
campus: [
{ required: true, message: t('campusPlaceholder'), trigger: 'blur' },
],
status: [
{ required: true, message: t('statusPlaceholder'), trigger: 'blur' },
],
} }
] })
,
gender: [ const emit = defineEmits(['complete'])
{ required: true, message: t('genderPlaceholder'), trigger: 'blur' },
/**
] * 确认
, * @param formEl
phone_number: [ */
{ required: true, message: t('phoneNumberPlaceholder'), trigger: 'blur' }, const confirm = async (formEl: FormInstance | undefined) => {
if (loading.value || !formEl) return
] let save = formData.id ? editCustomerResources : addCustomerResources
,
demand: [ await formEl.validate(async (valid) => {
{ required: true, message: t('demandPlaceholder'), trigger: 'blur' }, if (valid) {
loading.value = true
]
, let data = formData
purchasing_power: [
{ required: true, message: t('purchasingPowerPlaceholder'), trigger: 'blur' }, save(data)
.then((res) => {
] loading.value = false
, showDialog.value = false
cognitive_idea: [ emit('complete')
{ required: true, message: t('cognitiveIdeaPlaceholder'), trigger: 'blur' }, })
.catch((err) => {
] loading.value = false
, })
optional_class_time: [ }
{ required: true, message: t('optionalClassTimePlaceholder'), trigger: 'blur' }, })
}
]
, //
distance: [ let sourceList = ref([])
{ required: true, message: t('distancePlaceholder'), trigger: 'blur' }, const sourceDictList = async () => {
sourceList.value = await (await useDictionary('source')).data.dictionary
] }
, sourceDictList()
decision_maker: [ watch(
{ required: true, message: t('decisionMakerPlaceholder'), trigger: 'blur' }, () => sourceList.value,
() => {
] formData.source = sourceList.value[0].value
, }
initial_intent: [ )
{ required: true, message: t('initialIntentPlaceholder'), trigger: 'blur' }, let source_channelList = ref([])
const source_channelDictList = async () => {
] source_channelList.value = await (
, await useDictionary('SourceChannel')
campus: [ ).data.dictionary
{ required: true, message: t('campusPlaceholder'), trigger: 'blur' }, }
source_channelDictList()
] watch(
, () => source_channelList.value,
status: [ () => {
{ required: true, message: t('statusPlaceholder'), trigger: 'blur' }, formData.source_channel = source_channelList.value[0].value
}
] )
, let genderList = ref([])
} const genderDictList = async () => {
}) genderList.value = await (await useDictionary('zy_sex')).data.dictionary
}
const emit = defineEmits(['complete']) genderDictList()
watch(
/** () => genderList.value,
* 确认 () => {
* @param formEl formData.gender = genderList.value[0].value
*/ }
const confirm = async (formEl: FormInstance | undefined) => { )
if (loading.value || !formEl) return let purchasing_powerList = ref([])
let save = formData.id ? editCustomerResources : addCustomerResources const purchasing_powerDictList = async () => {
purchasing_powerList.value = await (
await formEl.validate(async (valid) => { await useDictionary('customer_purchasing_power')
if (valid) { ).data.dictionary
loading.value = true }
purchasing_powerDictList()
let data = formData watch(
() => purchasing_powerList.value,
save(data).then(res => { () => {
loading.value = false formData.purchasing_power = purchasing_powerList.value[0].value
showDialog.value = false }
emit('complete') )
}).catch(err => { let cognitive_ideaList = ref([])
loading.value = false const cognitive_ideaDictList = async () => {
}) cognitive_ideaList.value = await (
} await useDictionary('cognitive_concept')
}) ).data.dictionary
} }
cognitive_ideaDictList()
// watch(
let sourceList = ref([]) () => cognitive_ideaList.value,
const sourceDictList = async () => { () => {
sourceList.value = await (await useDictionary('source')).data.dictionary formData.cognitive_idea = cognitive_ideaList.value[0].value
} }
sourceDictList(); )
watch(() => sourceList.value, () => { formData.source = sourceList.value[0].value }) let initial_intentList = ref([])
let source_channelList = ref([]) const initial_intentDictList = async () => {
const source_channelDictList = async () => { initial_intentList.value = await (
source_channelList.value = await (await useDictionary('SourceChannel')).data.dictionary await useDictionary('preliminarycustomerintention')
} ).data.dictionary
source_channelDictList(); }
watch(() => source_channelList.value, () => { formData.source_channel = source_channelList.value[0].value }) initial_intentDictList()
let genderList = ref([]) watch(
const genderDictList = async () => { () => initial_intentList.value,
genderList.value = await (await useDictionary('zy_sex')).data.dictionary () => {
} formData.initial_intent = initial_intentList.value[0].value
genderDictList(); }
watch(() => genderList.value, () => { formData.gender = genderList.value[0].value }) )
let purchasing_powerList = ref([]) let statusList = ref([])
const purchasing_powerDictList = async () => { const statusDictList = async () => {
purchasing_powerList.value = await (await useDictionary('customer_purchasing_power')).data.dictionary statusList.value = await (await useDictionary('kh_status')).data.dictionary
} }
purchasing_powerDictList(); statusDictList()
watch(() => purchasing_powerList.value, () => { formData.purchasing_power = purchasing_powerList.value[0].value }) watch(
let cognitive_ideaList = ref([]) () => statusList.value,
const cognitive_ideaDictList = async () => { () => {
cognitive_ideaList.value = await (await useDictionary('cognitive_concept')).data.dictionary formData.status = statusList.value[0].value
} }
cognitive_ideaDictList(); )
watch(() => cognitive_ideaList.value, () => { formData.cognitive_idea = cognitive_ideaList.value[0].value })
let initial_intentList = ref([]) const campusList = ref([] as any[])
const initial_intentDictList = async () => { const setCampusList = async () => {
initial_intentList.value = await (await useDictionary('preliminarycustomerintention')).data.dictionary campusList.value = await (await getWithCampusList({})).data
} }
initial_intentDictList(); setCampusList()
watch(() => initial_intentList.value, () => { formData.initial_intent = initial_intentList.value[0].value }) const setFormData = async (row: any = null) => {
let statusList = ref([]) Object.assign(formData, initialFormData)
const statusDictList = async () => { loading.value = true
statusList.value = await (await useDictionary('kh_status')).data.dictionary if (row) {
} const data = await (await getCustomerResourcesInfo(row.id)).data
statusDictList(); if (data)
watch(() => statusList.value, () => { formData.status = statusList.value[0].value }) Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key]
})
const campusList = ref([] as any[]) }
const setCampusList = async () => { loading.value = false
campusList.value = await (await getWithCampusList({})).data }
}
setCampusList() //
const setFormData = async (row: any = null) => { const mobileVerify = (rule: any, value: any, callback: any) => {
Object.assign(formData, initialFormData) if (value && !/^1[3-9]\d{9}$/.test(value)) {
loading.value = true callback(new Error(t('generateMobile')))
if(row){ } else {
const data = await (await getCustomerResourcesInfo(row.id)).data callback()
if (data) Object.keys(formData).forEach((key: string) => { }
if (data[key] != undefined) formData[key] = data[key] }
})
} //
loading.value = false const idCardVerify = (rule: any, value: any, callback: any) => {
} if (
value &&
// !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
const mobileVerify = (rule: any, value: any, callback: any) => { value
if (value && !/^1[3-9]\d{9}$/.test(value)) { )
callback(new Error(t('generateMobile'))) ) {
} else { callback(new Error(t('generateIdCard')))
callback() } else {
} callback()
} }
}
//
const idCardVerify = (rule: any, value: any, callback: any) => { //
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) { const emailVerify = (rule: any, value: any, callback: any) => {
callback(new Error(t('generateIdCard'))) if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
} else { callback(new Error(t('generateEmail')))
callback() } else {
} callback()
} }
}
//
const emailVerify = (rule: any, value: any, callback: any) => { //
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) { const numberVerify = (rule: any, value: any, callback: any) => {
callback(new Error(t('generateEmail'))) if (!Number.isInteger(value)) {
} else { callback(new Error(t('generateNumber')))
callback() } else {
} callback()
} }
}
//
const numberVerify = (rule: any, value: any, callback: any) => { defineExpose({
if (!Number.isInteger(value)) { showDialog,
callback(new Error(t('generateNumber'))) setFormData,
} else { })
callback() </script>
}
} <style lang="scss" scoped></style>
<style lang="scss">
defineExpose({ .diy-dialog-wrap .el-form-item__label {
showDialog, height: auto !important;
setFormData }
}) </style>
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.diy-dialog-wrap .el-form-item__label{
height: auto !important;
}
</style>

537
admin/src/app/views/customer_resources/customer_resources.vue

@ -1,226 +1,311 @@
<template> <template>
<div class="main-container"> <div class="main-container">
<el-card class="box-card !border-none" shadow="never"> <el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<div class="flex justify-between items-center"> <span class="text-lg">{{ pageName }}</span>
<span class="text-lg">{{pageName}}</span> <el-button type="primary" @click="addEvent">
<el-button type="primary" @click="addEvent"> {{ t('addCustomerResources') }}
{{ t('addCustomerResources') }} </el-button>
</el-button> </div>
</div>
<el-card
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> class="box-card !border-none my-[10px] table-search-wrap"
<el-form :inline="true" :model="customerResourcesTable.searchParam" ref="searchFormRef"> shadow="never"
<el-form-item :label="t('name')" prop="name"> >
<el-input v-model="customerResourcesTable.searchParam.name" :placeholder="t('namePlaceholder')" /> <el-form
</el-form-item> :inline="true"
<el-form-item :label="t('phoneNumber')" prop="phone_number"> :model="customerResourcesTable.searchParam"
<el-input v-model="customerResourcesTable.searchParam.phone_number" :placeholder="t('phoneNumberPlaceholder')" /> ref="searchFormRef"
</el-form-item> >
<el-form-item> <el-form-item :label="t('name')" prop="name">
<el-button type="primary" @click="loadCustomerResourcesList()">{{ t('search') }}</el-button> <el-input
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> v-model="customerResourcesTable.searchParam.name"
</el-form-item> :placeholder="t('namePlaceholder')"
</el-form> />
</el-card> </el-form-item>
<el-form-item :label="t('phoneNumber')" prop="phone_number">
<div class="mt-[10px]"> <el-input
<el-table :data="customerResourcesTable.data" size="large" v-loading="customerResourcesTable.loading"> v-model="customerResourcesTable.searchParam.phone_number"
<template #empty> :placeholder="t('phoneNumberPlaceholder')"
<span>{{ !customerResourcesTable.loading ? t('emptyData') : '' }}</span> />
</template> </el-form-item>
<el-table-column :label="t('source')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }"> <el-form-item>
<div v-for="(item, index) in sourceList"> <el-button type="primary" @click="loadCustomerResourcesList()">{{
<div v-if="item.value == row.source">{{ item.name }}</div> t('search')
</div> }}</el-button>
</template> <el-button @click="resetForm(searchFormRef)">{{
</el-table-column> t('reset')
}}</el-button>
<el-table-column prop="consultant" :label="t('consultant')" min-width="120" :show-overflow-tooltip="true"/> </el-form-item>
</el-form>
<el-table-column prop="name" :label="t('name')" min-width="120" :show-overflow-tooltip="true"/> </el-card>
<el-table-column prop="age" :label="t('age')" min-width="120" :show-overflow-tooltip="true"/> <div class="mt-[10px]">
<el-table
<el-table-column :label="t('gender')" min-width="180" align="center" :show-overflow-tooltip="true"> :data="customerResourcesTable.data"
<template #default="{ row }"> size="large"
<div v-for="(item, index) in genderList"> v-loading="customerResourcesTable.loading"
<div v-if="item.value == row.gender">{{ item.name }}</div> >
</div> <template #empty>
</template> <span>{{
</el-table-column> !customerResourcesTable.loading ? t('emptyData') : ''
}}</span>
<el-table-column prop="phone_number" :label="t('phoneNumber')" min-width="120" :show-overflow-tooltip="true"/> </template>
<el-table-column
<el-table-column prop="decision_maker" :label="t('decisionMaker')" min-width="120" :show-overflow-tooltip="true"/> :label="t('source')"
min-width="180"
<el-table-column :label="t('operation')" fixed="right" min-width="120"> align="center"
<template #default="{ row }"> :show-overflow-tooltip="true"
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button> >
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button> <template #default="{ row }">
</template> <div v-for="(item, index) in sourceList">
</el-table-column> <div v-if="item.value == row.source">{{ item.name }}</div>
</div>
</el-table> </template>
<div class="mt-[16px] flex justify-end"> </el-table-column>
<el-pagination v-model:current-page="customerResourcesTable.page" v-model:page-size="customerResourcesTable.limit"
layout="total, sizes, prev, pager, next, jumper" :total="customerResourcesTable.total" <el-table-column
@size-change="loadCustomerResourcesList()" @current-change="loadCustomerResourcesList" /> prop="consultant"
</div> :label="t('consultant')"
</div> min-width="120"
:show-overflow-tooltip="true"
<edit ref="editCustomerResourcesDialog" @complete="loadCustomerResourcesList" /> />
</el-card>
</div> <el-table-column
</template> prop="name"
:label="t('name')"
<script lang="ts" setup> min-width="120"
import { reactive, ref, watch } from 'vue' :show-overflow-tooltip="true"
import { t } from '@/lang' />
import { useDictionary } from '@/app/api/dict'
import { getCustomerResourcesList, deleteCustomerResources, getWithCampusList } from '@/app/api/customer_resources' <el-table-column
import { img } from '@/utils/common' prop="age"
import { ElMessageBox,FormInstance } from 'element-plus' :label="t('age')"
import Edit from '@/app/views/customer_resources/components/customer-resources-edit.vue' min-width="120"
import { useRoute } from 'vue-router' :show-overflow-tooltip="true"
const route = useRoute() />
const pageName = route.meta.title;
<el-table-column
let customerResourcesTable = reactive({ :label="t('gender')"
page: 1, min-width="180"
limit: 10, align="center"
total: 0, :show-overflow-tooltip="true"
loading: true, >
data: [], <template #default="{ row }">
searchParam:{ <div v-for="(item, index) in genderList">
"name":"", <div v-if="item.value == row.gender">{{ item.name }}</div>
"phone_number":"" </div>
} </template>
}) </el-table-column>
const searchFormRef = ref<FormInstance>() <el-table-column
prop="phone_number"
// :label="t('phoneNumber')"
const selectData = ref<any[]>([]) min-width="120"
:show-overflow-tooltip="true"
// />
const sourceList = ref([] as any[])
const sourceDictList = async () => { <el-table-column
sourceList.value = await (await useDictionary('source')).data.dictionary prop="decision_maker"
} :label="t('decisionMaker')"
sourceDictList(); min-width="120"
const source_channelList = ref([] as any[]) :show-overflow-tooltip="true"
const source_channelDictList = async () => { />
source_channelList.value = await (await useDictionary('SourceChannel')).data.dictionary
} <el-table-column
source_channelDictList(); :label="t('operation')"
const genderList = ref([] as any[]) fixed="right"
const genderDictList = async () => { min-width="120"
genderList.value = await (await useDictionary('zy_sex')).data.dictionary >
} <template #default="{ row }">
genderDictList(); <el-button type="primary" link @click="editEvent(row)">{{
const purchasing_powerList = ref([] as any[]) t('edit')
const purchasing_powerDictList = async () => { }}</el-button>
purchasing_powerList.value = await (await useDictionary('customer_purchasing_power')).data.dictionary <el-button type="primary" link @click="deleteEvent(row.id)">{{
} t('delete')
purchasing_powerDictList(); }}</el-button>
const cognitive_ideaList = ref([] as any[]) </template>
const cognitive_ideaDictList = async () => { </el-table-column>
cognitive_ideaList.value = await (await useDictionary('cognitive_concept')).data.dictionary </el-table>
} <div class="mt-[16px] flex justify-end">
cognitive_ideaDictList(); <el-pagination
const initial_intentList = ref([] as any[]) v-model:current-page="customerResourcesTable.page"
const initial_intentDictList = async () => { v-model:page-size="customerResourcesTable.limit"
initial_intentList.value = await (await useDictionary('preliminarycustomerintention')).data.dictionary layout="total, sizes, prev, pager, next, jumper"
} :total="customerResourcesTable.total"
initial_intentDictList(); @size-change="loadCustomerResourcesList()"
const statusList = ref([] as any[]) @current-change="loadCustomerResourcesList"
const statusDictList = async () => { />
statusList.value = await (await useDictionary('kh_status')).data.dictionary </div>
} </div>
statusDictList();
<edit
/** ref="editCustomerResourcesDialog"
* 获取客户资源列表 @complete="loadCustomerResourcesList"
*/ />
const loadCustomerResourcesList = (page: number = 1) => { </el-card>
customerResourcesTable.loading = true </div>
customerResourcesTable.page = page </template>
getCustomerResourcesList({ <script lang="ts" setup>
page: customerResourcesTable.page, import { reactive, ref, watch } from 'vue'
limit: customerResourcesTable.limit, import { t } from '@/lang'
...customerResourcesTable.searchParam import { useDictionary } from '@/app/api/dict'
}).then(res => { import {
customerResourcesTable.loading = false getCustomerResourcesList,
customerResourcesTable.data = res.data.data deleteCustomerResources,
customerResourcesTable.total = res.data.total getWithCampusList,
}).catch(() => { } from '@/app/api/customer_resources'
customerResourcesTable.loading = false import { img } from '@/utils/common'
}) import { ElMessageBox, FormInstance } from 'element-plus'
} import Edit from '@/app/views/customer_resources/components/customer-resources-edit.vue'
loadCustomerResourcesList() import { useRoute } from 'vue-router'
const route = useRoute()
const editCustomerResourcesDialog: Record<string, any> | null = ref(null) const pageName = route.meta.title
/** let customerResourcesTable = reactive({
* 添加客户资源 page: 1,
*/ limit: 10,
const addEvent = () => { total: 0,
editCustomerResourcesDialog.value.setFormData() loading: true,
editCustomerResourcesDialog.value.showDialog = true data: [],
} searchParam: {
name: '',
/** phone_number: '',
* 编辑客户资源 },
* @param data })
*/
const editEvent = (data: any) => { const searchFormRef = ref<FormInstance>()
editCustomerResourcesDialog.value.setFormData(data)
editCustomerResourcesDialog.value.showDialog = true //
} const selectData = ref<any[]>([])
/** //
* 删除客户资源 const sourceList = ref([] as any[])
*/ const sourceDictList = async () => {
const deleteEvent = (id: number) => { sourceList.value = await (await useDictionary('source')).data.dictionary
ElMessageBox.confirm(t('customerResourcesDeleteTips'), t('warning'), }
{ sourceDictList()
confirmButtonText: t('confirm'), const source_channelList = ref([] as any[])
cancelButtonText: t('cancel'), const source_channelDictList = async () => {
type: 'warning', source_channelList.value = await (
} await useDictionary('SourceChannel')
).then(() => { ).data.dictionary
deleteCustomerResources(id).then(() => { }
loadCustomerResourcesList() source_channelDictList()
}).catch(() => { const genderList = ref([] as any[])
}) const genderDictList = async () => {
}) genderList.value = await (await useDictionary('zy_sex')).data.dictionary
} }
genderDictList()
const purchasing_powerList = ref([] as any[])
const campusList = ref([]) const purchasing_powerDictList = async () => {
const setCampusList = async () => { purchasing_powerList.value = await (
campusList.value = await (await getWithCampusList({})).data await useDictionary('customer_purchasing_power')
} ).data.dictionary
setCampusList() }
purchasing_powerDictList()
const resetForm = (formEl: FormInstance | undefined) => { const cognitive_ideaList = ref([] as any[])
if (!formEl) return const cognitive_ideaDictList = async () => {
formEl.resetFields() cognitive_ideaList.value = await (
loadCustomerResourcesList() await useDictionary('cognitive_concept')
} ).data.dictionary
</script> }
cognitive_ideaDictList()
<style lang="scss" scoped> const initial_intentList = ref([] as any[])
/* 多行超出隐藏 */ const initial_intentDictList = async () => {
.multi-hidden { initial_intentList.value = await (
word-break: break-all; await useDictionary('preliminarycustomerintention')
text-overflow: ellipsis; ).data.dictionary
overflow: hidden; }
display: -webkit-box; initial_intentDictList()
-webkit-line-clamp: 2; const statusList = ref([] as any[])
-webkit-box-orient: vertical; const statusDictList = async () => {
} statusList.value = await (await useDictionary('kh_status')).data.dictionary
</style> }
statusDictList()
/**
* 获取客户资源列表
*/
const loadCustomerResourcesList = (page: number = 1) => {
customerResourcesTable.loading = true
customerResourcesTable.page = page
getCustomerResourcesList({
page: customerResourcesTable.page,
limit: customerResourcesTable.limit,
...customerResourcesTable.searchParam,
})
.then((res) => {
customerResourcesTable.loading = false
customerResourcesTable.data = res.data.data
customerResourcesTable.total = res.data.total
})
.catch(() => {
customerResourcesTable.loading = false
})
}
loadCustomerResourcesList()
const editCustomerResourcesDialog: Record<string, any> | null = ref(null)
/**
* 添加客户资源
*/
const addEvent = () => {
editCustomerResourcesDialog.value.setFormData()
editCustomerResourcesDialog.value.showDialog = true
}
/**
* 编辑客户资源
* @param data
*/
const editEvent = (data: any) => {
editCustomerResourcesDialog.value.setFormData(data)
editCustomerResourcesDialog.value.showDialog = true
}
/**
* 删除客户资源
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('customerResourcesDeleteTips'), t('warning'), {
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}).then(() => {
deleteCustomerResources(id)
.then(() => {
loadCustomerResourcesList()
})
.catch(() => {})
})
}
const campusList = ref([])
const setCampusList = async () => {
campusList.value = await (await getWithCampusList({})).data
}
setCampusList()
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadCustomerResourcesList()
}
</script>
<style lang="scss" scoped>
/* 多行超出隐藏 */
.multi-hidden {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
</style>

242
admin/src/app/views/departments/components/departments-edit.vue

@ -1,33 +1,58 @@
<template> <template>
<el-dialog v-model="showDialog" :title="formData.id ? t('updateDepartments') : t('addDepartments')" width="50%" class="diy-dialog-wrap" :destroy-on-close="true"> <el-dialog
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading"> v-model="showDialog"
<el-form-item :label="t('departmentName')" prop="department_name"> :title="formData.id ? t('updateDepartments') : t('addDepartments')"
<el-input v-model="formData.department_name" clearable :placeholder="t('departmentNamePlaceholder')" class="input-width" /> width="50%"
</el-form-item> class="diy-dialog-wrap"
:destroy-on-close="true"
<el-form-item :label="t('parentDepartmentId')" > >
<el-select class="input-width" v-model="formData.parent_department_id" clearable :placeholder="t('parentDepartmentIdPlaceholder')"> <el-form
<el-option label="请选择" value=""></el-option> :model="formData"
<el-option label-width="120px"
v-for="(item, index) in parentDepartmentIdList" ref="formRef"
:key="index" :rules="formRules"
:label="item['department_name']" class="page-form"
:value="item['id']" v-loading="loading"
/> >
</el-select> <el-form-item :label="t('departmentName')" prop="department_name">
</el-form-item> <el-input
v-model="formData.department_name"
</el-form> clearable
:placeholder="t('departmentNamePlaceholder')"
<template #footer> class="input-width"
<span class="dialog-footer"> />
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button> </el-form-item>
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{
t('confirm') <el-form-item :label="t('parentDepartmentId')">
}}</el-button> <el-select
</span> class="input-width"
</template> v-model="formData.parent_department_id"
</el-dialog> clearable
:placeholder="t('parentDepartmentIdPlaceholder')"
>
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in parentDepartmentIdList"
:key="index"
:label="item['department_name']"
:value="item['id']"
/>
</el-select>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
<el-button
type="primary"
:loading="loading"
@click="confirm(formRef)"
>{{ t('confirm') }}</el-button
>
</span>
</template>
</el-dialog>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -35,7 +60,12 @@ import { ref, reactive, computed, watch } from 'vue'
import { useDictionary } from '@/app/api/dict' import { useDictionary } from '@/app/api/dict'
import { t } from '@/lang' import { t } from '@/lang'
import type { FormInstance } from 'element-plus' import type { FormInstance } from 'element-plus'
import { addDepartments, editDepartments, getDepartmentsInfo, getWithDepartmentsList } from '@/app/api/departments' import {
addDepartments,
editDepartments,
getDepartmentsInfo,
getWithDepartmentsList,
} from '@/app/api/departments'
let showDialog = ref(false) let showDialog = ref(false)
const loading = ref(false) const loading = ref(false)
@ -44,9 +74,9 @@ const loading = ref(false)
* 表单数据 * 表单数据
*/ */
const initialFormData = { const initialFormData = {
id: '', id: '',
department_name: '', department_name: '',
parent_department_id: '', parent_department_id: '',
} }
const formData: Record<string, any> = reactive({ ...initialFormData }) const formData: Record<string, any> = reactive({ ...initialFormData })
@ -54,18 +84,22 @@ const formRef = ref<FormInstance>()
// //
const formRules = computed(() => { const formRules = computed(() => {
return { return {
department_name: [ department_name: [
{ required: true, message: t('departmentNamePlaceholder'), trigger: 'blur' }, {
required: true,
] message: t('departmentNamePlaceholder'),
, trigger: 'blur',
},
],
parent_department_id: [ parent_department_id: [
{ required: true, message: t('parentDepartmentIdPlaceholder'), trigger: 'blur' }, {
required: true,
] message: t('parentDepartmentIdPlaceholder'),
trigger: 'blur',
} },
],
}
}) })
const emit = defineEmits(['complete']) const emit = defineEmits(['complete'])
@ -75,92 +109,98 @@ const emit = defineEmits(['complete'])
* @param formEl * @param formEl
*/ */
const confirm = async (formEl: FormInstance | undefined) => { const confirm = async (formEl: FormInstance | undefined) => {
if (loading.value || !formEl) return if (loading.value || !formEl) return
let save = formData.id ? editDepartments : addDepartments let save = formData.id ? editDepartments : addDepartments
await formEl.validate(async (valid) => { await formEl.validate(async (valid) => {
if (valid) { if (valid) {
loading.value = true loading.value = true
let data = formData let data = formData
save(data).then(res => { save(data)
loading.value = false .then((res) => {
showDialog.value = false loading.value = false
emit('complete') showDialog.value = false
}).catch(err => { emit('complete')
loading.value = false })
}) .catch((err) => {
} loading.value = false
}) })
}
})
} }
// //
const parentDepartmentIdList = ref([] as any[])
const parentDepartmentIdList = ref([] as any[]) const setParentDepartmentIdList = async () => {
const setParentDepartmentIdList = async () => { parentDepartmentIdList.value = await (await getWithDepartmentsList({})).data
parentDepartmentIdList.value = await (await getWithDepartmentsList({})).data }
} setParentDepartmentIdList()
setParentDepartmentIdList()
const setFormData = async (row: any = null) => { const setFormData = async (row: any = null) => {
Object.assign(formData, initialFormData) Object.assign(formData, initialFormData)
loading.value = true loading.value = true
if(row){ if (row) {
const data = await (await getDepartmentsInfo(row.id)).data const data = await (await getDepartmentsInfo(row.id)).data
if (data) Object.keys(formData).forEach((key: string) => { if (data)
if (data[key] != undefined) formData[key] = data[key] Object.keys(formData).forEach((key: string) => {
}) if (data[key] != undefined) formData[key] = data[key]
} })
loading.value = false }
loading.value = false
} }
// //
const mobileVerify = (rule: any, value: any, callback: any) => { const mobileVerify = (rule: any, value: any, callback: any) => {
if (value && !/^1[3-9]\d{9}$/.test(value)) { if (value && !/^1[3-9]\d{9}$/.test(value)) {
callback(new Error(t('generateMobile'))) callback(new Error(t('generateMobile')))
} else { } else {
callback() callback()
} }
} }
// //
const idCardVerify = (rule: any, value: any, callback: any) => { const idCardVerify = (rule: any, value: any, callback: any) => {
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) { if (
callback(new Error(t('generateIdCard'))) value &&
} else { !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
callback() value
} )
) {
callback(new Error(t('generateIdCard')))
} else {
callback()
}
} }
// //
const emailVerify = (rule: any, value: any, callback: any) => { const emailVerify = (rule: any, value: any, callback: any) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) { if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail'))) callback(new Error(t('generateEmail')))
} else { } else {
callback() callback()
} }
} }
// //
const numberVerify = (rule: any, value: any, callback: any) => { const numberVerify = (rule: any, value: any, callback: any) => {
if (!Number.isInteger(value)) { if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber'))) callback(new Error(t('generateNumber')))
} else { } else {
callback() callback()
} }
} }
defineExpose({ defineExpose({
showDialog, showDialog,
setFormData setFormData,
}) })
</script> </script>
<style lang="scss" scoped></style> <style lang="scss" scoped></style>
<style lang="scss"> <style lang="scss">
.diy-dialog-wrap .el-form-item__label{ .diy-dialog-wrap .el-form-item__label {
height: auto !important; height: auto !important;
} }
</style> </style>

292
admin/src/app/views/departments/departments.vue

@ -1,93 +1,140 @@
<template> <template>
<div class="main-container"> <div class="main-container">
<el-card class="box-card !border-none" shadow="never"> <el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<div class="flex justify-between items-center"> <span class="text-lg">{{ pageName }}</span>
<span class="text-lg">{{pageName}}</span> <el-button type="primary" @click="addEvent">
<el-button type="primary" @click="addEvent"> {{ t('addDepartments') }}
{{ t('addDepartments') }} </el-button>
</el-button> </div>
</div>
<el-card
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> class="box-card !border-none my-[10px] table-search-wrap"
<el-form :inline="true" :model="departmentsTable.searchParam" ref="searchFormRef"> shadow="never"
<el-form-item :label="t('departmentName')" prop="department_name"> >
<el-input v-model="departmentsTable.searchParam.department_name" :placeholder="t('departmentNamePlaceholder')" /> <el-form
</el-form-item> :inline="true"
:model="departmentsTable.searchParam"
<el-form-item :label="t('parentDepartmentId')" prop="parent_department_id"> ref="searchFormRef"
<el-select class="w-[280px]" v-model="departmentsTable.searchParam.parent_department_id" clearable :placeholder="t('parentDepartmentIdPlaceholder')"> >
<el-option <el-form-item :label="t('departmentName')" prop="department_name">
v-for="(item, index) in parentDepartmentIdList" <el-input
:key="index" v-model="departmentsTable.searchParam.department_name"
:label="item['department_name']" :placeholder="t('departmentNamePlaceholder')"
:value="item['id']" />
/> </el-form-item>
</el-select>
</el-form-item> <el-form-item
:label="t('parentDepartmentId')"
<el-form-item> prop="parent_department_id"
<el-button type="primary" @click="loadDepartmentsList()">{{ t('search') }}</el-button> >
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> <el-select
</el-form-item> class="w-[280px]"
</el-form> v-model="departmentsTable.searchParam.parent_department_id"
</el-card> clearable
:placeholder="t('parentDepartmentIdPlaceholder')"
<div class="mt-[10px]"> >
<el-table :data="departmentsTable.data" size="large" v-loading="departmentsTable.loading"> <el-option
<template #empty> v-for="(item, index) in parentDepartmentIdList"
<span>{{ !departmentsTable.loading ? t('emptyData') : '' }}</span> :key="index"
</template> :label="item['department_name']"
<el-table-column prop="department_name" :label="t('departmentName')" min-width="120" :show-overflow-tooltip="true"/> :value="item['id']"
/>
<el-table-column prop="parent_department_id_name" :label="t('parentDepartmentId')" min-width="120" :show-overflow-tooltip="true"/> </el-select>
</el-form-item>
<el-table-column prop="created_at" :label="t('createdAt')" min-width="120" :show-overflow-tooltip="true"/>
<el-form-item>
<el-table-column prop="updated_at" :label="t('updatedAt')" min-width="120" :show-overflow-tooltip="true"/> <el-button type="primary" @click="loadDepartmentsList()">{{
t('search')
<el-table-column :label="t('operation')" fixed="right" min-width="120"> }}</el-button>
<template #default="{ row }"> <el-button @click="resetForm(searchFormRef)">{{
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button> t('reset')
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button> }}</el-button>
</template> </el-form-item>
</el-table-column> </el-form>
</el-card>
</el-table>
<div class="mt-[16px] flex justify-end"> <div class="mt-[10px]">
<el-pagination v-model:current-page="departmentsTable.page" v-model:page-size="departmentsTable.limit" <el-table
layout="total, sizes, prev, pager, next, jumper" :total="departmentsTable.total" :data="departmentsTable.data"
@size-change="loadDepartmentsList()" @current-change="loadDepartmentsList" /> size="large"
</div> v-loading="departmentsTable.loading"
</div> >
<template #empty>
<edit ref="editDepartmentsDialog" @complete="loadDepartmentsList" /> <span>{{ !departmentsTable.loading ? t('emptyData') : '' }}</span>
</el-card> </template>
</div> <el-table-column
prop="department_name"
:label="t('departmentName')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column
prop="parent_department_id_name"
:label="t('parentDepartmentId')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column
:label="t('operation')"
fixed="right"
min-width="120"
>
<template #default="{ row }">
<el-button type="primary" link @click="editEvent(row)">{{
t('edit')
}}</el-button>
<el-button type="primary" link @click="deleteEvent(row.id)">{{
t('delete')
}}</el-button>
</template>
</el-table-column>
</el-table>
<div class="mt-[16px] flex justify-end">
<el-pagination
v-model:current-page="departmentsTable.page"
v-model:page-size="departmentsTable.limit"
layout="total, sizes, prev, pager, next, jumper"
:total="departmentsTable.total"
@size-change="loadDepartmentsList()"
@current-change="loadDepartmentsList"
/>
</div>
</div>
<edit ref="editDepartmentsDialog" @complete="loadDepartmentsList" />
</el-card>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { reactive, ref, watch } from 'vue' import { reactive, ref, watch } from 'vue'
import { t } from '@/lang' import { t } from '@/lang'
import { useDictionary } from '@/app/api/dict' import { useDictionary } from '@/app/api/dict'
import { getDepartmentsList, deleteDepartments, getWithDepartmentsList } from '@/app/api/departments' import {
getDepartmentsList,
deleteDepartments,
getWithDepartmentsList,
} from '@/app/api/departments'
import { img } from '@/utils/common' import { img } from '@/utils/common'
import { ElMessageBox,FormInstance } from 'element-plus' import { ElMessageBox, FormInstance } from 'element-plus'
import Edit from '@/app/views/departments/components/departments-edit.vue' import Edit from '@/app/views/departments/components/departments-edit.vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
const route = useRoute() const route = useRoute()
const pageName = route.meta.title; const pageName = route.meta.title
let departmentsTable = reactive({ let departmentsTable = reactive({
page: 1, page: 1,
limit: 10, limit: 10,
total: 0, total: 0,
loading: true, loading: true,
data: [], data: [],
searchParam:{ searchParam: {
"department_name":"", department_name: '',
"parent_department_id":"" parent_department_id: '',
} },
}) })
const searchFormRef = ref<FormInstance>() const searchFormRef = ref<FormInstance>()
@ -96,25 +143,26 @@ const searchFormRef = ref<FormInstance>()
const selectData = ref<any[]>([]) const selectData = ref<any[]>([])
// //
/** /**
* 获取部门列表 * 获取部门列表
*/ */
const loadDepartmentsList = (page: number = 1) => { const loadDepartmentsList = (page: number = 1) => {
departmentsTable.loading = true departmentsTable.loading = true
departmentsTable.page = page departmentsTable.page = page
getDepartmentsList({ getDepartmentsList({
page: departmentsTable.page, page: departmentsTable.page,
limit: departmentsTable.limit, limit: departmentsTable.limit,
...departmentsTable.searchParam ...departmentsTable.searchParam,
}).then(res => { })
departmentsTable.loading = false .then((res) => {
departmentsTable.data = res.data.data departmentsTable.loading = false
departmentsTable.total = res.data.total departmentsTable.data = res.data.data
}).catch(() => { departmentsTable.total = res.data.total
departmentsTable.loading = false })
.catch(() => {
departmentsTable.loading = false
}) })
} }
loadDepartmentsList() loadDepartmentsList()
@ -125,8 +173,8 @@ const editDepartmentsDialog: Record<string, any> | null = ref(null)
* 添加部门 * 添加部门
*/ */
const addEvent = () => { const addEvent = () => {
editDepartmentsDialog.value.setFormData() editDepartmentsDialog.value.setFormData()
editDepartmentsDialog.value.showDialog = true editDepartmentsDialog.value.showDialog = true
} }
/** /**
@ -134,50 +182,48 @@ const addEvent = () => {
* @param data * @param data
*/ */
const editEvent = (data: any) => { const editEvent = (data: any) => {
editDepartmentsDialog.value.setFormData(data) editDepartmentsDialog.value.setFormData(data)
editDepartmentsDialog.value.showDialog = true editDepartmentsDialog.value.showDialog = true
} }
/** /**
* 删除部门 * 删除部门
*/ */
const deleteEvent = (id: number) => { const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('departmentsDeleteTips'), t('warning'), ElMessageBox.confirm(t('departmentsDeleteTips'), t('warning'), {
{ confirmButtonText: t('confirm'),
confirmButtonText: t('confirm'), cancelButtonText: t('cancel'),
cancelButtonText: t('cancel'), type: 'warning',
type: 'warning', }).then(() => {
} deleteDepartments(id)
).then(() => { .then(() => {
deleteDepartments(id).then(() => { loadDepartmentsList()
loadDepartmentsList() })
}).catch(() => { .catch(() => {})
}) })
})
} }
const parentDepartmentIdList = ref([])
const parentDepartmentIdList = ref([]) const setParentDepartmentIdList = async () => {
const setParentDepartmentIdList = async () => { parentDepartmentIdList.value = await (await getWithDepartmentsList({})).data
parentDepartmentIdList.value = await (await getWithDepartmentsList({})).data }
} setParentDepartmentIdList()
setParentDepartmentIdList()
const resetForm = (formEl: FormInstance | undefined) => { const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return if (!formEl) return
formEl.resetFields() formEl.resetFields()
loadDepartmentsList() loadDepartmentsList()
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
/* 多行超出隐藏 */ /* 多行超出隐藏 */
.multi-hidden { .multi-hidden {
word-break: break-all; word-break: break-all;
text-overflow: ellipsis; text-overflow: ellipsis;
overflow: hidden; overflow: hidden;
display: -webkit-box; display: -webkit-box;
-webkit-line-clamp: 2; -webkit-line-clamp: 2;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
} }
</style> </style>

406
admin/src/app/views/exam_answers/components/exam-answers-edit.vue

@ -1,183 +1,223 @@
<template> <template>
<el-dialog v-model="showDialog" :title="formData.id ? t('updateExamAnswers') : t('addExamAnswers')" width="50%" class="diy-dialog-wrap" :destroy-on-close="true"> <el-dialog
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading"> v-model="showDialog"
<el-form-item :label="t('campusId')" prop="campus_id"> :title="formData.id ? t('updateExamAnswers') : t('addExamAnswers')"
<el-input v-model="formData.campus_id" clearable :placeholder="t('campusIdPlaceholder')" class="input-width" /> width="50%"
</el-form-item> class="diy-dialog-wrap"
:destroy-on-close="true"
<el-form-item :label="t('userId')" prop="user_id"> >
<el-input v-model="formData.user_id" clearable :placeholder="t('userIdPlaceholder')" class="input-width" /> <el-form
</el-form-item> :model="formData"
label-width="120px"
<el-form-item :label="t('questionId')" prop="question_id"> ref="formRef"
<el-input v-model="formData.question_id" clearable :placeholder="t('questionIdPlaceholder')" class="input-width" /> :rules="formRules"
</el-form-item> class="page-form"
v-loading="loading"
<el-form-item :label="t('answer')" > >
<el-input v-model="formData.answer" clearable :placeholder="t('answerPlaceholder')" class="input-width" /> <el-form-item :label="t('campusId')" prop="campus_id">
</el-form-item> <el-input
v-model="formData.campus_id"
<el-form-item :label="t('isCorrect')" > clearable
<el-input v-model="formData.is_correct" clearable :placeholder="t('isCorrectPlaceholder')" class="input-width" /> :placeholder="t('campusIdPlaceholder')"
</el-form-item> class="input-width"
/>
</el-form> </el-form-item>
<template #footer> <el-form-item :label="t('userId')" prop="user_id">
<span class="dialog-footer"> <el-input
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button> v-model="formData.user_id"
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{ clearable
t('confirm') :placeholder="t('userIdPlaceholder')"
}}</el-button> class="input-width"
</span> />
</template> </el-form-item>
</el-dialog>
</template> <el-form-item :label="t('questionId')" prop="question_id">
<el-input
<script lang="ts" setup> v-model="formData.question_id"
import { ref, reactive, computed, watch } from 'vue' clearable
import { useDictionary } from '@/app/api/dict' :placeholder="t('questionIdPlaceholder')"
import { t } from '@/lang' class="input-width"
import type { FormInstance } from 'element-plus' />
import { addExamAnswers, editExamAnswers, getExamAnswersInfo } from '@/app/api/exam_answers' </el-form-item>
let showDialog = ref(false) <el-form-item :label="t('answer')">
const loading = ref(false) <el-input
v-model="formData.answer"
/** clearable
* 表单数据 :placeholder="t('answerPlaceholder')"
*/ class="input-width"
const initialFormData = { />
id: '', </el-form-item>
campus_id: '',
user_id: '', <el-form-item :label="t('isCorrect')">
question_id: '', <el-input
answer: '', v-model="formData.is_correct"
is_correct: '', clearable
} :placeholder="t('isCorrectPlaceholder')"
const formData: Record<string, any> = reactive({ ...initialFormData }) class="input-width"
/>
const formRef = ref<FormInstance>() </el-form-item>
</el-form>
//
const formRules = computed(() => { <template #footer>
return { <span class="dialog-footer">
campus_id: [ <el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
{ required: true, message: t('campusIdPlaceholder'), trigger: 'blur' }, <el-button
type="primary"
] :loading="loading"
, @click="confirm(formRef)"
user_id: [ >{{ t('confirm') }}</el-button
{ required: true, message: t('userIdPlaceholder'), trigger: 'blur' }, >
</span>
] </template>
, </el-dialog>
question_id: [ </template>
{ required: true, message: t('questionIdPlaceholder'), trigger: 'blur' },
<script lang="ts" setup>
] import { ref, reactive, computed, watch } from 'vue'
, import { useDictionary } from '@/app/api/dict'
answer: [ import { t } from '@/lang'
{ required: true, message: t('answerPlaceholder'), trigger: 'blur' }, import type { FormInstance } from 'element-plus'
import {
] addExamAnswers,
, editExamAnswers,
is_correct: [ getExamAnswersInfo,
{ required: true, message: t('isCorrectPlaceholder'), trigger: 'blur' }, } from '@/app/api/exam_answers'
] let showDialog = ref(false)
, const loading = ref(false)
}
}) /**
* 表单数据
const emit = defineEmits(['complete']) */
const initialFormData = {
/** id: '',
* 确认 campus_id: '',
* @param formEl user_id: '',
*/ question_id: '',
const confirm = async (formEl: FormInstance | undefined) => { answer: '',
if (loading.value || !formEl) return is_correct: '',
let save = formData.id ? editExamAnswers : addExamAnswers }
const formData: Record<string, any> = reactive({ ...initialFormData })
await formEl.validate(async (valid) => {
if (valid) { const formRef = ref<FormInstance>()
loading.value = true
//
let data = formData const formRules = computed(() => {
return {
save(data).then(res => { campus_id: [
loading.value = false { required: true, message: t('campusIdPlaceholder'), trigger: 'blur' },
showDialog.value = false ],
emit('complete') user_id: [
}).catch(err => { { required: true, message: t('userIdPlaceholder'), trigger: 'blur' },
loading.value = false ],
}) question_id: [
} { required: true, message: t('questionIdPlaceholder'), trigger: 'blur' },
}) ],
} answer: [
{ required: true, message: t('answerPlaceholder'), trigger: 'blur' },
// ],
is_correct: [
{ required: true, message: t('isCorrectPlaceholder'), trigger: 'blur' },
],
const setFormData = async (row: any = null) => { }
Object.assign(formData, initialFormData) })
loading.value = true
if(row){ const emit = defineEmits(['complete'])
const data = await (await getExamAnswersInfo(row.id)).data
if (data) Object.keys(formData).forEach((key: string) => { /**
if (data[key] != undefined) formData[key] = data[key] * 确认
}) * @param formEl
} */
loading.value = false const confirm = async (formEl: FormInstance | undefined) => {
} if (loading.value || !formEl) return
let save = formData.id ? editExamAnswers : addExamAnswers
//
const mobileVerify = (rule: any, value: any, callback: any) => { await formEl.validate(async (valid) => {
if (value && !/^1[3-9]\d{9}$/.test(value)) { if (valid) {
callback(new Error(t('generateMobile'))) loading.value = true
} else {
callback() let data = formData
}
} save(data)
.then((res) => {
// loading.value = false
const idCardVerify = (rule: any, value: any, callback: any) => { showDialog.value = false
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) { emit('complete')
callback(new Error(t('generateIdCard'))) })
} else { .catch((err) => {
callback() loading.value = false
} })
} }
})
// }
const emailVerify = (rule: any, value: any, callback: any) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) { //
callback(new Error(t('generateEmail')))
} else { const setFormData = async (row: any = null) => {
callback() Object.assign(formData, initialFormData)
} loading.value = true
} if (row) {
const data = await (await getExamAnswersInfo(row.id)).data
// if (data)
const numberVerify = (rule: any, value: any, callback: any) => { Object.keys(formData).forEach((key: string) => {
if (!Number.isInteger(value)) { if (data[key] != undefined) formData[key] = data[key]
callback(new Error(t('generateNumber'))) })
} else { }
callback() loading.value = false
} }
}
//
defineExpose({ const mobileVerify = (rule: any, value: any, callback: any) => {
showDialog, if (value && !/^1[3-9]\d{9}$/.test(value)) {
setFormData callback(new Error(t('generateMobile')))
}) } else {
</script> callback()
}
<style lang="scss" scoped></style> }
<style lang="scss">
.diy-dialog-wrap .el-form-item__label{ //
height: auto !important; const idCardVerify = (rule: any, value: any, callback: any) => {
} if (
</style> value &&
!/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
value
)
) {
callback(new Error(t('generateIdCard')))
} else {
callback()
}
}
//
const emailVerify = (rule: any, value: any, callback: any) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail')))
} else {
callback()
}
}
//
const numberVerify = (rule: any, value: any, callback: any) => {
if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber')))
} else {
callback()
}
}
defineExpose({
showDialog,
setFormData,
})
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.diy-dialog-wrap .el-form-item__label {
height: auto !important;
}
</style>

431
admin/src/app/views/exam_answers/exam_answers.vue

@ -1,183 +1,248 @@
<template> <template>
<div class="main-container"> <div class="main-container">
<el-card class="box-card !border-none" shadow="never"> <el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<div class="flex justify-between items-center"> <span class="text-lg">{{ pageName }}</span>
<span class="text-lg">{{pageName}}</span> <el-button type="primary" @click="addEvent">
<el-button type="primary" @click="addEvent"> {{ t('addExamAnswers') }}
{{ t('addExamAnswers') }} </el-button>
</el-button> </div>
</div>
<el-card
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> class="box-card !border-none my-[10px] table-search-wrap"
<el-form :inline="true" :model="examAnswersTable.searchParam" ref="searchFormRef"> shadow="never"
<el-form-item :label="t('campusId')" prop="campus_id"> >
<el-input v-model="examAnswersTable.searchParam.campus_id" :placeholder="t('campusIdPlaceholder')" /> <el-form
</el-form-item> :inline="true"
<el-form-item :label="t('userId')" prop="user_id"> :model="examAnswersTable.searchParam"
<el-input v-model="examAnswersTable.searchParam.user_id" :placeholder="t('userIdPlaceholder')" /> ref="searchFormRef"
</el-form-item> >
<el-form-item :label="t('questionId')" prop="question_id"> <el-form-item :label="t('campusId')" prop="campus_id">
<el-input v-model="examAnswersTable.searchParam.question_id" :placeholder="t('questionIdPlaceholder')" /> <el-input
</el-form-item> v-model="examAnswersTable.searchParam.campus_id"
<el-form-item :label="t('answer')" prop="answer"> :placeholder="t('campusIdPlaceholder')"
<el-input v-model="examAnswersTable.searchParam.answer" :placeholder="t('answerPlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('isCorrect')" prop="is_correct"> <el-form-item :label="t('userId')" prop="user_id">
<el-input v-model="examAnswersTable.searchParam.is_correct" :placeholder="t('isCorrectPlaceholder')" /> <el-input
</el-form-item> v-model="examAnswersTable.searchParam.user_id"
<el-form-item> :placeholder="t('userIdPlaceholder')"
<el-button type="primary" @click="loadExamAnswersList()">{{ t('search') }}</el-button> />
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> </el-form-item>
</el-form-item> <el-form-item :label="t('questionId')" prop="question_id">
</el-form> <el-input
</el-card> v-model="examAnswersTable.searchParam.question_id"
:placeholder="t('questionIdPlaceholder')"
<div class="mt-[10px]"> />
<el-table :data="examAnswersTable.data" size="large" v-loading="examAnswersTable.loading"> </el-form-item>
<template #empty> <el-form-item :label="t('answer')" prop="answer">
<span>{{ !examAnswersTable.loading ? t('emptyData') : '' }}</span> <el-input
</template> v-model="examAnswersTable.searchParam.answer"
<el-table-column prop="campus_id" :label="t('campusId')" min-width="120" :show-overflow-tooltip="true"/> :placeholder="t('answerPlaceholder')"
/>
<el-table-column prop="user_id" :label="t('userId')" min-width="120" :show-overflow-tooltip="true"/> </el-form-item>
<el-form-item :label="t('isCorrect')" prop="is_correct">
<el-table-column prop="question_id" :label="t('questionId')" min-width="120" :show-overflow-tooltip="true"/> <el-input
v-model="examAnswersTable.searchParam.is_correct"
<el-table-column prop="answer" :label="t('answer')" min-width="120" :show-overflow-tooltip="true"/> :placeholder="t('isCorrectPlaceholder')"
/>
<el-table-column prop="is_correct" :label="t('isCorrect')" min-width="120" :show-overflow-tooltip="true"/> </el-form-item>
<el-table-column :label="t('operation')" fixed="right" min-width="120"> <el-form-item>
<template #default="{ row }"> <el-button type="primary" @click="loadExamAnswersList()">{{
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button> t('search')
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button> }}</el-button>
</template> <el-button @click="resetForm(searchFormRef)">{{
</el-table-column> t('reset')
}}</el-button>
</el-table> </el-form-item>
<div class="mt-[16px] flex justify-end"> </el-form>
<el-pagination v-model:current-page="examAnswersTable.page" v-model:page-size="examAnswersTable.limit" </el-card>
layout="total, sizes, prev, pager, next, jumper" :total="examAnswersTable.total"
@size-change="loadExamAnswersList()" @current-change="loadExamAnswersList" /> <div class="mt-[10px]">
</div> <el-table
</div> :data="examAnswersTable.data"
size="large"
<edit ref="editExamAnswersDialog" @complete="loadExamAnswersList" /> v-loading="examAnswersTable.loading"
</el-card> >
</div> <template #empty>
</template> <span>{{ !examAnswersTable.loading ? t('emptyData') : '' }}</span>
</template>
<script lang="ts" setup> <el-table-column
import { reactive, ref, watch } from 'vue' prop="campus_id"
import { t } from '@/lang' :label="t('campusId')"
import { useDictionary } from '@/app/api/dict' min-width="120"
import { getExamAnswersList, deleteExamAnswers } from '@/app/api/exam_answers' :show-overflow-tooltip="true"
import { img } from '@/utils/common' />
import { ElMessageBox,FormInstance } from 'element-plus'
import Edit from '@/app/views/exam_answers/components/exam-answers-edit.vue' <el-table-column
import { useRoute } from 'vue-router' prop="user_id"
const route = useRoute() :label="t('userId')"
const pageName = route.meta.title; min-width="120"
:show-overflow-tooltip="true"
let examAnswersTable = reactive({ />
page: 1,
limit: 10, <el-table-column
total: 0, prop="question_id"
loading: true, :label="t('questionId')"
data: [], min-width="120"
searchParam:{ :show-overflow-tooltip="true"
"campus_id":"", />
"user_id":"",
"question_id":"", <el-table-column
"answer":"", prop="answer"
"is_correct":"" :label="t('answer')"
} min-width="120"
}) :show-overflow-tooltip="true"
/>
const searchFormRef = ref<FormInstance>()
<el-table-column
// prop="is_correct"
const selectData = ref<any[]>([]) :label="t('isCorrect')"
min-width="120"
// :show-overflow-tooltip="true"
/>
/** <el-table-column
* 获取答题记录列表 :label="t('operation')"
*/ fixed="right"
const loadExamAnswersList = (page: number = 1) => { min-width="120"
examAnswersTable.loading = true >
examAnswersTable.page = page <template #default="{ row }">
<el-button type="primary" link @click="editEvent(row)">{{
getExamAnswersList({ t('edit')
page: examAnswersTable.page, }}</el-button>
limit: examAnswersTable.limit, <el-button type="primary" link @click="deleteEvent(row.id)">{{
...examAnswersTable.searchParam t('delete')
}).then(res => { }}</el-button>
examAnswersTable.loading = false </template>
examAnswersTable.data = res.data.data </el-table-column>
examAnswersTable.total = res.data.total </el-table>
}).catch(() => { <div class="mt-[16px] flex justify-end">
examAnswersTable.loading = false <el-pagination
}) v-model:current-page="examAnswersTable.page"
} v-model:page-size="examAnswersTable.limit"
loadExamAnswersList() layout="total, sizes, prev, pager, next, jumper"
:total="examAnswersTable.total"
const editExamAnswersDialog: Record<string, any> | null = ref(null) @size-change="loadExamAnswersList()"
@current-change="loadExamAnswersList"
/** />
* 添加答题记录 </div>
*/ </div>
const addEvent = () => {
editExamAnswersDialog.value.setFormData() <edit ref="editExamAnswersDialog" @complete="loadExamAnswersList" />
editExamAnswersDialog.value.showDialog = true </el-card>
} </div>
</template>
/**
* 编辑答题记录 <script lang="ts" setup>
* @param data import { reactive, ref, watch } from 'vue'
*/ import { t } from '@/lang'
const editEvent = (data: any) => { import { useDictionary } from '@/app/api/dict'
editExamAnswersDialog.value.setFormData(data) import { getExamAnswersList, deleteExamAnswers } from '@/app/api/exam_answers'
editExamAnswersDialog.value.showDialog = true import { img } from '@/utils/common'
} import { ElMessageBox, FormInstance } from 'element-plus'
import Edit from '@/app/views/exam_answers/components/exam-answers-edit.vue'
/** import { useRoute } from 'vue-router'
* 删除答题记录 const route = useRoute()
*/ const pageName = route.meta.title
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('examAnswersDeleteTips'), t('warning'), let examAnswersTable = reactive({
{ page: 1,
confirmButtonText: t('confirm'), limit: 10,
cancelButtonText: t('cancel'), total: 0,
type: 'warning', loading: true,
} data: [],
).then(() => { searchParam: {
deleteExamAnswers(id).then(() => { campus_id: '',
loadExamAnswersList() user_id: '',
}).catch(() => { question_id: '',
}) answer: '',
}) is_correct: '',
} },
})
const searchFormRef = ref<FormInstance>()
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return //
formEl.resetFields() const selectData = ref<any[]>([])
loadExamAnswersList()
} //
</script>
/**
<style lang="scss" scoped> * 获取答题记录列表
/* 多行超出隐藏 */ */
.multi-hidden { const loadExamAnswersList = (page: number = 1) => {
word-break: break-all; examAnswersTable.loading = true
text-overflow: ellipsis; examAnswersTable.page = page
overflow: hidden;
display: -webkit-box; getExamAnswersList({
-webkit-line-clamp: 2; page: examAnswersTable.page,
-webkit-box-orient: vertical; limit: examAnswersTable.limit,
} ...examAnswersTable.searchParam,
</style> })
.then((res) => {
examAnswersTable.loading = false
examAnswersTable.data = res.data.data
examAnswersTable.total = res.data.total
})
.catch(() => {
examAnswersTable.loading = false
})
}
loadExamAnswersList()
const editExamAnswersDialog: Record<string, any> | null = ref(null)
/**
* 添加答题记录
*/
const addEvent = () => {
editExamAnswersDialog.value.setFormData()
editExamAnswersDialog.value.showDialog = true
}
/**
* 编辑答题记录
* @param data
*/
const editEvent = (data: any) => {
editExamAnswersDialog.value.setFormData(data)
editExamAnswersDialog.value.showDialog = true
}
/**
* 删除答题记录
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('examAnswersDeleteTips'), t('warning'), {
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}).then(() => {
deleteExamAnswers(id)
.then(() => {
loadExamAnswersList()
})
.catch(() => {})
})
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadExamAnswersList()
}
</script>
<style lang="scss" scoped>
/* 多行超出隐藏 */
.multi-hidden {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
</style>

368
admin/src/app/views/exam_papers/components/exam-papers-edit.vue

@ -1,163 +1,205 @@
<template> <template>
<el-dialog v-model="showDialog" :title="formData.id ? t('updateExamPapers') : t('addExamPapers')" width="50%" class="diy-dialog-wrap" :destroy-on-close="true"> <el-dialog
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading"> v-model="showDialog"
<el-form-item :label="t('selectionMode')" prop="selection_mode"> :title="formData.id ? t('updateExamPapers') : t('addExamPapers')"
<el-input v-model="formData.selection_mode" clearable :placeholder="t('selectionModePlaceholder')" class="input-width" /> width="50%"
</el-form-item> class="diy-dialog-wrap"
:destroy-on-close="true"
<el-form-item :label="t('totalScore')" prop="total_score"> >
<el-input v-model="formData.total_score" clearable :placeholder="t('totalScorePlaceholder')" class="input-width" /> <el-form
</el-form-item> :model="formData"
label-width="120px"
<el-form-item :label="t('passingScore')" prop="passing_score"> ref="formRef"
<el-input v-model="formData.passing_score" clearable :placeholder="t('passingScorePlaceholder')" class="input-width" /> :rules="formRules"
</el-form-item> class="page-form"
v-loading="loading"
</el-form> >
<el-form-item :label="t('selectionMode')" prop="selection_mode">
<template #footer> <el-input
<span class="dialog-footer"> v-model="formData.selection_mode"
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button> clearable
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{ :placeholder="t('selectionModePlaceholder')"
t('confirm') class="input-width"
}}</el-button> />
</span> </el-form-item>
</template>
</el-dialog> <el-form-item :label="t('totalScore')" prop="total_score">
</template> <el-input
v-model="formData.total_score"
<script lang="ts" setup> clearable
import { ref, reactive, computed, watch } from 'vue' :placeholder="t('totalScorePlaceholder')"
import { useDictionary } from '@/app/api/dict' class="input-width"
import { t } from '@/lang' />
import type { FormInstance } from 'element-plus' </el-form-item>
import { addExamPapers, editExamPapers, getExamPapersInfo } from '@/app/api/exam_papers'
<el-form-item :label="t('passingScore')" prop="passing_score">
let showDialog = ref(false) <el-input
const loading = ref(false) v-model="formData.passing_score"
clearable
/** :placeholder="t('passingScorePlaceholder')"
* 表单数据 class="input-width"
*/ />
const initialFormData = { </el-form-item>
id: '', </el-form>
selection_mode: '',
total_score: '', <template #footer>
passing_score: '', <span class="dialog-footer">
} <el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
const formData: Record<string, any> = reactive({ ...initialFormData }) <el-button
type="primary"
const formRef = ref<FormInstance>() :loading="loading"
@click="confirm(formRef)"
// >{{ t('confirm') }}</el-button
const formRules = computed(() => { >
return { </span>
selection_mode: [ </template>
{ required: true, message: t('selectionModePlaceholder'), trigger: 'blur' }, </el-dialog>
</template>
]
, <script lang="ts" setup>
total_score: [ import { ref, reactive, computed, watch } from 'vue'
{ required: true, message: t('totalScorePlaceholder'), trigger: 'blur' }, import { useDictionary } from '@/app/api/dict'
import { t } from '@/lang'
] import type { FormInstance } from 'element-plus'
, import {
passing_score: [ addExamPapers,
{ required: true, message: t('passingScorePlaceholder'), trigger: 'blur' }, editExamPapers,
getExamPapersInfo,
] } from '@/app/api/exam_papers'
,
} let showDialog = ref(false)
}) const loading = ref(false)
const emit = defineEmits(['complete']) /**
* 表单数据
/** */
* 确认 const initialFormData = {
* @param formEl id: '',
*/ selection_mode: '',
const confirm = async (formEl: FormInstance | undefined) => { total_score: '',
if (loading.value || !formEl) return passing_score: '',
let save = formData.id ? editExamPapers : addExamPapers }
const formData: Record<string, any> = reactive({ ...initialFormData })
await formEl.validate(async (valid) => {
if (valid) { const formRef = ref<FormInstance>()
loading.value = true
//
let data = formData const formRules = computed(() => {
return {
save(data).then(res => { selection_mode: [
loading.value = false {
showDialog.value = false required: true,
emit('complete') message: t('selectionModePlaceholder'),
}).catch(err => { trigger: 'blur',
loading.value = false },
}) ],
} total_score: [
}) { required: true, message: t('totalScorePlaceholder'), trigger: 'blur' },
} ],
passing_score: [
// {
required: true,
message: t('passingScorePlaceholder'),
trigger: 'blur',
const setFormData = async (row: any = null) => { },
Object.assign(formData, initialFormData) ],
loading.value = true }
if(row){ })
const data = await (await getExamPapersInfo(row.id)).data
if (data) Object.keys(formData).forEach((key: string) => { const emit = defineEmits(['complete'])
if (data[key] != undefined) formData[key] = data[key]
}) /**
} * 确认
loading.value = false * @param formEl
} */
const confirm = async (formEl: FormInstance | undefined) => {
// if (loading.value || !formEl) return
const mobileVerify = (rule: any, value: any, callback: any) => { let save = formData.id ? editExamPapers : addExamPapers
if (value && !/^1[3-9]\d{9}$/.test(value)) {
callback(new Error(t('generateMobile'))) await formEl.validate(async (valid) => {
} else { if (valid) {
callback() loading.value = true
}
} let data = formData
// save(data)
const idCardVerify = (rule: any, value: any, callback: any) => { .then((res) => {
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) { loading.value = false
callback(new Error(t('generateIdCard'))) showDialog.value = false
} else { emit('complete')
callback() })
} .catch((err) => {
} loading.value = false
})
// }
const emailVerify = (rule: any, value: any, callback: any) => { })
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) { }
callback(new Error(t('generateEmail')))
} else { //
callback()
} const setFormData = async (row: any = null) => {
} Object.assign(formData, initialFormData)
loading.value = true
// if (row) {
const numberVerify = (rule: any, value: any, callback: any) => { const data = await (await getExamPapersInfo(row.id)).data
if (!Number.isInteger(value)) { if (data)
callback(new Error(t('generateNumber'))) Object.keys(formData).forEach((key: string) => {
} else { if (data[key] != undefined) formData[key] = data[key]
callback() })
} }
} loading.value = false
}
defineExpose({
showDialog, //
setFormData const mobileVerify = (rule: any, value: any, callback: any) => {
}) if (value && !/^1[3-9]\d{9}$/.test(value)) {
</script> callback(new Error(t('generateMobile')))
} else {
<style lang="scss" scoped></style> callback()
<style lang="scss"> }
.diy-dialog-wrap .el-form-item__label{ }
height: auto !important;
} //
</style> const idCardVerify = (rule: any, value: any, callback: any) => {
if (
value &&
!/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
value
)
) {
callback(new Error(t('generateIdCard')))
} else {
callback()
}
}
//
const emailVerify = (rule: any, value: any, callback: any) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail')))
} else {
callback()
}
}
//
const numberVerify = (rule: any, value: any, callback: any) => {
if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber')))
} else {
callback()
}
}
defineExpose({
showDialog,
setFormData,
})
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.diy-dialog-wrap .el-form-item__label {
height: auto !important;
}
</style>

391
admin/src/app/views/exam_papers/exam_papers.vue

@ -1,171 +1,220 @@
<template> <template>
<div class="main-container"> <div class="main-container">
<el-card class="box-card !border-none" shadow="never"> <el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<div class="flex justify-between items-center"> <span class="text-lg">{{ pageName }}</span>
<span class="text-lg">{{pageName}}</span> <el-button type="primary" @click="addEvent">
<el-button type="primary" @click="addEvent"> {{ t('addExamPapers') }}
{{ t('addExamPapers') }} </el-button>
</el-button> </div>
</div>
<el-card
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> class="box-card !border-none my-[10px] table-search-wrap"
<el-form :inline="true" :model="examPapersTable.searchParam" ref="searchFormRef"> shadow="never"
<el-form-item :label="t('selectionMode')" prop="selection_mode"> >
<el-input v-model="examPapersTable.searchParam.selection_mode" :placeholder="t('selectionModePlaceholder')" /> <el-form
</el-form-item> :inline="true"
<el-form-item :label="t('totalScore')" prop="total_score"> :model="examPapersTable.searchParam"
<el-input v-model="examPapersTable.searchParam.total_score" :placeholder="t('totalScorePlaceholder')" /> ref="searchFormRef"
</el-form-item> >
<el-form-item :label="t('passingScore')" prop="passing_score"> <el-form-item :label="t('selectionMode')" prop="selection_mode">
<el-input v-model="examPapersTable.searchParam.passing_score" :placeholder="t('passingScorePlaceholder')" /> <el-input
</el-form-item> v-model="examPapersTable.searchParam.selection_mode"
<el-form-item> :placeholder="t('selectionModePlaceholder')"
<el-button type="primary" @click="loadExamPapersList()">{{ t('search') }}</el-button> />
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> </el-form-item>
</el-form-item> <el-form-item :label="t('totalScore')" prop="total_score">
</el-form> <el-input
</el-card> v-model="examPapersTable.searchParam.total_score"
:placeholder="t('totalScorePlaceholder')"
<div class="mt-[10px]"> />
<el-table :data="examPapersTable.data" size="large" v-loading="examPapersTable.loading"> </el-form-item>
<template #empty> <el-form-item :label="t('passingScore')" prop="passing_score">
<span>{{ !examPapersTable.loading ? t('emptyData') : '' }}</span> <el-input
</template> v-model="examPapersTable.searchParam.passing_score"
<el-table-column prop="selection_mode" :label="t('selectionMode')" min-width="120" :show-overflow-tooltip="true"/> :placeholder="t('passingScorePlaceholder')"
/>
<el-table-column prop="total_score" :label="t('totalScore')" min-width="120" :show-overflow-tooltip="true"/> </el-form-item>
<el-table-column prop="passing_score" :label="t('passingScore')" min-width="120" :show-overflow-tooltip="true"/> <el-form-item>
<el-button type="primary" @click="loadExamPapersList()">{{
<el-table-column :label="t('operation')" fixed="right" min-width="120"> t('search')
<template #default="{ row }"> }}</el-button>
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button> <el-button @click="resetForm(searchFormRef)">{{
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button> t('reset')
</template> }}</el-button>
</el-table-column> </el-form-item>
</el-form>
</el-table> </el-card>
<div class="mt-[16px] flex justify-end">
<el-pagination v-model:current-page="examPapersTable.page" v-model:page-size="examPapersTable.limit" <div class="mt-[10px]">
layout="total, sizes, prev, pager, next, jumper" :total="examPapersTable.total" <el-table
@size-change="loadExamPapersList()" @current-change="loadExamPapersList" /> :data="examPapersTable.data"
</div> size="large"
</div> v-loading="examPapersTable.loading"
>
<edit ref="editExamPapersDialog" @complete="loadExamPapersList" /> <template #empty>
</el-card> <span>{{ !examPapersTable.loading ? t('emptyData') : '' }}</span>
</div> </template>
</template> <el-table-column
prop="selection_mode"
<script lang="ts" setup> :label="t('selectionMode')"
import { reactive, ref, watch } from 'vue' min-width="120"
import { t } from '@/lang' :show-overflow-tooltip="true"
import { useDictionary } from '@/app/api/dict' />
import { getExamPapersList, deleteExamPapers } from '@/app/api/exam_papers'
import { img } from '@/utils/common' <el-table-column
import { ElMessageBox,FormInstance } from 'element-plus' prop="total_score"
import Edit from '@/app/views/exam_papers/components/exam-papers-edit.vue' :label="t('totalScore')"
import { useRoute } from 'vue-router' min-width="120"
const route = useRoute() :show-overflow-tooltip="true"
const pageName = route.meta.title; />
let examPapersTable = reactive({ <el-table-column
page: 1, prop="passing_score"
limit: 10, :label="t('passingScore')"
total: 0, min-width="120"
loading: true, :show-overflow-tooltip="true"
data: [], />
searchParam:{
"selection_mode":"", <el-table-column
"total_score":"", :label="t('operation')"
"passing_score":"" fixed="right"
} min-width="120"
}) >
<template #default="{ row }">
const searchFormRef = ref<FormInstance>() <el-button type="primary" link @click="editEvent(row)">{{
t('edit')
// }}</el-button>
const selectData = ref<any[]>([]) <el-button type="primary" link @click="deleteEvent(row.id)">{{
t('delete')
// }}</el-button>
</template>
</el-table-column>
/** </el-table>
* 获取试卷列表 <div class="mt-[16px] flex justify-end">
*/ <el-pagination
const loadExamPapersList = (page: number = 1) => { v-model:current-page="examPapersTable.page"
examPapersTable.loading = true v-model:page-size="examPapersTable.limit"
examPapersTable.page = page layout="total, sizes, prev, pager, next, jumper"
:total="examPapersTable.total"
getExamPapersList({ @size-change="loadExamPapersList()"
page: examPapersTable.page, @current-change="loadExamPapersList"
limit: examPapersTable.limit, />
...examPapersTable.searchParam </div>
}).then(res => { </div>
examPapersTable.loading = false
examPapersTable.data = res.data.data <edit ref="editExamPapersDialog" @complete="loadExamPapersList" />
examPapersTable.total = res.data.total </el-card>
}).catch(() => { </div>
examPapersTable.loading = false </template>
})
} <script lang="ts" setup>
loadExamPapersList() import { reactive, ref, watch } from 'vue'
import { t } from '@/lang'
const editExamPapersDialog: Record<string, any> | null = ref(null) import { useDictionary } from '@/app/api/dict'
import { getExamPapersList, deleteExamPapers } from '@/app/api/exam_papers'
/** import { img } from '@/utils/common'
* 添加试卷 import { ElMessageBox, FormInstance } from 'element-plus'
*/ import Edit from '@/app/views/exam_papers/components/exam-papers-edit.vue'
const addEvent = () => { import { useRoute } from 'vue-router'
editExamPapersDialog.value.setFormData() const route = useRoute()
editExamPapersDialog.value.showDialog = true const pageName = route.meta.title
}
let examPapersTable = reactive({
/** page: 1,
* 编辑试卷 limit: 10,
* @param data total: 0,
*/ loading: true,
const editEvent = (data: any) => { data: [],
editExamPapersDialog.value.setFormData(data) searchParam: {
editExamPapersDialog.value.showDialog = true selection_mode: '',
} total_score: '',
passing_score: '',
/** },
* 删除试卷 })
*/
const deleteEvent = (id: number) => { const searchFormRef = ref<FormInstance>()
ElMessageBox.confirm(t('examPapersDeleteTips'), t('warning'),
{ //
confirmButtonText: t('confirm'), const selectData = ref<any[]>([])
cancelButtonText: t('cancel'),
type: 'warning', //
}
).then(() => { /**
deleteExamPapers(id).then(() => { * 获取试卷列表
loadExamPapersList() */
}).catch(() => { const loadExamPapersList = (page: number = 1) => {
}) examPapersTable.loading = true
}) examPapersTable.page = page
}
getExamPapersList({
page: examPapersTable.page,
limit: examPapersTable.limit,
const resetForm = (formEl: FormInstance | undefined) => { ...examPapersTable.searchParam,
if (!formEl) return })
formEl.resetFields() .then((res) => {
loadExamPapersList() examPapersTable.loading = false
} examPapersTable.data = res.data.data
</script> examPapersTable.total = res.data.total
})
<style lang="scss" scoped> .catch(() => {
/* 多行超出隐藏 */ examPapersTable.loading = false
.multi-hidden { })
word-break: break-all; }
text-overflow: ellipsis; loadExamPapersList()
overflow: hidden;
display: -webkit-box; const editExamPapersDialog: Record<string, any> | null = ref(null)
-webkit-line-clamp: 2;
-webkit-box-orient: vertical; /**
} * 添加试卷
</style> */
const addEvent = () => {
editExamPapersDialog.value.setFormData()
editExamPapersDialog.value.showDialog = true
}
/**
* 编辑试卷
* @param data
*/
const editEvent = (data: any) => {
editExamPapersDialog.value.setFormData(data)
editExamPapersDialog.value.showDialog = true
}
/**
* 删除试卷
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('examPapersDeleteTips'), t('warning'), {
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}).then(() => {
deleteExamPapers(id)
.then(() => {
loadExamPapersList()
})
.catch(() => {})
})
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadExamPapersList()
}
</script>
<style lang="scss" scoped>
/* 多行超出隐藏 */
.multi-hidden {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
</style>

583
admin/src/app/views/exam_questions/exam_questions.vue

@ -1,223 +1,360 @@
<template> <template>
<div class="main-container"> <div class="main-container">
<el-card class="box-card !border-none" shadow="never"> <el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<div class="flex justify-between items-center"> <span class="text-lg">{{ pageName }}</span>
<span class="text-lg">{{pageName}}</span> <el-button type="primary" @click="addEvent">
<el-button type="primary" @click="addEvent"> {{ t('addExamQuestions') }}
{{ t('addExamQuestions') }} </el-button>
</el-button> </div>
</div>
<el-card
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> class="box-card !border-none my-[10px] table-search-wrap"
<el-form :inline="true" :model="examQuestionsTable.searchParam" ref="searchFormRef"> shadow="never"
<el-form-item :label="t('questionType')" prop="question_type"> >
<el-input v-model="examQuestionsTable.searchParam.question_type" :placeholder="t('questionTypePlaceholder')" /> <el-form
</el-form-item> :inline="true"
<el-form-item :label="t('questionContentType')" prop="question_content_type"> :model="examQuestionsTable.searchParam"
<el-input v-model="examQuestionsTable.searchParam.question_content_type" :placeholder="t('questionContentTypePlaceholder')" /> ref="searchFormRef"
</el-form-item> >
<el-form-item :label="t('questionContent')" prop="question_content"> <el-form-item :label="t('questionType')" prop="question_type">
<el-input v-model="examQuestionsTable.searchParam.question_content" :placeholder="t('questionContentPlaceholder')" /> <el-input
</el-form-item> v-model="examQuestionsTable.searchParam.question_type"
<el-form-item :label="t('optionAContentType')" prop="option_a_content_type"> :placeholder="t('questionTypePlaceholder')"
<el-input v-model="examQuestionsTable.searchParam.option_a_content_type" :placeholder="t('optionAContentTypePlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('optionAContent')" prop="option_a_content"> <el-form-item
<el-input v-model="examQuestionsTable.searchParam.option_a_content" :placeholder="t('optionAContentPlaceholder')" /> :label="t('questionContentType')"
</el-form-item> prop="question_content_type"
<el-form-item :label="t('optionBContentType')" prop="option_b_content_type"> >
<el-input v-model="examQuestionsTable.searchParam.option_b_content_type" :placeholder="t('optionBContentTypePlaceholder')" /> <el-input
</el-form-item> v-model="examQuestionsTable.searchParam.question_content_type"
<el-form-item :label="t('optionBContent')" prop="option_b_content"> :placeholder="t('questionContentTypePlaceholder')"
<el-input v-model="examQuestionsTable.searchParam.option_b_content" :placeholder="t('optionBContentPlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('optionCContentType')" prop="option_c_content_type"> <el-form-item :label="t('questionContent')" prop="question_content">
<el-input v-model="examQuestionsTable.searchParam.option_c_content_type" :placeholder="t('optionCContentTypePlaceholder')" /> <el-input
</el-form-item> v-model="examQuestionsTable.searchParam.question_content"
<el-form-item :label="t('optionCContent')" prop="option_c_content"> :placeholder="t('questionContentPlaceholder')"
<el-input v-model="examQuestionsTable.searchParam.option_c_content" :placeholder="t('optionCContentPlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('optionDContentType')" prop="option_d_content_type"> <el-form-item
<el-input v-model="examQuestionsTable.searchParam.option_d_content_type" :placeholder="t('optionDContentTypePlaceholder')" /> :label="t('optionAContentType')"
</el-form-item> prop="option_a_content_type"
<el-form-item :label="t('optionDContent')" prop="option_d_content"> >
<el-input v-model="examQuestionsTable.searchParam.option_d_content" :placeholder="t('optionDContentPlaceholder')" /> <el-input
</el-form-item> v-model="examQuestionsTable.searchParam.option_a_content_type"
<el-form-item :label="t('correctAnswer')" prop="correct_answer"> :placeholder="t('optionAContentTypePlaceholder')"
<el-input v-model="examQuestionsTable.searchParam.correct_answer" :placeholder="t('correctAnswerPlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item :label="t('optionAContent')" prop="option_a_content">
<el-button type="primary" @click="loadExamQuestionsList()">{{ t('search') }}</el-button> <el-input
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> v-model="examQuestionsTable.searchParam.option_a_content"
</el-form-item> :placeholder="t('optionAContentPlaceholder')"
</el-form> />
</el-card> </el-form-item>
<el-form-item
<div class="mt-[10px]"> :label="t('optionBContentType')"
<el-table :data="examQuestionsTable.data" size="large" v-loading="examQuestionsTable.loading"> prop="option_b_content_type"
<template #empty> >
<span>{{ !examQuestionsTable.loading ? t('emptyData') : '' }}</span> <el-input
</template> v-model="examQuestionsTable.searchParam.option_b_content_type"
<el-table-column prop="question_type" :label="t('questionType')" min-width="120" :show-overflow-tooltip="true"/> :placeholder="t('optionBContentTypePlaceholder')"
/>
<el-table-column prop="question_content_type" :label="t('questionContentType')" min-width="120" :show-overflow-tooltip="true"/> </el-form-item>
<el-form-item :label="t('optionBContent')" prop="option_b_content">
<el-table-column prop="question_content" :label="t('questionContent')" min-width="120" :show-overflow-tooltip="true"/> <el-input
v-model="examQuestionsTable.searchParam.option_b_content"
<el-table-column prop="option_a_content_type" :label="t('optionAContentType')" min-width="120" :show-overflow-tooltip="true"/> :placeholder="t('optionBContentPlaceholder')"
/>
<el-table-column prop="option_a_content" :label="t('optionAContent')" min-width="120" :show-overflow-tooltip="true"/> </el-form-item>
<el-form-item
<el-table-column prop="option_b_content_type" :label="t('optionBContentType')" min-width="120" :show-overflow-tooltip="true"/> :label="t('optionCContentType')"
prop="option_c_content_type"
<el-table-column prop="option_b_content" :label="t('optionBContent')" min-width="120" :show-overflow-tooltip="true"/> >
<el-input
<el-table-column prop="option_c_content_type" :label="t('optionCContentType')" min-width="120" :show-overflow-tooltip="true"/> v-model="examQuestionsTable.searchParam.option_c_content_type"
:placeholder="t('optionCContentTypePlaceholder')"
<el-table-column prop="option_c_content" :label="t('optionCContent')" min-width="120" :show-overflow-tooltip="true"/> />
</el-form-item>
<el-table-column prop="option_d_content_type" :label="t('optionDContentType')" min-width="120" :show-overflow-tooltip="true"/> <el-form-item :label="t('optionCContent')" prop="option_c_content">
<el-input
<el-table-column prop="option_d_content" :label="t('optionDContent')" min-width="120" :show-overflow-tooltip="true"/> v-model="examQuestionsTable.searchParam.option_c_content"
:placeholder="t('optionCContentPlaceholder')"
<el-table-column prop="correct_answer" :label="t('correctAnswer')" min-width="120" :show-overflow-tooltip="true"/> />
</el-form-item>
<el-table-column :label="t('operation')" fixed="right" min-width="120"> <el-form-item
<template #default="{ row }"> :label="t('optionDContentType')"
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button> prop="option_d_content_type"
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button> >
</template> <el-input
</el-table-column> v-model="examQuestionsTable.searchParam.option_d_content_type"
:placeholder="t('optionDContentTypePlaceholder')"
</el-table> />
<div class="mt-[16px] flex justify-end"> </el-form-item>
<el-pagination v-model:current-page="examQuestionsTable.page" v-model:page-size="examQuestionsTable.limit" <el-form-item :label="t('optionDContent')" prop="option_d_content">
layout="total, sizes, prev, pager, next, jumper" :total="examQuestionsTable.total" <el-input
@size-change="loadExamQuestionsList()" @current-change="loadExamQuestionsList" /> v-model="examQuestionsTable.searchParam.option_d_content"
</div> :placeholder="t('optionDContentPlaceholder')"
</div> />
</el-form-item>
<el-form-item :label="t('correctAnswer')" prop="correct_answer">
</el-card> <el-input
</div> v-model="examQuestionsTable.searchParam.correct_answer"
</template> :placeholder="t('correctAnswerPlaceholder')"
/>
<script lang="ts" setup> </el-form-item>
import { reactive, ref, watch } from 'vue'
import { t } from '@/lang' <el-form-item>
import { useDictionary } from '@/app/api/dict' <el-button type="primary" @click="loadExamQuestionsList()">{{
import { getExamQuestionsList, deleteExamQuestions } from '@/app/api/exam_questions' t('search')
import { img } from '@/utils/common' }}</el-button>
import { ElMessageBox,FormInstance } from 'element-plus' <el-button @click="resetForm(searchFormRef)">{{
import { useRouter } from 'vue-router' t('reset')
import { useRoute } from 'vue-router' }}</el-button>
const route = useRoute() </el-form-item>
const pageName = route.meta.title; </el-form>
</el-card>
let examQuestionsTable = reactive({
page: 1, <div class="mt-[10px]">
limit: 10, <el-table
total: 0, :data="examQuestionsTable.data"
loading: true, size="large"
data: [], v-loading="examQuestionsTable.loading"
searchParam:{ >
"question_type":"", <template #empty>
"question_content_type":"", <span>{{ !examQuestionsTable.loading ? t('emptyData') : '' }}</span>
"question_content":"", </template>
"option_a_content_type":"", <el-table-column
"option_a_content":"", prop="question_type"
"option_b_content_type":"", :label="t('questionType')"
"option_b_content":"", min-width="120"
"option_c_content_type":"", :show-overflow-tooltip="true"
"option_c_content":"", />
"option_d_content_type":"",
"option_d_content":"", <el-table-column
"correct_answer":"" prop="question_content_type"
} :label="t('questionContentType')"
}) min-width="120"
:show-overflow-tooltip="true"
const searchFormRef = ref<FormInstance>() />
// <el-table-column
const selectData = ref<any[]>([]) prop="question_content"
:label="t('questionContent')"
// min-width="120"
:show-overflow-tooltip="true"
/>
/**
* 获取试题列表 <el-table-column
*/ prop="option_a_content_type"
const loadExamQuestionsList = (page: number = 1) => { :label="t('optionAContentType')"
examQuestionsTable.loading = true min-width="120"
examQuestionsTable.page = page :show-overflow-tooltip="true"
/>
getExamQuestionsList({
page: examQuestionsTable.page, <el-table-column
limit: examQuestionsTable.limit, prop="option_a_content"
...examQuestionsTable.searchParam :label="t('optionAContent')"
}).then(res => { min-width="120"
examQuestionsTable.loading = false :show-overflow-tooltip="true"
examQuestionsTable.data = res.data.data />
examQuestionsTable.total = res.data.total
}).catch(() => { <el-table-column
examQuestionsTable.loading = false prop="option_b_content_type"
}) :label="t('optionBContentType')"
} min-width="120"
loadExamQuestionsList() :show-overflow-tooltip="true"
/>
const router = useRouter()
<el-table-column
/** prop="option_b_content"
* 添加试题 :label="t('optionBContent')"
*/ min-width="120"
const addEvent = () => { :show-overflow-tooltip="true"
router.push('/exam_questions/exam_questions_edit') />
}
<el-table-column
/** prop="option_c_content_type"
* 编辑试题 :label="t('optionCContentType')"
* @param data min-width="120"
*/ :show-overflow-tooltip="true"
const editEvent = (data: any) => { />
router.push('/exam_questions/exam_questions_edit?id='+data.id)
} <el-table-column
prop="option_c_content"
/** :label="t('optionCContent')"
* 删除试题 min-width="120"
*/ :show-overflow-tooltip="true"
const deleteEvent = (id: number) => { />
ElMessageBox.confirm(t('examQuestionsDeleteTips'), t('warning'),
{ <el-table-column
confirmButtonText: t('confirm'), prop="option_d_content_type"
cancelButtonText: t('cancel'), :label="t('optionDContentType')"
type: 'warning', min-width="120"
} :show-overflow-tooltip="true"
).then(() => { />
deleteExamQuestions(id).then(() => {
loadExamQuestionsList() <el-table-column
}).catch(() => { prop="option_d_content"
}) :label="t('optionDContent')"
}) min-width="120"
} :show-overflow-tooltip="true"
/>
<el-table-column
const resetForm = (formEl: FormInstance | undefined) => { prop="correct_answer"
if (!formEl) return :label="t('correctAnswer')"
formEl.resetFields() min-width="120"
loadExamQuestionsList() :show-overflow-tooltip="true"
} />
</script>
<el-table-column
<style lang="scss" scoped> :label="t('operation')"
/* 多行超出隐藏 */ fixed="right"
.multi-hidden { min-width="120"
word-break: break-all; >
text-overflow: ellipsis; <template #default="{ row }">
overflow: hidden; <el-button type="primary" link @click="editEvent(row)">{{
display: -webkit-box; t('edit')
-webkit-line-clamp: 2; }}</el-button>
-webkit-box-orient: vertical; <el-button type="primary" link @click="deleteEvent(row.id)">{{
} t('delete')
</style> }}</el-button>
</template>
</el-table-column>
</el-table>
<div class="mt-[16px] flex justify-end">
<el-pagination
v-model:current-page="examQuestionsTable.page"
v-model:page-size="examQuestionsTable.limit"
layout="total, sizes, prev, pager, next, jumper"
:total="examQuestionsTable.total"
@size-change="loadExamQuestionsList()"
@current-change="loadExamQuestionsList"
/>
</div>
</div>
</el-card>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref, watch } from 'vue'
import { t } from '@/lang'
import { useDictionary } from '@/app/api/dict'
import {
getExamQuestionsList,
deleteExamQuestions,
} from '@/app/api/exam_questions'
import { img } from '@/utils/common'
import { ElMessageBox, FormInstance } from 'element-plus'
import { useRouter } from 'vue-router'
import { useRoute } from 'vue-router'
const route = useRoute()
const pageName = route.meta.title
let examQuestionsTable = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {
question_type: '',
question_content_type: '',
question_content: '',
option_a_content_type: '',
option_a_content: '',
option_b_content_type: '',
option_b_content: '',
option_c_content_type: '',
option_c_content: '',
option_d_content_type: '',
option_d_content: '',
correct_answer: '',
},
})
const searchFormRef = ref<FormInstance>()
//
const selectData = ref<any[]>([])
//
/**
* 获取试题列表
*/
const loadExamQuestionsList = (page: number = 1) => {
examQuestionsTable.loading = true
examQuestionsTable.page = page
getExamQuestionsList({
page: examQuestionsTable.page,
limit: examQuestionsTable.limit,
...examQuestionsTable.searchParam,
})
.then((res) => {
examQuestionsTable.loading = false
examQuestionsTable.data = res.data.data
examQuestionsTable.total = res.data.total
})
.catch(() => {
examQuestionsTable.loading = false
})
}
loadExamQuestionsList()
const router = useRouter()
/**
* 添加试题
*/
const addEvent = () => {
router.push('/exam_questions/exam_questions_edit')
}
/**
* 编辑试题
* @param data
*/
const editEvent = (data: any) => {
router.push('/exam_questions/exam_questions_edit?id=' + data.id)
}
/**
* 删除试题
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('examQuestionsDeleteTips'), t('warning'), {
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}).then(() => {
deleteExamQuestions(id)
.then(() => {
loadExamQuestionsList()
})
.catch(() => {})
})
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadExamQuestionsList()
}
</script>
<style lang="scss" scoped>
/* 多行超出隐藏 */
.multi-hidden {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
</style>

599
admin/src/app/views/exam_questions/exam_questions_edit.vue

@ -1,250 +1,349 @@
<template> <template>
<div class="main-container"> <div class="main-container">
<div class="detail-head"> <div class="detail-head">
<div class="left" @click="back()"> <div class="left" @click="back()">
<span class="iconfont iconxiangzuojiantou !text-xs"></span> <span class="iconfont iconxiangzuojiantou !text-xs"></span>
<span class="ml-[1px]">{{t('returnToPreviousPage')}}</span> <span class="ml-[1px]">{{ t('returnToPreviousPage') }}</span>
</div> </div>
<span class="adorn">|</span> <span class="adorn">|</span>
<span class="right">{{ pageName }}</span> <span class="right">{{ pageName }}</span>
</div> </div>
<el-card class="box-card !border-none" shadow="never"> <el-card class="box-card !border-none" shadow="never">
<el-form :model="formData" label-width="90px" ref="formRef" :rules="formRules" class="page-form"> <el-form
<el-form-item :label="t('questionType')" prop="question_type"> :model="formData"
<el-input v-model="formData.question_type" clearable :placeholder="t('questionTypePlaceholder')" class="input-width" /> label-width="90px"
</el-form-item> ref="formRef"
:rules="formRules"
<el-form-item :label="t('questionContentType')" prop="question_content_type"> class="page-form"
<el-input v-model="formData.question_content_type" clearable :placeholder="t('questionContentTypePlaceholder')" class="input-width" /> >
</el-form-item> <el-form-item :label="t('questionType')" prop="question_type">
<el-input
<el-form-item :label="t('questionContent')" prop="question_content"> v-model="formData.question_type"
<el-input v-model="formData.question_content" clearable :placeholder="t('questionContentPlaceholder')" class="input-width" /> clearable
</el-form-item> :placeholder="t('questionTypePlaceholder')"
class="input-width"
<el-form-item :label="t('optionAContentType')" > />
<el-input v-model="formData.option_a_content_type" clearable :placeholder="t('optionAContentTypePlaceholder')" class="input-width" /> </el-form-item>
</el-form-item>
<el-form-item
<el-form-item :label="t('optionAContent')" > :label="t('questionContentType')"
<el-input v-model="formData.option_a_content" clearable :placeholder="t('optionAContentPlaceholder')" class="input-width" /> prop="question_content_type"
</el-form-item> >
<el-input
<el-form-item :label="t('optionBContentType')" > v-model="formData.question_content_type"
<el-input v-model="formData.option_b_content_type" clearable :placeholder="t('optionBContentTypePlaceholder')" class="input-width" /> clearable
</el-form-item> :placeholder="t('questionContentTypePlaceholder')"
class="input-width"
<el-form-item :label="t('optionBContent')" > />
<el-input v-model="formData.option_b_content" clearable :placeholder="t('optionBContentPlaceholder')" class="input-width" /> </el-form-item>
</el-form-item>
<el-form-item :label="t('questionContent')" prop="question_content">
<el-form-item :label="t('optionCContentType')" > <el-input
<el-input v-model="formData.option_c_content_type" clearable :placeholder="t('optionCContentTypePlaceholder')" class="input-width" /> v-model="formData.question_content"
</el-form-item> clearable
:placeholder="t('questionContentPlaceholder')"
<el-form-item :label="t('optionCContent')" > class="input-width"
<el-input v-model="formData.option_c_content" clearable :placeholder="t('optionCContentPlaceholder')" class="input-width" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('optionDContentType')" > <el-form-item :label="t('optionAContentType')">
<el-input v-model="formData.option_d_content_type" clearable :placeholder="t('optionDContentTypePlaceholder')" class="input-width" /> <el-input
</el-form-item> v-model="formData.option_a_content_type"
clearable
<el-form-item :label="t('optionDContent')" > :placeholder="t('optionAContentTypePlaceholder')"
<el-input v-model="formData.option_d_content" clearable :placeholder="t('optionDContentPlaceholder')" class="input-width" /> class="input-width"
</el-form-item> />
</el-form-item>
<el-form-item :label="t('correctAnswer')" prop="correct_answer">
<el-input v-model="formData.correct_answer" clearable :placeholder="t('correctAnswerPlaceholder')" class="input-width" /> <el-form-item :label="t('optionAContent')">
</el-form-item> <el-input
v-model="formData.option_a_content"
</el-form> clearable
</el-card> :placeholder="t('optionAContentPlaceholder')"
<div class="fixed-footer-wrap"> class="input-width"
<div class="fixed-footer"> />
<el-button type="primary" @click="onSave(formRef)">{{ t('save') }}</el-button> </el-form-item>
<el-button @click="back()">{{ t('cancel') }}</el-button>
</div> <el-form-item :label="t('optionBContentType')">
</div> <el-input
</div> v-model="formData.option_b_content_type"
</template> clearable
:placeholder="t('optionBContentTypePlaceholder')"
<script lang="ts" setup> class="input-width"
import { ref, reactive, computed, watch } from 'vue' />
import { t } from '@/lang' </el-form-item>
import { useDictionary } from '@/app/api/dict'
import type { FormInstance } from 'element-plus' <el-form-item :label="t('optionBContent')">
import { getExamQuestionsInfo,addExamQuestions,editExamQuestions } from '@/app/api/exam_questions'; <el-input
import { useRoute } from 'vue-router' v-model="formData.option_b_content"
clearable
const route = useRoute() :placeholder="t('optionBContentPlaceholder')"
const id:number = parseInt(route.query.id); class="input-width"
const loading = ref(false) />
const pageName = route.meta.title </el-form-item>
<el-form-item :label="t('optionCContentType')">
<el-input
/** v-model="formData.option_c_content_type"
* 表单数据 clearable
*/ :placeholder="t('optionCContentTypePlaceholder')"
const initialFormData = { class="input-width"
id: 0, />
question_type: '', </el-form-item>
question_content_type: '',
question_content: '', <el-form-item :label="t('optionCContent')">
option_a_content_type: '', <el-input
option_a_content: '', v-model="formData.option_c_content"
option_b_content_type: '', clearable
option_b_content: '', :placeholder="t('optionCContentPlaceholder')"
option_c_content_type: '', class="input-width"
option_c_content: '', />
option_d_content_type: '', </el-form-item>
option_d_content: '',
correct_answer: '', <el-form-item :label="t('optionDContentType')">
} <el-input
const formData: Record<string, any> = reactive({ ...initialFormData }) v-model="formData.option_d_content_type"
clearable
const setFormData = async (id:number = 0) => { :placeholder="t('optionDContentTypePlaceholder')"
Object.assign(formData, initialFormData) class="input-width"
const data = await (await getExamQuestionsInfo(id)).data />
Object.keys(formData).forEach((key: string) => { </el-form-item>
if (data[key] != undefined) formData[key] = data[key]
}) <el-form-item :label="t('optionDContent')">
} <el-input
if(id) setFormData(id); v-model="formData.option_d_content"
clearable
const formRef = ref<FormInstance>() :placeholder="t('optionDContentPlaceholder')"
// class="input-width"
const selectData = ref<any[]>([]) />
</el-form-item>
//
<el-form-item :label="t('correctAnswer')" prop="correct_answer">
<el-input
v-model="formData.correct_answer"
// clearable
const formRules = computed(() => { :placeholder="t('correctAnswerPlaceholder')"
return { class="input-width"
question_type: [ />
{ required: true, message: t('questionTypePlaceholder'), trigger: 'blur' }, </el-form-item>
</el-form>
] </el-card>
, <div class="fixed-footer-wrap">
question_content_type: [ <div class="fixed-footer">
{ required: true, message: t('questionContentTypePlaceholder'), trigger: 'blur' }, <el-button type="primary" @click="onSave(formRef)">{{
t('save')
] }}</el-button>
, <el-button @click="back()">{{ t('cancel') }}</el-button>
question_content: [ </div>
{ required: true, message: t('questionContentPlaceholder'), trigger: 'blur' }, </div>
</div>
] </template>
,
option_a_content_type: [ <script lang="ts" setup>
{ required: true, message: t('optionAContentTypePlaceholder'), trigger: 'blur' }, import { ref, reactive, computed, watch } from 'vue'
import { t } from '@/lang'
] import { useDictionary } from '@/app/api/dict'
, import type { FormInstance } from 'element-plus'
option_a_content: [ import {
{ required: true, message: t('optionAContentPlaceholder'), trigger: 'blur' }, getExamQuestionsInfo,
addExamQuestions,
] editExamQuestions,
, } from '@/app/api/exam_questions'
option_b_content_type: [ import { useRoute } from 'vue-router'
{ required: true, message: t('optionBContentTypePlaceholder'), trigger: 'blur' },
const route = useRoute()
] const id: number = parseInt(route.query.id)
, const loading = ref(false)
option_b_content: [ const pageName = route.meta.title
{ required: true, message: t('optionBContentPlaceholder'), trigger: 'blur' },
/**
] * 表单数据
, */
option_c_content_type: [ const initialFormData = {
{ required: true, message: t('optionCContentTypePlaceholder'), trigger: 'blur' }, id: 0,
question_type: '',
] question_content_type: '',
, question_content: '',
option_c_content: [ option_a_content_type: '',
{ required: true, message: t('optionCContentPlaceholder'), trigger: 'blur' }, option_a_content: '',
option_b_content_type: '',
] option_b_content: '',
, option_c_content_type: '',
option_d_content_type: [ option_c_content: '',
{ required: true, message: t('optionDContentTypePlaceholder'), trigger: 'blur' }, option_d_content_type: '',
option_d_content: '',
] correct_answer: '',
, }
option_d_content: [ const formData: Record<string, any> = reactive({ ...initialFormData })
{ required: true, message: t('optionDContentPlaceholder'), trigger: 'blur' },
const setFormData = async (id: number = 0) => {
] Object.assign(formData, initialFormData)
, const data = await (await getExamQuestionsInfo(id)).data
correct_answer: [ Object.keys(formData).forEach((key: string) => {
{ required: true, message: t('correctAnswerPlaceholder'), trigger: 'blur' }, if (data[key] != undefined) formData[key] = data[key]
})
] }
, if (id) setFormData(id)
}
}) const formRef = ref<FormInstance>()
//
const onSave = async (formEl: FormInstance | undefined) => { const selectData = ref<any[]>([])
if (loading.value || !formEl) return
await formEl.validate(async (valid) => { //
if (valid) {
loading.value = true //
let data = formData const formRules = computed(() => {
return {
const save = id ? editExamQuestions : addExamQuestions question_type: [
save(data).then(res => { {
loading.value = false required: true,
history.back() message: t('questionTypePlaceholder'),
}).catch(err => { trigger: 'blur',
loading.value = false },
}) ],
question_content_type: [
} {
}) required: true,
} message: t('questionContentTypePlaceholder'),
trigger: 'blur',
// },
const mobileVerify = (rule: any, value: any, callback: any) => { ],
if (value && !/^1[3-9]\d{9}$/.test(value)) { question_content: [
callback(new Error(t('generateMobile'))) {
} else { required: true,
callback() message: t('questionContentPlaceholder'),
} trigger: 'blur',
} },
],
// option_a_content_type: [
const idCardVerify = (rule: any, value: any, callback: any) => { {
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) { required: true,
callback(new Error(t('generateIdCard'))) message: t('optionAContentTypePlaceholder'),
} else { trigger: 'blur',
callback() },
} ],
} option_a_content: [
{
// required: true,
const emailVerify = (rule: any, value: any, callback: any) => { message: t('optionAContentPlaceholder'),
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) { trigger: 'blur',
callback(new Error(t('generateEmail'))) },
} else { ],
callback() option_b_content_type: [
} {
} required: true,
message: t('optionBContentTypePlaceholder'),
trigger: 'blur',
// },
const numberVerify = (rule: any, value: any, callback: any) => { ],
if (!Number.isInteger(value)) { option_b_content: [
callback(new Error(t('generateNumber'))) {
} else { required: true,
callback() message: t('optionBContentPlaceholder'),
} trigger: 'blur',
} },
const back = () => { ],
history.back() option_c_content_type: [
} {
</script> required: true,
message: t('optionCContentTypePlaceholder'),
<style lang="scss" scoped></style> trigger: 'blur',
},
],
option_c_content: [
{
required: true,
message: t('optionCContentPlaceholder'),
trigger: 'blur',
},
],
option_d_content_type: [
{
required: true,
message: t('optionDContentTypePlaceholder'),
trigger: 'blur',
},
],
option_d_content: [
{
required: true,
message: t('optionDContentPlaceholder'),
trigger: 'blur',
},
],
correct_answer: [
{
required: true,
message: t('correctAnswerPlaceholder'),
trigger: 'blur',
},
],
}
})
const onSave = async (formEl: FormInstance | undefined) => {
if (loading.value || !formEl) return
await formEl.validate(async (valid) => {
if (valid) {
loading.value = true
let data = formData
const save = id ? editExamQuestions : addExamQuestions
save(data)
.then((res) => {
loading.value = false
history.back()
})
.catch((err) => {
loading.value = false
})
}
})
}
//
const mobileVerify = (rule: any, value: any, callback: any) => {
if (value && !/^1[3-9]\d{9}$/.test(value)) {
callback(new Error(t('generateMobile')))
} else {
callback()
}
}
//
const idCardVerify = (rule: any, value: any, callback: any) => {
if (
value &&
!/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
value
)
) {
callback(new Error(t('generateIdCard')))
} else {
callback()
}
}
//
const emailVerify = (rule: any, value: any, callback: any) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail')))
} else {
callback()
}
}
//
const numberVerify = (rule: any, value: any, callback: any) => {
if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber')))
} else {
callback()
}
}
const back = () => {
history.back()
}
</script>
<style lang="scss" scoped></style>

452
admin/src/app/views/exam_records/components/exam-records-edit.vue

@ -1,203 +1,249 @@
<template> <template>
<el-dialog v-model="showDialog" :title="formData.id ? t('updateExamRecords') : t('addExamRecords')" width="50%" class="diy-dialog-wrap" :destroy-on-close="true"> <el-dialog
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading"> v-model="showDialog"
<el-form-item :label="t('campusId')" prop="campus_id"> :title="formData.id ? t('updateExamRecords') : t('addExamRecords')"
<el-input v-model="formData.campus_id" clearable :placeholder="t('campusIdPlaceholder')" class="input-width" /> width="50%"
</el-form-item> class="diy-dialog-wrap"
:destroy-on-close="true"
<el-form-item :label="t('userId')" prop="user_id"> >
<el-input v-model="formData.user_id" clearable :placeholder="t('userIdPlaceholder')" class="input-width" /> <el-form
</el-form-item> :model="formData"
label-width="120px"
<el-form-item :label="t('paperId')" prop="paper_id"> ref="formRef"
<el-input v-model="formData.paper_id" clearable :placeholder="t('paperIdPlaceholder')" class="input-width" /> :rules="formRules"
</el-form-item> class="page-form"
v-loading="loading"
<el-form-item :label="t('score')" > >
<el-input v-model="formData.score" clearable :placeholder="t('scorePlaceholder')" class="input-width" /> <el-form-item :label="t('campusId')" prop="campus_id">
</el-form-item> <el-input
v-model="formData.campus_id"
<el-form-item :label="t('status')" > clearable
<el-input v-model="formData.status" clearable :placeholder="t('statusPlaceholder')" class="input-width" /> :placeholder="t('campusIdPlaceholder')"
</el-form-item> class="input-width"
/>
<el-form-item :label="t('startTime')" > </el-form-item>
<el-input v-model="formData.start_time" clearable :placeholder="t('startTimePlaceholder')" class="input-width" />
</el-form-item> <el-form-item :label="t('userId')" prop="user_id">
<el-input
<el-form-item :label="t('endTime')" > v-model="formData.user_id"
<el-input v-model="formData.end_time" clearable :placeholder="t('endTimePlaceholder')" class="input-width" /> clearable
</el-form-item> :placeholder="t('userIdPlaceholder')"
class="input-width"
</el-form> />
</el-form-item>
<template #footer>
<span class="dialog-footer"> <el-form-item :label="t('paperId')" prop="paper_id">
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button> <el-input
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{ v-model="formData.paper_id"
t('confirm') clearable
}}</el-button> :placeholder="t('paperIdPlaceholder')"
</span> class="input-width"
</template> />
</el-dialog> </el-form-item>
</template>
<el-form-item :label="t('score')">
<script lang="ts" setup> <el-input
import { ref, reactive, computed, watch } from 'vue' v-model="formData.score"
import { useDictionary } from '@/app/api/dict' clearable
import { t } from '@/lang' :placeholder="t('scorePlaceholder')"
import type { FormInstance } from 'element-plus' class="input-width"
import { addExamRecords, editExamRecords, getExamRecordsInfo } from '@/app/api/exam_records' />
</el-form-item>
let showDialog = ref(false)
const loading = ref(false) <el-form-item :label="t('status')">
<el-input
/** v-model="formData.status"
* 表单数据 clearable
*/ :placeholder="t('statusPlaceholder')"
const initialFormData = { class="input-width"
id: '', />
campus_id: '', </el-form-item>
user_id: '',
paper_id: '', <el-form-item :label="t('startTime')">
score: '', <el-input
status: '', v-model="formData.start_time"
start_time: '', clearable
end_time: '', :placeholder="t('startTimePlaceholder')"
} class="input-width"
const formData: Record<string, any> = reactive({ ...initialFormData }) />
</el-form-item>
const formRef = ref<FormInstance>()
<el-form-item :label="t('endTime')">
// <el-input
const formRules = computed(() => { v-model="formData.end_time"
return { clearable
campus_id: [ :placeholder="t('endTimePlaceholder')"
{ required: true, message: t('campusIdPlaceholder'), trigger: 'blur' }, class="input-width"
/>
] </el-form-item>
, </el-form>
user_id: [
{ required: true, message: t('userIdPlaceholder'), trigger: 'blur' }, <template #footer>
<span class="dialog-footer">
] <el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
, <el-button
paper_id: [ type="primary"
{ required: true, message: t('paperIdPlaceholder'), trigger: 'blur' }, :loading="loading"
@click="confirm(formRef)"
] >{{ t('confirm') }}</el-button
, >
score: [ </span>
{ required: true, message: t('scorePlaceholder'), trigger: 'blur' }, </template>
</el-dialog>
] </template>
,
status: [ <script lang="ts" setup>
{ required: true, message: t('statusPlaceholder'), trigger: 'blur' }, import { ref, reactive, computed, watch } from 'vue'
import { useDictionary } from '@/app/api/dict'
] import { t } from '@/lang'
, import type { FormInstance } from 'element-plus'
start_time: [ import {
{ required: true, message: t('startTimePlaceholder'), trigger: 'blur' }, addExamRecords,
editExamRecords,
] getExamRecordsInfo,
, } from '@/app/api/exam_records'
end_time: [
{ required: true, message: t('endTimePlaceholder'), trigger: 'blur' }, let showDialog = ref(false)
const loading = ref(false)
]
, /**
} * 表单数据
}) */
const initialFormData = {
const emit = defineEmits(['complete']) id: '',
campus_id: '',
/** user_id: '',
* 确认 paper_id: '',
* @param formEl score: '',
*/ status: '',
const confirm = async (formEl: FormInstance | undefined) => { start_time: '',
if (loading.value || !formEl) return end_time: '',
let save = formData.id ? editExamRecords : addExamRecords }
const formData: Record<string, any> = reactive({ ...initialFormData })
await formEl.validate(async (valid) => {
if (valid) { const formRef = ref<FormInstance>()
loading.value = true
//
let data = formData const formRules = computed(() => {
return {
save(data).then(res => { campus_id: [
loading.value = false { required: true, message: t('campusIdPlaceholder'), trigger: 'blur' },
showDialog.value = false ],
emit('complete') user_id: [
}).catch(err => { { required: true, message: t('userIdPlaceholder'), trigger: 'blur' },
loading.value = false ],
}) paper_id: [
} { required: true, message: t('paperIdPlaceholder'), trigger: 'blur' },
}) ],
} score: [
{ required: true, message: t('scorePlaceholder'), trigger: 'blur' },
// ],
status: [
{ required: true, message: t('statusPlaceholder'), trigger: 'blur' },
],
const setFormData = async (row: any = null) => { start_time: [
Object.assign(formData, initialFormData) { required: true, message: t('startTimePlaceholder'), trigger: 'blur' },
loading.value = true ],
if(row){ end_time: [
const data = await (await getExamRecordsInfo(row.id)).data { required: true, message: t('endTimePlaceholder'), trigger: 'blur' },
if (data) Object.keys(formData).forEach((key: string) => { ],
if (data[key] != undefined) formData[key] = data[key] }
}) })
}
loading.value = false const emit = defineEmits(['complete'])
}
/**
// * 确认
const mobileVerify = (rule: any, value: any, callback: any) => { * @param formEl
if (value && !/^1[3-9]\d{9}$/.test(value)) { */
callback(new Error(t('generateMobile'))) const confirm = async (formEl: FormInstance | undefined) => {
} else { if (loading.value || !formEl) return
callback() let save = formData.id ? editExamRecords : addExamRecords
}
} await formEl.validate(async (valid) => {
if (valid) {
// loading.value = true
const idCardVerify = (rule: any, value: any, callback: any) => {
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) { let data = formData
callback(new Error(t('generateIdCard')))
} else { save(data)
callback() .then((res) => {
} loading.value = false
} showDialog.value = false
emit('complete')
// })
const emailVerify = (rule: any, value: any, callback: any) => { .catch((err) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) { loading.value = false
callback(new Error(t('generateEmail'))) })
} else { }
callback() })
} }
}
//
//
const numberVerify = (rule: any, value: any, callback: any) => { const setFormData = async (row: any = null) => {
if (!Number.isInteger(value)) { Object.assign(formData, initialFormData)
callback(new Error(t('generateNumber'))) loading.value = true
} else { if (row) {
callback() const data = await (await getExamRecordsInfo(row.id)).data
} if (data)
} Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key]
defineExpose({ })
showDialog, }
setFormData loading.value = false
}) }
</script>
//
<style lang="scss" scoped></style> const mobileVerify = (rule: any, value: any, callback: any) => {
<style lang="scss"> if (value && !/^1[3-9]\d{9}$/.test(value)) {
.diy-dialog-wrap .el-form-item__label{ callback(new Error(t('generateMobile')))
height: auto !important; } else {
} callback()
</style> }
}
//
const idCardVerify = (rule: any, value: any, callback: any) => {
if (
value &&
!/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
value
)
) {
callback(new Error(t('generateIdCard')))
} else {
callback()
}
}
//
const emailVerify = (rule: any, value: any, callback: any) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail')))
} else {
callback()
}
}
//
const numberVerify = (rule: any, value: any, callback: any) => {
if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber')))
} else {
callback()
}
}
defineExpose({
showDialog,
setFormData,
})
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.diy-dialog-wrap .el-form-item__label {
height: auto !important;
}
</style>

471
admin/src/app/views/exam_records/exam_records.vue

@ -1,195 +1,276 @@
<template> <template>
<div class="main-container"> <div class="main-container">
<el-card class="box-card !border-none" shadow="never"> <el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<div class="flex justify-between items-center"> <span class="text-lg">{{ pageName }}</span>
<span class="text-lg">{{pageName}}</span> <el-button type="primary" @click="addEvent">
<el-button type="primary" @click="addEvent"> {{ t('addExamRecords') }}
{{ t('addExamRecords') }} </el-button>
</el-button> </div>
</div>
<el-card
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> class="box-card !border-none my-[10px] table-search-wrap"
<el-form :inline="true" :model="examRecordsTable.searchParam" ref="searchFormRef"> shadow="never"
<el-form-item :label="t('campusId')" prop="campus_id"> >
<el-input v-model="examRecordsTable.searchParam.campus_id" :placeholder="t('campusIdPlaceholder')" /> <el-form
</el-form-item> :inline="true"
<el-form-item :label="t('userId')" prop="user_id"> :model="examRecordsTable.searchParam"
<el-input v-model="examRecordsTable.searchParam.user_id" :placeholder="t('userIdPlaceholder')" /> ref="searchFormRef"
</el-form-item> >
<el-form-item :label="t('paperId')" prop="paper_id"> <el-form-item :label="t('campusId')" prop="campus_id">
<el-input v-model="examRecordsTable.searchParam.paper_id" :placeholder="t('paperIdPlaceholder')" /> <el-input
</el-form-item> v-model="examRecordsTable.searchParam.campus_id"
<el-form-item :label="t('score')" prop="score"> :placeholder="t('campusIdPlaceholder')"
<el-input v-model="examRecordsTable.searchParam.score" :placeholder="t('scorePlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('status')" prop="status"> <el-form-item :label="t('userId')" prop="user_id">
<el-input v-model="examRecordsTable.searchParam.status" :placeholder="t('statusPlaceholder')" /> <el-input
</el-form-item> v-model="examRecordsTable.searchParam.user_id"
<el-form-item :label="t('startTime')" prop="start_time"> :placeholder="t('userIdPlaceholder')"
<el-input v-model="examRecordsTable.searchParam.start_time" :placeholder="t('startTimePlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('endTime')" prop="end_time"> <el-form-item :label="t('paperId')" prop="paper_id">
<el-input v-model="examRecordsTable.searchParam.end_time" :placeholder="t('endTimePlaceholder')" /> <el-input
</el-form-item> v-model="examRecordsTable.searchParam.paper_id"
<el-form-item> :placeholder="t('paperIdPlaceholder')"
<el-button type="primary" @click="loadExamRecordsList()">{{ t('search') }}</el-button> />
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> </el-form-item>
</el-form-item> <el-form-item :label="t('score')" prop="score">
</el-form> <el-input
</el-card> v-model="examRecordsTable.searchParam.score"
:placeholder="t('scorePlaceholder')"
<div class="mt-[10px]"> />
<el-table :data="examRecordsTable.data" size="large" v-loading="examRecordsTable.loading"> </el-form-item>
<template #empty> <el-form-item :label="t('status')" prop="status">
<span>{{ !examRecordsTable.loading ? t('emptyData') : '' }}</span> <el-input
</template> v-model="examRecordsTable.searchParam.status"
<el-table-column prop="campus_id" :label="t('campusId')" min-width="120" :show-overflow-tooltip="true"/> :placeholder="t('statusPlaceholder')"
/>
<el-table-column prop="user_id" :label="t('userId')" min-width="120" :show-overflow-tooltip="true"/> </el-form-item>
<el-form-item :label="t('startTime')" prop="start_time">
<el-table-column prop="paper_id" :label="t('paperId')" min-width="120" :show-overflow-tooltip="true"/> <el-input
v-model="examRecordsTable.searchParam.start_time"
<el-table-column prop="score" :label="t('score')" min-width="120" :show-overflow-tooltip="true"/> :placeholder="t('startTimePlaceholder')"
/>
<el-table-column prop="status" :label="t('status')" min-width="120" :show-overflow-tooltip="true"/> </el-form-item>
<el-form-item :label="t('endTime')" prop="end_time">
<el-table-column prop="start_time" :label="t('startTime')" min-width="120" :show-overflow-tooltip="true"/> <el-input
v-model="examRecordsTable.searchParam.end_time"
<el-table-column prop="end_time" :label="t('endTime')" min-width="120" :show-overflow-tooltip="true"/> :placeholder="t('endTimePlaceholder')"
/>
<el-table-column :label="t('operation')" fixed="right" min-width="120"> </el-form-item>
<template #default="{ row }">
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button> <el-form-item>
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button> <el-button type="primary" @click="loadExamRecordsList()">{{
</template> t('search')
</el-table-column> }}</el-button>
<el-button @click="resetForm(searchFormRef)">{{
</el-table> t('reset')
<div class="mt-[16px] flex justify-end"> }}</el-button>
<el-pagination v-model:current-page="examRecordsTable.page" v-model:page-size="examRecordsTable.limit" </el-form-item>
layout="total, sizes, prev, pager, next, jumper" :total="examRecordsTable.total" </el-form>
@size-change="loadExamRecordsList()" @current-change="loadExamRecordsList" /> </el-card>
</div>
</div> <div class="mt-[10px]">
<el-table
<edit ref="editExamRecordsDialog" @complete="loadExamRecordsList" /> :data="examRecordsTable.data"
</el-card> size="large"
</div> v-loading="examRecordsTable.loading"
</template> >
<template #empty>
<script lang="ts" setup> <span>{{ !examRecordsTable.loading ? t('emptyData') : '' }}</span>
import { reactive, ref, watch } from 'vue' </template>
import { t } from '@/lang' <el-table-column
import { useDictionary } from '@/app/api/dict' prop="campus_id"
import { getExamRecordsList, deleteExamRecords } from '@/app/api/exam_records' :label="t('campusId')"
import { img } from '@/utils/common' min-width="120"
import { ElMessageBox,FormInstance } from 'element-plus' :show-overflow-tooltip="true"
import Edit from '@/app/views/exam_records/components/exam-records-edit.vue' />
import { useRoute } from 'vue-router'
const route = useRoute() <el-table-column
const pageName = route.meta.title; prop="user_id"
:label="t('userId')"
let examRecordsTable = reactive({ min-width="120"
page: 1, :show-overflow-tooltip="true"
limit: 10, />
total: 0,
loading: true, <el-table-column
data: [], prop="paper_id"
searchParam:{ :label="t('paperId')"
"campus_id":"", min-width="120"
"user_id":"", :show-overflow-tooltip="true"
"paper_id":"", />
"score":"",
"status":"", <el-table-column
"start_time":"", prop="score"
"end_time":"" :label="t('score')"
} min-width="120"
}) :show-overflow-tooltip="true"
/>
const searchFormRef = ref<FormInstance>()
<el-table-column
// prop="status"
const selectData = ref<any[]>([]) :label="t('status')"
min-width="120"
// :show-overflow-tooltip="true"
/>
/** <el-table-column
* 获取考试记录列表 prop="start_time"
*/ :label="t('startTime')"
const loadExamRecordsList = (page: number = 1) => { min-width="120"
examRecordsTable.loading = true :show-overflow-tooltip="true"
examRecordsTable.page = page />
getExamRecordsList({ <el-table-column
page: examRecordsTable.page, prop="end_time"
limit: examRecordsTable.limit, :label="t('endTime')"
...examRecordsTable.searchParam min-width="120"
}).then(res => { :show-overflow-tooltip="true"
examRecordsTable.loading = false />
examRecordsTable.data = res.data.data
examRecordsTable.total = res.data.total <el-table-column
}).catch(() => { :label="t('operation')"
examRecordsTable.loading = false fixed="right"
}) min-width="120"
} >
loadExamRecordsList() <template #default="{ row }">
<el-button type="primary" link @click="editEvent(row)">{{
const editExamRecordsDialog: Record<string, any> | null = ref(null) t('edit')
}}</el-button>
/** <el-button type="primary" link @click="deleteEvent(row.id)">{{
* 添加考试记录 t('delete')
*/ }}</el-button>
const addEvent = () => { </template>
editExamRecordsDialog.value.setFormData() </el-table-column>
editExamRecordsDialog.value.showDialog = true </el-table>
} <div class="mt-[16px] flex justify-end">
<el-pagination
/** v-model:current-page="examRecordsTable.page"
* 编辑考试记录 v-model:page-size="examRecordsTable.limit"
* @param data layout="total, sizes, prev, pager, next, jumper"
*/ :total="examRecordsTable.total"
const editEvent = (data: any) => { @size-change="loadExamRecordsList()"
editExamRecordsDialog.value.setFormData(data) @current-change="loadExamRecordsList"
editExamRecordsDialog.value.showDialog = true />
} </div>
</div>
/**
* 删除考试记录 <edit ref="editExamRecordsDialog" @complete="loadExamRecordsList" />
*/ </el-card>
const deleteEvent = (id: number) => { </div>
ElMessageBox.confirm(t('examRecordsDeleteTips'), t('warning'), </template>
{
confirmButtonText: t('confirm'), <script lang="ts" setup>
cancelButtonText: t('cancel'), import { reactive, ref, watch } from 'vue'
type: 'warning', import { t } from '@/lang'
} import { useDictionary } from '@/app/api/dict'
).then(() => { import { getExamRecordsList, deleteExamRecords } from '@/app/api/exam_records'
deleteExamRecords(id).then(() => { import { img } from '@/utils/common'
loadExamRecordsList() import { ElMessageBox, FormInstance } from 'element-plus'
}).catch(() => { import Edit from '@/app/views/exam_records/components/exam-records-edit.vue'
}) import { useRoute } from 'vue-router'
}) const route = useRoute()
} const pageName = route.meta.title
let examRecordsTable = reactive({
page: 1,
const resetForm = (formEl: FormInstance | undefined) => { limit: 10,
if (!formEl) return total: 0,
formEl.resetFields() loading: true,
loadExamRecordsList() data: [],
} searchParam: {
</script> campus_id: '',
user_id: '',
<style lang="scss" scoped> paper_id: '',
/* 多行超出隐藏 */ score: '',
.multi-hidden { status: '',
word-break: break-all; start_time: '',
text-overflow: ellipsis; end_time: '',
overflow: hidden; },
display: -webkit-box; })
-webkit-line-clamp: 2;
-webkit-box-orient: vertical; const searchFormRef = ref<FormInstance>()
}
</style> //
const selectData = ref<any[]>([])
//
/**
* 获取考试记录列表
*/
const loadExamRecordsList = (page: number = 1) => {
examRecordsTable.loading = true
examRecordsTable.page = page
getExamRecordsList({
page: examRecordsTable.page,
limit: examRecordsTable.limit,
...examRecordsTable.searchParam,
})
.then((res) => {
examRecordsTable.loading = false
examRecordsTable.data = res.data.data
examRecordsTable.total = res.data.total
})
.catch(() => {
examRecordsTable.loading = false
})
}
loadExamRecordsList()
const editExamRecordsDialog: Record<string, any> | null = ref(null)
/**
* 添加考试记录
*/
const addEvent = () => {
editExamRecordsDialog.value.setFormData()
editExamRecordsDialog.value.showDialog = true
}
/**
* 编辑考试记录
* @param data
*/
const editEvent = (data: any) => {
editExamRecordsDialog.value.setFormData(data)
editExamRecordsDialog.value.showDialog = true
}
/**
* 删除考试记录
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('examRecordsDeleteTips'), t('warning'), {
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}).then(() => {
deleteExamRecords(id)
.then(() => {
loadExamRecordsList()
})
.catch(() => {})
})
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadExamRecordsList()
}
</script>
<style lang="scss" scoped>
/* 多行超出隐藏 */
.multi-hidden {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
</style>

420
admin/src/app/views/market_performance/components/market-performance-edit.vue

@ -1,189 +1,231 @@
<template> <template>
<el-dialog v-model="showDialog" :title="formData.id ? t('updateMarketPerformance') : t('addMarketPerformance')" width="50%" class="diy-dialog-wrap" :destroy-on-close="true"> <el-dialog
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading"> v-model="showDialog"
<el-form-item :label="t('personnelId')" > :title="
<el-select class="input-width" v-model="formData.personnel_id" clearable :placeholder="t('personnelIdPlaceholder')"> formData.id ? t('updateMarketPerformance') : t('addMarketPerformance')
<el-option label="请选择" value=""></el-option> "
<el-option width="50%"
v-for="(item, index) in personnelIdList" class="diy-dialog-wrap"
:key="index" :destroy-on-close="true"
:label="item['name']" >
:value="item['id']" <el-form
/> :model="formData"
</el-select> label-width="120px"
</el-form-item> ref="formRef"
:rules="formRules"
<el-form-item :label="t('campusId')" > class="page-form"
<el-select class="input-width" v-model="formData.campus_id" clearable :placeholder="t('campusIdPlaceholder')"> v-loading="loading"
<el-option label="请选择" value=""></el-option> >
<el-option <el-form-item :label="t('personnelId')">
v-for="(item, index) in campusIdList" <el-select
:key="index" class="input-width"
:label="item['campus_name']" v-model="formData.personnel_id"
:value="item['id']" clearable
/> :placeholder="t('personnelIdPlaceholder')"
</el-select> >
</el-form-item> <el-option label="请选择" value=""></el-option>
<el-option
<el-form-item :label="t('performanceAmount')" > v-for="(item, index) in personnelIdList"
<el-input v-model="formData.performance_amount" clearable :placeholder="t('performanceAmountPlaceholder')" class="input-width" /> :key="index"
</el-form-item> :label="item['name']"
:value="item['id']"
</el-form> />
</el-select>
<template #footer> </el-form-item>
<span class="dialog-footer">
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button> <el-form-item :label="t('campusId')">
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{ <el-select
t('confirm') class="input-width"
}}</el-button> v-model="formData.campus_id"
</span> clearable
</template> :placeholder="t('campusIdPlaceholder')"
</el-dialog> >
</template> <el-option label="请选择" value=""></el-option>
<el-option
<script lang="ts" setup> v-for="(item, index) in campusIdList"
import { ref, reactive, computed, watch } from 'vue' :key="index"
import { useDictionary } from '@/app/api/dict' :label="item['campus_name']"
import { t } from '@/lang' :value="item['id']"
import type { FormInstance } from 'element-plus' />
import { addMarketPerformance, editMarketPerformance, getMarketPerformanceInfo, getWithPersonnelList, getWithCampusList } from '@/app/api/market_performance' </el-select>
</el-form-item>
let showDialog = ref(false)
const loading = ref(false) <el-form-item :label="t('performanceAmount')">
<el-input
/** v-model="formData.performance_amount"
* 表单数据 clearable
*/ :placeholder="t('performanceAmountPlaceholder')"
const initialFormData = { class="input-width"
id: '', />
personnel_id: '', </el-form-item>
campus_id: '', </el-form>
performance_amount: '',
} <template #footer>
const formData: Record<string, any> = reactive({ ...initialFormData }) <span class="dialog-footer">
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
const formRef = ref<FormInstance>() <el-button
type="primary"
// :loading="loading"
const formRules = computed(() => { @click="confirm(formRef)"
return { >{{ t('confirm') }}</el-button
personnel_id: [ >
{ required: true, message: t('personnelIdPlaceholder'), trigger: 'blur' }, </span>
</template>
] </el-dialog>
, </template>
campus_id: [
{ required: true, message: t('campusIdPlaceholder'), trigger: 'blur' }, <script lang="ts" setup>
import { ref, reactive, computed, watch } from 'vue'
] import { useDictionary } from '@/app/api/dict'
, import { t } from '@/lang'
performance_amount: [ import type { FormInstance } from 'element-plus'
{ required: true, message: t('performanceAmountPlaceholder'), trigger: 'blur' }, import {
addMarketPerformance,
] editMarketPerformance,
, getMarketPerformanceInfo,
} getWithPersonnelList,
}) getWithCampusList,
} from '@/app/api/market_performance'
const emit = defineEmits(['complete'])
let showDialog = ref(false)
/** const loading = ref(false)
* 确认
* @param formEl /**
*/ * 表单数据
const confirm = async (formEl: FormInstance | undefined) => { */
if (loading.value || !formEl) return const initialFormData = {
let save = formData.id ? editMarketPerformance : addMarketPerformance id: '',
personnel_id: '',
await formEl.validate(async (valid) => { campus_id: '',
if (valid) { performance_amount: '',
loading.value = true }
const formData: Record<string, any> = reactive({ ...initialFormData })
let data = formData
const formRef = ref<FormInstance>()
save(data).then(res => {
loading.value = false //
showDialog.value = false const formRules = computed(() => {
emit('complete') return {
}).catch(err => { personnel_id: [
loading.value = false { required: true, message: t('personnelIdPlaceholder'), trigger: 'blur' },
}) ],
} campus_id: [
}) { required: true, message: t('campusIdPlaceholder'), trigger: 'blur' },
} ],
performance_amount: [
// {
required: true,
message: t('performanceAmountPlaceholder'),
trigger: 'blur',
const personnelIdList = ref([] as any[]) },
const setPersonnelIdList = async () => { ],
personnelIdList.value = await (await getWithPersonnelList({})).data }
} })
setPersonnelIdList()
const campusIdList = ref([] as any[]) const emit = defineEmits(['complete'])
const setCampusIdList = async () => {
campusIdList.value = await (await getWithCampusList({})).data /**
} * 确认
setCampusIdList() * @param formEl
const setFormData = async (row: any = null) => { */
Object.assign(formData, initialFormData) const confirm = async (formEl: FormInstance | undefined) => {
loading.value = true if (loading.value || !formEl) return
if(row){ let save = formData.id ? editMarketPerformance : addMarketPerformance
const data = await (await getMarketPerformanceInfo(row.id)).data
if (data) Object.keys(formData).forEach((key: string) => { await formEl.validate(async (valid) => {
if (data[key] != undefined) formData[key] = data[key] if (valid) {
}) loading.value = true
}
loading.value = false let data = formData
}
save(data)
// .then((res) => {
const mobileVerify = (rule: any, value: any, callback: any) => { loading.value = false
if (value && !/^1[3-9]\d{9}$/.test(value)) { showDialog.value = false
callback(new Error(t('generateMobile'))) emit('complete')
} else { })
callback() .catch((err) => {
} loading.value = false
} })
}
// })
const idCardVerify = (rule: any, value: any, callback: any) => { }
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) {
callback(new Error(t('generateIdCard'))) //
} else {
callback() const personnelIdList = ref([] as any[])
} const setPersonnelIdList = async () => {
} personnelIdList.value = await (await getWithPersonnelList({})).data
}
// setPersonnelIdList()
const emailVerify = (rule: any, value: any, callback: any) => { const campusIdList = ref([] as any[])
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) { const setCampusIdList = async () => {
callback(new Error(t('generateEmail'))) campusIdList.value = await (await getWithCampusList({})).data
} else { }
callback() setCampusIdList()
} const setFormData = async (row: any = null) => {
} Object.assign(formData, initialFormData)
loading.value = true
// if (row) {
const numberVerify = (rule: any, value: any, callback: any) => { const data = await (await getMarketPerformanceInfo(row.id)).data
if (!Number.isInteger(value)) { if (data)
callback(new Error(t('generateNumber'))) Object.keys(formData).forEach((key: string) => {
} else { if (data[key] != undefined) formData[key] = data[key]
callback() })
} }
} loading.value = false
}
defineExpose({
showDialog, //
setFormData const mobileVerify = (rule: any, value: any, callback: any) => {
}) if (value && !/^1[3-9]\d{9}$/.test(value)) {
</script> callback(new Error(t('generateMobile')))
} else {
<style lang="scss" scoped></style> callback()
<style lang="scss"> }
.diy-dialog-wrap .el-form-item__label{ }
height: auto !important;
} //
</style> const idCardVerify = (rule: any, value: any, callback: any) => {
if (
value &&
!/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
value
)
) {
callback(new Error(t('generateIdCard')))
} else {
callback()
}
}
//
const emailVerify = (rule: any, value: any, callback: any) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail')))
} else {
callback()
}
}
//
const numberVerify = (rule: any, value: any, callback: any) => {
if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber')))
} else {
callback()
}
}
defineExpose({
showDialog,
setFormData,
})
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.diy-dialog-wrap .el-form-item__label {
height: auto !important;
}
</style>

426
admin/src/app/views/market_performance/market_performance.vue

@ -1,186 +1,240 @@
<template> <template>
<div class="main-container"> <div class="main-container">
<el-card class="box-card !border-none" shadow="never"> <el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<div class="flex justify-between items-center"> <span class="text-lg">{{ pageName }}</span>
<span class="text-lg">{{pageName}}</span> <!-- <el-button type="primary" @click="addEvent">
<!-- <el-button type="primary" @click="addEvent"> {{ t('addMarketPerformance') }}
{{ t('addMarketPerformance') }} </el-button> -->
</el-button> --> </div>
</div>
<el-card
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> class="box-card !border-none my-[10px] table-search-wrap"
<el-form :inline="true" :model="marketPerformanceTable.searchParam" ref="searchFormRef"> shadow="never"
>
<el-form-item :label="t('campusId')" prop="campus_id"> <el-form
<el-select class="w-[280px]" v-model="marketPerformanceTable.searchParam.campus_id" clearable :placeholder="t('campusIdPlaceholder')"> :inline="true"
<el-option :model="marketPerformanceTable.searchParam"
v-for="(item, index) in campusIdList" ref="searchFormRef"
:key="index" >
:label="item['campus_name']" <el-form-item :label="t('campusId')" prop="campus_id">
:value="item['id']" <el-select
/> class="w-[280px]"
</el-select> v-model="marketPerformanceTable.searchParam.campus_id"
</el-form-item> clearable
:placeholder="t('campusIdPlaceholder')"
<el-form-item :label="t('performanceAmount')" prop="performance_amount"> >
<el-input v-model="marketPerformanceTable.searchParam.performance_amount" :placeholder="t('performanceAmountPlaceholder')" /> <el-option
</el-form-item> v-for="(item, index) in campusIdList"
<el-form-item> :key="index"
<el-button type="primary" @click="loadMarketPerformanceList()">{{ t('search') }}</el-button> :label="item['campus_name']"
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> :value="item['id']"
</el-form-item> />
</el-form> </el-select>
</el-card> </el-form-item>
<div class="mt-[10px]"> <el-form-item
<el-table :data="marketPerformanceTable.data" size="large" v-loading="marketPerformanceTable.loading"> :label="t('performanceAmount')"
<template #empty> prop="performance_amount"
<span>{{ !marketPerformanceTable.loading ? t('emptyData') : '' }}</span> >
</template> <el-input
<el-table-column prop="personnel_id_name" :label="t('personnelId')" min-width="120" :show-overflow-tooltip="true"/> v-model="marketPerformanceTable.searchParam.performance_amount"
:placeholder="t('performanceAmountPlaceholder')"
<el-table-column prop="campus_id_name" :label="t('campusId')" min-width="120" :show-overflow-tooltip="true"/> />
</el-form-item>
<el-table-column prop="performance_amount" :label="t('performanceAmount')" min-width="120" :show-overflow-tooltip="true"/>
<!-- <el-form-item>
<el-table-column :label="t('operation')" fixed="right" min-width="120"> <el-button type="primary" @click="loadMarketPerformanceList()">{{
<template #default="{ row }"> t('search')
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button> }}</el-button>
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button> <el-button @click="resetForm(searchFormRef)">{{
</template> t('reset')
</el-table-column> --> }}</el-button>
</el-form-item>
</el-table> </el-form>
<div class="mt-[16px] flex justify-end"> </el-card>
<el-pagination v-model:current-page="marketPerformanceTable.page" v-model:page-size="marketPerformanceTable.limit"
layout="total, sizes, prev, pager, next, jumper" :total="marketPerformanceTable.total" <div class="mt-[10px]">
@size-change="loadMarketPerformanceList()" @current-change="loadMarketPerformanceList" /> <el-table
</div> :data="marketPerformanceTable.data"
</div> size="large"
v-loading="marketPerformanceTable.loading"
<edit ref="editMarketPerformanceDialog" @complete="loadMarketPerformanceList" /> >
</el-card> <template #empty>
</div> <span>{{
</template> !marketPerformanceTable.loading ? t('emptyData') : ''
}}</span>
<script lang="ts" setup> </template>
import { reactive, ref, watch } from 'vue' <el-table-column
import { t } from '@/lang' prop="personnel_id_name"
import { useDictionary } from '@/app/api/dict' :label="t('personnelId')"
import { getMarketPerformanceList, deleteMarketPerformance, getWithPersonnelList, getWithCampusList } from '@/app/api/market_performance' min-width="120"
import { img } from '@/utils/common' :show-overflow-tooltip="true"
import { ElMessageBox,FormInstance } from 'element-plus' />
import Edit from '@/app/views/market_performance/components/market-performance-edit.vue'
import { useRoute } from 'vue-router' <el-table-column
const route = useRoute() prop="campus_id_name"
const pageName = route.meta.title; :label="t('campusId')"
min-width="120"
let marketPerformanceTable = reactive({ :show-overflow-tooltip="true"
page: 1, />
limit: 10,
total: 0, <el-table-column
loading: true, prop="performance_amount"
data: [], :label="t('performanceAmount')"
searchParam:{ min-width="120"
"campus_id":"", :show-overflow-tooltip="true"
"performance_amount":"" />
}
}) <!--
<el-table-column :label="t('operation')" fixed="right" min-width="120">
const searchFormRef = ref<FormInstance>() <template #default="{ row }">
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
// <el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button>
const selectData = ref<any[]>([]) </template>
</el-table-column> -->
// </el-table>
<div class="mt-[16px] flex justify-end">
<el-pagination
/** v-model:current-page="marketPerformanceTable.page"
* 获取市场绩效列表 v-model:page-size="marketPerformanceTable.limit"
*/ layout="total, sizes, prev, pager, next, jumper"
const loadMarketPerformanceList = (page: number = 1) => { :total="marketPerformanceTable.total"
marketPerformanceTable.loading = true @size-change="loadMarketPerformanceList()"
marketPerformanceTable.page = page @current-change="loadMarketPerformanceList"
/>
getMarketPerformanceList({ </div>
page: marketPerformanceTable.page, </div>
limit: marketPerformanceTable.limit,
...marketPerformanceTable.searchParam <edit
}).then(res => { ref="editMarketPerformanceDialog"
marketPerformanceTable.loading = false @complete="loadMarketPerformanceList"
marketPerformanceTable.data = res.data.data />
marketPerformanceTable.total = res.data.total </el-card>
}).catch(() => { </div>
marketPerformanceTable.loading = false </template>
})
} <script lang="ts" setup>
loadMarketPerformanceList() import { reactive, ref, watch } from 'vue'
import { t } from '@/lang'
const editMarketPerformanceDialog: Record<string, any> | null = ref(null) import { useDictionary } from '@/app/api/dict'
import {
/** getMarketPerformanceList,
* 添加市场绩效 deleteMarketPerformance,
*/ getWithPersonnelList,
const addEvent = () => { getWithCampusList,
editMarketPerformanceDialog.value.setFormData() } from '@/app/api/market_performance'
editMarketPerformanceDialog.value.showDialog = true import { img } from '@/utils/common'
} import { ElMessageBox, FormInstance } from 'element-plus'
import Edit from '@/app/views/market_performance/components/market-performance-edit.vue'
/** import { useRoute } from 'vue-router'
* 编辑市场绩效 const route = useRoute()
* @param data const pageName = route.meta.title
*/
const editEvent = (data: any) => { let marketPerformanceTable = reactive({
editMarketPerformanceDialog.value.setFormData(data) page: 1,
editMarketPerformanceDialog.value.showDialog = true limit: 10,
} total: 0,
loading: true,
/** data: [],
* 删除市场绩效 searchParam: {
*/ campus_id: '',
const deleteEvent = (id: number) => { performance_amount: '',
ElMessageBox.confirm(t('marketPerformanceDeleteTips'), t('warning'), },
{ })
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'), const searchFormRef = ref<FormInstance>()
type: 'warning',
} //
).then(() => { const selectData = ref<any[]>([])
deleteMarketPerformance(id).then(() => {
loadMarketPerformanceList() //
}).catch(() => {
}) /**
}) * 获取市场绩效列表
} */
const loadMarketPerformanceList = (page: number = 1) => {
marketPerformanceTable.loading = true
const personnelIdList = ref([]) marketPerformanceTable.page = page
const setPersonnelIdList = async () => {
personnelIdList.value = await (await getWithPersonnelList({})).data getMarketPerformanceList({
} page: marketPerformanceTable.page,
setPersonnelIdList() limit: marketPerformanceTable.limit,
const campusIdList = ref([]) ...marketPerformanceTable.searchParam,
const setCampusIdList = async () => { })
campusIdList.value = await (await getWithCampusList({})).data .then((res) => {
} marketPerformanceTable.loading = false
setCampusIdList() marketPerformanceTable.data = res.data.data
marketPerformanceTable.total = res.data.total
const resetForm = (formEl: FormInstance | undefined) => { })
if (!formEl) return .catch(() => {
formEl.resetFields() marketPerformanceTable.loading = false
loadMarketPerformanceList() })
} }
</script> loadMarketPerformanceList()
<style lang="scss" scoped> const editMarketPerformanceDialog: Record<string, any> | null = ref(null)
/* 多行超出隐藏 */
.multi-hidden { /**
word-break: break-all; * 添加市场绩效
text-overflow: ellipsis; */
overflow: hidden; const addEvent = () => {
display: -webkit-box; editMarketPerformanceDialog.value.setFormData()
-webkit-line-clamp: 2; editMarketPerformanceDialog.value.showDialog = true
-webkit-box-orient: vertical; }
}
</style> /**
* 编辑市场绩效
* @param data
*/
const editEvent = (data: any) => {
editMarketPerformanceDialog.value.setFormData(data)
editMarketPerformanceDialog.value.showDialog = true
}
/**
* 删除市场绩效
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('marketPerformanceDeleteTips'), t('warning'), {
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}).then(() => {
deleteMarketPerformance(id)
.then(() => {
loadMarketPerformanceList()
})
.catch(() => {})
})
}
const personnelIdList = ref([])
const setPersonnelIdList = async () => {
personnelIdList.value = await (await getWithPersonnelList({})).data
}
setPersonnelIdList()
const campusIdList = ref([])
const setCampusIdList = async () => {
campusIdList.value = await (await getWithCampusList({})).data
}
setCampusIdList()
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadMarketPerformanceList()
}
</script>
<style lang="scss" scoped>
/* 多行超出隐藏 */
.multi-hidden {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
</style>

606
admin/src/app/views/order_table/components/order-table-edit.vue

@ -1,263 +1,343 @@
<template> <template>
<el-dialog v-model="showDialog" :title="formData.id ? t('updateOrderTable') : t('addOrderTable')" width="50%" class="diy-dialog-wrap" :destroy-on-close="true"> <el-dialog
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading"> v-model="showDialog"
<el-form-item :label="t('paymentId')" prop="payment_id"> :title="formData.id ? t('updateOrderTable') : t('addOrderTable')"
<el-input v-model="formData.payment_id" clearable :placeholder="t('paymentIdPlaceholder')" class="input-width" /> width="50%"
</el-form-item> class="diy-dialog-wrap"
:destroy-on-close="true"
<el-form-item :label="t('orderStatus')" prop="order_status"> >
<el-input v-model="formData.order_status" clearable :placeholder="t('orderStatusPlaceholder')" class="input-width" /> <el-form
</el-form-item> :model="formData"
label-width="120px"
<el-form-item :label="t('paymentType')" prop="payment_type"> ref="formRef"
<el-input v-model="formData.payment_type" clearable :placeholder="t('paymentTypePlaceholder')" class="input-width" /> :rules="formRules"
</el-form-item> class="page-form"
v-loading="loading"
<el-form-item :label="t('orderAmount')" prop="order_amount"> >
<el-input v-model="formData.order_amount" clearable :placeholder="t('orderAmountPlaceholder')" class="input-width" /> <el-form-item :label="t('paymentId')" prop="payment_id">
</el-form-item> <el-input
v-model="formData.payment_id"
<el-form-item :label="t('courseId')" prop="course_id"> clearable
<el-input v-model="formData.course_id" clearable :placeholder="t('courseIdPlaceholder')" class="input-width" /> :placeholder="t('paymentIdPlaceholder')"
</el-form-item> class="input-width"
/>
<el-form-item :label="t('classId')" prop="class_id"> </el-form-item>
<el-input v-model="formData.class_id" clearable :placeholder="t('classIdPlaceholder')" class="input-width" />
</el-form-item> <el-form-item :label="t('orderStatus')" prop="order_status">
<el-input
<el-form-item :label="t('staffId')" prop="staff_id"> v-model="formData.order_status"
<el-input v-model="formData.staff_id" clearable :placeholder="t('staffIdPlaceholder')" class="input-width" /> clearable
</el-form-item> :placeholder="t('orderStatusPlaceholder')"
class="input-width"
<el-form-item :label="t('resourceId')" prop="resource_id"> />
<el-input v-model="formData.resource_id" clearable :placeholder="t('resourceIdPlaceholder')" class="input-width" /> </el-form-item>
</el-form-item>
<el-form-item :label="t('paymentType')" prop="payment_type">
<el-form-item :label="t('afterSalesStatus')" > <el-input
<el-input v-model="formData.after_sales_status" clearable :placeholder="t('afterSalesStatusPlaceholder')" class="input-width" /> v-model="formData.payment_type"
</el-form-item> clearable
:placeholder="t('paymentTypePlaceholder')"
<el-form-item :label="t('afterSalesReason')" > class="input-width"
<el-input v-model="formData.after_sales_reason" clearable :placeholder="t('afterSalesReasonPlaceholder')" class="input-width" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('afterSalesTime')" > <el-form-item :label="t('orderAmount')" prop="order_amount">
<el-input v-model="formData.after_sales_time" clearable :placeholder="t('afterSalesTimePlaceholder')" class="input-width" /> <el-input
</el-form-item> v-model="formData.order_amount"
clearable
<el-form-item :label="t('paymentTime')" > :placeholder="t('orderAmountPlaceholder')"
<el-input v-model="formData.payment_time" clearable :placeholder="t('paymentTimePlaceholder')" class="input-width" /> class="input-width"
</el-form-item> />
</el-form-item>
<el-form-item :label="t('subscriptionPaymentTime')" >
<el-input v-model="formData.subscription_payment_time" clearable :placeholder="t('subscriptionPaymentTimePlaceholder')" class="input-width" /> <el-form-item :label="t('courseId')" prop="course_id">
</el-form-item> <el-input
v-model="formData.course_id"
</el-form> clearable
:placeholder="t('courseIdPlaceholder')"
<template #footer> class="input-width"
<span class="dialog-footer"> />
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button> </el-form-item>
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{
t('confirm') <el-form-item :label="t('classId')" prop="class_id">
}}</el-button> <el-input
</span> v-model="formData.class_id"
</template> clearable
</el-dialog> :placeholder="t('classIdPlaceholder')"
</template> class="input-width"
/>
<script lang="ts" setup> </el-form-item>
import { ref, reactive, computed, watch } from 'vue'
import { useDictionary } from '@/app/api/dict' <el-form-item :label="t('staffId')" prop="staff_id">
import { t } from '@/lang' <el-input
import type { FormInstance } from 'element-plus' v-model="formData.staff_id"
import { addOrderTable, editOrderTable, getOrderTableInfo } from '@/app/api/order_table' clearable
:placeholder="t('staffIdPlaceholder')"
let showDialog = ref(false) class="input-width"
const loading = ref(false) />
</el-form-item>
/**
* 表单数据 <el-form-item :label="t('resourceId')" prop="resource_id">
*/ <el-input
const initialFormData = { v-model="formData.resource_id"
id: '', clearable
payment_id: '', :placeholder="t('resourceIdPlaceholder')"
order_status: '', class="input-width"
payment_type: '', />
order_amount: '', </el-form-item>
course_id: '',
class_id: '', <el-form-item :label="t('afterSalesStatus')">
staff_id: '', <el-input
resource_id: '', v-model="formData.after_sales_status"
after_sales_status: '', clearable
after_sales_reason: '', :placeholder="t('afterSalesStatusPlaceholder')"
after_sales_time: '', class="input-width"
payment_time: '', />
subscription_payment_time: '', </el-form-item>
}
const formData: Record<string, any> = reactive({ ...initialFormData }) <el-form-item :label="t('afterSalesReason')">
<el-input
const formRef = ref<FormInstance>() v-model="formData.after_sales_reason"
clearable
// :placeholder="t('afterSalesReasonPlaceholder')"
const formRules = computed(() => { class="input-width"
return { />
payment_id: [ </el-form-item>
{ required: true, message: t('paymentIdPlaceholder'), trigger: 'blur' },
<el-form-item :label="t('afterSalesTime')">
] <el-input
, v-model="formData.after_sales_time"
order_status: [ clearable
{ required: true, message: t('orderStatusPlaceholder'), trigger: 'blur' }, :placeholder="t('afterSalesTimePlaceholder')"
class="input-width"
] />
, </el-form-item>
payment_type: [
{ required: true, message: t('paymentTypePlaceholder'), trigger: 'blur' }, <el-form-item :label="t('paymentTime')">
<el-input
] v-model="formData.payment_time"
, clearable
order_amount: [ :placeholder="t('paymentTimePlaceholder')"
{ required: true, message: t('orderAmountPlaceholder'), trigger: 'blur' }, class="input-width"
/>
] </el-form-item>
,
course_id: [ <el-form-item :label="t('subscriptionPaymentTime')">
{ required: true, message: t('courseIdPlaceholder'), trigger: 'blur' }, <el-input
v-model="formData.subscription_payment_time"
] clearable
, :placeholder="t('subscriptionPaymentTimePlaceholder')"
class_id: [ class="input-width"
{ required: true, message: t('classIdPlaceholder'), trigger: 'blur' }, />
</el-form-item>
] </el-form>
,
staff_id: [ <template #footer>
{ required: true, message: t('staffIdPlaceholder'), trigger: 'blur' }, <span class="dialog-footer">
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
] <el-button
, type="primary"
resource_id: [ :loading="loading"
{ required: true, message: t('resourceIdPlaceholder'), trigger: 'blur' }, @click="confirm(formRef)"
>{{ t('confirm') }}</el-button
] >
, </span>
after_sales_status: [ </template>
{ required: true, message: t('afterSalesStatusPlaceholder'), trigger: 'blur' }, </el-dialog>
</template>
]
, <script lang="ts" setup>
after_sales_reason: [ import { ref, reactive, computed, watch } from 'vue'
{ required: true, message: t('afterSalesReasonPlaceholder'), trigger: 'blur' }, import { useDictionary } from '@/app/api/dict'
import { t } from '@/lang'
] import type { FormInstance } from 'element-plus'
, import {
after_sales_time: [ addOrderTable,
{ required: true, message: t('afterSalesTimePlaceholder'), trigger: 'blur' }, editOrderTable,
getOrderTableInfo,
] } from '@/app/api/order_table'
,
payment_time: [ let showDialog = ref(false)
{ required: true, message: t('paymentTimePlaceholder'), trigger: 'blur' }, const loading = ref(false)
] /**
, * 表单数据
subscription_payment_time: [ */
{ required: true, message: t('subscriptionPaymentTimePlaceholder'), trigger: 'blur' }, const initialFormData = {
id: '',
] payment_id: '',
, order_status: '',
} payment_type: '',
}) order_amount: '',
course_id: '',
const emit = defineEmits(['complete']) class_id: '',
staff_id: '',
/** resource_id: '',
* 确认 after_sales_status: '',
* @param formEl after_sales_reason: '',
*/ after_sales_time: '',
const confirm = async (formEl: FormInstance | undefined) => { payment_time: '',
if (loading.value || !formEl) return subscription_payment_time: '',
let save = formData.id ? editOrderTable : addOrderTable }
const formData: Record<string, any> = reactive({ ...initialFormData })
await formEl.validate(async (valid) => {
if (valid) { const formRef = ref<FormInstance>()
loading.value = true
//
let data = formData const formRules = computed(() => {
return {
save(data).then(res => { payment_id: [
loading.value = false { required: true, message: t('paymentIdPlaceholder'), trigger: 'blur' },
showDialog.value = false ],
emit('complete') order_status: [
}).catch(err => { { required: true, message: t('orderStatusPlaceholder'), trigger: 'blur' },
loading.value = false ],
}) payment_type: [
} { required: true, message: t('paymentTypePlaceholder'), trigger: 'blur' },
}) ],
} order_amount: [
{ required: true, message: t('orderAmountPlaceholder'), trigger: 'blur' },
// ],
course_id: [
{ required: true, message: t('courseIdPlaceholder'), trigger: 'blur' },
],
const setFormData = async (row: any = null) => { class_id: [
Object.assign(formData, initialFormData) { required: true, message: t('classIdPlaceholder'), trigger: 'blur' },
loading.value = true ],
if(row){ staff_id: [
const data = await (await getOrderTableInfo(row.id)).data { required: true, message: t('staffIdPlaceholder'), trigger: 'blur' },
if (data) Object.keys(formData).forEach((key: string) => { ],
if (data[key] != undefined) formData[key] = data[key] resource_id: [
}) { required: true, message: t('resourceIdPlaceholder'), trigger: 'blur' },
} ],
loading.value = false after_sales_status: [
} {
required: true,
// message: t('afterSalesStatusPlaceholder'),
const mobileVerify = (rule: any, value: any, callback: any) => { trigger: 'blur',
if (value && !/^1[3-9]\d{9}$/.test(value)) { },
callback(new Error(t('generateMobile'))) ],
} else { after_sales_reason: [
callback() {
} required: true,
} message: t('afterSalesReasonPlaceholder'),
trigger: 'blur',
// },
const idCardVerify = (rule: any, value: any, callback: any) => { ],
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) { after_sales_time: [
callback(new Error(t('generateIdCard'))) {
} else { required: true,
callback() message: t('afterSalesTimePlaceholder'),
} trigger: 'blur',
} },
],
// payment_time: [
const emailVerify = (rule: any, value: any, callback: any) => { { required: true, message: t('paymentTimePlaceholder'), trigger: 'blur' },
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) { ],
callback(new Error(t('generateEmail'))) subscription_payment_time: [
} else { {
callback() required: true,
} message: t('subscriptionPaymentTimePlaceholder'),
} trigger: 'blur',
},
// ],
const numberVerify = (rule: any, value: any, callback: any) => { }
if (!Number.isInteger(value)) { })
callback(new Error(t('generateNumber')))
} else { const emit = defineEmits(['complete'])
callback()
} /**
} * 确认
* @param formEl
defineExpose({ */
showDialog, const confirm = async (formEl: FormInstance | undefined) => {
setFormData if (loading.value || !formEl) return
}) let save = formData.id ? editOrderTable : addOrderTable
</script>
await formEl.validate(async (valid) => {
<style lang="scss" scoped></style> if (valid) {
<style lang="scss"> loading.value = true
.diy-dialog-wrap .el-form-item__label{
height: auto !important; let data = formData
}
</style> save(data)
.then((res) => {
loading.value = false
showDialog.value = false
emit('complete')
})
.catch((err) => {
loading.value = false
})
}
})
}
//
const setFormData = async (row: any = null) => {
Object.assign(formData, initialFormData)
loading.value = true
if (row) {
const data = await (await getOrderTableInfo(row.id)).data
if (data)
Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key]
})
}
loading.value = false
}
//
const mobileVerify = (rule: any, value: any, callback: any) => {
if (value && !/^1[3-9]\d{9}$/.test(value)) {
callback(new Error(t('generateMobile')))
} else {
callback()
}
}
//
const idCardVerify = (rule: any, value: any, callback: any) => {
if (
value &&
!/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
value
)
) {
callback(new Error(t('generateIdCard')))
} else {
callback()
}
}
//
const emailVerify = (rule: any, value: any, callback: any) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail')))
} else {
callback()
}
}
//
const numberVerify = (rule: any, value: any, callback: any) => {
if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber')))
} else {
callback()
}
}
defineExpose({
showDialog,
setFormData,
})
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.diy-dialog-wrap .el-form-item__label {
height: auto !important;
}
</style>

600
admin/src/app/views/order_table/order_table.vue

@ -1,231 +1,369 @@
<template> <template>
<div class="main-container"> <div class="main-container">
<el-card class="box-card !border-none" shadow="never"> <el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<div class="flex justify-between items-center"> <span class="text-lg">{{ pageName }}</span>
<span class="text-lg">{{pageName}}</span> <el-button type="primary" @click="addEvent">
<el-button type="primary" @click="addEvent"> {{ t('addOrderTable') }}
{{ t('addOrderTable') }} </el-button>
</el-button> </div>
</div>
<el-card
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> class="box-card !border-none my-[10px] table-search-wrap"
<el-form :inline="true" :model="orderTableTable.searchParam" ref="searchFormRef"> shadow="never"
<el-form-item :label="t('paymentId')" prop="payment_id"> >
<el-input v-model="orderTableTable.searchParam.payment_id" :placeholder="t('paymentIdPlaceholder')" /> <el-form
</el-form-item> :inline="true"
<el-form-item :label="t('orderStatus')" prop="order_status"> :model="orderTableTable.searchParam"
<el-input v-model="orderTableTable.searchParam.order_status" :placeholder="t('orderStatusPlaceholder')" /> ref="searchFormRef"
</el-form-item> >
<el-form-item :label="t('paymentType')" prop="payment_type"> <el-form-item :label="t('paymentId')" prop="payment_id">
<el-input v-model="orderTableTable.searchParam.payment_type" :placeholder="t('paymentTypePlaceholder')" /> <el-input
</el-form-item> v-model="orderTableTable.searchParam.payment_id"
<el-form-item :label="t('orderAmount')" prop="order_amount"> :placeholder="t('paymentIdPlaceholder')"
<el-input v-model="orderTableTable.searchParam.order_amount" :placeholder="t('orderAmountPlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('courseId')" prop="course_id"> <el-form-item :label="t('orderStatus')" prop="order_status">
<el-input v-model="orderTableTable.searchParam.course_id" :placeholder="t('courseIdPlaceholder')" /> <el-input
</el-form-item> v-model="orderTableTable.searchParam.order_status"
<el-form-item :label="t('classId')" prop="class_id"> :placeholder="t('orderStatusPlaceholder')"
<el-input v-model="orderTableTable.searchParam.class_id" :placeholder="t('classIdPlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('staffId')" prop="staff_id"> <el-form-item :label="t('paymentType')" prop="payment_type">
<el-input v-model="orderTableTable.searchParam.staff_id" :placeholder="t('staffIdPlaceholder')" /> <el-input
</el-form-item> v-model="orderTableTable.searchParam.payment_type"
<el-form-item :label="t('resourceId')" prop="resource_id"> :placeholder="t('paymentTypePlaceholder')"
<el-input v-model="orderTableTable.searchParam.resource_id" :placeholder="t('resourceIdPlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('afterSalesStatus')" prop="after_sales_status"> <el-form-item :label="t('orderAmount')" prop="order_amount">
<el-input v-model="orderTableTable.searchParam.after_sales_status" :placeholder="t('afterSalesStatusPlaceholder')" /> <el-input
</el-form-item> v-model="orderTableTable.searchParam.order_amount"
<el-form-item :label="t('afterSalesReason')" prop="after_sales_reason"> :placeholder="t('orderAmountPlaceholder')"
<el-input v-model="orderTableTable.searchParam.after_sales_reason" :placeholder="t('afterSalesReasonPlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('afterSalesTime')" prop="after_sales_time"> <el-form-item :label="t('courseId')" prop="course_id">
<el-input v-model="orderTableTable.searchParam.after_sales_time" :placeholder="t('afterSalesTimePlaceholder')" /> <el-input
</el-form-item> v-model="orderTableTable.searchParam.course_id"
<el-form-item :label="t('paymentTime')" prop="payment_time"> :placeholder="t('courseIdPlaceholder')"
<el-input v-model="orderTableTable.searchParam.payment_time" :placeholder="t('paymentTimePlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('subscriptionPaymentTime')" prop="subscription_payment_time"> <el-form-item :label="t('classId')" prop="class_id">
<el-input v-model="orderTableTable.searchParam.subscription_payment_time" :placeholder="t('subscriptionPaymentTimePlaceholder')" /> <el-input
</el-form-item> v-model="orderTableTable.searchParam.class_id"
<el-form-item> :placeholder="t('classIdPlaceholder')"
<el-button type="primary" @click="loadOrderTableList()">{{ t('search') }}</el-button> />
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> </el-form-item>
</el-form-item> <el-form-item :label="t('staffId')" prop="staff_id">
</el-form> <el-input
</el-card> v-model="orderTableTable.searchParam.staff_id"
:placeholder="t('staffIdPlaceholder')"
<div class="mt-[10px]"> />
<el-table :data="orderTableTable.data" size="large" v-loading="orderTableTable.loading"> </el-form-item>
<template #empty> <el-form-item :label="t('resourceId')" prop="resource_id">
<span>{{ !orderTableTable.loading ? t('emptyData') : '' }}</span> <el-input
</template> v-model="orderTableTable.searchParam.resource_id"
<el-table-column prop="payment_id" :label="t('paymentId')" min-width="120" :show-overflow-tooltip="true"/> :placeholder="t('resourceIdPlaceholder')"
/>
<el-table-column prop="order_status" :label="t('orderStatus')" min-width="120" :show-overflow-tooltip="true"/> </el-form-item>
<el-form-item
<el-table-column prop="payment_type" :label="t('paymentType')" min-width="120" :show-overflow-tooltip="true"/> :label="t('afterSalesStatus')"
prop="after_sales_status"
<el-table-column prop="order_amount" :label="t('orderAmount')" min-width="120" :show-overflow-tooltip="true"/> >
<el-input
<el-table-column prop="course_id" :label="t('courseId')" min-width="120" :show-overflow-tooltip="true"/> v-model="orderTableTable.searchParam.after_sales_status"
:placeholder="t('afterSalesStatusPlaceholder')"
<el-table-column prop="class_id" :label="t('classId')" min-width="120" :show-overflow-tooltip="true"/> />
</el-form-item>
<el-table-column prop="staff_id" :label="t('staffId')" min-width="120" :show-overflow-tooltip="true"/> <el-form-item
:label="t('afterSalesReason')"
<el-table-column prop="resource_id" :label="t('resourceId')" min-width="120" :show-overflow-tooltip="true"/> prop="after_sales_reason"
>
<el-table-column prop="after_sales_status" :label="t('afterSalesStatus')" min-width="120" :show-overflow-tooltip="true"/> <el-input
v-model="orderTableTable.searchParam.after_sales_reason"
<el-table-column prop="after_sales_reason" :label="t('afterSalesReason')" min-width="120" :show-overflow-tooltip="true"/> :placeholder="t('afterSalesReasonPlaceholder')"
/>
<el-table-column prop="after_sales_time" :label="t('afterSalesTime')" min-width="120" :show-overflow-tooltip="true"/> </el-form-item>
<el-form-item :label="t('afterSalesTime')" prop="after_sales_time">
<el-table-column prop="payment_time" :label="t('paymentTime')" min-width="120" :show-overflow-tooltip="true"/> <el-input
v-model="orderTableTable.searchParam.after_sales_time"
<el-table-column prop="subscription_payment_time" :label="t('subscriptionPaymentTime')" min-width="120" :show-overflow-tooltip="true"/> :placeholder="t('afterSalesTimePlaceholder')"
/>
<el-table-column :label="t('operation')" fixed="right" min-width="120"> </el-form-item>
<template #default="{ row }"> <el-form-item :label="t('paymentTime')" prop="payment_time">
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button> <el-input
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button> v-model="orderTableTable.searchParam.payment_time"
</template> :placeholder="t('paymentTimePlaceholder')"
</el-table-column> />
</el-form-item>
</el-table> <el-form-item
<div class="mt-[16px] flex justify-end"> :label="t('subscriptionPaymentTime')"
<el-pagination v-model:current-page="orderTableTable.page" v-model:page-size="orderTableTable.limit" prop="subscription_payment_time"
layout="total, sizes, prev, pager, next, jumper" :total="orderTableTable.total" >
@size-change="loadOrderTableList()" @current-change="loadOrderTableList" /> <el-input
</div> v-model="orderTableTable.searchParam.subscription_payment_time"
</div> :placeholder="t('subscriptionPaymentTimePlaceholder')"
/>
<edit ref="editOrderTableDialog" @complete="loadOrderTableList" /> </el-form-item>
</el-card>
</div> <el-form-item>
</template> <el-button type="primary" @click="loadOrderTableList()">{{
t('search')
<script lang="ts" setup> }}</el-button>
import { reactive, ref, watch } from 'vue' <el-button @click="resetForm(searchFormRef)">{{
import { t } from '@/lang' t('reset')
import { useDictionary } from '@/app/api/dict' }}</el-button>
import { getOrderTableList, deleteOrderTable } from '@/app/api/order_table' </el-form-item>
import { img } from '@/utils/common' </el-form>
import { ElMessageBox,FormInstance } from 'element-plus' </el-card>
import Edit from '@/app/views/order_table/components/order-table-edit.vue'
import { useRoute } from 'vue-router' <div class="mt-[10px]">
const route = useRoute() <el-table
const pageName = route.meta.title; :data="orderTableTable.data"
size="large"
let orderTableTable = reactive({ v-loading="orderTableTable.loading"
page: 1, >
limit: 10, <template #empty>
total: 0, <span>{{ !orderTableTable.loading ? t('emptyData') : '' }}</span>
loading: true, </template>
data: [], <el-table-column
searchParam:{ prop="payment_id"
"payment_id":"", :label="t('paymentId')"
"order_status":"", min-width="120"
"payment_type":"", :show-overflow-tooltip="true"
"order_amount":"", />
"course_id":"",
"class_id":"", <el-table-column
"staff_id":"", prop="order_status"
"resource_id":"", :label="t('orderStatus')"
"after_sales_status":"", min-width="120"
"after_sales_reason":"", :show-overflow-tooltip="true"
"after_sales_time":"", />
"payment_time":"",
"subscription_payment_time":"" <el-table-column
} prop="payment_type"
}) :label="t('paymentType')"
min-width="120"
const searchFormRef = ref<FormInstance>() :show-overflow-tooltip="true"
/>
//
const selectData = ref<any[]>([]) <el-table-column
prop="order_amount"
// :label="t('orderAmount')"
min-width="120"
:show-overflow-tooltip="true"
/** />
* 获取订单列表
*/ <el-table-column
const loadOrderTableList = (page: number = 1) => { prop="course_id"
orderTableTable.loading = true :label="t('courseId')"
orderTableTable.page = page min-width="120"
:show-overflow-tooltip="true"
getOrderTableList({ />
page: orderTableTable.page,
limit: orderTableTable.limit, <el-table-column
...orderTableTable.searchParam prop="class_id"
}).then(res => { :label="t('classId')"
orderTableTable.loading = false min-width="120"
orderTableTable.data = res.data.data :show-overflow-tooltip="true"
orderTableTable.total = res.data.total />
}).catch(() => {
orderTableTable.loading = false <el-table-column
}) prop="staff_id"
} :label="t('staffId')"
loadOrderTableList() min-width="120"
:show-overflow-tooltip="true"
const editOrderTableDialog: Record<string, any> | null = ref(null) />
/** <el-table-column
* 添加订单 prop="resource_id"
*/ :label="t('resourceId')"
const addEvent = () => { min-width="120"
editOrderTableDialog.value.setFormData() :show-overflow-tooltip="true"
editOrderTableDialog.value.showDialog = true />
}
<el-table-column
/** prop="after_sales_status"
* 编辑订单 :label="t('afterSalesStatus')"
* @param data min-width="120"
*/ :show-overflow-tooltip="true"
const editEvent = (data: any) => { />
editOrderTableDialog.value.setFormData(data)
editOrderTableDialog.value.showDialog = true <el-table-column
} prop="after_sales_reason"
:label="t('afterSalesReason')"
/** min-width="120"
* 删除订单 :show-overflow-tooltip="true"
*/ />
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('orderTableDeleteTips'), t('warning'), <el-table-column
{ prop="after_sales_time"
confirmButtonText: t('confirm'), :label="t('afterSalesTime')"
cancelButtonText: t('cancel'), min-width="120"
type: 'warning', :show-overflow-tooltip="true"
} />
).then(() => {
deleteOrderTable(id).then(() => { <el-table-column
loadOrderTableList() prop="payment_time"
}).catch(() => { :label="t('paymentTime')"
}) min-width="120"
}) :show-overflow-tooltip="true"
} />
<el-table-column
prop="subscription_payment_time"
const resetForm = (formEl: FormInstance | undefined) => { :label="t('subscriptionPaymentTime')"
if (!formEl) return min-width="120"
formEl.resetFields() :show-overflow-tooltip="true"
loadOrderTableList() />
}
</script> <el-table-column
:label="t('operation')"
<style lang="scss" scoped> fixed="right"
/* 多行超出隐藏 */ min-width="120"
.multi-hidden { >
word-break: break-all; <template #default="{ row }">
text-overflow: ellipsis; <el-button type="primary" link @click="editEvent(row)">{{
overflow: hidden; t('edit')
display: -webkit-box; }}</el-button>
-webkit-line-clamp: 2; <el-button type="primary" link @click="deleteEvent(row.id)">{{
-webkit-box-orient: vertical; t('delete')
} }}</el-button>
</style> </template>
</el-table-column>
</el-table>
<div class="mt-[16px] flex justify-end">
<el-pagination
v-model:current-page="orderTableTable.page"
v-model:page-size="orderTableTable.limit"
layout="total, sizes, prev, pager, next, jumper"
:total="orderTableTable.total"
@size-change="loadOrderTableList()"
@current-change="loadOrderTableList"
/>
</div>
</div>
<edit ref="editOrderTableDialog" @complete="loadOrderTableList" />
</el-card>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref, watch } from 'vue'
import { t } from '@/lang'
import { useDictionary } from '@/app/api/dict'
import { getOrderTableList, deleteOrderTable } from '@/app/api/order_table'
import { img } from '@/utils/common'
import { ElMessageBox, FormInstance } from 'element-plus'
import Edit from '@/app/views/order_table/components/order-table-edit.vue'
import { useRoute } from 'vue-router'
const route = useRoute()
const pageName = route.meta.title
let orderTableTable = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {
payment_id: '',
order_status: '',
payment_type: '',
order_amount: '',
course_id: '',
class_id: '',
staff_id: '',
resource_id: '',
after_sales_status: '',
after_sales_reason: '',
after_sales_time: '',
payment_time: '',
subscription_payment_time: '',
},
})
const searchFormRef = ref<FormInstance>()
//
const selectData = ref<any[]>([])
//
/**
* 获取订单列表
*/
const loadOrderTableList = (page: number = 1) => {
orderTableTable.loading = true
orderTableTable.page = page
getOrderTableList({
page: orderTableTable.page,
limit: orderTableTable.limit,
...orderTableTable.searchParam,
})
.then((res) => {
orderTableTable.loading = false
orderTableTable.data = res.data.data
orderTableTable.total = res.data.total
})
.catch(() => {
orderTableTable.loading = false
})
}
loadOrderTableList()
const editOrderTableDialog: Record<string, any> | null = ref(null)
/**
* 添加订单
*/
const addEvent = () => {
editOrderTableDialog.value.setFormData()
editOrderTableDialog.value.showDialog = true
}
/**
* 编辑订单
* @param data
*/
const editEvent = (data: any) => {
editOrderTableDialog.value.setFormData(data)
editOrderTableDialog.value.showDialog = true
}
/**
* 删除订单
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('orderTableDeleteTips'), t('warning'), {
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}).then(() => {
deleteOrderTable(id)
.then(() => {
loadOrderTableList()
})
.catch(() => {})
})
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadOrderTableList()
}
</script>
<style lang="scss" scoped>
/* 多行超出隐藏 */
.multi-hidden {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
</style>

462
admin/src/app/views/performance_records/components/performance-records-edit.vue

@ -1,203 +1,259 @@
<template> <template>
<el-dialog v-model="showDialog" :title="formData.id ? t('updatePerformanceRecords') : t('addPerformanceRecords')" width="50%" class="diy-dialog-wrap" :destroy-on-close="true"> <el-dialog
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading"> v-model="showDialog"
<el-form-item :label="t('staffId')" prop="staff_id"> :title="
<el-input v-model="formData.staff_id" clearable :placeholder="t('staffIdPlaceholder')" class="input-width" /> formData.id ? t('updatePerformanceRecords') : t('addPerformanceRecords')
</el-form-item> "
width="50%"
<el-form-item :label="t('resourceId')" prop="resource_id"> class="diy-dialog-wrap"
<el-input v-model="formData.resource_id" clearable :placeholder="t('resourceIdPlaceholder')" class="input-width" /> :destroy-on-close="true"
</el-form-item> >
<el-form
<el-form-item :label="t('orderId')" > :model="formData"
<el-input v-model="formData.order_id" clearable :placeholder="t('orderIdPlaceholder')" class="input-width" /> label-width="120px"
</el-form-item> ref="formRef"
:rules="formRules"
<el-form-item :label="t('orderStatus')" > class="page-form"
<el-input v-model="formData.order_status" clearable :placeholder="t('orderStatusPlaceholder')" class="input-width" /> v-loading="loading"
</el-form-item> >
<el-form-item :label="t('staffId')" prop="staff_id">
<el-form-item :label="t('performanceType')" prop="performance_type"> <el-input
<el-input v-model="formData.performance_type" clearable :placeholder="t('performanceTypePlaceholder')" class="input-width" /> v-model="formData.staff_id"
</el-form-item> clearable
:placeholder="t('staffIdPlaceholder')"
<el-form-item :label="t('performanceValue')" prop="performance_value"> class="input-width"
<el-input v-model="formData.performance_value" clearable :placeholder="t('performanceValuePlaceholder')" class="input-width" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('remarks')" > <el-form-item :label="t('resourceId')" prop="resource_id">
<el-input v-model="formData.remarks" clearable :placeholder="t('remarksPlaceholder')" class="input-width" /> <el-input
</el-form-item> v-model="formData.resource_id"
clearable
</el-form> :placeholder="t('resourceIdPlaceholder')"
class="input-width"
<template #footer> />
<span class="dialog-footer"> </el-form-item>
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{ <el-form-item :label="t('orderId')">
t('confirm') <el-input
}}</el-button> v-model="formData.order_id"
</span> clearable
</template> :placeholder="t('orderIdPlaceholder')"
</el-dialog> class="input-width"
</template> />
</el-form-item>
<script lang="ts" setup>
import { ref, reactive, computed, watch } from 'vue' <el-form-item :label="t('orderStatus')">
import { useDictionary } from '@/app/api/dict' <el-input
import { t } from '@/lang' v-model="formData.order_status"
import type { FormInstance } from 'element-plus' clearable
import { addPerformanceRecords, editPerformanceRecords, getPerformanceRecordsInfo } from '@/app/api/performance_records' :placeholder="t('orderStatusPlaceholder')"
class="input-width"
let showDialog = ref(false) />
const loading = ref(false) </el-form-item>
/** <el-form-item :label="t('performanceType')" prop="performance_type">
* 表单数据 <el-input
*/ v-model="formData.performance_type"
const initialFormData = { clearable
id: '', :placeholder="t('performanceTypePlaceholder')"
staff_id: '', class="input-width"
resource_id: '', />
order_id: '', </el-form-item>
order_status: '',
performance_type: '', <el-form-item :label="t('performanceValue')" prop="performance_value">
performance_value: '', <el-input
remarks: '', v-model="formData.performance_value"
} clearable
const formData: Record<string, any> = reactive({ ...initialFormData }) :placeholder="t('performanceValuePlaceholder')"
class="input-width"
const formRef = ref<FormInstance>() />
</el-form-item>
//
const formRules = computed(() => { <el-form-item :label="t('remarks')">
return { <el-input
staff_id: [ v-model="formData.remarks"
{ required: true, message: t('staffIdPlaceholder'), trigger: 'blur' }, clearable
:placeholder="t('remarksPlaceholder')"
] class="input-width"
, />
resource_id: [ </el-form-item>
{ required: true, message: t('resourceIdPlaceholder'), trigger: 'blur' }, </el-form>
] <template #footer>
, <span class="dialog-footer">
order_id: [ <el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
{ required: true, message: t('orderIdPlaceholder'), trigger: 'blur' }, <el-button
type="primary"
] :loading="loading"
, @click="confirm(formRef)"
order_status: [ >{{ t('confirm') }}</el-button
{ required: true, message: t('orderStatusPlaceholder'), trigger: 'blur' }, >
</span>
] </template>
, </el-dialog>
performance_type: [ </template>
{ required: true, message: t('performanceTypePlaceholder'), trigger: 'blur' },
<script lang="ts" setup>
] import { ref, reactive, computed, watch } from 'vue'
, import { useDictionary } from '@/app/api/dict'
performance_value: [ import { t } from '@/lang'
{ required: true, message: t('performanceValuePlaceholder'), trigger: 'blur' }, import type { FormInstance } from 'element-plus'
import {
] addPerformanceRecords,
, editPerformanceRecords,
remarks: [ getPerformanceRecordsInfo,
{ required: true, message: t('remarksPlaceholder'), trigger: 'blur' }, } from '@/app/api/performance_records'
] let showDialog = ref(false)
, const loading = ref(false)
}
}) /**
* 表单数据
const emit = defineEmits(['complete']) */
const initialFormData = {
/** id: '',
* 确认 staff_id: '',
* @param formEl resource_id: '',
*/ order_id: '',
const confirm = async (formEl: FormInstance | undefined) => { order_status: '',
if (loading.value || !formEl) return performance_type: '',
let save = formData.id ? editPerformanceRecords : addPerformanceRecords performance_value: '',
remarks: '',
await formEl.validate(async (valid) => { }
if (valid) { const formData: Record<string, any> = reactive({ ...initialFormData })
loading.value = true
const formRef = ref<FormInstance>()
let data = formData
//
save(data).then(res => { const formRules = computed(() => {
loading.value = false return {
showDialog.value = false staff_id: [
emit('complete') { required: true, message: t('staffIdPlaceholder'), trigger: 'blur' },
}).catch(err => { ],
loading.value = false resource_id: [
}) { required: true, message: t('resourceIdPlaceholder'), trigger: 'blur' },
} ],
}) order_id: [
} { required: true, message: t('orderIdPlaceholder'), trigger: 'blur' },
],
// order_status: [
{ required: true, message: t('orderStatusPlaceholder'), trigger: 'blur' },
],
performance_type: [
const setFormData = async (row: any = null) => { {
Object.assign(formData, initialFormData) required: true,
loading.value = true message: t('performanceTypePlaceholder'),
if(row){ trigger: 'blur',
const data = await (await getPerformanceRecordsInfo(row.id)).data },
if (data) Object.keys(formData).forEach((key: string) => { ],
if (data[key] != undefined) formData[key] = data[key] performance_value: [
}) {
} required: true,
loading.value = false message: t('performanceValuePlaceholder'),
} trigger: 'blur',
},
// ],
const mobileVerify = (rule: any, value: any, callback: any) => { remarks: [
if (value && !/^1[3-9]\d{9}$/.test(value)) { { required: true, message: t('remarksPlaceholder'), trigger: 'blur' },
callback(new Error(t('generateMobile'))) ],
} else { }
callback() })
}
} const emit = defineEmits(['complete'])
// /**
const idCardVerify = (rule: any, value: any, callback: any) => { * 确认
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) { * @param formEl
callback(new Error(t('generateIdCard'))) */
} else { const confirm = async (formEl: FormInstance | undefined) => {
callback() if (loading.value || !formEl) return
} let save = formData.id ? editPerformanceRecords : addPerformanceRecords
}
await formEl.validate(async (valid) => {
// if (valid) {
const emailVerify = (rule: any, value: any, callback: any) => { loading.value = true
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail'))) let data = formData
} else {
callback() save(data)
} .then((res) => {
} loading.value = false
showDialog.value = false
// emit('complete')
const numberVerify = (rule: any, value: any, callback: any) => { })
if (!Number.isInteger(value)) { .catch((err) => {
callback(new Error(t('generateNumber'))) loading.value = false
} else { })
callback() }
} })
} }
defineExpose({ //
showDialog,
setFormData const setFormData = async (row: any = null) => {
}) Object.assign(formData, initialFormData)
</script> loading.value = true
if (row) {
<style lang="scss" scoped></style> const data = await (await getPerformanceRecordsInfo(row.id)).data
<style lang="scss"> if (data)
.diy-dialog-wrap .el-form-item__label{ Object.keys(formData).forEach((key: string) => {
height: auto !important; if (data[key] != undefined) formData[key] = data[key]
} })
</style> }
loading.value = false
}
//
const mobileVerify = (rule: any, value: any, callback: any) => {
if (value && !/^1[3-9]\d{9}$/.test(value)) {
callback(new Error(t('generateMobile')))
} else {
callback()
}
}
//
const idCardVerify = (rule: any, value: any, callback: any) => {
if (
value &&
!/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
value
)
) {
callback(new Error(t('generateIdCard')))
} else {
callback()
}
}
//
const emailVerify = (rule: any, value: any, callback: any) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail')))
} else {
callback()
}
}
//
const numberVerify = (rule: any, value: any, callback: any) => {
if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber')))
} else {
callback()
}
}
defineExpose({
showDialog,
setFormData,
})
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.diy-dialog-wrap .el-form-item__label {
height: auto !important;
}
</style>

479
admin/src/app/views/performance_records/performance_records.vue

@ -1,195 +1,284 @@
<template> <template>
<div class="main-container"> <div class="main-container">
<el-card class="box-card !border-none" shadow="never"> <el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<div class="flex justify-between items-center"> <span class="text-lg">{{ pageName }}</span>
<span class="text-lg">{{pageName}}</span> <el-button type="primary" @click="addEvent">
<el-button type="primary" @click="addEvent"> {{ t('addPerformanceRecords') }}
{{ t('addPerformanceRecords') }} </el-button>
</el-button> </div>
</div>
<el-card
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> class="box-card !border-none my-[10px] table-search-wrap"
<el-form :inline="true" :model="performanceRecordsTable.searchParam" ref="searchFormRef"> shadow="never"
<el-form-item :label="t('staffId')" prop="staff_id"> >
<el-input v-model="performanceRecordsTable.searchParam.staff_id" :placeholder="t('staffIdPlaceholder')" /> <el-form
</el-form-item> :inline="true"
<el-form-item :label="t('resourceId')" prop="resource_id"> :model="performanceRecordsTable.searchParam"
<el-input v-model="performanceRecordsTable.searchParam.resource_id" :placeholder="t('resourceIdPlaceholder')" /> ref="searchFormRef"
</el-form-item> >
<el-form-item :label="t('orderId')" prop="order_id"> <el-form-item :label="t('staffId')" prop="staff_id">
<el-input v-model="performanceRecordsTable.searchParam.order_id" :placeholder="t('orderIdPlaceholder')" /> <el-input
</el-form-item> v-model="performanceRecordsTable.searchParam.staff_id"
<el-form-item :label="t('orderStatus')" prop="order_status"> :placeholder="t('staffIdPlaceholder')"
<el-input v-model="performanceRecordsTable.searchParam.order_status" :placeholder="t('orderStatusPlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('performanceType')" prop="performance_type"> <el-form-item :label="t('resourceId')" prop="resource_id">
<el-input v-model="performanceRecordsTable.searchParam.performance_type" :placeholder="t('performanceTypePlaceholder')" /> <el-input
</el-form-item> v-model="performanceRecordsTable.searchParam.resource_id"
<el-form-item :label="t('performanceValue')" prop="performance_value"> :placeholder="t('resourceIdPlaceholder')"
<el-input v-model="performanceRecordsTable.searchParam.performance_value" :placeholder="t('performanceValuePlaceholder')" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('remarks')" prop="remarks"> <el-form-item :label="t('orderId')" prop="order_id">
<el-input v-model="performanceRecordsTable.searchParam.remarks" :placeholder="t('remarksPlaceholder')" /> <el-input
</el-form-item> v-model="performanceRecordsTable.searchParam.order_id"
<el-form-item> :placeholder="t('orderIdPlaceholder')"
<el-button type="primary" @click="loadPerformanceRecordsList()">{{ t('search') }}</el-button> />
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> </el-form-item>
</el-form-item> <el-form-item :label="t('orderStatus')" prop="order_status">
</el-form> <el-input
</el-card> v-model="performanceRecordsTable.searchParam.order_status"
:placeholder="t('orderStatusPlaceholder')"
<div class="mt-[10px]"> />
<el-table :data="performanceRecordsTable.data" size="large" v-loading="performanceRecordsTable.loading"> </el-form-item>
<template #empty> <el-form-item :label="t('performanceType')" prop="performance_type">
<span>{{ !performanceRecordsTable.loading ? t('emptyData') : '' }}</span> <el-input
</template> v-model="performanceRecordsTable.searchParam.performance_type"
<el-table-column prop="staff_id" :label="t('staffId')" min-width="120" :show-overflow-tooltip="true"/> :placeholder="t('performanceTypePlaceholder')"
/>
<el-table-column prop="resource_id" :label="t('resourceId')" min-width="120" :show-overflow-tooltip="true"/> </el-form-item>
<el-form-item :label="t('performanceValue')" prop="performance_value">
<el-table-column prop="order_id" :label="t('orderId')" min-width="120" :show-overflow-tooltip="true"/> <el-input
v-model="performanceRecordsTable.searchParam.performance_value"
<el-table-column prop="order_status" :label="t('orderStatus')" min-width="120" :show-overflow-tooltip="true"/> :placeholder="t('performanceValuePlaceholder')"
/>
<el-table-column prop="performance_type" :label="t('performanceType')" min-width="120" :show-overflow-tooltip="true"/> </el-form-item>
<el-form-item :label="t('remarks')" prop="remarks">
<el-table-column prop="performance_value" :label="t('performanceValue')" min-width="120" :show-overflow-tooltip="true"/> <el-input
v-model="performanceRecordsTable.searchParam.remarks"
<el-table-column prop="remarks" :label="t('remarks')" min-width="120" :show-overflow-tooltip="true"/> :placeholder="t('remarksPlaceholder')"
/>
<el-table-column :label="t('operation')" fixed="right" min-width="120"> </el-form-item>
<template #default="{ row }">
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button> <el-form-item>
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button> <el-button type="primary" @click="loadPerformanceRecordsList()">{{
</template> t('search')
</el-table-column> }}</el-button>
<el-button @click="resetForm(searchFormRef)">{{
</el-table> t('reset')
<div class="mt-[16px] flex justify-end"> }}</el-button>
<el-pagination v-model:current-page="performanceRecordsTable.page" v-model:page-size="performanceRecordsTable.limit" </el-form-item>
layout="total, sizes, prev, pager, next, jumper" :total="performanceRecordsTable.total" </el-form>
@size-change="loadPerformanceRecordsList()" @current-change="loadPerformanceRecordsList" /> </el-card>
</div>
</div> <div class="mt-[10px]">
<el-table
<edit ref="editPerformanceRecordsDialog" @complete="loadPerformanceRecordsList" /> :data="performanceRecordsTable.data"
</el-card> size="large"
</div> v-loading="performanceRecordsTable.loading"
</template> >
<template #empty>
<script lang="ts" setup> <span>{{
import { reactive, ref, watch } from 'vue' !performanceRecordsTable.loading ? t('emptyData') : ''
import { t } from '@/lang' }}</span>
import { useDictionary } from '@/app/api/dict' </template>
import { getPerformanceRecordsList, deletePerformanceRecords } from '@/app/api/performance_records' <el-table-column
import { img } from '@/utils/common' prop="staff_id"
import { ElMessageBox,FormInstance } from 'element-plus' :label="t('staffId')"
import Edit from '@/app/views/performance_records/components/performance-records-edit.vue' min-width="120"
import { useRoute } from 'vue-router' :show-overflow-tooltip="true"
const route = useRoute() />
const pageName = route.meta.title;
<el-table-column
let performanceRecordsTable = reactive({ prop="resource_id"
page: 1, :label="t('resourceId')"
limit: 10, min-width="120"
total: 0, :show-overflow-tooltip="true"
loading: true, />
data: [],
searchParam:{ <el-table-column
"staff_id":"", prop="order_id"
"resource_id":"", :label="t('orderId')"
"order_id":"", min-width="120"
"order_status":"", :show-overflow-tooltip="true"
"performance_type":"", />
"performance_value":"",
"remarks":"" <el-table-column
} prop="order_status"
}) :label="t('orderStatus')"
min-width="120"
const searchFormRef = ref<FormInstance>() :show-overflow-tooltip="true"
/>
//
const selectData = ref<any[]>([]) <el-table-column
prop="performance_type"
// :label="t('performanceType')"
min-width="120"
:show-overflow-tooltip="true"
/** />
* 获取绩效记录列表
*/ <el-table-column
const loadPerformanceRecordsList = (page: number = 1) => { prop="performance_value"
performanceRecordsTable.loading = true :label="t('performanceValue')"
performanceRecordsTable.page = page min-width="120"
:show-overflow-tooltip="true"
getPerformanceRecordsList({ />
page: performanceRecordsTable.page,
limit: performanceRecordsTable.limit, <el-table-column
...performanceRecordsTable.searchParam prop="remarks"
}).then(res => { :label="t('remarks')"
performanceRecordsTable.loading = false min-width="120"
performanceRecordsTable.data = res.data.data :show-overflow-tooltip="true"
performanceRecordsTable.total = res.data.total />
}).catch(() => {
performanceRecordsTable.loading = false <el-table-column
}) :label="t('operation')"
} fixed="right"
loadPerformanceRecordsList() min-width="120"
>
const editPerformanceRecordsDialog: Record<string, any> | null = ref(null) <template #default="{ row }">
<el-button type="primary" link @click="editEvent(row)">{{
/** t('edit')
* 添加绩效记录 }}</el-button>
*/ <el-button type="primary" link @click="deleteEvent(row.id)">{{
const addEvent = () => { t('delete')
editPerformanceRecordsDialog.value.setFormData() }}</el-button>
editPerformanceRecordsDialog.value.showDialog = true </template>
} </el-table-column>
</el-table>
/** <div class="mt-[16px] flex justify-end">
* 编辑绩效记录 <el-pagination
* @param data v-model:current-page="performanceRecordsTable.page"
*/ v-model:page-size="performanceRecordsTable.limit"
const editEvent = (data: any) => { layout="total, sizes, prev, pager, next, jumper"
editPerformanceRecordsDialog.value.setFormData(data) :total="performanceRecordsTable.total"
editPerformanceRecordsDialog.value.showDialog = true @size-change="loadPerformanceRecordsList()"
} @current-change="loadPerformanceRecordsList"
/>
/** </div>
* 删除绩效记录 </div>
*/
const deleteEvent = (id: number) => { <edit
ElMessageBox.confirm(t('performanceRecordsDeleteTips'), t('warning'), ref="editPerformanceRecordsDialog"
{ @complete="loadPerformanceRecordsList"
confirmButtonText: t('confirm'), />
cancelButtonText: t('cancel'), </el-card>
type: 'warning', </div>
} </template>
).then(() => {
deletePerformanceRecords(id).then(() => { <script lang="ts" setup>
loadPerformanceRecordsList() import { reactive, ref, watch } from 'vue'
}).catch(() => { import { t } from '@/lang'
}) import { useDictionary } from '@/app/api/dict'
}) import {
} getPerformanceRecordsList,
deletePerformanceRecords,
} from '@/app/api/performance_records'
import { img } from '@/utils/common'
const resetForm = (formEl: FormInstance | undefined) => { import { ElMessageBox, FormInstance } from 'element-plus'
if (!formEl) return import Edit from '@/app/views/performance_records/components/performance-records-edit.vue'
formEl.resetFields() import { useRoute } from 'vue-router'
loadPerformanceRecordsList() const route = useRoute()
} const pageName = route.meta.title
</script>
let performanceRecordsTable = reactive({
<style lang="scss" scoped> page: 1,
/* 多行超出隐藏 */ limit: 10,
.multi-hidden { total: 0,
word-break: break-all; loading: true,
text-overflow: ellipsis; data: [],
overflow: hidden; searchParam: {
display: -webkit-box; staff_id: '',
-webkit-line-clamp: 2; resource_id: '',
-webkit-box-orient: vertical; order_id: '',
} order_status: '',
</style> performance_type: '',
performance_value: '',
remarks: '',
},
})
const searchFormRef = ref<FormInstance>()
//
const selectData = ref<any[]>([])
//
/**
* 获取绩效记录列表
*/
const loadPerformanceRecordsList = (page: number = 1) => {
performanceRecordsTable.loading = true
performanceRecordsTable.page = page
getPerformanceRecordsList({
page: performanceRecordsTable.page,
limit: performanceRecordsTable.limit,
...performanceRecordsTable.searchParam,
})
.then((res) => {
performanceRecordsTable.loading = false
performanceRecordsTable.data = res.data.data
performanceRecordsTable.total = res.data.total
})
.catch(() => {
performanceRecordsTable.loading = false
})
}
loadPerformanceRecordsList()
const editPerformanceRecordsDialog: Record<string, any> | null = ref(null)
/**
* 添加绩效记录
*/
const addEvent = () => {
editPerformanceRecordsDialog.value.setFormData()
editPerformanceRecordsDialog.value.showDialog = true
}
/**
* 编辑绩效记录
* @param data
*/
const editEvent = (data: any) => {
editPerformanceRecordsDialog.value.setFormData(data)
editPerformanceRecordsDialog.value.showDialog = true
}
/**
* 删除绩效记录
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('performanceRecordsDeleteTips'), t('warning'), {
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}).then(() => {
deletePerformanceRecords(id)
.then(() => {
loadPerformanceRecordsList()
})
.catch(() => {})
})
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadPerformanceRecordsList()
}
</script>
<style lang="scss" scoped>
/* 多行超出隐藏 */
.multi-hidden {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
</style>

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save