Browse Source

Merge remote-tracking branch 'origin/master'

master
liutong 10 months ago
parent
commit
85a44559b1
  1. 13
      admin/src/app/api/service_logs.js
  2. 141
      admin/src/app/views/customer_resources/components/UserProfile.vue
  3. 15
      admin/src/app/views/customer_resources/customer_resources.vue
  4. 14
      admin/src/app/views/school_approval/process/index.vue
  5. 165
      admin/src/app/views/service_logs/service_logs.vue
  6. 88
      admin/src/app/views/student_course_usage/student_course_usage.vue
  7. 10
      niucloud/app/adminapi/controller/school_approval/Process.php
  8. 39
      niucloud/app/adminapi/controller/service_logs/ServiceLogs.php
  9. 6
      niucloud/app/adminapi/controller/student_course_usage/StudentCourseUsage.php
  10. 31
      niucloud/app/adminapi/route/service_logs.php
  11. 18
      niucloud/app/api/controller/apiController/ClassApi.php
  12. 7
      niucloud/app/api/controller/apiController/TeachingResearch.php
  13. 2
      niucloud/app/api/route/route.php
  14. 11
      niucloud/app/model/class_grade/ClassGrade.php
  15. 57
      niucloud/app/model/class_personnel_rel/ClassPersonnelRel.php
  16. 44
      niucloud/app/model/service_logs/ServiceLogs.php
  17. 4
      niucloud/app/service/admin/customer_resources/CustomerResourcesService.php
  18. 60
      niucloud/app/service/admin/service_logs/ServiceLogsService.php
  19. 28
      niucloud/app/service/admin/student_course_usage/StudentCourseUsageService.php
  20. 102
      niucloud/app/service/api/apiService/jlClassService.php
  21. 24
      niucloud/app/service/school_approval/SchoolApprovalProcessService.php

13
admin/src/app/api/service_logs.js

@ -0,0 +1,13 @@
import request from '@/utils/request'
// USER_CODE_BEGIN -- service_logs
/**
*
* @param params
* @returns
*/
export function getServiceLogsList(params) {
return request.get(`service_logs/service_logs`, {params})
}

141
admin/src/app/views/customer_resources/components/UserProfile.vue

