Browse Source

代码格式化

master
王泽彦 10 months ago
parent
commit
adf2ea85a9
  1. 4
      admin/components.d.ts
  2. 26
      admin/src/app/api/communication_records.ts
  3. 42
      admin/src/app/api/order_table.ts
  4. 39
      admin/src/app/api/physical_test.ts
  5. 32
      admin/src/app/api/student_courses.ts
  6. 3
      admin/src/app/api/sys.ts
  7. 40
      admin/src/app/lang/zh-cn/communication_records.communication_records.json
  8. 3
      admin/src/app/lang/zh-cn/customer_resource_changes.customer_resource_changes.json
  9. 210
      admin/src/app/lang/zh-cn/customer_resources.customer_resources.json
  10. 28
      admin/src/app/lang/zh-cn/exam_questions.exam_questions_edit.json
  11. 40
      admin/src/app/lang/zh-cn/order_table.order_table.json
  12. 72
      admin/src/app/lang/zh-cn/physical_test.physical_test.json
  13. 76
      admin/src/app/lang/zh-cn/physical_test.physical_test_edit.json
  14. 36
      admin/src/app/lang/zh-cn/student_courses.student_courses.json
  15. 72
      admin/src/app/lang/zh-cn/tc_dialog.physical_test_edit.json
  16. 2
      admin/src/app/views/campus_person_role/campus_person_role.vue
  17. 551
      admin/src/app/views/communication_records/communication_records.vue
  18. 614
      admin/src/app/views/communication_records/components/communication-records-edit.vue
  19. 850
      admin/src/app/views/customer_resources/customer_resources.vue
  20. 595
      admin/src/app/views/order_table/components/order-table-edit.vue
  21. 561
      admin/src/app/views/order_table/order_table.vue
  22. 740
      admin/src/app/views/physical_test/components/physical-test-edit.vue
  23. 472
      admin/src/app/views/physical_test/physical_test.vue
  24. 764
      admin/src/app/views/physical_test/physical_test_edit.vue
  25. 331
      admin/src/app/views/setting/pay.vue
  26. 504
      admin/src/app/views/student_courses/components/student-courses-edit.vue
  27. 472
      admin/src/app/views/student_courses/student_courses.vue
  28. 520
      admin/src/app/views/tc_dialog/tc_dialog.vue
  29. 25
      admin/src/app/views/timetables/timetables.vue
  30. 416
      admin/src/app/views/xsyj/xsyj.vue

4
admin/components.d.ts

