Browse Source

Merge branch 'master' of http://gitlab.frkj.cc/php/zhjwxt

master
李双庆 10 months ago
parent
commit
59810e6996
  1. 23
      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. 5
      admin/src/app/api/sys.ts
  5. 5
      admin/src/app/lang/zh-cn/course.course.json
  6. 2
      admin/src/app/lang/zh-cn/market_performance.market_performance.json
  7. 18
      admin/src/app/lang/zh-cn/person_course_schedule.person_course_schedule.json
  8. 2
      admin/src/app/views/campus_person_role/components/campus-person-role-edit.vue
  9. 11
      admin/src/app/views/classroom/classroom.vue
  10. 17
      admin/src/app/views/course/components/course-edit.vue
  11. 9
      admin/src/app/views/course_schedule/components/course-schedule-edit.vue
  12. 3
      admin/src/app/views/customer_resources/components/fp.vue
  13. 96
      admin/src/app/views/market_performance/components/market-performance-edit.vue
  14. 132
      admin/src/app/views/market_performance/market_performance.vue
  15. 134
      admin/src/app/views/person_course_schedule/components/person-course-schedule-edit.vue
  16. 221
      admin/src/app/views/person_course_schedule/person_course_schedule.vue
  17. 231
      admin/src/app/views/physical_test/components/physical-test-edit.vue
  18. 52
      admin/src/app/views/scsjtj/components/BarChart.vue
  19. 17
      admin/src/app/views/scsjtj/components/Card.vue
  20. 69
      admin/src/app/views/scsjtj/components/PieChart.vue
  21. 127
      admin/src/app/views/scsjtj/scsjtj.vue
  22. 28
      admin/src/app/views/service/components/service-edit.vue
  23. 25
      admin/src/app/views/service/service.vue
  24. 1
      admin/src/app/views/student/student.vue
  25. 35
      admin/src/app/views/timetables/timetables.vue
  26. 2
      admin/src/app/views/venue/venue.vue
  27. BIN
      niucloud/app.zip
  28. 3
      niucloud/app/adminapi/controller/campus/Campus.php
  29. 4
      niucloud/app/adminapi/controller/classroom/Classroom.php
  30. 2
      niucloud/app/adminapi/controller/course/Course.php
  31. 1
      niucloud/app/adminapi/controller/customer_resources/CustomerResources.php
  32. 4
      niucloud/app/adminapi/controller/market_performance/MarketPerformance.php
  33. 39
      niucloud/app/adminapi/controller/person_course_schedule/PersonCourseSchedule.php
  34. 1
      niucloud/app/adminapi/controller/student/Student.php
  35. 15
      niucloud/app/adminapi/controller/sys/System.php
  36. 1
      niucloud/app/adminapi/route/market_performance.php
  37. 8
      niucloud/app/adminapi/route/person_course_schedule.php
  38. 1
      niucloud/app/adminapi/route/service.php
  39. 3
      niucloud/app/adminapi/route/sys.php
  40. 7
      niucloud/app/api/controller/apiController/CustomerResources.php
  41. 42
      niucloud/app/api/controller/login/Login.php
  42. 8
      niucloud/app/api/controller/upload/Upload.php
  43. 2
      niucloud/app/api/route/route.php
  44. 3
      niucloud/app/event.php
  45. 124
      niucloud/app/listener/personnel/Student.php
  46. 4
      niucloud/app/model/chat_friends/ChatFriends.php
  47. 18
      niucloud/app/model/market_performance/MarketPerformance.php
  48. 80
      niucloud/app/model/person_course_schedule/PersonCourseSchedule.php
  49. 9
      niucloud/app/service/admin/auth/AuthService.php
  50. 8
      niucloud/app/service/admin/campus/CampusService.php
  51. 2
      niucloud/app/service/admin/campus_person_role/CampusPersonRoleService.php
  52. 8
      niucloud/app/service/admin/classroom/ClassroomService.php
  53. 2
      niucloud/app/service/admin/course_schedule/CourseScheduleService.php
  54. 15
      niucloud/app/service/admin/customer_resources/CustomerResourcesService.php
  55. 2
      niucloud/app/service/admin/market_performance/MarketPerformanceService.php
  56. 48
      niucloud/app/service/admin/person_course_schedule/PersonCourseScheduleService.php
  57. 2
      niucloud/app/service/admin/student/StudentService.php
  58. 57
      niucloud/app/service/admin/sys/SystemService.php
  59. 7
      niucloud/app/service/api/apiService/ChatService.php
  60. 41
      niucloud/app/service/api/apiService/CustomerResourcesService.php
  61. 6
      niucloud/app/service/api/apiService/ResourceSharingService.php
  62. 37
      niucloud/app/service/api/pay/PayService.php
  63. 4
      niucloud/app/service/api/upload/UploadService.php
  64. 18
      niucloud/app/validate/person_course_schedule/PersonCourseSchedule.php
  65. 10
      node_modules/.yarn-integrity
  66. 4
      yarn.lock

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