@ -0,0 +1,141 @@
<template>
<el-dialog
v-model="showDialog"
title="客户详情"
width="80%"
class="user-profile p-6"
:destroy-on-close="true"
>
<!-- 顶部用户信息 -->
<el-card class="mb-4">
<div class="flex items-center">
<el-avatar :size="60" class="mr-4" />
<div>
<h2 class="text-xl font-bold">{{ user.name }}</h2>
<p>ID: {{ user.id }}</p>
<p>电话: {{ user.phone }}</p>
</div>
</div>
</el-card>
<!-- 标签导航 -->
<el-tabs v-model="activeTab" class="mb-4">
<el-tab-pane label="六要素" name="six-elements" />
<el-tab-pane label="修改日志" name="log" />
<el-tab-pane label="学生情况" name="student" />
<el-tab-pane label="订单列表" name="orders" />
<el-tab-pane label="课程列表" name="courses" />
</el-tabs>
<!-- 六要素信息卡片 -->
<el-card v-if="activeTab === 'six-elements'">
<h3 class="text-lg font-bold mb-4">六要素信息</h3>
<el-row :gutter="20" class="mb-2">
<el-col :span="8">需求购买力<el-tag>{{ info.purchasePower }}</el-tag></el-col>
<el-col :span="8">认知理念<el-tag>{{ info.knowledge }}</el-tag></el-col>
<el-col :span="8">距离<span>{{ info.distance }}</span></el-col>
</el-row>
<el-row :gutter="20" class="mb-2">
<el-col :span="8">可谈上课时间<span>{{ info.canTalkDate }}</span></el-col>
<el-col :span="8">承诺到访时间<span>{{ info.promisedVisitDate }}</span></el-col>
<el-col :span="8">实际到访时间<span>{{ info.actualVisitDate }}</span></el-col>
</el-row>
<el-row :gutter="20" class="mb-2">
<el-col :span="8">电话后的意向程度<el-tag>{{ info.phoneIntention }}</el-tag></el-col>
<el-col :span="8">是否关单
<el-tag :type="info.isClosed ? 'success' : 'danger'">{{ info.isClosed ? '是' : '否' }}</el-tag>
</el-col>
</el-row>
<!-- 备注与访问情况 -->
<el-form label-position="top" class="mt-4">
<el-form-item label="沟通备注">
<el-input v-model="info.notes" placeholder="填写备注" disabled/>
</el-form-item>
<el-form-item label="一访情况">
<el-input v-model="info.visit1" placeholder="填写一访情况" disabled/>
</el-form-item>
<el-form-item label="二访情况">
<el-input v-model="info.visit2" placeholder="填写二访情况" disabled/>
</el-form-item>
</el-form>
</el-card>
</el-dialog>
</template>
<script setup>
import { useDictionary } from '@/app/api/dict'
import { ref, reactive, computed, watch } from 'vue'
let showDialog = ref(false)
const activeTab = ref('six-elements')
const user = reactive({
name: '王五1',
id: 'U001',
phone: '13914556707'
})
const info = reactive({
purchasePower: '',
knowledge: '',
distance: '',
canTalkDate: '',
promisedVisitDate: '',
actualVisitDate: '',
phoneIntention: '',
isClosed: '',
notes: '',
visit1: '',
visit2: ''
})
let call_intentList = ref([])
let purchase_powerList = ref([])
let concept_awarenessList = ref([])
const setFormData = async (row) => {
call_intentList.value = await (
await useDictionary('preliminarycustomerintention')
).data.dictionary
purchase_powerList.value = await (
await useDictionary('customer_purchasing_power')
).data.dictionary
concept_awarenessList.value = await (
await useDictionary('cognitive_concept')
).data.dictionary
user.name = row.name;
user.id = row.id;
user.phone = row.phone_number;
info.purchasePower = purchase_powerList.value.flat().find(item => item.value == row.six.purchase_power)?.name || '';
info.knowledge = concept_awarenessList.value.flat().find(item => item.value == row.six.concept_awareness)?.name || '';
info.distance = row.six.distance;
info.canTalkDate = row.six.preferred_class_time;
info.promisedVisitDate = row.six.promised_visit_time;
info.actualVisitDate = row.six.actual_visit_time;
info.phoneIntention = call_intentList.value.flat().find(item => item.value == row.six.call_intent)?.name || '';
info.isClosed = row.six.is_closed == 1 ? true : false;
info.notes = row.six.communication;
info.visit1 = row.six.first_visit_status;
info.visit2 = row.six.second_visit_status;
console.log(call_intentList.value);
}
defineExpose({
showDialog,
setFormData
})
</script>
<style scoped>
.user-profile {
margin: 0 auto;
}
</style>

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

@ -127,6 +127,9 @@
<el-dropdown-item command="resourceChanges">
客户信息修改记录
</el-dropdown-item>
<el-dropdown-item command="UserProfile">
客户详情
</el-dropdown-item>
<el-dropdown-item command="editEvent">
{{ t('edit') }}
</el-dropdown-item>
@ -180,6 +183,7 @@
<tc ref="TcCustomerResourcesDialog" @complete="loadCustomerResourcesList" />
<user ref="UserProfileDialog" @complete="loadCustomerResourcesList" />
</el-card>
</div>
</template>
@ -195,6 +199,8 @@
import Fp from '@/app/views/customer_resources/components/fp.vue'
import Order from '@/app/views/order_table/components/order-table-edit.vue'
import Tc from '@/app/views/tc_dialog/tc_dialog.vue'
import User from '@/app/views/customer_resources/components/UserProfile.vue'
import { ArrowDown } from '@element-plus/icons-vue'
import { getMemberLabelAll } from '@/app/api/member'
@ -244,6 +250,9 @@
case 'deleteEvent':
deleteEvent(row.id)
break
case 'UserProfile':
UserProfile(row)
break
}
}
@ -278,6 +287,7 @@
}
const TcCustomerResourcesDialog : Record<string, any> | null = ref(null)
const tcEvent = (row : any) => {
TcCustomerResourcesDialog.value.setFormData(row)
@ -290,7 +300,12 @@
}
const UserProfileDialog : Record<string, any> | null = ref(null)
const UserProfile = (row : any) => {
UserProfileDialog.value.setFormData(row)
UserProfileDialog.value.showDialog = true
}
const searchFormRef = ref<FormInstance>()