@ -41,8 +41,6 @@ declare module '@vue/runtime-core' {
ElOption: typeof import('element-plus/es')['ElOption'] ElOption: typeof import('element-plus/es')['ElOption']
ElPagination: typeof import('element-plus/es')['ElPagination'] ElPagination: typeof import('element-plus/es')['ElPagination']
ElPopover: typeof import('element-plus/es')['ElPopover'] ElPopover: typeof import('element-plus/es')['ElPopover']
ElRadio: typeof import('element-plus/es')['ElRadio']
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
ElRow: typeof import('element-plus/es')['ElRow'] ElRow: typeof import('element-plus/es')['ElRow']
ElScrollbar: typeof import('element-plus/es')['ElScrollbar'] ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
ElSelect: typeof import('element-plus/es')['ElSelect'] ElSelect: typeof import('element-plus/es')['ElSelect']
@ -52,9 +50,7 @@ declare module '@vue/runtime-core' {
ElTableColumn: typeof import('element-plus/es')['ElTableColumn'] ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
ElTabPane: typeof import('element-plus/es')['ElTabPane'] ElTabPane: typeof import('element-plus/es')['ElTabPane']
ElTabs: typeof import('element-plus/es')['ElTabs'] ElTabs: typeof import('element-plus/es')['ElTabs']
ElTag: typeof import('element-plus/es')['ElTag']
ElTooltip: typeof import('element-plus/es')['ElTooltip'] ElTooltip: typeof import('element-plus/es')['ElTooltip']
ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']
ElUpload: typeof import('element-plus/es')['ElUpload'] ElUpload: typeof import('element-plus/es')['ElUpload']
ExportSure: typeof import('./src/components/export-sure/index.vue')['default'] ExportSure: typeof import('./src/components/export-sure/index.vue')['default']
HeatMap: typeof import('./src/components/heat-map/index.vue')['default'] HeatMap: typeof import('./src/components/heat-map/index.vue')['default']

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

@ -1,7 +1,5 @@
import request from '@/utils/request' import request from '@/utils/request'
// USER_CODE_BEGIN -- communication_records // USER_CODE_BEGIN -- communication_records
/** /**
* *
@ -9,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 })
} }
/** /**
@ -18,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}`)
} }
/** /**
@ -27,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,
})
} }
/** /**
@ -37,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 }
)
} }
/** /**
@ -46,11 +51,14 @@ 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,
})
} }
export function getWithCustomerResourcesList(params: Record<string,any>){ export function getWithCustomerResourcesList(params: Record<string, any>) {
return request.get('communication_records/customer_resources_all', {params}) return request.get('communication_records/customer_resources_all', { params })
} }
// USER_CODE_END -- communication_records // USER_CODE_END -- communication_records

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

@ -1,9 +1,5 @@
import request from '@/utils/request' import request from '@/utils/request'
// USER_CODE_BEGIN -- order_table // USER_CODE_BEGIN -- order_table
/** /**
* *
@ -11,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 })
} }
/** /**
@ -20,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}`)
} }
/** /**
@ -29,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,
})
} }
/** /**
@ -39,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,
})
} }
/** /**
@ -48,17 +50,23 @@ 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,
})
} }
export function getWithCustomerResourcesList(params: Record<string,any>){ export function getWithCustomerResourcesList(params: Record<string, any>) {
return request.get('order_table/customer_resources_all', {params}) return request.get('order_table/customer_resources_all', { params })
}export function getWithCourseList(params: Record<string,any>){ }
return request.get('order_table/course_all', {params}) export function getWithCourseList(params: Record<string, any>) {
}export function getWithClassGradeList(params: Record<string,any>){ return request.get('order_table/course_all', { params })
return request.get('order_table/class_grade_all', {params}) }
}export function getWithPersonnelList(params: Record<string,any>){ export function getWithClassGradeList(params: Record<string, any>) {
return request.get('order_table/personnel_all', {params}) return request.get('order_table/class_grade_all', { params })
}
export function getWithPersonnelList(params: Record<string, any>) {
return request.get('order_table/personnel_all', { params })
} }
// USER_CODE_END -- order_table // USER_CODE_END -- order_table

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

@ -1,11 +1,5 @@
import request from '@/utils/request' import request from '@/utils/request'
// USER_CODE_BEGIN -- physical_test // USER_CODE_BEGIN -- physical_test
/** /**
* *
@ -13,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 })
} }
/** /**
@ -22,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}`)
} }
/** /**
@ -31,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,
})
} }
/** /**
@ -41,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,
})
} }
/** /**
@ -50,15 +50,20 @@ 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,
})
} }
export function getWithCustomerResourcesList(params: Record<string,any>){ export function getWithCustomerResourcesList(params: Record<string, any>) {
return request.get('physical_test/customer_resources_all', {params}) return request.get('physical_test/customer_resources_all', { params })
}export function getWithStudentList(params: Record<string,any>){ }
return request.get('physical_test/student_all', {params}) export function getWithStudentList(params: Record<string, any>) {
}export function getWithPersonnelList(params: Record<string,any>){ return request.get('physical_test/student_all', { params })
return request.get('physical_test/personnel_all', {params}) }
export function getWithPersonnelList(params: Record<string, any>) {
return request.get('physical_test/personnel_all', { params })
} }
// USER_CODE_END -- physical_test // USER_CODE_END -- physical_test

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

@ -1,9 +1,5 @@
import request from '@/utils/request' import request from '@/utils/request'
// USER_CODE_BEGIN -- student_courses // USER_CODE_BEGIN -- student_courses
/** /**
* *
@ -11,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 })
} }
/** /**
@ -20,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}`)
} }
/** /**
@ -29,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,
})
} }
/** /**
@ -39,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,
})
} }
/** /**
@ -48,13 +50,17 @@ 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,
})
} }
export function getWithStudentList(params: Record<string,any>){ export function getWithStudentList(params: Record<string, any>) {
return request.get('student_courses/student_all', {params}) return request.get('student_courses/student_all', { params })
}export function getWithCourseList(params: Record<string,any>){ }
return request.get('student_courses/course_all', {params}) export function getWithCourseList(params: Record<string, any>) {
return request.get('student_courses/course_all', { params })
} }
// USER_CODE_END -- student_courses // USER_CODE_END -- student_courses

3
admin/src/app/api/sys.ts

@ -765,7 +765,6 @@ export function yjpzConfig(params: Record<string, any>) {
return request.post(`sys/yjpz_config`, params) return request.post(`sys/yjpz_config`, params)
} }
export function xsyjConfig(params: Record<string, any>) { export function xsyjConfig(params: Record<string, any>) {
return request.post(`sys/xsyj_config`, params) return request.post(`sys/xsyj_config`, params)
} }
@ -773,5 +772,3 @@ export function xsyjConfig(params: Record<string, any>) {
export function getXsyjConfig() { export function getXsyjConfig() {
return request.get('sys/get_xsyj_config') return request.get('sys/get_xsyj_config')
} }

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

@ -1,21 +1,21 @@
{ {
"resourceId":"资源", "resourceId": "资源",
"resourceIdPlaceholder":"全部", "resourceIdPlaceholder": "全部",
"resourceType":"资源类型", "resourceType": "资源类型",
"resourceTypePlaceholder":"请输入资源类型", "resourceTypePlaceholder": "请输入资源类型",
"communicationType":"沟通类型", "communicationType": "沟通类型",
"communicationTypePlaceholder":"请输入沟通类型", "communicationTypePlaceholder": "请输入沟通类型",
"communicationResult":"沟通结果", "communicationResult": "沟通结果",
"communicationResultPlaceholder":"请输入沟通结果", "communicationResultPlaceholder": "请输入沟通结果",
"communicationTime":"沟通时间", "communicationTime": "沟通时间",
"communicationTimePlaceholder":"请输入沟通时间", "communicationTimePlaceholder": "请输入沟通时间",
"remarks":"备注", "remarks": "备注",
"remarksPlaceholder":"请输入备注", "remarksPlaceholder": "请输入备注",
"tag":"标签", "tag": "标签",
"tagPlaceholder":"请输入标签", "tagPlaceholder": "请输入标签",
"addCommunicationRecords":"添加沟通记录", "addCommunicationRecords": "添加沟通记录",
"updateCommunicationRecords":"编辑沟通记录", "updateCommunicationRecords": "编辑沟通记录",
"communicationRecordsDeleteTips":"确定要删除该数据吗?", "communicationRecordsDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

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

@ -18,7 +18,4 @@
"customerResourceChangesDeleteTips": "确定要删除该数据吗?", "customerResourceChangesDeleteTips": "确定要删除该数据吗?",
"startDate": "请选择开始时间", "startDate": "请选择开始时间",
"endDate": "请选择结束时间" "endDate": "请选择结束时间"
} }

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

@ -1,107 +1,105 @@
{ {
"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": "请选择结束时间",
"resourceId": "资源",
"resourceId":"资源", "resourceIdPlaceholder": "请输入资源",
"resourceIdPlaceholder":"请输入资源", "orderStatus": "订单状态",
"orderStatus":"订单状态", "orderStatusPlaceholder": "请输入订单状态",
"orderStatusPlaceholder":"请输入订单状态", "paymentType": "付款类型",
"paymentType":"付款类型", "paymentTypePlaceholder": "请输入付款类型",
"paymentTypePlaceholder":"请输入付款类型", "orderAmount": "订单金额",
"orderAmount":"订单金额", "orderAmountPlaceholder": "请输入订单金额",
"orderAmountPlaceholder":"请输入订单金额", "courseId": "课程",
"courseId":"课程", "courseIdPlaceholder": "请输入课程",
"courseIdPlaceholder":"请输入课程", "classId": "班级",
"classId":"班级", "classIdPlaceholder": "请输入班级",
"classIdPlaceholder":"请输入班级", "staffId": "人员",
"staffId":"人员", "paymentTime": "支付时间",
"paymentTime":"支付时间", "addOrderTable": "添加订单",
"addOrderTable":"添加订单", "updateOrderTable": "编辑订单",
"updateOrderTable":"编辑订单",
"resourceId": "客户姓名",
"resourceIdPlaceholder": "全部",
"resourceId":"客户姓名", "studentId": "学员姓名",
"resourceIdPlaceholder":"全部", "studentIdPlaceholder": "全部",
"studentId":"学员姓名", "height": "身高",
"studentIdPlaceholder":"全部", "heightPlaceholder": "请输入身高",
"height":"身高", "createdAt": "创建时间",
"heightPlaceholder":"请输入身高", "updatedAt": "修改时间",
"createdAt":"创建时间", "addPhysicalTest": "添加体测",
"updatedAt":"修改时间", "updatePhysicalTest": "编辑体测",
"addPhysicalTest":"添加体测", "physicalTestDeleteTips": "确定要删除该数据吗?",
"updatePhysicalTest":"编辑体测", "startDate": "请选择开始时间",
"physicalTestDeleteTips":"确定要删除该数据吗?", "endDate": "请选择结束时间",
"startDate":"请选择开始时间",
"endDate":"请选择结束时间", "resourceId": "客户姓名",
"resourceIdPlaceholder": "全部",
"resourceId":"客户姓名", "studentId": "学员姓名",
"resourceIdPlaceholder":"全部", "studentIdPlaceholder": "全部",
"studentId":"学员姓名", "height": "身高",
"studentIdPlaceholder":"全部", "heightPlaceholder": "请输入身高",
"height":"身高", "weight": "体重",
"heightPlaceholder":"请输入身高", "weightPlaceholder": "请输入体重",
"weight":"体重", "coachId": "教练",
"weightPlaceholder":"请输入体重", "coachIdPlaceholder": "请输入教练",
"coachId":"教练", "seatedForwardBend": "坐位体前屈",
"coachIdPlaceholder":"请输入教练", "seatedForwardBendPlaceholder": "请输入坐位体前屈",
"seatedForwardBend":"坐位体前屈", "sitUps": "仰卧卷腹",
"seatedForwardBendPlaceholder":"请输入坐位体前屈", "sitUpsPlaceholder": "请输入仰卧卷腹",
"sitUps":"仰卧卷腹", "pushUps": "九十度仰卧撑",
"sitUpsPlaceholder":"请输入仰卧卷腹", "pushUpsPlaceholder": "请输入九十度仰卧撑",
"pushUps":"九十度仰卧撑", "flamingoBalance": "火烈鸟平衡测试",
"pushUpsPlaceholder":"请输入九十度仰卧撑", "flamingoBalancePlaceholder": "请输入火烈鸟平衡测试",
"flamingoBalance":"火烈鸟平衡测试", "thirtySecJump": "三十秒双脚连续跳",
"flamingoBalancePlaceholder":"请输入火烈鸟平衡测试", "thirtySecJumpPlaceholder": "请输入三十秒双脚连续跳",
"thirtySecJump":"三十秒双脚连续跳", "standingLongJump": "立定跳远",
"thirtySecJumpPlaceholder":"请输入三十秒双脚连续跳", "standingLongJumpPlaceholder": "请输入立定跳远",
"standingLongJump":"立定跳远", "agilityRun": "4乘10m灵敏折返跑",
"standingLongJumpPlaceholder":"请输入立定跳远", "agilityRunPlaceholder": "请输入4乘10m灵敏折返跑",
"agilityRun":"4乘10m灵敏折返跑", "balanceBeam": "走平衡木",
"agilityRunPlaceholder":"请输入4乘10m灵敏折返跑", "balanceBeamPlaceholder": "请输入走平衡木",
"balanceBeam":"走平衡木", "tennisThrow": "网球掷远",
"balanceBeamPlaceholder":"请输入走平衡木", "tennisThrowPlaceholder": "请输入网球掷远",
"tennisThrow":"网球掷远", "tenMeterShuttleRun": "十米往返跑",
"tennisThrowPlaceholder":"请输入网球掷远", "tenMeterShuttleRunPlaceholder": "请输入十米往返跑",
"tenMeterShuttleRun":"十米往返跑", "addPhysicalTest": "添加体测",
"tenMeterShuttleRunPlaceholder":"请输入十米往返跑", "updatePhysicalTest": "编辑体测",
"addPhysicalTest":"添加体测", "physicalTestDeleteTips": "确定要删除该数据吗?",
"updatePhysicalTest":"编辑体测", "startDate": "请选择开始时间",
"physicalTestDeleteTips":"确定要删除该数据吗?", "endDate": "请选择结束时间"
"startDate":"请选择开始时间", }
"endDate":"请选择结束时间"
}

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

@ -1,15 +1,15 @@
{ {
"questionType":"题型", "questionType": "题型",
"questionContentType":"题干", "questionContentType": "题干",
"questionContent":"题干内容", "questionContent": "题干内容",
"optionAContentType":"选项类型", "optionAContentType": "选项类型",
"optionAContent":"选项内容", "optionAContent": "选项内容",
"correctAnswer":"正确答案", "correctAnswer": "正确答案",
"questionTypePlaceholder":"请选择题型", "questionTypePlaceholder": "请选择题型",
"questionContentTypePlaceholder":"请选择题干类型", "questionContentTypePlaceholder": "请选择题干类型",
"questionContentPlaceholder":"请输入题干内容", "questionContentPlaceholder": "请输入题干内容",
"correctAnswerPlaceholder":"请输入正确答案", "correctAnswerPlaceholder": "请输入正确答案",
"addExamQuestions":"添加试题", "addExamQuestions": "添加试题",
"updateExamQuestions":"编辑试题", "updateExamQuestions": "编辑试题",
"examQuestionsDeleteTips":"确定要删除该试题吗?" "examQuestionsDeleteTips": "确定要删除该试题吗?"
} }

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

@ -1,21 +1,21 @@
{ {
"resourceId":"资源", "resourceId": "资源",
"resourceIdPlaceholder":"请输入资源", "resourceIdPlaceholder": "请输入资源",
"orderStatus":"订单状态", "orderStatus": "订单状态",
"orderStatusPlaceholder":"请输入订单状态", "orderStatusPlaceholder": "请输入订单状态",
"paymentType":"付款类型", "paymentType": "付款类型",
"paymentTypePlaceholder":"请输入付款类型", "paymentTypePlaceholder": "请输入付款类型",
"orderAmount":"订单金额", "orderAmount": "订单金额",
"orderAmountPlaceholder":"请输入订单金额", "orderAmountPlaceholder": "请输入订单金额",
"courseId":"课程", "courseId": "课程",
"courseIdPlaceholder":"请输入课程", "courseIdPlaceholder": "请输入课程",
"classId":"班级", "classId": "班级",
"classIdPlaceholder":"请输入班级", "classIdPlaceholder": "请输入班级",
"staffId":"人员", "staffId": "人员",
"paymentTime":"支付时间", "paymentTime": "支付时间",
"addOrderTable":"添加订单", "addOrderTable": "添加订单",
"updateOrderTable":"编辑订单", "updateOrderTable": "编辑订单",
"orderTableDeleteTips":"确定要删除该数据吗?", "orderTableDeleteTips": "确定要删除该数据吗?",
"startDate":"请选择开始时间", "startDate": "请选择开始时间",
"endDate":"请选择结束时间" "endDate": "请选择结束时间"
} }

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

@ -1,37 +1,37 @@
{ {
"resourceId":"客户姓名", "resourceId": "客户姓名",
"resourceIdPlaceholder":"全部", "resourceIdPlaceholder": "全部",
"studentId":"学员姓名", "studentId": "学员姓名",
"studentIdPlaceholder":"全部", "studentIdPlaceholder": "全部",
"height":"身高", "height": "身高",
"heightPlaceholder":"请输入身高", "heightPlaceholder": "请输入身高",
"weight":"体重", "weight": "体重",
"weightPlaceholder":"请输入体重", "weightPlaceholder": "请输入体重",
"coachId":"教练", "coachId": "教练",
"coachIdPlaceholder":"请输入教练", "coachIdPlaceholder": "请输入教练",
"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": "请选择结束时间"
} }

76
admin/src/app/lang/zh-cn/physical_test.physical_test_edit.json

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

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

@ -1,19 +1,19 @@
{ {
"studentId":"学员", "studentId": "学员",
"studentIdPlaceholder":"全部", "studentIdPlaceholder": "全部",
"courseId":"课程", "courseId": "课程",
"courseIdPlaceholder":"全部", "courseIdPlaceholder": "全部",
"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": "请选择结束时间"
} }

72
admin/src/app/lang/zh-cn/tc_dialog.physical_test_edit.json

@ -1,37 +1,37 @@
{ {
"resourceId":"客户姓名", "resourceId": "客户姓名",
"resourceIdPlaceholder":"全部", "resourceIdPlaceholder": "全部",
"studentId":"学员姓名", "studentId": "学员姓名",
"studentIdPlaceholder":"全部", "studentIdPlaceholder": "全部",
"height":"身高", "height": "身高",
"heightPlaceholder":"请输入身高", "heightPlaceholder": "请输入身高",
"weight":"体重", "weight": "体重",
"weightPlaceholder":"请输入体重", "weightPlaceholder": "请输入体重",
"coachId":"教练", "coachId": "教练",
"coachIdPlaceholder":"请输入教练", "coachIdPlaceholder": "请输入教练",
"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": "请选择结束时间"
} }

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

@ -186,7 +186,7 @@ const route = useRoute()
const pageName = route.meta.title const pageName = route.meta.title
// ?dept_id=1 // ?dept_id=1
const dept_id = pageName == '市场人员列表' ? 1 : 2; const dept_id = pageName == '市场人员列表' ? 1 : 2
let campusPersonRoleTable = reactive({ let campusPersonRoleTable = reactive({
page: 1, page: 1,
limit: 10, limit: 10,

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

@ -1,231 +1,320 @@
<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('resourceId')" prop="resource_id"> <el-form
<el-select class="w-[280px]" v-model="communicationRecordsTable.searchParam.resource_id" clearable :placeholder="t('resourceIdPlaceholder')"> :inline="true"
<el-option :model="communicationRecordsTable.searchParam"
v-for="(item, index) in resourceIdList" ref="searchFormRef"
:key="index" >
:label="item['name']" <el-form-item :label="t('resourceId')" prop="resource_id">
:value="item['id']" <el-select
/> class="w-[280px]"
</el-select> v-model="communicationRecordsTable.searchParam.resource_id"
</el-form-item> clearable
:placeholder="t('resourceIdPlaceholder')"
>
<el-form-item :label="t('communicationType')" prop="communication_type"> <el-option
<el-select class="w-[280px]" v-model="communicationRecordsTable.searchParam.communication_type" clearable :placeholder="t('communicationTypePlaceholder')"> v-for="(item, index) in resourceIdList"
<el-option label="全部" value=""></el-option> :key="index"
<el-option :label="item['name']"
v-for="(item, index) in communication_typeList" :value="item['id']"
:key="index" />
:label="item.name" </el-select>
:value="item.value" </el-form-item>
/>
</el-select> <el-form-item
</el-form-item> :label="t('communicationType')"
prop="communication_type"
<el-form-item> >
<el-button type="primary" @click="loadCommunicationRecordsList()">{{ t('search') }}</el-button> <el-select
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> class="w-[280px]"
</el-form-item> v-model="communicationRecordsTable.searchParam.communication_type"
</el-form> clearable
</el-card> :placeholder="t('communicationTypePlaceholder')"
>
<div class="mt-[10px]"> <el-option label="全部" value=""></el-option>
<el-table :data="communicationRecordsTable.data" size="large" v-loading="communicationRecordsTable.loading"> <el-option
<template #empty> v-for="(item, index) in communication_typeList"
<span>{{ !communicationRecordsTable.loading ? t('emptyData') : '' }}</span> :key="index"
</template> :label="item.name"
<el-table-column prop="resource_id_name" :label="t('resourceId')" min-width="120" :show-overflow-tooltip="true"/> :value="item.value"
/>
<el-table-column prop="resource_type" :label="t('resourceType')" min-width="120" :show-overflow-tooltip="true"/> </el-select>
</el-form-item>
<el-table-column :label="t('communicationType')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }"> <el-form-item>
<div v-for="(item, index) in communication_typeList"> <el-button type="primary" @click="loadCommunicationRecordsList()">{{
<div v-if="item.value == row.communication_type">{{ item.name }}</div> t('search')
</div> }}</el-button>
</template> <el-button @click="resetForm(searchFormRef)">{{
</el-table-column> t('reset')
}}</el-button>
<el-table-column :label="t('communicationResult')" min-width="180" align="center" :show-overflow-tooltip="true"> </el-form-item>
<template #default="{ row }"> </el-form>
<div v-for="(item, index) in communication_resultList"> </el-card>
<div v-if="item.value == row.communication_result">{{ item.name }}</div>
</div> <div class="mt-[10px]">
</template> <el-table
</el-table-column> :data="communicationRecordsTable.data"
size="large"
<el-table-column prop="communication_time" :label="t('communicationTime')" min-width="120" :show-overflow-tooltip="true"/> v-loading="communicationRecordsTable.loading"
>
<el-table-column prop="remarks" :label="t('remarks')" min-width="120" :show-overflow-tooltip="true"/> <template #empty>
<span>{{
<el-table-column :label="t('tag')" min-width="180" align="center" :show-overflow-tooltip="true"> !communicationRecordsTable.loading ? t('emptyData') : ''
<template #default="{ row }"> }}</span>
<div v-for="(item, index) in tagList"> </template>
<div v-if="item.value == row.tag">{{ item.name }}</div> <el-table-column
</div> prop="resource_id_name"
</template> :label="t('resourceId')"
</el-table-column> 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-table-column
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button> prop="resource_type"
</template> :label="t('resourceType')"
</el-table-column> min-width="120"
:show-overflow-tooltip="true"
</el-table> />
<div class="mt-[16px] flex justify-end">
<el-pagination v-model:current-page="communicationRecordsTable.page" v-model:page-size="communicationRecordsTable.limit" <el-table-column
layout="total, sizes, prev, pager, next, jumper" :total="communicationRecordsTable.total" :label="t('communicationType')"
@size-change="loadCommunicationRecordsList()" @current-change="loadCommunicationRecordsList" /> min-width="180"
</div> align="center"
</div> :show-overflow-tooltip="true"
>
<edit ref="editCommunicationRecordsDialog" @complete="loadCommunicationRecordsList" /> <template #default="{ row }">
</el-card> <div v-for="(item, index) in communication_typeList">
</div> <div v-if="item.value == row.communication_type">
</template> {{ item.name }}
</div>
<script lang="ts" setup> </div>
import { reactive, ref, watch } from 'vue' </template>
import { t } from '@/lang' </el-table-column>
import { useDictionary } from '@/app/api/dict'
import { getCommunicationRecordsList, deleteCommunicationRecords, getWithCustomerResourcesList } from '@/app/api/communication_records' <el-table-column
import { img } from '@/utils/common' :label="t('communicationResult')"
import { ElMessageBox,FormInstance } from 'element-plus' min-width="180"
import Edit from '@/app/views/communication_records/components/communication-records-edit.vue' align="center"
import { useRoute } from 'vue-router' :show-overflow-tooltip="true"
const route = useRoute() >
const pageName = route.meta.title; <template #default="{ row }">
<div v-for="(item, index) in communication_resultList">
let communicationRecordsTable = reactive({ <div v-if="item.value == row.communication_result">
page: 1, {{ item.name }}
limit: 10, </div>
total: 0, </div>
loading: true, </template>
data: [], </el-table-column>
searchParam:{
"resource_id":"", <el-table-column
"communication_type":"" prop="communication_time"
} :label="t('communicationTime')"
}) min-width="120"
:show-overflow-tooltip="true"
const searchFormRef = ref<FormInstance>() />
// <el-table-column
const selectData = ref<any[]>([]) prop="remarks"
:label="t('remarks')"
// min-width="120"
const communication_typeList = ref([] as any[]) :show-overflow-tooltip="true"
const communication_typeDictList = async () => { />
communication_typeList.value = await (await useDictionary('communication_type')).data.dictionary
} <el-table-column
communication_typeDictList(); :label="t('tag')"
const communication_resultList = ref([] as any[]) min-width="180"
const communication_resultDictList = async () => { align="center"
communication_resultList.value = await (await useDictionary('communication_result')).data.dictionary :show-overflow-tooltip="true"
} >
communication_resultDictList(); <template #default="{ row }">
const tagList = ref([] as any[]) <div v-for="(item, index) in tagList">
const tagDictList = async () => { <div v-if="item.value == row.tag">{{ item.name }}</div>
tagList.value = await (await useDictionary('tag')).data.dictionary </div>
} </template>
tagDictList(); </el-table-column>
/** <el-table-column
* 获取沟通记录列表 :label="t('operation')"
*/ fixed="right"
const loadCommunicationRecordsList = (page: number = 1) => { min-width="120"
communicationRecordsTable.loading = true >
communicationRecordsTable.page = page <template #default="{ row }">
<el-button type="primary" link @click="editEvent(row)">{{
getCommunicationRecordsList({ t('edit')
page: communicationRecordsTable.page, }}</el-button>
limit: communicationRecordsTable.limit, <el-button type="primary" link @click="deleteEvent(row.id)">{{
...communicationRecordsTable.searchParam t('delete')
}).then(res => { }}</el-button>
communicationRecordsTable.loading = false </template>
communicationRecordsTable.data = res.data.data </el-table-column>
communicationRecordsTable.total = res.data.total </el-table>
}).catch(() => { <div class="mt-[16px] flex justify-end">
communicationRecordsTable.loading = false <el-pagination
}) v-model:current-page="communicationRecordsTable.page"
} v-model:page-size="communicationRecordsTable.limit"
loadCommunicationRecordsList() layout="total, sizes, prev, pager, next, jumper"
:total="communicationRecordsTable.total"
const editCommunicationRecordsDialog: Record<string, any> | null = ref(null) @size-change="loadCommunicationRecordsList()"
@current-change="loadCommunicationRecordsList"
/** />
* 添加沟通记录 </div>
*/ </div>
const addEvent = () => {
editCommunicationRecordsDialog.value.setFormData() <edit
editCommunicationRecordsDialog.value.showDialog = true ref="editCommunicationRecordsDialog"
} @complete="loadCommunicationRecordsList"
/>
/** </el-card>
* 编辑沟通记录 </div>
* @param data </template>
*/
const editEvent = (data: any) => { <script lang="ts" setup>
editCommunicationRecordsDialog.value.setFormData(data) import { reactive, ref, watch } from 'vue'
editCommunicationRecordsDialog.value.showDialog = true import { t } from '@/lang'
} import { useDictionary } from '@/app/api/dict'
import {
/** getCommunicationRecordsList,
* 删除沟通记录 deleteCommunicationRecords,
*/ getWithCustomerResourcesList,
const deleteEvent = (id: number) => { } from '@/app/api/communication_records'
ElMessageBox.confirm(t('communicationRecordsDeleteTips'), t('warning'), import { img } from '@/utils/common'
{ import { ElMessageBox, FormInstance } from 'element-plus'
confirmButtonText: t('confirm'), import Edit from '@/app/views/communication_records/components/communication-records-edit.vue'
cancelButtonText: t('cancel'), import { useRoute } from 'vue-router'
type: 'warning', const route = useRoute()
} const pageName = route.meta.title
).then(() => {
deleteCommunicationRecords(id).then(() => { let communicationRecordsTable = reactive({
loadCommunicationRecordsList() page: 1,
}).catch(() => { limit: 10,
}) total: 0,
}) loading: true,
} data: [],
searchParam: {
resource_id: '',
const resourceIdList = ref([]) communication_type: '',
const setResourceIdList = async () => { },
resourceIdList.value = await (await getWithCustomerResourcesList({})).data })
}
setResourceIdList() const searchFormRef = ref<FormInstance>()
const resetForm = (formEl: FormInstance | undefined) => { //
if (!formEl) return const selectData = ref<any[]>([])
formEl.resetFields()
loadCommunicationRecordsList() //
} const communication_typeList = ref([] as any[])
</script> const communication_typeDictList = async () => {
communication_typeList.value = await (
<style lang="scss" scoped> await useDictionary('communication_type')
/* 多行超出隐藏 */ ).data.dictionary
.multi-hidden { }
word-break: break-all; communication_typeDictList()
text-overflow: ellipsis; const communication_resultList = ref([] as any[])
overflow: hidden; const communication_resultDictList = async () => {
display: -webkit-box; communication_resultList.value = await (
-webkit-line-clamp: 2; await useDictionary('communication_result')
-webkit-box-orient: vertical; ).data.dictionary
} }
</style> communication_resultDictList()
const tagList = ref([] as any[])
const tagDictList = async () => {
tagList.value = await (await useDictionary('tag')).data.dictionary
}
tagDictList()
/**
* 获取沟通记录列表
*/
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 resourceIdList = ref([])
const setResourceIdList = async () => {
resourceIdList.value = await (await getWithCustomerResourcesList({})).data
}
setResourceIdList()
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>

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

@ -1,262 +1,352 @@
<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('resourceId')" prop="resource_id"> :title="
<el-select class="input-width" v-model="formData.resource_id" clearable :placeholder="t('resourceIdPlaceholder')"> formData.id
<el-option label="请选择" value=""></el-option> ? t('updateCommunicationRecords')
<el-option : t('addCommunicationRecords')
v-for="(item, index) in resourceIdList" "
:key="index" width="50%"
:label="item['name']" class="diy-dialog-wrap"
:value="item['id']" :destroy-on-close="true"
/> >
</el-select> <el-form
</el-form-item> :model="formData"
label-width="120px"
<el-form-item :label="t('resourceType')" prop="resource_type"> ref="formRef"
<el-input v-model="formData.resource_type" clearable :placeholder="t('resourceTypePlaceholder')" class="input-width" /> :rules="formRules"
</el-form-item> class="page-form"
v-loading="loading"
<el-form-item :label="t('communicationType')" prop="communication_type"> >
<el-select class="input-width" v-model="formData.communication_type" clearable :placeholder="t('communicationTypePlaceholder')"> <el-form-item :label="t('resourceId')" prop="resource_id">
<el-option label="请选择" value=""></el-option> <el-select
<el-option class="input-width"
v-for="(item, index) in communication_typeList" v-model="formData.resource_id"
:key="index" clearable
:label="item.name" :placeholder="t('resourceIdPlaceholder')"
:value="item.value" >
/> <el-option label="请选择" value=""></el-option>
</el-select> <el-option
</el-form-item> v-for="(item, index) in resourceIdList"
:key="index"
<el-form-item :label="t('communicationResult')" prop="communication_result"> :label="item['name']"
<el-select class="input-width" v-model="formData.communication_result" clearable :placeholder="t('communicationResultPlaceholder')"> :value="item['id']"
<el-option label="请选择" value=""></el-option> />
<el-option </el-select>
v-for="(item, index) in communication_resultList" </el-form-item>
:key="index"
:label="item.name" <el-form-item :label="t('resourceType')" prop="resource_type">
:value="item.value" <el-input
/> v-model="formData.resource_type"
</el-select> clearable
</el-form-item> :placeholder="t('resourceTypePlaceholder')"
class="input-width"
<el-form-item :label="t('communicationTime')" prop="communication_time" class="input-width"> />
<el-date-picker </el-form-item>
class="flex-1 !flex"
v-model="formData.communication_time" <el-form-item :label="t('communicationType')" prop="communication_type">
clearable <el-select
type="datetime" class="input-width"
value-format="YYYY-MM-DD HH:mm:ss" v-model="formData.communication_type"
:placeholder="t('communicationTimePlaceholder')"> clearable
</el-date-picker> :placeholder="t('communicationTypePlaceholder')"
</el-form-item> >
<el-form-item :label="t('remarks')" > <el-option label="请选择" value=""></el-option>
<el-input v-model="formData.remarks" type="textarea" rows="4" clearable :placeholder="t('remarksPlaceholder')" class="input-width"/> <el-option
</el-form-item> v-for="(item, index) in communication_typeList"
<el-form-item :label="t('tag')" > :key="index"
<el-select class="input-width" v-model="formData.tag" clearable :placeholder="t('tagPlaceholder')"> :label="item.name"
<el-option label="请选择" value=""></el-option> :value="item.value"
<el-option />
v-for="(item, index) in tagList" </el-select>
:key="index" </el-form-item>
:label="item.name"
:value="item.value" <el-form-item
/> :label="t('communicationResult')"
</el-select> prop="communication_result"
</el-form-item> >
<el-select
</el-form> class="input-width"
v-model="formData.communication_result"
<template #footer> clearable
<span class="dialog-footer"> :placeholder="t('communicationResultPlaceholder')"
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button> >
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{ <el-option label="请选择" value=""></el-option>
t('confirm') <el-option
}}</el-button> v-for="(item, index) in communication_resultList"
</span> :key="index"
</template> :label="item.name"
</el-dialog> :value="item.value"
</template> />
</el-select>
<script lang="ts" setup> </el-form-item>
import { ref, reactive, computed, watch } from 'vue'
import { useDictionary } from '@/app/api/dict' <el-form-item
import { t } from '@/lang' :label="t('communicationTime')"
import type { FormInstance } from 'element-plus' prop="communication_time"
import { addCommunicationRecords, editCommunicationRecords, getCommunicationRecordsInfo, getWithCustomerResourcesList } from '@/app/api/communication_records' class="input-width"
>
let showDialog = ref(false) <el-date-picker
const loading = ref(false) class="flex-1 !flex"
v-model="formData.communication_time"
/** clearable
* 表单数据 type="datetime"
*/ value-format="YYYY-MM-DD HH:mm:ss"
const initialFormData = { :placeholder="t('communicationTimePlaceholder')"
id: '', >
resource_id: '', </el-date-picker>
resource_type: '', </el-form-item>
communication_type: '', <el-form-item :label="t('remarks')">
communication_result: '', <el-input
communication_time: '', v-model="formData.remarks"
remarks: '', type="textarea"
tag: '', rows="4"
} clearable
const formData: Record<string, any> = reactive({ ...initialFormData }) :placeholder="t('remarksPlaceholder')"
class="input-width"
const formRef = ref<FormInstance>() />
</el-form-item>
// <el-form-item :label="t('tag')">
const formRules = computed(() => { <el-select
return { class="input-width"
resource_id: [ v-model="formData.tag"
{ required: true, message: t('resourceIdPlaceholder'), trigger: 'blur' }, clearable
:placeholder="t('tagPlaceholder')"
] >
, <el-option label="请选择" value=""></el-option>
resource_type: [ <el-option
{ required: true, message: t('resourceTypePlaceholder'), trigger: 'blur' }, v-for="(item, index) in tagList"
:key="index"
] :label="item.name"
, :value="item.value"
communication_type: [ />
{ required: true, message: t('communicationTypePlaceholder'), trigger: 'blur' }, </el-select>
</el-form-item>
] </el-form>
,
communication_result: [ <template #footer>
{ required: true, message: t('communicationResultPlaceholder'), trigger: 'blur' }, <span class="dialog-footer">
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
] <el-button
, type="primary"
communication_time: [ :loading="loading"
{ required: true, message: t('communicationTimePlaceholder'), 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>
tag: [ import { ref, reactive, computed, watch } from 'vue'
{ required: true, message: t('tagPlaceholder'), trigger: 'blur' }, import { useDictionary } from '@/app/api/dict'
import { t } from '@/lang'
] import type { FormInstance } from 'element-plus'
, import {
} addCommunicationRecords,
}) editCommunicationRecords,
getCommunicationRecordsInfo,
const emit = defineEmits(['complete']) getWithCustomerResourcesList,
} from '@/app/api/communication_records'
/**
* 确认 let showDialog = ref(false)
* @param formEl const loading = ref(false)
*/
const confirm = async (formEl: FormInstance | undefined) => { /**
if (loading.value || !formEl) return * 表单数据
let save = formData.id ? editCommunicationRecords : addCommunicationRecords */
const initialFormData = {
await formEl.validate(async (valid) => { id: '',
if (valid) { resource_id: '',
loading.value = true resource_type: '',
communication_type: '',
let data = formData communication_result: '',
communication_time: '',
save(data).then(res => { remarks: '',
loading.value = false tag: '',
showDialog.value = false }
emit('complete') const formData: Record<string, any> = reactive({ ...initialFormData })
}).catch(err => {
loading.value = false const formRef = ref<FormInstance>()
})
} //
}) const formRules = computed(() => {
} return {
resource_id: [
// { required: true, message: t('resourceIdPlaceholder'), trigger: 'blur' },
let communication_typeList = ref([]) ],
const communication_typeDictList = async () => { resource_type: [
communication_typeList.value = await (await useDictionary('communication_type')).data.dictionary {
} required: true,
communication_typeDictList(); message: t('resourceTypePlaceholder'),
watch(() => communication_typeList.value, () => { formData.communication_type = communication_typeList.value[0].value }) trigger: 'blur',
let communication_resultList = ref([]) },
const communication_resultDictList = async () => { ],
communication_resultList.value = await (await useDictionary('communication_result')).data.dictionary communication_type: [
} {
communication_resultDictList(); required: true,
watch(() => communication_resultList.value, () => { formData.communication_result = communication_resultList.value[0].value }) message: t('communicationTypePlaceholder'),
let tagList = ref([]) trigger: 'blur',
const tagDictList = async () => { },
tagList.value = await (await useDictionary('tag')).data.dictionary ],
} communication_result: [
tagDictList(); {
watch(() => tagList.value, () => { formData.tag = tagList.value[0].value }) required: true,
message: t('communicationResultPlaceholder'),
trigger: 'blur',
const resourceIdList = ref([] as any[]) },
const setResourceIdList = async () => { ],
resourceIdList.value = await (await getWithCustomerResourcesList({})).data communication_time: [
} {
setResourceIdList() required: true,
const setFormData = async (row: any = null) => { message: t('communicationTimePlaceholder'),
Object.assign(formData, initialFormData) trigger: 'blur',
loading.value = true },
if(row){ ],
const data = await (await getCommunicationRecordsInfo(row.id)).data remarks: [
if (data) Object.keys(formData).forEach((key: string) => { { required: true, message: t('remarksPlaceholder'), trigger: 'blur' },
if (data[key] != undefined) formData[key] = data[key] ],
}) tag: [{ required: true, message: t('tagPlaceholder'), trigger: 'blur' }],
} }
loading.value = false })
}
const emit = defineEmits(['complete'])
//
const mobileVerify = (rule: any, value: any, callback: any) => { /**
if (value && !/^1[3-9]\d{9}$/.test(value)) { * 确认
callback(new Error(t('generateMobile'))) * @param formEl
} else { */
callback() const confirm = async (formEl: FormInstance | undefined) => {
} if (loading.value || !formEl) return
} let save = formData.id ? editCommunicationRecords : addCommunicationRecords
// await formEl.validate(async (valid) => {
const idCardVerify = (rule: any, value: any, callback: any) => { if (valid) {
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 = true
callback(new Error(t('generateIdCard')))
} else { let data = formData
callback()
} save(data)
} .then((res) => {
loading.value = false
// showDialog.value = false
const emailVerify = (rule: any, value: any, callback: any) => { emit('complete')
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) { })
callback(new Error(t('generateEmail'))) .catch((err) => {
} else { loading.value = false
callback() })
} }
} })
}
//
const numberVerify = (rule: any, value: any, callback: any) => { //
if (!Number.isInteger(value)) { let communication_typeList = ref([])
callback(new Error(t('generateNumber'))) const communication_typeDictList = async () => {
} else { communication_typeList.value = await (
callback() await useDictionary('communication_type')
} ).data.dictionary
} }
communication_typeDictList()
defineExpose({ watch(
showDialog, () => communication_typeList.value,
setFormData () => {
}) formData.communication_type = communication_typeList.value[0].value
</script> }
)
<style lang="scss" scoped></style> let communication_resultList = ref([])
<style lang="scss"> const communication_resultDictList = async () => {
.diy-dialog-wrap .el-form-item__label{ communication_resultList.value = await (
height: auto !important; await useDictionary('communication_result')
} ).data.dictionary
</style> }
communication_resultDictList()
watch(
() => communication_resultList.value,
() => {
formData.communication_result = communication_resultList.value[0].value
}
)
let tagList = ref([])
const tagDictList = async () => {
tagList.value = await (await useDictionary('tag')).data.dictionary
}
tagDictList()
watch(
() => tagList.value,
() => {
formData.tag = tagList.value[0].value
}
)
const resourceIdList = ref([] as any[])
const setResourceIdList = async () => {
resourceIdList.value = await (await getWithCustomerResourcesList({})).data
}
setResourceIdList()
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>

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

