Browse Source

合并wangzeyan

wangzeyan
王泽彦 11 months ago
parent
commit
dfaaa51b00
  1. 58
      admin/package-lock.json
  2. 7
      admin/package.json
  3. 562
      admin/src/app/views/classroom/classroom.vue
  4. 577
      admin/src/app/views/classroom/components/classroom-edit.vue
  5. 127
      admin/src/app/views/timetables/timetables.vue
  6. 81
      admin/src/app/views/yjpz_config/yjpz_config.vue
  7. 7620
      admin/yarn.lock
  8. 2
      niucloud/app/adminapi/route/class.php
  9. 2
      niucloud/app/adminapi/route/classroom.php
  10. 123
      niucloud/app/common.php
  11. 12
      niucloud/app/model/classroom/Classroom.php
  12. 6
      niucloud/app/service/admin/classroom/ClassroomService.php
  13. 2
      niucloud/app/service/admin/personnel/PersonnelService.php

58
admin/package-lock.json

@ -9,6 +9,11 @@
"version": "1.0.0", "version": "1.0.0",
"dependencies": { "dependencies": {
"@element-plus/icons-vue": "2.0.10", "@element-plus/icons-vue": "2.0.10",
"@fullcalendar/core": "^6.1.17",
"@fullcalendar/daygrid": "^6.1.17",
"@fullcalendar/interaction": "^6.1.17",
"@fullcalendar/timegrid": "^6.1.17",
"@fullcalendar/vue3": "^6.1.17",
"@highlightjs/vue-plugin": "2.1.0", "@highlightjs/vue-plugin": "2.1.0",
"@types/lodash-es": "4.17.6", "@types/lodash-es": "4.17.6",
"@vueuse/core": "9.12.0", "@vueuse/core": "9.12.0",
@ -962,6 +967,50 @@
"resolved": "https://registry.npmmirror.com/@floating-ui/utils/-/utils-0.1.6.tgz", "resolved": "https://registry.npmmirror.com/@floating-ui/utils/-/utils-0.1.6.tgz",
"integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==" "integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A=="
}, },
"node_modules/@fullcalendar/core": {
"version": "6.1.17",
"resolved": "https://registry.npmmirror.com/@fullcalendar/core/-/core-6.1.17.tgz",
"integrity": "sha512-0W7lnIrv18ruJ5zeWBeNZXO8qCWlzxDdp9COFEsZnyNjiEhUVnrW/dPbjRKYpL0edGG0/Lhs0ghp1z/5ekt8ZA==",
"dependencies": {
"preact": "~10.12.1"
}
},
"node_modules/@fullcalendar/daygrid": {
"version": "6.1.17",
"resolved": "https://registry.npmmirror.com/@fullcalendar/daygrid/-/daygrid-6.1.17.tgz",
"integrity": "sha512-K7m+pd7oVJ9fW4h7CLDdDGJbc9szJ1xDU1DZ2ag+7oOo1aCNLv44CehzkkknM6r8EYlOOhgaelxQpKAI4glj7A==",
"peerDependencies": {
"@fullcalendar/core": "~6.1.17"
}
},
"node_modules/@fullcalendar/interaction": {
"version": "6.1.17",
"resolved": "https://registry.npmmirror.com/@fullcalendar/interaction/-/interaction-6.1.17.tgz",
"integrity": "sha512-AudvQvgmJP2FU89wpSulUUjeWv24SuyCx8FzH2WIPVaYg+vDGGYarI7K6PcM3TH7B/CyaBjm5Rqw9lXgnwt5YA==",
"peerDependencies": {
"@fullcalendar/core": "~6.1.17"
}
},
"node_modules/@fullcalendar/timegrid": {
"version": "6.1.17",
"resolved": "https://registry.npmmirror.com/@fullcalendar/timegrid/-/timegrid-6.1.17.tgz",
"integrity": "sha512-K4PlA3L3lclLOs3IX8cvddeiJI9ZVMD7RA9IqaWwbvac771971foc9tFze9YY+Pqesf6S+vhS2dWtEVlERaGlQ==",
"dependencies": {
"@fullcalendar/daygrid": "~6.1.17"
},
"peerDependencies": {
"@fullcalendar/core": "~6.1.17"
}
},
"node_modules/@fullcalendar/vue3": {
"version": "6.1.17",
"resolved": "https://registry.npmmirror.com/@fullcalendar/vue3/-/vue3-6.1.17.tgz",
"integrity": "sha512-0+qi/PK/xCkTQXh2CaeN2AkP+SvQTznPhwBXuIyrtsR0Ua8UpmGEXI+my3qQ6o003r8gPUY2e785ywIyhX2zCA==",
"peerDependencies": {
"@fullcalendar/core": "~6.1.17",
"vue": "^3.0.11"
}
},
"node_modules/@highlightjs/vue-plugin": { "node_modules/@highlightjs/vue-plugin": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmmirror.com/@highlightjs/vue-plugin/-/vue-plugin-2.1.0.tgz", "resolved": "https://registry.npmmirror.com/@highlightjs/vue-plugin/-/vue-plugin-2.1.0.tgz",
@ -4997,6 +5046,15 @@
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
"dev": true "dev": true
}, },
"node_modules/preact": {
"version": "10.12.1",
"resolved": "https://registry.npmmirror.com/preact/-/preact-10.12.1.tgz",
"integrity": "sha512-l8386ixSsBdbreOAkqtrwqHwdvR35ID8c3rKPa8lCWuO86dBi32QWHV4vfsZK1utLLFMvw+Z5Ad4XLkZzchscg==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/preact"
}
},
"node_modules/prelude-ls": { "node_modules/prelude-ls": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmmirror.com/prelude-ls/-/prelude-ls-1.2.1.tgz", "resolved": "https://registry.npmmirror.com/prelude-ls/-/prelude-ls-1.2.1.tgz",

7
admin/package.json

@ -10,6 +10,11 @@
}, },
"dependencies": { "dependencies": {
"@element-plus/icons-vue": "2.0.10", "@element-plus/icons-vue": "2.0.10",
"@fullcalendar/core": "^6.1.17",
"@fullcalendar/daygrid": "^6.1.17",
"@fullcalendar/interaction": "^6.1.17",
"@fullcalendar/timegrid": "^6.1.17",
"@fullcalendar/vue3": "^6.1.17",
"@highlightjs/vue-plugin": "2.1.0", "@highlightjs/vue-plugin": "2.1.0",
"@types/lodash-es": "4.17.6", "@types/lodash-es": "4.17.6",
"@vueuse/core": "9.12.0", "@vueuse/core": "9.12.0",
@ -55,4 +60,4 @@
"vite": "4.1.0", "vite": "4.1.0",
"vue-tsc": "1.0.24" "vue-tsc": "1.0.24"
} }
} }

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

