Browse Source

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

master
王泽彦 9 months ago
parent
commit
88466dd169
  1. 22
      admin/src/app/api/course_schedule.ts
  2. 7
      admin/src/app/api/salary.ts
  3. 2
      admin/src/app/views/attendance/attendance.vue
  4. 12
      admin/src/app/views/contract/components/ff.vue
  5. 240
      admin/src/app/views/course_schedule/components/ff.vue
  6. 17
      admin/src/app/views/course_schedule/course_schedule.vue
  7. 18
      admin/src/app/views/order_table/order_table.vue
  8. 32
      admin/src/app/views/salary/salary.vue
  9. 31
      niucloud/app/adminapi/controller/course_schedule/CourseSchedule.php
  10. 3
      niucloud/app/adminapi/controller/order_table/OrderTable.php
  11. 9
      niucloud/app/adminapi/controller/salary/Salary.php
  12. 10
      niucloud/app/adminapi/route/course_schedule.php
  13. 5
      niucloud/app/adminapi/route/salary.php
  14. 19
      niucloud/app/service/admin/attendance/AttendanceService.php
  15. 59
      niucloud/app/service/admin/course_schedule/CourseScheduleService.php
  16. 13
      niucloud/app/service/admin/order_table/OrderTableService.php
  17. 12
      niucloud/app/service/admin/salary/SalaryService.php

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