14
admin/src/app/views/school_approval/process/index.vue

@ -52,9 +52,9 @@
>
<el-table-column :label="'ID'" prop="id" width="80" />
<el-table-column :label="'流程名称'" prop="process_name" min-width="180" />
<el-table-column :label="'申请人ID'" prop="applicant_id" width="100" />
<el-table-column :label="'申请人'" prop="applicant_name" width="100" />
<el-table-column :label="'申请时间'" prop="application_time" width="180" />
<el-table-column :label="'当前审批人ID'" prop="current_approver_id" width="100" />
<el-table-column :label="'当前审批人'" prop="current_approver_name" width="100" />
<el-table-column :label="'审批状态'" prop="approval_status" width="100">
<template #default="{ row }">
<el-tag :type="getStatusType(row.approval_status)">
@ -202,14 +202,14 @@
<el-descriptions-item :label="'流程名称'">
{{ state.detailDialog.info.process_name }}
</el-descriptions-item>
<el-descriptions-item :label="'申请人ID'">
{{ state.detailDialog.info.applicant_id }}
<el-descriptions-item :label="'申请人'">
{{ state.detailDialog.info.applicant_name }}
</el-descriptions-item>
<el-descriptions-item :label="'申请时间'">
{{ state.detailDialog.info.application_time }}
</el-descriptions-item>
<el-descriptions-item :label="'当前审批人ID'">
{{ state.detailDialog.info.current_approver_id }}
<el-descriptions-item :label="'当前审批人'">
{{ state.detailDialog.info.current_approver_name }}
</el-descriptions-item>
<el-descriptions-item :label="'审批状态'">
<el-tag :type="getStatusType(state.detailDialog.info.approval_status)">
@ -237,7 +237,7 @@
{{ '参与者' + (index + 1) }}
</div>
<div class="text-gray-500">
{{ '参与者ID' }}{{ node.participant_id }}
{{ '参与者' }}{{ node.name }}
</div>
<div class="text-gray-500">
{{ '顺序' }}{{ node.sequence }}

165
admin/src/app/views/service_logs/service_logs.vue