@ -1,280 +1,282 @@
<template> <template>
<div class="main-container"> <div class="main-container">
<el-card class="box-card !border-none" shadow="never"> <el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center"> <div class="flex justify-between items-center">
<span class="text-lg">{{pageName}}</span> <span class="text-lg">{{pageName}}</span>
<el-button type="primary" @click="addEvent"> <el-button type="primary" @click="addEvent">
{{ t('addClassroom') }} {{ t('addClassroom') }}
</el-button> </el-button>
</div> </div>
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> <el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="classroomTable.searchParam" ref="searchFormRef"> <el-form :inline="true" :model="classroomTable.searchParam" ref="searchFormRef">
<el-form-item :label="t('campusId')" prop="campus_id"> <el-form-item :label="t('campusId')" prop="campus_id">
<el-select class="w-[280px]" v-model="classroomTable.searchParam.campus_id" clearable :placeholder="t('campusIdPlaceholder')"> <el-select class="w-[280px]" v-model="classroomTable.searchParam.campus_id" clearable :placeholder="t('campusIdPlaceholder')">
<el-option <el-option
v-for="(item, index) in campusIdList" v-for="(item, index) in campusIdList"
:key="index" :key="index"
:label="item['campus_name']" :label="item['campus_name']"
:value="item['id']" :value="item['id']"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item :label="t('className')" prop="class_name"> <el-form-item :label="t('className')" prop="class_name">
<el-input v-model="classroomTable.searchParam.class_name" :placeholder="t('classNamePlaceholder')" /> <el-input v-model="classroomTable.searchParam.class_name" :placeholder="t('classNamePlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item :label="t('headCoach')" prop="head_coach"> <el-form-item :label="t('headCoach')" prop="head_coach">
<el-select class="w-[280px]" v-model="classroomTable.searchParam.head_coach" clearable :placeholder="t('headCoachPlaceholder')"> <el-select class="w-[280px]" v-model="classroomTable.searchParam.head_coach" clearable :placeholder="t('headCoachPlaceholder')">
<el-option <el-option
v-for="(item, index) in headCoachList" v-for="(item, index) in headCoachList"
:key="index" :key="index"
:label="item['name']" :label="item['name']"
:value="item['id']" :value="item['id']"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item :label="t('classType')" prop="class_type"> <el-form-item :label="t('classType')" prop="class_type">
<el-select class="w-[280px]" v-model="classroomTable.searchParam.class_type" clearable :placeholder="t('classTypePlaceholder')"> <el-select class="w-[280px]" v-model="classroomTable.searchParam.class_type" clearable :placeholder="t('classTypePlaceholder')">
<el-option label="全部" value=""></el-option> <el-option label="全部" value=""></el-option>
<el-option <el-option
v-for="(item, index) in class_typeList" v-for="(item, index) in class_typeList"
:key="index" :key="index"
:label="item.name" :label="item.name"
:value="item.value" :value="item.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item :label="t('assistantCoach')" prop="assistant_coach"> <el-form-item :label="t('assistantCoach')" prop="assistant_coach">
<el-select class="w-[280px]" v-model="classroomTable.searchParam.assistant_coach" clearable :placeholder="t('assistantCoachPlaceholder')"> <el-select class="w-[280px]" v-model="classroomTable.searchParam.assistant_coach" clearable :placeholder="t('assistantCoachPlaceholder')">
<el-option <el-option
v-for="(item, index) in assistantCoachList" v-for="(item, index) in assistantCoachList"
:key="index" :key="index"
:label="item['name']" :label="item['name']"
:value="item['id']" :value="item['id']"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item :label="t('createdAt')" prop="created_at"> <el-form-item :label="t('createdAt')" prop="created_at">
<el-input v-model="classroomTable.searchParam.created_at" :placeholder="t('createdAtPlaceholder')" /> <el-input v-model="classroomTable.searchParam.created_at" :placeholder="t('createdAtPlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item :label="t('status')" prop="status"> <el-form-item :label="t('status')" prop="status">
<el-select class="w-[280px]" v-model="classroomTable.searchParam.status" clearable :placeholder="t('statusPlaceholder')"> <el-select class="w-[280px]" v-model="classroomTable.searchParam.status" clearable :placeholder="t('statusPlaceholder')">
<el-option label="全部" value=""></el-option> <el-option label="全部" value=""></el-option>
<el-option <el-option
v-for="(item, index) in statusList" v-for="(item, index) in statusList"
:key="index" :key="index"
:label="item.name" :label="item.name"
:value="item.value" :value="item.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item>
<el-button type="primary" @click="loadClassroomList()">{{ t('search') }}</el-button> <el-form-item>
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button> <el-button type="primary" @click="loadClassroomList()">{{ t('search') }}</el-button>
</el-form-item> <el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
</el-form> </el-form-item>
</el-card> </el-form>
</el-card>
<div class="mt-[10px]">
<el-table :data="classroomTable.data" size="large" v-loading="classroomTable.loading"> <div class="mt-[10px]">
<template #empty> <el-table :data="classroomTable.data" size="large" v-loading="classroomTable.loading">
<span>{{ !classroomTable.loading ? t('emptyData') : '' }}</span> <template #empty>
</template> <span>{{ !classroomTable.loading ? t('emptyData') : '' }}</span>
<el-table-column prop="campus_id_name" :label="t('campusId')" min-width="120" :show-overflow-tooltip="true"/> </template>
<el-table-column prop="campus_id_name" :label="t('campusId')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="class_name" :label="t('className')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="class_name" :label="t('className')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="head_coach_name" :label="t('headCoach')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="head_coach_name" :label="t('headCoach')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="age_group" :label="t('ageGroup')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="age_group" :label="t('ageGroup')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column :label="t('classType')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }"> <el-table-column :label="t('classType')" min-width="180" align="center" :show-overflow-tooltip="true">
<div v-for="(item, index) in class_typeList"> <template #default="{ row }">
<div v-if="item.value == row.class_type">{{ item.name }}</div> <div v-for="(item, index) in class_typeList">
</div> <div v-if="item.value == row.class_type">{{ item.name }}</div>
</template> </div>
</el-table-column> </template>
</el-table-column>
<el-table-column prop="assistant_coach_name" :label="t('assistantCoach')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="assistant_coach_name" :label="t('assistantCoach')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column :label="t('status')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }"> <el-table-column :label="t('status')" min-width="180" align="center" :show-overflow-tooltip="true">
<div v-for="(item, index) in statusList"> <template #default="{ row }">
<div v-if="item.value == row.status">{{ item.name }}</div> <div v-for="(item, index) in statusList">
</div> <div v-if="item.value == row.status">{{ item.name }}</div>
</template> </div>
</el-table-column> </template>
</el-table-column>
<el-table-column prop="sort_order" :label="t('sortOrder')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="sort_order" :label="t('sortOrder')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column :label="t('operation')" fixed="right" min-width="120">
<template #default="{ row }">
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button> <el-table-column :label="t('operation')" fixed="right" min-width="120">
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button> <template #default="{ row }">
</template> <el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
</el-table-column> <el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button>
</template>
</el-table> </el-table-column>
<div class="mt-[16px] flex justify-end">
<el-pagination v-model:current-page="classroomTable.page" v-model:page-size="classroomTable.limit" </el-table>
layout="total, sizes, prev, pager, next, jumper" :total="classroomTable.total" <div class="mt-[16px] flex justify-end">
@size-change="loadClassroomList()" @current-change="loadClassroomList" /> <el-pagination v-model:current-page="classroomTable.page" v-model:page-size="classroomTable.limit"
</div> layout="total, sizes, prev, pager, next, jumper" :total="classroomTable.total"
</div> @size-change="loadClassroomList()" @current-change="loadClassroomList" />
</div>
<edit ref="editClassroomDialog" @complete="loadClassroomList" /> </div>
</el-card>
</div> <edit ref="editClassroomDialog" @complete="loadClassroomList" />
</template> </el-card>
</div>
<script lang="ts" setup> </template>
import { reactive, ref, watch } from 'vue'
import { t } from '@/lang' <script lang="ts" setup>
import { useDictionary } from '@/app/api/dict' import { reactive, ref, watch } from 'vue'
import { getClassroomList, deleteClassroom, getWithCampusList, getWithPersonnelList, getWithPersonnelList } from '@/app/api/classroom' import { t } from '@/lang'
import { img } from '@/utils/common' import { useDictionary } from '@/app/api/dict'
import { ElMessageBox,FormInstance } from 'element-plus' import { getClassroomList, deleteClassroom, getWithCampusList, getWithPersonnelList } from '@/app/api/classroom'
import Edit from '@/app/views/classroom/components/classroom-edit.vue' import { ElMessageBox,FormInstance } from 'element-plus'
import { useRoute } from 'vue-router' import Edit from '@/app/views/classroom/components/classroom-edit.vue'
const route = useRoute() import { useRoute } from 'vue-router'
const pageName = route.meta.title; const route = useRoute()
const pageName = route.meta.title;
let classroomTable = reactive({
page: 1, let classroomTable = reactive({
limit: 10, page: 1,
total: 0, limit: 10,
loading: true, total: 0,
data: [], loading: true,
searchParam:{ data: [],
"campus_id":"", searchParam:{
"class_name":"", "campus_id":"",
"head_coach":"", "class_name":"",
"class_type":"", "head_coach":"",
"assistant_coach":"", "class_type":"",
"created_at":"", "assistant_coach":"",
"status":"" "created_at":"",
} "status":""
}) }
})
const searchFormRef = ref<FormInstance>()
const searchFormRef = ref<FormInstance>()
//
const selectData = ref<any[]>([]) //
const selectData = ref<any[]>([])
//
const class_typeList = ref([] as any[]) //
const class_typeDictList = async () => { const class_typeList = ref([] as any[])
class_typeList.value = await (await useDictionary('class_type')).data.dictionary const class_typeDictList = async () => {
} class_typeList.value = await (await useDictionary('class_type')).data.dictionary
class_typeDictList(); }
const statusList = ref([] as any[]) class_typeDictList();
const statusDictList = async () => { const statusList = ref([] as any[])
statusList.value = await (await useDictionary('SiteStatus')).data.dictionary const statusDictList = async () => {
} statusList.value = await (await useDictionary('SiteStatus')).data.dictionary
statusDictList(); }
statusDictList();
/**
* 获取场地管理列表
*/ /**
const loadClassroomList = (page: number = 1) => { * 获取场地管理列表
classroomTable.loading = true */
classroomTable.page = page const loadClassroomList = (page: number = 1) => {
classroomTable.loading = true
getClassroomList({ classroomTable.page = page
page: classroomTable.page,
limit: classroomTable.limit, getClassroomList({
...classroomTable.searchParam page: classroomTable.page,
}).then(res => { limit: classroomTable.limit,
classroomTable.loading = false ...classroomTable.searchParam
classroomTable.data = res.data.data }).then(res => {
classroomTable.total = res.data.total classroomTable.loading = false
}).catch(() => { classroomTable.data = res.data.data
classroomTable.loading = false classroomTable.total = res.data.total
}) }).catch(() => {
} classroomTable.loading = false
loadClassroomList() })
}
const editClassroomDialog: Record<string, any> | null = ref(null) loadClassroomList()
/** const editClassroomDialog: Record<string, any> | null = ref(null)
* 添加场地管理
*/ /**
const addEvent = () => { * 添加场地管理
editClassroomDialog.value.setFormData() */
editClassroomDialog.value.showDialog = true const addEvent = () => {
} editClassroomDialog.value.setFormData()
editClassroomDialog.value.showDialog = true
/** }
* 编辑场地管理
* @param data /**
*/ * 编辑场地管理
const editEvent = (data: any) => { * @param data
editClassroomDialog.value.setFormData(data) */
editClassroomDialog.value.showDialog = true const editEvent = (data: any) => {
} editClassroomDialog.value.setFormData(data)
editClassroomDialog.value.showDialog = true
/** }
* 删除场地管理
*/ /**
const deleteEvent = (id: number) => { * 删除场地管理
ElMessageBox.confirm(t('classroomDeleteTips'), t('warning'), */
{ const deleteEvent = (id: number) => {
confirmButtonText: t('confirm'), ElMessageBox.confirm(t('classroomDeleteTips'), t('warning'),
cancelButtonText: t('cancel'), {
type: 'warning', confirmButtonText: t('confirm'),
} cancelButtonText: t('cancel'),
).then(() => { type: 'warning',
deleteClassroom(id).then(() => { }
loadClassroomList() ).then(() => {
}).catch(() => { deleteClassroom(id).then(() => {
}) loadClassroomList()
}) }).catch(() => {
} })
})
}
const campusIdList = ref([])
const setCampusIdList = async () => {
campusIdList.value = await (await getWithCampusList({})).data const campusIdList = ref([])
} const setCampusIdList = async () => {
setCampusIdList() campusIdList.value = await (await getWithCampusList({})).data
const headCoachList = ref([]) }
const setHeadCoachList = async () => { setCampusIdList()
headCoachList.value = await (await getWithPersonnelList({})).data const headCoachList = ref([])
} const setHeadCoachList = async () => {
setHeadCoachList() headCoachList.value = await (await getWithPersonnelList({})).data
const assistantCoachList = ref([]) }
const setAssistantCoachList = async () => { setHeadCoachList()
assistantCoachList.value = await (await getWithPersonnelList({})).data const assistantCoachList = ref([])
} const setAssistantCoachList = async () => {
setAssistantCoachList() assistantCoachList.value = await (await getWithPersonnelList({})).data
}
const resetForm = (formEl: FormInstance | undefined) => { setAssistantCoachList()
if (!formEl) return
formEl.resetFields() const resetForm = (formEl: FormInstance | undefined) => {
loadClassroomList() if (!formEl) return
} formEl.resetFields()
</script> loadClassroomList()
}
<style lang="scss" scoped> </script>
/* 多行超出隐藏 */
.multi-hidden { <style lang="scss" scoped>
word-break: break-all; /* 多行超出隐藏 */
text-overflow: ellipsis; .multi-hidden {
overflow: hidden; word-break: break-all;
display: -webkit-box; text-overflow: ellipsis;
-webkit-line-clamp: 2; overflow: hidden;
-webkit-box-orient: vertical; display: -webkit-box;
} -webkit-line-clamp: 2;
</style> -webkit-box-orient: vertical;
}
</style>