@ -73,4 +73,26 @@ export function getCourseStudents(id: number) {
export function getResourceByNameOrPhone(params: Record<string, any>) {
return request.get(`customer_resources/personnel_all_byname`, { params })
}
// USER_CODE_END -- course_schedule
export function scheduleList(params: Record<string, any>) {
return request.get(`course_schedule/scheduleList`, { params })
}
export function resourceList(params: Record<string, any>) {
return request.get(`course_schedule/resourceList`, { params })
}
export function getCourseInfo(params: Record<string, any>) {
return request.get(`course_schedule/courseInfo`, { params })
}
export function addSchedule(params: Record<string, any>) {
return request.post('course_schedule/addSchedule', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
}

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

@ -55,6 +55,13 @@ export function deleteSalary(id: number) {
return request.delete(`salary/salary/${id}`, { showErrorMessage: true, showSuccessMessage: true })
}
export function ffSalary(id: number) {
return request.get(`salary/ffsalary/${id}`, { showErrorMessage: true, showSuccessMessage: true })
}
export function getWithPersonnelList(params: Record<string,any>){
return request.get('salary/personnel_all', {params})
}export function getWithDepartmentsList(params: Record<string,any>){

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

@ -75,6 +75,8 @@
</template>
<el-table-column prop="campus_id_name" :label="t('campusId')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="role_name" label="角色" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="staff_id_name" :label="t('staffId')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="attendance_date" :label="t('attendanceDate')" min-width="120" :show-overflow-tooltip="true"/>

12
admin/src/app/views/contract/components/ff.vue

@ -68,15 +68,17 @@
:total="lessonCourseTeachingTable.total" @size-change="loadLessonCourseTeachingList()"
@current-change="loadLessonCourseTeachingList" />
</div>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{ t('confirm') }}</el-button>
</span>
</template>
</div>
</el-tab-pane>

240
admin/src/app/views/course_schedule/components/ff.vue

@ -0,0 +1,240 @@
<template>
<el-dialog
v-model="showDialog"
title="课程安排"
width="50%"
class="diy-dialog-wrap"
:destroy-on-close="true"
>
<view class="detail-root">
<view class="section">
<view class="student-list">
<view
v-for="(stu, idx) in form.students"
:key="idx"
class="student-item"
>
<view class="avatar">{{ stu.name.charAt(0) }}</view>
<view class="info">
<view class="name">{{ stu.name }}</view>
<view class="desc">{{ getStatusText(stu.status) }}</view>
</view>
</view>
<view
v-for="n in form.courseInfo.available_capacity"
:key="'empty-' + n"
class="student-item empty"
@click="addStudent(n)"
>
<view class="avatar empty-avatar">+</view>
<view class="info">
<view class="name">空位</view>
<view class="desc">点击添加学员</view>
</view>
</view>
</view>
</view>
</view>
</el-dialog>
<!-- 选择资源弹窗 -->
<el-dialog v-model="showResourceDialog" title="选择资源" width="30%" :destroy-on-close="true">
<el-select v-model="selectedResourceId" placeholder="请选择资源" style="width: 100%;">
<el-option
v-for="item in form.resourceList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
<template #footer>
<el-button @click="showResourceDialog = false">取消</el-button>
<el-button type="primary" @click="confirmAddStudent">确定</el-button>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import { ref,reactive } from 'vue'
import {
scheduleList,
resourceList,
getCourseInfo,
addSchedule
} from '@/app/api/course_schedule'
const showResourceDialog = ref(false) //
const selectedResourceId = ref(null) // ID
const pendingAddIndex = ref(null) //
let showDialog = ref(false)
const loading = ref(false)
let form = reactive({
course_id: 0,
resource_id: 0,
students:[],
resourceList:[],
courseInfo:[]
})
const setFormData = async (course_id='',resource_id='') => {
form.course_id = course_id
form.resource_id = resource_id
init()
}
const init = async () => {
const data = await getCourseInfo({id:form.course_id});
form.courseInfo = data.data
const response = await scheduleList({schedule_id:form.course_id});
form.students = response.data
const res = await resourceList({});
form.resourceList = res.data
loading.value = false
}
const addStudent = async (index) => {
pendingAddIndex.value = index
showResourceDialog.value = true
}
const confirmAddStudent = async () => {
const data = {
'resources_id':selectedResourceId.value,
'person_type':'customer_resource',
'schedule_id':form.course_id,
'course_date':form.courseInfo.course_date,
'time_slot':form.courseInfo.time_slot
};
const response = await addSchedule(data);
init();
showResourceDialog.value = false
}
const getStatusText = (status) => {
const statusMap = {
0: '待上课',
1: '已上课',
2: '请假',
}
return statusMap[status] || status
}
defineExpose({
showDialog,
setFormData
})
</script>
<style lang="scss" scoped>
.detail-root {
// background: #232323;
min-height: 100vh;
// padding-bottom: 30px;
}
.header {
padding: 40px 30px 20px 30px;
.title {
color: #fff;
font-size: 36px;
font-weight: bold;
}
.date {
color: #29d3b4;
font-size: 26px;
margin-top: 10px;
}
}
.section {
margin: 30px;
background: #434544;
border-radius: 16px;
// padding: 30px 20px;
}
.section-title {
color: #ffd86b;
font-size: 28px;
margin-bottom: 20px;
}
.student-list {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.student-item {
background: #333;
border-radius: 12px;
display: flex;
align-items: center;
padding: 18px 24px;
min-width: 260px;
.avatar {
width: 60px;
height: 60px;
border-radius: 50%;
background: #29d3b4;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
font-size: 32px;
margin-right: 18px;
}
.info {
.name {
color: #fff;
font-size: 28px;
}
.desc {
color: #bdbdbd;
font-size: 22px;
margin-top: 4px;
}
}
&.empty {
border: 2px dashed #ffd86b;
background: #232323;
margin-left: 20px;
margin-top: 10px;
height: 200px;
.avatar.empty-avatar {
background: #ffd86b;
color: #232323;
font-size: 36px;
}
.info .name {
color: #ffd86b;
}
.info .desc {
color: #ffd86b;
}
}
}
</style>

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

@ -188,6 +188,10 @@
<el-button type="primary" link @click="editEvent(row)">{{
t('edit')
}}</el-button>
<el-button type="primary" link @click="ffEvent(row)">分配</el-button>
<el-button type="primary" link @click="deleteEvent(row.id)">{{
t('delete')
}}</el-button>
@ -207,6 +211,9 @@
</div>
<edit ref="editCourseScheduleDialog" @complete="loadCourseScheduleList" />
<ff ref="ffCourseScheduleDialog" @complete="loadCourseScheduleList" />
</el-card>
</div>
</template>
@ -224,6 +231,7 @@ import { getWithCampusList, getAllVenueList } from '@/app/api/venue'
import { img } from '@/utils/common'
import { ElMessageBox, FormInstance } from 'element-plus'
import Edit from '@/app/views/course_schedule/components/course-schedule-edit.vue'
import Ff from '@/app/views/course_schedule/components/ff.vue'
import { useRoute } from 'vue-router'
const route = useRoute()
const pageName = route.meta.title
@ -347,6 +355,15 @@ const editEvent = (data: any) => {
editCourseScheduleDialog.value.showDialog = true
}
const ffCourseScheduleDialog: Record<string, any> | null = ref(null)
const ffEvent = (data: any) => {
ffCourseScheduleDialog.value.setFormData(data.id,data.resource_id)
ffCourseScheduleDialog.value.showDialog = true
}
/**
* 删除课程安排
*/

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

@ -18,6 +18,19 @@
:value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="订单类型" prop="order_type">
<el-select class="w-[280px]" v-model="orderTableTable.searchParam.order_type" clearable
placeholder="请选择订单类型">
<el-option label="全部" value=""></el-option>
<el-option label="新订单" :value="1"></el-option>
<el-option label="续费订单" :value="2"></el-option>
<el-option label="内部员工订单" :value="3"></el-option>
</el-select>
</el-form-item>
<el-form-item :label="t('paymentType')" prop="payment_type">
<el-select class="w-[280px]" v-model="orderTableTable.searchParam.payment_type" clearable
@ -46,6 +59,8 @@
</template>
<el-table-column prop="resource_id_name" :label="t('resourceId')" min-width="120"
:show-overflow-tooltip="true" />
<el-table-column prop="type" label="订单类型" min-width="120" />
<el-table-column :label="t('orderStatus')" min-width="180" align="center"
:show-overflow-tooltip="true">
@ -151,7 +166,8 @@
searchParam: {
order_status: '',
payment_type: '',
resource_id: route.query.resource_id ?? ''
resource_id: route.query.resource_id ?? '',
order_type:''
},
})

32
admin/src/app/views/salary/salary.vue

@ -69,6 +69,12 @@
<el-table-column prop="department_id_name" :label="t('departmentId')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="base_salary" label="底薪" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="performance_bonus" label="绩效" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="deductions" label="扣款" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="other_subsidies" label="其他补贴" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="net_salary" :label="t('netSalary')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column :label="t('paymentStatus')" min-width="180" align="center" :show-overflow-tooltip="true">
@ -93,10 +99,11 @@
<el-table-column prop="updated_at" :label="t('updatedAt')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column :label="t('operation')" fixed="right" min-width="120">
<el-table-column :label="t('operation')" fixed="right" min-width="200" >
<template #default="{ row }">
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button>
<el-button type="primary" link @click="editEvent(row)" v-if="row.status == 1">{{ t('edit') }}</el-button>
<el-button type="primary" link @click="deleteEvent(row.id)" v-if="row.status == 1">{{ t('delete') }}</el-button>
<el-button type="primary" link @click="ffEvent(row.id)" v-if="row.status == 1">发放</el-button>
</template>
</el-table-column>
@ -117,7 +124,7 @@
import { reactive, ref, watch } from 'vue'
import { t } from '@/lang'
import { useDictionary } from '@/app/api/dict'
import { getSalaryList, deleteSalary, getWithPersonnelList, getWithDepartmentsList } from '@/app/api/salary'
import { getSalaryList, deleteSalary, getWithPersonnelList, getWithDepartmentsList,ffSalary } from '@/app/api/salary'
import { img } from '@/utils/common'
import { ElMessageBox,FormInstance } from 'element-plus'
import Edit from '@/app/views/salary/components/salary-edit.vue'
@ -214,6 +221,23 @@ const deleteEvent = (id: number) => {
})
}
const ffEvent = (id: number) => {
ElMessageBox.confirm("请确定发放工资", t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}
).then(() => {
ffSalary(id).then(() => {
loadSalaryList()
}).catch(() => {
})
})
}
const staffIdList = ref([])
const setStaffIdList = async () => {

31
niucloud/app/adminapi/controller/course_schedule/CourseSchedule.php

@ -137,4 +137,35 @@ class CourseSchedule extends BaseAdminController
]);
return success((new CourseScheduleService())->getCampusVenue($data));
}
public function scheduleList(){
$data = $this->request->params([
["schedule_id",'']
]);
return success((new CourseScheduleService())->schedule_list($data));
}
public function resourceList(){
return success((new CourseScheduleService())->resourceList());
}
public function courseInfo(){
$data = $this->request->params([
["id",'']
]);
return success((new CourseScheduleService())->courseInfo($data['id']));
}
public function addSchedule(){
$data = $this->request->params([
["resources_id",''],
["person_type",''],
["schedule_id",''],
["course_date",''],
["time_slot",'']
]);
return (new CourseScheduleService())->addSchedule($data);
}
}

