Browse Source

处理冲突

master
王泽彦 10 months ago
parent
commit
ef77b7c436
  1. 31
      admin/src/app/api/market_performance.ts
  2. 35
      admin/src/app/api/person_course_schedule.ts
  3. 2
      admin/src/app/api/service.ts
  4. 7
      admin/src/app/api/sys.ts
  5. 26
      admin/src/app/lang/zh-cn/market_performance.market_performance.json
  6. 34
      admin/src/app/lang/zh-cn/person_course_schedule.person_course_schedule.json
  7. 11
      admin/src/app/views/classroom/classroom.vue
  8. 3
      admin/src/app/views/customer_resources/components/fp.vue
  9. 420
      admin/src/app/views/market_performance/components/market-performance-edit.vue
  10. 434
      admin/src/app/views/market_performance/market_performance.vue
  11. 436
      admin/src/app/views/person_course_schedule/components/person-course-schedule-edit.vue
  12. 469
      admin/src/app/views/person_course_schedule/person_course_schedule.vue
  13. 739
      admin/src/app/views/physical_test/components/physical-test-edit.vue
  14. 52
      admin/src/app/views/scsjtj/components/BarChart.vue
  15. 17
      admin/src/app/views/scsjtj/components/Card.vue
  16. 69
      admin/src/app/views/scsjtj/components/PieChart.vue
  17. 127
      admin/src/app/views/scsjtj/scsjtj.vue
  18. 28
      admin/src/app/views/service/components/service-edit.vue
  19. 25
      admin/src/app/views/service/service.vue
  20. 1
      admin/src/app/views/student/student.vue
  21. 2
      admin/src/app/views/venue/venue.vue
  22. 5
      niucloud/app/adminapi/controller/campus/Campus.php
  23. 4
      niucloud/app/adminapi/controller/classroom/Classroom.php
  24. 1
      niucloud/app/adminapi/controller/customer_resources/CustomerResources.php
  25. 6
      niucloud/app/adminapi/controller/market_performance/MarketPerformance.php
  26. 39
      niucloud/app/adminapi/controller/person_course_schedule/PersonCourseSchedule.php
  27. 1
      niucloud/app/adminapi/controller/student/Student.php
  28. 15
      niucloud/app/adminapi/controller/sys/System.php
  29. 1
      niucloud/app/adminapi/route/market_performance.php
  30. 8
      niucloud/app/adminapi/route/person_course_schedule.php
  31. 1
      niucloud/app/adminapi/route/service.php
  32. 3
      niucloud/app/adminapi/route/sys.php
  33. 7
      niucloud/app/api/controller/apiController/CustomerResources.php
  34. 8
      niucloud/app/api/controller/upload/Upload.php
  35. 2
      niucloud/app/api/route/route.php
  36. 4
      niucloud/app/model/chat_friends/ChatFriends.php
  37. 18
      niucloud/app/model/market_performance/MarketPerformance.php
  38. 82
      niucloud/app/model/person_course_schedule/PersonCourseSchedule.php
  39. 8
      niucloud/app/service/admin/campus/CampusService.php
  40. 8
      niucloud/app/service/admin/classroom/ClassroomService.php
  41. 15
      niucloud/app/service/admin/customer_resources/CustomerResourcesService.php
  42. 4
      niucloud/app/service/admin/market_performance/MarketPerformanceService.php
  43. 51
      niucloud/app/service/admin/person_course_schedule/PersonCourseScheduleService.php
  44. 2
      niucloud/app/service/admin/student/StudentService.php
  45. 57
      niucloud/app/service/admin/sys/SystemService.php
  46. 7
      niucloud/app/service/api/apiService/ChatService.php
  47. 41
      niucloud/app/service/api/apiService/CustomerResourcesService.php
  48. 6
      niucloud/app/service/api/apiService/ResourceSharingService.php
  49. 4
      niucloud/app/service/api/upload/UploadService.php
  50. 18
      niucloud/app/validate/person_course_schedule/PersonCourseSchedule.php

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

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

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