@ -1,5 +1,7 @@
import request from '@/utils/request'
// USER_CODE_BEGIN -- market_performance
/**
*
@ -16,7 +18,7 @@ export function getMarketPerformanceList(params: Record<string, any>) {
* @returns
*/
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
*/
export function addMarketPerformance(params: Record<string, any>) {
return request.post('market_performance/market_performance', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.post('market_performance/market_performance', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -38,11 +37,7 @@ export function addMarketPerformance(params: Record<string, any>) {
* @returns
*/
export function editMarketPerformance(params: Record<string, any>) {
return request.put(
`market_performance/market_performance/${params.id}`,
params,
{ showErrorMessage: true, showSuccessMessage: true }
)
return request.put(`market_performance/market_performance/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -51,16 +46,12 @@ export function editMarketPerformance(params: Record<string, any>) {
* @returns
*/
export function deleteMarketPerformance(id: number) {
return request.delete(`market_performance/market_performance/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.delete(`market_performance/market_performance/${id}`, { showErrorMessage: true, showSuccessMessage: true })
}
export function getWithPersonnelList(params: Record<string,any>){
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})
}

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

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

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

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

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

@ -23,6 +23,7 @@
"updateCourse": "编辑课程",
"courseDeleteTips": "确定要删除该数据吗?",
"startDate": "请选择开始时间",
"endDate": "请选择结束时间"
"endDate": "请选择结束时间",
"giftSessionCount": "赠送课时",
"giftSessionCountPlaceholder": "请输入赠送课时"
}

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

@ -5,6 +5,8 @@
"campusIdPlaceholder":"全部",
"performanceAmount":"绩效金额",
"performanceAmountPlaceholder":"请输入绩效金额",
"createdAt":"创建时间",
"createdAtPlaceholder":"请输入创建时间",
"addMarketPerformance":"添加市场绩效",
"updateMarketPerformance":"编辑市场绩效",
"marketPerformanceDeleteTips":"确定要删除该数据吗?",

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

@ -1,14 +1,12 @@
{
"id": "关系编号",
"idPlaceholder": "请输入关系编号",
"personId": "人员或资源ID",
"personIdPlaceholder": "请输入人员或资源ID",
"personType": "人员类型: student-正式学员, customer_resource-客户资源",
"personTypePlaceholder": "请输入人员类型: student-正式学员, customer_resource-客户资源",
"scheduleId": "课程安排ID",
"scheduleIdPlaceholder": "请输入课程安排ID",
"courseDate": "上课日期",
"courseDatePlaceholder": "请输入上课日期",
"personId":"资源",
"personIdPlaceholder":"全部",
"personType":"人员类型",
"personTypePlaceholder":"请输入人员类型",
"scheduleId":"课程类型",
"scheduleIdPlaceholder":"请输入课程类型",
"courseDate":"上课时间",
"courseDatePlaceholder":"请输入上课时间",
"timeSlot":"上课时段",
"timeSlotPlaceholder":"请输入上课时段",
"addPersonCourseSchedule":"添加人员与课程安排关系",

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

@ -149,6 +149,8 @@ if(pageName == '市场人员列表'){
}else if(pageName == '销售人员列表'){
initialFormData.dept_id = 2;
// campusPersonRoleTable.searchParam.role_id = 2;
}else if(pageName == '教练管理'){
initialFormData.dept_id = 3;
}
const formData: Record<string, any> = reactive({ ...initialFormData })

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

@ -221,6 +221,8 @@
<el-button type="primary" link @click="deleteEvent(row.id)"
>{{ t('delete') }}
</el-button>
<el-button type="primary" link @click="classEvent(row.id)">学员</el-button>
</template>
</el-table-column>
</el-table>
@ -253,8 +255,9 @@ import {
} from '@/app/api/classroom'
import { ElMessageBox, FormInstance } from 'element-plus'
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 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>()
//

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

@ -55,6 +55,15 @@
/>
</el-form-item>
<el-form-item :label="t('giftSessionCount')" prop="gift_session_count">
<el-input
v-model="formData.gift_session_count"
clearable
:placeholder="t('giftSessionCountPlaceholder')"
class="input-width"
/>
</el-form-item>
<el-form-item
:label="t('singleSessionCount')"
prop="single_session_count"
@ -142,6 +151,7 @@ const initialFormData = {
internal_reminder: '',
customer_reminder: '',
remarks: '',
gift_session_count: '0',
}
const formData: Record<string, any> = reactive({ ...initialFormData })
@ -166,6 +176,13 @@ const formRules = computed(() => {
trigger: 'blur',
},
],
gift_session_count: [
{
required: false,
message: t('giftSessionCountPlaceholder'),
trigger: 'blur',
},
],
single_session_count: [
{
required: true,

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

@ -504,13 +504,12 @@ const numberVerify = (rule: any, value: any, callback: any) => {
//
const disabledDate = (time: Date) => {
//
const today = new Date()
today.setHours(0, 0, 0, 0)
const currentDate = new Date(time)
currentDate.setHours(0, 0, 0, 0)
//
return today.getTime() > currentDate.getTime()
const tomorrow = new Date(today)
tomorrow.setDate(tomorrow.getDate() + 1)
return time.getTime() < tomorrow.getTime()
}
defineExpose({

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

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

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

@ -1,28 +1,8 @@
<template>
<el-dialog
v-model="showDialog"
:title="
formData.id ? t('updateMarketPerformance') : t('addMarketPerformance')
"
width="50%"
class="diy-dialog-wrap"
:destroy-on-close="true"
>
<el-form
:model="formData"
label-width="120px"
ref="formRef"
:rules="formRules"
class="page-form"
v-loading="loading"
>
<el-dialog v-model="showDialog" :title="formData.id ? t('updateMarketPerformance') : t('addMarketPerformance')" width="50%" class="diy-dialog-wrap" :destroy-on-close="true">
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
<el-form-item :label="t('personnelId')" >
<el-select
class="input-width"
v-model="formData.personnel_id"
clearable
:placeholder="t('personnelIdPlaceholder')"
>
<el-select class="input-width" v-model="formData.personnel_id" clearable :placeholder="t('personnelIdPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in personnelIdList"
@ -34,12 +14,7 @@
</el-form-item>
<el-form-item :label="t('campusId')" >
<el-select
class="input-width"
v-model="formData.campus_id"
clearable
:placeholder="t('campusIdPlaceholder')"
>
<el-select class="input-width" v-model="formData.campus_id" clearable :placeholder="t('campusIdPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in campusIdList"
@ -51,24 +26,17 @@
</el-form-item>
<el-form-item :label="t('performanceAmount')" >
<el-input
v-model="formData.performance_amount"
clearable
:placeholder="t('performanceAmountPlaceholder')"
class="input-width"
/>
<el-input v-model="formData.performance_amount" clearable :placeholder="t('performanceAmountPlaceholder')" 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
>
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{
t('confirm')
}}</el-button>
</span>
</template>
</el-dialog>
@ -79,13 +47,7 @@ import { ref, reactive, computed, watch } from 'vue'
import { useDictionary } from '@/app/api/dict'
import { t } from '@/lang'
import type { FormInstance } from 'element-plus'
import {
addMarketPerformance,
editMarketPerformance,
getMarketPerformanceInfo,
getWithPersonnelList,
getWithCampusList,
} from '@/app/api/market_performance'
import { addMarketPerformance, editMarketPerformance, getMarketPerformanceInfo, getWithPersonnelList, getWithCampusList } from '@/app/api/market_performance'
let showDialog = ref(false)
const loading = ref(false)
@ -108,17 +70,19 @@ const formRules = computed(() => {
return {
personnel_id: [
{ required: true, message: t('personnelIdPlaceholder'), trigger: 'blur' },
],
]
,
campus_id: [
{ required: true, message: t('campusIdPlaceholder'), trigger: 'blur' },
],
]
,
performance_amount: [
{
required: true,
message: t('performanceAmountPlaceholder'),
trigger: 'blur',
},
],
{ required: true, message: t('performanceAmountPlaceholder'), trigger: 'blur' },
]
,
}
})
@ -138,13 +102,11 @@ const confirm = async (formEl: FormInstance | undefined) => {
let data = formData
save(data)
.then((res) => {
save(data).then(res => {
loading.value = false
showDialog.value = false
emit('complete')
})
.catch((err) => {
}).catch(err => {
loading.value = false
})
}
@ -153,6 +115,8 @@ const confirm = async (formEl: FormInstance | undefined) => {
//
const personnelIdList = ref([] as any[])
const setPersonnelIdList = async () => {
personnelIdList.value = await (await getWithPersonnelList({})).data
@ -168,8 +132,7 @@ const setFormData = async (row: any = null) => {
loading.value = true
if(row){
const data = await (await getMarketPerformanceInfo(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]
})
}
@ -187,12 +150,7 @@ const mobileVerify = (rule: any, value: any, callback: any) => {
//
const idCardVerify = (rule: any, value: any, callback: any) => {
if (
value &&
!/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
value
)
) {
if (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()
@ -219,7 +177,7 @@ const numberVerify = (rule: any, value: any, callback: any) => {
defineExpose({
showDialog,
setFormData,
setFormData
})
</script>

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

@ -1,6 +1,7 @@
<template>
<div class="main-container">
<el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<span class="text-lg">{{pageName}}</span>
<!-- <el-button type="primary" @click="addEvent">
@ -8,22 +9,11 @@
</el-button> -->
</div>
<el-card
class="box-card !border-none my-[10px] table-search-wrap"
shadow="never"
>
<el-form
:inline="true"
:model="marketPerformanceTable.searchParam"
ref="searchFormRef"
>
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="marketPerformanceTable.searchParam" ref="searchFormRef">
<el-form-item :label="t('campusId')" prop="campus_id">
<el-select
class="w-[280px]"
v-model="marketPerformanceTable.searchParam.campus_id"
clearable
:placeholder="t('campusIdPlaceholder')"
>
<el-select class="w-[280px]" v-model="marketPerformanceTable.searchParam.campus_id" clearable :placeholder="t('campusIdPlaceholder')">
<el-option
v-for="(item, index) in campusIdList"
:key="index"
@ -33,83 +23,50 @@
</el-select>
</el-form-item>
<el-form-item
:label="t('performanceAmount')"
prop="performance_amount"
>
<el-input
v-model="marketPerformanceTable.searchParam.performance_amount"
:placeholder="t('performanceAmountPlaceholder')"
/>
<el-form-item :label="t('performanceAmount')" prop="performance_amount">
<el-input v-model="marketPerformanceTable.searchParam.performance_amount" :placeholder="t('performanceAmountPlaceholder')" />
</el-form-item>
<el-form-item :label="t('createdAt')" prop="created_at">
<el-date-picker v-model="marketPerformanceTable.searchParam.created_at" type="datetimerange" format="YYYY-MM-DD hh:mm:ss"
:start-placeholder="t('startDate')" :end-placeholder="t('endDate')" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="loadMarketPerformanceList()">{{
t('search')
}}</el-button>
<el-button @click="resetForm(searchFormRef)">{{
t('reset')
}}</el-button>
<el-button type="primary" @click="loadMarketPerformanceList()">{{ t('search') }}</el-button>
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
</el-form-item>
</el-form>
</el-card>
<div class="mt-[10px]">
<el-table
:data="marketPerformanceTable.data"
size="large"
v-loading="marketPerformanceTable.loading"
>
<el-table :data="marketPerformanceTable.data" size="large" v-loading="marketPerformanceTable.loading">
<template #empty>
<span>{{
!marketPerformanceTable.loading ? t('emptyData') : ''
}}</span>
<span>{{ !marketPerformanceTable.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column
prop="personnel_id_name"
:label="t('personnelId')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column prop="personnel_id_name" :label="t('personnelId')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column
prop="campus_id_name"
:label="t('campusId')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column prop="campus_id_name" :label="t('campusId')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column
prop="performance_amount"
:label="t('performanceAmount')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column prop="performance_amount" :label="t('performanceAmount')" min-width="120" :show-overflow-tooltip="true"/>
<!--
<el-table-column :label="t('operation')" fixed="right" min-width="120">
<el-table-column prop="created_at" :label="t('createdAt')" min-width="120" :show-overflow-tooltip="true"/>
<!-- <el-table-column :label="t('operation')" fixed="right" min-width="120">
<template #default="{ row }">
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button>
</template>
</el-table-column> -->
</el-table>
<div class="mt-[16px] flex justify-end">
<el-pagination
v-model:current-page="marketPerformanceTable.page"
v-model:page-size="marketPerformanceTable.limit"
layout="total, sizes, prev, pager, next, jumper"
:total="marketPerformanceTable.total"
@size-change="loadMarketPerformanceList()"
@current-change="loadMarketPerformanceList"
/>
<el-pagination v-model:current-page="marketPerformanceTable.page" v-model:page-size="marketPerformanceTable.limit"
layout="total, sizes, prev, pager, next, jumper" :total="marketPerformanceTable.total"
@size-change="loadMarketPerformanceList()" @current-change="loadMarketPerformanceList" />
</div>
</div>
<edit
ref="editMarketPerformanceDialog"
@complete="loadMarketPerformanceList"
/>
<edit ref="editMarketPerformanceDialog" @complete="loadMarketPerformanceList" />
</el-card>
</div>
</template>
@ -118,18 +75,13 @@
import { reactive, ref, watch } from 'vue'
import { t } from '@/lang'
import { useDictionary } from '@/app/api/dict'
import {
getMarketPerformanceList,
deleteMarketPerformance,
getWithPersonnelList,
getWithCampusList,
} from '@/app/api/market_performance'
import { getMarketPerformanceList, deleteMarketPerformance, getWithPersonnelList, getWithCampusList } from '@/app/api/market_performance'
import { img } from '@/utils/common'
import { ElMessageBox,FormInstance } from 'element-plus'
import Edit from '@/app/views/market_performance/components/market-performance-edit.vue'
import { useRoute } from 'vue-router'
const route = useRoute()
const pageName = route.meta.title
const pageName = route.meta.title;
let marketPerformanceTable = reactive({
page: 1,
@ -138,9 +90,10 @@ let marketPerformanceTable = reactive({
loading: true,
data: [],
searchParam:{
campus_id: '',
performance_amount: '',
},
"campus_id":"",
"performance_amount":"",
"created_at":[]
}
})
const searchFormRef = ref<FormInstance>()
@ -150,6 +103,7 @@ const selectData = ref<any[]>([])
//
/**
* 获取市场绩效列表
*/
@ -160,14 +114,12 @@ const loadMarketPerformanceList = (page: number = 1) => {
getMarketPerformanceList({
page: marketPerformanceTable.page,
limit: marketPerformanceTable.limit,
...marketPerformanceTable.searchParam,
})
.then((res) => {
...marketPerformanceTable.searchParam
}).then(res => {
marketPerformanceTable.loading = false
marketPerformanceTable.data = res.data.data
marketPerformanceTable.total = res.data.total
})
.catch(() => {
}).catch(() => {
marketPerformanceTable.loading = false
})
}
@ -196,19 +148,21 @@ const editEvent = (data: any) => {
* 删除市场绩效
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('marketPerformanceDeleteTips'), t('warning'), {
ElMessageBox.confirm(t('marketPerformanceDeleteTips'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}).then(() => {
deleteMarketPerformance(id)
.then(() => {
}
).then(() => {
deleteMarketPerformance(id).then(() => {
loadMarketPerformanceList()
}).catch(() => {
})
.catch(() => {})
})
}
const personnelIdList = ref([])
const setPersonnelIdList = async () => {
personnelIdList.value = await (await getWithPersonnelList({})).data

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

@ -1,78 +1,50 @@
<template>
<el-dialog
v-model="showDialog"
:title="
formData.id
? t('updatePersonCourseSchedule')
: t('addPersonCourseSchedule')
"
width="50%"
class="diy-dialog-wrap"
:destroy-on-close="true"
>
<el-form
:model="formData"
label-width="120px"
ref="formRef"
:rules="formRules"
class="page-form"
v-loading="loading"
>
<el-dialog v-model="showDialog" :title="formData.id ? t('updatePersonCourseSchedule') : t('addPersonCourseSchedule')" width="50%" class="diy-dialog-wrap" :destroy-on-close="true">
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
<el-form-item :label="t('personId')" prop="person_id">
<el-input
v-model="formData.person_id"
clearable
:placeholder="t('personIdPlaceholder')"
class="input-width"
<el-select class="input-width" v-model="formData.person_id" clearable :placeholder="t('personIdPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in personIdList"
:key="index"
:label="item['name']"
:value="item['id']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('personType')" prop="person_type">
<el-input
v-model="formData.person_type"
clearable
:placeholder="t('personTypePlaceholder')"
class="input-width"
<el-select class="input-width" v-model="formData.person_type" clearable :placeholder="t('personTypePlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in person_typeList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</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-input v-model="formData.schedule_id" clearable :placeholder="t('scheduleIdPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('courseDate')" prop="course_date">
<el-input
v-model="formData.course_date"
clearable
:placeholder="t('courseDatePlaceholder')"
class="input-width"
/>
<el-input v-model="formData.course_date" clearable :placeholder="t('courseDatePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('timeSlot')" prop="time_slot">
<el-input
v-model="formData.time_slot"
clearable
:placeholder="t('timeSlotPlaceholder')"
class="input-width"
/>
<el-input v-model="formData.time_slot" clearable :placeholder="t('timeSlotPlaceholder')" 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
>
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{
t('confirm')
}}</el-button>
</span>
</template>
</el-dialog>
@ -83,11 +55,7 @@ import { ref, reactive, computed, watch } from 'vue'
import { useDictionary } from '@/app/api/dict'
import { t } from '@/lang'
import type { FormInstance } from 'element-plus'
import {
addPersonCourseSchedule,
editPersonCourseSchedule,
getPersonCourseScheduleInfo,
} from '@/app/api/person_course_schedule'
import { addPersonCourseSchedule, editPersonCourseSchedule, getPersonCourseScheduleInfo, getWithCustomerResourcesList } from '@/app/api/person_course_schedule'
let showDialog = ref(false)
const loading = ref(false)
@ -112,19 +80,29 @@ const formRules = computed(() => {
return {
person_id: [
{ required: true, message: t('personIdPlaceholder'), trigger: 'blur' },
],
]
,
person_type: [
{ required: true, message: t('personTypePlaceholder'), trigger: 'blur' },
],
]
,
schedule_id: [
{ required: true, message: t('scheduleIdPlaceholder'), trigger: 'blur' },
],
]
,
course_date: [
{ required: true, message: t('courseDatePlaceholder'), trigger: 'blur' },
],
]
,
time_slot: [
{ required: true, message: t('timeSlotPlaceholder'), trigger: 'blur' },
],
]
,
}
})
@ -144,13 +122,11 @@ const confirm = async (formEl: FormInstance | undefined) => {
let data = formData
save(data)
.then((res) => {
save(data).then(res => {
loading.value = false
showDialog.value = false
emit('complete')
})
.catch((err) => {
}).catch(err => {
loading.value = false
})
}
@ -158,14 +134,25 @@ const confirm = async (formEl: FormInstance | undefined) => {
}
//
let person_typeList = ref([])
const person_typeDictList = async () => {
person_typeList.value = await (await useDictionary('person_type')).data.dictionary
}
person_typeDictList();
watch(() => person_typeList.value, () => { formData.person_type = person_typeList.value[0].value })
const personIdList = ref([] as any[])
const setPersonIdList = async () => {
personIdList.value = await (await getWithCustomerResourcesList({})).data
}
setPersonIdList()
const setFormData = async (row: any = null) => {
Object.assign(formData, initialFormData)
loading.value = true
if(row){
const data = await (await getPersonCourseScheduleInfo(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]
})
}
@ -183,12 +170,7 @@ const mobileVerify = (rule: any, value: any, callback: any) => {
//
const idCardVerify = (rule: any, value: any, callback: any) => {
if (
value &&
!/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
value
)
) {
if (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()
@ -215,7 +197,7 @@ const numberVerify = (rule: any, value: any, callback: any) => {
defineExpose({
showDialog,
setFormData,
setFormData
})
</script>

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

@ -1,141 +1,76 @@
<template>
<div class="main-container">
<el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<span class="text-lg">{{pageName}}</span>
<el-button type="primary" @click="addEvent">
{{ t('addPersonCourseSchedule') }}
</el-button>
</div>
<el-card
class="box-card !border-none my-[10px] table-search-wrap"
shadow="never"
>
<el-form
:inline="true"
:model="personCourseScheduleTable.searchParam"
ref="searchFormRef"
>
<el-form-item :label="t('personId')" prop="person_id">
<el-input
v-model="personCourseScheduleTable.searchParam.person_id"
:placeholder="t('personIdPlaceholder')"
/>
</el-form-item>
<el-form-item :label="t('personType')" prop="person_type">
<el-input
v-model="personCourseScheduleTable.searchParam.person_type"
:placeholder="t('personTypePlaceholder')"
/>
</el-form-item>
<el-form-item :label="t('scheduleId')" prop="schedule_id">
<el-input
v-model="personCourseScheduleTable.searchParam.schedule_id"
:placeholder="t('scheduleIdPlaceholder')"
/>
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="personCourseScheduleTable.searchParam" ref="searchFormRef">
<el-form-item label="资源名称" prop="name">
<el-input v-model="personCourseScheduleTable.searchParam.name"
placeholder="请输入资源名称" />
</el-form-item>
<el-form-item :label="t('courseDate')" prop="course_date">
<el-input
v-model="personCourseScheduleTable.searchParam.course_date"
:placeholder="t('courseDatePlaceholder')"
/>
<el-form-item label="资源手机号" prop="phone_number">
<el-input v-model="personCourseScheduleTable.searchParam.phone_number"
placeholder="请输入资源手机号" />
</el-form-item>
<el-form-item :label="t('timeSlot')" prop="time_slot">
<el-input
v-model="personCourseScheduleTable.searchParam.time_slot"
:placeholder="t('timeSlotPlaceholder')"
/>
<el-form-item label="校区" prop="campus_name">
<el-input v-model="personCourseScheduleTable.searchParam.campus_name"
placeholder="请输入校区" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="loadPersonCourseScheduleList()">{{
t('search')
}}</el-button>
<el-button @click="resetForm(searchFormRef)">{{
t('reset')
}}</el-button>
<el-button type="primary" @click="loadPersonCourseScheduleList()">{{ t('search') }}</el-button>
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
</el-form-item>
</el-form>
</el-card>
<div class="mt-[10px]">
<el-table
:data="personCourseScheduleTable.data"
size="large"
v-loading="personCourseScheduleTable.loading"
>
<el-table :data="personCourseScheduleTable.data" size="large" v-loading="personCourseScheduleTable.loading">
<template #empty>
<span>{{
!personCourseScheduleTable.loading ? t('emptyData') : ''
}}</span>
<span>{{ !personCourseScheduleTable.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column
prop="person_id"
:label="t('personId')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column
prop="person_type"
:label="t('personType')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column
prop="schedule_id"
:label="t('scheduleId')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column
prop="course_date"
:label="t('courseDate')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column
prop="time_slot"
:label="t('timeSlot')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column
:label="t('operation')"
fixed="right"
min-width="120"
>
<el-table-column prop="name" label="资源名称" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column label="人员类型" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
<el-button type="primary" link @click="editEvent(row)">{{
t('edit')
}}</el-button>
<el-button type="primary" link @click="deleteEvent(row.id)">{{
t('delete')
}}</el-button>
<div v-for="(item, index) in person_typeList">
<div v-if="item.value == row.person_type">{{ item.name }}</div>
</div>
</template>
</el-table-column>
<el-table-column prop="course_type" label="课程类型" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="course_date" :label="t('courseDate')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="time_slot" :label="t('timeSlot')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column :label="t('operation')" fixed="right" min-width="120">
<template #default="{ row }">
<el-button type="primary" link @click="deleteEvent(row.id)">请假</el-button>
<el-button type="primary" link @click="xkEvent(row.id)">消课</el-button>
</template>
</el-table-column>
</el-table>
<div class="mt-[16px] flex justify-end">
<el-pagination
v-model:current-page="personCourseScheduleTable.page"
v-model:page-size="personCourseScheduleTable.limit"
layout="total, sizes, prev, pager, next, jumper"
:total="personCourseScheduleTable.total"
@size-change="loadPersonCourseScheduleList()"
@current-change="loadPersonCourseScheduleList"
/>
<el-pagination v-model:current-page="personCourseScheduleTable.page" v-model:page-size="personCourseScheduleTable.limit"
layout="total, sizes, prev, pager, next, jumper" :total="personCourseScheduleTable.total"
@size-change="loadPersonCourseScheduleList()" @current-change="loadPersonCourseScheduleList" />
</div>
</div>
<edit
ref="editPersonCourseScheduleDialog"
@complete="loadPersonCourseScheduleList"
/>
<edit ref="editPersonCourseScheduleDialog" @complete="loadPersonCourseScheduleList" />
</el-card>
</div>
</template>
@ -144,16 +79,13 @@
import { reactive, ref, watch } from 'vue'
import { t } from '@/lang'
import { useDictionary } from '@/app/api/dict'
import {
getPersonCourseScheduleList,
deletePersonCourseSchedule,
} from '@/app/api/person_course_schedule'
import { getPersonCourseScheduleList, deletePersonCourseSchedule, getWithCustomerResourcesList,xkPersonCourseSchedule} from '@/app/api/person_course_schedule'
import { img } from '@/utils/common'
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'
const route = useRoute()
const pageName = route.meta.title
const pageName = route.meta.title;
let personCourseScheduleTable = reactive({
page: 1,
@ -162,12 +94,10 @@ let personCourseScheduleTable = reactive({
loading: true,
data: [],
searchParam:{
person_id: '',
person_type: '',
schedule_id: '',
course_date: '',
time_slot: '',
},
"name":"",
"phone_number":"",
"campus_name":""
}
})
const searchFormRef = ref<FormInstance>()
@ -176,6 +106,11 @@ const searchFormRef = ref<FormInstance>()
const selectData = ref<any[]>([])
//
const person_typeList = ref([] as any[])
const person_typeDictList = async () => {
person_typeList.value = await (await useDictionary('person_type')).data.dictionary
}
person_typeDictList();
/**
* 获取人员与课程安排关系列表
@ -187,14 +122,12 @@ const loadPersonCourseScheduleList = (page: number = 1) => {
getPersonCourseScheduleList({
page: personCourseScheduleTable.page,
limit: personCourseScheduleTable.limit,
...personCourseScheduleTable.searchParam,
})
.then((res) => {
...personCourseScheduleTable.searchParam
}).then(res => {
personCourseScheduleTable.loading = false
personCourseScheduleTable.data = res.data.data
personCourseScheduleTable.total = res.data.total
})
.catch(() => {
}).catch(() => {
personCourseScheduleTable.loading = false
})
}
@ -223,19 +156,43 @@ const editEvent = (data: any) => {
* 删除人员与课程安排关系
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('personCourseScheduleDeleteTips'), t('warning'), {
ElMessageBox.confirm("确定请假吗", t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}
).then(() => {
deletePersonCourseSchedule(id).then(() => {
loadPersonCourseScheduleList()
}).catch(() => {
})
})
}
const xkEvent = (id: number) => {
ElMessageBox.confirm("确定销课吗", t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}).then(() => {
deletePersonCourseSchedule(id)
.then(() => {
}
).then(() => {
xkPersonCourseSchedule(id).then(() => {
loadPersonCourseScheduleList()
}).catch(() => {
})
.catch(() => {})
})
}
const personIdList = ref([])
const setPersonIdList = async () => {
personIdList.value = await (await getWithCustomerResourcesList({})).data
}
setPersonIdList()
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()

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

@ -1,72 +1,45 @@
<template>
<el-dialog
v-model="showDialog"
:title="formData.id ? t('updatePhysicalTest') : t('addPhysicalTest')"
width="50%"
class="diy-dialog-wrap"
:destroy-on-close="true"
>
<el-form
:model="formData"
label-width="120px"
ref="formRef"
:rules="formRules"
class="page-form"
v-loading="loading"
>
<el-dialog v-model="showDialog" :title="formData.id ? t('updatePhysicalTest') : t('addPhysicalTest')" width="50%"
class="diy-dialog-wrap" :destroy-on-close="true">
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form"
v-loading="loading">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item :label="t('resourceId')" prop="resource_id">
<el-select
class="input-width"
v-model="formData.resource_id"
clearable
:placeholder="t('resourceIdPlaceholder')"
>
<el-select class="input-width" v-model="formData.resource_id" clearable
:placeholder="t('resourceIdPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in resourceIdList"
:key="index"
:label="item['name']"
:value="item['id']"
/>
<el-option v-for="(item, index) in resourceIdList" :key="index" :label="item['name']"
:value="item['id']" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="t('studentId')" prop="student_id">
<el-select
class="input-width"
v-model="formData.student_id"
clearable
:placeholder="t('studentIdPlaceholder')"
>
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in studentIdList"
:key="index"
:label="item['name']"
:value="item['id']"
/>
<el-select class="input-width" v-model="formData.student_id" clearable
:placeholder="t('studentIdPlaceholder')">
<el-option label="请选择" :value="0"></el-option>
<el-option v-for="(item, index) in studentIdList" :key="index" :label="item['name']"
:value="item['id']" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item :label="t('height')" prop="height">
<el-input
v-model="formData.height"
clearable
:placeholder="t('heightPlaceholder')"
class="input-width"
/>
<el-input v-model="formData.height" clearable :placeholder="t('heightPlaceholder')"
class="input-width" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="t('weight')" prop="weight">
<el-input
v-model="formData.weight"
clearable
:placeholder="t('weightPlaceholder')"
class="input-width"
/>
<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-col>
</el-row>
<!-- <el-form-item :label="t('coachId')" prop="coach_id">
<el-select
class="input-width"
v-model="formData.coach_id"
@ -81,108 +54,86 @@
:value="item['id']"
/>
</el-select>
</el-form-item>
</el-form-item> -->
<el-row :gutter="20">
<el-col :span="12">
<el-form-item :label="t('seatedForwardBend')">
<el-input
v-model="formData.seated_forward_bend"
clearable
:placeholder="t('seatedForwardBendPlaceholder')"
class="input-width"
/>
<el-input v-model="formData.seated_forward_bend" clearable
:placeholder="t('seatedForwardBendPlaceholder')" class="input-width" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="t('sitUps')">
<el-input
v-model="formData.sit_ups"
clearable
:placeholder="t('sitUpsPlaceholder')"
class="input-width"
/>
<el-input v-model="formData.sit_ups" clearable :placeholder="t('sitUpsPlaceholder')"
class="input-width" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item :label="t('pushUps')">
<el-input
v-model="formData.push_ups"
clearable
:placeholder="t('pushUpsPlaceholder')"
class="input-width"
/>
<el-input v-model="formData.push_ups" clearable :placeholder="t('pushUpsPlaceholder')"
class="input-width" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="t('flamingoBalance')">
<el-input
v-model="formData.flamingo_balance"
clearable
:placeholder="t('flamingoBalancePlaceholder')"
class="input-width"
/>
<el-input v-model="formData.flamingo_balance" clearable
:placeholder="t('flamingoBalancePlaceholder')" class="input-width" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item :label="t('thirtySecJump')">
<el-input
v-model="formData.thirty_sec_jump"
clearable
:placeholder="t('thirtySecJumpPlaceholder')"
class="input-width"
/>
<el-input v-model="formData.thirty_sec_jump" clearable
:placeholder="t('thirtySecJumpPlaceholder')" class="input-width" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="t('standingLongJump')">
<el-input
v-model="formData.standing_long_jump"
clearable
:placeholder="t('standingLongJumpPlaceholder')"
class="input-width"
/>
<el-input v-model="formData.standing_long_jump" clearable
:placeholder="t('standingLongJumpPlaceholder')" class="input-width" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item :label="t('agilityRun')">
<el-input
v-model="formData.agility_run"
clearable
:placeholder="t('agilityRunPlaceholder')"
class="input-width"
/>
<el-input v-model="formData.agility_run" clearable :placeholder="t('agilityRunPlaceholder')"
class="input-width" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="t('balanceBeam')">
<el-input
v-model="formData.balance_beam"
clearable
:placeholder="t('balanceBeamPlaceholder')"
class="input-width"
/>
<el-input v-model="formData.balance_beam" clearable :placeholder="t('balanceBeamPlaceholder')"
class="input-width" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item :label="t('tennisThrow')">
<el-input
v-model="formData.tennis_throw"
clearable
:placeholder="t('tennisThrowPlaceholder')"
class="input-width"
/>
<el-input v-model="formData.tennis_throw" clearable :placeholder="t('tennisThrowPlaceholder')"
class="input-width" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="t('tenMeterShuttleRun')">
<el-input
v-model="formData.ten_meter_shuttle_run"
clearable
:placeholder="t('tenMeterShuttleRunPlaceholder')"
class="input-width"
/>
<el-input v-model="formData.ten_meter_shuttle_run" clearable
:placeholder="t('tenMeterShuttleRunPlaceholder')" class="input-width" />
</el-form-item>
</el-col>
</el-row>
</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
>
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{ t('confirm') }}</el-button>
</span>
</template>
</el-dialog>
@ -214,7 +165,7 @@ const initialFormData = {
student_id: '',
height: '',
weight: '',
coach_id: '',
// coach_id: '',
seated_forward_bend: '',
sit_ups: '',
push_ups: '',
@ -236,18 +187,18 @@ const formRules = computed(() => {
resource_id: [
{ required: true, message: t('resourceIdPlaceholder'), trigger: 'blur' },
],
student_id: [
{ required: true, message: t('studentIdPlaceholder'), trigger: 'blur' },
],
// student_id: [
// { required: true, message: t('studentIdPlaceholder'), trigger: 'blur' },
// ],
height: [
{ required: true, message: t('heightPlaceholder'), trigger: 'blur' },
],
weight: [
{ required: true, message: t('weightPlaceholder'), trigger: 'blur' },
],
coach_id: [
{ required: true, message: t('coachIdPlaceholder'), trigger: 'blur' },
],
// coach_id: [
// { required: true, message: t('coachIdPlaceholder'), trigger: 'blur' },
// ],
seated_forward_bend: [
{
required: true,

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 :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 :label="t('executionRules')" prop="execution_rules">
@ -28,7 +36,7 @@
v-for="(item, index) in staff_reminderList"
:key="index"
:label="item.name"
:value="Number(item.value)"
:value="item.value"
/>
</el-select>
</el-form-item>
@ -40,7 +48,7 @@
v-for="(item, index) in customer_reminderList"
:key="index"
:label="item.name"
:value="Number(item.value)"
:value="item.value"
/>
</el-select>
</el-form-item>
@ -52,14 +60,14 @@
v-for="(item, index) in customer_confirmationList"
:key="index"
:label="item.name"
:value="Number(item.value)"
:value="item.value"
/>
</el-select>
</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-form-item> -->
</el-form-item>
<el-form-item :label="t('status')" prop="status">
<el-select class="input-width" v-model="formData.status" clearable :placeholder="t('statusPlaceholder')">
@ -109,7 +117,7 @@ const initialFormData = {
staff_reminder: '',
customer_reminder: '',
customer_confirmation: '',
// customer_feedback: '',
customer_feedback: '',
status: '',
}
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([])
const staff_reminderDictList = async () => {
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-input v-model="serviceTable.searchParam.service_name" :placeholder="t('serviceNamePlaceholder')" />
</el-form-item>
<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 :label="t('status')" prop="status">
<el-select class="w-[280px]" v-model="serviceTable.searchParam.status" clearable :placeholder="t('statusPlaceholder')">
<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="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"/>
@ -109,6 +125,11 @@ const searchFormRef = ref<FormInstance>()
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_reminderDictList = async () => {
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":"",
"created_at":[],
"member_label":'',
"class_id": route.query.class_id ?? ''
}
})

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

@ -468,25 +468,44 @@ const searchPerson = async () => {
}
try {
// ID
const currentSelectedIds = [...selectedStudentIds.value]
const currentSelectedStudents = [...selectedStudents.value]
//
const previousTrialStudents = [...trialStudents.value]
const response = await getResourceByNameOrPhone({
name: searchKeyword.value.trim()
})
if (response.data) {
// ID
const currentSelectedIds = [...selectedStudentIds.value]
//
const newTrialStudents = response.data || []
trialStudents.value = response.data || []
students.value = trialStudents.value
// 使Map
const studentMap = new Map()
// checkedtrue
//
const checkedStudents = students.value.filter(student => student.checked === true)
//
previousTrialStudents.forEach(student => {
studentMap.set(student.id, student)
})
// id
newTrialStudents.forEach(student => {
studentMap.set(student.id, student)
})
// 使
//
trialStudents.value = Array.from(studentMap.values())
students.value = trialStudents.value
//
selectedStudentIds.value = currentSelectedIds
selectedStudents.value = currentSelectedStudents
// checked
const checkedStudents = students.value.filter(student => student.checked === true)
if (checkedStudents.length > 0) {
checkedStudents.forEach(student => {
if (!selectedStudentIds.value.includes(student.id)) {

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

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

BIN
niucloud/app.zip

Binary file not shown.

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

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

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

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

2
niucloud/app/adminapi/controller/course/Course.php

@ -68,6 +68,7 @@ class Course extends BaseAdminController
["internal_reminder", 0],
["customer_reminder", 0],
["remarks", ""],
["gift_session_count ", ""],
]);
$this->validate($data, 'app\validate\course\Course.add');
@ -93,6 +94,7 @@ class Course extends BaseAdminController
["customer_reminder", 0],
["remarks", ""],
["contract_id",""],
["gift_session_count ",""],
]);
$this->validate($data, 'app\validate\course\Course.edit');
(new CourseService())->edit($id, $data);

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

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

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

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

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

@ -28,11 +28,9 @@ class PersonCourseSchedule extends BaseAdminController
*/
public function lists(){
$data = $this->request->params([
["person_id",""],
["person_type",""],
["schedule_id",""],
["course_date",""],
["time_slot",""]
["name",""],
["phone_number",""],
["campus_name",""]
]);
return success((new PersonCourseScheduleService())->getPage($data));
}
@ -52,9 +50,12 @@ class PersonCourseSchedule extends BaseAdminController
*/
public function add(){
$data = $this->request->params([
["resources_id",0],
["person_id",0],
["person_type",""],
["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');
$id = (new PersonCourseScheduleService())->add($data);
@ -68,8 +69,11 @@ class PersonCourseSchedule extends BaseAdminController
*/
public function edit(int $id){
$data = $this->request->params([
["resources_id",0],
["schedule_id",0]
["person_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');
@ -84,13 +88,18 @@ class PersonCourseSchedule extends BaseAdminController
*/
public function del(int $id){
(new PersonCourseScheduleService())->del($id);
return success('DELETE_SUCCESS');
return success('请假成功');
}
/**
* 获取试课人员
*/
public function getTryCoursePerson($schedule_id){
return success((new PersonCourseScheduleService())->getTryCoursePerson($schedule_id));
public function xk(int $id){
(new PersonCourseScheduleService())->xk($id);
return success('销课成功');
}
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",""],
["created_at",["",""]],
['member_label', 0],
["class_id",""]
]);
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(){
// $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([
['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\AdminCheckToken;
use app\adminapi\middleware\AdminLog;
// USER_CODE_BEGIN -- market_performance
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\AdminCheckToken;
use app\adminapi\middleware\AdminLog;
// USER_CODE_BEGIN -- person_course_schedule
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::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([
AdminCheckToken::class,
AdminCheckRole::class,

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

@ -16,6 +16,7 @@ use app\adminapi\middleware\AdminCheckToken;
use app\adminapi\middleware\AdminLog;
// USER_CODE_BEGIN -- service
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('scsjtj', 'sys.System/scsjtj');
})->middleware([
AdminCheckToken::class,
AdminCheckRole::class,

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

@ -131,6 +131,9 @@ class CustomerResources extends BaseApiService
"distance" => $request->param('distance', ''),//距离
"communication" => $request->param('communication', ''),//沟通备注
"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){
@ -139,6 +142,10 @@ class CustomerResources extends BaseApiService
}
}
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 === ''){
return fail("缺少必填项{$k}");
}

42
niucloud/app/api/controller/login/Login.php

@ -12,6 +12,7 @@
namespace app\api\controller\login;
use app\dict\member\MemberLoginTypeDict;
use app\model\order_table\OrderTable;
use app\model\sys\SysConfig;
use app\service\admin\sys\SystemService;
use app\service\api\captcha\CaptchaService;
@ -138,43 +139,8 @@ class Login extends BaseController
}
public function test(){
$pay_config = Db::name("campus_pay")->where(['campus_id' => 1])->find();
$sysConfig = new SysConfig();
$vx_config = $sysConfig->where(['config_key' => 'WECHAT'])->value("value");
$config = [
// 必填-商户号
'mch_id' => $pay_config['mchid'],
// 必填-商户私钥 字符串或路径
'mch_secret_cert' => $pay_config['apiclient_cert'],
// 必填-商户公钥证书路径
'mch_public_cert_path' => $pay_config['apiclient_key'],
// 必填
'notify_url' => 'https://zh.hnhbty.cn/api/pay/qrcodenotify',
// 选填-公众号 的 app_id
'mp_app_id' => $vx_config['app_id'],
// 选填-小程序 的 app_id
'mini_app_id' => '',
'mch_secret_key' => $pay_config['pay_sign_key'],
];
$params = [
'out_trade_no' => '123123',
'body' => '测试',
'money' => 100,
];
$pay = new PayLoader('Wechatpay', $config);
$url = $pay->scan($params);
$path = qrcode(
$url['code_url'],
'',
[],
'upload/qrcode/pay/'
);
echo "<img src='/" . $path . "'>";die;
$order = new OrderTable();
$order_info = $order->where(['id' => 8])->find();
event('Student', ['event_type' => 'add','order_info' => $order_info]);
}
}

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\UploadService;
use core\base\BaseApiController;
use think\Request;
use think\Response;
class Upload extends BaseApiController
@ -24,12 +25,15 @@ class Upload extends BaseApiController
* 图片上传
* @return Response
*/
public function image(){
public function image(Request $request){
$extraData = $request->all();
$data = $this->request->params([
['file', 'file'],
]);
$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验证的
Route::group(function () {
//上传图片
//员工端-上传图片
Route::post('uploadImage', 'upload.Upload/image');
//员工端详情
Route::get('personnel/info', 'apiController.Personnel/info');

3
niucloud/app/event.php

@ -113,6 +113,9 @@ $system_event = [
//计算业绩
'CalculatePerformance' => [ 'app\listener\personnel\CalculatePerformance' ],
//学员
'Student' => [ 'app\listener\personnel\Student' ],
],
'subscribe' => [
],

124
niucloud/app/listener/personnel/Student.php

@ -0,0 +1,124 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\listener\personnel;
use app\model\class_resources_rel\ClassResourcesRel;
use app\model\course\Course;
use app\model\course_schedule\CourseSchedule;
use app\model\customer_resources\CustomerResources;
use app\model\order_table\OrderTable;
use app\model\student_course_usage\StudentCourseUsage;
use app\model\student_courses\StudentCourses;
use think\facade\Db;
/**
* 学员
*/
class Student
{
protected $personnel;
public function handle(array $params)
{
if ($params['event_type'] === 'add') {
$this->studentAdd($params['data']);
}
if ($params['event_type'] === 'xiaoke') {
$this->studentXiaoke($params['data']);
}
}
public function studentXiaoke($data){
$courseSchedule = new CourseSchedule();
$studentCourses = new StudentCourses();
$student_course_usage = new StudentCourseUsage();
$schedule_info = $courseSchedule->where(['id' => $data['schedule_id']])->find();
$studentCourses_info = $studentCourses->where(['student_id' => $data['student_id'],'course_id' => $schedule_info['course_id']])->find();
$student_course_usage->insert([
'student_course_id' => $studentCourses_info['id'],
'used_hours' => $studentCourses_info['single_session_count'],
'usage_date' => date("Y-m-d")
]);
}
public function studentAdd($order_info){
$student = new \app\model\student\Student();
$order = new OrderTable();
$cust = new CustomerResources();
$class_resources_rel = new ClassResourcesRel();
$course = new Course();
$studentCourses = new StudentCourses();
$order_count = $order->where(['resource_id' => $order_info['resource_id']])->count();
$cust_info = $cust->where(['id' => $order_info['resource_id']])->find();
//创建学员关系逻辑
if($order_count <= 1){
$sex_arr = ['male' => 1, 'female' => 2, 'other' => 0];
//首次支付创建学员
$student_id = $student->insertGetId([
'name' => $cust_info['name'],
'gender' => $sex_arr[$cust_info['gender']],
'age' => $cust_info['age'],
'campus_id' => $cust_info['campus'],
'class_id' => $order_info['class_id'],
'status' => 1,
'user_id' => $order_info['resource_id']
]);
}else{
$student_id = $student->where(['user_id' => $order_info['resource_id'],'class_id' => $order_info['class_id']])->value('id');
}
//学员课程逻辑
$course_info = $course->where(['id' => $order_info['course_id']])->find();
$studentCourses->insert([
'student_id' => $student_id,
'course_id' => $order_info['course_id'],
'total_hours' => $course_info['session_count'],
'gift_hours' => $course_info['gift_session_count'],
'start_date' => date("Y-m-d"),
'end_date' => date("Y-m-d", strtotime("+30 days")),
'single_session_count' => $course_info['single_session_count']
]);
//班级资源关系逻辑
$is_rel = $class_resources_rel->where(
['resource_id' => $order_info['resource_id'],'class_id' => $order_info['class_id']]
)->find();
if($is_rel){
$class_resources_rel->where(['id' => $is_rel['id']])->update(['status' => 2]);
}else{
$class_resources_rel->insert([
'class_id' => $order_info['class_id'],
'resource_id' => $order_info['resource_id'],
'campus_id' => $cust_info['campus'],
'source_type' => 'student',
'join_time' => time(),
'status' => 1,
'create_time' => date("Y-m-d H:i:s"),
'update_time' => date("Y-m-d H:i:s")
]);
}
}
}

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

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

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

@ -11,14 +11,12 @@
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 think\model\concern\SoftDelete;
use think\model\relation\HasMany;
use think\model\relation\HasOne;
use app\model\customer_resources\CustomerResources;
/**
* 人员与课程安排关系模型
* Class PersonCourseSchedule
@ -26,6 +24,8 @@ use think\model\relation\HasOne;
*/
class PersonCourseSchedule extends BaseModel
{
/**
* 数据表主键
* @var string
@ -38,20 +38,9 @@ class PersonCourseSchedule extends BaseModel
*/
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 $data
*/
@ -62,68 +51,13 @@ class PersonCourseSchedule extends BaseModel
}
}
/**
* 搜索器:人员与课程安排关系人员类型: 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()
{
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');
public function customerResources(){
return $this->hasOne(CustomerResources::class, 'id', 'person_id')->joinType('left')->withField('name,id')->bind(['person_id_name'=>'name']);
}
}

9
niucloud/app/service/admin/auth/AuthService.php

@ -11,6 +11,8 @@
namespace app\service\admin\auth;
use app\model\campus_person_role\CampusPersonRole;
use app\model\personnel\Personnel;
use app\Request;
use app\service\admin\sys\MenuService;
use app\service\admin\sys\RoleService;
@ -91,7 +93,12 @@ class AuthService extends BaseAdminService
if ($is_admin) {//查询全部启用的权限
return ( new MenuService() )->getAllMenuList($status, $is_tree, $is_button);
} else {
$user_role_ids = $user_info[ 'role_ids' ];
$per = new Personnel();
$CampusPersonRole = new CampusPersonRole();
$per_id = $per->where(['sys_user_id' => $this->uid])->column('id');
$user_role_ids = $CampusPersonRole->where(['person_id' => $per_id])->column('role_id');
//
$role_service = new RoleService();
$menu_keys = $role_service->getMenuKeysByRoleIds($user_role_ids ?? []);
return $menu_service->getMenuListByMenuKeys($menu_keys, $is_tree, is_button:$is_button);

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

2
niucloud/app/service/admin/campus_person_role/CampusPersonRoleService.php

@ -93,6 +93,8 @@ class CampusPersonRoleService extends BaseAdminService
public function add(array $data)
{
$res = $this->model->create($data);
return $res->id;
}

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

2
niucloud/app/service/admin/course_schedule/CourseScheduleService.php

@ -109,7 +109,7 @@ class CourseScheduleService extends BaseAdminService
'time_slot' => $data['time_slot'],
'course_id' => $data['course_id'],
'coach_id' => $data['coach_id'],
'auto_schedule' => $data['is_system_add']
'auto_schedule' => $data['auto_schedule']
];
$status = $this->model->where([
['course_date', '=', $data['course_date']],

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

2
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';
$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);
return $list;
}

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

@ -11,6 +11,7 @@
namespace app\service\admin\person_course_schedule;
use app\model\course\Course;
use app\model\course_schedule\CourseSchedule;
use app\model\customer_resources\CustomerResources;
use app\model\person_course_schedule\PersonCourseSchedule;
@ -38,14 +39,37 @@ class PersonCourseScheduleService extends BaseAdminService
* @param array $where
* @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,deleted_at';
$order = 'id desc';
$order = 'a.id desc';
$where = [];
if($data['name']){
$where[] = ['b.name','=',$data['name']];
}
$search_model = $this->model->withSearch(["id", "person_id", "person_type", "schedule_id", "course_date", "time_slot"], $where)->field($field)->order($order);
$list = $this->pageQuery($search_model);
return $list;
if($data['phone_number']){
$where[] = ['b.phone_number','=',$data['phone_number']];
}
if($data['campus_name']){
$where[] = ['c.campus_name','=',$data['campus_name']];
}
$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;
});
}
/**
@ -57,7 +81,7 @@ class PersonCourseScheduleService extends BaseAdminService
{
$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;
}
@ -194,4 +218,14 @@ class PersonCourseScheduleService extends BaseAdminService
}
return $data;
}
public function xk(int $id){
$data = $this->model->where([['id', '=', $id]])->find();
event('Student', ['event_type' => 'xiaoke','data' => $data]);
return true;
}
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';
$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) {
$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 app\job\sys\CheckJob;
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\market_performance\MarketPerformance;
use app\model\personnel\Personnel;
use app\model\student\Student;
use app\model\sys\SysConfig;
@ -285,4 +288,58 @@ class SystemService extends BaseAdminService
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']);
}
$data = $model->paginate([
$data = $model
->with([
'personnel',
'customer',
])
->paginate([
'list_rows' => $limit,
'page' => $page,
])->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_resources\CustomerResources;
use app\model\dict\Dict;
use app\model\member\Member;
use app\model\personnel\Personnel;
use app\model\resource_sharing\ResourceSharing;
use app\model\six_speed\SixSpeed;
@ -122,10 +123,47 @@ class CustomerResourcesService extends BaseApiService
//开启事物
Db::startTrans();
try {
$customer_resources = CustomerResources::where('id', $where['id'])->find();
$six_speed = SixSpeed::where('resource_id', $where['id'])->find();
if ($customer_resources) {
$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);//客户资源表
if (!$update_1) {
@ -157,7 +195,6 @@ class CustomerResourcesService extends BaseApiService
$six_speed_data['resource_id'] = $where['id'];
//查六要素是否存在
$six_speed = SixSpeed::where('resource_id', $where['id'])->find();
if ($six_speed) {
$six_speed = $six_speed->toArray();
//更新六要素

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

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

37
niucloud/app/service/api/pay/PayService.php

@ -166,9 +166,7 @@ class PayService extends BaseApiService
public function qrcodeNotify($data,$order_id)
{
$student = new Student();
$order = new OrderTable();
$cust = new CustomerResources();
$order_info = $order->where(['id' => $order_id])->find();
if($order_info['order_status'] == 'pending' and !empty($order_info['ipv3'])){
$resource = $data['resource'];
@ -182,39 +180,8 @@ class PayService extends BaseApiService
$order->where(['payment_id' => $info['out_trade_no']])->update(['order_status' => 'paid','payment_time' => date("Y-m-d H:i:s")]);
$order_count = $order->where(['resource_id' => $order_info['resource_id']])->count();
$cust_info = $cust->where(['id' => $order_info['resource_id']])->find();
if($order_count <= 1){
$sex_arr = ['male' => 1, 'female' => 2, 'other' => 0];
//首次支付创建学员
$student->insert([
'name' => $cust_info['name'],
'gender' => $sex_arr[$cust_info['gender']],
'age' => $cust_info['age'],
'campus_id' => $cust_info['campus'],
'class_id' => $order_info['class_id'],
'status' => 1,
'user_id' => $order_info['resource_id']
]);
}
$is_rel = Db::name("class_resources_rel")->where(
['resource_id' => $order_info['resource_id'],'class_id' => $order_info['class_id']]
)->find();
if($is_rel){
Db::name("class_resources_rel")->where(['id' => $is_rel['id']])->update(['status' => 2]);
}else{
Db::name("class_resources_rel")->insert([
'class_id' => $order_info['class_id'],
'resource_id' => $order_info['resource_id'],
'campus_id' => $cust_info['campus'],
'source_type' => 'student',
'join_time' => time(),
'status' => 1,
'create_time' => date("Y-m-d H:i:s"),
'update_time' => date("Y-m-d H:i:s")
]);
}
event('Student', ['event_type' => 'add','data' => $order_info]);
}
}

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

@ -34,9 +34,9 @@ class UploadService extends BaseApiService
* @return array
* @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();
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 = [
'resources_id' => 'require',
'schedule_id' => 'require'
'person_id' => 'require',
'person_type' => 'require',
'schedule_id' => 'require',
'course_date' => 'require',
'time_slot' => 'require',
];
protected $message = [
'resources_id.require' => ['common_validate.require', ['person_id']],
'schedule_id.require' => ['common_validate.require', ['schedule_id']]
'person_id.require' => ['common_validate.require', ['person_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 = [
"add" => ['resources_id', 'schedule_id'],
"edit" => ['resources_id', 'schedule_id']
"add" => ['person_id', 'person_type', 'schedule_id', 'course_date', 'time_slot'],
"edit" => ['person_id', 'person_type', 'schedule_id', 'course_date', 'time_slot']
];
}

10
node_modules/.yarn-integrity

@ -0,0 +1,10 @@
{
"systemParams": "win32-x64-108",
"modulesFolders": [],
"flags": [],
"linkedModules": [],
"topLevelPatterns": [],
"lockfileEntries": {},
"files": [],
"artifacts": {}
}

4
yarn.lock

@ -0,0 +1,4 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
Loading…
Cancel
Save