3
niucloud/app/adminapi/controller/order_table/OrderTable.php

@ -30,7 +30,8 @@ class OrderTable extends BaseAdminController
$data = $this->request->params([
["order_status",""],
["payment_type",""],
["resource_id",""]
["resource_id",""],
["order_type",""]
]);
return success((new OrderTableService())->getPage($data));
}

9
niucloud/app/adminapi/controller/salary/Salary.php

@ -102,7 +102,14 @@ class Salary extends BaseAdminController
return success('DELETE_SUCCESS');
}
public function ffsalary(int $id){
(new SalaryService())->ffsalary($id);
return success('发放成功');
}
public function getPersonnelAll(){
return success(( new SalaryService())->getPersonnelAll());
}

10
niucloud/app/adminapi/route/course_schedule.php

@ -33,7 +33,15 @@ Route::group('course_schedule', function () {
Route::get('campus_venue', 'course_schedule.CourseSchedule/getCampusVenue');
Route::get('timetables', 'course_schedule.CourseSchedule/timetables');
Route::get('scheduleList', 'course_schedule.CourseSchedule/scheduleList');
Route::get('resourceList', 'course_schedule.CourseSchedule/resourceList');
Route::get('courseInfo', 'course_schedule.CourseSchedule/courseInfo');
Route::post('addSchedule', 'course_schedule.CourseSchedule/addSchedule');
})->middleware([
AdminCheckToken::class,
AdminCheckRole::class,

5
niucloud/app/adminapi/route/salary.php

@ -32,7 +32,10 @@ Route::group('salary', function () {
Route::put('salary/:id', 'salary.Salary/edit');
//删除工资
Route::delete('salary/:id', 'salary.Salary/del');
Route::get('ffsalary/:id', 'salary.Salary/ffsalary');
Route::get('personnel_all','salary.Salary/getPersonnelAll');
Route::get('departments_all','salary.Salary/getDepartmentsAll');

19
niucloud/app/service/admin/attendance/AttendanceService.php

@ -38,10 +38,19 @@ class AttendanceService extends BaseAdminService
*/
public function getPage(array $where = [])
{
$field = 'id,campus_id,staff_id,attendance_date,check_in_time,check_out_time,remarks,status,created_at,updated_at,coordinate';
$order = 'id desc';
$search_model = $this->model->withSearch(["campus_id","staff_id","attendance_date","status"], $where)->with(['campus','personnel'])->field($field)->order($order);
$field = 'a.*,d.role_name';
$order = 'a.id desc';
$search_model = $this->model
->alias("a")
->join(['school_personnel' => 'b'],'a.staff_id = b.id','left')
->join(['school_campus_person_role' => 'c'],'b.id = c.person_id','left')
->join(['school_sys_role' => 'd'],'c.role_id = d.role_id','left')
->withSearch(["a.campus_id","a.staff_id","a.attendance_date","a.status"], $where)
->with(['campus','personnel'])
->field($field)
->order($order);
$list = $this->pageQuery($search_model);
return $list;
}
@ -96,7 +105,7 @@ class AttendanceService extends BaseAdminService
return $res;
}
public function getCampusAll(){
$campusModel = new Campus();
return $campusModel->select()->toArray();

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

@ -11,12 +11,15 @@
namespace app\service\admin\course_schedule;
use app\model\assignment\Assignment;
use app\model\course_schedule\CourseSchedule;
use app\model\person_course_schedule\PersonCourseSchedule;
use app\model\personnel\Personnel;
use app\model\student_courses\StudentCourses;
use app\model\venue\Venue;
use app\service\admin\venue\VenueService;
use core\base\BaseAdminService;
use think\facade\Db;
/**
@ -288,4 +291,60 @@ class CourseScheduleService extends BaseAdminService
{
return (new Venue())->where('availability_status', 1)->where('campus_id', $id)->select();
}
public function schedule_list(array $data){
$personCourseSchedule = new PersonCourseSchedule();
$list = $personCourseSchedule
->alias('a')
->join(['school_customer_resources' => 'b'],'a.resources_id = b.id','left')
->where('a.schedule_id',$data['schedule_id'])
->field("b.name,a.status")
->select()->toArray();
return $list;
}
public function resourceList(){
$studentCourse = new StudentCourses();
$data = $studentCourse->alias("a")
->join(['school_customer_resources' => 'b'],'a.resource_id = b.id','left')
->where([
['a.end_date','<=',date('Y-m-d')]
])
->field("b.name,b.id")->select();
return $data ? $data->toArray() : [];
}
public function courseInfo(int $data){
$CourseSchedule = new CourseSchedule();
$info = $CourseSchedule
->where('id', $data)->findOrEmpty();
return $info->toArray();
}
public function addSchedule(array $data){
$CourseSchedule = new CourseSchedule();
$personCourseSchedule = new PersonCourseSchedule();
if($personCourseSchedule->where([
'resources_id' => $data['resources_id'],
'schedule_id' => $data['schedule_id']
])->find()){
return fail("重复添加");
}
$personCourseSchedule->insert([
'resources_id' => $data['resources_id'],
'person_id' => 1,
'person_type' => $data['person_type'],
'schedule_id' => $data['schedule_id'],
'course_date' => $data['course_date'],
'time_slot' => $data['time_slot'],
]);
$CourseSchedule->where(['id' => $data['schedule_id']])->dec("available_capacity")->update();
return success("添加成功");
}
}

13
niucloud/app/service/admin/order_table/OrderTableService.php

@ -41,7 +41,7 @@ class OrderTableService extends BaseAdminService
public function getPage(array $data = [])
{
$where = [];
$field = 'id,resource_id,payment_id,order_status,payment_type,order_amount,course_id,class_id,staff_id,after_sales_status,after_sales_reason,after_sales_time,created_at,updated_at,payment_time,subscription_payment_time';
$field = 'id,resource_id,payment_id,order_type,order_status,payment_type,order_amount,course_id,class_id,staff_id,after_sales_status,after_sales_reason,after_sales_time,created_at,updated_at,payment_time,subscription_payment_time';
$order = 'id desc';
if($data['order_status']){
$where[] = ['order_status','=',$data['order_status']];
@ -54,9 +54,16 @@ class OrderTableService extends BaseAdminService
if($data['resource_id']){
$where[] = ['resource_id','=',$data['resource_id']];
}
if($data['order_type']){
$where[] = ['order_type','=',$data['order_type']];
}
$search_model = $this->model->where($where)->with(['customerResources','course','classGrade','personnel'])->field($field)->order($order);
$list = $this->pageQuery($search_model);
return $list;
return $this->pageQuery($search_model, function ($item, $key) {
$type = [1=>'新订单',2=>'续费订单',3=>'内部员工订单'];
$item['type'] = $type[$item['order_type']] ?? '';
});
}
/**

12
niucloud/app/service/admin/salary/SalaryService.php

@ -38,7 +38,7 @@ class SalaryService extends BaseAdminService
*/
public function getPage(array $where = [])
{
$field = 'id,staff_id,department_id,base_salary,performance_bonus,deductions,other_subsidies,net_salary,payment_status,payment_method,remarks,salary_month,process_id,created_at,updated_at';
$field = 'id,staff_id,department_id,base_salary,status,performance_bonus,deductions,other_subsidies,net_salary,payment_status,payment_method,remarks,salary_month,process_id,created_at,updated_at';
$order = 'id desc';
$search_model = $this->model->withSearch(["staff_id","department_id","payment_status","created_at"], $where)->with(['personnel','departments'])->field($field)->order($order);
@ -96,7 +96,15 @@ class SalaryService extends BaseAdminService
return $res;
}
public function ffsalary(int $id)
{
$res = $this->model->where([['id', '=', $id]])->update(['status' => 2]);
return $res;
}
public function getPersonnelAll(){
$personnelModel = new Personnel();
return $personnelModel->select()->toArray();

Loading…
Cancel
Save