@ -1,5 +1,7 @@
import request from '@/utils/request' import request from '@/utils/request'
// USER_CODE_BEGIN -- person_course_schedule // USER_CODE_BEGIN -- person_course_schedule
/** /**
* *
@ -7,9 +9,7 @@ import request from '@/utils/request'
* @returns * @returns
*/ */
export function getPersonCourseScheduleList(params: Record<string, any>) { export function getPersonCourseScheduleList(params: Record<string, any>) {
return request.get(`person_course_schedule/person_course_schedule`, { return request.get(`person_course_schedule/person_course_schedule`, {params})
params,
})
} }
/** /**
@ -18,7 +18,7 @@ export function getPersonCourseScheduleList(params: Record<string, any>) {
* @returns * @returns
*/ */
export function getPersonCourseScheduleInfo(id: number) { export function getPersonCourseScheduleInfo(id: number) {
return request.get(`person_course_schedule/person_course_schedule/${id}`) return request.get(`person_course_schedule/person_course_schedule/${id}`);
} }
/** /**
@ -27,10 +27,7 @@ export function getPersonCourseScheduleInfo(id: number) {
* @returns * @returns
*/ */
export function addPersonCourseSchedule(params: Record<string, any>) { export function addPersonCourseSchedule(params: Record<string, any>) {
return request.post('person_course_schedule/person_course_schedule', params, { return request.post('person_course_schedule/person_course_schedule', params, { showErrorMessage: true, showSuccessMessage: true })
showErrorMessage: true,
showSuccessMessage: true,
})
} }
/** /**
@ -40,11 +37,7 @@ export function addPersonCourseSchedule(params: Record<string, any>) {
* @returns * @returns
*/ */
export function editPersonCourseSchedule(params: Record<string, any>) { export function editPersonCourseSchedule(params: Record<string, any>) {
return request.put( return request.put(`person_course_schedule/person_course_schedule/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
`person_course_schedule/person_course_schedule/${params.id}`,
params,
{ showErrorMessage: true, showSuccessMessage: true }
)
} }
/** /**
@ -53,14 +46,16 @@ export function editPersonCourseSchedule(params: Record<string, any>) {
* @returns * @returns
*/ */
export function deletePersonCourseSchedule(id: number) { export function deletePersonCourseSchedule(id: number) {
return request.delete(`person_course_schedule/person_course_schedule/${id}`, { return request.delete(`person_course_schedule/person_course_schedule/${id}`, { showErrorMessage: true, showSuccessMessage: true })
showErrorMessage: true, }
showSuccessMessage: true,
})
export function xkPersonCourseSchedule(id: number) {
return request.delete(`person_course_schedule/xk/${id}`, { showErrorMessage: true, showSuccessMessage: true })
} }
/**获取试课人员列表 */
export function getTryCoursePerson(id: number) { export function getWithCustomerResourcesList(params: Record<string,any>){
return request.get(`person_course_schedule/get_try_course_person/${id}`) return request.get('person_course_schedule/customer_resources_all', {params})
} }
// USER_CODE_END -- person_course_schedule // USER_CODE_END -- person_course_schedule

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

@ -2,6 +2,8 @@ import request from '@/utils/request'
// USER_CODE_BEGIN -- service // USER_CODE_BEGIN -- service
/** /**
* *

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

@ -790,4 +790,9 @@ export function getHome(params: Record<string, any>) {
export function setDocument(params: Record<string, any>) { export function setDocument(params: Record<string, any>) {
return request.post('sys/document/document', params) return request.post('sys/document/document', params)
} }
export function getScsjtj(params: Record<string, any>) {
return request.post('sys/scsjtj', params)
}

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

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

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

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

11
admin/src/app/views/classroom/classroom.vue

@ -221,6 +221,8 @@
<el-button type="primary" link @click="deleteEvent(row.id)" <el-button type="primary" link @click="deleteEvent(row.id)"
>{{ t('delete') }} >{{ t('delete') }}
</el-button> </el-button>
<el-button type="primary" link @click="classEvent(row.id)">学员</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -253,8 +255,9 @@ import {
} from '@/app/api/classroom' } from '@/app/api/classroom'
import { ElMessageBox, FormInstance } from 'element-plus' import { ElMessageBox, FormInstance } from 'element-plus'
import Edit from '@/app/views/classroom/components/classroom-edit.vue' import Edit from '@/app/views/classroom/components/classroom-edit.vue'
import { useRoute } from 'vue-router'
import { useRouter, useRoute } from 'vue-router'
const router = useRouter()
const route = useRoute() const route = useRoute()
const pageName = route.meta.title const pageName = route.meta.title
@ -275,6 +278,12 @@ let classroomTable = reactive({
}, },
}) })
const classEvent = (class_id : number) => {
console.log(class_id);
router.push({ path: '/student/student', query: { class_id: class_id } })
}
const searchFormRef = ref<FormInstance>() const searchFormRef = ref<FormInstance>()
// //

3
admin/src/app/views/customer_resources/components/fp.vue

@ -20,6 +20,7 @@
v-model="formData.shared_by" v-model="formData.shared_by"
clearable clearable
placeholder="请选择分配人员" placeholder="请选择分配人员"
filterable
> >
<el-option label="请选择" value=""></el-option> <el-option label="请选择" value=""></el-option>
<el-option <el-option
@ -99,7 +100,7 @@ const confirm = async (formEl: FormInstance | undefined) => {
const consultantList = ref([] as any[]) const consultantList = ref([] as any[])
const setConsultantList = async () => { const setConsultantList = async () => {
consultantList.value = await (await getWithPersonnelList({ role_id: 2 })).data consultantList.value = await (await getWithPersonnelList({ role_id: 2 ,dept_id:2})).data
} }
setConsultantList() setConsultantList()

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

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

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

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

436
admin/src/app/views/person_course_schedule/components/person-course-schedule-edit.vue

@ -1,227 +1,209 @@
<template> <template>
<el-dialog <el-dialog v-model="showDialog" :title="formData.id ? t('updatePersonCourseSchedule') : t('addPersonCourseSchedule')" width="50%" class="diy-dialog-wrap" :destroy-on-close="true">
v-model="showDialog" <el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
:title=" <el-form-item :label="t('personId')" prop="person_id">
formData.id <el-select class="input-width" v-model="formData.person_id" clearable :placeholder="t('personIdPlaceholder')">
? t('updatePersonCourseSchedule') <el-option label="请选择" value=""></el-option>
: t('addPersonCourseSchedule') <el-option
" v-for="(item, index) in personIdList"
width="50%" :key="index"
class="diy-dialog-wrap" :label="item['name']"
:destroy-on-close="true" :value="item['id']"
> />
<el-form </el-select>
:model="formData" </el-form-item>
label-width="120px"
ref="formRef" <el-form-item :label="t('personType')" prop="person_type">
:rules="formRules" <el-select class="input-width" v-model="formData.person_type" clearable :placeholder="t('personTypePlaceholder')">
class="page-form" <el-option label="请选择" value=""></el-option>
v-loading="loading" <el-option
> v-for="(item, index) in person_typeList"
<el-form-item :label="t('personId')" prop="person_id"> :key="index"
<el-input :label="item.name"
v-model="formData.person_id" :value="item.value"
clearable />
:placeholder="t('personIdPlaceholder')" </el-select>
class="input-width" </el-form-item>
/>
</el-form-item> <el-form-item :label="t('scheduleId')" prop="schedule_id">
<el-input v-model="formData.schedule_id" clearable :placeholder="t('scheduleIdPlaceholder')" class="input-width" />
<el-form-item :label="t('personType')" prop="person_type"> </el-form-item>
<el-input
v-model="formData.person_type" <el-form-item :label="t('courseDate')" prop="course_date">
clearable <el-input v-model="formData.course_date" clearable :placeholder="t('courseDatePlaceholder')" class="input-width" />
:placeholder="t('personTypePlaceholder')" </el-form-item>
class="input-width"
/> <el-form-item :label="t('timeSlot')" prop="time_slot">
</el-form-item> <el-input v-model="formData.time_slot" clearable :placeholder="t('timeSlotPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('scheduleId')" prop="schedule_id">
<el-input </el-form>
v-model="formData.schedule_id"
clearable <template #footer>
:placeholder="t('scheduleIdPlaceholder')" <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('courseDate')" prop="course_date"> </span>
<el-input </template>
v-model="formData.course_date" </el-dialog>
clearable </template>
:placeholder="t('courseDatePlaceholder')"
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('timeSlot')" prop="time_slot"> import type { FormInstance } from 'element-plus'
<el-input import { addPersonCourseSchedule, editPersonCourseSchedule, getPersonCourseScheduleInfo, getWithCustomerResourcesList } from '@/app/api/person_course_schedule'
v-model="formData.time_slot"
clearable let showDialog = ref(false)
:placeholder="t('timeSlotPlaceholder')" const loading = ref(false)
class="input-width"
/> /**
</el-form-item> * 表单数据
</el-form> */
const initialFormData = {
<template #footer> id: '',
<span class="dialog-footer"> person_id: '',
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button> person_type: '',
<el-button schedule_id: '',
type="primary" course_date: '',
:loading="loading" time_slot: '',
@click="confirm(formRef)" }
>{{ t('confirm') }}</el-button const formData: Record<string, any> = reactive({ ...initialFormData })
>
</span> const formRef = ref<FormInstance>()
</template>
</el-dialog> //
</template> const formRules = computed(() => {
return {
<script lang="ts" setup> person_id: [
import { ref, reactive, computed, watch } from 'vue' { required: true, message: t('personIdPlaceholder'), trigger: 'blur' },
import { useDictionary } from '@/app/api/dict'
import { t } from '@/lang' ]
import type { FormInstance } from 'element-plus' ,
import { person_type: [
addPersonCourseSchedule, { required: true, message: t('personTypePlaceholder'), trigger: 'blur' },
editPersonCourseSchedule,
getPersonCourseScheduleInfo, ]
} from '@/app/api/person_course_schedule' ,
schedule_id: [
let showDialog = ref(false) { required: true, message: t('scheduleIdPlaceholder'), trigger: 'blur' },
const loading = ref(false)
]
/** ,
* 表单数据 course_date: [
*/ { required: true, message: t('courseDatePlaceholder'), trigger: 'blur' },
const initialFormData = {
id: '', ]
person_id: '', ,
person_type: '', time_slot: [
schedule_id: '', { required: true, message: t('timeSlotPlaceholder'), trigger: 'blur' },
course_date: '',
time_slot: '', ]
} ,
const formData: Record<string, any> = reactive({ ...initialFormData }) }
})
const formRef = ref<FormInstance>()
const emit = defineEmits(['complete'])
//
const formRules = computed(() => { /**
return { * 确认
person_id: [ * @param formEl
{ required: true, message: t('personIdPlaceholder'), trigger: 'blur' }, */
], const confirm = async (formEl: FormInstance | undefined) => {
person_type: [ if (loading.value || !formEl) return
{ required: true, message: t('personTypePlaceholder'), trigger: 'blur' }, let save = formData.id ? editPersonCourseSchedule : addPersonCourseSchedule
],
schedule_id: [ await formEl.validate(async (valid) => {
{ required: true, message: t('scheduleIdPlaceholder'), trigger: 'blur' }, if (valid) {
], loading.value = true
course_date: [
{ required: true, message: t('courseDatePlaceholder'), trigger: 'blur' }, let data = formData
],
time_slot: [ save(data).then(res => {
{ required: true, message: t('timeSlotPlaceholder'), trigger: 'blur' }, loading.value = false
], showDialog.value = false
} emit('complete')
}) }).catch(err => {
loading.value = false
const emit = defineEmits(['complete']) })
}
/** })
* 确认 }
* @param formEl
*/ //
const confirm = async (formEl: FormInstance | undefined) => { let person_typeList = ref([])
if (loading.value || !formEl) return const person_typeDictList = async () => {
let save = formData.id ? editPersonCourseSchedule : addPersonCourseSchedule person_typeList.value = await (await useDictionary('person_type')).data.dictionary
}
await formEl.validate(async (valid) => { person_typeDictList();
if (valid) { watch(() => person_typeList.value, () => { formData.person_type = person_typeList.value[0].value })
loading.value = true
let data = formData const personIdList = ref([] as any[])
const setPersonIdList = async () => {
save(data) personIdList.value = await (await getWithCustomerResourcesList({})).data
.then((res) => { }
loading.value = false setPersonIdList()
showDialog.value = false const setFormData = async (row: any = null) => {
emit('complete') Object.assign(formData, initialFormData)
}) loading.value = true
.catch((err) => { if(row){
loading.value = false const data = await (await getPersonCourseScheduleInfo(row.id)).data
}) if (data) Object.keys(formData).forEach((key: string) => {
} if (data[key] != undefined) formData[key] = data[key]
}) })
} }
loading.value = false
// }
const setFormData = async (row: any = null) => { //
Object.assign(formData, initialFormData) const mobileVerify = (rule: any, value: any, callback: any) => {
loading.value = true if (value && !/^1[3-9]\d{9}$/.test(value)) {
if (row) { callback(new Error(t('generateMobile')))
const data = await (await getPersonCourseScheduleInfo(row.id)).data } else {
if (data) callback()
Object.keys(formData).forEach((key: string) => { }
if (data[key] != undefined) formData[key] = data[key] }
})
} //
loading.value = false const idCardVerify = (rule: any, value: any, callback: any) => {
} if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) {
callback(new Error(t('generateIdCard')))
// } else {
const mobileVerify = (rule: any, value: any, callback: any) => { callback()
if (value && !/^1[3-9]\d{9}$/.test(value)) { }
callback(new Error(t('generateMobile'))) }
} 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 {
const idCardVerify = (rule: any, value: any, callback: any) => { callback()
if ( }
value && }
!/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
value //
) const numberVerify = (rule: any, value: any, callback: any) => {
) { if (!Number.isInteger(value)) {
callback(new Error(t('generateIdCard'))) callback(new Error(t('generateNumber')))
} else { } else {
callback() callback()
} }
} }
// defineExpose({
const emailVerify = (rule: any, value: any, callback: any) => { showDialog,
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) { setFormData
callback(new Error(t('generateEmail'))) })
} else { </script>
callback()
} <style lang="scss" scoped></style>
} <style lang="scss">
.diy-dialog-wrap .el-form-item__label{
// height: auto !important;
const numberVerify = (rule: any, value: any, callback: any) => { }
if (!Number.isInteger(value)) { </style>
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>

469
admin/src/app/views/person_course_schedule/person_course_schedule.vue

@ -1,256 +1,213 @@
<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">
<span class="text-lg">{{ pageName }}</span> <div class="flex justify-between items-center">
<el-button type="primary" @click="addEvent"> <span class="text-lg">{{pageName}}</span>
{{ t('addPersonCourseSchedule') }}
</el-button> </div>
</div>
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-card <el-form :inline="true" :model="personCourseScheduleTable.searchParam" ref="searchFormRef">
class="box-card !border-none my-[10px] table-search-wrap"
shadow="never" <el-form-item label="资源名称" prop="name">
> <el-input v-model="personCourseScheduleTable.searchParam.name"
<el-form placeholder="请输入资源名称" />
:inline="true" </el-form-item>
:model="personCourseScheduleTable.searchParam"
ref="searchFormRef" <el-form-item label="资源手机号" prop="phone_number">
> <el-input v-model="personCourseScheduleTable.searchParam.phone_number"
<el-form-item :label="t('personId')" prop="person_id"> placeholder="请输入资源手机号" />
<el-input </el-form-item>
v-model="personCourseScheduleTable.searchParam.person_id"
:placeholder="t('personIdPlaceholder')" <el-form-item label="校区" prop="campus_name">
/> <el-input v-model="personCourseScheduleTable.searchParam.campus_name"
</el-form-item> placeholder="请输入校区" />
<el-form-item :label="t('personType')" prop="person_type"> </el-form-item>
<el-input
v-model="personCourseScheduleTable.searchParam.person_type"
:placeholder="t('personTypePlaceholder')"
/> <el-form-item>
</el-form-item> <el-button type="primary" @click="loadPersonCourseScheduleList()">{{ t('search') }}</el-button>
<el-form-item :label="t('scheduleId')" prop="schedule_id"> <el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
<el-input </el-form-item>
v-model="personCourseScheduleTable.searchParam.schedule_id" </el-form>
:placeholder="t('scheduleIdPlaceholder')" </el-card>
/>
</el-form-item> <div class="mt-[10px]">
<el-form-item :label="t('courseDate')" prop="course_date"> <el-table :data="personCourseScheduleTable.data" size="large" v-loading="personCourseScheduleTable.loading">
<el-input <template #empty>
v-model="personCourseScheduleTable.searchParam.course_date" <span>{{ !personCourseScheduleTable.loading ? t('emptyData') : '' }}</span>
:placeholder="t('courseDatePlaceholder')" </template>
/> <el-table-column prop="name" label="资源名称" min-width="120" :show-overflow-tooltip="true"/>
</el-form-item>
<el-form-item :label="t('timeSlot')" prop="time_slot"> <el-table-column label="人员类型" min-width="180" align="center" :show-overflow-tooltip="true">
<el-input <template #default="{ row }">
v-model="personCourseScheduleTable.searchParam.time_slot" <div v-for="(item, index) in person_typeList">
:placeholder="t('timeSlotPlaceholder')" <div v-if="item.value == row.person_type">{{ item.name }}</div>
/> </div>
</el-form-item> </template>
</el-table-column>
<el-form-item>
<el-button type="primary" @click="loadPersonCourseScheduleList()">{{ <el-table-column prop="course_type" label="课程类型" min-width="120" :show-overflow-tooltip="true"/>
t('search')
}}</el-button> <el-table-column prop="course_date" :label="t('courseDate')" min-width="120" :show-overflow-tooltip="true"/>
<el-button @click="resetForm(searchFormRef)">{{
t('reset') <el-table-column prop="time_slot" :label="t('timeSlot')" 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="deleteEvent(row.id)">请假</el-button>
<el-button type="primary" link @click="xkEvent(row.id)">消课</el-button>
<div class="mt-[10px]"> </template>
<el-table </el-table-column>
:data="personCourseScheduleTable.data"
size="large" </el-table>
v-loading="personCourseScheduleTable.loading" <div class="mt-[16px] flex justify-end">
> <el-pagination v-model:current-page="personCourseScheduleTable.page" v-model:page-size="personCourseScheduleTable.limit"
<template #empty> layout="total, sizes, prev, pager, next, jumper" :total="personCourseScheduleTable.total"
<span>{{ @size-change="loadPersonCourseScheduleList()" @current-change="loadPersonCourseScheduleList" />
!personCourseScheduleTable.loading ? t('emptyData') : '' </div>
}}</span> </div>
</template>
<el-table-column <edit ref="editPersonCourseScheduleDialog" @complete="loadPersonCourseScheduleList" />
prop="person_id" </el-card>
:label="t('personId')" </div>
min-width="120" </template>
:show-overflow-tooltip="true"
/> <script lang="ts" setup>
import { reactive, ref, watch } from 'vue'
<el-table-column import { t } from '@/lang'
prop="person_type" import { useDictionary } from '@/app/api/dict'
:label="t('personType')" import { getPersonCourseScheduleList, deletePersonCourseSchedule, getWithCustomerResourcesList,xkPersonCourseSchedule} from '@/app/api/person_course_schedule'
min-width="120" import { img } from '@/utils/common'
:show-overflow-tooltip="true" import { ElMessageBox,FormInstance } from 'element-plus'
/> import Edit from '@/app/views/person_course_schedule/components/person-course-schedule-edit.vue'
import { useRoute } from 'vue-router'
<el-table-column const route = useRoute()
prop="schedule_id" const pageName = route.meta.title;
:label="t('scheduleId')"
min-width="120" let personCourseScheduleTable = reactive({
:show-overflow-tooltip="true" page: 1,
/> limit: 10,
total: 0,
<el-table-column loading: true,
prop="course_date" data: [],
:label="t('courseDate')" searchParam:{
min-width="120" "name":"",
:show-overflow-tooltip="true" "phone_number":"",
/> "campus_name":""
}
<el-table-column })
prop="time_slot"
:label="t('timeSlot')" const searchFormRef = ref<FormInstance>()
min-width="120"
:show-overflow-tooltip="true" //
/> const selectData = ref<any[]>([])
<el-table-column //
:label="t('operation')" const person_typeList = ref([] as any[])
fixed="right" const person_typeDictList = async () => {
min-width="120" person_typeList.value = await (await useDictionary('person_type')).data.dictionary
> }
<template #default="{ row }"> person_typeDictList();
<el-button type="primary" link @click="editEvent(row)">{{
t('edit') /**
}}</el-button> * 获取人员与课程安排关系列表
<el-button type="primary" link @click="deleteEvent(row.id)">{{ */
t('delete') const loadPersonCourseScheduleList = (page: number = 1) => {
}}</el-button> personCourseScheduleTable.loading = true
</template> personCourseScheduleTable.page = page
</el-table-column>
</el-table> getPersonCourseScheduleList({
<div class="mt-[16px] flex justify-end"> page: personCourseScheduleTable.page,
<el-pagination limit: personCourseScheduleTable.limit,
v-model:current-page="personCourseScheduleTable.page" ...personCourseScheduleTable.searchParam
v-model:page-size="personCourseScheduleTable.limit" }).then(res => {
layout="total, sizes, prev, pager, next, jumper" personCourseScheduleTable.loading = false
:total="personCourseScheduleTable.total" personCourseScheduleTable.data = res.data.data
@size-change="loadPersonCourseScheduleList()" personCourseScheduleTable.total = res.data.total
@current-change="loadPersonCourseScheduleList" }).catch(() => {
/> personCourseScheduleTable.loading = false
</div> })
</div> }
loadPersonCourseScheduleList()
<edit
ref="editPersonCourseScheduleDialog" const editPersonCourseScheduleDialog: Record<string, any> | null = ref(null)
@complete="loadPersonCourseScheduleList"
/> /**
</el-card> * 添加人员与课程安排关系
</div> */
</template> const addEvent = () => {
editPersonCourseScheduleDialog.value.setFormData()
<script lang="ts" setup> editPersonCourseScheduleDialog.value.showDialog = true
import { reactive, ref, watch } from 'vue' }
import { t } from '@/lang'
import { useDictionary } from '@/app/api/dict' /**
import { * 编辑人员与课程安排关系
getPersonCourseScheduleList, * @param data
deletePersonCourseSchedule, */
} from '@/app/api/person_course_schedule' const editEvent = (data: any) => {
import { img } from '@/utils/common' editPersonCourseScheduleDialog.value.setFormData(data)
import { ElMessageBox, FormInstance } from 'element-plus' editPersonCourseScheduleDialog.value.showDialog = true
import Edit from '@/app/views/person_course_schedule/components/person-course-schedule-edit.vue' }
import { useRoute } from 'vue-router'
const route = useRoute() /**
const pageName = route.meta.title * 删除人员与课程安排关系
*/
let personCourseScheduleTable = reactive({ const deleteEvent = (id: number) => {
page: 1, ElMessageBox.confirm("确定请假吗", t('warning'),
limit: 10, {
total: 0, confirmButtonText: t('confirm'),
loading: true, cancelButtonText: t('cancel'),
data: [], type: 'warning',
searchParam: { }
person_id: '', ).then(() => {
person_type: '', deletePersonCourseSchedule(id).then(() => {
schedule_id: '', loadPersonCourseScheduleList()
course_date: '', }).catch(() => {
time_slot: '', })
}, })
}) }
const searchFormRef = ref<FormInstance>() const xkEvent = (id: number) => {
ElMessageBox.confirm("确定销课吗", t('warning'),
// {
const selectData = ref<any[]>([]) confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
// type: 'warning',
}
/** ).then(() => {
* 获取人员与课程安排关系列表 xkPersonCourseSchedule(id).then(() => {
*/ loadPersonCourseScheduleList()
const loadPersonCourseScheduleList = (page: number = 1) => { }).catch(() => {
personCourseScheduleTable.loading = true })
personCourseScheduleTable.page = page })
}
getPersonCourseScheduleList({
page: personCourseScheduleTable.page,
limit: personCourseScheduleTable.limit,
...personCourseScheduleTable.searchParam, const personIdList = ref([])
}) const setPersonIdList = async () => {
.then((res) => { personIdList.value = await (await getWithCustomerResourcesList({})).data
personCourseScheduleTable.loading = false }
personCourseScheduleTable.data = res.data.data setPersonIdList()
personCourseScheduleTable.total = res.data.total
}) const resetForm = (formEl: FormInstance | undefined) => {
.catch(() => { if (!formEl) return
personCourseScheduleTable.loading = false formEl.resetFields()
}) loadPersonCourseScheduleList()
} }
loadPersonCourseScheduleList() </script>
const editPersonCourseScheduleDialog: Record<string, any> | null = ref(null) <style lang="scss" scoped>
/* 多行超出隐藏 */
/** .multi-hidden {
* 添加人员与课程安排关系 word-break: break-all;
*/ text-overflow: ellipsis;
const addEvent = () => { overflow: hidden;
editPersonCourseScheduleDialog.value.setFormData() display: -webkit-box;
editPersonCourseScheduleDialog.value.showDialog = true -webkit-line-clamp: 2;
} -webkit-box-orient: vertical;
}
/** </style>
* 编辑人员与课程安排关系
* @param data
*/
const editEvent = (data: any) => {
editPersonCourseScheduleDialog.value.setFormData(data)
editPersonCourseScheduleDialog.value.showDialog = true
}
/**
* 删除人员与课程安排关系
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('personCourseScheduleDeleteTips'), t('warning'), {
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}).then(() => {
deletePersonCourseSchedule(id)
.then(() => {
loadPersonCourseScheduleList()
})
.catch(() => {})
})
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadPersonCourseScheduleList()
}
</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>

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

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

52
admin/src/app/views/scsjtj/components/BarChart.vue

@ -0,0 +1,52 @@
<template>
<div ref="chartRef" style="width: 100%; height: 300px;"></div>
</template>
<script setup>
import { onMounted, ref, watch } from 'vue'
import * as echarts from 'echarts'
const props = defineProps({
data: {
type: Array,
default: () => []
}
})
const chartRef = ref(null)
let chartInstance = null
const renderChart = () => {
if (!chartInstance) {
chartInstance = echarts.init(chartRef.value)
}
const option = {
xAxis: {
type: 'category',
data: props.data.map(item => item.name)
},
yAxis: {
type: 'value'
},
series: [
{
type: 'bar',
data: props.data.map(item => item.value),
itemStyle: {
color: '#3b82f6'
},
barWidth: '40%'
}
]
}
chartInstance.setOption(option)
}
onMounted(() => {
renderChart()
})
watch(() => props.data, renderChart, { deep: true })
</script>

17
admin/src/app/views/scsjtj/components/Card.vue

@ -0,0 +1,17 @@
<template>
<div class="bg-white rounded-lg shadow p-4 text-center">
<div class="text-sm text-gray-500 mb-1">{{ title }}</div>
<div :class="['text-2xl font-semibold', color]">{{ value }}</div>
</div>
</template>
<script setup>
defineProps({
title: String,
value: String,
color: {
type: String,
default: 'text-gray-800'
}
})
</script>

69
admin/src/app/views/scsjtj/components/PieChart.vue

@ -0,0 +1,69 @@
<template>
<div ref="chartRef" style="width: 100%; height: 300px;"></div>
</template>
<script setup>
import { onMounted, ref, watch } from 'vue'
import * as echarts from 'echarts'
const props = defineProps({
data: {
type: Array,
default: () => []
}
})
const chartRef = ref(null)
let chartInstance = null
const renderChart = () => {
if (!chartInstance) {
chartInstance = echarts.init(chartRef.value)
}
const option = {
tooltip: {
trigger: 'item'
},
legend: {
bottom: 10
},
series: [
{
name: '资源来源',
type: 'pie',
radius: ['40%', '70%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 10,
borderColor: '#fff',
borderWidth: 2
},
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: '16',
fontWeight: 'bold'
}
},
labelLine: {
show: false
},
data: props.data
}
]
}
chartInstance.setOption(option)
}
onMounted(() => {
renderChart()
})
watch(() => props.data, renderChart, { deep: true })
</script>

127
admin/src/app/views/scsjtj/scsjtj.vue

@ -0,0 +1,127 @@
<template>
<div class="main-container">
<el-card shadow="never" class="!border-none">
<template #header>
<span class="text-sm text-[#a19f98]">业绩统计</span>
</template>
<el-row :gutter="24">
<el-col :span="4">
<Card title="资源数量" :value="info.zysl" color="text-blue-600" />
</el-col>
<el-col :span="5">
<Card title="已沟通资源" :value="info.ygt" color="text-green-600" />
</el-col>
<el-col :span="5">
<Card title="未沟通资源" :value="info.wgt" color="text-orange-600" />
</el-col>
<el-col :span="5">
<Card title="市场人员数量" :value="info.scry" color="text-purple-600" />
</el-col>
<el-col :span="5">
<Card title="已核算绩效金额" :value="info.yhs" color="text-red-600" />
</el-col>
</el-row>
</el-card>
<el-row :gutter="15" class="mt-[15px]">
<el-col :span="24">
<el-card shadow="never" class="!border-none">
<div class="flex items-center space-x-4">
<el-date-picker
v-model="dateRange"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
/>
<el-button type="primary" @click="Init()">搜索</el-button>
<el-button @click="dateRange = []">重置</el-button>
</div>
</el-card>
</el-col>
</el-row>
<el-row :gutter="15" class="mt-[15px]">
<el-col :span="12">
<el-card shadow="never" class="!border-none">
<el-card shadow="hover">
<h3 class="text-md font-bold mb-2">市场人员业绩统计</h3>
<BarChart :data="barData" />
</el-card>
</el-card>
</el-col>
<el-col :span="12">
<el-card shadow="never" class="!border-none">
<el-card shadow="hover">
<h3 class="text-md font-bold mb-2">资源来源分布</h3>
<PieChart :data="pieData" />
</el-card>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script setup>
import { ref,reactive } from 'vue'
import { ElDatePicker, ElButton, ElCard } from 'element-plus'
import Card from './components/Card.vue'
import BarChart from './components/BarChart.vue'
import PieChart from './components/PieChart.vue'
import { getScsjtj } from '@/app/api/sys'
const dateRange = ref([])
const barData = ref([])
const pieData = ref([])
const info = reactive({
zysl: 0,
ygt: 0,
wgt: 0,
scry: 0,
yhs: 0
})
const Init = () => {
getScsjtj({'dateRange':dateRange.value})
.then((res) => {
console.log(res);
info.zysl = res.data.zysl
info.ygt = res.data.ygt
info.wgt = res.data.wgt
info.scry = res.data.scry
info.yhs = res.data.yhs
barData.value = res.data.barData
pieData.value = res.data.pieData
})
.catch(() => {
})
}
Init();
</script>
<style scoped>
</style>

28
admin/src/app/views/service/components/service-edit.vue

@ -14,7 +14,15 @@
</el-form-item> </el-form-item>
<el-form-item :label="t('serviceType')" prop="service_type"> <el-form-item :label="t('serviceType')" prop="service_type">
<el-input v-model="formData.service_type" clearable :placeholder="t('serviceTypePlaceholder')" class="input-width" /> <el-select class="input-width" v-model="formData.service_type" clearable :placeholder="t('serviceTypePlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in service_typeList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item> </el-form-item>
<el-form-item :label="t('executionRules')" prop="execution_rules"> <el-form-item :label="t('executionRules')" prop="execution_rules">
@ -28,7 +36,7 @@
v-for="(item, index) in staff_reminderList" v-for="(item, index) in staff_reminderList"
:key="index" :key="index"
:label="item.name" :label="item.name"
:value="Number(item.value)" :value="item.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -40,7 +48,7 @@
v-for="(item, index) in customer_reminderList" v-for="(item, index) in customer_reminderList"
:key="index" :key="index"
:label="item.name" :label="item.name"
:value="Number(item.value)" :value="item.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -52,14 +60,14 @@
v-for="(item, index) in customer_confirmationList" v-for="(item, index) in customer_confirmationList"
:key="index" :key="index"
:label="item.name" :label="item.name"
:value="Number(item.value)" :value="item.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- <el-form-item :label="t('customerFeedback')" > <el-form-item :label="t('customerFeedback')" >
<el-input v-model="formData.customer_feedback" clearable :placeholder="t('customerFeedbackPlaceholder')" class="input-width" /> <el-input v-model="formData.customer_feedback" clearable :placeholder="t('customerFeedbackPlaceholder')" class="input-width" />
</el-form-item> --> </el-form-item>
<el-form-item :label="t('status')" prop="status"> <el-form-item :label="t('status')" prop="status">
<el-select class="input-width" v-model="formData.status" clearable :placeholder="t('statusPlaceholder')"> <el-select class="input-width" v-model="formData.status" clearable :placeholder="t('statusPlaceholder')">
@ -109,7 +117,7 @@ const initialFormData = {
staff_reminder: '', staff_reminder: '',
customer_reminder: '', customer_reminder: '',
customer_confirmation: '', customer_confirmation: '',
// customer_feedback: '', customer_feedback: '',
status: '', status: '',
} }
const formData: Record<string, any> = reactive({ ...initialFormData }) const formData: Record<string, any> = reactive({ ...initialFormData })
@ -200,6 +208,12 @@ const confirm = async (formEl: FormInstance | undefined) => {
} }
// //
let service_typeList = ref([])
const service_typeDictList = async () => {
service_typeList.value = await (await useDictionary('service_type')).data.dictionary
}
service_typeDictList();
watch(() => service_typeList.value, () => { formData.service_type = service_typeList.value[0].value })
let staff_reminderList = ref([]) let staff_reminderList = ref([])
const staff_reminderDictList = async () => { const staff_reminderDictList = async () => {
staff_reminderList.value = await (await useDictionary('global_true_or_false')).data.dictionary staff_reminderList.value = await (await useDictionary('global_true_or_false')).data.dictionary

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

@ -14,10 +14,20 @@
<el-form-item :label="t('serviceName')" prop="service_name"> <el-form-item :label="t('serviceName')" prop="service_name">
<el-input v-model="serviceTable.searchParam.service_name" :placeholder="t('serviceNamePlaceholder')" /> <el-input v-model="serviceTable.searchParam.service_name" :placeholder="t('serviceNamePlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item :label="t('serviceType')" prop="service_type"> <el-form-item :label="t('serviceType')" prop="service_type">
<el-input v-model="serviceTable.searchParam.service_type" :placeholder="t('serviceTypePlaceholder')" /> <el-select class="w-[280px]" v-model="serviceTable.searchParam.service_type" clearable :placeholder="t('serviceTypePlaceholder')">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in service_typeList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item> </el-form-item>
<el-form-item :label="t('status')" prop="status"> <el-form-item :label="t('status')" prop="status">
<el-select class="w-[280px]" v-model="serviceTable.searchParam.status" clearable :placeholder="t('statusPlaceholder')"> <el-select class="w-[280px]" v-model="serviceTable.searchParam.status" clearable :placeholder="t('statusPlaceholder')">
<el-option label="全部" value=""></el-option> <el-option label="全部" value=""></el-option>
@ -46,7 +56,13 @@
<el-table-column prop="description" :label="t('description')" min-width="120" :show-overflow-tooltip="true"/> <el-table-column prop="description" :label="t('description')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="service_type" :label="t('serviceType')" min-width="120" :show-overflow-tooltip="true"/> <el-table-column :label="t('serviceType')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
<div v-for="(item, index) in service_typeList">
<div v-if="item.value == row.service_type">{{ item.name }}</div>
</div>
</template>
</el-table-column>
<el-table-column prop="customer_feedback" :label="t('customerFeedback')" min-width="120" :show-overflow-tooltip="true"/> <el-table-column prop="customer_feedback" :label="t('customerFeedback')" min-width="120" :show-overflow-tooltip="true"/>
@ -109,6 +125,11 @@ const searchFormRef = ref<FormInstance>()
const selectData = ref<any[]>([]) const selectData = ref<any[]>([])
// //
const service_typeList = ref([] as any[])
const service_typeDictList = async () => {
service_typeList.value = await (await useDictionary('service_type')).data.dictionary
}
service_typeDictList();
const staff_reminderList = ref([] as any[]) const staff_reminderList = ref([] as any[])
const staff_reminderDictList = async () => { const staff_reminderDictList = async () => {
staff_reminderList.value = await (await useDictionary('global_true_or_false')).data.dictionary staff_reminderList.value = await (await useDictionary('global_true_or_false')).data.dictionary

1
admin/src/app/views/student/student.vue

@ -169,6 +169,7 @@ let studentTable = reactive({
"contact_phone":"", "contact_phone":"",
"created_at":[], "created_at":[],
"member_label":'', "member_label":'',
"class_id": route.query.class_id ?? ''
} }
}) })

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

@ -118,7 +118,7 @@
<span>{{ !venueTable.loading ? t('emptyData') : '' }}</span> <span>{{ !venueTable.loading ? t('emptyData') : '' }}</span>
</template> </template>
<el-table-column <el-table-column
prop="campus_id_name" prop="campus.campus_name"
:label="t('campusId')" :label="t('campusId')"
min-width="120" min-width="120"
:show-overflow-tooltip="true" :show-overflow-tooltip="true"

5
niucloud/app/adminapi/controller/campus/Campus.php

@ -89,9 +89,8 @@ class Campus extends BaseAdminController
* @return \think\Response * @return \think\Response
*/ */
public function del(int $id){ public function del(int $id){
(new CampusService())->del($id); return (new CampusService())->del($id);
return success('DELETE_SUCCESS');
} }
} }

4
niucloud/app/adminapi/controller/classroom/Classroom.php

@ -102,8 +102,8 @@ class Classroom extends BaseAdminController
*/ */
public function del(int $id) public function del(int $id)
{ {
(new ClassroomService())->del($id); return (new ClassroomService())->del($id);
return success('DELETE_SUCCESS');
} }

1
niucloud/app/adminapi/controller/customer_resources/CustomerResources.php

@ -154,6 +154,7 @@ class CustomerResources extends BaseAdminController
{ {
$data = $this->request->params([ $data = $this->request->params([
["role_id", ""], ["role_id", ""],
["dept_id",""]
]); ]);
return success((new CustomerResourcesService())->getPersonnelAll($data)); return success((new CustomerResourcesService())->getPersonnelAll($data));

6
niucloud/app/adminapi/controller/market_performance/MarketPerformance.php

@ -29,9 +29,9 @@ class MarketPerformance extends BaseAdminController
public function lists(){ public function lists(){
$data = $this->request->params([ $data = $this->request->params([
["campus_id",""], ["campus_id",""],
["performance_amount",""] ["performance_amount",""],
["created_at",["",""]]
]); ]);
return success((new MarketPerformanceService())->getPage($data)); return success((new MarketPerformanceService())->getPage($data));
} }
@ -87,7 +87,7 @@ class MarketPerformance extends BaseAdminController
return success('DELETE_SUCCESS'); return success('DELETE_SUCCESS');
} }
public function getPersonnelAll(){ public function getPersonnelAll(){
return success(( new MarketPerformanceService())->getPersonnelAll()); return success(( new MarketPerformanceService())->getPersonnelAll());
} }

39
niucloud/app/adminapi/controller/person_course_schedule/PersonCourseSchedule.php

@ -28,11 +28,9 @@ class PersonCourseSchedule extends BaseAdminController
*/ */
public function lists(){ public function lists(){
$data = $this->request->params([ $data = $this->request->params([
["person_id",""], ["name",""],
["person_type",""], ["phone_number",""],
["schedule_id",""], ["campus_name",""]
["course_date",""],
["time_slot",""]
]); ]);
return success((new PersonCourseScheduleService())->getPage($data)); return success((new PersonCourseScheduleService())->getPage($data));
} }
@ -52,9 +50,12 @@ class PersonCourseSchedule extends BaseAdminController
*/ */
public function add(){ public function add(){
$data = $this->request->params([ $data = $this->request->params([
["resources_id",0], ["person_id",0],
["person_type",""],
["schedule_id",0], ["schedule_id",0],
["schedule_id",0] ["course_date","2025-05-29 17:03:27"],
["time_slot",""],
]); ]);
$this->validate($data, 'app\validate\person_course_schedule\PersonCourseSchedule.add'); $this->validate($data, 'app\validate\person_course_schedule\PersonCourseSchedule.add');
$id = (new PersonCourseScheduleService())->add($data); $id = (new PersonCourseScheduleService())->add($data);
@ -68,8 +69,11 @@ class PersonCourseSchedule extends BaseAdminController
*/ */
public function edit(int $id){ public function edit(int $id){
$data = $this->request->params([ $data = $this->request->params([
["resources_id",0], ["person_id",0],
["schedule_id",0] ["person_type",""],
["schedule_id",0],
["course_date","2025-05-29 17:03:27"],
["time_slot",""],
]); ]);
$this->validate($data, 'app\validate\person_course_schedule\PersonCourseSchedule.edit'); $this->validate($data, 'app\validate\person_course_schedule\PersonCourseSchedule.edit');
@ -84,13 +88,18 @@ class PersonCourseSchedule extends BaseAdminController
*/ */
public function del(int $id){ public function del(int $id){
(new PersonCourseScheduleService())->del($id); (new PersonCourseScheduleService())->del($id);
return success('DELETE_SUCCESS'); return success('请假成功');
} }
/** public function xk(int $id){
* 获取试课人员 (new PersonCourseScheduleService())->xk($id);
*/ return success('销课成功');
public function getTryCoursePerson($schedule_id){ }
return success((new PersonCourseScheduleService())->getTryCoursePerson($schedule_id));
public function getCustomerResourcesAll(){
return success(( new PersonCourseScheduleService())->getCustomerResourcesAll());
} }
} }

1
niucloud/app/adminapi/controller/student/Student.php

@ -34,6 +34,7 @@ class Student extends BaseAdminController
["contact_phone",""], ["contact_phone",""],
["created_at",["",""]], ["created_at",["",""]],
['member_label', 0], ['member_label', 0],
["class_id",""]
]); ]);
return success((new StudentService())->getPage($data)); return success((new StudentService())->getPage($data));
} }

15
niucloud/app/adminapi/controller/sys/System.php

@ -152,12 +152,6 @@ class System extends BaseAdminController
} }
public function home(){ public function home(){
// $data = $this->request->params([
// ['start_date', date('Y-m-d', strtotime('-6 day')) ],
// ['end_date', date('Y-m-d', strtotime('+1 day'))],
// ''
// ]);
$data = $this->request->params([ $data = $this->request->params([
['date', 'week'], ['date', 'week'],
]); ]);
@ -166,4 +160,13 @@ class System extends BaseAdminController
} }
public function scsjtj(){
$data = $this->request->params([
['dateRange', []],
]);
return success(data: (new SystemService())->scsjtj($data));
}
} }

1
niucloud/app/adminapi/route/market_performance.php

@ -14,6 +14,7 @@ use think\facade\Route;
use app\adminapi\middleware\AdminCheckRole; use app\adminapi\middleware\AdminCheckRole;
use app\adminapi\middleware\AdminCheckToken; use app\adminapi\middleware\AdminCheckToken;
use app\adminapi\middleware\AdminLog; use app\adminapi\middleware\AdminLog;
// USER_CODE_BEGIN -- market_performance // USER_CODE_BEGIN -- market_performance
Route::group('market_performance', function () { Route::group('market_performance', function () {

8
niucloud/app/adminapi/route/person_course_schedule.php

@ -14,6 +14,7 @@ use think\facade\Route;
use app\adminapi\middleware\AdminCheckRole; use app\adminapi\middleware\AdminCheckRole;
use app\adminapi\middleware\AdminCheckToken; use app\adminapi\middleware\AdminCheckToken;
use app\adminapi\middleware\AdminLog; use app\adminapi\middleware\AdminLog;
// USER_CODE_BEGIN -- person_course_schedule // USER_CODE_BEGIN -- person_course_schedule
Route::group('person_course_schedule', function () { Route::group('person_course_schedule', function () {
@ -28,8 +29,11 @@ Route::group('person_course_schedule', function () {
Route::put('person_course_schedule/:id', 'person_course_schedule.PersonCourseSchedule/edit'); Route::put('person_course_schedule/:id', 'person_course_schedule.PersonCourseSchedule/edit');
//删除人员与课程安排关系 //删除人员与课程安排关系
Route::delete('person_course_schedule/:id', 'person_course_schedule.PersonCourseSchedule/del'); Route::delete('person_course_schedule/:id', 'person_course_schedule.PersonCourseSchedule/del');
//获取试课人员
Route::get('get_try_course_person/:schedule_id', 'person_course_schedule.PersonCourseSchedule/getTryCoursePerson'); Route::delete('xk/:id', 'person_course_schedule.PersonCourseSchedule/xk');
Route::get('customer_resources_all','person_course_schedule.PersonCourseSchedule/getCustomerResourcesAll');
})->middleware([ })->middleware([
AdminCheckToken::class, AdminCheckToken::class,
AdminCheckRole::class, AdminCheckRole::class,

1
niucloud/app/adminapi/route/service.php

@ -16,6 +16,7 @@ use app\adminapi\middleware\AdminCheckToken;
use app\adminapi\middleware\AdminLog; use app\adminapi\middleware\AdminLog;
// USER_CODE_BEGIN -- service // USER_CODE_BEGIN -- service
Route::group('service', function () { Route::group('service', function () {

3
niucloud/app/adminapi/route/sys.php

@ -340,6 +340,9 @@ Route::group('sys', function() {
Route::post('home', 'sys.System/home'); Route::post('home', 'sys.System/home');
Route::post('scsjtj', 'sys.System/scsjtj');
})->middleware([ })->middleware([
AdminCheckToken::class, AdminCheckToken::class,
AdminCheckRole::class, AdminCheckRole::class,

7
niucloud/app/api/controller/apiController/CustomerResources.php

@ -131,6 +131,9 @@ class CustomerResources extends BaseApiService
"distance" => $request->param('distance', ''),//距离 "distance" => $request->param('distance', ''),//距离
"communication" => $request->param('communication', ''),//沟通备注 "communication" => $request->param('communication', ''),//沟通备注
"staff_id" => $request->param('staff_id', ''),//人员ID "staff_id" => $request->param('staff_id', ''),//人员ID
"first_visit_status" => $request->param('first_visit_status', null),//一访情况
"second_visit_status" => $request->param('second_visit_status', null),//二访情况
]; ];
foreach($customer_resources_data as $k=>$v){ foreach($customer_resources_data as $k=>$v){
@ -139,6 +142,10 @@ class CustomerResources extends BaseApiService
} }
} }
foreach($six_speed_data as $k=>$v){ foreach($six_speed_data as $k=>$v){
// 排除 first_visit_status 和 second_visit_status 的必填校验
if (in_array($k, ['first_visit_status', 'second_visit_status'])) {
continue;
}
if(!isset($v) || $v === ''){ if(!isset($v) || $v === ''){
return fail("缺少必填项{$k}"); return fail("缺少必填项{$k}");
} }

8
niucloud/app/api/controller/upload/Upload.php

@ -15,6 +15,7 @@ use app\service\api\upload\Base64Service;
use app\service\api\upload\FetchService; use app\service\api\upload\FetchService;
use app\service\api\upload\UploadService; use app\service\api\upload\UploadService;
use core\base\BaseApiController; use core\base\BaseApiController;
use think\Request;
use think\Response; use think\Response;
class Upload extends BaseApiController class Upload extends BaseApiController
@ -24,12 +25,15 @@ class Upload extends BaseApiController
* 图片上传 * 图片上传
* @return Response * @return Response
*/ */
public function image(){ public function image(Request $request){
$extraData = $request->all();
$data = $this->request->params([ $data = $this->request->params([
['file', 'file'], ['file', 'file'],
]); ]);
$upload_service = new UploadService(); $upload_service = new UploadService();
return success($upload_service->image($data['file'])); return success($upload_service->image($data['file'],$extraData));
} }
/** /**

2
niucloud/app/api/route/route.php

@ -201,7 +201,7 @@ Route::group(function () {
//需要token验证的 //需要token验证的
Route::group(function () { Route::group(function () {
//上传图片 //员工端-上传图片
Route::post('uploadImage', 'upload.Upload/image'); Route::post('uploadImage', 'upload.Upload/image');
//员工端详情 //员工端详情
Route::get('personnel/info', 'apiController.Personnel/info'); Route::get('personnel/info', 'apiController.Personnel/info');

4
niucloud/app/model/chat_friends/ChatFriends.php

@ -80,8 +80,8 @@ class ChatFriends extends BaseModel
} }
public function campus(){ public function customer(){
return $this->hasOne(CustomerResources::class, 'id', 'customer_resources_id')->joinType('left')->withField('name,id')->bind(['customer_resources_id'=>'name']); return $this->hasOne(CustomerResources::class, 'id', 'customer_resources_id')->joinType('left')->withField('name,id')->bind(['customer_resources_id_name'=>'name']);
} }
public function personnel(){ public function personnel(){

18
niucloud/app/model/market_performance/MarketPerformance.php

@ -70,6 +70,24 @@ class MarketPerformance extends BaseModel
} }
} }
/**
* 搜索器:市场绩效创建时间
* @param $value
* @param $data
*/
public function searchCreatedAtAttr($query, $value, $data)
{
$start = empty($value[0]) ? 0 : strtotime($value[0]);
$end = empty($value[1]) ? 0 : strtotime($value[1]);
if ($start > 0 && $end > 0) {
$query->where([["created_at", "between", [$start, $end]]]);
} else if ($start > 0 && $end == 0) {
$query->where([["created_at", ">=", $start]]);
} else if ($start == 0 && $end > 0) {
$query->where([["created_at", "<=", $end]]);
}
}

82
niucloud/app/model/person_course_schedule/PersonCourseSchedule.php

@ -11,14 +11,12 @@
namespace app\model\person_course_schedule; namespace app\model\person_course_schedule;
use app\model\customer_resources\CustomerResources;
use app\model\personnel\Personnel;
use app\model\student\Student;
use core\base\BaseModel; use core\base\BaseModel;
use think\model\concern\SoftDelete;
use think\model\relation\HasMany; use think\model\relation\HasMany;
use think\model\relation\HasOne; use think\model\relation\HasOne;
use app\model\customer_resources\CustomerResources;
/** /**
* 人员与课程安排关系模型 * 人员与课程安排关系模型
* Class PersonCourseSchedule * Class PersonCourseSchedule
@ -26,6 +24,8 @@ use think\model\relation\HasOne;
*/ */
class PersonCourseSchedule extends BaseModel class PersonCourseSchedule extends BaseModel
{ {
/** /**
* 数据表主键 * 数据表主键
* @var string * @var string
@ -38,92 +38,26 @@ class PersonCourseSchedule extends BaseModel
*/ */
protected $name = 'person_course_schedule'; protected $name = 'person_course_schedule';
/**
* 搜索器:人员与课程安排关系关系编号
* @param $value
* @param $data
*/
public function searchIdAttr($query, $value, $data)
{
if ($value) {
$query->where("id", $value);
}
}
/** /**
* 搜索器:人员与课程安排关系人员或资源ID * 搜索器:人员与课程安排关系资源
* @param $value * @param $value
* @param $data * @param $data
*/ */
public function searchPersonIdAttr($query, $value, $data) public function searchPersonIdAttr($query, $value, $data)
{ {
if ($value) { if ($value) {
$query->where("person_id", $value); $query->where("person_id", $value);
} }
} }
/**
* 搜索器:人员与课程安排关系人员类型: student-正式学员, customer_resource-客户资源
* @param $value
* @param $data
*/
public function searchPersonTypeAttr($query, $value, $data)
{
if ($value) {
$query->where("person_type", $value);
}
}
/**
* 搜索器:人员与课程安排关系课程安排ID
* @param $value
* @param $data
*/
public function searchScheduleIdAttr($query, $value, $data)
{
if ($value) {
$query->where("schedule_id", $value);
}
}
/**
* 搜索器:人员与课程安排关系上课日期
* @param $value
* @param $data
*/
public function searchCourseDateAttr($query, $value, $data)
{
if ($value) {
$query->where("course_date", $value);
}
}
/**
* 搜索器:人员与课程安排关系上课时段
* @param $value
* @param $data
*/
public function searchTimeSlotAttr($query, $value, $data)
{
if ($value) {
$query->where("time_slot", $value);
}
}
public function person() public function customerResources(){
{ return $this->hasOne(CustomerResources::class, 'id', 'person_id')->joinType('left')->withField('name,id')->bind(['person_id_name'=>'name']);
return $this->hasOne(Personnel::class, 'id', 'person_id');
}
public function student()
{
return $this->hasOne(Student::class, 'id', 'student_id');
}
public function resources()
{
return $this->hasOne(CustomerResources::class, 'id', 'resources_id');
} }
} }

8
niucloud/app/service/admin/campus/CampusService.php

@ -13,6 +13,7 @@ namespace app\service\admin\campus;
use app\model\campus\Campus; use app\model\campus\Campus;
use app\model\student\Student;
use core\base\BaseAdminService; use core\base\BaseAdminService;
@ -94,13 +95,16 @@ class CampusService extends BaseAdminService
/** /**
* 删除校区 * 删除校区
* @param int $id * @param int $id
* @return bool
*/ */
public function del(int $id) public function del(int $id)
{ {
$student = new Student();
if($student->where(['campus_id' => $id])->find()){
return fail("校区下有学员禁止删除");
}
$model = $this->model->where([['id', '=', $id]])->find(); $model = $this->model->where([['id', '=', $id]])->find();
$res = $model->delete(); $res = $model->delete();
return $res; return success('DELETE_SUCCESS');
} }

8
niucloud/app/service/admin/classroom/ClassroomService.php

@ -17,6 +17,7 @@ use app\model\course_schedule\CourseSchedule;
use app\model\personnel\Personnel; use app\model\personnel\Personnel;
use app\model\rel\ClassPersonnelRel; use app\model\rel\ClassPersonnelRel;
use app\model\student\Student;
use core\base\BaseAdminService; use core\base\BaseAdminService;
@ -90,13 +91,16 @@ class ClassroomService extends BaseAdminService
/** /**
* 删除场地管理 * 删除场地管理
* @param int $id * @param int $id
* @return bool
*/ */
public function del(int $id) public function del(int $id)
{ {
$student = new Student();
if($student->where(['class_id' => $id])->find()){
return fail("班级下有学员禁止删除");
}
$model = $this->model->where([['id', '=', $id]])->find(); $model = $this->model->where([['id', '=', $id]])->find();
$res = $model->delete(); $res = $model->delete();
return $res; return success('DELETE_SUCCESS');
} }

15
niucloud/app/service/admin/customer_resources/CustomerResourcesService.php

@ -136,7 +136,7 @@ class CustomerResourcesService extends BaseAdminService
$data['consultant'] = $personnel->where(['sys_user_id' => $this->uid])->value("id"); $data['consultant'] = $personnel->where(['sys_user_id' => $this->uid])->value("id");
if (!$data['consultant']) { if (!$data['consultant']) {
return fail("操作失败"); return fail("超级管理员不允许添加资源");
} }
$sixSpeed = new SixSpeed(); $sixSpeed = new SixSpeed();
@ -299,15 +299,20 @@ class CustomerResourcesService extends BaseAdminService
public function getPersonnelAll($data) public function getPersonnelAll($data)
{ {
$school_campus_person_role = new CampusPersonRole();
$personnelModel = new Personnel(); $personnelModel = new Personnel();
$where = []; $where = [];
if ($data['role_id']) { if ($data['role_id']) {
$where[] = ['b.role_id', '=', $data['role_id']]; $where[] = ['a.role_id', '=', $data['role_id']];
} }
return $personnelModel if ($data['dept_id']) {
$where[] = ['a.dept_id', '=', $data['dept_id']];
}
return $school_campus_person_role
->alias("a") ->alias("a")
->join(['school_campus_person_role' => 'b'], 'a.id = b.person_id', 'left') ->join(['school_personnel' => 'b'], 'a.person_id = b.id', 'left')
->field("a.*") ->field("b.*")
->where($where)->select()->toArray(); ->where($where)->select()->toArray();
} }

4
niucloud/app/service/admin/market_performance/MarketPerformanceService.php

@ -41,7 +41,7 @@ class MarketPerformanceService extends BaseAdminService
$field = 'id,personnel_id,campus_id,performance_amount,resource_count,performance_date,performance_config,performance_algorithm,status,created_at,updated_at'; $field = 'id,personnel_id,campus_id,performance_amount,resource_count,performance_date,performance_config,performance_algorithm,status,created_at,updated_at';
$order = 'id desc'; $order = 'id desc';
$search_model = $this->model->where(get_campus_where($this->uid))->withSearch(["campus_id","performance_amount"], $where)->with(['personnel','campus'])->field($field)->order($order); $search_model = $this->model->withSearch(["campus_id","performance_amount","created_at"], $where)->with(['personnel','campus'])->field($field)->order($order);
$list = $this->pageQuery($search_model); $list = $this->pageQuery($search_model);
return $list; return $list;
} }
@ -96,7 +96,7 @@ class MarketPerformanceService extends BaseAdminService
return $res; return $res;
} }
public function getPersonnelAll(){ public function getPersonnelAll(){
$personnelModel = new Personnel(); $personnelModel = new Personnel();
return $personnelModel->select()->toArray(); return $personnelModel->select()->toArray();

51
niucloud/app/service/admin/person_course_schedule/PersonCourseScheduleService.php

@ -11,6 +11,7 @@
namespace app\service\admin\person_course_schedule; namespace app\service\admin\person_course_schedule;
use app\model\course\Course;
use app\model\course_schedule\CourseSchedule; use app\model\course_schedule\CourseSchedule;
use app\model\customer_resources\CustomerResources; use app\model\customer_resources\CustomerResources;
use app\model\person_course_schedule\PersonCourseSchedule; use app\model\person_course_schedule\PersonCourseSchedule;
@ -38,14 +39,37 @@ class PersonCourseScheduleService extends BaseAdminService
* @param array $where * @param array $where
* @return array * @return array
*/ */
public function getPage(array $where = []) public function getPage(array $data = [])
{ {
$field = 'id,person_id,person_type,schedule_id,course_date,time_slot,created_at,updated_at'; $order = 'a.id desc';
$order = 'id desc'; $where = [];
if($data['name']){
$where[] = ['b.name','=',$data['name']];
}
if($data['phone_number']){
$where[] = ['b.phone_number','=',$data['phone_number']];
}
$search_model = $this->model->withSearch(["id", "person_id", "person_type", "schedule_id", "course_date", "time_slot"], $where)->field($field)->order($order); if($data['campus_name']){
$list = $this->pageQuery($search_model); $where[] = ['c.campus_name','=',$data['campus_name']];
return $list; }
$search_model = $this->model
->alias("a")
->join(['school_customer_resources' => 'b'],'a.person_id = b.id','left')
->join(['school_campus'=>'c'],'b.campus = c.id','left')
->where($where)
->field('a.*,b.name')
->order($order);
return $this->pageQuery($search_model, function ($item, $key) {
// $course = new Course();
$course_schedule = new CourseSchedule();
$course_type = $course_schedule
->alias("a")
->join(['school_course' => 'b'],'a.course_id = b.id','left')
->value("b.course_type");
$item['course_type'] = $course_type;
});
} }
/** /**
@ -55,9 +79,9 @@ class PersonCourseScheduleService extends BaseAdminService
*/ */
public function getInfo(int $id) public function getInfo(int $id)
{ {
$field = 'id,person_id,person_type,schedule_id,course_date,time_slot,created_at,updated_at'; $field = 'id,person_id,person_type,schedule_id,course_date,time_slot,created_at,updated_at,deleted_at';
$info = $this->model->field($field)->where([['id', "=", $id]])->findOrEmpty()->toArray(); $info = $this->model->field($field)->where([['id', "=", $id]])->with(['customerResources'])->findOrEmpty()->toArray();
return $info; return $info;
} }
@ -194,4 +218,15 @@ class PersonCourseScheduleService extends BaseAdminService
} }
return $data; return $data;
} }
public function xk(int $id){
$model = $this->model->where([['id', '=', $id]])->find();
$res = $model->delete();
return $res;
}
public function getCustomerResourcesAll(){
$customerResourcesModel = new CustomerResources();
return $customerResourcesModel->select()->toArray();
}
} }

2
niucloud/app/service/admin/student/StudentService.php

@ -45,7 +45,7 @@ class StudentService extends BaseAdminService
$field = 'id,user_id,campus_id,class_id,name,gender,age,birthday,member_label,emergency_contact,contact_phone,note,status,created_at,updated_at,deleted_at'; $field = 'id,user_id,campus_id,class_id,name,gender,age,birthday,member_label,emergency_contact,contact_phone,note,status,created_at,updated_at,deleted_at';
$order = 'id desc'; $order = 'id desc';
$search_model = $this->model->withSearch(["campus_id", "name", "emergency_contact", "contact_phone", "created_at", "member_label"], $where)->with(['customerResources', 'campus', 'classGrade'])->field($field)->order($order); $search_model = $this->model->withSearch(["campus_id", "name", "emergency_contact", "contact_phone", "created_at", "member_label","class_id"], $where)->with(['customerResources', 'campus', 'classGrade'])->field($field)->order($order);
return $this->pageQuery($search_model, function ($item, $key) { return $this->pageQuery($search_model, function ($item, $key) {
$item = $this->makeUp($item); $item = $this->makeUp($item);
}); });

57
niucloud/app/service/admin/sys/SystemService.php

@ -14,7 +14,10 @@ namespace app\service\admin\sys;
use addon\shop\app\model\ShopStat; use addon\shop\app\model\ShopStat;
use app\job\sys\CheckJob; use app\job\sys\CheckJob;
use app\model\campus\Campus; use app\model\campus\Campus;
use app\model\campus_person_role\CampusPersonRole;
use app\model\communication_records\CommunicationRecords;
use app\model\customer_resources\CustomerResources; use app\model\customer_resources\CustomerResources;
use app\model\market_performance\MarketPerformance;
use app\model\personnel\Personnel; use app\model\personnel\Personnel;
use app\model\student\Student; use app\model\student\Student;
use app\model\sys\SysConfig; use app\model\sys\SysConfig;
@ -285,4 +288,58 @@ class SystemService extends BaseAdminService
return $data; return $data;
} }
public function scsjtj(array $row){
$customerResources = new CustomerResources();
$campus_person_role = new CampusPersonRole();
$communication_records = new CommunicationRecords();
$market_performance = new MarketPerformance();
$per = new Personnel();
$data['zysl'] = $customerResources->count();
$data['ygt'] = 0;
$data['wgt'] = 0;
$list = $customerResources->select();
foreach ($list as $k => $v) {
if($communication_records->where(['resource_id' => $v['id']])->find()){
$data['ygt']++;
}else{
$data['wgt']++;
}
}
$data['scry'] = $campus_person_role->where(['dept_id' => 1])->count();
$start = date('Y-m-01');
$end = date('Y-m-t');
$data['yhs'] = $market_performance->whereBetween('performance_date', [$start, $end])->Sum("performance_amount");
$data['barData'] = [];
$where = [];
$c_where = [];
if(!empty($row['dateRange'])){
$where[] = ['performance_date','>=',$row['dateRange'][0]];
$where[] = ['performance_date','<=',$row['dateRange'][1]];
$c_where[] = ['create_date','>=',$row['dateRange'][0]];
$c_where[] = ['create_date','<=',$row['dateRange'][1]];
}
$sc_list = $campus_person_role->where(['dept_id' => 1])->select()->toArray();
foreach ($sc_list as $k => $v) {
$data['barData'][] = [
'name' => $per->where(['id' => $v['person_id']])->value('name'),
'value' => $market_performance->where(['personnel_id' => $v['person_id']])->where($where)->Sum("performance_amount")
];
}
$arr = [0=>'未知',1=>'线上',2=>'地推',3=>'转介绍',4=>'活动',5=>'内部员工'];
$data['pieData'] = [];
foreach ($arr as $k => $v) {
$data['pieData'][] = [
'name' => $v,
'value' => $customerResources->where(['source_channel' => $k])->where($c_where)->count()
];
}
return $data;
}
} }

7
niucloud/app/service/api/apiService/ChatService.php

@ -48,7 +48,12 @@ class ChatService extends BaseApiService
$model = $model->where('customer_resources_id', $where['customer_resources_id']); $model = $model->where('customer_resources_id', $where['customer_resources_id']);
} }
$data = $model->paginate([ $data = $model
->with([
'personnel',
'customer',
])
->paginate([
'list_rows' => $limit, 'list_rows' => $limit,
'page' => $page, 'page' => $page,
])->toArray(); ])->toArray();

41
niucloud/app/service/api/apiService/CustomerResourcesService.php

@ -15,6 +15,7 @@ use app\model\campus_person_role\CampusPersonRole;
use app\model\customer_resource_changes\CustomerResourceChanges; use app\model\customer_resource_changes\CustomerResourceChanges;
use app\model\customer_resources\CustomerResources; use app\model\customer_resources\CustomerResources;
use app\model\dict\Dict; use app\model\dict\Dict;
use app\model\member\Member;
use app\model\personnel\Personnel; use app\model\personnel\Personnel;
use app\model\resource_sharing\ResourceSharing; use app\model\resource_sharing\ResourceSharing;
use app\model\six_speed\SixSpeed; use app\model\six_speed\SixSpeed;
@ -122,10 +123,47 @@ class CustomerResourcesService extends BaseApiService
//开启事物 //开启事物
Db::startTrans(); Db::startTrans();
try { try {
$customer_resources = CustomerResources::where('id', $where['id'])->find(); $customer_resources = CustomerResources::where('id', $where['id'])->find();
$six_speed = SixSpeed::where('resource_id', $where['id'])->find();
if ($customer_resources) { if ($customer_resources) {
$customer_resources = $customer_resources->toArray(); $customer_resources = $customer_resources->toArray();
if(!$customer_resources['member_id'] && $six_speed){
//新数据存在一访问 或者旧数据存在一访的情况 && 这用户没注册过member账号的情况下才给他创建member账号
if(!empty($six_speed_data['first_visit_status']) || $six_speed['first_visit_status']){
$sex = 0;
switch ($customer_resources_data['gender']) {
case 'male'://男
$sex = 1;
break;
case 'female'://女
$sex = 2;
break;
default://其他
$sex = 0;
break;
}
$password = create_password($customer_resources_data['phone_number']);//创建密码
//给用户创建member账号
$member_id = Member::insertGetId([
'username'=>$customer_resources_data['phone_number'],//会员用户名
'mobile'=>$customer_resources_data['phone_number'],//手机号
'password'=>$password,//会员密码
'nickname'=>$customer_resources_data['name'],//会员昵称
'sex'=>$sex,//性别 0保密 1男 2女
'member_time'=>time(),//成为会员时间
]);
if($member_id){
$customer_resources_data['member_id'] = $member_id;
}else{
Db::rollback();
$res['msg'] = '创建用户账号失败';
return $res;
}
}
}
} }
$update_1 = CustomerResources::where('id', $where['id'])->update($customer_resources_data);//客户资源表 $update_1 = CustomerResources::where('id', $where['id'])->update($customer_resources_data);//客户资源表
if (!$update_1) { if (!$update_1) {
@ -157,7 +195,6 @@ class CustomerResourcesService extends BaseApiService
$six_speed_data['resource_id'] = $where['id']; $six_speed_data['resource_id'] = $where['id'];
//查六要素是否存在 //查六要素是否存在
$six_speed = SixSpeed::where('resource_id', $where['id'])->find();
if ($six_speed) { if ($six_speed) {
$six_speed = $six_speed->toArray(); $six_speed = $six_speed->toArray();
//更新六要素 //更新六要素

6
niucloud/app/service/api/apiService/ResourceSharingService.php

@ -115,15 +115,19 @@ class ResourceSharingService extends BaseApiService
]); ]);
} }
])->field($field)->find(); ])->field($field)->find();
if($data){
$data = $data->toArray();
}
if (!empty($data['customerResource'])) { if (!empty($data['customerResource'])) {
$data['customerResource']['cj_count'] = OrderTable::where('resource_id', $data['customerResource']['id']) $data['customerResource']['cj_count'] = OrderTable::where('resource_id', $data['customerResource']['id'])
->where('order_status', 'paid') ->where('order_status', 'paid')
->count();//成交次数 ->count();//成交次数
} }
// dd(123123,$data);
if ($data) { if ($data) {
$res['code'] = 1; $res['code'] = 1;
$res['msg'] = '操作成功'; $res['msg'] = '操作成功';
$res['data'] = $data->toArray(); $res['data'] = $data;
} else { } else {
$res['code'] = 0; $res['code'] = 0;

4
niucloud/app/service/api/upload/UploadService.php

@ -34,9 +34,9 @@ class UploadService extends BaseApiService
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
public function image($file) public function image($file,array $extraData = [])
{ {
$dir = $this->root_path . '/' . 'image' . '/' . date('Ym') . '/' . date('d'); $dir = $this->root_path . '/' . 'image' . '/' . date('Ym') . '/' . date('d');//打印结果 例如=file/image/202505/29
$core_upload_service = new CoreUploadService(); $core_upload_service = new CoreUploadService();
return $core_upload_service->image($file, $dir, $this->cate_id); return $core_upload_service->image($file, $dir, $this->cate_id);
} }

18
niucloud/app/validate/person_course_schedule/PersonCourseSchedule.php

@ -20,18 +20,24 @@ class PersonCourseSchedule extends BaseValidate
{ {
protected $rule = [ protected $rule = [
'resources_id' => 'require', 'person_id' => 'require',
'schedule_id' => 'require' 'person_type' => 'require',
'schedule_id' => 'require',
'course_date' => 'require',
'time_slot' => 'require',
]; ];
protected $message = [ protected $message = [
'resources_id.require' => ['common_validate.require', ['person_id']], 'person_id.require' => ['common_validate.require', ['person_id']],
'schedule_id.require' => ['common_validate.require', ['schedule_id']] 'person_type.require' => ['common_validate.require', ['person_type']],
'schedule_id.require' => ['common_validate.require', ['schedule_id']],
'course_date.require' => ['common_validate.require', ['course_date']],
'time_slot.require' => ['common_validate.require', ['time_slot']],
]; ];
protected $scene = [ protected $scene = [
"add" => ['resources_id', 'schedule_id'], "add" => ['person_id', 'person_type', 'schedule_id', 'course_date', 'time_slot'],
"edit" => ['resources_id', 'schedule_id'] "edit" => ['person_id', 'person_type', 'schedule_id', 'course_date', 'time_slot']
]; ];
} }

Loading…
Cancel
Save