@ -0,0 +1,165 @@
<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>
</div>
<el-card
class="box-card !border-none my-[10px] table-search-wrap"
shadow="never"
>
<el-form
:inline="true"
:model="studentCourseUsageTable.searchParam"
ref="searchFormRef"
>
<el-form-item label="家长姓名" prop="name">
<el-input
v-model="studentCourseUsageTable.searchParam.name"
placeholder="请输入家长姓名"
/>
</el-form-item>
<el-form-item label="评分" prop="score">
<el-input
v-model="studentCourseUsageTable.searchParam.score"
placeholder="请输入评分"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="loadServiceLogsList()">{{
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="studentCourseUsageTable.data"
size="large"
v-loading="studentCourseUsageTable.loading"
>
<template #empty>
<span>{{
!studentCourseUsageTable.loading ? t('emptyData') : ''
}}</span>
</template>
<el-table-column prop="name" label="家长姓名" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="staff_name" label="教练姓名" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="service_name" label="服务内容" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="customer_confirmation" label="是否需要反馈" min-width="120" :show-overflow-tooltip="true">
<template #default="{ row }">
<div v-if="row.customer_confirmation == 1"></div>
<div v-if="row.customer_confirmation == 0"></div>
</template>
</el-table-column>
<el-table-column prop="score" label="反馈分数" min-width="120" :show-overflow-tooltip="true"/>
</el-table>
<div class="mt-[16px] flex justify-end">
<el-pagination
v-model:current-page="studentCourseUsageTable.page"
v-model:page-size="studentCourseUsageTable.limit"
layout="total, sizes, prev, pager, next, jumper"
:total="studentCourseUsageTable.total"
@size-change="loadServiceLogsList()"
@current-change="loadServiceLogsList"
/>
</div>
</div>
</el-card>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref, watch } from 'vue'
import { t } from '@/lang'
import { useDictionary } from '@/app/api/dict'
import {
getServiceLogsList,
} from '@/app/api/service_logs'
import { img } from '@/utils/common'
import { ElMessageBox, FormInstance } from 'element-plus'
import { useRoute } from 'vue-router'
const route = useRoute()
const pageName = route.meta.title
let studentCourseUsageTable = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {
name: '',
score: '',
},
})
const searchFormRef = ref<FormInstance>()
//
const selectData = ref<any[]>([])
//
/**
* 获取学员课时消费记录列表
*/
const loadServiceLogsList = (page: number = 1) => {
studentCourseUsageTable.loading = true
studentCourseUsageTable.page = page
getServiceLogsList({
page: studentCourseUsageTable.page,
limit: studentCourseUsageTable.limit,
...studentCourseUsageTable.searchParam,
})
.then((res) => {
studentCourseUsageTable.loading = false
studentCourseUsageTable.data = res.data.data
studentCourseUsageTable.total = res.data.total
})
.catch(() => {
studentCourseUsageTable.loading = false
})
}
loadServiceLogsList()
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
}
</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>

88
admin/src/app/views/student_course_usage/student_course_usage.vue

@ -3,9 +3,6 @@
<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('addStudentCourseUsage') }}
</el-button>
</div>
<el-card
@ -17,25 +14,28 @@
:model="studentCourseUsageTable.searchParam"
ref="searchFormRef"
>
<el-form-item :label="t('studentCourseId')" prop="student_course_id">
<el-form-item label="家长名称" prop="emergency_contact">
<el-input
v-model="studentCourseUsageTable.searchParam.student_course_id"
:placeholder="t('studentCourseIdPlaceholder')"
/>
</el-form-item>
<el-form-item :label="t('usedHours')" prop="used_hours">
<el-input
v-model="studentCourseUsageTable.searchParam.used_hours"
:placeholder="t('usedHoursPlaceholder')"
/>
</el-form-item>
<el-form-item :label="t('usageDate')" prop="usage_date">
<el-input
v-model="studentCourseUsageTable.searchParam.usage_date"
:placeholder="t('usageDatePlaceholder')"
v-model="studentCourseUsageTable.searchParam.emergency_contact"
placeholder="请输入家长名称"
/>
</el-form-item>
<el-form-item label="学生名称" prop="student_name">
<el-input
v-model="studentCourseUsageTable.searchParam.student_name"
placeholder="请输入学生名称"
/>
</el-form-item>
<el-form-item label="手机号" prop="contact_phone">
<el-input
v-model="studentCourseUsageTable.searchParam.contact_phone"
placeholder="请输入手机号"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="loadStudentCourseUsageList()">{{
t('search')
@ -58,41 +58,23 @@
!studentCourseUsageTable.loading ? t('emptyData') : ''
}}</span>
</template>
<el-table-column
prop="student_course_id"
:label="t('studentCourseId')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column
prop="used_hours"
:label="t('usedHours')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column prop="course_name" label="课程名称" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="student_name" label="学员姓名" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="emergency_contact" label="家长称呼" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="total_hours" label="课时数量" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="used_hours" label="消课数量" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="sy_time" label="剩余课时" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="gift_hours" label="赠送课时" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column
prop="usage_date"
:label="t('usageDate')"
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
@ -136,9 +118,9 @@ let studentCourseUsageTable = reactive({
loading: true,
data: [],
searchParam: {
student_course_id: '',
used_hours: '',
usage_date: '',
emergency_contact: '',
student_name: '',
contact_phone: '',
},
})