577
admin/src/app/views/classroom/components/classroom-edit.vue

@ -1,287 +1,290 @@
<template> <template>
<el-dialog v-model="showDialog" :title="formData.id ? t('updateClassroom') : t('addClassroom')" width="50%" class="diy-dialog-wrap" :destroy-on-close="true"> <el-dialog v-model="showDialog" :title="formData.id ? t('updateClassroom') : t('addClassroom')" 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 :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
<el-form-item :label="t('campusId')" prop="campus_id"> <el-form-item :label="t('campusId')" prop="campus_id">
<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 label="请选择" value=""></el-option>
<el-option <el-option
v-for="(item, index) in campusIdList" v-for="(item, index) in campusIdList"
:key="index" :key="index"
:label="item['campus_name']" :label="item['campus_name']"
:value="item['id']" :value="item['id']"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item :label="t('className')" prop="class_name"> <el-form-item :label="t('className')" prop="class_name">
<el-input v-model="formData.class_name" clearable :placeholder="t('classNamePlaceholder')" class="input-width" /> <el-input v-model="formData.class_name" clearable :placeholder="t('classNamePlaceholder')" class="input-width" />
</el-form-item> </el-form-item>
<el-form-item :label="t('headCoach')" prop="head_coach"> <el-form-item :label="t('headCoach')" prop="head_coach">
<el-select class="input-width" v-model="formData.head_coach" clearable :placeholder="t('headCoachPlaceholder')"> <el-select class="input-width" v-model="formData.head_coach" clearable :placeholder="t('headCoachPlaceholder')">
<el-option label="请选择" value=""></el-option> <el-option label="请选择" value=""></el-option>
<el-option <el-option
v-for="(item, index) in headCoachList" v-for="(item, index) in headCoachList"
:key="index" :key="index"
:label="item['name']" :label="item['name']"
:value="item['id']" :value="item['id']"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item :label="t('ageGroup')" > <el-form-item :label="t('ageGroup')" >
<el-input v-model="formData.age_group" clearable :placeholder="t('ageGroupPlaceholder')" class="input-width" /> <el-input v-model="formData.age_group" clearable :placeholder="t('ageGroupPlaceholder')" class="input-width" />
</el-form-item> </el-form-item>
<el-form-item :label="t('classType')" prop="class_type"> <el-form-item :label="t('classType')" prop="class_type">
<el-select class="input-width" v-model="formData.class_type" clearable :placeholder="t('classTypePlaceholder')"> <el-select class="input-width" v-model="formData.class_type" clearable :placeholder="t('classTypePlaceholder')">
<el-option label="请选择" value=""></el-option> <el-option label="请选择" value=""></el-option>
<el-option <el-option
v-for="(item, index) in class_typeList" v-for="(item, index) in class_typeList"
:key="index" :key="index"
:label="item.name" :label="item.name"
:value="item.value" :value="item.value"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item :label="t('assistantCoach')" > <el-form-item :label="t('assistantCoach')" >
<el-select class="input-width" v-model="formData.assistant_coach" clearable :placeholder="t('assistantCoachPlaceholder')"> <el-select class="input-width" v-model="formData.assistant_coach" clearable :placeholder="t('assistantCoachPlaceholder')">
<el-option label="请选择" value=""></el-option> <el-option label="请选择" value=""></el-option>
<el-option <el-option
v-for="(item, index) in assistantCoachList" v-for="(item, index) in assistantCoachList"
:key="index" :key="index"
:label="item['name']" :label="item['name']"
:value="item['id']" :value="item['id']"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item :label="t('status')" prop="status"> <el-form-item :label="t('status')" prop="status">
<el-radio-group v-model="formData.status" :placeholder="t('statusPlaceholder')"> <el-radio-group v-model="formData.status" :placeholder="t('statusPlaceholder')">
<el-radio <el-radio
v-for="(item, index) in statusList" v-for="(item, index) in statusList"
:key="index" :label="item.value"> :key="index" :label="item.value">
{{ item.name }} {{ item.name }}
</el-radio> </el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item :label="t('sortOrder')" > <el-form-item :label="t('sortOrder')" >
<el-input v-model="formData.sort_order" clearable :placeholder="t('sortOrderPlaceholder')" class="input-width" /> <el-input v-model="formData.sort_order" clearable :placeholder="t('sortOrderPlaceholder')" class="input-width" />
</el-form-item> </el-form-item>
<el-form-item :label="t('remarks')" > <el-form-item :label="t('remarks')" >
<el-input v-model="formData.remarks" clearable :placeholder="t('remarksPlaceholder')" class="input-width" /> <el-input v-model="formData.remarks" clearable :placeholder="t('remarksPlaceholder')" class="input-width" />
</el-form-item> </el-form-item>
</el-form>
</el-form>
<template #footer>
<span class="dialog-footer"> <template #footer>
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button> <span class="dialog-footer">
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{ <el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
t('confirm') <el-button type="primary" :loading="loading" @click="confirm(formRef)">{{
}}</el-button> t('confirm')
</span> }}</el-button>
</template> </span>
</el-dialog> </template>
</template> </el-dialog>
</template>
<script lang="ts" setup>
import { ref, reactive, computed, watch } from 'vue' <script lang="ts" setup>
import { useDictionary } from '@/app/api/dict' import { ref, reactive, computed, watch } from 'vue'
import { t } from '@/lang' import { useDictionary } from '@/app/api/dict'
import type { FormInstance } from 'element-plus' import { t } from '@/lang'
import { addClassroom, editClassroom, getClassroomInfo, getWithCampusList, getWithPersonnelList, getWithPersonnelList } from '@/app/api/classroom' import type { FormInstance } from 'element-plus'
import { addClassroom, editClassroom, getClassroomInfo, getWithCampusList, getWithPersonnelList } from '@/app/api/classroom'
let showDialog = ref(false)
const loading = ref(false) let showDialog = ref(false)
const loading = ref(false)
/**
* 表单数据 /**
*/ * 表单数据
const initialFormData = { */
id: '', const initialFormData = {
campus_id: '', id: '',
class_name: '', campus_id: '',
head_coach: '', class_name: '',
age_group: '', head_coach: '',
class_type: '', age_group: '',
assistant_coach: '', class_type: '',
status: '', assistant_coach: '',
sort_order: '', status: '',
remarks: '', sort_order: '',
} remarks: '',
const formData: Record<string, any> = reactive({ ...initialFormData })
}
const formRef = ref<FormInstance>() const formData: Record<string, any> = reactive({ ...initialFormData })
// const formRef = ref<FormInstance>()
const formRules = computed(() => {
return { //
campus_id: [ const formRules = computed(() => {
{ required: true, message: t('campusIdPlaceholder'), trigger: 'blur' }, return {
campus_id: [
] { required: true, message: t('campusIdPlaceholder'), trigger: 'blur' },
,
class_name: [ ]
{ required: true, message: t('classNamePlaceholder'), trigger: 'blur' }, ,
class_name: [
] { required: true, message: t('classNamePlaceholder'), trigger: 'blur' },
,
head_coach: [ ]
{ required: true, message: t('headCoachPlaceholder'), trigger: 'blur' }, ,
head_coach: [
] { required: true, message: t('headCoachPlaceholder'), trigger: 'blur' },
,
age_group: [ ]
{ required: true, message: t('ageGroupPlaceholder'), trigger: 'blur' }, ,
age_group: [
] { required: true, message: t('ageGroupPlaceholder'), trigger: 'blur' },
,
class_type: [ ]
{ required: true, message: t('classTypePlaceholder'), trigger: 'blur' }, ,
class_type: [
] { required: true, message: t('classTypePlaceholder'), trigger: 'blur' },
,
assistant_coach: [ ]
{ required: true, message: t('assistantCoachPlaceholder'), trigger: 'blur' }, ,
assistant_coach: [
] { required: true, message: t('assistantCoachPlaceholder'), trigger: 'blur' },
,
status: [ ]
{ required: true, message: t('statusPlaceholder'), trigger: 'blur' }, ,
status: [
] { required: true, message: t('statusPlaceholder'), trigger: 'blur' },
,
sort_order: [ ]
{ required: true, message: t('sortOrderPlaceholder'), trigger: 'blur' }, ,
sort_order: [
] { required: true, message: t('sortOrderPlaceholder'), trigger: 'blur' },
,
remarks: [ ]
{ required: true, message: t('remarksPlaceholder'), trigger: 'blur' }, ,
remarks: [
] { required: true, message: t('remarksPlaceholder'), trigger: 'blur' },
,
} ]
}) ,
}
const emit = defineEmits(['complete']) })
/** const emit = defineEmits(['complete'])
* 确认
* @param formEl /**
*/ * 确认
const confirm = async (formEl: FormInstance | undefined) => { * @param formEl
if (loading.value || !formEl) return */
let save = formData.id ? editClassroom : addClassroom const confirm = async (formEl: FormInstance | undefined) => {
if (loading.value || !formEl) return
await formEl.validate(async (valid) => { let save = formData.id ? editClassroom : addClassroom
if (valid) {
loading.value = true await formEl.validate(async (valid) => {
if (valid) {
let data = formData loading.value = true
save(data).then(res => { let data = formData
loading.value = false
showDialog.value = false save(data).then(res => {
emit('complete') loading.value = false
}).catch(err => { showDialog.value = false
loading.value = false emit('complete')
}) }).catch(err => {
} loading.value = false
}) })
} }
})
// }
let class_typeList = ref([])
const class_typeDictList = async () => { //
class_typeList.value = await (await useDictionary('class_type')).data.dictionary let class_typeList = ref([])
} const class_typeDictList = async () => {
class_typeDictList(); class_typeList.value = await (await useDictionary('class_type')).data.dictionary
watch(() => class_typeList.value, () => { formData.class_type = class_typeList.value[0].value }) }
let statusList = ref([]) class_typeDictList();
const statusDictList = async () => { watch(() => class_typeList.value, () => { formData.class_type = class_typeList.value[0].value })
statusList.value = await (await useDictionary('SiteStatus')).data.dictionary let statusList = ref([])
} const statusDictList = async () => {
statusDictList(); statusList.value = await (await useDictionary('SiteStatus')).data.dictionary
watch(() => statusList.value, () => { formData.status = statusList.value[0].value }) }
statusDictList();
watch(() => statusList.value, () => { formData.status = statusList.value[0].value })
const campusIdList = ref([] as any[])
const setCampusIdList = async () => {
campusIdList.value = await (await getWithCampusList({})).data
} const campusIdList = ref([] as any[])
setCampusIdList() const setCampusIdList = async () => {
const headCoachList = ref([] as any[]) campusIdList.value = await (await getWithCampusList({})).data
const setHeadCoachList = async () => { }
headCoachList.value = await (await getWithPersonnelList({})).data setCampusIdList()
} const headCoachList = ref([] as any[])
setHeadCoachList() const setHeadCoachList = async () => {
const assistantCoachList = ref([] as any[]) headCoachList.value = await (await getWithPersonnelList({})).data
const setAssistantCoachList = async () => { }
assistantCoachList.value = await (await getWithPersonnelList({})).data setHeadCoachList()
} const assistantCoachList = ref([] as any[])
setAssistantCoachList() const setAssistantCoachList = async () => {
const setFormData = async (row: any = null) => { assistantCoachList.value = await (await getWithPersonnelList({})).data
Object.assign(formData, initialFormData) }
loading.value = true setAssistantCoachList()
if(row){ const setFormData = async (row: any = null) => {
const data = await (await getClassroomInfo(row.id)).data Object.assign(formData, initialFormData)
if (data) Object.keys(formData).forEach((key: string) => { loading.value = true
if (data[key] != undefined) formData[key] = data[key] if(row){
}) const data = await (await getClassroomInfo(row.id)).data
} if (data) Object.keys(formData).forEach((key: string) => {
loading.value = false if (data[key] != undefined) formData[key] = data[key]
} })
}
// loading.value = false
const mobileVerify = (rule: any, value: any, callback: any) => { }
if (value && !/^1[3-9]\d{9}$/.test(value)) {
callback(new Error(t('generateMobile'))) //
} else { const mobileVerify = (rule: any, value: any, callback: any) => {
callback() if (value && !/^1[3-9]\d{9}$/.test(value)) {
} callback(new Error(t('generateMobile')))
} } else {
callback()
// }
const idCardVerify = (rule: any, value: any, callback: any) => { }
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) {
callback(new Error(t('generateIdCard'))) //
} else { const idCardVerify = (rule: any, value: any, callback: any) => {
callback() if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) {
} callback(new Error(t('generateIdCard')))
} } else {
callback()
// }
const emailVerify = (rule: any, value: any, callback: any) => { }
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail'))) //
} else { const emailVerify = (rule: any, value: any, callback: any) => {
callback() if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
} callback(new Error(t('generateEmail')))
} } else {
callback()
// }
const numberVerify = (rule: any, value: any, callback: any) => { }
if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber'))) //
} else { const numberVerify = (rule: any, value: any, callback: any) => {
callback() if (!Number.isInteger(value)) {
} callback(new Error(t('generateNumber')))
} } else {
callback()
defineExpose({ }
showDialog, }
setFormData
}) defineExpose({
</script> showDialog,
setFormData
<style lang="scss" scoped></style> })
<style lang="scss"> </script>
.diy-dialog-wrap .el-form-item__label{
height: auto !important; <style lang="scss" scoped></style>
} <style lang="scss">
</style> .diy-dialog-wrap .el-form-item__label{
height: auto !important;
}
</style>

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