@ -1,368 +1,496 @@
<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
<el-button type="primary" @click="addEvent" v-if="customerResourcesTable.searchParam.type == 'khzy'"> type="primary"
{{ t('addCustomerResources') }} @click="addEvent"
</el-button> v-if="customerResourcesTable.searchParam.type == 'khzy'"
</div> >
{{ t('addCustomerResources') }}
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> </el-button>
<el-form :inline="true" :model="customerResourcesTable.searchParam" ref="searchFormRef"> </div>
<el-form-item :label="t('name')" prop="name">
<el-input v-model="customerResourcesTable.searchParam.name" <el-card
:placeholder="t('namePlaceholder')" /> class="box-card !border-none my-[10px] table-search-wrap"
</el-form-item> shadow="never"
>
<el-form-item label="年龄" prop="age"> <el-form
<el-input v-model="customerResourcesTable.searchParam.age" placeholder="请输入年龄" /> :inline="true"
</el-form-item> :model="customerResourcesTable.searchParam"
ref="searchFormRef"
>
<el-form-item label="性别" prop="gender"> <el-form-item :label="t('name')" prop="name">
<el-select v-model="customerResourcesTable.searchParam.gender" placeholder="请选择性别"> <el-input
<el-option label="男性" value="male" /> v-model="customerResourcesTable.searchParam.name"
<el-option label="女性" value="female" /> :placeholder="t('namePlaceholder')"
<el-option label="其他" value="other" /> />
</el-select> </el-form-item>
</el-form-item>
<el-form-item label="年龄" prop="age">
<el-input
v-model="customerResourcesTable.searchParam.age"
<el-form-item :label="t('phoneNumber')" prop="phone_number"> placeholder="请输入年龄"
<el-input v-model="customerResourcesTable.searchParam.phone_number" />
:placeholder="t('phoneNumberPlaceholder')" /> </el-form-item>
</el-form-item>
<el-form-item label="性别" prop="gender">
<el-select
<el-form-item label="创建时间"> v-model="customerResourcesTable.searchParam.gender"
<el-date-picker v-model="customerResourcesTable.searchParam.created_at" type="daterange" range-separator="" placeholder="请选择性别"
start-placeholder="开始日期" end-placeholder="结束日期" format="YYYY-MM-DD" >
value-format="YYYY-MM-DD" /> <el-option label="男性" value="male" />
</el-form-item> <el-option label="女性" value="female" />
<el-option label="其他" value="other" />
<!-- 更新时间 --> </el-select>
<el-form-item label="更新时间"> </el-form-item>
<el-date-picker v-model="customerResourcesTable.searchParam.updated_at" type="daterange" range-separator=""
start-placeholder="开始日期" end-placeholder="结束日期" format="YYYY-MM-DD" <el-form-item :label="t('phoneNumber')" prop="phone_number">
value-format="YYYY-MM-DD" /> <el-input
</el-form-item> v-model="customerResourcesTable.searchParam.phone_number"
:placeholder="t('phoneNumberPlaceholder')"
/>
<el-form-item> </el-form-item>
<el-button type="primary" @click="loadCustomerResourcesList()">{{ t('search') }}</el-button>
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> <el-form-item label="创建时间">
</el-form-item> <el-date-picker
</el-form> v-model="customerResourcesTable.searchParam.created_at"
</el-card> type="daterange"
range-separator="至"
<div class="mt-[10px]"> start-placeholder="开始日期"
<el-table :data="customerResourcesTable.data" size="large" v-loading="customerResourcesTable.loading"> end-placeholder="结束日期"
<template #empty> format="YYYY-MM-DD"
<span>{{ !customerResourcesTable.loading ? t('emptyData') : '' }}</span> value-format="YYYY-MM-DD"
</template> />
<el-table-column :label="t('source')" min-width="180" align="center" :show-overflow-tooltip="true"> </el-form-item>
<template #default="{ row }">
<div v-for="(item, index) in sourceList"> <!-- 更新时间 -->
<div v-if="item.value == row.source">{{ item.name }}</div> <el-form-item label="更新时间">
</div> <el-date-picker
</template> v-model="customerResourcesTable.searchParam.updated_at"
</el-table-column> type="daterange"
range-separator="至"
<el-table-column prop="consultant_name" :label="t('consultant')" min-width="120" start-placeholder="开始日期"
:show-overflow-tooltip="true" /> end-placeholder="结束日期"
format="YYYY-MM-DD"
<el-table-column prop="name" :label="t('name')" min-width="120" :show-overflow-tooltip="true" /> value-format="YYYY-MM-DD"
/>
<el-table-column prop="age" :label="t('age')" min-width="50" :show-overflow-tooltip="true" /> </el-form-item>
<el-table-column :label="t('gender')" min-width="60" align="center" :show-overflow-tooltip="true"> <el-form-item>
<template #default="{ row }"> <el-button type="primary" @click="loadCustomerResourcesList()">{{
<div v-for="(item, index) in genderList"> t('search')
<div v-if="item.value == row.gender">{{ item.name }}</div> }}</el-button>
</div> <el-button @click="resetForm(searchFormRef)">{{
</template> t('reset')
</el-table-column> }}</el-button>
</el-form-item>
<el-table-column prop="phone_number" :label="t('phoneNumber')" min-width="120" </el-form>
:show-overflow-tooltip="true" /> </el-card>
<el-table-column prop="decision_maker" :label="t('decisionMaker')" min-width="120" <div class="mt-[10px]">
:show-overflow-tooltip="true" /> <el-table
:data="customerResourcesTable.data"
size="large"
<el-table-column prop="created_at" label="添加时间" min-width="120" :show-overflow-tooltip="true" /> v-loading="customerResourcesTable.loading"
>
<el-table-column prop="updated_at" label="修改时间" min-width="120" :show-overflow-tooltip="true" /> <template #empty>
<span>{{
!customerResourcesTable.loading ? t('emptyData') : ''
<el-table-column :label="t('operation')" fixed="right" min-width="200" v-if="customerResourcesTable.searchParam.type == 'khzy'"> }}</span>
<template #default="{ row }"> </template>
<el-button type="primary" link @click="modificationLog(row.id)">六要素修改记录</el-button> <el-table-column
<el-button type="primary" link @click="resourceChanges(row.id)">客户信息修改记录</el-button> :label="t('source')"
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button> min-width="180"
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button> align="center"
:show-overflow-tooltip="true"
</template> >
</el-table-column> <template #default="{ row }">
<div v-for="(item, index) in sourceList">
<div v-if="item.value == row.source">{{ item.name }}</div>
</div>
<el-table-column :label="t('operation')" fixed="right" min-width="200" </template>
v-if="customerResourcesTable.searchParam.type == 'yjfp'"> </el-table-column>
<template #default="{ row }">
<el-button type="primary" link @click="fpEvent(row)">分配</el-button> <el-table-column
</template> prop="consultant_name"
</el-table-column> :label="t('consultant')"
min-width="120"
:show-overflow-tooltip="true"
<el-table-column :label="t('operation')" fixed="right" min-width="200" />
v-if="customerResourcesTable.searchParam.type == 'zylb'">
<template #default="{ row }"> <el-table-column
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button> prop="name"
:label="t('name')"
<el-button type="primary" link @click="addOrder({'resource_id':row.id})">添加订单</el-button> min-width="120"
:show-overflow-tooltip="true"
<el-button type="primary" link @click="tcEvent({'resource_id':row.id})">体测</el-button> />
</template>
</el-table-column> <el-table-column
prop="age"
</el-table> :label="t('age')"
<div class="mt-[16px] flex justify-end"> min-width="50"
<el-pagination v-model:current-page="customerResourcesTable.page" :show-overflow-tooltip="true"
v-model:page-size="customerResourcesTable.limit" />
layout="total, sizes, prev, pager, next, jumper" :total="customerResourcesTable.total"
@size-change="loadCustomerResourcesList()" @current-change="loadCustomerResourcesList" /> <el-table-column
</div> :label="t('gender')"
</div> min-width="60"
align="center"
<edit ref="editCustomerResourcesDialog" @complete="loadCustomerResourcesList" /> :show-overflow-tooltip="true"
>
<fp ref="fpCustomerResourcesDialog" @complete="loadCustomerResourcesList" /> <template #default="{ row }">
<div v-for="(item, index) in genderList">
<Order ref="editOrderTableDialog" @complete="loadCustomerResourcesList" /> <div v-if="item.value == row.gender">{{ item.name }}</div>
</div>
<tc ref="TcCustomerResourcesDialog" @complete="loadCustomerResourcesList" /> </template>
</el-table-column>
</el-card>
</div> <el-table-column
prop="phone_number"
:label="t('phoneNumber')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column
prop="decision_maker"
:label="t('decisionMaker')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column
prop="created_at"
label="添加时间"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column
prop="updated_at"
label="修改时间"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column
:label="t('operation')"
fixed="right"
min-width="200"
v-if="customerResourcesTable.searchParam.type == 'khzy'"
>
<template #default="{ row }">
<el-button type="primary" link @click="modificationLog(row.id)"
>六要素修改记录</el-button
>
<el-button type="primary" link @click="resourceChanges(row.id)"
>客户信息修改记录</el-button
>
<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-column
:label="t('operation')"
fixed="right"
min-width="200"
v-if="customerResourcesTable.searchParam.type == 'yjfp'"
>
<template #default="{ row }">
<el-button type="primary" link @click="fpEvent(row)"
>分配</el-button
>
</template>
</el-table-column>
<el-table-column
:label="t('operation')"
fixed="right"
min-width="200"
v-if="customerResourcesTable.searchParam.type == 'zylb'"
>
<template #default="{ row }">
<el-button type="primary" link @click="editEvent(row)">{{
t('edit')
}}</el-button>
<el-button
type="primary"
link
@click="addOrder({ resource_id: row.id })"
>添加订单</el-button
>
<el-button
type="primary"
link
@click="tcEvent({ resource_id: row.id })"
>体测</el-button
>
</template>
</el-table-column>
</el-table>
<div class="mt-[16px] flex justify-end">
<el-pagination
v-model:current-page="customerResourcesTable.page"
v-model:page-size="customerResourcesTable.limit"
layout="total, sizes, prev, pager, next, jumper"
:total="customerResourcesTable.total"
@size-change="loadCustomerResourcesList()"
@current-change="loadCustomerResourcesList"
/>
</div>
</div>
<edit
ref="editCustomerResourcesDialog"
@complete="loadCustomerResourcesList"
/>
<fp
ref="fpCustomerResourcesDialog"
@complete="loadCustomerResourcesList"
/>
<Order ref="editOrderTableDialog" @complete="loadCustomerResourcesList" />
<tc
ref="TcCustomerResourcesDialog"
@complete="loadCustomerResourcesList"
/>
</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 { getCustomerResourcesList, deleteCustomerResources, getWithPersonnelList, getWithCampusList } from '@/app/api/customer_resources' import {
import { img } from '@/utils/common' getCustomerResourcesList,
import { ElMessageBox, FormInstance } from 'element-plus' deleteCustomerResources,
import Edit from '@/app/views/customer_resources/components/customer-resources-edit.vue' getWithPersonnelList,
import Fp from '@/app/views/customer_resources/components/fp.vue' getWithCampusList,
import Order from '@/app/views/order_table/components/order-table-edit.vue' } from '@/app/api/customer_resources'
import { img } from '@/utils/common'
import Tc from '@/app/views/tc_dialog/tc_dialog.vue' import { ElMessageBox, FormInstance } from 'element-plus'
import Edit from '@/app/views/customer_resources/components/customer-resources-edit.vue'
import { useRouter, useRoute } from 'vue-router' import Fp from '@/app/views/customer_resources/components/fp.vue'
const route = useRoute() import Order from '@/app/views/order_table/components/order-table-edit.vue'
const pageName = route.meta.title;
const router = useRouter() import Tc from '@/app/views/tc_dialog/tc_dialog.vue'
let customerResourcesTable = reactive({ import { useRouter, useRoute } from 'vue-router'
page: 1, const route = useRoute()
limit: 10, const pageName = route.meta.title
total: 0, const router = useRouter()
loading: true,
data: [], let customerResourcesTable = reactive({
searchParam: { page: 1,
"name": "", limit: 10,
"age": "", total: 0,
"gender": "", loading: true,
"phone_number": "", data: [],
'type': '', searchParam: {
"created_at" : "", name: '',
"updated_at" : "" age: '',
} gender: '',
}) phone_number: '',
type: '',
if (pageName == '业绩分配') { created_at: '',
customerResourcesTable.searchParam.type = 'yjfp'; updated_at: '',
} else if (pageName == '客户资源列表') { },
customerResourcesTable.searchParam.type = 'khzy'; })
} else if (pageName == '资源列表') {
customerResourcesTable.searchParam.type = 'zylb'; if (pageName == '业绩分配') {
} customerResourcesTable.searchParam.type = 'yjfp'
} else if (pageName == '客户资源列表') {
// const type = pageName == '' ? 'yjfp' : 'khzy'; customerResourcesTable.searchParam.type = 'khzy'
} else if (pageName == '资源列表') {
customerResourcesTable.searchParam.type = 'zylb'
}
const modificationLog = (id : number) => {
router.push({ path: '/six_speed_modification_log/six_speed_modification_log', query: { id: id } }) // const type = pageName == '' ? 'yjfp' : 'khzy';
}
const modificationLog = (id: number) => {
const resourceChanges = (id : number) => { router.push({
router.push({ path: '/customer_resource_changes/customer_resource_changes', query: { id: id } }) path: '/six_speed_modification_log/six_speed_modification_log',
} query: { id: id },
})
}
/**
* 添加订单 const resourceChanges = (id: number) => {
*/ router.push({
const editOrderTableDialog : Record<string, any> | null = ref(null) path: '/customer_resource_changes/customer_resource_changes',
const addOrder = (row : any) => { query: { id: id },
})
console.log(row); }
editOrderTableDialog.value.setFormData(row)
editOrderTableDialog.value.showDialog = true /**
} * 添加订单
*/
const editOrderTableDialog: Record<string, any> | null = ref(null)
const TcCustomerResourcesDialog : Record<string, any> | null = ref(null) const addOrder = (row: any) => {
const tcEvent = (row : any) => { console.log(row)
TcCustomerResourcesDialog.value.setFormData(row) editOrderTableDialog.value.setFormData(row)
TcCustomerResourcesDialog.value.showDialog = true editOrderTableDialog.value.showDialog = true
} }
const TcCustomerResourcesDialog: Record<string, any> | null = ref(null)
const tcEvent = (row: any) => {
TcCustomerResourcesDialog.value.setFormData(row)
const searchFormRef = ref<FormInstance>() TcCustomerResourcesDialog.value.showDialog = true
}
//
const selectData = ref<any[]>([]) const searchFormRef = ref<FormInstance>()
// //
const sourceList = ref([] as any[]) const selectData = ref<any[]>([])
const sourceDictList = async () => {
sourceList.value = await (await useDictionary('source')).data.dictionary //
} const sourceList = ref([] as any[])
sourceDictList(); const sourceDictList = async () => {
const source_channelList = ref([] as any[]) sourceList.value = await (await useDictionary('source')).data.dictionary
const source_channelDictList = async () => { }
source_channelList.value = await (await useDictionary('SourceChannel')).data.dictionary sourceDictList()
} const source_channelList = ref([] as any[])
source_channelDictList(); const source_channelDictList = async () => {
const genderList = ref([] as any[]) source_channelList.value = await (
const genderDictList = async () => { await useDictionary('SourceChannel')
genderList.value = await (await useDictionary('zy_sex')).data.dictionary ).data.dictionary
} }
genderDictList(); source_channelDictList()
const purchasing_powerList = ref([] as any[]) const genderList = ref([] as any[])
const purchasing_powerDictList = async () => { const genderDictList = async () => {
purchasing_powerList.value = await (await useDictionary('customer_purchasing_power')).data.dictionary genderList.value = await (await useDictionary('zy_sex')).data.dictionary
} }
purchasing_powerDictList(); genderDictList()
const cognitive_ideaList = ref([] as any[]) const purchasing_powerList = ref([] as any[])
const cognitive_ideaDictList = async () => { const purchasing_powerDictList = async () => {
cognitive_ideaList.value = await (await useDictionary('cognitive_concept')).data.dictionary purchasing_powerList.value = await (
} await useDictionary('customer_purchasing_power')
cognitive_ideaDictList(); ).data.dictionary
const initial_intentList = ref([] as any[]) }
const initial_intentDictList = async () => { purchasing_powerDictList()
initial_intentList.value = await (await useDictionary('preliminarycustomerintention')).data.dictionary const cognitive_ideaList = ref([] as any[])
} const cognitive_ideaDictList = async () => {
initial_intentDictList(); cognitive_ideaList.value = await (
const statusList = ref([] as any[]) await useDictionary('cognitive_concept')
const statusDictList = async () => { ).data.dictionary
statusList.value = await (await useDictionary('kh_status')).data.dictionary }
} cognitive_ideaDictList()
statusDictList(); const initial_intentList = ref([] as any[])
const initial_intentDictList = async () => {
initial_intentList.value = await (
/** await useDictionary('preliminarycustomerintention')
* 获取客户资源列表 ).data.dictionary
*/ }
const loadCustomerResourcesList = (page : number = 1) => { initial_intentDictList()
customerResourcesTable.loading = true const statusList = ref([] as any[])
customerResourcesTable.page = page const statusDictList = async () => {
statusList.value = await (await useDictionary('kh_status')).data.dictionary
getCustomerResourcesList({ }
page: customerResourcesTable.page, statusDictList()
limit: customerResourcesTable.limit,
...customerResourcesTable.searchParam /**
}).then(res => { * 获取客户资源列表
customerResourcesTable.loading = false */
customerResourcesTable.data = res.data.data const loadCustomerResourcesList = (page: number = 1) => {
customerResourcesTable.total = res.data.total customerResourcesTable.loading = true
}).catch(() => { customerResourcesTable.page = page
customerResourcesTable.loading = false
}) getCustomerResourcesList({
} page: customerResourcesTable.page,
loadCustomerResourcesList() limit: customerResourcesTable.limit,
...customerResourcesTable.searchParam,
const editCustomerResourcesDialog : Record<string, any> | null = ref(null) })
.then((res) => {
const fpCustomerResourcesDialog : Record<string, any> | null = ref(null) customerResourcesTable.loading = false
customerResourcesTable.data = res.data.data
/** customerResourcesTable.total = res.data.total
* 添加客户资源 })
*/ .catch(() => {
const addEvent = () => { customerResourcesTable.loading = false
editCustomerResourcesDialog.value.setFormData() })
editCustomerResourcesDialog.value.showDialog = true }
} loadCustomerResourcesList()
/** const editCustomerResourcesDialog: Record<string, any> | null = ref(null)
* 编辑客户资源
* @param data const fpCustomerResourcesDialog: Record<string, any> | null = ref(null)
*/
const editEvent = (data : any) => { /**
editCustomerResourcesDialog.value.setFormData(data) * 添加客户资源
editCustomerResourcesDialog.value.showDialog = true */
} const addEvent = () => {
editCustomerResourcesDialog.value.setFormData()
const fpEvent = (data : any) => { editCustomerResourcesDialog.value.showDialog = true
fpCustomerResourcesDialog.value.setFormData(data) }
fpCustomerResourcesDialog.value.showDialog = true
} /**
* 编辑客户资源
* @param data
/** */
* 删除客户资源 const editEvent = (data: any) => {
*/ editCustomerResourcesDialog.value.setFormData(data)
const deleteEvent = (id : number) => { editCustomerResourcesDialog.value.showDialog = true
ElMessageBox.confirm(t('customerResourcesDeleteTips'), t('warning'), }
{
confirmButtonText: t('confirm'), const fpEvent = (data: any) => {
cancelButtonText: t('cancel'), fpCustomerResourcesDialog.value.setFormData(data)
type: 'warning', fpCustomerResourcesDialog.value.showDialog = true
} }
).then(() => {
deleteCustomerResources(id).then(() => { /**
loadCustomerResourcesList() * 删除客户资源
}).catch(() => { */
}) const deleteEvent = (id: number) => {
}) ElMessageBox.confirm(t('customerResourcesDeleteTips'), t('warning'), {
} confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
const consultantList = ref([]) }).then(() => {
const setConsultantList = async () => { deleteCustomerResources(id)
consultantList.value = await (await getWithPersonnelList({})).data .then(() => {
} loadCustomerResourcesList()
setConsultantList() })
const campusList = ref([]) .catch(() => {})
const setCampusList = async () => { })
campusList.value = await (await getWithCampusList({})).data }
}
setCampusList() const consultantList = ref([])
const setConsultantList = async () => {
const resetForm = (formEl : FormInstance | undefined) => { consultantList.value = await (await getWithPersonnelList({})).data
if (!formEl) return }
formEl.resetFields() setConsultantList()
loadCustomerResourcesList() 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> </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>

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

@ -1,267 +1,328 @@
<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('resourceId')" prop="resource_id"> :title="formData.id ? t('updateOrderTable') : t('addOrderTable')"
<el-select class="input-width" v-model="formData.resource_id" clearable :placeholder="t('resourceIdPlaceholder')"> width="50%"
<el-option label="请选择" value=""></el-option> class="diy-dialog-wrap"
<el-option :destroy-on-close="true"
v-for="(item, index) in resourceIdList" >
:key="index" <el-form
:label="item['name']" :model="formData"
:value="item['id']" label-width="120px"
/> ref="formRef"
</el-select> :rules="formRules"
</el-form-item> class="page-form"
v-loading="loading"
<el-form-item :label="t('orderStatus')" prop="order_status"> >
<el-select class="input-width" v-model="formData.order_status" clearable :placeholder="t('orderStatusPlaceholder')"> <el-form-item :label="t('resourceId')" prop="resource_id">
<el-option label="请选择" value=""></el-option> <el-select
<el-option class="input-width"
v-for="(item, index) in order_statusList" v-model="formData.resource_id"
:key="index" clearable
:label="item.name" :placeholder="t('resourceIdPlaceholder')"
:value="item.value" >
/> <el-option label="请选择" value=""></el-option>
</el-select> <el-option
</el-form-item> v-for="(item, index) in resourceIdList"
:key="index"
<el-form-item :label="t('paymentType')" prop="payment_type"> :label="item['name']"
<el-select class="input-width" v-model="formData.payment_type" clearable :placeholder="t('paymentTypePlaceholder')"> :value="item['id']"
<el-option label="请选择" value=""></el-option> />
<el-option </el-select>
v-for="(item, index) in payment_typeList" </el-form-item>
:key="index"
:label="item.name" <el-form-item :label="t('orderStatus')" prop="order_status">
:value="item.value" <el-select
/> class="input-width"
</el-select> v-model="formData.order_status"
</el-form-item> clearable
:placeholder="t('orderStatusPlaceholder')"
<el-form-item :label="t('orderAmount')" prop="order_amount"> >
<el-input v-model="formData.order_amount" clearable :placeholder="t('orderAmountPlaceholder')" class="input-width" /> <el-option label="请选择" value=""></el-option>
</el-form-item> <el-option
v-for="(item, index) in order_statusList"
<el-form-item :label="t('courseId')" prop="course_id"> :key="index"
<el-select class="input-width" v-model="formData.course_id" clearable :placeholder="t('courseIdPlaceholder')"> :label="item.name"
<el-option label="请选择" value=""></el-option> :value="item.value"
<el-option />
v-for="(item, index) in courseIdList" </el-select>
:key="index" </el-form-item>
:label="item['course_name']"
:value="item['id']" <el-form-item :label="t('paymentType')" prop="payment_type">
/> <el-select
</el-select> class="input-width"
</el-form-item> v-model="formData.payment_type"
clearable
<el-form-item :label="t('classId')" prop="class_id"> :placeholder="t('paymentTypePlaceholder')"
<el-select class="input-width" v-model="formData.class_id" clearable :placeholder="t('classIdPlaceholder')"> >
<el-option label="请选择" value=""></el-option> <el-option label="请选择" value=""></el-option>
<el-option <el-option
v-for="(item, index) in classIdList" v-for="(item, index) in payment_typeList"
:key="index" :key="index"
:label="item['class_name']" :label="item.name"
:value="item['id']" :value="item.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-form> <el-form-item :label="t('orderAmount')" prop="order_amount">
<el-input
<template #footer> v-model="formData.order_amount"
<span class="dialog-footer"> clearable
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button> :placeholder="t('orderAmountPlaceholder')"
<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-select
</template> class="input-width"
v-model="formData.course_id"
<script lang="ts" setup> clearable
import { ref, reactive, computed, watch } from 'vue' :placeholder="t('courseIdPlaceholder')"
import { useDictionary } from '@/app/api/dict' >
import { t } from '@/lang' <el-option label="请选择" value=""></el-option>
import type { FormInstance } from 'element-plus' <el-option
import { addOrderTable, editOrderTable, getOrderTableInfo, getWithCustomerResourcesList, getWithCourseList, getWithClassGradeList, getWithPersonnelList } from '@/app/api/order_table' v-for="(item, index) in courseIdList"
:key="index"
let showDialog = ref(false) :label="item['course_name']"
const loading = ref(false) :value="item['id']"
/>
/** </el-select>
* 表单数据 </el-form-item>
*/
const initialFormData = { <el-form-item :label="t('classId')" prop="class_id">
id: '', <el-select
resource_id: '', class="input-width"
order_status: '', v-model="formData.class_id"
payment_type: '', clearable
order_amount: '', :placeholder="t('classIdPlaceholder')"
course_id: '', >
class_id: '', <el-option label="请选择" value=""></el-option>
} <el-option
const formData: Record<string, any> = reactive({ ...initialFormData }) v-for="(item, index) in classIdList"
:key="index"
const formRef = ref<FormInstance>() :label="item['class_name']"
:value="item['id']"
// />
const formRules = computed(() => { </el-select>
return { </el-form-item>
resource_id: [ </el-form>
{ required: true, message: t('resourceIdPlaceholder'), trigger: 'blur' },
<template #footer>
] <span class="dialog-footer">
, <el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
order_status: [ <el-button
{ required: true, message: t('orderStatusPlaceholder'), trigger: 'blur' }, type="primary"
:loading="loading"
] @click="confirm(formRef)"
, >{{ t('confirm') }}</el-button
payment_type: [ >
{ required: true, message: t('paymentTypePlaceholder'), trigger: 'blur' }, </span>
</template>
] </el-dialog>
, </template>
order_amount: [
{ required: true, message: t('orderAmountPlaceholder'), trigger: 'blur' }, <script lang="ts" setup>
import { ref, reactive, computed, watch } from 'vue'
] import { useDictionary } from '@/app/api/dict'
, import { t } from '@/lang'
course_id: [ import type { FormInstance } from 'element-plus'
{ required: true, message: t('courseIdPlaceholder'), trigger: 'blur' }, import {
addOrderTable,
] editOrderTable,
, getOrderTableInfo,
class_id: [ getWithCustomerResourcesList,
{ required: true, message: t('classIdPlaceholder'), trigger: 'blur' }, getWithCourseList,
getWithClassGradeList,
] getWithPersonnelList,
, } from '@/app/api/order_table'
}
}) let showDialog = ref(false)
const loading = ref(false)
const emit = defineEmits(['complete'])
/**
/** * 表单数据
* 确认 */
* @param formEl const initialFormData = {
*/ id: '',
const confirm = async (formEl: FormInstance | undefined) => { resource_id: '',
if (loading.value || !formEl) return order_status: '',
let save = formData.id ? editOrderTable : addOrderTable payment_type: '',
order_amount: '',
await formEl.validate(async (valid) => { course_id: '',
if (valid) { class_id: '',
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 => { resource_id: [
loading.value = false { required: true, message: t('resourceIdPlaceholder'), trigger: 'blur' },
}) ],
} order_status: [
}) { required: true, message: t('orderStatusPlaceholder'), trigger: 'blur' },
} ],
payment_type: [
// { required: true, message: t('paymentTypePlaceholder'), trigger: 'blur' },
let order_statusList = ref([]) ],
const order_statusDictList = async () => { order_amount: [
order_statusList.value = await (await useDictionary('order_status')).data.dictionary { required: true, message: t('orderAmountPlaceholder'), trigger: 'blur' },
} ],
order_statusDictList(); course_id: [
watch(() => order_statusList.value, () => { formData.order_status = order_statusList.value[0].value }) { required: true, message: t('courseIdPlaceholder'), trigger: 'blur' },
let payment_typeList = ref([]) ],
const payment_typeDictList = async () => { class_id: [
payment_typeList.value = await (await useDictionary('payment_type')).data.dictionary { required: true, message: t('classIdPlaceholder'), trigger: 'blur' },
} ],
payment_typeDictList(); }
watch(() => payment_typeList.value, () => { formData.payment_type = payment_typeList.value[0].value }) })
const emit = defineEmits(['complete'])
const resourceIdList = ref([] as any[])
const setResourceIdList = async () => { /**
resourceIdList.value = await (await getWithCustomerResourcesList({})).data * 确认
} * @param formEl
setResourceIdList() */
const courseIdList = ref([] as any[]) const confirm = async (formEl: FormInstance | undefined) => {
const setCourseIdList = async () => { if (loading.value || !formEl) return
courseIdList.value = await (await getWithCourseList({})).data let save = formData.id ? editOrderTable : addOrderTable
}
setCourseIdList() await formEl.validate(async (valid) => {
const classIdList = ref([] as any[]) if (valid) {
const setClassIdList = async () => { loading.value = true
classIdList.value = await (await getWithClassGradeList({})).data
} let data = formData
setClassIdList()
const staffIdList = ref([] as any[]) save(data)
const setStaffIdList = async () => { .then((res) => {
staffIdList.value = await (await getWithPersonnelList({})).data loading.value = false
} showDialog.value = false
setStaffIdList() emit('complete')
const setFormData = async (row: any = null) => { })
Object.assign(formData, initialFormData) .catch((err) => {
Object.assign(formData, row) loading.value = false
// formData.resource_id = row.resource_id; })
// console.log(0) }
// 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] let order_statusList = ref([])
// }) const order_statusDictList = async () => {
// } order_statusList.value = await (
// loading.value = false await useDictionary('order_status')
} ).data.dictionary
}
// order_statusDictList()
const mobileVerify = (rule: any, value: any, callback: any) => { watch(
if (value && !/^1[3-9]\d{9}$/.test(value)) { () => order_statusList.value,
callback(new Error(t('generateMobile'))) () => {
} else { formData.order_status = order_statusList.value[0].value
callback() }
} )
} let payment_typeList = ref([])
const payment_typeDictList = async () => {
// payment_typeList.value = await (
const idCardVerify = (rule: any, value: any, callback: any) => { await useDictionary('payment_type')
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)) { ).data.dictionary
callback(new Error(t('generateIdCard'))) }
} else { payment_typeDictList()
callback() watch(
} () => payment_typeList.value,
} () => {
formData.payment_type = payment_typeList.value[0].value
// }
const emailVerify = (rule: any, value: any, callback: any) => { )
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail'))) const resourceIdList = ref([] as any[])
} else { const setResourceIdList = async () => {
callback() resourceIdList.value = await (await getWithCustomerResourcesList({})).data
} }
} setResourceIdList()
const courseIdList = ref([] as any[])
// const setCourseIdList = async () => {
const numberVerify = (rule: any, value: any, callback: any) => { courseIdList.value = await (await getWithCourseList({})).data
if (!Number.isInteger(value)) { }
callback(new Error(t('generateNumber'))) setCourseIdList()
} else { const classIdList = ref([] as any[])
callback() const setClassIdList = async () => {
} classIdList.value = await (await getWithClassGradeList({})).data
} }
setClassIdList()
defineExpose({ const staffIdList = ref([] as any[])
showDialog, const setStaffIdList = async () => {
setFormData staffIdList.value = await (await getWithPersonnelList({})).data
}) }
</script> setStaffIdList()
const setFormData = async (row: any = null) => {
<style lang="scss" scoped></style> Object.assign(formData, initialFormData)
<style lang="scss"> Object.assign(formData, row)
.diy-dialog-wrap .el-form-item__label{ // formData.resource_id = row.resource_id;
height: auto !important; // console.log(0)
} // loading.value = true
</style> // 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>

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

@ -1,238 +1,323 @@
<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('orderStatus')" prop="order_status"> <el-form
<el-select class="w-[280px]" v-model="orderTableTable.searchParam.order_status" clearable :placeholder="t('orderStatusPlaceholder')"> :inline="true"
<el-option label="全部" value=""></el-option> :model="orderTableTable.searchParam"
<el-option ref="searchFormRef"
v-for="(item, index) in order_statusList" >
:key="index" <el-form-item :label="t('orderStatus')" prop="order_status">
:label="item.name" <el-select
:value="item.value" class="w-[280px]"
/> v-model="orderTableTable.searchParam.order_status"
</el-select> clearable
</el-form-item> :placeholder="t('orderStatusPlaceholder')"
>
<el-option label="全部" value=""></el-option>
<el-form-item :label="t('paymentType')" prop="payment_type"> <el-option
<el-select class="w-[280px]" v-model="orderTableTable.searchParam.payment_type" clearable :placeholder="t('paymentTypePlaceholder')"> v-for="(item, index) in order_statusList"
<el-option label="全部" value=""></el-option> :key="index"
<el-option :label="item.name"
v-for="(item, index) in payment_typeList" :value="item.value"
:key="index" />
:label="item.name" </el-select>
:value="item.value" </el-form-item>
/>
</el-select> <el-form-item :label="t('paymentType')" prop="payment_type">
</el-form-item> <el-select
class="w-[280px]"
<el-form-item> v-model="orderTableTable.searchParam.payment_type"
<el-button type="primary" @click="loadOrderTableList()">{{ t('search') }}</el-button> clearable
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> :placeholder="t('paymentTypePlaceholder')"
</el-form-item> >
</el-form> <el-option label="全部" value=""></el-option>
</el-card> <el-option
v-for="(item, index) in payment_typeList"
<div class="mt-[10px]"> :key="index"
<el-table :data="orderTableTable.data" size="large" v-loading="orderTableTable.loading"> :label="item.name"
<template #empty> :value="item.value"
<span>{{ !orderTableTable.loading ? t('emptyData') : '' }}</span> />
</template> </el-select>
<el-table-column prop="resource_id_name" :label="t('resourceId')" min-width="120" :show-overflow-tooltip="true"/> </el-form-item>
<el-table-column :label="t('orderStatus')" min-width="180" align="center" :show-overflow-tooltip="true"> <el-form-item>
<template #default="{ row }"> <el-button type="primary" @click="loadOrderTableList()">{{
<div v-for="(item, index) in order_statusList"> t('search')
<div v-if="item.value == row.order_status">{{ item.name }}</div> }}</el-button>
</div> <el-button @click="resetForm(searchFormRef)">{{
</template> t('reset')
</el-table-column> }}</el-button>
</el-form-item>
<el-table-column :label="t('paymentType')" min-width="180" align="center" :show-overflow-tooltip="true"> </el-form>
<template #default="{ row }"> </el-card>
<div v-for="(item, index) in payment_typeList">
<div v-if="item.value == row.payment_type">{{ item.name }}</div> <div class="mt-[10px]">
</div> <el-table
</template> :data="orderTableTable.data"
</el-table-column> size="large"
v-loading="orderTableTable.loading"
<el-table-column prop="order_amount" :label="t('orderAmount')" min-width="120" :show-overflow-tooltip="true"/> >
<template #empty>
<el-table-column prop="course_id_name" :label="t('courseId')" min-width="120" :show-overflow-tooltip="true"/> <span>{{ !orderTableTable.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column prop="class_id_name" :label="t('classId')" min-width="120" :show-overflow-tooltip="true"/> <el-table-column
prop="resource_id_name"
<el-table-column prop="staff_id_name" :label="t('staffId')" min-width="120" :show-overflow-tooltip="true"/> :label="t('resourceId')"
min-width="120"
<el-table-column prop="payment_time" :label="t('paymentTime')" min-width="120" :show-overflow-tooltip="true"/> :show-overflow-tooltip="true"
/>
<el-table-column :label="t('operation')" fixed="right" min-width="120">
<template #default="{ row }"> <el-table-column
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button> :label="t('orderStatus')"
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button> min-width="180"
</template> align="center"
</el-table-column> :show-overflow-tooltip="true"
>
</el-table> <template #default="{ row }">
<div class="mt-[16px] flex justify-end"> <div v-for="(item, index) in order_statusList">
<el-pagination v-model:current-page="orderTableTable.page" v-model:page-size="orderTableTable.limit" <div v-if="item.value == row.order_status">{{ item.name }}</div>
layout="total, sizes, prev, pager, next, jumper" :total="orderTableTable.total" </div>
@size-change="loadOrderTableList()" @current-change="loadOrderTableList" /> </template>
</div> </el-table-column>
</div>
<el-table-column
<edit ref="editOrderTableDialog" @complete="loadOrderTableList" /> :label="t('paymentType')"
</el-card> min-width="180"
</div> align="center"
</template> :show-overflow-tooltip="true"
>
<script lang="ts" setup> <template #default="{ row }">
import { reactive, ref, watch } from 'vue' <div v-for="(item, index) in payment_typeList">
import { t } from '@/lang' <div v-if="item.value == row.payment_type">{{ item.name }}</div>
import { useDictionary } from '@/app/api/dict' </div>
import { getOrderTableList, deleteOrderTable, getWithCustomerResourcesList, getWithCourseList, getWithClassGradeList, getWithPersonnelList } from '@/app/api/order_table' </template>
import { img } from '@/utils/common' </el-table-column>
import { ElMessageBox,FormInstance } from 'element-plus'
import Edit from '@/app/views/order_table/components/order-table-edit.vue' <el-table-column
import { useRoute } from 'vue-router' prop="order_amount"
const route = useRoute() :label="t('orderAmount')"
const pageName = route.meta.title; min-width="120"
:show-overflow-tooltip="true"
let orderTableTable = reactive({ />
page: 1,
limit: 10, <el-table-column
total: 0, prop="course_id_name"
loading: true, :label="t('courseId')"
data: [], min-width="120"
searchParam:{ :show-overflow-tooltip="true"
"order_status":"", />
"payment_type":""
} <el-table-column
}) prop="class_id_name"
:label="t('classId')"
const searchFormRef = ref<FormInstance>() min-width="120"
:show-overflow-tooltip="true"
// />
const selectData = ref<any[]>([])
<el-table-column
// prop="staff_id_name"
const order_statusList = ref([] as any[]) :label="t('staffId')"
const order_statusDictList = async () => { min-width="120"
order_statusList.value = await (await useDictionary('order_status')).data.dictionary :show-overflow-tooltip="true"
} />
order_statusDictList();
const payment_typeList = ref([] as any[]) <el-table-column
const payment_typeDictList = async () => { prop="payment_time"
payment_typeList.value = await (await useDictionary('payment_type')).data.dictionary :label="t('paymentTime')"
} min-width="120"
payment_typeDictList(); :show-overflow-tooltip="true"
/>
/**
* 获取订单列表 <el-table-column
*/ :label="t('operation')"
const loadOrderTableList = (page: number = 1) => { fixed="right"
orderTableTable.loading = true min-width="120"
orderTableTable.page = page >
<template #default="{ row }">
getOrderTableList({ <el-button type="primary" link @click="editEvent(row)">{{
page: orderTableTable.page, t('edit')
limit: orderTableTable.limit, }}</el-button>
...orderTableTable.searchParam <el-button type="primary" link @click="deleteEvent(row.id)">{{
}).then(res => { t('delete')
orderTableTable.loading = false }}</el-button>
orderTableTable.data = res.data.data </template>
orderTableTable.total = res.data.total </el-table-column>
}).catch(() => { </el-table>
orderTableTable.loading = false <div class="mt-[16px] flex justify-end">
}) <el-pagination
} v-model:current-page="orderTableTable.page"
loadOrderTableList() v-model:page-size="orderTableTable.limit"
layout="total, sizes, prev, pager, next, jumper"
const editOrderTableDialog: Record<string, any> | null = ref(null) :total="orderTableTable.total"
@size-change="loadOrderTableList()"
/** @current-change="loadOrderTableList"
* 添加订单 />
*/ </div>
const addEvent = () => { </div>
editOrderTableDialog.value.setFormData()
editOrderTableDialog.value.showDialog = true <edit ref="editOrderTableDialog" @complete="loadOrderTableList" />
} </el-card>
</div>
/** </template>
* 编辑订单
* @param data <script lang="ts" setup>
*/ import { reactive, ref, watch } from 'vue'
const editEvent = (data: any) => { import { t } from '@/lang'
editOrderTableDialog.value.setFormData(data) import { useDictionary } from '@/app/api/dict'
editOrderTableDialog.value.showDialog = true import {
} getOrderTableList,
deleteOrderTable,
/** getWithCustomerResourcesList,
* 删除订单 getWithCourseList,
*/ getWithClassGradeList,
const deleteEvent = (id: number) => { getWithPersonnelList,
ElMessageBox.confirm(t('orderTableDeleteTips'), t('warning'), } from '@/app/api/order_table'
{ import { img } from '@/utils/common'
confirmButtonText: t('confirm'), import { ElMessageBox, FormInstance } from 'element-plus'
cancelButtonText: t('cancel'), import Edit from '@/app/views/order_table/components/order-table-edit.vue'
type: 'warning', import { useRoute } from 'vue-router'
} const route = useRoute()
).then(() => { const pageName = route.meta.title
deleteOrderTable(id).then(() => {
loadOrderTableList() let orderTableTable = reactive({
}).catch(() => { page: 1,
}) limit: 10,
}) total: 0,
} loading: true,
data: [],
searchParam: {
const resourceIdList = ref([]) order_status: '',
const setResourceIdList = async () => { payment_type: '',
resourceIdList.value = await (await getWithCustomerResourcesList({})).data },
} })
setResourceIdList()
const courseIdList = ref([]) const searchFormRef = ref<FormInstance>()
const setCourseIdList = async () => {
courseIdList.value = await (await getWithCourseList({})).data //
} const selectData = ref<any[]>([])
setCourseIdList()
const classIdList = ref([]) //
const setClassIdList = async () => { const order_statusList = ref([] as any[])
classIdList.value = await (await getWithClassGradeList({})).data const order_statusDictList = async () => {
} order_statusList.value = await (
setClassIdList() await useDictionary('order_status')
const staffIdList = ref([]) ).data.dictionary
const setStaffIdList = async () => { }
staffIdList.value = await (await getWithPersonnelList({})).data order_statusDictList()
} const payment_typeList = ref([] as any[])
setStaffIdList() const payment_typeDictList = async () => {
payment_typeList.value = await (
const resetForm = (formEl: FormInstance | undefined) => { await useDictionary('payment_type')
if (!formEl) return ).data.dictionary
formEl.resetFields() }
loadOrderTableList() payment_typeDictList()
}
</script> /**
* 获取订单列表
<style lang="scss" scoped> */
/* 多行超出隐藏 */ const loadOrderTableList = (page: number = 1) => {
.multi-hidden { orderTableTable.loading = true
word-break: break-all; orderTableTable.page = page
text-overflow: ellipsis;
overflow: hidden; getOrderTableList({
display: -webkit-box; page: orderTableTable.page,
-webkit-line-clamp: 2; limit: orderTableTable.limit,
-webkit-box-orient: vertical; ...orderTableTable.searchParam,
} })
</style> .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 resourceIdList = ref([])
const setResourceIdList = async () => {
resourceIdList.value = await (await getWithCustomerResourcesList({})).data
}
setResourceIdList()
const courseIdList = ref([])
const setCourseIdList = async () => {
courseIdList.value = await (await getWithCourseList({})).data
}
setCourseIdList()
const classIdList = ref([])
const setClassIdList = async () => {
classIdList.value = await (await getWithClassGradeList({})).data
}
setClassIdList()
const staffIdList = ref([])
const setStaffIdList = async () => {
staffIdList.value = await (await getWithPersonnelList({})).data
}
setStaffIdList()
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>

740
admin/src/app/views/physical_test/components/physical-test-edit.vue

@ -1,324 +1,416 @@
<template> <template>
<el-dialog v-model="showDialog" :title="formData.id ? t('updatePhysicalTest') : t('addPhysicalTest')" 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('resourceId')" prop="resource_id"> :title="formData.id ? t('updatePhysicalTest') : t('addPhysicalTest')"
<el-select class="input-width" v-model="formData.resource_id" clearable :placeholder="t('resourceIdPlaceholder')"> width="50%"
<el-option label="请选择" value=""></el-option> class="diy-dialog-wrap"
<el-option :destroy-on-close="true"
v-for="(item, index) in resourceIdList" >
:key="index" <el-form
:label="item['name']" :model="formData"
:value="item['id']" label-width="120px"
/> ref="formRef"
</el-select> :rules="formRules"
</el-form-item> class="page-form"
v-loading="loading"
<el-form-item :label="t('studentId')" prop="student_id"> >
<el-select class="input-width" v-model="formData.student_id" clearable :placeholder="t('studentIdPlaceholder')"> <el-form-item :label="t('resourceId')" prop="resource_id">
<el-option label="请选择" value=""></el-option> <el-select
<el-option class="input-width"
v-for="(item, index) in studentIdList" v-model="formData.resource_id"
:key="index" clearable
:label="item['name']" :placeholder="t('resourceIdPlaceholder')"
:value="item['id']" >
/> <el-option label="请选择" value=""></el-option>
</el-select> <el-option
</el-form-item> v-for="(item, index) in resourceIdList"
:key="index"
<el-form-item :label="t('height')" prop="height"> :label="item['name']"
<el-input v-model="formData.height" clearable :placeholder="t('heightPlaceholder')" class="input-width" /> :value="item['id']"
</el-form-item> />
</el-select>
<el-form-item :label="t('weight')" prop="weight"> </el-form-item>
<el-input v-model="formData.weight" clearable :placeholder="t('weightPlaceholder')" class="input-width" />
</el-form-item> <el-form-item :label="t('studentId')" prop="student_id">
<el-select
<el-form-item :label="t('coachId')" prop="coach_id"> class="input-width"
<el-select class="input-width" v-model="formData.coach_id" clearable :placeholder="t('coachIdPlaceholder')"> v-model="formData.student_id"
<el-option label="请选择" value=""></el-option> clearable
<el-option :placeholder="t('studentIdPlaceholder')"
v-for="(item, index) in coachIdList" >
:key="index" <el-option label="请选择" value=""></el-option>
:label="item['name']" <el-option
:value="item['id']" v-for="(item, index) in studentIdList"
/> :key="index"
</el-select> :label="item['name']"
</el-form-item> :value="item['id']"
/>
<el-form-item :label="t('seatedForwardBend')" > </el-select>
<el-input v-model="formData.seated_forward_bend" clearable :placeholder="t('seatedForwardBendPlaceholder')" class="input-width" /> </el-form-item>
</el-form-item>
<el-form-item :label="t('height')" prop="height">
<el-form-item :label="t('sitUps')" > <el-input
<el-input v-model="formData.sit_ups" clearable :placeholder="t('sitUpsPlaceholder')" class="input-width" /> v-model="formData.height"
</el-form-item> clearable
:placeholder="t('heightPlaceholder')"
<el-form-item :label="t('pushUps')" > class="input-width"
<el-input v-model="formData.push_ups" clearable :placeholder="t('pushUpsPlaceholder')" class="input-width" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('flamingoBalance')" > <el-form-item :label="t('weight')" prop="weight">
<el-input v-model="formData.flamingo_balance" clearable :placeholder="t('flamingoBalancePlaceholder')" class="input-width" /> <el-input
</el-form-item> v-model="formData.weight"
clearable
<el-form-item :label="t('thirtySecJump')" > :placeholder="t('weightPlaceholder')"
<el-input v-model="formData.thirty_sec_jump" clearable :placeholder="t('thirtySecJumpPlaceholder')" class="input-width" /> class="input-width"
</el-form-item> />
</el-form-item>
<el-form-item :label="t('standingLongJump')" >
<el-input v-model="formData.standing_long_jump" clearable :placeholder="t('standingLongJumpPlaceholder')" class="input-width" /> <el-form-item :label="t('coachId')" prop="coach_id">
</el-form-item> <el-select
class="input-width"
<el-form-item :label="t('agilityRun')" > v-model="formData.coach_id"
<el-input v-model="formData.agility_run" clearable :placeholder="t('agilityRunPlaceholder')" class="input-width" /> clearable
</el-form-item> :placeholder="t('coachIdPlaceholder')"
>
<el-form-item :label="t('balanceBeam')" > <el-option label="请选择" value=""></el-option>
<el-input v-model="formData.balance_beam" clearable :placeholder="t('balanceBeamPlaceholder')" class="input-width" /> <el-option
</el-form-item> v-for="(item, index) in coachIdList"
:key="index"
<el-form-item :label="t('tennisThrow')" > :label="item['name']"
<el-input v-model="formData.tennis_throw" clearable :placeholder="t('tennisThrowPlaceholder')" class="input-width" /> :value="item['id']"
</el-form-item> />
</el-select>
<el-form-item :label="t('tenMeterShuttleRun')" > </el-form-item>
<el-input v-model="formData.ten_meter_shuttle_run" clearable :placeholder="t('tenMeterShuttleRunPlaceholder')" class="input-width" />
</el-form-item> <el-form-item :label="t('seatedForwardBend')">
<el-input
</el-form> v-model="formData.seated_forward_bend"
clearable
<template #footer> :placeholder="t('seatedForwardBendPlaceholder')"
<span class="dialog-footer"> class="input-width"
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button> />
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{ </el-form-item>
t('confirm')
}}</el-button> <el-form-item :label="t('sitUps')">
</span> <el-input
</template> v-model="formData.sit_ups"
</el-dialog> clearable
</template> :placeholder="t('sitUpsPlaceholder')"
class="input-width"
<script lang="ts" setup> />
import { ref, reactive, computed, watch } from 'vue' </el-form-item>
import { useDictionary } from '@/app/api/dict'
import { t } from '@/lang' <el-form-item :label="t('pushUps')">
import type { FormInstance } from 'element-plus' <el-input
import { addPhysicalTest, editPhysicalTest, getPhysicalTestInfo, getWithCustomerResourcesList, getWithStudentList, getWithPersonnelList } from '@/app/api/physical_test' v-model="formData.push_ups"
clearable
let showDialog = ref(false) :placeholder="t('pushUpsPlaceholder')"
const loading = ref(false) class="input-width"
/>
/** </el-form-item>
* 表单数据
*/ <el-form-item :label="t('flamingoBalance')">
const initialFormData = { <el-input
id: '', v-model="formData.flamingo_balance"
resource_id: '', clearable
student_id: '', :placeholder="t('flamingoBalancePlaceholder')"
height: '', class="input-width"
weight: '', />
coach_id: '', </el-form-item>
seated_forward_bend: '',
sit_ups: '', <el-form-item :label="t('thirtySecJump')">
push_ups: '', <el-input
flamingo_balance: '', v-model="formData.thirty_sec_jump"
thirty_sec_jump: '', clearable
standing_long_jump: '', :placeholder="t('thirtySecJumpPlaceholder')"
agility_run: '', class="input-width"
balance_beam: '', />
tennis_throw: '', </el-form-item>
ten_meter_shuttle_run: '',
} <el-form-item :label="t('standingLongJump')">
const formData: Record<string, any> = reactive({ ...initialFormData }) <el-input
v-model="formData.standing_long_jump"
const formRef = ref<FormInstance>() clearable
:placeholder="t('standingLongJumpPlaceholder')"
// class="input-width"
const formRules = computed(() => { />
return { </el-form-item>
resource_id: [
{ required: true, message: t('resourceIdPlaceholder'), trigger: 'blur' }, <el-form-item :label="t('agilityRun')">
<el-input
] v-model="formData.agility_run"
, clearable
student_id: [ :placeholder="t('agilityRunPlaceholder')"
{ required: true, message: t('studentIdPlaceholder'), trigger: 'blur' }, class="input-width"
/>
] </el-form-item>
,
height: [ <el-form-item :label="t('balanceBeam')">
{ required: true, message: t('heightPlaceholder'), trigger: 'blur' }, <el-input
v-model="formData.balance_beam"
] clearable
, :placeholder="t('balanceBeamPlaceholder')"
weight: [ class="input-width"
{ required: true, message: t('weightPlaceholder'), trigger: 'blur' }, />
</el-form-item>
]
, <el-form-item :label="t('tennisThrow')">
coach_id: [ <el-input
{ required: true, message: t('coachIdPlaceholder'), trigger: 'blur' }, v-model="formData.tennis_throw"
clearable
] :placeholder="t('tennisThrowPlaceholder')"
, class="input-width"
seated_forward_bend: [ />
{ required: true, message: t('seatedForwardBendPlaceholder'), trigger: 'blur' }, </el-form-item>
] <el-form-item :label="t('tenMeterShuttleRun')">
, <el-input
sit_ups: [ v-model="formData.ten_meter_shuttle_run"
{ required: true, message: t('sitUpsPlaceholder'), trigger: 'blur' }, clearable
:placeholder="t('tenMeterShuttleRunPlaceholder')"
] class="input-width"
, />
push_ups: [ </el-form-item>
{ required: true, message: t('pushUpsPlaceholder'), trigger: 'blur' }, </el-form>
] <template #footer>
, <span class="dialog-footer">
flamingo_balance: [ <el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
{ required: true, message: t('flamingoBalancePlaceholder'), trigger: 'blur' }, <el-button
type="primary"
] :loading="loading"
, @click="confirm(formRef)"
thirty_sec_jump: [ >{{ t('confirm') }}</el-button
{ required: true, message: t('thirtySecJumpPlaceholder'), trigger: 'blur' }, >
</span>
] </template>
, </el-dialog>
standing_long_jump: [ </template>
{ required: true, message: t('standingLongJumpPlaceholder'), trigger: 'blur' },
<script lang="ts" setup>
] import { ref, reactive, computed, watch } from 'vue'
, import { useDictionary } from '@/app/api/dict'
agility_run: [ import { t } from '@/lang'
{ required: true, message: t('agilityRunPlaceholder'), trigger: 'blur' }, import type { FormInstance } from 'element-plus'
import {
] addPhysicalTest,
, editPhysicalTest,
balance_beam: [ getPhysicalTestInfo,
{ required: true, message: t('balanceBeamPlaceholder'), trigger: 'blur' }, getWithCustomerResourcesList,
getWithStudentList,
] getWithPersonnelList,
, } from '@/app/api/physical_test'
tennis_throw: [
{ required: true, message: t('tennisThrowPlaceholder'), trigger: 'blur' }, let showDialog = ref(false)
const loading = ref(false)
]
, /**
ten_meter_shuttle_run: [ * 表单数据
{ required: true, message: t('tenMeterShuttleRunPlaceholder'), trigger: 'blur' }, */
const initialFormData = {
] id: '',
, resource_id: '',
} student_id: '',
}) height: '',
weight: '',
const emit = defineEmits(['complete']) coach_id: '',
seated_forward_bend: '',
/** sit_ups: '',
* 确认 push_ups: '',
* @param formEl flamingo_balance: '',
*/ thirty_sec_jump: '',
const confirm = async (formEl: FormInstance | undefined) => { standing_long_jump: '',
if (loading.value || !formEl) return agility_run: '',
let save = formData.id ? editPhysicalTest : addPhysicalTest balance_beam: '',
tennis_throw: '',
await formEl.validate(async (valid) => { ten_meter_shuttle_run: '',
if (valid) { }
loading.value = true const formData: Record<string, any> = reactive({ ...initialFormData })
let data = formData const formRef = ref<FormInstance>()
save(data).then(res => { //
loading.value = false const formRules = computed(() => {
showDialog.value = false return {
emit('complete') resource_id: [
}).catch(err => { { required: true, message: t('resourceIdPlaceholder'), trigger: 'blur' },
loading.value = false ],
}) student_id: [
} { required: true, message: t('studentIdPlaceholder'), trigger: 'blur' },
}) ],
} height: [
{ required: true, message: t('heightPlaceholder'), trigger: 'blur' },
// ],
weight: [
{ required: true, message: t('weightPlaceholder'), trigger: 'blur' },
],
const resourceIdList = ref([] as any[]) coach_id: [
const setResourceIdList = async () => { { required: true, message: t('coachIdPlaceholder'), trigger: 'blur' },
resourceIdList.value = await (await getWithCustomerResourcesList({})).data ],
} seated_forward_bend: [
setResourceIdList() {
const studentIdList = ref([] as any[]) required: true,
const setStudentIdList = async () => { message: t('seatedForwardBendPlaceholder'),
studentIdList.value = await (await getWithStudentList({})).data trigger: 'blur',
} },
setStudentIdList() ],
const coachIdList = ref([] as any[]) sit_ups: [
const setCoachIdList = async () => { { required: true, message: t('sitUpsPlaceholder'), trigger: 'blur' },
coachIdList.value = await (await getWithPersonnelList({})).data ],
} push_ups: [
setCoachIdList() { required: true, message: t('pushUpsPlaceholder'), trigger: 'blur' },
const setFormData = async (row: any = null) => { ],
Object.assign(formData, initialFormData) flamingo_balance: [
loading.value = true {
required: true,
Object.assign(formData, row) message: t('flamingoBalancePlaceholder'),
// if(row){ trigger: 'blur',
// const data = await (await getPhysicalTestInfo(row.id)).data },
// if (data) Object.keys(formData).forEach((key: string) => { ],
// if (data[key] != undefined) formData[key] = data[key] thirty_sec_jump: [
// }) {
// } required: true,
loading.value = false message: t('thirtySecJumpPlaceholder'),
} trigger: 'blur',
},
// ],
const mobileVerify = (rule: any, value: any, callback: any) => { standing_long_jump: [
if (value && !/^1[3-9]\d{9}$/.test(value)) { {
callback(new Error(t('generateMobile'))) required: true,
} else { message: t('standingLongJumpPlaceholder'),
callback() trigger: 'blur',
} },
} ],
agility_run: [
// { required: true, message: t('agilityRunPlaceholder'), 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)) { balance_beam: [
callback(new Error(t('generateIdCard'))) { required: true, message: t('balanceBeamPlaceholder'), trigger: 'blur' },
} else { ],
callback() tennis_throw: [
} { required: true, message: t('tennisThrowPlaceholder'), trigger: 'blur' },
} ],
ten_meter_shuttle_run: [
// {
const emailVerify = (rule: any, value: any, callback: any) => { required: true,
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) { message: t('tenMeterShuttleRunPlaceholder'),
callback(new Error(t('generateEmail'))) trigger: 'blur',
} else { },
callback() ],
} }
} })
// const emit = defineEmits(['complete'])
const numberVerify = (rule: any, value: any, callback: any) => {
if (!Number.isInteger(value)) { /**
callback(new Error(t('generateNumber'))) * 确认
} else { * @param formEl
callback() */
} const confirm = async (formEl: FormInstance | undefined) => {
} if (loading.value || !formEl) return
let save = formData.id ? editPhysicalTest : addPhysicalTest
defineExpose({
showDialog, await formEl.validate(async (valid) => {
setFormData if (valid) {
}) loading.value = true
</script>
let data = formData
<style lang="scss" scoped></style>
<style lang="scss"> save(data)
.diy-dialog-wrap .el-form-item__label{ .then((res) => {
height: auto !important; loading.value = false
} showDialog.value = false
</style> emit('complete')
})
.catch((err) => {
loading.value = false
})
}
})
}
//
const resourceIdList = ref([] as any[])
const setResourceIdList = async () => {
resourceIdList.value = await (await getWithCustomerResourcesList({})).data
}
setResourceIdList()
const studentIdList = ref([] as any[])
const setStudentIdList = async () => {
studentIdList.value = await (await getWithStudentList({})).data
}
setStudentIdList()
const coachIdList = ref([] as any[])
const setCoachIdList = async () => {
coachIdList.value = await (await getWithPersonnelList({})).data
}
setCoachIdList()
const setFormData = async (row: any = null) => {
Object.assign(formData, initialFormData)
loading.value = true
Object.assign(formData, row)
// if(row){
// const data = await (await getPhysicalTestInfo(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>

472
admin/src/app/views/physical_test/physical_test.vue

@ -1,204 +1,268 @@
<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('addPhysicalTest') }}
{{ t('addPhysicalTest') }} </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="physicalTestTable.searchParam" ref="searchFormRef"> shadow="never"
>
<el-form-item :label="t('resourceId')" prop="resource_id"> <el-form
<el-select class="w-[280px]" v-model="physicalTestTable.searchParam.resource_id" clearable :placeholder="t('resourceIdPlaceholder')"> :inline="true"
<el-option :model="physicalTestTable.searchParam"
v-for="(item, index) in resourceIdList" ref="searchFormRef"
:key="index" >
:label="item['name']" <el-form-item :label="t('resourceId')" prop="resource_id">
:value="item['id']" <el-select
/> class="w-[280px]"
</el-select> v-model="physicalTestTable.searchParam.resource_id"
</el-form-item> clearable
:placeholder="t('resourceIdPlaceholder')"
>
<el-form-item :label="t('studentId')" prop="student_id"> <el-option
<el-select class="w-[280px]" v-model="physicalTestTable.searchParam.student_id" clearable :placeholder="t('studentIdPlaceholder')"> v-for="(item, index) in resourceIdList"
<el-option :key="index"
v-for="(item, index) in studentIdList" :label="item['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('studentId')" prop="student_id">
<el-select
<el-form-item> class="w-[280px]"
<el-button type="primary" @click="loadPhysicalTestList()">{{ t('search') }}</el-button> v-model="physicalTestTable.searchParam.student_id"
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> clearable
</el-form-item> :placeholder="t('studentIdPlaceholder')"
</el-form> >
</el-card> <el-option
v-for="(item, index) in studentIdList"
<div class="mt-[10px]"> :key="index"
<el-table :data="physicalTestTable.data" size="large" v-loading="physicalTestTable.loading"> :label="item['name']"
<template #empty> :value="item['id']"
<span>{{ !physicalTestTable.loading ? t('emptyData') : '' }}</span> />
</template> </el-select>
<el-table-column prop="resource_id_name" :label="t('resourceId')" min-width="120" :show-overflow-tooltip="true"/> </el-form-item>
<el-table-column prop="student_id_name" :label="t('studentId')" min-width="120" :show-overflow-tooltip="true"/> <el-form-item>
<el-button type="primary" @click="loadPhysicalTestList()">{{
<el-table-column prop="height" :label="t('height')" min-width="120" :show-overflow-tooltip="true"/> t('search')
}}</el-button>
<el-table-column prop="weight" :label="t('weight')" min-width="120" :show-overflow-tooltip="true"/> <el-button @click="resetForm(searchFormRef)">{{
t('reset')
<el-table-column prop="coach_id_name" :label="t('coachId')" min-width="120" :show-overflow-tooltip="true"/> }}</el-button>
</el-form-item>
<el-table-column :label="t('operation')" fixed="right" min-width="120"> </el-form>
<template #default="{ row }"> </el-card>
<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> <div class="mt-[10px]">
</template> <el-table
</el-table-column> :data="physicalTestTable.data"
size="large"
</el-table> v-loading="physicalTestTable.loading"
<div class="mt-[16px] flex justify-end"> >
<el-pagination v-model:current-page="physicalTestTable.page" v-model:page-size="physicalTestTable.limit" <template #empty>
layout="total, sizes, prev, pager, next, jumper" :total="physicalTestTable.total" <span>{{ !physicalTestTable.loading ? t('emptyData') : '' }}</span>
@size-change="loadPhysicalTestList()" @current-change="loadPhysicalTestList" /> </template>
</div> <el-table-column
</div> prop="resource_id_name"
:label="t('resourceId')"
<edit ref="editPhysicalTestDialog" @complete="loadPhysicalTestList" /> min-width="120"
</el-card> :show-overflow-tooltip="true"
</div> />
</template>
<el-table-column
<script lang="ts" setup> prop="student_id_name"
import { reactive, ref, watch } from 'vue' :label="t('studentId')"
import { t } from '@/lang' min-width="120"
import { useDictionary } from '@/app/api/dict' :show-overflow-tooltip="true"
import { getPhysicalTestList, deletePhysicalTest, getWithCustomerResourcesList, getWithStudentList, getWithPersonnelList } from '@/app/api/physical_test' />
import { img } from '@/utils/common'
import { ElMessageBox,FormInstance } from 'element-plus' <el-table-column
import Edit from '@/app/views/physical_test/components/physical-test-edit.vue' prop="height"
import { useRoute } from 'vue-router' :label="t('height')"
const route = useRoute() min-width="120"
const pageName = route.meta.title; :show-overflow-tooltip="true"
/>
let physicalTestTable = reactive({
page: 1, <el-table-column
limit: 10, prop="weight"
total: 0, :label="t('weight')"
loading: true, min-width="120"
data: [], :show-overflow-tooltip="true"
searchParam:{ />
"resource_id":"",
"student_id":"" <el-table-column
} prop="coach_id_name"
}) :label="t('coachId')"
min-width="120"
const searchFormRef = ref<FormInstance>() :show-overflow-tooltip="true"
/>
//
const selectData = ref<any[]>([]) <el-table-column
:label="t('operation')"
// fixed="right"
min-width="120"
>
/** <template #default="{ row }">
* 获取体测列表 <el-button type="primary" link @click="editEvent(row)">{{
*/ t('edit')
const loadPhysicalTestList = (page: number = 1) => { }}</el-button>
physicalTestTable.loading = true <el-button type="primary" link @click="deleteEvent(row.id)">{{
physicalTestTable.page = page t('delete')
}}</el-button>
getPhysicalTestList({ </template>
page: physicalTestTable.page, </el-table-column>
limit: physicalTestTable.limit, </el-table>
...physicalTestTable.searchParam <div class="mt-[16px] flex justify-end">
}).then(res => { <el-pagination
physicalTestTable.loading = false v-model:current-page="physicalTestTable.page"
physicalTestTable.data = res.data.data v-model:page-size="physicalTestTable.limit"
physicalTestTable.total = res.data.total layout="total, sizes, prev, pager, next, jumper"
}).catch(() => { :total="physicalTestTable.total"
physicalTestTable.loading = false @size-change="loadPhysicalTestList()"
}) @current-change="loadPhysicalTestList"
} />
loadPhysicalTestList() </div>
</div>
const editPhysicalTestDialog: Record<string, any> | null = ref(null)
<edit ref="editPhysicalTestDialog" @complete="loadPhysicalTestList" />
/** </el-card>
* 添加体测 </div>
*/ </template>
const addEvent = () => {
editPhysicalTestDialog.value.setFormData() <script lang="ts" setup>
editPhysicalTestDialog.value.showDialog = true import { reactive, ref, watch } from 'vue'
} import { t } from '@/lang'
import { useDictionary } from '@/app/api/dict'
/** import {
* 编辑体测 getPhysicalTestList,
* @param data deletePhysicalTest,
*/ getWithCustomerResourcesList,
const editEvent = (data: any) => { getWithStudentList,
editPhysicalTestDialog.value.setFormData(data) getWithPersonnelList,
editPhysicalTestDialog.value.showDialog = true } from '@/app/api/physical_test'
} import { img } from '@/utils/common'
import { ElMessageBox, FormInstance } from 'element-plus'
/** import Edit from '@/app/views/physical_test/components/physical-test-edit.vue'
* 删除体测 import { useRoute } from 'vue-router'
*/ const route = useRoute()
const deleteEvent = (id: number) => { const pageName = route.meta.title
ElMessageBox.confirm(t('physicalTestDeleteTips'), t('warning'),
{ let physicalTestTable = reactive({
confirmButtonText: t('confirm'), page: 1,
cancelButtonText: t('cancel'), limit: 10,
type: 'warning', total: 0,
} loading: true,
).then(() => { data: [],
deletePhysicalTest(id).then(() => { searchParam: {
loadPhysicalTestList() resource_id: '',
}).catch(() => { student_id: '',
}) },
}) })
}
const searchFormRef = ref<FormInstance>()
const resourceIdList = ref([]) //
const setResourceIdList = async () => { const selectData = ref<any[]>([])
resourceIdList.value = await (await getWithCustomerResourcesList({})).data
} //
setResourceIdList()
const studentIdList = ref([]) /**
const setStudentIdList = async () => { * 获取体测列表
studentIdList.value = await (await getWithStudentList({})).data */
} const loadPhysicalTestList = (page: number = 1) => {
setStudentIdList() physicalTestTable.loading = true
const coachIdList = ref([]) physicalTestTable.page = page
const setCoachIdList = async () => {
coachIdList.value = await (await getWithPersonnelList({})).data getPhysicalTestList({
} page: physicalTestTable.page,
setCoachIdList() limit: physicalTestTable.limit,
...physicalTestTable.searchParam,
const resetForm = (formEl: FormInstance | undefined) => { })
if (!formEl) return .then((res) => {
formEl.resetFields() physicalTestTable.loading = false
loadPhysicalTestList() physicalTestTable.data = res.data.data
} physicalTestTable.total = res.data.total
</script> })
.catch(() => {
<style lang="scss" scoped> physicalTestTable.loading = false
/* 多行超出隐藏 */ })
.multi-hidden { }
word-break: break-all; loadPhysicalTestList()
text-overflow: ellipsis;
overflow: hidden; const editPhysicalTestDialog: Record<string, any> | null = ref(null)
display: -webkit-box;
-webkit-line-clamp: 2; /**
-webkit-box-orient: vertical; * 添加体测
} */
</style> const addEvent = () => {
editPhysicalTestDialog.value.setFormData()
editPhysicalTestDialog.value.showDialog = true
}
/**
* 编辑体测
* @param data
*/
const editEvent = (data: any) => {
editPhysicalTestDialog.value.setFormData(data)
editPhysicalTestDialog.value.showDialog = true
}
/**
* 删除体测
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('physicalTestDeleteTips'), t('warning'), {
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}).then(() => {
deletePhysicalTest(id)
.then(() => {
loadPhysicalTestList()
})
.catch(() => {})
})
}
const resourceIdList = ref([])
const setResourceIdList = async () => {
resourceIdList.value = await (await getWithCustomerResourcesList({})).data
}
setResourceIdList()
const studentIdList = ref([])
const setStudentIdList = async () => {
studentIdList.value = await (await getWithStudentList({})).data
}
setStudentIdList()
const coachIdList = ref([])
const setCoachIdList = async () => {
coachIdList.value = await (await getWithPersonnelList({})).data
}
setCoachIdList()
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadPhysicalTestList()
}
</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>

764
admin/src/app/views/physical_test/physical_test_edit.vue

@ -1,339 +1,425 @@
<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('resourceId')" prop="resource_id"> :model="formData"
<el-select class="input-width" v-model="formData.resource_id" clearable :placeholder="t('resourceIdPlaceholder')"> label-width="90px"
<el-option label="请选择" value=""></el-option> ref="formRef"
<el-option :rules="formRules"
v-for="(item, index) in resourceIdList" class="page-form"
:key="index" >
:label="item['name']" <el-form-item :label="t('resourceId')" prop="resource_id">
:value="item['id']" <el-select
/> class="input-width"
</el-select> v-model="formData.resource_id"
</el-form-item> clearable
:placeholder="t('resourceIdPlaceholder')"
<el-form-item :label="t('studentId')" prop="student_id"> >
<el-select class="input-width" v-model="formData.student_id" clearable :placeholder="t('studentIdPlaceholder')"> <el-option label="请选择" value=""></el-option>
<el-option label="请选择" value=""></el-option> <el-option
<el-option v-for="(item, index) in resourceIdList"
v-for="(item, index) in studentIdList" :key="index"
:key="index" :label="item['name']"
:label="item['name']" :value="item['id']"
:value="item['id']" />
/> </el-select>
</el-select> </el-form-item>
</el-form-item>
<el-form-item :label="t('studentId')" prop="student_id">
<el-form-item :label="t('height')" prop="height"> <el-select
<el-input v-model="formData.height" clearable :placeholder="t('heightPlaceholder')" class="input-width" /> class="input-width"
</el-form-item> v-model="formData.student_id"
clearable
<el-form-item :label="t('weight')" prop="weight"> :placeholder="t('studentIdPlaceholder')"
<el-input v-model="formData.weight" clearable :placeholder="t('weightPlaceholder')" class="input-width" /> >
</el-form-item> <el-option label="请选择" value=""></el-option>
<el-option
<el-form-item :label="t('coachId')" prop="coach_id"> v-for="(item, index) in studentIdList"
<el-select class="input-width" v-model="formData.coach_id" clearable :placeholder="t('coachIdPlaceholder')"> :key="index"
<el-option label="请选择" value=""></el-option> :label="item['name']"
<el-option :value="item['id']"
v-for="(item, index) in coachIdList" />
:key="index" </el-select>
:label="item['name']" </el-form-item>
:value="item['id']"
/> <el-form-item :label="t('height')" prop="height">
</el-select> <el-input
</el-form-item> v-model="formData.height"
clearable
<el-form-item :label="t('createdAt')" > :placeholder="t('heightPlaceholder')"
<el-input v-model="formData.created_at" clearable :placeholder="t('createdAtPlaceholder')" class="input-width" /> class="input-width"
</el-form-item> />
</el-form-item>
<el-form-item :label="t('updatedAt')" >
<el-input v-model="formData.updated_at" clearable :placeholder="t('updatedAtPlaceholder')" class="input-width" /> <el-form-item :label="t('weight')" prop="weight">
</el-form-item> <el-input
v-model="formData.weight"
<el-form-item :label="t('seatedForwardBend')" > clearable
<el-input v-model="formData.seated_forward_bend" clearable :placeholder="t('seatedForwardBendPlaceholder')" class="input-width" /> :placeholder="t('weightPlaceholder')"
</el-form-item> class="input-width"
/>
<el-form-item :label="t('sitUps')" > </el-form-item>
<el-input v-model="formData.sit_ups" clearable :placeholder="t('sitUpsPlaceholder')" class="input-width" />
</el-form-item> <el-form-item :label="t('coachId')" prop="coach_id">
<el-select
<el-form-item :label="t('pushUps')" > class="input-width"
<el-input v-model="formData.push_ups" clearable :placeholder="t('pushUpsPlaceholder')" class="input-width" /> v-model="formData.coach_id"
</el-form-item> clearable
:placeholder="t('coachIdPlaceholder')"
<el-form-item :label="t('flamingoBalance')" > >
<el-input v-model="formData.flamingo_balance" clearable :placeholder="t('flamingoBalancePlaceholder')" class="input-width" /> <el-option label="请选择" value=""></el-option>
</el-form-item> <el-option
v-for="(item, index) in coachIdList"
<el-form-item :label="t('thirtySecJump')" > :key="index"
<el-input v-model="formData.thirty_sec_jump" clearable :placeholder="t('thirtySecJumpPlaceholder')" class="input-width" /> :label="item['name']"
</el-form-item> :value="item['id']"
/>
<el-form-item :label="t('standingLongJump')" > </el-select>
<el-input v-model="formData.standing_long_jump" clearable :placeholder="t('standingLongJumpPlaceholder')" class="input-width" /> </el-form-item>
</el-form-item>
<el-form-item :label="t('createdAt')">
<el-form-item :label="t('agilityRun')" > <el-input
<el-input v-model="formData.agility_run" clearable :placeholder="t('agilityRunPlaceholder')" class="input-width" /> v-model="formData.created_at"
</el-form-item> clearable
:placeholder="t('createdAtPlaceholder')"
<el-form-item :label="t('balanceBeam')" > class="input-width"
<el-input v-model="formData.balance_beam" clearable :placeholder="t('balanceBeamPlaceholder')" class="input-width" /> />
</el-form-item> </el-form-item>
<el-form-item :label="t('tennisThrow')" > <el-form-item :label="t('updatedAt')">
<el-input v-model="formData.tennis_throw" clearable :placeholder="t('tennisThrowPlaceholder')" class="input-width" /> <el-input
</el-form-item> v-model="formData.updated_at"
clearable
<el-form-item :label="t('tenMeterShuttleRun')" > :placeholder="t('updatedAtPlaceholder')"
<el-input v-model="formData.ten_meter_shuttle_run" clearable :placeholder="t('tenMeterShuttleRunPlaceholder')" class="input-width" /> class="input-width"
</el-form-item> />
</el-form-item>
</el-form>
</el-card> <el-form-item :label="t('seatedForwardBend')">
<div class="fixed-footer-wrap"> <el-input
<div class="fixed-footer"> v-model="formData.seated_forward_bend"
<el-button type="primary" @click="onSave(formRef)">{{ t('save') }}</el-button> clearable
<el-button @click="back()">{{ t('cancel') }}</el-button> :placeholder="t('seatedForwardBendPlaceholder')"
</div> class="input-width"
</div> />
</div> </el-form-item>
</template>
<el-form-item :label="t('sitUps')">
<script lang="ts" setup> <el-input
import { ref, reactive, computed, watch } from 'vue' v-model="formData.sit_ups"
import { t } from '@/lang' clearable
import { useDictionary } from '@/app/api/dict' :placeholder="t('sitUpsPlaceholder')"
import type { FormInstance } from 'element-plus' class="input-width"
import { getPhysicalTestInfo,addPhysicalTest,editPhysicalTest, getWithCustomerResourcesList, getWithStudentList, getWithPersonnelList } from '@/app/api/physical_test'; />
import { useRoute } from 'vue-router' </el-form-item>
const route = useRoute() <el-form-item :label="t('pushUps')">
const id:number = parseInt(route.query.id); <el-input
const loading = ref(false) v-model="formData.push_ups"
const pageName = route.meta.title clearable
:placeholder="t('pushUpsPlaceholder')"
class="input-width"
/>
/** </el-form-item>
* 表单数据
*/ <el-form-item :label="t('flamingoBalance')">
const initialFormData = { <el-input
id: 0, v-model="formData.flamingo_balance"
resource_id: '', clearable
student_id: '', :placeholder="t('flamingoBalancePlaceholder')"
height: '', class="input-width"
weight: '', />
coach_id: '', </el-form-item>
created_at: '',
updated_at: '', <el-form-item :label="t('thirtySecJump')">
seated_forward_bend: '', <el-input
sit_ups: '', v-model="formData.thirty_sec_jump"
push_ups: '', clearable
flamingo_balance: '', :placeholder="t('thirtySecJumpPlaceholder')"
thirty_sec_jump: '', class="input-width"
standing_long_jump: '', />
agility_run: '', </el-form-item>
balance_beam: '',
tennis_throw: '', <el-form-item :label="t('standingLongJump')">
ten_meter_shuttle_run: '', <el-input
} v-model="formData.standing_long_jump"
const formData: Record<string, any> = reactive({ ...initialFormData }) clearable
:placeholder="t('standingLongJumpPlaceholder')"
const setFormData = async (id:number = 0) => { class="input-width"
Object.assign(formData, initialFormData) />
const data = await (await getPhysicalTestInfo(id)).data </el-form-item>
Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key] <el-form-item :label="t('agilityRun')">
}) <el-input
} v-model="formData.agility_run"
if(id) setFormData(id); clearable
:placeholder="t('agilityRunPlaceholder')"
const formRef = ref<FormInstance>() class="input-width"
// />
const selectData = ref<any[]>([]) </el-form-item>
// <el-form-item :label="t('balanceBeam')">
<el-input
v-model="formData.balance_beam"
clearable
const resourceIdList = ref([] as any[]) :placeholder="t('balanceBeamPlaceholder')"
const setResourceIdList = async () => { class="input-width"
resourceIdList.value = await (await getWithCustomerResourcesList({})).data />
} </el-form-item>
setResourceIdList()
const studentIdList = ref([] as any[]) <el-form-item :label="t('tennisThrow')">
const setStudentIdList = async () => { <el-input
studentIdList.value = await (await getWithStudentList({})).data v-model="formData.tennis_throw"
} clearable
setStudentIdList() :placeholder="t('tennisThrowPlaceholder')"
const coachIdList = ref([] as any[]) class="input-width"
const setCoachIdList = async () => { />
coachIdList.value = await (await getWithPersonnelList({})).data </el-form-item>
}
setCoachIdList() <el-form-item :label="t('tenMeterShuttleRun')">
// <el-input
const formRules = computed(() => { v-model="formData.ten_meter_shuttle_run"
return { clearable
resource_id: [ :placeholder="t('tenMeterShuttleRunPlaceholder')"
{ required: true, message: t('resourceIdPlaceholder'), trigger: 'blur' }, class="input-width"
/>
] </el-form-item>
, </el-form>
student_id: [ </el-card>
{ required: true, message: t('studentIdPlaceholder'), trigger: 'blur' }, <div class="fixed-footer-wrap">
<div class="fixed-footer">
] <el-button type="primary" @click="onSave(formRef)">{{
, t('save')
height: [ }}</el-button>
{ required: true, message: t('heightPlaceholder'), trigger: 'blur' }, <el-button @click="back()">{{ t('cancel') }}</el-button>
</div>
] </div>
, </div>
weight: [ </template>
{ required: true, message: t('weightPlaceholder'), trigger: 'blur' },
<script lang="ts" setup>
] import { ref, reactive, computed, watch } from 'vue'
, import { t } from '@/lang'
coach_id: [ import { useDictionary } from '@/app/api/dict'
{ required: true, message: t('coachIdPlaceholder'), trigger: 'blur' }, import type { FormInstance } from 'element-plus'
import {
] getPhysicalTestInfo,
, addPhysicalTest,
created_at: [ editPhysicalTest,
{ required: true, message: t('createdAtPlaceholder'), trigger: 'blur' }, getWithCustomerResourcesList,
getWithStudentList,
] getWithPersonnelList,
, } from '@/app/api/physical_test'
updated_at: [ import { useRoute } from 'vue-router'
{ required: true, message: t('updatedAtPlaceholder'), trigger: 'blur' },
const route = useRoute()
] const id: number = parseInt(route.query.id)
, const loading = ref(false)
seated_forward_bend: [ const pageName = route.meta.title
{ required: true, message: t('seatedForwardBendPlaceholder'), trigger: 'blur' },
/**
] * 表单数据
, */
sit_ups: [ const initialFormData = {
{ required: true, message: t('sitUpsPlaceholder'), trigger: 'blur' }, id: 0,
resource_id: '',
] student_id: '',
, height: '',
push_ups: [ weight: '',
{ required: true, message: t('pushUpsPlaceholder'), trigger: 'blur' }, coach_id: '',
created_at: '',
] updated_at: '',
, seated_forward_bend: '',
flamingo_balance: [ sit_ups: '',
{ required: true, message: t('flamingoBalancePlaceholder'), trigger: 'blur' }, push_ups: '',
flamingo_balance: '',
] thirty_sec_jump: '',
, standing_long_jump: '',
thirty_sec_jump: [ agility_run: '',
{ required: true, message: t('thirtySecJumpPlaceholder'), trigger: 'blur' }, balance_beam: '',
tennis_throw: '',
] ten_meter_shuttle_run: '',
, }
standing_long_jump: [ const formData: Record<string, any> = reactive({ ...initialFormData })
{ required: true, message: t('standingLongJumpPlaceholder'), trigger: 'blur' },
const setFormData = async (id: number = 0) => {
] Object.assign(formData, initialFormData)
, const data = await (await getPhysicalTestInfo(id)).data
agility_run: [ Object.keys(formData).forEach((key: string) => {
{ required: true, message: t('agilityRunPlaceholder'), trigger: 'blur' }, if (data[key] != undefined) formData[key] = data[key]
})
] }
, if (id) setFormData(id)
balance_beam: [
{ required: true, message: t('balanceBeamPlaceholder'), trigger: 'blur' }, const formRef = ref<FormInstance>()
//
] const selectData = ref<any[]>([])
,
tennis_throw: [ //
{ required: true, message: t('tennisThrowPlaceholder'), trigger: 'blur' },
const resourceIdList = ref([] as any[])
] const setResourceIdList = async () => {
, resourceIdList.value = await (await getWithCustomerResourcesList({})).data
ten_meter_shuttle_run: [ }
{ required: true, message: t('tenMeterShuttleRunPlaceholder'), trigger: 'blur' }, setResourceIdList()
const studentIdList = ref([] as any[])
] const setStudentIdList = async () => {
, studentIdList.value = await (await getWithStudentList({})).data
} }
}) setStudentIdList()
const coachIdList = ref([] as any[])
const onSave = async (formEl: FormInstance | undefined) => { const setCoachIdList = async () => {
if (loading.value || !formEl) return coachIdList.value = await (await getWithPersonnelList({})).data
await formEl.validate(async (valid) => { }
if (valid) { setCoachIdList()
loading.value = true //
let data = formData const formRules = computed(() => {
return {
const save = id ? editPhysicalTest : addPhysicalTest resource_id: [
save(data).then(res => { { required: true, message: t('resourceIdPlaceholder'), trigger: 'blur' },
loading.value = false ],
history.back() student_id: [
}).catch(err => { { required: true, message: t('studentIdPlaceholder'), trigger: 'blur' },
loading.value = false ],
}) height: [
{ required: true, message: t('heightPlaceholder'), trigger: 'blur' },
} ],
}) weight: [
} { required: true, message: t('weightPlaceholder'), trigger: 'blur' },
],
// coach_id: [
const mobileVerify = (rule: any, value: any, callback: any) => { { required: true, message: t('coachIdPlaceholder'), trigger: 'blur' },
if (value && !/^1[3-9]\d{9}$/.test(value)) { ],
callback(new Error(t('generateMobile'))) created_at: [
} else { { required: true, message: t('createdAtPlaceholder'), trigger: 'blur' },
callback() ],
} updated_at: [
} { required: true, message: t('updatedAtPlaceholder'), trigger: 'blur' },
],
// seated_forward_bend: [
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('seatedForwardBendPlaceholder'),
} else { trigger: 'blur',
callback() },
} ],
} sit_ups: [
{ required: true, message: t('sitUpsPlaceholder'), trigger: 'blur' },
// ],
const emailVerify = (rule: any, value: any, callback: any) => { push_ups: [
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) { { required: true, message: t('pushUpsPlaceholder'), trigger: 'blur' },
callback(new Error(t('generateEmail'))) ],
} else { flamingo_balance: [
callback() {
} required: true,
} message: t('flamingoBalancePlaceholder'),
trigger: 'blur',
},
// ],
const numberVerify = (rule: any, value: any, callback: any) => { thirty_sec_jump: [
if (!Number.isInteger(value)) { {
callback(new Error(t('generateNumber'))) required: true,
} else { message: t('thirtySecJumpPlaceholder'),
callback() trigger: 'blur',
} },
} ],
const back = () => { standing_long_jump: [
history.back() {
} required: true,
</script> message: t('standingLongJumpPlaceholder'),
trigger: 'blur',
<style lang="scss" scoped></style> },
],
agility_run: [
{ required: true, message: t('agilityRunPlaceholder'), trigger: 'blur' },
],
balance_beam: [
{ required: true, message: t('balanceBeamPlaceholder'), trigger: 'blur' },
],
tennis_throw: [
{ required: true, message: t('tennisThrowPlaceholder'), trigger: 'blur' },
],
ten_meter_shuttle_run: [
{
required: true,
message: t('tenMeterShuttleRunPlaceholder'),
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 ? editPhysicalTest : addPhysicalTest
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>

331
admin/src/app/views/setting/pay.vue

@ -1,63 +1,116 @@
<template> <template>
<!--支付设置--> <!--支付设置-->
<div class="main-container" v-loading="payLoading"> <div class="main-container" v-loading="payLoading">
<el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center" v-if="!payLoading">
<span class="text-page-title">{{ pageName }}</span>
<el-button type="primary" @click="isEdit = true" ref="setConfigBtn">{{
t('setConfig')
}}</el-button>
</div>
</el-card>
<el-card class="box-card !border-none" shadow="never"> <el-card
<div class="flex justify-between items-center" v-if="!payLoading"> class="box-card mt-[15px] !border-none"
<span class="text-page-title">{{ pageName }}</span> shadow="never"
<el-button type="primary" @click="isEdit = true" ref="setConfigBtn">{{ t('setConfig') }}</el-button> v-for="(payItems, payKey) in payConfigData"
</div> :key="payKey"
</el-card> >
<h3 class="panel-title !text-sm">{{ payItems.name }}</h3>
<el-card class="box-card mt-[15px] !border-none" shadow="never" v-for="(payItems, payKey) in payConfigData" :key="payKey">
<h3 class="panel-title !text-sm">{{ payItems.name }}</h3> <div>
<div
<div> class="flex items-center justify-between p-[10px] table-item-border bg"
<div class="flex items-center justify-between p-[10px] table-item-border bg"> >
<span class="text-base w-[230px]">{{ t('payType') }}</span> <span class="text-base w-[230px]">{{ t('payType') }}</span>
<span class="text-base w-[110px] text-center">{{ t('onState') }}</span> <span class="text-base w-[110px] text-center">{{
<span class="text-base w-[80px] text-center" v-if="isEdit">{{ t('templateName') }}</span> t('onState')
</div> }}</span>
<span class="text-base w-[80px] text-center" v-if="isEdit">{{
t('templateName')
}}</span>
</div>
<div ref="fieldBoxRefs" :data-key="payKey"> <div ref="fieldBoxRefs" :data-key="payKey">
<div class="flex items-center justify-between p-[10px] table-item-border" v-for="(childrenItem, childrenIndex) in payItems.pay_type" :key="childrenItem.redio_key" :id="payKey + '_' + childrenIndex"> <div
<div class="flex w-[230px] flex-shrink-0"> class="flex items-center justify-between p-[10px] table-item-border"
<span v-if="isEdit" class="iconfont icontuodong mr-2 handle cursor-pointer"></span> v-for="(childrenItem, childrenIndex) in payItems.pay_type"
<div class="flex items-center select-none"> :key="childrenItem.redio_key"
<div class="mr-[15px] w-[30px] h-[30px] flex-shrink-0"> :id="payKey + '_' + childrenIndex"
<img class="w-[30px]" :src="img(childrenItem.icon)" /> >
</div> <div class="flex w-[230px] flex-shrink-0">
<span class="text-base text-[#666]">{{ childrenItem.name }}</span> <span
</div> v-if="isEdit"
</div> class="iconfont icontuodong mr-2 handle cursor-pointer"
<div class="flex items-center justify-center w-[110px] select-none"> ></span>
<el-switch v-if="isEdit" v-model="childrenItem.status" :active-value="1" :inactive-value="0" :active-text="t('isEnable')" @change="enablePaymentMode(childrenItem)" /> <div class="flex items-center select-none">
<div v-else> <div class="mr-[15px] w-[30px] h-[30px] flex-shrink-0">
<el-tag v-if="childrenItem.status" class="ml-2" type="success">{{ t('open') }}</el-tag> <img class="w-[30px]" :src="img(childrenItem.icon)" />
<el-tag v-else class="ml-2" type="info">{{ t('notOpen') }}</el-tag>
</div>
</div>
<div class="flex items-center justify-center w-[80px] select-none" v-if="isEdit">
<button class="text-base" @click="configPayFn(childrenItem)" v-if="childrenItem.setting_component">{{ t('clickConfigure') }}</button>
<button v-else>--</button>
</div>
</div>
</div> </div>
<span class="text-base text-[#666]">{{
childrenItem.name
}}</span>
</div>
</div> </div>
</el-card> <div class="flex items-center justify-center w-[110px] select-none">
<el-switch
<div class="fixed-footer-wrap" v-if="isEdit"> v-if="isEdit"
<div class="fixed-footer"> v-model="childrenItem.status"
<el-button type="primary" :loading="loading" @click="cancelFn">{{ t('cancel') }}</el-button> :active-value="1"
<el-button type="primary" :loading="loading" @click="saveFn(formRef)">{{ t('save') }}</el-button> :inactive-value="0"
:active-text="t('isEnable')"
@change="enablePaymentMode(childrenItem)"
/>
<div v-else>
<el-tag
v-if="childrenItem.status"
class="ml-2"
type="success"
>{{ t('open') }}</el-tag
>
<el-tag v-else class="ml-2" type="info">{{
t('notOpen')
}}</el-tag>
</div>
</div>
<div
class="flex items-center justify-center w-[80px] select-none"
v-if="isEdit"
>
<button
class="text-base"
@click="configPayFn(childrenItem)"
v-if="childrenItem.setting_component"
>
{{ t('clickConfigure') }}
</button>
<button v-else>--</button>
</div> </div>
</div>
</div> </div>
</div>
</el-card>
<template v-for="(item, index) in payTypeList"> <div class="fixed-footer-wrap" v-if="isEdit">
<component :is="item.setting_component" :ref="(el) => setPayTypeRefs(el, item.key)" v-if="item.setting_component" @complete="setConfigInfo"/> <div class="fixed-footer">
</template> <el-button type="primary" :loading="loading" @click="cancelFn">{{
t('cancel')
}}</el-button>
<el-button type="primary" :loading="loading" @click="saveFn(formRef)">{{
t('save')
}}</el-button>
</div>
</div> </div>
<template v-for="(item, index) in payTypeList">
<component
:is="item.setting_component"
:ref="(el) => setPayTypeRefs(el, item.key)"
v-if="item.setting_component"
@complete="setConfigInfo"
/>
</template>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -79,14 +132,17 @@ const payTypeRefs = ref({})
const modules: any = import.meta.glob('@/**/*.vue') const modules: any = import.meta.glob('@/**/*.vue')
getAllPayType().then(({ data }) => { getAllPayType().then(({ data }) => {
Object.keys(data).forEach((key: string) => { Object.keys(data).forEach((key: string) => {
data[key].setting_component && (data[key].setting_component = defineAsyncComponent(modules[data[key].setting_component])) data[key].setting_component &&
}) (data[key].setting_component = defineAsyncComponent(
payTypeList.value = data modules[data[key].setting_component]
))
})
payTypeList.value = data
}) })
const setPayTypeRefs = (el: any, index: string) => { const setPayTypeRefs = (el: any, index: string) => {
payTypeRefs.value[index] = (el) payTypeRefs.value[index] = el
} }
const payLoading = ref(true) const payLoading = ref(true)
@ -97,124 +153,127 @@ const setConfigBtn = ref()
// //
const payConfigData = ref([]) const payConfigData = ref([])
const checkPayConfigList = () => { const checkPayConfigList = () => {
getPayConfigList().then(res => { getPayConfigList().then((res) => {
const payData = res.data const payData = res.data
for (const i in payData) { for (const i in payData) {
const payType = payData[i].pay_type const payType = payData[i].pay_type
const pay_type = [] const pay_type = []
let default_key = '' let default_key = ''
payType.forEach((item, index) => { payType.forEach((item, index) => {
item.redio_key = payData[i].key + '_' + item.key item.redio_key = payData[i].key + '_' + item.key
item.defauit_key = '' item.defauit_key = ''
if (item.is_default == 1) { if (item.is_default == 1) {
default_key = item.redio_key default_key = item.redio_key
}
pay_type.push(item)
})
payData[payData[i].key].default_pay_type = default_key
payData[payData[i].key].pay_type = pay_type
} }
payConfigData.value = payData pay_type.push(item)
payLoading.value = false })
nextTick(() => {
fieldBoxRefs.value.forEach((item, index) => { payData[payData[i].key].default_pay_type = default_key
sortableFn(item, index) payData[payData[i].key].pay_type = pay_type
}) }
}) payConfigData.value = payData
payLoading.value = false
nextTick(() => {
fieldBoxRefs.value.forEach((item, index) => {
sortableFn(item, index)
})
}) })
})
} }
checkPayConfigList() checkPayConfigList()
// //
const setConfigInfo = (data:any) => { const setConfigInfo = (data: any) => {
payConfigData.value[data.channel].pay_type.forEach(element => { payConfigData.value[data.channel].pay_type.forEach((element) => {
if (element.key == data.type) { if (element.key == data.type) {
element.config = data.config element.config = data.config
} }
}) })
console.log(payConfigData.value) console.log(payConfigData.value)
} }
// //
const configPayFn = (data:any) => { const configPayFn = (data: any) => {
payTypeRefs.value[data.key].setFormData(data) payTypeRefs.value[data.key].setFormData(data)
payTypeRefs.value[data.key].showDialog = true payTypeRefs.value[data.key].showDialog = true
} }
// //
const enablePaymentMode = async (data: any) => { const enablePaymentMode = async (data: any) => {
if (payTypeRefs.value[data.key] && typeof payTypeRefs.value[data.key].enableVerify == 'function') { if (
payTypeRefs.value[data.key].setFormData(data) payTypeRefs.value[data.key] &&
typeof payTypeRefs.value[data.key].enableVerify == 'function'
const verify = payTypeRefs.value[data.key].enableVerify() ) {
if (!verify) { payTypeRefs.value[data.key].setFormData(data)
data.status = 0
ElMessage(t('configurePaymentMethod')) const verify = payTypeRefs.value[data.key].enableVerify()
return false if (!verify) {
} data.status = 0
ElMessage(t('configurePaymentMethod'))
return false
} }
}
} }
interface SortableEvt extends SortableEvent { interface SortableEvt extends SortableEvent {
originalEvent?: DragEvent originalEvent?: DragEvent
} }
// //
const fieldBoxRefs = ref<any>([]) const fieldBoxRefs = ref<any>([])
watch(isEdit, (newValue, oldValue) => { watch(isEdit, (newValue, oldValue) => {
if (newValue) { if (newValue) {
nextTick(() => { nextTick(() => {
fieldBoxRefs.value.forEach((item:any, index:any) => { fieldBoxRefs.value.forEach((item: any, index: any) => {
sortableFn(item, index) sortableFn(item, index)
}) })
}) })
} }
}) })
// item=>index // item=>index
const sortableFn = (item, index) => { const sortableFn = (item, index) => {
const sortable = Sortable.create(item, { const sortable = Sortable.create(item, {
group: { group: {
put: false // put: false, //
}, },
handle: '.handle', handle: '.handle',
animation: 200, animation: 200,
disabled: false, disabled: false,
onEnd: (evt) => { onEnd: (evt) => {
const key = evt.target.getAttribute('data-key') const key = evt.target.getAttribute('data-key')
const data = payConfigData.value[key].pay_type const data = payConfigData.value[key].pay_type
data.splice(evt.newIndex, 0, ...data.splice(evt.oldIndex, 1)) data.splice(evt.newIndex, 0, ...data.splice(evt.oldIndex, 1))
} },
}) })
} }
// //
const saveFn = () => { const saveFn = () => {
payLoading.value = true payLoading.value = true
const data = cloneDeep(payConfigData.value) const data = cloneDeep(payConfigData.value)
Object.values(data).forEach((item, index) => { Object.values(data).forEach((item, index) => {
item.pay_type.forEach((subItem:any, subIndex:any) => { item.pay_type.forEach((subItem: any, subIndex: any) => {
subItem.sort = subIndex subItem.sort = subIndex
})
}) })
})
setPatConfig({ config: data }).then(res => { setPatConfig({ config: data }).then((res) => {
checkPayConfigList() checkPayConfigList()
isEdit.value = false isEdit.value = false
payLoading.value = false payLoading.value = false
}) })
} }
// //
const cancelFn = () => { const cancelFn = () => {
location.reload() location.reload()
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.table-item-border { .table-item-border {
@apply border-b border-[var(--el-border-color)]; @apply border-b border-[var(--el-border-color)];
} }
</style> </style>

504
admin/src/app/views/student_courses/components/student-courses-edit.vue

@ -1,231 +1,273 @@
<template> <template>
<el-dialog v-model="showDialog" :title="formData.id ? t('updateStudentCourses') : t('addStudentCourses')" 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('studentId')" prop="student_id"> :title="formData.id ? t('updateStudentCourses') : t('addStudentCourses')"
<el-select class="input-width" v-model="formData.student_id" clearable :placeholder="t('studentIdPlaceholder')"> width="50%"
<el-option label="请选择" value=""></el-option> class="diy-dialog-wrap"
<el-option :destroy-on-close="true"
v-for="(item, index) in studentIdList" >
:key="index" <el-form
:label="item['name']" :model="formData"
:value="item['id']" label-width="120px"
/> ref="formRef"
</el-select> :rules="formRules"
</el-form-item> class="page-form"
v-loading="loading"
<el-form-item :label="t('courseId')" prop="course_id"> >
<el-select class="input-width" v-model="formData.course_id" clearable :placeholder="t('courseIdPlaceholder')"> <el-form-item :label="t('studentId')" prop="student_id">
<el-option label="请选择" value=""></el-option> <el-select
<el-option class="input-width"
v-for="(item, index) in courseIdList" v-model="formData.student_id"
:key="index" clearable
:label="item['course_name']" :placeholder="t('studentIdPlaceholder')"
:value="item['id']" >
/> <el-option label="请选择" value=""></el-option>
</el-select> <el-option
</el-form-item> v-for="(item, index) in studentIdList"
:key="index"
<el-form-item :label="t('totalHours')" prop="total_hours"> :label="item['name']"
<el-input v-model="formData.total_hours" clearable :placeholder="t('totalHoursPlaceholder')" class="input-width" /> :value="item['id']"
</el-form-item> />
</el-select>
<el-form-item :label="t('giftHours')" > </el-form-item>
<el-input v-model="formData.gift_hours" clearable :placeholder="t('giftHoursPlaceholder')" class="input-width" />
</el-form-item> <el-form-item :label="t('courseId')" prop="course_id">
<el-select
<el-form-item :label="t('startDate')" prop="start_date" class="input-width"> class="input-width"
<el-date-picker v-model="formData.course_id"
class="flex-1 !flex" clearable
v-model="formData.start_date" :placeholder="t('courseIdPlaceholder')"
clearable >
type="datetime" <el-option label="请选择" value=""></el-option>
value-format="YYYY-MM-DD HH:mm:ss" <el-option
:placeholder="t('startDatePlaceholder')"> v-for="(item, index) in courseIdList"
</el-date-picker> :key="index"
</el-form-item> :label="item['course_name']"
<el-form-item :label="t('endDate')" prop="end_date" class="input-width"> :value="item['id']"
<el-date-picker />
class="flex-1 !flex" </el-select>
v-model="formData.end_date" </el-form-item>
clearable
type="datetime" <el-form-item :label="t('totalHours')" prop="total_hours">
value-format="YYYY-MM-DD HH:mm:ss" <el-input
:placeholder="t('endDatePlaceholder')"> v-model="formData.total_hours"
</el-date-picker> clearable
</el-form-item> :placeholder="t('totalHoursPlaceholder')"
</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('giftHours')">
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{ <el-input
t('confirm') v-model="formData.gift_hours"
}}</el-button> clearable
</span> :placeholder="t('giftHoursPlaceholder')"
</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('startDate')"
import { useDictionary } from '@/app/api/dict' prop="start_date"
import { t } from '@/lang' class="input-width"
import type { FormInstance } from 'element-plus' >
import { addStudentCourses, editStudentCourses, getStudentCoursesInfo, getWithStudentList, getWithCourseList } from '@/app/api/student_courses' <el-date-picker
class="flex-1 !flex"
let showDialog = ref(false) v-model="formData.start_date"
const loading = ref(false) clearable
type="datetime"
/** value-format="YYYY-MM-DD HH:mm:ss"
* 表单数据 :placeholder="t('startDatePlaceholder')"
*/ >
const initialFormData = { </el-date-picker>
id: '', </el-form-item>
student_id: '', <el-form-item :label="t('endDate')" prop="end_date" class="input-width">
course_id: '', <el-date-picker
total_hours: '', class="flex-1 !flex"
gift_hours: '', v-model="formData.end_date"
start_date: '', clearable
end_date: '', type="datetime"
} value-format="YYYY-MM-DD HH:mm:ss"
const formData: Record<string, any> = reactive({ ...initialFormData }) :placeholder="t('endDatePlaceholder')"
>
const formRef = ref<FormInstance>() </el-date-picker>
</el-form-item>
// </el-form>
const formRules = computed(() => {
return { <template #footer>
student_id: [ <span class="dialog-footer">
{ required: true, message: t('studentIdPlaceholder'), trigger: 'blur' }, <el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
<el-button
] type="primary"
, :loading="loading"
course_id: [ @click="confirm(formRef)"
{ required: true, message: t('courseIdPlaceholder'), trigger: 'blur' }, >{{ t('confirm') }}</el-button
>
] </span>
, </template>
total_hours: [ </el-dialog>
{ required: true, message: t('totalHoursPlaceholder'), trigger: 'blur' }, </template>
] <script lang="ts" setup>
, import { ref, reactive, computed, watch } from 'vue'
gift_hours: [ import { useDictionary } from '@/app/api/dict'
{ required: true, message: t('giftHoursPlaceholder'), trigger: 'blur' }, import { t } from '@/lang'
import type { FormInstance } from 'element-plus'
] import {
, addStudentCourses,
start_date: [ editStudentCourses,
{ required: true, message: t('startDatePlaceholder'), trigger: 'blur' }, getStudentCoursesInfo,
getWithStudentList,
] getWithCourseList,
, } from '@/app/api/student_courses'
end_date: [
{ required: true, message: t('endDatePlaceholder'), trigger: 'blur' }, let showDialog = ref(false)
const loading = ref(false)
]
, /**
} * 表单数据
}) */
const initialFormData = {
const emit = defineEmits(['complete']) id: '',
student_id: '',
/** course_id: '',
* 确认 total_hours: '',
* @param formEl gift_hours: '',
*/ start_date: '',
const confirm = async (formEl: FormInstance | undefined) => { end_date: '',
if (loading.value || !formEl) return }
let save = formData.id ? editStudentCourses : addStudentCourses 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 {
student_id: [
save(data).then(res => { { required: true, message: t('studentIdPlaceholder'), trigger: 'blur' },
loading.value = false ],
showDialog.value = false course_id: [
emit('complete') { required: true, message: t('courseIdPlaceholder'), trigger: 'blur' },
}).catch(err => { ],
loading.value = false total_hours: [
}) { required: true, message: t('totalHoursPlaceholder'), trigger: 'blur' },
} ],
}) gift_hours: [
} { required: true, message: t('giftHoursPlaceholder'), trigger: 'blur' },
],
// start_date: [
{ required: true, message: t('startDatePlaceholder'), trigger: 'blur' },
],
end_date: [
const studentIdList = ref([] as any[]) { required: true, message: t('endDatePlaceholder'), trigger: 'blur' },
const setStudentIdList = async () => { ],
studentIdList.value = await (await getWithStudentList({})).data }
} })
setStudentIdList()
const courseIdList = ref([] as any[]) const emit = defineEmits(['complete'])
const setCourseIdList = async () => {
courseIdList.value = await (await getWithCourseList({})).data /**
} * 确认
setCourseIdList() * @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 ? editStudentCourses : addStudentCourses
const data = await (await getStudentCoursesInfo(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 studentIdList = ref([] as any[])
} const setStudentIdList = async () => {
} studentIdList.value = await (await getWithStudentList({})).data
}
// setStudentIdList()
const emailVerify = (rule: any, value: any, callback: any) => { const courseIdList = ref([] as any[])
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) { const setCourseIdList = async () => {
callback(new Error(t('generateEmail'))) courseIdList.value = await (await getWithCourseList({})).data
} else { }
callback() setCourseIdList()
} 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 getStudentCoursesInfo(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>

472
admin/src/app/views/student_courses/student_courses.vue

@ -1,201 +1,271 @@
<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('addStudentCourses') }}
{{ t('addStudentCourses') }} </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="studentCoursesTable.searchParam" ref="searchFormRef"> shadow="never"
>
<el-form-item :label="t('studentId')" prop="student_id"> <el-form
<el-select class="w-[280px]" v-model="studentCoursesTable.searchParam.student_id" clearable :placeholder="t('studentIdPlaceholder')"> :inline="true"
<el-option :model="studentCoursesTable.searchParam"
v-for="(item, index) in studentIdList" ref="searchFormRef"
:key="index" >
:label="item['name']" <el-form-item :label="t('studentId')" prop="student_id">
:value="item['id']" <el-select
/> class="w-[280px]"
</el-select> v-model="studentCoursesTable.searchParam.student_id"
</el-form-item> clearable
:placeholder="t('studentIdPlaceholder')"
>
<el-form-item :label="t('courseId')" prop="course_id"> <el-option
<el-select class="w-[280px]" v-model="studentCoursesTable.searchParam.course_id" clearable :placeholder="t('courseIdPlaceholder')"> v-for="(item, index) in studentIdList"
<el-option :key="index"
v-for="(item, index) in courseIdList" :label="item['name']"
:key="index" :value="item['id']"
:label="item['course_name']" />
:value="item['id']" </el-select>
/> </el-form-item>
</el-select>
</el-form-item> <el-form-item :label="t('courseId')" prop="course_id">
<el-select
<el-form-item> class="w-[280px]"
<el-button type="primary" @click="loadStudentCoursesList()">{{ t('search') }}</el-button> v-model="studentCoursesTable.searchParam.course_id"
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> clearable
</el-form-item> :placeholder="t('courseIdPlaceholder')"
</el-form> >
</el-card> <el-option
v-for="(item, index) in courseIdList"
<div class="mt-[10px]"> :key="index"
<el-table :data="studentCoursesTable.data" size="large" v-loading="studentCoursesTable.loading"> :label="item['course_name']"
<template #empty> :value="item['id']"
<span>{{ !studentCoursesTable.loading ? t('emptyData') : '' }}</span> />
</template> </el-select>
<el-table-column prop="student_id_name" :label="t('studentId')" min-width="120" :show-overflow-tooltip="true"/> </el-form-item>
<el-table-column prop="course_id_name" :label="t('courseId')" min-width="120" :show-overflow-tooltip="true"/> <el-form-item>
<el-button type="primary" @click="loadStudentCoursesList()">{{
<el-table-column prop="total_hours" :label="t('totalHours')" min-width="120" :show-overflow-tooltip="true"/> t('search')
}}</el-button>
<el-table-column prop="gift_hours" :label="t('giftHours')" min-width="120" :show-overflow-tooltip="true"/> <el-button @click="resetForm(searchFormRef)">{{
t('reset')
<el-table-column prop="start_date" :label="t('startDate')" min-width="120" :show-overflow-tooltip="true"/> }}</el-button>
</el-form-item>
<el-table-column prop="end_date" :label="t('endDate')" min-width="120" :show-overflow-tooltip="true"/> </el-form>
</el-card>
<el-table-column :label="t('operation')" fixed="right" min-width="120">
<template #default="{ row }"> <div class="mt-[10px]">
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button> <el-table
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button> :data="studentCoursesTable.data"
</template> size="large"
</el-table-column> v-loading="studentCoursesTable.loading"
>
</el-table> <template #empty>
<div class="mt-[16px] flex justify-end"> <span>{{
<el-pagination v-model:current-page="studentCoursesTable.page" v-model:page-size="studentCoursesTable.limit" !studentCoursesTable.loading ? t('emptyData') : ''
layout="total, sizes, prev, pager, next, jumper" :total="studentCoursesTable.total" }}</span>
@size-change="loadStudentCoursesList()" @current-change="loadStudentCoursesList" /> </template>
</div> <el-table-column
</div> prop="student_id_name"
:label="t('studentId')"
<edit ref="editStudentCoursesDialog" @complete="loadStudentCoursesList" /> min-width="120"
</el-card> :show-overflow-tooltip="true"
</div> />
</template>
<el-table-column
<script lang="ts" setup> prop="course_id_name"
import { reactive, ref, watch } from 'vue' :label="t('courseId')"
import { t } from '@/lang' min-width="120"
import { useDictionary } from '@/app/api/dict' :show-overflow-tooltip="true"
import { getStudentCoursesList, deleteStudentCourses, getWithStudentList, getWithCourseList } from '@/app/api/student_courses' />
import { img } from '@/utils/common'
import { ElMessageBox,FormInstance } from 'element-plus' <el-table-column
import Edit from '@/app/views/student_courses/components/student-courses-edit.vue' prop="total_hours"
import { useRoute } from 'vue-router' :label="t('totalHours')"
const route = useRoute() min-width="120"
const pageName = route.meta.title; :show-overflow-tooltip="true"
/>
let studentCoursesTable = reactive({
page: 1, <el-table-column
limit: 10, prop="gift_hours"
total: 0, :label="t('giftHours')"
loading: true, min-width="120"
data: [], :show-overflow-tooltip="true"
searchParam:{ />
"student_id":"",
"course_id":"" <el-table-column
} prop="start_date"
}) :label="t('startDate')"
min-width="120"
const searchFormRef = ref<FormInstance>() :show-overflow-tooltip="true"
/>
//
const selectData = ref<any[]>([]) <el-table-column
prop="end_date"
// :label="t('endDate')"
min-width="120"
:show-overflow-tooltip="true"
/** />
* 获取学员课程列表
*/ <el-table-column
const loadStudentCoursesList = (page: number = 1) => { :label="t('operation')"
studentCoursesTable.loading = true fixed="right"
studentCoursesTable.page = page min-width="120"
>
getStudentCoursesList({ <template #default="{ row }">
page: studentCoursesTable.page, <el-button type="primary" link @click="editEvent(row)">{{
limit: studentCoursesTable.limit, t('edit')
...studentCoursesTable.searchParam }}</el-button>
}).then(res => { <el-button type="primary" link @click="deleteEvent(row.id)">{{
studentCoursesTable.loading = false t('delete')
studentCoursesTable.data = res.data.data }}</el-button>
studentCoursesTable.total = res.data.total </template>
}).catch(() => { </el-table-column>
studentCoursesTable.loading = false </el-table>
}) <div class="mt-[16px] flex justify-end">
} <el-pagination
loadStudentCoursesList() v-model:current-page="studentCoursesTable.page"
v-model:page-size="studentCoursesTable.limit"
const editStudentCoursesDialog: Record<string, any> | null = ref(null) layout="total, sizes, prev, pager, next, jumper"
:total="studentCoursesTable.total"
/** @size-change="loadStudentCoursesList()"
* 添加学员课程 @current-change="loadStudentCoursesList"
*/ />
const addEvent = () => { </div>
editStudentCoursesDialog.value.setFormData() </div>
editStudentCoursesDialog.value.showDialog = true
} <edit ref="editStudentCoursesDialog" @complete="loadStudentCoursesList" />
</el-card>
/** </div>
* 编辑学员课程 </template>
* @param data
*/ <script lang="ts" setup>
const editEvent = (data: any) => { import { reactive, ref, watch } from 'vue'
editStudentCoursesDialog.value.setFormData(data) import { t } from '@/lang'
editStudentCoursesDialog.value.showDialog = true import { useDictionary } from '@/app/api/dict'
} import {
getStudentCoursesList,
/** deleteStudentCourses,
* 删除学员课程 getWithStudentList,
*/ getWithCourseList,
const deleteEvent = (id: number) => { } from '@/app/api/student_courses'
ElMessageBox.confirm(t('studentCoursesDeleteTips'), t('warning'), import { img } from '@/utils/common'
{ import { ElMessageBox, FormInstance } from 'element-plus'
confirmButtonText: t('confirm'), import Edit from '@/app/views/student_courses/components/student-courses-edit.vue'
cancelButtonText: t('cancel'), import { useRoute } from 'vue-router'
type: 'warning', const route = useRoute()
} const pageName = route.meta.title
).then(() => {
deleteStudentCourses(id).then(() => { let studentCoursesTable = reactive({
loadStudentCoursesList() page: 1,
}).catch(() => { limit: 10,
}) total: 0,
}) loading: true,
} data: [],
searchParam: {
student_id: '',
const studentIdList = ref([]) course_id: '',
const setStudentIdList = async () => { },
studentIdList.value = await (await getWithStudentList({})).data })
}
setStudentIdList() const searchFormRef = ref<FormInstance>()
const courseIdList = ref([])
const setCourseIdList = async () => { //
courseIdList.value = await (await getWithCourseList({})).data const selectData = ref<any[]>([])
}
setCourseIdList() //
const resetForm = (formEl: FormInstance | undefined) => { /**
if (!formEl) return * 获取学员课程列表
formEl.resetFields() */
loadStudentCoursesList() const loadStudentCoursesList = (page: number = 1) => {
} studentCoursesTable.loading = true
</script> studentCoursesTable.page = page
<style lang="scss" scoped> getStudentCoursesList({
/* 多行超出隐藏 */ page: studentCoursesTable.page,
.multi-hidden { limit: studentCoursesTable.limit,
word-break: break-all; ...studentCoursesTable.searchParam,
text-overflow: ellipsis; })
overflow: hidden; .then((res) => {
display: -webkit-box; studentCoursesTable.loading = false
-webkit-line-clamp: 2; studentCoursesTable.data = res.data.data
-webkit-box-orient: vertical; studentCoursesTable.total = res.data.total
} })
</style> .catch(() => {
studentCoursesTable.loading = false
})
}
loadStudentCoursesList()
const editStudentCoursesDialog: Record<string, any> | null = ref(null)
/**
* 添加学员课程
*/
const addEvent = () => {
editStudentCoursesDialog.value.setFormData()
editStudentCoursesDialog.value.showDialog = true
}
/**
* 编辑学员课程
* @param data
*/
const editEvent = (data: any) => {
editStudentCoursesDialog.value.setFormData(data)
editStudentCoursesDialog.value.showDialog = true
}
/**
* 删除学员课程
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('studentCoursesDeleteTips'), t('warning'), {
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}).then(() => {
deleteStudentCourses(id)
.then(() => {
loadStudentCoursesList()
})
.catch(() => {})
})
}
const studentIdList = ref([])
const setStudentIdList = async () => {
studentIdList.value = await (await getWithStudentList({})).data
}
setStudentIdList()
const courseIdList = ref([])
const setCourseIdList = async () => {
courseIdList.value = await (await getWithCourseList({})).data
}
setCourseIdList()
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadStudentCoursesList()
}
</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>

520
admin/src/app/views/tc_dialog/tc_dialog.vue

@ -1,239 +1,281 @@
<template> <template>
<el-dialog <el-dialog
v-model="showDialog" v-model="showDialog"
title="体测列表" title="体测列表"
width="80%" width="80%"
class="diy-dialog-wrap" class="diy-dialog-wrap"
:destroy-on-close="true" :destroy-on-close="true"
> >
<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">体测列表</span>
<span class="text-lg">体测列表</span> <el-button type="primary" @click="addEvent">
<el-button type="primary" @click="addEvent"> {{ t('addPhysicalTest') }}
{{ t('addPhysicalTest') }} </el-button>
</el-button> </div>
</div>
<!-- <el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<!-- <el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> <el-form :inline="true" :model="physicalTestTable.searchParam" ref="searchFormRef">
<el-form :inline="true" :model="physicalTestTable.searchParam" ref="searchFormRef">
<el-form-item :label="t('resourceId')" prop="resource_id">
<el-form-item :label="t('resourceId')" prop="resource_id"> <el-select class="w-[280px]" v-model="physicalTestTable.searchParam.resource_id" clearable :placeholder="t('resourceIdPlaceholder')">
<el-select class="w-[280px]" v-model="physicalTestTable.searchParam.resource_id" clearable :placeholder="t('resourceIdPlaceholder')"> <el-option
<el-option v-for="(item, index) in resourceIdList"
v-for="(item, index) in resourceIdList" :key="index"
:key="index" :label="item['name']"
:label="item['name']" :value="item['id']"
:value="item['id']" />
/> </el-select>
</el-select> </el-form-item>
</el-form-item>
<el-form-item :label="t('studentId')" prop="student_id">
<el-form-item :label="t('studentId')" prop="student_id"> <el-select class="w-[280px]" v-model="physicalTestTable.searchParam.student_id" clearable :placeholder="t('studentIdPlaceholder')">
<el-select class="w-[280px]" v-model="physicalTestTable.searchParam.student_id" clearable :placeholder="t('studentIdPlaceholder')"> <el-option
<el-option v-for="(item, index) in studentIdList"
v-for="(item, index) in studentIdList" :key="index"
:key="index" :label="item['name']"
:label="item['name']" :value="item['id']"
:value="item['id']" />
/> </el-select>
</el-select> </el-form-item>
</el-form-item>
<el-form-item :label="t('height')" prop="height">
<el-form-item :label="t('height')" prop="height"> <el-input v-model="physicalTestTable.searchParam.height" :placeholder="t('heightPlaceholder')" />
<el-input v-model="physicalTestTable.searchParam.height" :placeholder="t('heightPlaceholder')" /> </el-form-item>
</el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="loadPhysicalTestList()">{{ t('search') }}</el-button> <el-button type="primary" @click="loadPhysicalTestList()">{{ t('search') }}</el-button>
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> <el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</el-card> --> </el-card> -->
<div class="mt-[10px]"> <div class="mt-[10px]">
<el-table :data="physicalTestTable.data" size="large" v-loading="physicalTestTable.loading"> <el-table
<template #empty> :data="physicalTestTable.data"
<span>{{ !physicalTestTable.loading ? t('emptyData') : '' }}</span> size="large"
</template> v-loading="physicalTestTable.loading"
<el-table-column prop="resource_id_name" :label="t('resourceId')" min-width="120" :show-overflow-tooltip="true"/> >
<template #empty>
<el-table-column prop="student_id_name" :label="t('studentId')" min-width="120" :show-overflow-tooltip="true"/> <span>{{
!physicalTestTable.loading ? t('emptyData') : ''
<el-table-column prop="height" :label="t('height')" min-width="120" :show-overflow-tooltip="true"/> }}</span>
</template>
<el-table-column prop="created_at" :label="t('createdAt')" min-width="120" :show-overflow-tooltip="true"/> <el-table-column
prop="resource_id_name"
<el-table-column prop="updated_at" :label="t('updatedAt')" min-width="120" :show-overflow-tooltip="true"/> :label="t('resourceId')"
min-width="120"
<el-table-column :label="t('operation')" fixed="right" min-width="120"> :show-overflow-tooltip="true"
<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> --> <el-table-column
</template> prop="student_id_name"
</el-table-column> :label="t('studentId')"
min-width="120"
</el-table> :show-overflow-tooltip="true"
<div class="mt-[16px] flex justify-end"> />
<el-pagination v-model:current-page="physicalTestTable.page" v-model:page-size="physicalTestTable.limit"
layout="total, sizes, prev, pager, next, jumper" :total="physicalTestTable.total" <el-table-column
@size-change="loadPhysicalTestList()" @current-change="loadPhysicalTestList" /> prop="height"
</div> :label="t('height')"
</div> min-width="120"
:show-overflow-tooltip="true"
<edit ref="editPhysicalTestDialog" @complete="loadPhysicalTestList" /> />
</el-card>
</div> <el-table-column
prop="created_at"
</el-dialog> :label="t('createdAt')"
</template> min-width="120"
:show-overflow-tooltip="true"
<script lang="ts" setup> />
import { reactive, ref, watch } from 'vue'
import { t } from '@/lang' <el-table-column
import { useDictionary } from '@/app/api/dict' prop="updated_at"
import { getPhysicalTestList, deletePhysicalTest, getWithCustomerResourcesList, getWithStudentList, getWithPersonnelList } from '@/app/api/physical_test' :label="t('updatedAt')"
import { img } from '@/utils/common' min-width="120"
import { ElMessageBox,FormInstance } from 'element-plus' :show-overflow-tooltip="true"
import Edit from '@/app/views/physical_test/components/physical-test-edit.vue' />
import { useRouter } from 'vue-router'
import { useRoute } from 'vue-router' <el-table-column
const route = useRoute() :label="t('operation')"
const pageName = route.meta.title; fixed="right"
let showDialog = ref(false) min-width="120"
>
<template #default="{ row }">
<el-button type="primary" link @click="editEvent(row)">{{
let physicalTestTable = reactive({ t('edit')
page: 1, }}</el-button>
limit: 10, <!-- <el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button> -->
total: 0, </template>
loading: true, </el-table-column>
data: [], </el-table>
searchParam:{ <div class="mt-[16px] flex justify-end">
"resource_id":"", <el-pagination
"student_id":"", v-model:current-page="physicalTestTable.page"
"height":"" v-model:page-size="physicalTestTable.limit"
} layout="total, sizes, prev, pager, next, jumper"
}) :total="physicalTestTable.total"
@size-change="loadPhysicalTestList()"
const searchFormRef = ref<FormInstance>() @current-change="loadPhysicalTestList"
/>
// </div>
const selectData = ref<any[]>([]) </div>
// <edit ref="editPhysicalTestDialog" @complete="loadPhysicalTestList" />
</el-card>
</div>
/** </el-dialog>
* 获取体测列表 </template>
*/
const loadPhysicalTestList = (page: number = 1) => { <script lang="ts" setup>
physicalTestTable.loading = true import { reactive, ref, watch } from 'vue'
physicalTestTable.page = page import { t } from '@/lang'
import { useDictionary } from '@/app/api/dict'
getPhysicalTestList({ import {
page: physicalTestTable.page, getPhysicalTestList,
limit: physicalTestTable.limit, deletePhysicalTest,
...physicalTestTable.searchParam getWithCustomerResourcesList,
}).then(res => { getWithStudentList,
physicalTestTable.loading = false getWithPersonnelList,
physicalTestTable.data = res.data.data } from '@/app/api/physical_test'
physicalTestTable.total = res.data.total import { img } from '@/utils/common'
}).catch(() => { import { ElMessageBox, FormInstance } from 'element-plus'
physicalTestTable.loading = false import Edit from '@/app/views/physical_test/components/physical-test-edit.vue'
}) import { useRouter } from 'vue-router'
} import { useRoute } from 'vue-router'
const route = useRoute()
const pageName = route.meta.title
const router = useRouter() let showDialog = ref(false)
const editPhysicalTestDialog: Record<string, any> | null = ref(null) let physicalTestTable = reactive({
page: 1,
/** limit: 10,
* 添加体测 total: 0,
*/ loading: true,
const addEvent = () => { data: [],
editPhysicalTestDialog.value.setFormData({'resource_id':physicalTestTable.searchParam.resource_id}) searchParam: {
editPhysicalTestDialog.value.showDialog = true resource_id: '',
} student_id: '',
height: '',
},
/** })
* 编辑体测
* @param data const searchFormRef = ref<FormInstance>()
*/
const editEvent = (data: any) => { //
// router.push('/physical_test/physical_test_edit?id='+data.id) const selectData = ref<any[]>([])
editPhysicalTestDialog.value.setFormData(data)
editPhysicalTestDialog.value.showDialog = true //
}
/**
/** * 获取体测列表
* 删除体测 */
*/ const loadPhysicalTestList = (page: number = 1) => {
const deleteEvent = (id: number) => { physicalTestTable.loading = true
ElMessageBox.confirm(t('physicalTestDeleteTips'), t('warning'), physicalTestTable.page = page
{
confirmButtonText: t('confirm'), getPhysicalTestList({
cancelButtonText: t('cancel'), page: physicalTestTable.page,
type: 'warning', limit: physicalTestTable.limit,
} ...physicalTestTable.searchParam,
).then(() => { })
deletePhysicalTest(id).then(() => { .then((res) => {
loadPhysicalTestList() physicalTestTable.loading = false
}).catch(() => { physicalTestTable.data = res.data.data
}) physicalTestTable.total = res.data.total
}) })
} .catch(() => {
physicalTestTable.loading = false
})
const resourceIdList = ref([]) }
const setResourceIdList = async () => {
resourceIdList.value = await (await getWithCustomerResourcesList({})).data const router = useRouter()
}
setResourceIdList() const editPhysicalTestDialog: Record<string, any> | null = ref(null)
const studentIdList = ref([])
const setStudentIdList = async () => { /**
studentIdList.value = await (await getWithStudentList({})).data * 添加体测
} */
setStudentIdList() const addEvent = () => {
const coachIdList = ref([]) editPhysicalTestDialog.value.setFormData({
const setCoachIdList = async () => { resource_id: physicalTestTable.searchParam.resource_id,
coachIdList.value = await (await getWithPersonnelList({})).data })
} editPhysicalTestDialog.value.showDialog = true
setCoachIdList() }
const resetForm = (formEl: FormInstance | undefined) => { /**
if (!formEl) return * 编辑体测
formEl.resetFields() * @param data
loadPhysicalTestList() */
} const editEvent = (data: any) => {
// router.push('/physical_test/physical_test_edit?id='+data.id)
editPhysicalTestDialog.value.setFormData(data)
const setFormData = async (row: any = null) => { editPhysicalTestDialog.value.showDialog = true
// Object.assign(formData, initialFormData) }
physicalTestTable.searchParam.resource_id = row.resource_id
/**
console.log(physicalTestTable.searchParam.resource_id); * 删除体测
*/
loadPhysicalTestList() const deleteEvent = (id: number) => {
} ElMessageBox.confirm(t('physicalTestDeleteTips'), t('warning'), {
defineExpose({ confirmButtonText: t('confirm'),
showDialog, cancelButtonText: t('cancel'),
setFormData type: 'warning',
}) }).then(() => {
</script> deletePhysicalTest(id)
.then(() => {
<style lang="scss" scoped> loadPhysicalTestList()
/* 多行超出隐藏 */ })
.multi-hidden { .catch(() => {})
word-break: break-all; })
text-overflow: ellipsis; }
overflow: hidden;
display: -webkit-box; const resourceIdList = ref([])
-webkit-line-clamp: 2; const setResourceIdList = async () => {
-webkit-box-orient: vertical; resourceIdList.value = await (await getWithCustomerResourcesList({})).data
} }
</style> setResourceIdList()
const studentIdList = ref([])
const setStudentIdList = async () => {
studentIdList.value = await (await getWithStudentList({})).data
}
setStudentIdList()
const coachIdList = ref([])
const setCoachIdList = async () => {
coachIdList.value = await (await getWithPersonnelList({})).data
}
setCoachIdList()
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadPhysicalTestList()
}
const setFormData = async (row: any = null) => {
// Object.assign(formData, initialFormData)
physicalTestTable.searchParam.resource_id = row.resource_id
console.log(physicalTestTable.searchParam.resource_id)
loadPhysicalTestList()
}
defineExpose({
showDialog,
setFormData,
})
</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>

25
admin/src/app/views/timetables/timetables.vue

@ -26,7 +26,9 @@
value-format="YYYY-MM-DD" value-format="YYYY-MM-DD"
@change="handleDateRangeChange" @change="handleDateRangeChange"
/> />
<el-button type="primary" class="ml-2" @click="fetchData">查询</el-button> <el-button type="primary" class="ml-2" @click="fetchData"
>查询</el-button
>
</div> </div>
<el-button @click="addSchedule">添加课程</el-button> <el-button @click="addSchedule">添加课程</el-button>
</div> </div>
@ -66,7 +68,9 @@
> >
<template #default="{ row }"> <template #default="{ row }">
<div v-if="row.course && row.course.classroom == classroom"> <div v-if="row.course && row.course.classroom == classroom">
<div class="teacher-name">{{ getTeacherName(row.course.teacher) }}</div> <div class="teacher-name">
{{ getTeacherName(row.course.teacher) }}
</div>
<div class="student-list"> <div class="student-list">
<el-tag <el-tag
v-for="student in row.course.students" v-for="student in row.course.students"
@ -88,8 +92,15 @@
<!-- 详情弹窗 --> <!-- 详情弹窗 -->
<el-dialog v-model="dialogVisible" title="课程详情"> <el-dialog v-model="dialogVisible" title="课程详情">
<p><strong>教师:</strong> {{ getTeacherName(selectedCourse?.teacher) }}</p> <p>
<p><strong>学员:</strong> {{ selectedCourse?.students.map(id => getStudentName(id)).join(', ') }}</p> <strong>教师:</strong> {{ getTeacherName(selectedCourse?.teacher) }}
</p>
<p>
<strong>学员:</strong>
{{
selectedCourse?.students.map((id) => getStudentName(id)).join(', ')
}}
</p>
</el-dialog> </el-dialog>
</div> </div>
</el-card> </el-card>
@ -107,7 +118,7 @@ const selectedCampus = ref('')
// //
const dateRange = ref([ const dateRange = ref([
getMonday(new Date()).toISOString().split('T')[0], getMonday(new Date()).toISOString().split('T')[0],
getSunday(new Date()).toISOString().split('T')[0] getSunday(new Date()).toISOString().split('T')[0],
]) ])
// //
@ -167,11 +178,11 @@ const fetchData = async () => {
params.start_date = dateRange.value[0] params.start_date = dateRange.value[0]
params.end_date = dateRange.value[1] params.end_date = dateRange.value[1]
} }
if (selectedCampus.value) { if (selectedCampus.value) {
params.campus_id = selectedCampus.value params.campus_id = selectedCampus.value
} }
const response = await getTimetables(params) const response = await getTimetables(params)
if (response.data) { if (response.data) {
days.value = response.data days.value = response.data

416
admin/src/app/views/xsyj/xsyj.vue

@ -1,212 +1,228 @@
<template> <template>
<div class="main-container"> <div class="main-container">
<el-card class="box-card !border-none" shadow="never" v-loading="loading"> <el-card class="box-card !border-none" shadow="never" v-loading="loading">
<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="addStage"> 新增阶段 </el-button>
<el-button type="primary" @click="addStage"> </div>
新增阶段 </el-card>
</el-button>
</div> <el-card class="box-card !border-none" shadow="never">
</el-card> <div
class="flex items-center justify-between p-[10px] table-item-border bg"
>
<span class="text-base w-[230px]">阶段名称</span>
<el-card class="box-card !border-none" shadow="never" > <span class="text-base w-[110px] text-center">底薪</span>
</div>
<div class="flex items-center justify-between p-[10px] table-item-border bg">
<span class="text-base w-[230px]">阶段名称</span> <el-collapse v-model="activeNames" accordion>
<span class="text-base w-[110px] text-center">底薪</span> <el-collapse-item
</div> v-for="(stage, index) in stages"
:key="stage.id"
<el-collapse v-model="activeNames" accordion > :name="stage.id"
<el-collapse-item v-for="(stage, index) in stages" :key="stage.id" :name="stage.id"> >
<template #title>
<template #title> <div class="collapse-title">
<div class="collapse-title"> <span class="title-name">{{ stage.name }}</span>
<span class="title-name">{{ stage.name }}</span> <span class="arrow">{{ stage.price }} </span>
<span class="arrow">{{ stage.price }} </span> <!-- <span class="arrow">&gt;</span> -->
<!-- <span class="arrow">&gt;</span> --> </div>
</div> </template>
</template>
<el-form label-width="100px" style="margin-bottom: 10px">
<el-form label-width="100px" style="margin-bottom: 10px"> <el-form-item label="阶段名称">
<el-form-item label="阶段名称"> <el-input v-model="stage.name" placeholder="请输入阶段名称" />
<el-input v-model="stage.name" placeholder="请输入阶段名称" /> </el-form-item>
</el-form-item> </el-form>
</el-form>
<el-form label-width="100px" style="margin-bottom: 10px">
<el-form label-width="100px" style="margin-bottom: 10px"> <el-form-item label="阶段底薪">
<el-form-item label="阶段底薪"> <el-input v-model="stage.price" placeholder="请输入阶段底薪" />
<el-input v-model="stage.price" placeholder="请输入阶段底薪" /> </el-form-item>
</el-form-item> </el-form>
</el-form>
<el-button type="success" size="small" @click="addRule(stage)"
>新增规则</el-button
>
<el-button type="success" size="small" @click="addRule(stage)">新增规则</el-button>
<el-table :data="stage.rules" border style="margin-top: 10px">
<el-table :data="stage.rules" border style="margin-top: 10px"> <el-table-column prop="renewal_standard_min" label="续费上限">
<el-table-column prop="renewal_standard_min" label="续费上限"> <template #default="{ row }">
<template #default="{ row }"> <el-input
<el-input v-model="row.renewal_standard_min" placeholder="请输入续费上限" /> v-model="row.renewal_standard_min"
</template> placeholder="请输入续费上限"
</el-table-column> />
</template>
<el-table-column prop="renewal_standard_max" label="续费下限"> </el-table-column>
<template #default="{ row }">
<el-input v-model="row.renewal_standard_max" placeholder="请输入续费下限" /> <el-table-column prop="renewal_standard_max" label="续费下限">
</template> <template #default="{ row }">
</el-table-column> <el-input
v-model="row.renewal_standard_max"
<el-table-column prop="renewal_commission" label="续费提成"> placeholder="请输入续费下限"
<template #default="{ row }"> />
<el-input v-model="row.renewal_commission" placeholder="%" /> </template>
</template> </el-table-column>
</el-table-column>
<el-table-column prop="renewal_commission" label="续费提成">
<el-table-column prop="new_count_min" label="新单成交数上限"> <template #default="{ row }">
<template #default="{ row }"> <el-input v-model="row.renewal_commission" placeholder="%" />
<el-input v-model="row.new_count_min" /> </template>
</template> </el-table-column>
</el-table-column>
<el-table-column prop="new_count_min" label="新单成交数上限">
<el-table-column prop="new_count_max" label="新单成交数下限"> <template #default="{ row }">
<template #default="{ row }"> <el-input v-model="row.new_count_min" />
<el-input v-model="row.new_count_max" /> </template>
</template> </el-table-column>
</el-table-column>
<el-table-column prop="new_count_max" label="新单成交数下限">
<el-table-column prop="new_move_5" label="新招(5+1)x3"> <template #default="{ row }">
<template #default="{ row }"> <el-input v-model="row.new_count_max" />
<el-input v-model="row.new_move_5" /> </template>
</template> </el-table-column>
</el-table-column>
<el-table-column prop="new_move_7" label="新招(7+1)x3"> <el-table-column prop="new_move_5" label="新招(5+1)x3">
<template #default="{ row }"> <template #default="{ row }">
<el-input v-model="row.new_move_7" /> <el-input v-model="row.new_move_5" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" width="100"> <el-table-column prop="new_move_7" label="新招(7+1)x3">
<template #default="{ $index }"> <template #default="{ row }">
<el-button type="danger" size="small" @click="removeRule(stage, $index)">删除</el-button> <el-input v-model="row.new_move_7" />
</template> </template>
</el-table-column> </el-table-column>
</el-table> <el-table-column label="操作" width="100">
<template #default="{ $index }">
<el-button type="danger" size="small" style="margin-top: 10px" <el-button
@click="removeStage(index)">删除该阶段</el-button> type="danger"
</el-collapse-item> size="small"
</el-collapse> @click="removeRule(stage, $index)"
>删除</el-button
<div style="text-align: right; margin-top: 20px;"> >
<el-button type="primary" @click="onSave">提交保存</el-button> </template>
</div> </el-table-column>
</el-card> </el-table>
<el-button
type="danger"
size="small"
style="margin-top: 10px"
@click="removeStage(index)"
>删除该阶段</el-button
>
</el-collapse-item>
</el-collapse>
<div style="text-align: right; margin-top: 20px">
<el-button type="primary" @click="onSave">提交保存</el-button>
</div>
</el-card>
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { xsyjConfig, getXsyjConfig } from '@/app/api/sys' import { xsyjConfig, getXsyjConfig } from '@/app/api/sys'
import { reactive, ref } from 'vue' import { reactive, ref } from 'vue'
import {ElMessage} from 'element-plus' import { ElMessage } from 'element-plus'
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
const loading = ref(true) const loading = ref(true)
const stages = ref([]) const stages = ref([])
const activeNames = ref(null) const activeNames = ref(null)
function addStage() { function addStage() {
const newStage = { const newStage = {
name: '默认阶段', name: '默认阶段',
price:0, price: 0,
rules: [{ rules: [
renewal_standard_min: '', {
renewal_standard_max: '', renewal_standard_min: '',
renewal_commission: '', renewal_standard_max: '',
new_count_min: '', renewal_commission: '',
new_count_max: '', new_count_min: '',
new_move_5: '', new_count_max: '',
new_move_7: '' new_move_5: '',
}] new_move_7: '',
} },
stages.value.push(newStage) ],
activeNames.value = newStage.name }
} stages.value.push(newStage)
activeNames.value = newStage.name
function removeStage(index) { }
stages.value.splice(index, 1)
} function removeStage(index) {
stages.value.splice(index, 1)
function addRule(stage) { }
stage.rules.push({
renewal_standard_min: '', function addRule(stage) {
renewal_standard_max: '', stage.rules.push({
renewal_commission: '', renewal_standard_min: '',
new_count_min: '', renewal_standard_max: '',
new_count_max: '', renewal_commission: '',
new_move_5: '', new_count_min: '',
new_move_7: '' new_count_max: '',
}) new_move_5: '',
} new_move_7: '',
})
function removeRule(stage, ruleIndex) { }
if (stage.rules.length === 1) {
ElMessage.warning('至少保留一条规则') function removeRule(stage, ruleIndex) {
return if (stage.rules.length === 1) {
} ElMessage.warning('至少保留一条规则')
stage.rules.splice(ruleIndex, 1) return
} }
stage.rules.splice(ruleIndex, 1)
const setFormData = async () => { }
const data = await (await getXsyjConfig()).data
stages.value = data const setFormData = async () => {
loading.value = false const data = await (await getXsyjConfig()).data
} stages.value = data
loading.value = false
setFormData(); }
const onSave = async () => { setFormData()
xsyjConfig(stages.value)
.then(() => { const onSave = async () => {
loading.value = true xsyjConfig(stages.value)
setFormData() .then(() => {
}) loading.value = true
.catch(() => { setFormData()
loading.value = false })
}) .catch(() => {
} loading.value = false
})
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.collapse-title { .collapse-title {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
width: 100%; width: 100%;
font-size: 14px; font-size: 14px;
font-weight: 500; font-weight: 500;
padding-right: 10px; padding-right: 10px;
color: #333; color: #333;
padding: 10px; padding: 10px;
} }
.title-name { .title-name {
width: 230px; width: 230px;
} }
.title-salary { .title-salary {
width: 110px; width: 110px;
text-align: center; text-align: center;
color: #7438D5; color: #7438d5;
} }
.arrow {
margin-left: auto;
color: #999;
font-size: 14px;
}
.arrow {
margin-left: auto;
color: #999;
font-size: 14px;
}
</style> </style>

Loading…
Cancel
Save