10
niucloud/app/adminapi/controller/school_approval/Process.php

@ -37,25 +37,25 @@ class Process extends BaseAdminController
$where = [];
if ($status !== '') {
$where[] = ['approval_status', '=', $status];
$where[] = ['a.approval_status', '=', $status];
}
$process_name = input('process_name', '');
if (!empty($process_name)) {
$where[] = ['process_name', 'like', "%{$process_name}%"];
$where[] = ['a.process_name', 'like', "%{$process_name}%"];
}
// 我发起的审批
$applicant_id = input('applicant_id', 0);
if (!empty($applicant_id)) {
$where[] = ['applicant_id', '=', $applicant_id];
$where[] = ['a.applicant_id', '=', $applicant_id];
}
// 待我审批的
$approver_id = input('approver_id', 0);
if (!empty($approver_id)) {
$where[] = ['current_approver_id', '=', $approver_id];
$where[] = ['approval_status', '=', 'pending'];
$where[] = ['a.current_approver_id', '=', $approver_id];
$where[] = ['a.approval_status', '=', 'pending'];
}
$data = $this->service->getList($where, (int)$page, (int)$limit);

39
niucloud/app/adminapi/controller/service_logs/ServiceLogs.php

@ -0,0 +1,39 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\adminapi\controller\service_logs;
use app\service\admin\service_logs\ServiceLogsService;
use core\base\BaseAdminController;
use app\service\admin\service\ServiceService;
/**
* 服务控制器
* Class Service
* @package app\adminapi\controller\service
*/
class ServiceLogs extends BaseAdminController
{
/**
* 获取服务列表
* @return \think\Response
*/
public function lists(){
$data = $this->request->params([
["name",""],
["score",""]
]);
return success((new ServiceLogsService())->getPage($data));
}
}

6
niucloud/app/adminapi/controller/student_course_usage/StudentCourseUsage.php

@ -28,9 +28,9 @@ class StudentCourseUsage extends BaseAdminController
*/
public function lists(){
$data = $this->request->params([
["student_course_id",""],
["used_hours",""],
["usage_date",""]
["emergency_contact",""],
["student_name",""],
["contact_phone",""]
]);
return success((new StudentCourseUsageService())->getPage($data));
}

31
niucloud/app/adminapi/route/service_logs.php

@ -0,0 +1,31 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
use think\facade\Route;
use app\adminapi\middleware\AdminCheckRole;
use app\adminapi\middleware\AdminCheckToken;
use app\adminapi\middleware\AdminLog;
// USER_CODE_BEGIN -- service
Route::group('service_logs', function () {
Route::get('service_logs', 'service_logs.ServiceLogs/lists');
})->middleware([
AdminCheckToken::class,
AdminCheckRole::class,
AdminLog::class
]);
// USER_CODE_END -- service

18
niucloud/app/api/controller/apiController/ClassApi.php