@ -0,0 +1,127 @@
<template>
<div class="schedule-container">
<!-- 周视图日历 -->
<FullCalendar
:options="calendarOptions"
ref="fullCalendar"
class="calendar"
/>
<!-- 课程详情弹窗 -->
<el-dialog
v-model="dialogVisible"
title="课程人员安排"
width="30%"
:before-close="handleClose"
>
<div v-if="selectedEvent">
<h3>{{ selectedEvent.title }}</h3>
<p>时间{{ selectedEvent.time }}</p>
<h4>参与人员</h4>
<ul>
<li v-for="person in selectedEvent.people" :key="person.id">
{{ person.name }} - {{ person.role }}
</li>
</ul>
</div>
</el-dialog>
</div>
</template>
<script setup>
import {ref} from 'vue';
import FullCalendar from '@fullcalendar/vue3';
import dayGridPlugin from '@fullcalendar/daygrid';
import timeGridPlugin from '@fullcalendar/timegrid';
import interactionPlugin from '@fullcalendar/interaction'; //
import zhLocale from '@fullcalendar/core/locales/zh-cn';
//
const courses = ref([
{
id: 1,
title: '数学课',
start: '2025-05-18 08:00:00',
end: '2025-05-18 09:00:00',
people: [
{id: 1, name: '张老师', role: '主讲'},
{id: 2, name: '李同学', role: '学生'}
]
},
{
id: 2,
title: '英语课',
start: '2025-05-18 10:00:00',
end: '2025-05-18 11:00:00',
people: [
{id: 3, name: '王老师', role: '主讲'}
]
}
]);
//
const dialogVisible = ref(false);
const selectedEvent = ref(null);
// FullCalendar
const calendarOptions = ref({
locale: zhLocale,
plugins: [
dayGridPlugin,
timeGridPlugin,
interactionPlugin //
],
initialView: 'timeGridWeek', //
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'timeGridWeek,timeGridDay' //
},
events: courses.value,
eventClick: (info) => {
selectedEvent.value = {
title: info.event.title,
time: `${info.event.start.toLocaleTimeString()} - ${info.event.end.toLocaleTimeString()}`,
people: info.event.extendedProps.people
};
dialogVisible.value = true;
},
eventContent: (arg) => {
//
return {html: `<div class="fc-event-title">${arg.event.title}</div>`};
},
allDaySlot: false, //
slotDuration: '01:00', // 1
slotLabelFormat: {
hour: 'numeric',
minute: '2-digit',
omitZeroMinute: false,
meridiem: 'short'
}
});
//
const handleClose = () => {
dialogVisible.value = false;
selectedEvent.value = null;
};
</script>
<style>
.schedule-container {
padding: 20px;
}
.calendar {
margin-bottom: 20px;
}
.fc-event-title {
white-space: normal !important;
font-size: 14px;
}
.fc-timegrid-event {
cursor: pointer;
}
</style>

81
admin/src/app/views/yjpz_config/yjpz_config.vue

@ -1,49 +1,54 @@
<template> <template>
<div class="main-container"> <div class="main-container">
<el-card class="box-card !border-none" shadow="never"> <el-card class="box-card !border-none" shadow="never">
<el-form <div class="flex justify-between items-center">
class="page-form" <span class="text-lg">市场人员绩效配置</span>
:model="formData" </div>
label-width="150px" <div style="margin-top: 20px">
ref="ruleFormRef" <el-form
:rules="formRules" class="page-form"
v-loading="loading" :model="formData"
> label-width="150px"
<el-form-item ref="ruleFormRef"
v-for="day in weekDays" :rules="formRules"
:key="day.key" v-loading="loading"
:label="day.label"
:prop="`priceRules.${day.key}`"
> >
<span style="margin: 0 8px">每个</span> <el-form-item
<el-input v-for="day in weekDays"
v-model.number="formData.priceRules[day.key].basePrice" :key="day.key"
placeholder="请输入" :label="day.label"
class="input-width" :prop="`priceRules.${day.key}`"
clearable >
/> <span style="margin: 0 8px">每个</span>
<span style="margin: 0 8px"> 超过</span> <el-input
<el-input v-model.number="formData.priceRules[day.key].basePrice"
v-model.number="formData.priceRules[day.key].limitCount" placeholder="请输入"
placeholder="请输入" class="input-width"
class="input-width" clearable
clearable />
/> <span style="margin: 0 8px"> 超过</span>
<span style="margin: 0 8px"></span> <el-input
<el-input v-model.number="formData.priceRules[day.key].limitCount"
v-model.number="formData.priceRules[day.key].extraPrice" placeholder="请输入"
placeholder="请输入" class="input-width"
class="input-width" clearable
clearable />
/> <span style="margin: 0 8px"></span>
<span style="margin-left: 4px"></span> <el-input
</el-form-item> v-model.number="formData.priceRules[day.key].extraPrice"
</el-form> placeholder="请输入"
class="input-width"
clearable
/>
<span style="margin-left: 4px"></span>
</el-form-item>
</el-form>
</div>
</el-card> </el-card>
<div class="fixed-footer-wrap"> <div class="fixed-footer-wrap">
<div class="fixed-footer"> <div class="fixed-footer">
<el-button type="primary" @click="onSave()">提交</el-button> <el-button type="primary" @click="onSave()">保存</el-button>
</div> </div>
</div> </div>
</div> </div>