@ -12,7 +12,7 @@
namespace app\api\controller\apiController;
use app\Request;
use app\service\api\apiService\CourseService;
use app\service\api\apiService\jlClassService;
use core\base\BaseApiService;
@ -21,22 +21,24 @@ use core\base\BaseApiService;
* Class Personnel
* @package app\api\controller\apiController
*/
class ClassSpi extends BaseApiService
class ClassApi extends BaseApiService
{
//课程列表
public function jlClassList(Request $request){
$id = $this->member_id;
dd(111);
return success((new CourseService())->list($id,$data));
$data = $this->request->params([
["name",'']
]);
return success((new jlClassService())->list($id,$data));
}
//获取课程详情
public function courseInfo(Request $request){
//课程详情
public function jlClassInfo(Request $request){
$data = $this->request->params([
["id",0]
["class_id",0]
]);
return success('SUCCESS',(new CourseService())->info($data['id']));
return success('获取成功',(new jlClassService())->info($data['class_id']));
}
}

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

@ -115,10 +115,15 @@ class TeachingResearch extends BaseApiService
if ($resLessonTeaching['answers_num'] >= $res['number_answers']) {
return fail('已超过答题次数', []);
} else {
if (count($userRes['data']['cameus_dept_arr']) > 0) {
$campus_id = $userRes['data']['cameus_dept_arr'][0]['campus_id'];
} else {
$campus_id = 0;
}
foreach ($result as &$v){
$v['user_id'] = $userRes['data']['id'];
$v['question_id'] = $v['ids'];
$v['campus_id'] = 0;
$v['campus_id'] = $campus_id;
$v['answer'] = $v['value'];
$resEq = $ExamQuestions->where('id',$v['ids'])->find();
if ($resEq['correct_answer'] == $v['value']){

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

@ -294,6 +294,8 @@ Route::group(function () {
Route::get('course/delStudentCourse', 'apiController.course/delStudentCourse');
//班级列表
Route::get('class/jlClassList', 'apiController.classApi/jlClassList');
//班级详情
Route::get('class/jlClassInfo', 'apiController.classApi/jlClassInfo');
//课程列表
Route::get('course/courseList', 'apiController.course/courseList');
//获取课程详情

11
niucloud/app/model/class_grade/ClassGrade.php

@ -13,6 +13,7 @@ namespace app\model\class_grade;
use app\model\campus\Campus;
use app\model\personnel\Personnel;
use app\model\class_personnel_rel\ClassPersonnelRel;
use core\base\BaseModel;
use think\model\concern\SoftDelete;
use think\model\relation\HasMany;
@ -229,6 +230,16 @@ class ClassGrade extends BaseModel
return $this->hasOne(Personnel::class, 'id', 'head_coach')->joinType('left')->withField('name,id')->bind(['head_coach_name'=>'name']);
}
public function personnelAll(){
return $this->hasOne(Personnel::class, 'id', 'head_coach')->joinType('left')->withField('head_img,id')->bind(['head_coach_head_img'=>'head_img']);
}
public function personnelName(){
return $this->hasOne(Personnel::class, 'id', 'head_coach')->joinType('left')->withField('name,id')->bind(['head_coach_name'=>'name']);
}
public function classPersonnelRel(){
return $this->hasMany(ClassPersonnelRel::class, 'class_id', 'id');
}
}

57
niucloud/app/model/class_personnel_rel/ClassPersonnelRel.php

@ -0,0 +1,57 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\model\class_personnel_rel;
use core\base\BaseModel;
use think\model\concern\SoftDelete;
use think\model\relation\HasMany;
use think\model\relation\HasOne;
use app\model\student\Student;
use app\model\student_courses\StudentCourses;
use app\model\class_grade\ClassGrade;
use app\model\customer_resources\CustomerResources;
use app\model\campus\Campus;
class ClassPersonnelRel extends BaseModel
{
/**
* 数据表主键
* @var string
*/
protected $pk = 'id';
/**
* 模型名称
* @var string
*/
protected $name = 'class_personnel_rel';
public function student(){
return $this->hasOne(Student::class, 'id', 'source_id');
}
public function studentCourses(){
return $this->hasOne(StudentCourses::class, 'student_id', 'source_id')->joinType('left')->withField('end_date,student_id')->bind(['end_date'=>'end_date']);
}
public function studentCoursesInfo(){
return $this->hasOne(StudentCourses::class, 'student_id', 'source_id');
}
}

44
niucloud/app/model/service_logs/ServiceLogs.php

@ -0,0 +1,44 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\model\service_logs;
use core\base\BaseModel;
use think\model\concern\SoftDelete;
use think\model\relation\HasMany;
use think\model\relation\HasOne;
/**
* 服务模型
* Class Service
* @package app\model\service
*/
class ServiceLogs extends BaseModel
{
/**
* 数据表主键
* @var string
*/
protected $pk = 'id';
/**
* 模型名称
* @var string
*/
protected $name = 'service_logs';
}

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

@ -95,6 +95,10 @@ class CustomerResourcesService extends BaseAdminService
return $this->pageQuery($search_model, function ($item, $key) {
$item = $this->makeUp($item);
$sixSpeed = new SixSpeed();
$data = $sixSpeed->where(['resource_id' => $item['id']])->findOrEmpty()->toArray();
$item['six'] = $data;
});
}

60
niucloud/app/service/admin/service_logs/ServiceLogsService.php

@ -0,0 +1,60 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\service\admin\service_logs;
use app\model\service_logs\ServiceLogs;
use core\base\BaseAdminService;
/**
* 学员课时消费记录服务层
* Class StudentCourseUsageService
* @package app\service\admin\student_course_usage
*/
class ServiceLogsService extends BaseAdminService
{
public function __construct()
{
parent::__construct();
$this->model = new ServiceLogs();
}
/**
* 获取学员课时消费记录列表
* @return array
*/
public function getPage(array $data = [])
{
$where = [];
if($data['name']){
$where[] = ['b.name','like','%'.$data['name'].'%'];
}
if($data['score']){
$where[] = ['a.score','=',$data['score']];
}
$search_model = $this->model
->alias("a")
->join(['school_customer_resources' => 'b'],'a.resource_id = b.id','left')
->join(['school_personnel' => 'c'],'a.staff_id = c.id','left')
->join(['school_service' => 'd'],'a.service_id = d.id','left')
->where($where)
->field("a.*,b.name,c.name as staff_name,d.service_name,d.customer_confirmation")
->order("a.id desc");
$list = $this->pageQuery($search_model);
return $list;
}
}

28
niucloud/app/service/admin/student_course_usage/StudentCourseUsageService.php

@ -31,15 +31,31 @@ class StudentCourseUsageService extends BaseAdminService
/**
* 获取学员课时消费记录列表
* @param array $where
* @return array
*/
public function getPage(array $where = [])
public function getPage(array $data = [])
{
$field = 'id,student_course_id,used_hours,usage_date,created_at,updated_at';
$order = 'id desc';
$search_model = $this->model->withSearch(["id","student_course_id","used_hours","usage_date"], $where)->field($field)->order($order);
$where = [];
if($data['emergency_contact']){
$where[] = ['c.emergency_contact','like','%'.$data['emergency_contact'].'%'];
}
if($data['student_name']){
$where[] = ['c.name','like','%'.$data['student_name'].'%'];
}
if($data['contact_phone']){
$where[] = ['c.contact_phone','=',$data['contact_phone']];
}
$search_model = $this->model
->alias("a")
->join(['school_student_courses' => 'b'],'a.student_course_id = b.id','left')
->join(['school_student' => 'c'],'b.student_id = c.id','left')
->join(['school_course' => 'd'],'b.course_id = d.id','left')
->where($where)
->field("a.*,c.name as student_name,c.emergency_contact,d.course_name,b.total_hours,ROUND(b.total_hours - b.use_total_hours) as sy_time,ROUND(b.gift_hours - b.use_gift_hours) as gift_hours")
->order("a.id desc");
$list = $this->pageQuery($search_model);
return $list;
}

102
niucloud/app/service/api/apiService/jlClassService.php

@ -0,0 +1,102 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\service\api\apiService;
use app\model\class_grade\ClassGrade;
use core\base\BaseApiService;
/**
* 考勤管理服务层
* Class MemberService
* @package app\service\api\member
*/
class jlClassService extends BaseApiService
{
public function __construct()
{
parent::__construct();
$this->model = (new ClassGrade());
}
//列表
public function list($id,$data)
{
$order = 'id desc';
$where = [];
if ($data['name'] !== '') {
$where[] = ['name','like','%'.$data['name'].'%'];
}
$search_model = $this->model->where('head_coach', $id)->where($where)->order($order)
->with(['classPersonnelRel' => function($query) {
$query->with(['student' => function($query) {
$query->with(['customerResources' => function($query) {
$query->with(['member' => function($query) {
$query->select();
}]);
}]);
},'studentCourses']);
},'personnelAll']);
$list = $this->pageQuery($search_model);
foreach ($list['data'] as &$v){
if (count($v['classPersonnelRel']) > 0) {
$now = time();
$count = 0;
foreach ($v['classPersonnelRel'] as $item) {
if (isset($item['end_date'])) {
$endTime = strtotime($item['end_date']);
if ($endTime > $now && $endTime <= $now + 7 * 86400) {
$count++;
}
}
}
$v['end_count'] = $count;
} else {
$v['end_count'] = 0;
}
}
return $list;
}
public function info($data)
{
$search_model = $this->model->where('id', $data)
->with(['classPersonnelRel' => function($query) {
$query->with(['student' => function($query) {
$query->with(['customerResources' => function($query) {
$query->with(['member' => function($query) {
$query->select();
}]);
}]);
},'studentCourses','studentCoursesInfo']);
},'personnelAll', 'personnelName']);
$list = $search_model->find();
if (count($list['classPersonnelRel']) > 0) {
$now = time();
$count = 0;
foreach ($list['classPersonnelRel'] as $item) {
if (isset($item['end_date'])) {
$endTime = strtotime($item['end_date']);
if ($endTime > $now && $endTime <= $now + 7 * 86400) {
$count++;
}
}
}
$v['end_count'] = $count;
} else {
$v['end_count'] = 0;
}
return $list;
}
}

24
niucloud/app/service/school_approval/SchoolApprovalProcessService.php

@ -3,6 +3,7 @@ declare(strict_types=1);
namespace app\service\school_approval;
use app\model\personnel\Personnel;
use app\model\school_approval\SchoolApprovalConfig;
use app\model\school_approval\SchoolApprovalConfigNode;
use app\model\school_approval\SchoolApprovalParticipants;
@ -26,10 +27,13 @@ class SchoolApprovalProcessService
*/
public function getList(array $where = [], int $page = 1, int $limit = 10): array
{
$field = 'id, process_name, applicant_id, application_time, current_approver_id, approval_status, approval_time, remarks, created_at, updated_at';
$order = 'id desc';
$field = 'a.*,b.name as applicant_name,c.name as current_approver_name';
$order = 'a.id desc';
$list = (new SchoolApprovalProcess())
->alias("a")
->join(['school_personnel' => 'b'],'a.applicant_id = b.id','left')
->join(['school_personnel' => 'c'],'a.current_approver_id = c.id','left')
->where($where)
->field($field)
->order($order)
@ -52,12 +56,24 @@ class SchoolApprovalProcessService
*/
public function getInfo(int $id): array
{
$info = (new SchoolApprovalProcess())->with(['participants'])->where(['id' => $id])->find();
$info = (new SchoolApprovalProcess())
->alias("a")
->join(['school_personnel' => 'b'],'a.applicant_id = b.id','left')
->join(['school_personnel' => 'c'],'a.current_approver_id = c.id','left')
->with(['participants'])
->where(['a.id' => $id])
->field('a.*,b.name as applicant_name,c.name as current_approver_name')
->find();
if (empty($info)) {
return [];
}
$info = $info->toArray();
$Personnel = new Personnel();
foreach ($info['participants'] as $key => $value) {
$info['participants'][$key]['name'] = $Personnel->where(['id' => $value['participant_id']])->value('name');
}
return $info->toArray();
return $info;
}
/**

Loading…
Cancel
Save