7620
admin/yarn.lock

File diff suppressed because it is too large

2
niucloud/app/adminapi/route/class.php

@ -57,8 +57,6 @@ Route::group('class', function () {
Route::get('personnel_all','class.Class/getPersonnelAll'); Route::get('personnel_all','class.Class/getPersonnelAll');
Route::get('personnel_all','class.Class/getPersonnelAll');
})->middleware([ })->middleware([
AdminCheckToken::class, AdminCheckToken::class,
AdminCheckRole::class, AdminCheckRole::class,

2
niucloud/app/adminapi/route/classroom.php

@ -33,8 +33,6 @@ Route::group('classroom', function () {
Route::get('personnel_all','classroom.Classroom/getPersonnelAll'); Route::get('personnel_all','classroom.Classroom/getPersonnelAll');
Route::get('personnel_all','classroom.Classroom/getPersonnelAll');
})->middleware([ })->middleware([
AdminCheckToken::class, AdminCheckToken::class,
AdminCheckRole::class, AdminCheckRole::class,

123
niucloud/app/common.php

@ -21,13 +21,13 @@ use app\service\core\sys\CoreSysConfigService;
* @param int $http_code * @param int $http_code
* @return Response * @return Response
*/ */
function success($msg = 'SUCCESS', $data = [], int $code = 1, int $http_code = 200) : Response function success($msg = 'SUCCESS', $data = [], int $code = 1, int $http_code = 200): Response
{ {
if (is_array($msg)) { if (is_array($msg)) {
$data = $msg; $data = $msg;
$msg = 'SUCCESS'; $msg = 'SUCCESS';
} }
return Response::create([ 'data' => $data, 'msg' => get_lang($msg), 'code' => $code ], 'json', $http_code); return Response::create(['data' => $data, 'msg' => get_lang($msg), 'code' => $code], 'json', $http_code);
} }
@ -39,13 +39,13 @@ function success($msg = 'SUCCESS', $data = [], int $code = 1, int $http_code = 2
* @param int $http_code * @param int $http_code
* @return Response * @return Response
*/ */
function fail($msg = 'FAIL', ?array $data = [], int $code = 0, int $http_code = 200) : Response function fail($msg = 'FAIL', ?array $data = [], int $code = 0, int $http_code = 200): Response
{ {
if (is_array($msg)) { if (is_array($msg)) {
$data = $msg; $data = $msg;
$msg = 'FAIL'; $msg = 'FAIL';
} }
return Response::create([ 'data' => $data, 'msg' => get_lang($msg), 'code' => $code ], 'json', $http_code); return Response::create(['data' => $data, 'msg' => get_lang($msg), 'code' => $code], 'json', $http_code);
} }
/** /**
@ -76,17 +76,17 @@ function list_to_tree($list, $pk = 'id', $pid = 'pid', $child = 'child', $root =
// 创建基于主键的数组引用 // 创建基于主键的数组引用
$refer = array(); $refer = array();
foreach ($list as $key => $data) { foreach ($list as $key => $data) {
$refer[ $data[ $pk ] ] =& $list[ $key ]; $refer[$data[$pk]] =& $list[$key];
} }
foreach ($list as $key => $data) { foreach ($list as $key => $data) {
// 判断是否存在parent // 判断是否存在parent
$parent_id = $data[ $pid ]; $parent_id = $data[$pid];
if ($root == $parent_id) { if ($root == $parent_id) {
$tree[] =& $list[ $key ]; $tree[] =& $list[$key];
} else { } else {
if (isset($refer[ $parent_id ])) { if (isset($refer[$parent_id])) {
$parent =& $refer[ $parent_id ]; $parent =& $refer[$parent_id];
$parent[ $child ][] =& $list[ $key ]; $parent[$child][] =& $list[$key];
} }
} }
} }
@ -137,11 +137,11 @@ function array_keys_search($array, $keys, $index = '', $is_sort = true)
$list = array(); $list = array();
foreach ($keys as $key) { foreach ($keys as $key) {
if (isset($array[ $key ])) { if (isset($array[$key])) {
if ($is_sort) { if ($is_sort) {
$list[] = $array[ $key ]; $list[] = $array[$key];
} else { } else {
$list[ $key ] = $array[ $key ]; $list[$key] = $array[$key];
} }
} }
@ -166,7 +166,7 @@ function del_target_dir($path, $delDir)
//打开目录句柄 //打开目录句柄
$handle = opendir($path); $handle = opendir($path);
if ($handle) { if ($handle) {
while (false !== ( $item = readdir($handle) )) { while (false !== ($item = readdir($handle))) {
if ($item != "." && $item != "..") { if ($item != "." && $item != "..") {
if (is_dir("$path/$item")) { if (is_dir("$path/$item")) {
del_target_dir("$path/$item", $delDir); del_target_dir("$path/$item", $delDir);
@ -200,7 +200,7 @@ function system_name(?string $key = '')
'channel_name' => env('system.channel_name', 'channel'), 'channel_name' => env('system.channel_name', 'channel'),
]; ];
if (!empty($key)) { if (!empty($key)) {
return $params[ $key ]; return $params[$key];
} else { } else {
return $params; return $params;
} }
@ -219,11 +219,11 @@ function get_date_by_time(?int $time = null)
function get_start_and_end_time_by_day($day = '') function get_start_and_end_time_by_day($day = '')
{ {
$date = $day ? : date('Y-m-d'); $date = $day ?: date('Y-m-d');
$day_start_time = strtotime($date); $day_start_time = strtotime($date);
//当天结束之间 //当天结束之间
$day_end_time = $day_start_time + 86400; $day_end_time = $day_start_time + 86400;
return [ $day_start_time, $day_end_time ]; return [$day_start_time, $day_end_time];
} }
/** /**
@ -361,7 +361,7 @@ function format_money($number)
function format_float_money($number, $precision = 2) function format_float_money($number, $precision = 2)
{ {
if ($precision > 0) { if ($precision > 0) {
return sprintf('%.' . $precision . 'f', floor($number * ( 10 ** $precision )) / ( 10 ** $precision )); return sprintf('%.' . $precision . 'f', floor($number * (10 ** $precision)) / (10 ** $precision));
} else { } else {
return sprintf('%.' . $precision . 'f', floor($number)); return sprintf('%.' . $precision . 'f', floor($number));
} }
@ -491,19 +491,19 @@ function array_merge2(array $array1, array $array2)
if (array_key_exists($array2_k, $array1)) { if (array_key_exists($array2_k, $array1)) {
if (is_array($array2_v)) { if (is_array($array2_v)) {
foreach ($array2_v as $array2_kk => $array2_vv) { foreach ($array2_v as $array2_kk => $array2_vv) {
if (array_key_exists($array2_kk, $array1[ $array2_k ])) { if (array_key_exists($array2_kk, $array1[$array2_k])) {
if (is_array($array2_vv)) { if (is_array($array2_vv)) {
$array1[ $array2_k ][ $array2_kk ] = array_merge($array1[ $array2_k ][ $array2_kk ], $array2_vv); $array1[$array2_k][$array2_kk] = array_merge($array1[$array2_k][$array2_kk], $array2_vv);
} }
} else { } else {
$array1[ $array2_k ][ $array2_kk ] = $array2_vv; $array1[$array2_k][$array2_kk] = $array2_vv;
} }
} }
} else { } else {
$array1[ $array2_k ] = $array2_v; $array1[$array2_k] = $array2_v;
} }
} else { } else {
$array1[ $array2_k ] = $array2_v; $array1[$array2_k] = $array2_v;
} }
} }
return $array1; return $array1;
@ -550,8 +550,8 @@ function dir_copy(string $src = '', string $dst = '', &$files = [], $exclude_dir
} }
$dir = opendir($src); $dir = opendir($src);
dir_mkdir($dst); dir_mkdir($dst);
while (false !== ( $file = readdir($dir) )) { while (false !== ($file = readdir($dir))) {
if (( $file != '.' ) && ( $file != '..' )) { if (($file != '.') && ($file != '..')) {
if (is_dir($src . '/' . $file)) { if (is_dir($src . '/' . $file)) {
// 排除目录 // 排除目录
if (count($exclude_dirs) && in_array($file, $exclude_dirs)) continue; if (count($exclude_dirs) && in_array($file, $exclude_dirs)) continue;
@ -631,7 +631,7 @@ function parse_sql($content = '', $string = false, $replace = [])
// 多行注释标记 // 多行注释标记
$comment = false; $comment = false;
// 按行分割,兼容多个平台 // 按行分割,兼容多个平台
$content = str_replace([ "\r\n", "\r" ], "\n", $content); $content = str_replace(["\r\n", "\r"], "\n", $content);
$content = explode("\n", trim($content)); $content = explode("\n", trim($content));
// 循环处理每一行 // 循环处理每一行
foreach ($content as $line) { foreach ($content as $line) {
@ -723,10 +723,10 @@ function getFileMap($path, $arr = [])
if ($file_path != '.' && $file_path != '..') { if ($file_path != '.' && $file_path != '..') {
$temp_path = $path . '/' . $file_path; $temp_path = $path . '/' . $file_path;
if (is_dir($temp_path)) { if (is_dir($temp_path)) {
$arr[ $temp_path ] = $file_path; $arr[$temp_path] = $file_path;
$arr = getFileMap($temp_path, $arr); $arr = getFileMap($temp_path, $arr);
} else { } else {
$arr[ $temp_path ] = $file_path; $arr[$temp_path] = $file_path;
} }
} }
} }
@ -751,9 +751,9 @@ function cache_remember(string $name = null, $value = '', $tag = null, $options
$value = Container::getInstance()->invokeFunction($value); $value = Container::getInstance()->invokeFunction($value);
} }
if (is_null($tag)) { if (is_null($tag)) {
Cache::set($name, $value, $options[ 'expire' ] ?? null); Cache::set($name, $value, $options['expire'] ?? null);
} else { } else {
Cache::tag($tag)->set($name, $value, $options[ 'expire' ] ?? null); Cache::tag($tag)->set($name, $value, $options['expire'] ?? null);
} }
return $value; return $value;
@ -778,7 +778,7 @@ function image_to_base64(string $path, $is_delete = false)
{ {
if (!file_exists($path)) return 'image not exist'; if (!file_exists($path)) return 'image not exist';
$mime = getimagesize($path)[ 'mime' ]; $mime = getimagesize($path)['mime'];
$image_data = file_get_contents($path); $image_data = file_get_contents($path);
// 将图片转换为 base64 // 将图片转换为 base64
$base64_data = base64_encode($image_data); $base64_data = base64_encode($image_data);
@ -799,7 +799,7 @@ function image_to_base64(string $path, $is_delete = false)
function get_thumb_images($image, $thumb_type = 'all', bool $is_throw_exception = false) function get_thumb_images($image, $thumb_type = 'all', bool $is_throw_exception = false)
{ {
return ( new CoreImageService() )->thumb($image, $thumb_type, $is_throw_exception); return (new CoreImageService())->thumb($image, $thumb_type, $is_throw_exception);
} }
/** /**
@ -811,10 +811,10 @@ function version_to_int($version)
{ {
$version_array = explode(".", $version); $version_array = explode(".", $version);
$v1 = sprintf('%03s', (int) $version_array[ 0 ] ?? 0); $v1 = sprintf('%03s', (int)$version_array[0] ?? 0);
$v2 = sprintf('%03s', (int) $version_array[ 1 ] ?? 0); $v2 = sprintf('%03s', (int)$version_array[1] ?? 0);
$v3 = sprintf('%03s', (int) $version_array[ 2 ] ?? 0); $v3 = sprintf('%03s', (int)$version_array[2] ?? 0);
return (int) "{$v1}{$v2}{$v3}"; return (int)"{$v1}{$v2}{$v3}";
} }
/** /**
@ -827,13 +827,13 @@ function version_to_string($ver)
if ($ver > 999) { if ($ver > 999) {
if ($ver > 999999) { if ($ver > 999999) {
$ver .= ""; $ver .= "";
$v3 = (int) substr($ver, -3); $v3 = (int)substr($ver, -3);
$v2 = (int) substr($ver, -6, 3); $v2 = (int)substr($ver, -6, 3);
$v1 = (int) substr($ver, 0, -6); $v1 = (int)substr($ver, 0, -6);
} else { } else {
$ver .= ""; $ver .= "";
$v3 = (int) substr($ver, -3); $v3 = (int)substr($ver, -3);
$v2 = (int) substr($ver, 0, -3); $v2 = (int)substr($ver, 0, -3);
$v1 = 0; $v1 = 0;
} }
} else { } else {
@ -889,10 +889,10 @@ function file_copy(string $source_file, string $to_file)
* @param $size * @param $size
* @return string * @return string
*/ */
function qrcode($url, $page, $data, $dir = '', $channel = 'h5', $style = [ 'is_transparent' => true ], $outfile = true) function qrcode($url, $page, $data, $dir = '', $channel = 'h5', $style = ['is_transparent' => true], $outfile = true)
{ {
if ($outfile) { if ($outfile) {
$dir = $dir ? : 'upload' . '/' . 'qrcode/';//二维码默认存储位置 $dir = $dir ?: 'upload' . '/' . 'qrcode/';//二维码默认存储位置
if (!is_dir($dir) && !mkdir($dir, 0777, true) && !is_dir($dir)) { if (!is_dir($dir) && !mkdir($dir, 0777, true) && !is_dir($dir)) {
throw new \RuntimeException(sprintf('Directory "%s" was not created', $dir)); throw new \RuntimeException(sprintf('Directory "%s" was not created', $dir));
} }
@ -911,8 +911,8 @@ function qrcode($url, $page, $data, $dir = '', $channel = 'h5', $style = [ 'is_t
'channel' => $channel, 'channel' => $channel,
'outfile' => $outfile 'outfile' => $outfile
]))); ])));
if (!empty($result[ 0 ])) { if (!empty($result[0])) {
$path = $result[ 0 ]; $path = $result[0];
} }
return $path; return $path;
} }
@ -928,7 +928,7 @@ function qrcode($url, $page, $data, $dir = '', $channel = 'h5', $style = [ 'is_t
*/ */
function poster($id, $type, array $param = [], string $channel = '', bool $is_throw_exception = true) function poster($id, $type, array $param = [], string $channel = '', bool $is_throw_exception = true)
{ {
return ( new \app\service\core\poster\CorePosterService() )->get($id, $type, $param, $channel, $is_throw_exception); return (new \app\service\core\poster\CorePosterService())->get($id, $type, $param, $channel, $is_throw_exception);
} }
/** /**
@ -949,7 +949,7 @@ function is_url($string)
* 获取站点插件 * 获取站点插件
* @return array * @return array
*/ */
function get_site_addons() : array function get_site_addons(): array
{ {
$addons = Cache::get("local_install_addons"); $addons = Cache::get("local_install_addons");
return is_null($addons) ? [] : $addons; return is_null($addons) ? [] : $addons;
@ -957,7 +957,7 @@ function get_site_addons() : array
function get_wap_domain() function get_wap_domain()
{ {
$wap_url = ( new CoreSysConfigService() )->getSceneDomain()[ 'wap_url' ]; $wap_url = (new CoreSysConfigService())->getSceneDomain()['wap_url'];
return $wap_url; return $wap_url;
} }
@ -970,7 +970,7 @@ function get_wap_domain()
*/ */
function str_sub($str, $length = 10, $is_need_apostrophe = true) function str_sub($str, $length = 10, $is_need_apostrophe = true)
{ {
return mb_substr($str, 0, $length, 'UTF-8') . ( $is_need_apostrophe ? '...' : '' ); return mb_substr($str, 0, $length, 'UTF-8') . ($is_need_apostrophe ? '...' : '');
} }
/** /**
@ -1010,10 +1010,10 @@ function get_last_time($time = null)
$text = floor($t / 60) . '分钟前'; //一小时内 $text = floor($t / 60) . '分钟前'; //一小时内
break; break;
case $t < 60 * 60 * 24: case $t < 60 * 60 * 24:
$text = floor($t / ( 60 * 60 )) . '小时前'; // 一天内 $text = floor($t / (60 * 60)) . '小时前'; // 一天内
break; break;
case $t < 60 * 60 * 24 * 3: case $t < 60 * 60 * 24 * 3:
$text = floor($time / ( 60 * 60 * 24 )) == 1 ? '昨天' . date('H:i', $time) : '前天' . date('H:i', $time); //昨天和前天 $text = floor($time / (60 * 60 * 24)) == 1 ? '昨天' . date('H:i', $time) : '前天' . date('H:i', $time); //昨天和前天
break; break;
case $t < 60 * 60 * 24 * 30: case $t < 60 * 60 * 24 * 30:
$text = date('m-d H:i', $time); //一个月内 $text = date('m-d H:i', $time); //一个月内
@ -1028,21 +1028,22 @@ function get_last_time($time = null)
return $text; return $text;
} }
function get_campus_where($user_id){ function get_campus_where($user_id)
{
$where = []; $where = [];
if($user_id == 1){ if ($user_id == 1) {
return $where; return $where;
} }
$personnel = new Personnel(); $personnel = new Personnel();
$role = new CampusPersonRole(); $role = new CampusPersonRole();
$personnel_id = $personnel->where(['sys_user_id' => $user_id])->value('id'); $personnel_id = $personnel->where(['sys_user_id' => $user_id])->value('id');
if(!$personnel_id){ if (!$personnel_id) {
$where[] = ['campus_id','in',[]]; $where[] = ['campus_id', 'in', []];
} }
$campus_ids = $role->where(['person_id' => $personnel_id])->column('campus_id'); $campus_ids = $role->where(['person_id' => $personnel_id])->column('campus_id');
$where[] = ['campus_id','in',$campus_ids]; $where[] = ['campus_id', 'in', $campus_ids];
return $where; return $where;
} }
@ -1074,3 +1075,13 @@ function getModifiedFields(array $oldData, array $newData): array
'new_values' => json_encode($newValues, JSON_UNESCAPED_UNICODE), 'new_values' => json_encode($newValues, JSON_UNESCAPED_UNICODE),
]; ];
} }
// 获取员工编号
function getEmployeeNumber()
{
$personnel = new Personnel();
// 获取最新id
$max_id = $personnel->max('id') + 1;
$max_id = str_pad($max_id, 5, '0', STR_PAD_LEFT);
return date('Ymd') . $max_id;
}

12
niucloud/app/model/classroom/Classroom.php

@ -15,12 +15,9 @@ use core\base\BaseModel;
use think\model\concern\SoftDelete; use think\model\concern\SoftDelete;
use think\model\relation\HasMany; use think\model\relation\HasMany;
use think\model\relation\HasOne; use think\model\relation\HasOne;
use app\model\campus\Campus; use app\model\campus\Campus;
use app\model\personnel\Personnel; use app\model\personnel\Personnel;
use app\model\personnel\Personnel;
/** /**
* 场地管理模型 * 场地管理模型
@ -139,12 +136,7 @@ class Classroom extends BaseModel
$query->where("status", $value); $query->where("status", $value);
} }
} }
public function campus(){ public function campus(){
return $this->hasOne(Campus::class, 'id', 'campus_id')->joinType('left')->withField('campus_name,id')->bind(['campus_id_name'=>'campus_name']); return $this->hasOne(Campus::class, 'id', 'campus_id')->joinType('left')->withField('campus_name,id')->bind(['campus_id_name'=>'campus_name']);
} }
@ -153,8 +145,4 @@ class Classroom extends BaseModel
return $this->hasOne(Personnel::class, 'id', 'head_coach')->joinType('left')->withField('name,id')->bind(['head_coach_name'=>'name']); return $this->hasOne(Personnel::class, 'id', 'head_coach')->joinType('left')->withField('name,id')->bind(['head_coach_name'=>'name']);
} }
public function personnel(){
return $this->hasOne(Personnel::class, 'id', 'assistant_coach')->joinType('left')->withField('name,id')->bind(['assistant_coach_name'=>'name']);
}
} }

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

@ -14,7 +14,6 @@ namespace app\service\admin\classroom;
use app\model\classroom\Classroom; use app\model\classroom\Classroom;
use app\model\campus\Campus; use app\model\campus\Campus;
use app\model\personnel\Personnel; use app\model\personnel\Personnel;
use app\model\personnel\Personnel;
use core\base\BaseAdminService; use core\base\BaseAdminService;
@ -109,10 +108,5 @@ class ClassroomService extends BaseAdminService
return $personnelModel->select()->toArray(); return $personnelModel->select()->toArray();
} }
public function getPersonnelAll(){
$personnelModel = new Personnel();
return $personnelModel->select()->toArray();
}
} }

2
niucloud/app/service/admin/personnel/PersonnelService.php

@ -88,6 +88,8 @@ class PersonnelService extends BaseAdminService
]); ]);
$data['sys_user_id'] = $uid; $data['sys_user_id'] = $uid;
} }
// 员工编号
$data['employee_number'] = getEmployeeNumber();
$res = $this->model->create($data); $res = $this->model->create($data);
Db::commit(); Db::commit();
return $res->id; return $res->id;

Loading…
Cancel
Save