更新系统
|
|
@ -0,0 +1,26 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 学期配置列表
|
||||
export function configLists(params?: Record<string, any>) {
|
||||
return request.get({ url: '/config/list', params })
|
||||
}
|
||||
|
||||
// 学期配置详情
|
||||
export function configDetail(params: Record<string, any>) {
|
||||
return request.get({ url: '/config/detail', params })
|
||||
}
|
||||
|
||||
// 学期配置新增
|
||||
export function configAdd(params: Record<string, any>) {
|
||||
return request.post({ url: '/config/add', params })
|
||||
}
|
||||
|
||||
// 学期配置编辑
|
||||
export function configEdit(params: Record<string, any>) {
|
||||
return request.post({ url: '/config/edit', params })
|
||||
}
|
||||
|
||||
// 学期配置删除
|
||||
export function configDelete(params: Record<string, any>) {
|
||||
return request.post({ url: '/config/del', params })
|
||||
}
|
||||
|
|
@ -57,3 +57,13 @@ export function courseUploadFile(formData: FormData) {
|
|||
}
|
||||
)
|
||||
}
|
||||
|
||||
// 获取可排课时间段
|
||||
export function courseAvailableSlots() {
|
||||
return request.get({ url: '/course.schedule/time' })
|
||||
}
|
||||
|
||||
// 获取当前人数可用教室
|
||||
export function courseAvailableRooms(params: Record<string, any>) {
|
||||
return request.get({ url: '/course.schedule/classroom', params })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 教学任务主列表
|
||||
export function taskLists(params?: Record<string, any>) {
|
||||
return request.get({ url: '/task/list', params })
|
||||
}
|
||||
|
||||
// 教学任务主详情
|
||||
export function taskDetail(params: Record<string, any>) {
|
||||
return request.get({ url: '/task/detail', params })
|
||||
}
|
||||
|
||||
// 教学任务主新增
|
||||
export function taskAdd(params: Record<string, any>) {
|
||||
return request.post({ url: '/task/add', params })
|
||||
}
|
||||
|
||||
// 教学任务主编辑
|
||||
export function taskEdit(params: Record<string, any>) {
|
||||
return request.post({ url: '/task/edit', params })
|
||||
}
|
||||
|
||||
// 教学任务主删除
|
||||
export function taskDelete(params: Record<string, any>) {
|
||||
return request.post({ url: '/task/del', params })
|
||||
}
|
||||
|
||||
// 班级教学任务查询
|
||||
export function taskSearch(params: Record<string, any>) {
|
||||
return request.get({ url: '/task.progress/detail', params })
|
||||
}
|
||||
|
||||
// 班级教学任务课程列表
|
||||
export function taskCourseList(params: Record<string, any>) {
|
||||
return request.get({ url: '/task/course', params })
|
||||
}
|
||||
|
||||
// 班级教学任务教师列表
|
||||
export function taskTeacherList(params: Record<string, any>) {
|
||||
return request.get({ url: '/task', params })
|
||||
}
|
||||
|
|
@ -39,3 +39,13 @@ export function teacherCourseAdd(params: Record<string, any>) {
|
|||
export function teacherCourseDelete(params: Record<string, any>) {
|
||||
return request.post({ url: '/teacher/course/del', params })
|
||||
}
|
||||
|
||||
// 配置教师角色
|
||||
export function teacherConfigRole(params: Record<string, any>) {
|
||||
return request.post({ url: '/teacher/config', params })
|
||||
}
|
||||
|
||||
// 获取教师角色配置
|
||||
export function teacherGetConfig() {
|
||||
return request.get({ url: '/teacher/get.config' })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 获取当前学年信息
|
||||
export function timeAcademicYear() {
|
||||
return request.get({ url: '/time/academicYear' })
|
||||
}
|
||||
|
||||
// 获取当前日期时间
|
||||
export function timeCurrentDate() {
|
||||
return request.get({ url: '/time/currentDate' })
|
||||
}
|
||||
|
||||
// 获取当前学期信息
|
||||
export function timeCurrentSemester() {
|
||||
return request.get({ url: '/time/currentSemester' })
|
||||
}
|
||||
|
||||
// 获取刷新配置
|
||||
export function timeRefreshConfig() {
|
||||
return request.get({ url: '/time/refreshConfig' })
|
||||
}
|
||||
|
|
@ -32,6 +32,9 @@
|
|||
<full-screen />
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="navbar-item">
|
||||
<Time />
|
||||
</div>
|
||||
<div class="navbar-item">
|
||||
<user-drop-down />
|
||||
</div>
|
||||
|
|
@ -63,6 +66,7 @@ import Fold from './fold.vue'
|
|||
import FullScreen from './full-screen.vue'
|
||||
import MultipleTabs from './multiple-tabs.vue'
|
||||
import Refresh from './refresh.vue'
|
||||
import Time from './time.vue'
|
||||
import UserDropDown from './user-drop-down.vue'
|
||||
|
||||
const appStore = useAppStore()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,113 @@
|
|||
<template>
|
||||
<el-tooltip class="box-item" effect="dark" :content="tooltipContent" placement="bottom">
|
||||
<div class="time h-full cursor-pointer flex items-center px-2">
|
||||
<div class="time-info">
|
||||
<div class="date-time">{{ dateTime }}</div>
|
||||
<div class="semester-week">{{ semesterName }}第{{ weekNumber }}周</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||
|
||||
import { timeCurrentDate, timeCurrentSemester } from '@/api/time'
|
||||
|
||||
// 定义接口类型
|
||||
interface DateInfo {
|
||||
dateTime: string
|
||||
date: string
|
||||
dayOfWeek: string
|
||||
weekOfYear: number
|
||||
}
|
||||
|
||||
interface SemesterInfo {
|
||||
semesterName: string
|
||||
displayName: string
|
||||
weekNumber: number
|
||||
}
|
||||
|
||||
// 响应式数据
|
||||
const dateTime = ref('')
|
||||
const semesterName = ref('')
|
||||
const weekNumber = ref(0)
|
||||
|
||||
// tooltip提示内容(与其他组件保持一致的交互提示)
|
||||
const tooltipContent = computed(() => `当前时间:${dateTime.value}`)
|
||||
|
||||
// 获取日期时间数据
|
||||
const fetchDateTime = async () => {
|
||||
try {
|
||||
const res = await timeCurrentDate()
|
||||
if (res) {
|
||||
const data = res as DateInfo
|
||||
dateTime.value = `${data.date} ${data.dayOfWeek}`
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取时间失败', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学期数据
|
||||
const fetchSemester = async () => {
|
||||
try {
|
||||
const res = await timeCurrentSemester()
|
||||
if (res) {
|
||||
const data = res as SemesterInfo
|
||||
semesterName.value = data.displayName
|
||||
weekNumber.value = data.weekNumber
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取学期信息失败', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 定时刷新时间(每分钟)
|
||||
let timer: number | null = null
|
||||
|
||||
onMounted(() => {
|
||||
fetchDateTime()
|
||||
fetchSemester()
|
||||
timer = window.setInterval(fetchDateTime, 60000)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
if (timer) {
|
||||
clearInterval(timer)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.time {
|
||||
.time-info {
|
||||
text-align: right;
|
||||
line-height: 1.2;
|
||||
|
||||
.date-time {
|
||||
font-size: 14px;
|
||||
color: var(--text-color-primary);
|
||||
}
|
||||
|
||||
.semester-week {
|
||||
font-size: 12px;
|
||||
color: var(--text-color-secondary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 适配移动端显示(与其他组件保持一致的响应式处理)
|
||||
@media (max-width: 768px) {
|
||||
.time {
|
||||
.time-info {
|
||||
.date-time {
|
||||
font-size: 12px;
|
||||
}
|
||||
.semester-week {
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,176 @@
|
|||
<template>
|
||||
<div class="edit-popup">
|
||||
<popup
|
||||
ref="popupRef"
|
||||
:title="popupTitle"
|
||||
:async="true"
|
||||
width="550px"
|
||||
:clickModalClose="true"
|
||||
@confirm="handleSubmit"
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-form ref="formRef" :model="formData" label-width="84px" :rules="formRules">
|
||||
<el-form-item label="" prop="id">
|
||||
<el-input v-model="formData.id" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
<el-form-item label="学年,如:2025-2026" prop="academicYear">
|
||||
<el-input v-model="formData.academicYear" placeholder="请输入学年,如:2025-2026" />
|
||||
</el-form-item>
|
||||
<el-form-item label="学期代码:SPRING/AUTUMN" prop="semesterCode">
|
||||
<el-input v-model="formData.semesterCode" placeholder="请输入学期代码:SPRING/AUTUMN" />
|
||||
</el-form-item>
|
||||
<el-form-item label="学期名称" prop="semesterName">
|
||||
<el-input v-model="formData.semesterName" placeholder="请输入学期名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="学期开始日期" prop="startDate">
|
||||
<el-date-picker
|
||||
class="flex-1 !flex"
|
||||
v-model="formData.startDate"
|
||||
type="datetime"
|
||||
clearable
|
||||
value-format="YYYY-MM-DD hh:mm:ss"
|
||||
placeholder="请选择学期开始日期"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="学期结束日期" prop="endDate">
|
||||
<el-date-picker
|
||||
class="flex-1 !flex"
|
||||
v-model="formData.endDate"
|
||||
type="datetime"
|
||||
clearable
|
||||
value-format="YYYY-MM-DD hh:mm:ss"
|
||||
placeholder="请选择学期结束日期"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态:1-有效,0-无效" prop="status">
|
||||
<el-radio-group v-model="formData.status" placeholder="请选择状态:1-有效,0-无效">
|
||||
<el-radio label="0">请选择字典生成</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</popup>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import type { PropType } from 'vue'
|
||||
|
||||
import { configAdd, configDetail, configEdit } from '@/api/config'
|
||||
import Popup from '@/components/popup/index.vue'
|
||||
import feedback from '@/utils/feedback'
|
||||
defineProps({
|
||||
dictData: {
|
||||
type: Object as PropType<Record<string, any[]>>,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
const emit = defineEmits(['success', 'close'])
|
||||
const formRef = shallowRef<FormInstance>()
|
||||
const popupRef = shallowRef<InstanceType<typeof Popup>>()
|
||||
const mode = ref('add')
|
||||
const popupTitle = computed(() => {
|
||||
return mode.value == 'edit' ? '编辑学期配置' : '新增学期配置'
|
||||
})
|
||||
|
||||
const formData = reactive({
|
||||
id: '',
|
||||
academicYear: '',
|
||||
semesterCode: '',
|
||||
semesterName: '',
|
||||
startDate: '',
|
||||
endDate: '',
|
||||
status: '',
|
||||
})
|
||||
|
||||
const formRules = {
|
||||
id: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入',
|
||||
trigger: ['blur']
|
||||
}
|
||||
],
|
||||
academicYear: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入学年,如:2025-2026',
|
||||
trigger: ['blur']
|
||||
}
|
||||
],
|
||||
semesterCode: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入学期代码:SPRING/AUTUMN',
|
||||
trigger: ['blur']
|
||||
}
|
||||
],
|
||||
semesterName: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入学期名称',
|
||||
trigger: ['blur']
|
||||
}
|
||||
],
|
||||
startDate: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择学期开始日期',
|
||||
trigger: ['blur']
|
||||
}
|
||||
],
|
||||
endDate: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择学期结束日期',
|
||||
trigger: ['blur']
|
||||
}
|
||||
],
|
||||
status: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择状态:1-有效,0-无效',
|
||||
trigger: ['blur']
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
const handleSubmit = async () => {
|
||||
await formRef.value?.validate()
|
||||
const data: any = { ...formData }
|
||||
mode.value == 'edit' ? await configEdit(data) : await configAdd(data)
|
||||
popupRef.value?.close()
|
||||
feedback.msgSuccess('操作成功')
|
||||
emit('success')
|
||||
}
|
||||
|
||||
const open = (type = 'add') => {
|
||||
mode.value = type
|
||||
popupRef.value?.open()
|
||||
}
|
||||
|
||||
const setFormData = async (data: Record<string, any>) => {
|
||||
for (const key in formData) {
|
||||
if (data[key] != null && data[key] != undefined) {
|
||||
//@ts-ignore
|
||||
formData[key] = data[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const getDetail = async (row: Record<string, any>) => {
|
||||
const data = await configDetail({
|
||||
id: row.id
|
||||
})
|
||||
setFormData(data)
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
emit('close')
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
open,
|
||||
setFormData,
|
||||
getDetail
|
||||
})
|
||||
</script>
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
<template>
|
||||
<div class="index-lists">
|
||||
<el-card class="!border-none" shadow="never">
|
||||
<el-form ref="formRef" class="mb-[-16px]" :model="queryParams" :inline="true">
|
||||
<el-form-item label="学年,如:2025-2026" prop="academicYear">
|
||||
<el-input class="w-[280px]" v-model="queryParams.academicYear" />
|
||||
</el-form-item>
|
||||
<el-form-item label="学期代码:SPRING/AUTUMN" prop="semesterCode">
|
||||
<el-input class="w-[280px]" v-model="queryParams.semesterCode" />
|
||||
</el-form-item>
|
||||
<el-form-item label="学期名称" prop="semesterName">
|
||||
<el-input class="w-[280px]" v-model="queryParams.semesterName" />
|
||||
</el-form-item>
|
||||
<el-form-item label="学期开始日期" prop="startDate">
|
||||
<daterange-picker
|
||||
v-model:startTime="queryParams.createTimeStart"
|
||||
v-model:endTime="queryParams.createTimeEnd"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="学期结束日期" prop="endDate">
|
||||
<daterange-picker
|
||||
v-model:startTime="queryParams.createTimeStart"
|
||||
v-model:endTime="queryParams.createTimeEnd"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态:1-有效,0-无效" prop="status">
|
||||
<el-select
|
||||
v-model="queryParams.status"
|
||||
class="w-[280px]"
|
||||
clearable
|
||||
>
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="resetPage">查询</el-button>
|
||||
<el-button @click="resetParams">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<el-card class="!border-none mt-4" shadow="never">
|
||||
<div>
|
||||
<el-button v-perms="['config:add']" type="primary" @click="handleAdd()">
|
||||
<template #icon>
|
||||
<icon name="el-icon-Plus" />
|
||||
</template>
|
||||
新增
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table
|
||||
class="mt-4"
|
||||
size="large"
|
||||
v-loading="pager.loading"
|
||||
:data="pager.lists"
|
||||
>
|
||||
<el-table-column label="学年,如:2025-2026" prop="academicYear" min-width="100" />
|
||||
<el-table-column label="学期代码:SPRING/AUTUMN" prop="semesterCode" min-width="100" />
|
||||
<el-table-column label="学期名称" prop="semesterName" min-width="100" />
|
||||
<el-table-column label="学期开始日期" prop="startDate" min-width="100" />
|
||||
<el-table-column label="学期结束日期" prop="endDate" min-width="100" />
|
||||
<el-table-column label="状态:1-有效,0-无效" prop="status" min-width="100" />
|
||||
<el-table-column label="" prop="createTime" min-width="100" />
|
||||
<el-table-column label="" prop="updateTime" min-width="100" />
|
||||
<el-table-column label="操作" width="120" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
v-perms="['config:edit']"
|
||||
type="primary"
|
||||
link
|
||||
@click="handleEdit(row)"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
v-perms="['config:del']"
|
||||
type="danger"
|
||||
link
|
||||
@click="handleDelete(row.id)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="flex justify-end mt-4">
|
||||
<pagination v-model="pager" @change="getLists" />
|
||||
</div>
|
||||
</el-card>
|
||||
<edit-popup v-if="showEdit" ref="editRef" @success="getLists" @close="showEdit = false" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup name="config">
|
||||
import { configDelete, configLists } from '@/api/config'
|
||||
import { usePaging } from '@/hooks/usePaging'
|
||||
import feedback from '@/utils/feedback'
|
||||
|
||||
import EditPopup from './edit.vue'
|
||||
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
|
||||
const showEdit = ref(false)
|
||||
const queryParams = reactive({
|
||||
academicYear: '',
|
||||
semesterCode: '',
|
||||
semesterName: '',
|
||||
startDateStart: '',
|
||||
startDateEnd: '',
|
||||
endDateStart: '',
|
||||
endDateEnd: '',
|
||||
status: '',
|
||||
createTimeStart: '',
|
||||
createTimeEnd: ''
|
||||
})
|
||||
|
||||
const { pager, getLists, resetPage, resetParams } = usePaging({
|
||||
fetchFun: configLists,
|
||||
params: queryParams
|
||||
})
|
||||
|
||||
const handleAdd = async () => {
|
||||
showEdit.value = true
|
||||
await nextTick()
|
||||
editRef.value?.open('add')
|
||||
}
|
||||
|
||||
const handleEdit = async (data: any) => {
|
||||
showEdit.value = true
|
||||
await nextTick()
|
||||
editRef.value?.open('edit')
|
||||
editRef.value?.getDetail(data)
|
||||
}
|
||||
|
||||
const handleDelete = async (id: number) => {
|
||||
await feedback.confirm('确定要删除?')
|
||||
await configDelete({ id })
|
||||
feedback.msgSuccess('删除成功')
|
||||
getLists()
|
||||
}
|
||||
|
||||
getLists()
|
||||
</script>
|
||||
|
|
@ -8,6 +8,22 @@
|
|||
</template>
|
||||
新增
|
||||
</el-button>
|
||||
<el-select v-model="teacher.id" class="w-[280px] ml-10" clearable>
|
||||
<el-option
|
||||
v-for="cole in getRoleLists"
|
||||
:key="cole.id"
|
||||
:value="cole.id"
|
||||
:label="cole.name"
|
||||
/>
|
||||
</el-select>
|
||||
<el-button
|
||||
v-perms="['teacher/config']"
|
||||
class="ml-1"
|
||||
type="primary"
|
||||
@click="configTeacher"
|
||||
>
|
||||
配置教师角色
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="mt-4" v-loading="pager.loading">
|
||||
<div>
|
||||
|
|
@ -64,7 +80,8 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup name="role">
|
||||
import { roleDelete, roleLists } from '@/api/perms/role'
|
||||
import { roleAll, roleDelete, roleLists } from '@/api/perms/role'
|
||||
import { teacherConfigRole, teacherGetConfig } from '@/api/teacher'
|
||||
import { usePaging } from '@/hooks/usePaging'
|
||||
import feedback from '@/utils/feedback'
|
||||
|
||||
|
|
@ -75,9 +92,27 @@ const editRef = shallowRef<InstanceType<typeof EditPopup>>()
|
|||
const authRef = shallowRef<InstanceType<typeof AuthPopup>>()
|
||||
const showEdit = ref(false)
|
||||
const showAuth = ref(false)
|
||||
const getRoleLists = ref<Array<{ id: number; name: string }>>([])
|
||||
const teacher = reactive({
|
||||
id: ''
|
||||
})
|
||||
const { pager, getLists } = usePaging({
|
||||
fetchFun: roleLists
|
||||
})
|
||||
|
||||
const fetchRoleLists = async () => {
|
||||
try {
|
||||
const res = await roleAll(null)
|
||||
const config = await teacherGetConfig()
|
||||
teacher.id = config.id
|
||||
console.log('res:', res)
|
||||
getRoleLists.value = res
|
||||
console.log('getRoleLists:', getRoleLists)
|
||||
} catch (err) {
|
||||
feedback.msgError('获取学期列表失败')
|
||||
}
|
||||
}
|
||||
|
||||
const handleAdd = async () => {
|
||||
showEdit.value = true
|
||||
await nextTick()
|
||||
|
|
@ -105,5 +140,10 @@ const handleDelete = async (id: number) => {
|
|||
getLists()
|
||||
}
|
||||
|
||||
const configTeacher = async () => {
|
||||
await teacherConfigRole(teacher)
|
||||
}
|
||||
|
||||
getLists()
|
||||
fetchRoleLists()
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,570 @@
|
|||
<template>
|
||||
<div class="index-lists">
|
||||
<el-card class="!border-none" shadow="never">
|
||||
<el-form ref="formRef" class="mb-[-16px]" :model="queryParams" :inline="true">
|
||||
<el-form-item label="班级" prop="classId">
|
||||
<el-select
|
||||
v-model="queryParams.classId"
|
||||
placeholder="请输入班级名称搜索"
|
||||
:remote="true"
|
||||
:remote-method="handleClassRemoteSearch"
|
||||
:loading="classSearchLoading"
|
||||
filterable
|
||||
clearable
|
||||
remote-show-suffix
|
||||
class="w-[280px]"
|
||||
@change="handleClassChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in getClassLists.lists"
|
||||
:key="item.id"
|
||||
:value="item.id"
|
||||
:label="item.className"
|
||||
@click="handleStudentClick(item)"
|
||||
>
|
||||
<template #default>
|
||||
<span
|
||||
style="color: var(--el-text-color-secondary); font-size: 13px"
|
||||
>
|
||||
{{ item.classCode }}
|
||||
</span>
|
||||
<span style="margin-left: 8px">{{ item.className }}</span>
|
||||
</template>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学期" prop="semesterId">
|
||||
<el-select
|
||||
v-model="queryParams.semesterId"
|
||||
class="w-[280px]"
|
||||
clearable
|
||||
@change="handleSemesterChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="college in getConfigLists.lists"
|
||||
:key="college.id"
|
||||
:value="college.id"
|
||||
:label="college.config"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<div class="flex">
|
||||
<el-card class="!border-none mt-4 mr-4" shadow="never" style="width: 75%">
|
||||
<el-table class="mb-4" size="large" v-loading="loading" :data="tableData" border>
|
||||
<!-- 序号列(包含时间、类型、状态) -->
|
||||
<el-table-column label="节次" width="50" class-name="first-column" align="left">
|
||||
<template #default="{ $index }">
|
||||
<div class="index-info">
|
||||
<div class="index-details">
|
||||
<div class="index-number">{{ $index + 1 }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="时间" width="80" class-name="first-column" align="left">
|
||||
<template #default="{ row }">
|
||||
<div class="index-info">
|
||||
<div class="index-details">
|
||||
<div class="flex justify-center" style="font-size: 12px">
|
||||
{{ getRowStartTime(row) }}
|
||||
</div>
|
||||
<div class="flex justify-center" style="font-size: 6px">——</div>
|
||||
<div class="flex justify-center" style="font-size: 12px">
|
||||
{{ getRowEndTime(row) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="星期一" min-width="80" align="center">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row[1]" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="星期二" min-width="80" align="center">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row[2]" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="星期三" min-width="80" align="center">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row[3]" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="星期四" min-width="80" align="center">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row[4]" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="星期五" min-width="80" align="center">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row[5]" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="星期六" min-width="80" align="center">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row[6]" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="星期日" min-width="80" align="center">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row[7]" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
<el-card class="mt-4" shadow="never" style="width: 24%">
|
||||
<!-- 改为标签页 -->
|
||||
<el-tabs v-model="activeTab" style="margin-top: -10px">
|
||||
<el-tab-pane label="课程列表" name="course" class="course-list-container">
|
||||
<div class="mb-4">
|
||||
<h3 class="text-lg font-semibold">课程列表</h3>
|
||||
<p class="text-sm text-gray-500 mt-1">当前班级和学期下的可用课程</p>
|
||||
</div>
|
||||
<div
|
||||
v-if="getCourseLists.lists.length === 0"
|
||||
class="text-center py-8 text-gray-400"
|
||||
>
|
||||
暂无课程数据,请选择班级和学期
|
||||
</div>
|
||||
<div v-else class="space-y-4 max-h-[700px] overflow-y-auto">
|
||||
<el-card
|
||||
v-for="item in getCourseLists.lists"
|
||||
:key="item.id"
|
||||
shadow="hover"
|
||||
class="cursor-pointer hover:bg-blue-50 transition-colors duration-200"
|
||||
@click="handleCourseClick(item)"
|
||||
>
|
||||
<div class="p-0">
|
||||
<div class="flex justify-between items-start">
|
||||
<div>
|
||||
<h4 class="font-medium text-sm">
|
||||
课程:{{ item.courseName }}
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between text-xs text-gray-600">
|
||||
<span>教师: {{ item.teacherName }}</span>
|
||||
<span>周学时: {{ item.totalWeeks }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="selectedCourseId === item.id"
|
||||
class="pt-3 border-t border-gray-100"
|
||||
>
|
||||
<div class="text-xs text-gray-700">
|
||||
<div class="flex items-center mb-1">
|
||||
<span class="font-medium">总学时:</span>
|
||||
<span>{{ item.totalHours }}</span>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<span class="font-medium">周数:</span>
|
||||
<span>{{ item.totalWeeks }}周</span>
|
||||
</div>
|
||||
<p
|
||||
class="text-xs text-gray-500"
|
||||
style="color: darkgray"
|
||||
>
|
||||
{{ item.taskCode }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
<div class="flex justify-end mt-6">
|
||||
<pagination
|
||||
layout="prev, pager, next"
|
||||
v-model="pager"
|
||||
@change="getLists"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="教室列表" name="classroom" class="course-list-container">
|
||||
<div class="mb-4">
|
||||
<h3 class="text-lg font-semibold">教室列表</h3>
|
||||
<p class="text-sm text-gray-500 mt-1">当前可用的教室资源</p>
|
||||
</div>
|
||||
<div
|
||||
v-if="getRoomLists.lists.length === 0"
|
||||
class="text-center py-8 text-gray-400"
|
||||
>
|
||||
暂无教室数据
|
||||
</div>
|
||||
<div v-else class="space-y-4 max-h-[700px] overflow-y-auto">
|
||||
<el-card
|
||||
v-for="item in getRoomLists.lists"
|
||||
:key="item.id"
|
||||
shadow="hover"
|
||||
class="cursor-pointer hover:bg-blue-50 transition-colors duration-200"
|
||||
@click="handleClassroomClick(item)"
|
||||
>
|
||||
<div class="p-0">
|
||||
<div class="flex justify-between items-start">
|
||||
<div>
|
||||
<h4 class="font-medium text-sm">
|
||||
教室:{{ item.classroomName }}
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between text-xs text-gray-600">
|
||||
<span>类型: {{ item.classroomTypeName }}</span>
|
||||
<span>容量: {{ item.capacity }}人</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="selectedRoomId === item.id"
|
||||
class="pt-3 border-t border-gray-100"
|
||||
>
|
||||
<div class="text-xs text-gray-700">
|
||||
<div class="flex items-center mb-1">
|
||||
<span class="font-medium">编号:</span>
|
||||
<span>{{ item.classroomCode }}</span>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<span class="font-medium">位置:</span>
|
||||
<span>{{ item.location }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { computed, reactive, ref } from 'vue'
|
||||
|
||||
import { classLists } from '@/api/class'
|
||||
import { configLists } from '@/api/config'
|
||||
import { courseAvailableRooms, courseAvailableSlots } from '@/api/course'
|
||||
import { taskLists } from '@/api/task'
|
||||
import { timeCurrentSemester } from '@/api/time'
|
||||
import { usePaging } from '@/hooks/usePaging'
|
||||
import feedback from '@/utils/feedback'
|
||||
|
||||
const getConfigLists = ref<{
|
||||
lists: Array<{
|
||||
id: number
|
||||
academicYear: string
|
||||
semesterCode: string
|
||||
config: string
|
||||
startDate: string
|
||||
endDate: string
|
||||
}>
|
||||
}>({ lists: [] })
|
||||
const getClassLists = ref<{
|
||||
lists: Array<{ id: number; className: string; classCode: string; maxStudentCount: number }>
|
||||
}>({ lists: [] })
|
||||
const classSearchLoading = ref(false)
|
||||
const classSearchTimer = ref<number | null>(null)
|
||||
const activeTab = ref('course')
|
||||
|
||||
// 时间段数据
|
||||
const getTimeData = ref<{
|
||||
lists: Array<{
|
||||
timeSlotId: number
|
||||
classId: number
|
||||
classroomId: number
|
||||
courseId: number
|
||||
semesterId: number
|
||||
teacherId: number
|
||||
}>
|
||||
}>({ lists: [] })
|
||||
|
||||
// 课程列表数据
|
||||
const getCourseLists = ref<{
|
||||
lists: Array<{
|
||||
id: number
|
||||
courseId: number
|
||||
courseName: string
|
||||
taskCode: string
|
||||
totalHours: number
|
||||
teacherId: number
|
||||
teacherName: string
|
||||
totalWeeks: number
|
||||
}>
|
||||
}>({ lists: [] })
|
||||
// 课程加载状态
|
||||
const courseLoading = ref(false)
|
||||
// 选中的课程ID
|
||||
const selectedCourseId = ref<number | null>(null)
|
||||
|
||||
// 教室列表数据
|
||||
const getRoomLists = ref<{
|
||||
lists: Array<{
|
||||
id: number
|
||||
classroomName: string
|
||||
classroomCode: string
|
||||
classroomTypeName: string
|
||||
location: string
|
||||
capacity: number
|
||||
}>
|
||||
}>({ lists: [] })
|
||||
// 教室加载状态
|
||||
const roomLoading = ref(false)
|
||||
// 选中的教室ID
|
||||
const selectedRoomId = ref<number | null>(null)
|
||||
|
||||
const loading = ref(false)
|
||||
const queryParams = reactive({
|
||||
classId: '',
|
||||
semesterId: '',
|
||||
maxStudentCount: 0
|
||||
})
|
||||
|
||||
// 班级变化处理
|
||||
const handleClassChange = async () => {
|
||||
if (queryParams.classId && queryParams.semesterId) {
|
||||
await fetchCourseLists()
|
||||
await fetchRoomLists()
|
||||
}
|
||||
}
|
||||
|
||||
const handleStudentClick = (item: any) => {
|
||||
queryParams.maxStudentCount = item.maxStudentCount || 0
|
||||
|
||||
}
|
||||
|
||||
// 学期变化处理
|
||||
const handleSemesterChange = async () => {
|
||||
if (queryParams.classId && queryParams.semesterId) {
|
||||
await fetchCourseLists()
|
||||
}
|
||||
}
|
||||
|
||||
// 获取班级列表
|
||||
const fetchClassLists = async (params: string) => {
|
||||
try {
|
||||
const res = await classLists({
|
||||
className: params.trim()
|
||||
})
|
||||
getClassLists.value = res
|
||||
} catch (err) {
|
||||
feedback.msgError('获取课程列表失败')
|
||||
getClassLists.value = { lists: [] }
|
||||
} finally {
|
||||
classSearchLoading.value = false
|
||||
}
|
||||
}
|
||||
const handleClassRemoteSearch = (keyword: string) => {
|
||||
if (classSearchTimer.value) clearTimeout(classSearchTimer.value)
|
||||
|
||||
classSearchTimer.value = setTimeout(async () => {
|
||||
classSearchLoading.value = true
|
||||
await fetchClassLists(keyword)
|
||||
}, 300)
|
||||
}
|
||||
|
||||
// 获取学期列表
|
||||
const fetchConfigLists = async () => {
|
||||
try {
|
||||
const res = await configLists()
|
||||
const handleData = JSON.parse(JSON.stringify(res))
|
||||
handleData.lists = handleData.lists.map((item: any) => ({
|
||||
...item,
|
||||
config: `${item.academicYear}${item.semesterCode == 'SPRING' ? ' 春' : ' 秋'}`
|
||||
}))
|
||||
getConfigLists.value = handleData
|
||||
await fetchSemester()
|
||||
} catch (err) {
|
||||
feedback.msgError('获取学期列表失败')
|
||||
}
|
||||
}
|
||||
|
||||
const fetchSemester = async () => {
|
||||
try {
|
||||
const res = await timeCurrentSemester()
|
||||
if (res) {
|
||||
queryParams.semesterId = res.id
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取学期信息失败', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取课程列表
|
||||
const fetchCourseLists = async () => {
|
||||
try {
|
||||
courseLoading.value = true
|
||||
// 使用taskLists接口获取课程列表
|
||||
const response = await taskLists({
|
||||
classId: queryParams.classId,
|
||||
semesterId: queryParams.semesterId
|
||||
})
|
||||
// 映射新接口返回的数据格式到组件所需格式
|
||||
const mappedCourses = response.lists.map(
|
||||
(task: {
|
||||
id: any
|
||||
courseId: any
|
||||
courseName: any
|
||||
taskCode: any
|
||||
weeklyHours: number
|
||||
totalWeeks: number
|
||||
teacherId: any
|
||||
teacherName: any
|
||||
}) => ({
|
||||
id: task.id,
|
||||
courseId: task.courseId,
|
||||
courseName: task.courseName,
|
||||
taskCode: task.taskCode,
|
||||
totalHours: task.weeklyHours * task.totalWeeks, // 总学时=周学时×总周数
|
||||
teacherId: task.teacherId,
|
||||
teacherName: task.teacherName,
|
||||
totalWeeks: task.totalWeeks
|
||||
})
|
||||
)
|
||||
getCourseLists.value = { lists: mappedCourses }
|
||||
} catch (err) {
|
||||
console.log('获取课程列表失败', err)
|
||||
feedback.msgError('获取课程列表失败')
|
||||
getCourseLists.value = { lists: [] }
|
||||
} finally {
|
||||
courseLoading.value = false
|
||||
}
|
||||
}
|
||||
// 课程点击处理
|
||||
const handleCourseClick = (course: any) => {
|
||||
selectedCourseId.value = selectedCourseId.value === course.id ? null : course.id
|
||||
}
|
||||
|
||||
// 获取教室列表
|
||||
const fetchRoomLists = async () => {
|
||||
try {
|
||||
roomLoading.value = true
|
||||
// 使用taskLists接口获取教室列表
|
||||
const response = await courseAvailableRooms({
|
||||
num: queryParams.maxStudentCount
|
||||
})
|
||||
// 映射新接口返回的数据格式到组件所需格式
|
||||
const mappedRooms = response.map(
|
||||
(task: {
|
||||
id: number
|
||||
classroomName: string
|
||||
classroomCode: string
|
||||
classroomTypeName: string
|
||||
location: string
|
||||
capacity: number
|
||||
}) => ({
|
||||
id: task.id,
|
||||
classroomName: task.classroomName,
|
||||
classroomCode: task.classroomCode,
|
||||
classroomTypeName: task.classroomTypeName,
|
||||
location: task.location,
|
||||
capacity: task.capacity
|
||||
})
|
||||
)
|
||||
getRoomLists.value = { lists: mappedRooms }
|
||||
} catch (err) {
|
||||
console.log('获取教室列表失败', err)
|
||||
feedback.msgError('获取教室列表失败')
|
||||
getRoomLists.value = { lists: [] }
|
||||
} finally {
|
||||
roomLoading.value = false
|
||||
}
|
||||
}
|
||||
// 教室点击处理
|
||||
const handleClassroomClick = (classroom: any) => {
|
||||
selectedRoomId.value = selectedRoomId.value === classroom.id ? null : classroom.id
|
||||
}
|
||||
|
||||
// 清理定时器
|
||||
onBeforeUnmount(() => {
|
||||
if (classSearchTimer.value) clearTimeout(classSearchTimer.value)
|
||||
})
|
||||
|
||||
// 所有数据列表
|
||||
const allLists = ref<any[]>([])
|
||||
|
||||
const { pager, getLists } = usePaging({
|
||||
fetchFun: taskLists,
|
||||
params: queryParams,
|
||||
size: 7
|
||||
})
|
||||
|
||||
// 请求数据列表
|
||||
const getTimeLists = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await courseAvailableSlots()
|
||||
allLists.value = res
|
||||
return Promise.resolve(res)
|
||||
} catch (err) {
|
||||
return Promise.reject(err)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 处理表格数据,按节次分组,构建星期矩阵
|
||||
const tableData = computed(() => {
|
||||
const timeSlotMap = new Map<string, Record<number, any>>()
|
||||
allLists.value.forEach((item) => {
|
||||
const key = `${item.startTime}-${item.endTime}`
|
||||
if (!timeSlotMap.has(key)) {
|
||||
timeSlotMap.set(key, {})
|
||||
}
|
||||
const slotGroup = timeSlotMap.get(key)!
|
||||
slotGroup[item.dayOfWeek] = item
|
||||
})
|
||||
|
||||
return Array.from(timeSlotMap.values()).sort((a, b) => {
|
||||
const aTime = Object.values(a)[0]?.startTime || ''
|
||||
const bTime = Object.values(b)[0]?.startTime || ''
|
||||
return aTime.localeCompare(bTime)
|
||||
})
|
||||
})
|
||||
|
||||
const getRowBaseInfo = (row: Record<number, any>) => {
|
||||
return Object.values(row).find((item) => item) || {}
|
||||
}
|
||||
|
||||
const getRowStartTime = (row: Record<number, any>) => {
|
||||
const baseInfo = getRowBaseInfo(row)
|
||||
const start = baseInfo?.startTime
|
||||
if (start == null) return ''
|
||||
const s = String(start)
|
||||
return s.length > 3 ? s.slice(0, -3) : ''
|
||||
}
|
||||
|
||||
const getRowEndTime = (row: Record<number, any>) => {
|
||||
const baseInfo = getRowBaseInfo(row)
|
||||
const end = baseInfo?.endTime
|
||||
if (end == null) return ''
|
||||
const s = String(end)
|
||||
return s.length > 3 ? s.slice(0, -3) : ''
|
||||
}
|
||||
|
||||
// 初始化时获取数据
|
||||
getTimeLists()
|
||||
fetchClassLists('')
|
||||
fetchConfigLists()
|
||||
</script>
|
||||
<style scoped>
|
||||
:deep(.first-column) {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
.course-list-container {
|
||||
height: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.course-list-container .el-card {
|
||||
border: 1px solid #e4e7ed;
|
||||
}
|
||||
|
||||
.course-list-container .el-card:hover {
|
||||
border-color: #409eff;
|
||||
}
|
||||
|
||||
:deep(.el-tag) {
|
||||
height: 24px;
|
||||
line-height: 22px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -37,7 +37,12 @@
|
|||
<el-input class="w-[280px]" v-model="queryParams.headTeacherId" />
|
||||
</el-form-item>
|
||||
<el-form-item label="班级状态" prop="classStatus">
|
||||
<el-select v-model="queryParams.classStatus" class="w-[280px]" clearable>
|
||||
<el-select
|
||||
v-model="queryParams.classStatus"
|
||||
class="w-[280px]"
|
||||
clearable
|
||||
@change="getLists"
|
||||
>
|
||||
<el-option label="在读" :value="1" />
|
||||
<el-option label="毕业" :value="2" />
|
||||
</el-select>
|
||||
|
|
@ -49,21 +54,17 @@
|
|||
</el-form>
|
||||
</el-card>
|
||||
<el-card class="!border-none mt-4" shadow="never">
|
||||
<div>
|
||||
<el-button v-perms="['class:add']" type="primary" @click="handleAdd()">
|
||||
<template #icon>
|
||||
<icon name="el-icon-Plus" />
|
||||
</template>
|
||||
新增
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table class="mt-4" size="large" v-loading="pager.loading" :data="pager.lists">
|
||||
<el-table
|
||||
class="mt-4 large-table clickable-row-table"
|
||||
size="large"
|
||||
v-loading="pager.loading"
|
||||
:data="pager.lists"
|
||||
@row-click="(row: any) => handleRowClick(row)"
|
||||
>
|
||||
<el-table-column label="学院名称" prop="collegeName" min-width="100" />
|
||||
<el-table-column label="专业名称" prop="majorName" min-width="100" />
|
||||
<el-table-column label="班级代码" prop="classCode" min-width="100" />
|
||||
<el-table-column label="班级名称" prop="className" min-width="100" />
|
||||
<el-table-column label="学生人数" prop="studentCount" min-width="100" />
|
||||
<el-table-column label="最大学生数" prop="maxStudentCount" min-width="100" />
|
||||
<el-table-column label="入学年份" prop="enrollmentYear" min-width="100" />
|
||||
<el-table-column label="预计毕业年份" prop="graduationYear" min-width="100" />
|
||||
<el-table-column
|
||||
|
|
@ -72,26 +73,11 @@
|
|||
min-width="100"
|
||||
:formatter="formatClassStatus"
|
||||
/>
|
||||
<el-table-column label="创建时间" prop="createTime" min-width="100" />
|
||||
<el-table-column label="更新时间" prop="updateTime" min-width="100" />
|
||||
<el-table-column label="操作" width="120" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
v-perms="['class:edit']"
|
||||
type="primary"
|
||||
link
|
||||
@click="handleEdit(row)"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
v-perms="['class:del']"
|
||||
type="danger"
|
||||
link
|
||||
@click="handleDelete(row.id)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
<el-table-column label="任务进度" min-width="100">
|
||||
<template #default="scope">
|
||||
<span :class="getProgressClass(scope.row.progress)">
|
||||
{{ formatClassProgress(scope.row.progress) }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
|
@ -99,22 +85,25 @@
|
|||
<pagination v-model="pager" @change="getLists" />
|
||||
</div>
|
||||
</el-card>
|
||||
<edit-popup v-if="showEdit" ref="editRef" @success="getLists" @close="showEdit = false" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="class">
|
||||
import { classDelete, classLists } from '@/api/class'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
import { classLists } from '@/api/class'
|
||||
import { collegeLists } from '@/api/college'
|
||||
import { majorLists } from '@/api/major'
|
||||
import { taskSearch } from '@/api/task'
|
||||
import { usePaging } from '@/hooks/usePaging'
|
||||
import { getRoutePath } from '@/router'
|
||||
import feedback from '@/utils/feedback'
|
||||
|
||||
import EditPopup from './edit.vue'
|
||||
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
|
||||
const getCollegeLists = ref<{ lists: Array<{ id: number; collegeName: string }> }>({ lists: [] })
|
||||
const getMajorLists = ref<{ lists: Array<{ id: number; majorName: string }> }>({ lists: [] })
|
||||
const showEdit = ref(false)
|
||||
const router = useRouter()
|
||||
const queryParams = reactive({
|
||||
id: '',
|
||||
collegeName: '',
|
||||
majorName: '',
|
||||
classCode: '',
|
||||
|
|
@ -124,11 +113,25 @@ const queryParams = reactive({
|
|||
headTeacherId: '',
|
||||
enrollmentYear: '',
|
||||
graduationYear: '',
|
||||
classStatus: null
|
||||
classStatus: 1
|
||||
})
|
||||
|
||||
const { pager, getLists, resetPage, resetParams } = usePaging({
|
||||
fetchFun: classLists,
|
||||
fetchFun: async (params) => {
|
||||
const classData = await classLists(params)
|
||||
// 获取每个班级的进度信息
|
||||
for (const cls of classData.lists) {
|
||||
try {
|
||||
const progressRes = await taskSearch({ classId: cls.id })
|
||||
// 假设progressRes包含一个status字段表示进度状态
|
||||
cls.progress = progressRes.arrangementProgress
|
||||
} catch (err) {
|
||||
console.error(`获取班级${cls.id}进度失败`, err)
|
||||
cls.progress = 'unknown'
|
||||
}
|
||||
}
|
||||
return classData
|
||||
},
|
||||
params: queryParams
|
||||
})
|
||||
|
||||
|
|
@ -158,27 +161,115 @@ const formatClassStatus = (row: any, column: any, cellValue: any) => {
|
|||
return statusMap[String(cellValue)] || cellValue
|
||||
}
|
||||
|
||||
const handleAdd = async () => {
|
||||
showEdit.value = true
|
||||
await nextTick()
|
||||
editRef.value?.open('add')
|
||||
const formatClassProgress = (progressValue: any) => {
|
||||
const statusMap: Record<string, string> = {
|
||||
draft: '草稿',
|
||||
confirmed: '确认',
|
||||
published: '发布',
|
||||
archived: '归档',
|
||||
unknown: '未知'
|
||||
}
|
||||
return statusMap[String(progressValue)] || progressValue
|
||||
}
|
||||
|
||||
const handleEdit = async (data: any) => {
|
||||
showEdit.value = true
|
||||
await nextTick()
|
||||
editRef.value?.open('edit')
|
||||
editRef.value?.getDetail(data)
|
||||
// 根据进度返回对应的CSS类名
|
||||
const getProgressClass = (progressValue: any) => {
|
||||
const progress = String(progressValue)
|
||||
const classMap: Record<string, string> = {
|
||||
draft: 'progress-draft',
|
||||
confirmed: 'progress-confirmed',
|
||||
published: 'progress-published',
|
||||
archived: 'progress-archived',
|
||||
unknown: 'progress-unknown'
|
||||
}
|
||||
return classMap[progress] || 'progress-default'
|
||||
}
|
||||
|
||||
const handleDelete = async (id: number) => {
|
||||
await feedback.confirm('确定要删除?')
|
||||
await classDelete({ id })
|
||||
feedback.msgSuccess('删除成功')
|
||||
getLists()
|
||||
const handleRowClick = (row: any) => {
|
||||
router.push({
|
||||
path: getRoutePath('task/list'),
|
||||
query: { classId: row.id }
|
||||
})
|
||||
}
|
||||
|
||||
getLists()
|
||||
fetchCollegeLists()
|
||||
fetchMajorLists()
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
:deep(.clickable-row-table .el-table__row) {
|
||||
cursor: default;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
:deep(.clickable-row-table .el-table__row:hover) {
|
||||
cursor: pointer;
|
||||
background-color: #f0f9ff !important;
|
||||
border-left: 3px solid #409eff;
|
||||
}
|
||||
|
||||
:deep(.clickable-row-table .el-table__row.current-row) {
|
||||
background-color: #e6f7ff !important;
|
||||
}
|
||||
|
||||
:deep(.el-table tbody tr:hover > td) {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
/* 进度样式 */
|
||||
:deep(.progress-draft) {
|
||||
color: #909399;
|
||||
font-weight: 500;
|
||||
background-color: #f4f4f5;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
:deep(.progress-confirmed) {
|
||||
color: #e6a23c;
|
||||
font-weight: 600;
|
||||
background-color: #fdf6ec;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
:deep(.progress-published) {
|
||||
color: #67c23a;
|
||||
font-weight: 600;
|
||||
background-color: #f0f9eb;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
:deep(.progress-archived) {
|
||||
color: #909399;
|
||||
font-weight: 500;
|
||||
background-color: #f4f4f5;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
display: inline-block;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
:deep(.progress-unknown) {
|
||||
color: #f56c6c;
|
||||
font-weight: 500;
|
||||
background-color: #fef0f0;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
:deep(.progress-default) {
|
||||
color: #409eff;
|
||||
font-weight: 500;
|
||||
background-color: #ecf5ff;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,542 @@
|
|||
<template>
|
||||
<div class="edit-popup">
|
||||
<popup
|
||||
ref="popupRef"
|
||||
:title="popupTitle"
|
||||
:async="true"
|
||||
width="550px"
|
||||
:clickModalClose="true"
|
||||
@confirm="handleSubmit"
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-form ref="formRef" :model="formData" label-width="84px" :rules="formRules">
|
||||
<el-form-item label="任务编号" prop="taskCode">
|
||||
<span>{{ formData.taskCode }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="学期" prop="semesterId">
|
||||
<el-select
|
||||
v-model="formData.semesterId"
|
||||
class="w-[280px]"
|
||||
@change="fetchConfigChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="college in getConfigLists.lists"
|
||||
:key="college.id"
|
||||
:value="college.id"
|
||||
:label="college.config"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="课程" prop="courseId">
|
||||
<el-select
|
||||
v-model="formData.courseId"
|
||||
class="w-[280px]"
|
||||
clearable
|
||||
@change="fetchCourseChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in getCourseLists.lists"
|
||||
:key="item.id"
|
||||
:value="item.id"
|
||||
:label="item.courseName"
|
||||
>
|
||||
<template #default>
|
||||
<span
|
||||
style="color: var(--el-text-color-secondary); font-size: 13px"
|
||||
>{{ item.courseCode }}</span
|
||||
>
|
||||
<span style="margin-left: 8px">{{ item.courseName }}</span>
|
||||
</template>
|
||||
</el-option>
|
||||
</el-select>
|
||||
<span
|
||||
style="
|
||||
color: var(--el-text-color-secondary);
|
||||
font-size: 13px;
|
||||
margin-left: 24px;
|
||||
"
|
||||
>
|
||||
学分:{{ fromCourse.credits }} 总学时:{{ fromCourse.totalHours }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="教师" prop="teacherId">
|
||||
<div style="display: flex; align-items: center; gap: 12px">
|
||||
<el-select
|
||||
v-model="formData.teacherId"
|
||||
class="w-[280px]"
|
||||
clearable
|
||||
:loading="teacherSearchLoading"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in getTeacherLists.lists"
|
||||
:key="item.id"
|
||||
:value="item.id"
|
||||
:label="item.name"
|
||||
>
|
||||
<template #default>
|
||||
<span
|
||||
style="
|
||||
color: var(--el-text-color-secondary);
|
||||
font-size: 13px;
|
||||
"
|
||||
>{{ item.teacherCode }}</span
|
||||
>
|
||||
<span style="margin-left: 8px">{{ item.name }}</span>
|
||||
</template>
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-switch
|
||||
v-model="ignoreCourseSwitch"
|
||||
active-text="忽略课程"
|
||||
active-value="true"
|
||||
inactive-value="false"
|
||||
@change="fetchTeacherLists"
|
||||
/>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="周学时" prop="weeklyHours">
|
||||
<el-input-number
|
||||
v-model="formData.weeklyHours"
|
||||
:min="1"
|
||||
:max="30"
|
||||
controls-position="right"
|
||||
/>
|
||||
<span
|
||||
style="
|
||||
color: var(--el-text-color-secondary);
|
||||
font-size: 13px;
|
||||
margin-left: 24px;
|
||||
"
|
||||
>
|
||||
请输入周学时,范围 1-30
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="总周数" prop="totalWeeks">
|
||||
<el-input-number
|
||||
v-model="formData.totalWeeks"
|
||||
:min="1"
|
||||
:max="20"
|
||||
controls-position="right"
|
||||
/>
|
||||
<span
|
||||
style="
|
||||
color: var(--el-text-color-secondary);
|
||||
font-size: 13px;
|
||||
margin-left: 24px;
|
||||
"
|
||||
>
|
||||
请输入总周数,范围 1-20
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input
|
||||
v-model="formData.remark"
|
||||
placeholder="请输入备注"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 4, maxRows: 6 }"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</popup>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import type { PropType } from 'vue'
|
||||
|
||||
import { classDetail } from '@/api/class'
|
||||
import { configDetail, configLists } from '@/api/config'
|
||||
import { courseDetail } from '@/api/course'
|
||||
import { taskAdd, taskCourseList, taskDetail, taskEdit, taskTeacherList } from '@/api/task'
|
||||
import { teacherDetail } from '@/api/teacher'
|
||||
import { timeCurrentSemester } from '@/api/time'
|
||||
import Popup from '@/components/popup/index.vue'
|
||||
import feedback from '@/utils/feedback'
|
||||
defineProps({
|
||||
dictData: {
|
||||
type: Object as PropType<Record<string, any[]>>,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
const emit = defineEmits(['success', 'close'])
|
||||
|
||||
const getConfigLists = ref<{
|
||||
lists: Array<{ id: number; academicYear: string; semesterCode: string; config: string }>
|
||||
}>({ lists: [] })
|
||||
const getCourseLists = ref<{
|
||||
lists: Array<{
|
||||
id: number
|
||||
courseName: string
|
||||
courseCode: string
|
||||
credits: number
|
||||
totalHours: number
|
||||
}>
|
||||
}>({ lists: [] })
|
||||
const getTeacherLists = ref<{
|
||||
lists: Array<{ id: number; name: string; teacherCode: string }>
|
||||
}>({ lists: [] })
|
||||
|
||||
const courseSearchLoading = ref(false)
|
||||
const courseSearchTimer = ref<number | null>(null)
|
||||
const teacherSearchLoading = ref(false)
|
||||
const teacherSearchTimer = ref<number | null>(null)
|
||||
|
||||
const ignoreCourseSwitch = ref<string>('true')
|
||||
const formRef = shallowRef<FormInstance>()
|
||||
const popupRef = shallowRef<InstanceType<typeof Popup>>()
|
||||
const mode = ref('add')
|
||||
const popupTitle = computed(() => {
|
||||
return mode.value == 'edit' ? '编辑教学任务' : '新增教学任务'
|
||||
})
|
||||
|
||||
const formData = reactive({
|
||||
id: '',
|
||||
collegeId: '',
|
||||
semesterId: '',
|
||||
courseId: '',
|
||||
teacherId: '',
|
||||
classId: 0,
|
||||
weeklyHours: 0,
|
||||
totalWeeks: 0,
|
||||
remark: '',
|
||||
taskCode: ''
|
||||
})
|
||||
|
||||
const formCode = reactive({
|
||||
semesterCode: '',
|
||||
courseCode: '',
|
||||
classCode: ''
|
||||
})
|
||||
|
||||
const fromCourse = reactive({
|
||||
totalHours: 0,
|
||||
credits: 0
|
||||
})
|
||||
|
||||
const formRules = {
|
||||
id: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入唯一主键',
|
||||
trigger: ['blur']
|
||||
}
|
||||
],
|
||||
semesterId: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入学期ID',
|
||||
trigger: ['blur']
|
||||
}
|
||||
],
|
||||
courseId: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入课程ID',
|
||||
trigger: ['blur']
|
||||
}
|
||||
],
|
||||
teacherId: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入教师ID',
|
||||
trigger: ['blur']
|
||||
}
|
||||
],
|
||||
classId: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入班级ID',
|
||||
trigger: ['blur']
|
||||
}
|
||||
],
|
||||
weeklyHours: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入周学时,范围 1-30',
|
||||
trigger: ['blur']
|
||||
}
|
||||
],
|
||||
totalWeeks: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入总周数,范围 1-20',
|
||||
trigger: ['blur']
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
const fetchConfigChange = async () => {
|
||||
fetchTaskCode()
|
||||
await fetchCourseLists()
|
||||
}
|
||||
const fetchConfigLists = async () => {
|
||||
try {
|
||||
const res = await configLists()
|
||||
const handleData = JSON.parse(JSON.stringify(res))
|
||||
handleData.lists = handleData.lists.map((item: any) => ({
|
||||
...item,
|
||||
config: `${item.academicYear}${item.semesterCode == 'SPRING' ? ' 春' : ' 秋'}`
|
||||
}))
|
||||
getConfigLists.value = handleData
|
||||
await fetchSemester()
|
||||
} catch (err) {
|
||||
feedback.msgError('获取学期列表失败')
|
||||
}
|
||||
}
|
||||
const fetchSemester = async () => {
|
||||
try {
|
||||
const res = await timeCurrentSemester()
|
||||
if (res) {
|
||||
formData.semesterId = res.id
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取学期信息失败', error)
|
||||
}
|
||||
}
|
||||
const fetchSemesterCode = async () => {
|
||||
try {
|
||||
const res = await configDetail({ id: formData.semesterId })
|
||||
if (res) {
|
||||
formCode.semesterCode = `${res.academicYear}${
|
||||
res.semesterCode == 'SPRING' ? '-1' : '-2'
|
||||
}`
|
||||
console.log('formCode.semesterCode', formCode.semesterCode)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取学期代码失败', error)
|
||||
}
|
||||
}
|
||||
|
||||
const fetchCourseChange = async () => {
|
||||
const selectedCourse = getCourseLists.value.lists.find(
|
||||
(item) => item.id === Number(formData.courseId)
|
||||
)
|
||||
if (selectedCourse) {
|
||||
fromCourse.credits = selectedCourse.credits
|
||||
fromCourse.totalHours = selectedCourse.totalHours
|
||||
} else {
|
||||
fromCourse.credits = 0
|
||||
fromCourse.totalHours = 0
|
||||
if (formData.courseId) {
|
||||
try {
|
||||
const res = await courseDetail({ id: formData.courseId })
|
||||
fromCourse.credits = res.credits
|
||||
fromCourse.totalHours = res.totalHours
|
||||
} catch (err) {
|
||||
console.error('获取选中课程详情失败', err)
|
||||
feedback.msgError('获取课程学分/总学时失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
await fetchTaskCode()
|
||||
await fetchTeacherLists()
|
||||
}
|
||||
const fetchCourseLists = async () => {
|
||||
try {
|
||||
courseSearchLoading.value = true
|
||||
const courseIdRes = await taskCourseList({
|
||||
classId: formData.classId,
|
||||
semesterId: formData.semesterId
|
||||
})
|
||||
const courseIds = courseIdRes
|
||||
if (!Array.isArray(courseIds) || courseIds.length === 0) {
|
||||
getCourseLists.value = { lists: [] }
|
||||
return
|
||||
}
|
||||
const courseDetailPromises = courseIds.map(async (courseId) => {
|
||||
const realId = courseId
|
||||
const detail = await courseDetail({ id: realId })
|
||||
return {
|
||||
id: detail.id,
|
||||
courseName: detail.courseName,
|
||||
courseCode: detail.courseCode,
|
||||
credits: detail.credits,
|
||||
totalHours: detail.totalHours
|
||||
}
|
||||
})
|
||||
|
||||
const settledResults = await Promise.allSettled(courseDetailPromises)
|
||||
const courseDetails = settledResults.reduce(
|
||||
(acc, result, index) => {
|
||||
if (result.status === 'fulfilled') {
|
||||
acc.push(result.value)
|
||||
} else {
|
||||
console.error(`获取课程ID ${courseIds[index]} 详情失败:`, result.reason)
|
||||
}
|
||||
return acc
|
||||
},
|
||||
[] as {
|
||||
id: number
|
||||
courseName: string
|
||||
courseCode: string
|
||||
credits: number
|
||||
totalHours: number
|
||||
}[]
|
||||
)
|
||||
console.log('获取课程列表', courseDetails)
|
||||
getCourseLists.value = { lists: courseDetails }
|
||||
|
||||
if (formData.courseId) {
|
||||
const selectedCourse = courseDetails.find(
|
||||
(item) => item.id === Number(formData.courseId)
|
||||
)
|
||||
if (selectedCourse) {
|
||||
fromCourse.credits = selectedCourse.credits
|
||||
fromCourse.totalHours = selectedCourse.totalHours
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('获取课程列表失败')
|
||||
feedback.msgError('获取课程列表失败')
|
||||
getCourseLists.value = { lists: [] }
|
||||
} finally {
|
||||
courseSearchLoading.value = false
|
||||
}
|
||||
await fetchTeacherLists()
|
||||
}
|
||||
const fetchCourseCode = async () => {
|
||||
try {
|
||||
if (
|
||||
formData.courseId == null ||
|
||||
formData.courseId === undefined ||
|
||||
formData.courseId === ''
|
||||
) {
|
||||
formCode.courseCode = '?'
|
||||
return
|
||||
}
|
||||
const res = await courseDetail({ id: formData.courseId })
|
||||
if (res) {
|
||||
formCode.courseCode = res.courseCode
|
||||
console.log('formCode.courseCode', formCode.courseCode)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取课程代码失败', error)
|
||||
}
|
||||
}
|
||||
|
||||
const fetchTeacherLists = async () => {
|
||||
try {
|
||||
teacherSearchLoading.value = true
|
||||
const teacherIdRes = await taskTeacherList({
|
||||
collegeId: formData.collegeId,
|
||||
courseId: formData.courseId,
|
||||
ignoreCourse: ignoreCourseSwitch.value === 'true'
|
||||
})
|
||||
console.log('教师IDs', teacherIdRes)
|
||||
const teacherIds = teacherIdRes
|
||||
if (!Array.isArray(teacherIds) || teacherIds.length === 0) {
|
||||
getTeacherLists.value = { lists: [] }
|
||||
return
|
||||
}
|
||||
const teacherDetailPromises = teacherIds.map(async (teacherId) => {
|
||||
const realId = teacherId
|
||||
const detail = await teacherDetail({ id: realId })
|
||||
return {
|
||||
id: detail.id,
|
||||
name: detail.name,
|
||||
teacherCode: detail.teacherCode
|
||||
}
|
||||
})
|
||||
const settledResults = await Promise.allSettled(teacherDetailPromises)
|
||||
const courseDetails = settledResults.reduce((acc, result, index) => {
|
||||
if (result.status === 'fulfilled') {
|
||||
acc.push(result.value)
|
||||
} else {
|
||||
console.error(`获取教师ID ${teacherIds[index]} 详情失败:`, result.reason)
|
||||
}
|
||||
return acc
|
||||
}, [] as { id: number; name: string; teacherCode: string }[])
|
||||
console.log('获取教师列表', courseDetails)
|
||||
getTeacherLists.value = { lists: courseDetails }
|
||||
} catch (err) {
|
||||
console.log('获取教师列表失败')
|
||||
feedback.msgError('获取教师列表失败')
|
||||
getTeacherLists.value = { lists: [] }
|
||||
} finally {
|
||||
teacherSearchLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (courseSearchTimer.value) clearTimeout(courseSearchTimer.value)
|
||||
if (teacherSearchTimer.value) clearTimeout(teacherSearchTimer.value)
|
||||
})
|
||||
|
||||
const fetchTaskCode = async () => {
|
||||
await fetchSemesterCode()
|
||||
await fetchCourseCode()
|
||||
formData.taskCode = formCode.semesterCode + '-' + formCode.courseCode + '-' + formCode.classCode
|
||||
console.log('提交的教学任务编码', formData.taskCode)
|
||||
}
|
||||
|
||||
const handleSubmit = async () => {
|
||||
const validateResult = await formRef.value?.validate()
|
||||
if (!validateResult) return
|
||||
if (fromCourse.totalHours === 0) {
|
||||
feedback.msgError('请先选择课程,获取课程总学时后再提交!')
|
||||
return
|
||||
}
|
||||
const calcTotalHours = formData.weeklyHours * formData.totalWeeks
|
||||
if (calcTotalHours !== fromCourse.totalHours) {
|
||||
feedback.msgError(
|
||||
`学时校验失败!周学时(${formData.weeklyHours}) × 总周数(${formData.totalWeeks}) = ${calcTotalHours},与课程总学时(${fromCourse.totalHours})不相等,请修正!`
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
await fetchTaskCode()
|
||||
await formRef.value?.validate()
|
||||
const data: any = { ...formData }
|
||||
mode.value == 'edit' ? await taskEdit(data) : await taskAdd(data)
|
||||
popupRef.value?.close()
|
||||
feedback.msgSuccess('操作成功')
|
||||
emit('success')
|
||||
}
|
||||
|
||||
const open = async (type = 'add') => {
|
||||
mode.value = type
|
||||
await fetchConfigLists()
|
||||
await fetchCourseLists()
|
||||
popupRef.value?.open()
|
||||
}
|
||||
|
||||
const setFormData = async (data: Record<string, any>) => {
|
||||
for (const key in formData) {
|
||||
if (data[key] != null && data[key] != undefined) {
|
||||
//@ts-ignore
|
||||
formData[key] = data[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const getClassDetail = async (classId: number) => {
|
||||
try {
|
||||
const data = await classDetail({ id: classId })
|
||||
formData.classId = data.id
|
||||
formData.collegeId = data.collegeId
|
||||
formCode.classCode = data.classCode
|
||||
return data
|
||||
} catch (err) {
|
||||
feedback.msgError('获取班级详情失败')
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const getDetail = async (row: Record<string, any>) => {
|
||||
const data = await taskDetail({
|
||||
id: row.id
|
||||
})
|
||||
setFormData(data)
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
emit('close')
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
open,
|
||||
setFormData,
|
||||
getDetail,
|
||||
getClassDetail
|
||||
})
|
||||
</script>
|
||||
|
|
@ -0,0 +1,321 @@
|
|||
<template>
|
||||
<div class="index-lists">
|
||||
<el-card class="!border-none" shadow="never">
|
||||
<div style="display: flex; align-items: center; margin-bottom: 16px">
|
||||
<div style="font-size: 18px; font-weight: 500">
|
||||
{{ classData.className }}
|
||||
</div>
|
||||
<div style="font-size: 16px; font-weight: 400; margin-left: 32px; color: #606266">
|
||||
状态:{{ formatClassProgress(classData.classProgress) }}
|
||||
</div>
|
||||
</div>
|
||||
<el-form ref="formRef" class="mb-[-16px]" :model="queryParams" :inline="true">
|
||||
<el-form-item label="教学任务业务编号" prop="taskCode">
|
||||
<el-input class="w-[280px]" v-model="queryParams.taskCode" />
|
||||
</el-form-item>
|
||||
<el-form-item label="学期" prop="semesterId">
|
||||
<el-select v-model="queryParams.semesterId" class="w-[280px]" clearable>
|
||||
<el-option
|
||||
v-for="college in getConfigLists.lists"
|
||||
:key="college.id"
|
||||
:value="college.id"
|
||||
:label="college.config"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="课程" prop="courseId">
|
||||
<el-select
|
||||
v-model="queryParams.courseId"
|
||||
placeholder="请输入课程名称搜索"
|
||||
:remote="true"
|
||||
:remote-method="handleCourseRemoteSearch"
|
||||
:loading="courseSearchLoading"
|
||||
filterable
|
||||
clearable
|
||||
remote-show-suffix
|
||||
class="w-[280px]"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in getCourseLists.lists"
|
||||
:key="item.id"
|
||||
:value="item.id"
|
||||
:label="item.courseName"
|
||||
>
|
||||
<template #default>
|
||||
<span
|
||||
style="color: var(--el-text-color-secondary); font-size: 13px"
|
||||
>
|
||||
{{ item.courseCode }}
|
||||
</span>
|
||||
<span style="margin-left: 8px">{{ item.courseName }}</span>
|
||||
</template>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="教师" prop="teacherId">
|
||||
<el-select
|
||||
v-model="queryParams.teacherId"
|
||||
placeholder="请输入教师名称搜索"
|
||||
:remote="true"
|
||||
:remote-method="handleTeacherRemoteSearch"
|
||||
:loading="teacherSearchLoading"
|
||||
filterable
|
||||
clearable
|
||||
remote-show-suffix
|
||||
class="w-[280px]"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in getTeacherLists.lists"
|
||||
:key="item.id"
|
||||
:value="item.id"
|
||||
:label="item.name"
|
||||
>
|
||||
<template #default>
|
||||
<span
|
||||
style="color: var(--el-text-color-secondary); font-size: 13px"
|
||||
>
|
||||
{{ item.teacherCode }}
|
||||
</span>
|
||||
<span style="margin-left: 8px">{{ item.name }}</span>
|
||||
</template>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="resetPage">查询</el-button>
|
||||
<el-button @click="resetParams">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<el-card class="!border-none mt-4" shadow="never">
|
||||
<div>
|
||||
<el-button v-perms="['task:add']" type="primary" @click="handleAdd()">
|
||||
<template #icon>
|
||||
<icon name="el-icon-Plus" />
|
||||
</template>
|
||||
新增
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table class="mt-4" size="large" v-loading="pager.loading" :data="pager.lists">
|
||||
<el-table-column label="教学任务业务编号" prop="taskCode" min-width="280" />
|
||||
<el-table-column label="学期" prop="semesterName" min-width="210" />
|
||||
<el-table-column label="课程" prop="courseName" min-width="100" />
|
||||
<el-table-column label="教师" prop="teacherName" min-width="100" />
|
||||
<el-table-column label="班级" prop="className" min-width="100" />
|
||||
<el-table-column label="周学时" prop="weeklyHours" min-width="100" />
|
||||
<el-table-column label="总周数" prop="totalWeeks" min-width="100" />
|
||||
<el-table-column label="状态" prop="status" min-width="100" />
|
||||
<el-table-column label="备注" prop="remark" min-width="100" />
|
||||
<el-table-column label="创建人" prop="createrName" min-width="100" />
|
||||
<el-table-column label="创建时间" prop="createdTime" min-width="100" />
|
||||
<el-table-column label="最后更新人" prop="updaterName" min-width="100" />
|
||||
<el-table-column label="最后更新时间" prop="updatedTime" min-width="100" />
|
||||
<el-table-column label="操作" width="120" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
v-perms="['task:edit']"
|
||||
type="primary"
|
||||
link
|
||||
@click="handleEdit(row)"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
v-perms="['task:del']"
|
||||
type="danger"
|
||||
link
|
||||
@click="handleDelete(row.id)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="flex justify-end mt-4">
|
||||
<pagination v-model="pager" @change="getLists" />
|
||||
</div>
|
||||
</el-card>
|
||||
<edit-popup v-if="showEdit" ref="editRef" @success="getLists" @close="showEdit = false" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup name="task">
|
||||
import { classDetail } from '@/api/class'
|
||||
import { configLists } from '@/api/config'
|
||||
import { courseLists } from '@/api/course'
|
||||
import { taskDelete, taskLists, taskSearch } from '@/api/task'
|
||||
import { teacherLists } from '@/api/teacher'
|
||||
import { timeCurrentSemester } from '@/api/time'
|
||||
import { usePaging } from '@/hooks/usePaging'
|
||||
import feedback from '@/utils/feedback'
|
||||
|
||||
import EditPopup from './edit.vue'
|
||||
const getConfigLists = ref<{
|
||||
lists: Array<{ id: number; academicYear: string; semesterCode: string; config: string }>
|
||||
}>({ lists: [] })
|
||||
const getCourseLists = ref<{
|
||||
lists: Array<{ id: number; courseName: string; courseCode: string }>
|
||||
}>({ lists: [] })
|
||||
const getTeacherLists = ref<{
|
||||
lists: Array<{ id: number; name: string; teacherCode: string }>
|
||||
}>({ lists: [] })
|
||||
|
||||
const courseSearchLoading = ref(false)
|
||||
const courseSearchTimer = ref<number | null>(null)
|
||||
const teacherSearchLoading = ref(false)
|
||||
const teacherSearchTimer = ref<number | null>(null)
|
||||
|
||||
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
|
||||
const showEdit = ref(false)
|
||||
const route = useRoute()
|
||||
const queryParams = reactive({
|
||||
taskCode: '',
|
||||
semesterId: '',
|
||||
courseId: '',
|
||||
teacherId: '',
|
||||
classId: '',
|
||||
weeklyHours: '',
|
||||
totalWeeks: '',
|
||||
createdBy: '',
|
||||
updatedBy: ''
|
||||
})
|
||||
const classData = reactive({
|
||||
classCode: '',
|
||||
className: '',
|
||||
classProgress: ''
|
||||
})
|
||||
|
||||
const { pager, getLists, resetPage, resetParams } = usePaging({
|
||||
fetchFun: taskLists,
|
||||
params: queryParams
|
||||
})
|
||||
|
||||
const fetchConfigLists = async () => {
|
||||
try {
|
||||
const res = await configLists()
|
||||
const handleData = JSON.parse(JSON.stringify(res))
|
||||
handleData.lists = handleData.lists.map((item: any) => ({
|
||||
...item,
|
||||
config: `${item.academicYear}${item.semesterCode == 'SPRING' ? ' 春' : ' 秋'}`
|
||||
}))
|
||||
getConfigLists.value = handleData
|
||||
await fetchSemester()
|
||||
} catch (err) {
|
||||
feedback.msgError('获取学期列表失败')
|
||||
}
|
||||
}
|
||||
const fetchSemester = async () => {
|
||||
try {
|
||||
const res = await timeCurrentSemester()
|
||||
if (res) {
|
||||
queryParams.semesterId = res.id
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取学期信息失败', error)
|
||||
}
|
||||
}
|
||||
|
||||
const fetchCourseLists = async (params: string) => {
|
||||
try {
|
||||
const res = await courseLists({
|
||||
courseName: params.trim() // 搜索关键词
|
||||
})
|
||||
getCourseLists.value = res
|
||||
} catch (err) {
|
||||
feedback.msgError('获取课程列表失败')
|
||||
getCourseLists.value = { lists: [] } // 失败时清空列表
|
||||
} finally {
|
||||
courseSearchLoading.value = false // 关闭加载状态
|
||||
}
|
||||
}
|
||||
const handleCourseRemoteSearch = (keyword: string) => {
|
||||
if (courseSearchTimer.value) clearTimeout(courseSearchTimer.value)
|
||||
|
||||
courseSearchTimer.value = setTimeout(async () => {
|
||||
courseSearchLoading.value = true
|
||||
await fetchCourseLists(keyword)
|
||||
}, 300)
|
||||
}
|
||||
|
||||
const fetchTeacherLists = async (params: string) => {
|
||||
try {
|
||||
const res = await teacherLists({
|
||||
name: params.trim() // 搜索关键词
|
||||
})
|
||||
getTeacherLists.value = res
|
||||
} catch (err) {
|
||||
feedback.msgError('获取教师列表失败')
|
||||
getTeacherLists.value = { lists: [] } // 失败时清空列表
|
||||
} finally {
|
||||
teacherSearchLoading.value = false // 关闭加载状态
|
||||
}
|
||||
}
|
||||
const handleTeacherRemoteSearch = (keyword: string) => {
|
||||
if (teacherSearchTimer.value) clearTimeout(teacherSearchTimer.value)
|
||||
|
||||
teacherSearchTimer.value = setTimeout(async () => {
|
||||
teacherSearchLoading.value = true
|
||||
await fetchTeacherLists(keyword)
|
||||
}, 300)
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (courseSearchTimer.value) clearTimeout(courseSearchTimer.value)
|
||||
if (teacherSearchTimer.value) clearTimeout(teacherSearchTimer.value)
|
||||
})
|
||||
|
||||
const getClassDetail = async () => {
|
||||
try {
|
||||
console.log('route.query.classId', route.query.classId)
|
||||
const res = await classDetail({
|
||||
id: Number(route.query.classId),
|
||||
semesterId: queryParams.semesterId
|
||||
})
|
||||
classData.classCode = res.classCode
|
||||
classData.className = res.className
|
||||
const progressRes = await taskSearch({ classId: Number(route.query.classId) })
|
||||
console.log('progressRes', progressRes)
|
||||
classData.classProgress = progressRes.arrangementProgress || '暂无进度信息'
|
||||
} catch (err) {
|
||||
feedback.msgError('获取班级详情失败')
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const formatClassProgress = (cellValue: any) => {
|
||||
const statusMap: Record<string, string> = {
|
||||
draft: '草稿',
|
||||
confirmed: '确认',
|
||||
published: '发布',
|
||||
archived: '归档',
|
||||
default: '默认'
|
||||
}
|
||||
return statusMap[String(cellValue)] || cellValue
|
||||
}
|
||||
|
||||
const handleAdd = async () => {
|
||||
showEdit.value = true
|
||||
await nextTick()
|
||||
editRef.value?.open('add')
|
||||
editRef.value?.getClassDetail(Number(route.query.classId))
|
||||
}
|
||||
|
||||
const handleEdit = async (data: any) => {
|
||||
showEdit.value = true
|
||||
await nextTick()
|
||||
editRef.value?.open('edit')
|
||||
editRef.value?.getDetail(data)
|
||||
}
|
||||
|
||||
const handleDelete = async (id: number) => {
|
||||
await feedback.confirm('确定要删除?')
|
||||
await taskDelete({ id })
|
||||
feedback.msgSuccess('删除成功')
|
||||
getLists()
|
||||
}
|
||||
|
||||
fetchConfigLists()
|
||||
getClassDetail()
|
||||
fetchCourseLists('')
|
||||
fetchTeacherLists('')
|
||||
getLists()
|
||||
</script>
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
<template>
|
||||
<div class="delete-popup">
|
||||
<popup
|
||||
ref="popupRef"
|
||||
title="删除确认"
|
||||
:async="true"
|
||||
width="400px"
|
||||
:clickModalClose="true"
|
||||
@confirm="handleSubmit"
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-form ref="formRef" :model="formData" label-width="120px" :rules="formRules">
|
||||
<el-form-item label="删除数量" prop="count">
|
||||
<el-input-number
|
||||
v-model="formData.count"
|
||||
placeholder="请输入删除数量"
|
||||
:min="1"
|
||||
:max="9999"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</popup>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import type { FormInstance } from 'element-plus'
|
||||
|
||||
import { slotDelete } from '@/api/slot'
|
||||
import Popup from '@/components/popup/index.vue'
|
||||
import feedback from '@/utils/feedback'
|
||||
|
||||
const emit = defineEmits(['success', 'close'])
|
||||
const formRef = shallowRef<FormInstance>()
|
||||
const popupRef = shallowRef<InstanceType<typeof Popup>>()
|
||||
|
||||
const formData = reactive({
|
||||
count: 1
|
||||
})
|
||||
|
||||
const formRules = {
|
||||
count: [
|
||||
{ required: true, message: '请输入删除数量', trigger: ['blur'] },
|
||||
{ type: 'number', min: 1, message: '数量必须大于0', trigger: ['blur'] }
|
||||
]
|
||||
}
|
||||
|
||||
const handleSubmit = async () => {
|
||||
await formRef.value?.validate()
|
||||
await slotDelete({ count: formData.count })
|
||||
popupRef.value?.close()
|
||||
feedback.msgSuccess('删除成功')
|
||||
emit('success')
|
||||
}
|
||||
|
||||
const open = () => {
|
||||
formRef.value?.resetFields()
|
||||
popupRef.value?.open()
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
emit('close')
|
||||
}
|
||||
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
<template>
|
||||
<div class="edit-popup">
|
||||
<popup
|
||||
ref="popupRef"
|
||||
:title="popupTitle"
|
||||
:async="true"
|
||||
width="550px"
|
||||
:clickModalClose="true"
|
||||
@confirm="handleSubmit"
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-form ref="formRef" :model="formData" label-width="164px" :rules="formRules">
|
||||
<el-form-item label="开始时间" prop="startTime">
|
||||
<el-time-picker
|
||||
class="flex-1 !flex"
|
||||
v-model="formData.startTime"
|
||||
is-arrow-control
|
||||
clearable
|
||||
format="HH:mm"
|
||||
value-format="HH:mm"
|
||||
placeholder="请选择开始时间"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="mode == 'edit'" label="结束时间" prop="endTime">
|
||||
<el-time-picker
|
||||
class="flex-1 !flex"
|
||||
v-model="formData.endTime"
|
||||
is-arrow-control
|
||||
clearable
|
||||
format="HH:mm"
|
||||
value-format="HH:mm"
|
||||
placeholder="请选择结束时间"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="mode == 'add'" label="节次时长(分钟)" prop="duration">
|
||||
<el-input-number v-model="formData.duration" :max="9999" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="mode == 'add'"
|
||||
label="节次间隔时长(分钟)"
|
||||
prop="intervalDuration"
|
||||
>
|
||||
<el-input-number v-model="formData.intervalDuration" :max="9999" />
|
||||
</el-form-item>
|
||||
<el-form-item v-if="mode == 'add'" label="连续添加节次数量" prop="num">
|
||||
<el-input-number
|
||||
v-model="formData.num"
|
||||
placeholder="请输入连续添加节次数量"
|
||||
:max="9999"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否排课" prop="isScheduled">
|
||||
<el-switch
|
||||
v-model="formData.isScheduled"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</popup>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import type { PropType } from 'vue'
|
||||
|
||||
import { slotEdit, slotInsert } from '@/api/slot'
|
||||
import Popup from '@/components/popup/index.vue'
|
||||
import feedback from '@/utils/feedback'
|
||||
defineProps({
|
||||
dictData: {
|
||||
type: Object as PropType<Record<string, any[]>>,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
const emit = defineEmits(['success', 'close'])
|
||||
const formRef = shallowRef<FormInstance>()
|
||||
const popupRef = shallowRef<InstanceType<typeof Popup>>()
|
||||
const mode = ref('add')
|
||||
const popupTitle = computed(() => {
|
||||
return mode.value == 'edit' ? '编辑节次' : '新增节次'
|
||||
})
|
||||
|
||||
const formData = reactive({
|
||||
startTime: '',
|
||||
endTime: '',
|
||||
duration: '',
|
||||
section: '',
|
||||
intervalDuration: '',
|
||||
isScheduled: 1,
|
||||
num: 1
|
||||
})
|
||||
|
||||
const formRules = {
|
||||
startTime: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择开始时间',
|
||||
trigger: ['blur']
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
const handleSubmit = async () => {
|
||||
await formRef.value?.validate()
|
||||
const data: any = { ...formData }
|
||||
mode.value == 'edit' ? await slotEdit(data) : await slotInsert(data)
|
||||
popupRef.value?.close()
|
||||
feedback.msgSuccess('操作成功')
|
||||
emit('success')
|
||||
}
|
||||
|
||||
const open = (type = 'add', defaultStartTime = '') => {
|
||||
mode.value = type
|
||||
formRef.value?.resetFields()
|
||||
if (type === 'add' && defaultStartTime) {
|
||||
formData.startTime = defaultStartTime
|
||||
}
|
||||
popupRef.value?.open()
|
||||
}
|
||||
|
||||
const setFormData = async (data: Record<string, any>) => {
|
||||
for (const key in formData) {
|
||||
if (data[key] != null && data[key] != undefined) {
|
||||
//@ts-ignore
|
||||
formData[key] = data[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
emit('close')
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
open,
|
||||
setFormData
|
||||
})
|
||||
</script>
|
||||
|
|
@ -129,7 +129,7 @@
|
|||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup name="slot">
|
||||
<script lang="ts" setup name="slot1">
|
||||
import { computed, nextTick, reactive, ref, shallowRef } from 'vue'
|
||||
|
||||
import { slotLists, slotUniform } from '@/api/slot'
|
||||
|
|
@ -148,7 +148,7 @@ const queryParams = reactive({
|
|||
slotName: '',
|
||||
slotType: '',
|
||||
isScheduled: '',
|
||||
duration: '',
|
||||
duration: 40,
|
||||
intervalDuration: ''
|
||||
})
|
||||
|
||||
|
|
@ -275,6 +275,7 @@ getLists()
|
|||
|
||||
:deep(.el-table tbody tr:hover > td) {
|
||||
background-color: transparent !important;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.cell-content {
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
NODE_ENV = 'production'
|
||||
# Base API
|
||||
VITE_APP_BASE_URL=''
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
.vscode
|
||||
.idea
|
||||
dist/
|
||||
node_modules/
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
/* eslint-env node */
|
||||
require('@rushstack/eslint-patch/modern-module-resolution')
|
||||
|
||||
module.exports = {
|
||||
root: true,
|
||||
ignorePatterns: ['/auto-imports.d.ts', '/components.d.ts'],
|
||||
extends: [
|
||||
'plugin:vue/vue3-essential',
|
||||
'eslint:recommended',
|
||||
'@vue/eslint-config-typescript/recommended',
|
||||
'@vue/eslint-config-prettier',
|
||||
'./.eslintrc-auto-import.json'
|
||||
],
|
||||
plugins: ['simple-import-sort'],
|
||||
rules: {
|
||||
'simple-import-sort/imports': 'error', // 强制导入语句排序
|
||||
'prettier/prettier': [
|
||||
'warn',
|
||||
{
|
||||
semi: false,
|
||||
singleQuote: true,
|
||||
printWidth: 100,
|
||||
proseWrap: 'preserve',
|
||||
bracketSameLine: false,
|
||||
endOfLine: 'lf',
|
||||
tabWidth: 4,
|
||||
useTabs: false,
|
||||
trailingComma: 'none'
|
||||
}
|
||||
],
|
||||
'vue/multi-word-component-names': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/ban-ts-comment': 'off',
|
||||
'no-undef': 'off',
|
||||
'vue/prefer-import-from-vue': 'off',
|
||||
'no-prototype-builtins': 'off',
|
||||
'prefer-spread': 'off',
|
||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||
'@typescript-eslint/no-non-null-asserted-optional-chain': 'off'
|
||||
},
|
||||
globals: {
|
||||
module: 'readonly'
|
||||
}
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
.DS_Store
|
||||
dist
|
||||
dist-ssr
|
||||
coverage
|
||||
*.local
|
||||
|
||||
# unplugin-auto-import
|
||||
auto-imports.d.ts
|
||||
components.d.ts
|
||||
.eslintrc-auto-import.json
|
||||
|
||||
/cypress/videos/
|
||||
/cypress/screenshots/
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
# .env
|
||||
.env.development
|
||||
.env.production
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
.vscode
|
||||
.idea
|
||||
dist/
|
||||
node_modules/
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"printWidth": 100,
|
||||
"proseWrap": "preserve",
|
||||
"bracketSameLine": false,
|
||||
"endOfLine": "lf",
|
||||
"tabWidth": 4,
|
||||
"useTabs": false,
|
||||
"trailingComma": "none"
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
# vue-project
|
||||
|
||||
This template should help get you started developing with Vue 3 in Vite.
|
||||
|
||||
## Recommended IDE Setup
|
||||
|
||||
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
|
||||
|
||||
## Type Support for `.vue` Imports in TS
|
||||
|
||||
TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
|
||||
|
||||
If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
|
||||
|
||||
1. Disable the built-in TypeScript Extension
|
||||
1. Run `Extensions: Show Built-in Extensions` from VSCode's command palette
|
||||
2. Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
|
||||
2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
|
||||
|
||||
## Customize configuration
|
||||
|
||||
See [Vite Configuration Reference](https://vitejs.dev/config/).
|
||||
|
||||
## Project Setup
|
||||
|
||||
```sh
|
||||
npm install
|
||||
```
|
||||
|
||||
### Compile and Hot-Reload for Development
|
||||
|
||||
```sh
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Type-Check, Compile and Minify for Production
|
||||
|
||||
```sh
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Lint with [ESLint](https://eslint.org/)
|
||||
|
||||
```sh
|
||||
npm run lint
|
||||
```
|
||||
|
|
@ -1 +0,0 @@
|
|||
/// <reference types="vite/client" />
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>后台管理系统</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.preload {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
.circular {
|
||||
height: 42px;
|
||||
width: 42px;
|
||||
animation: loading-rotate 2s linear infinite;
|
||||
}
|
||||
|
||||
.circular .path {
|
||||
animation: loading-dash 1.5s ease-in-out infinite;
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: 0;
|
||||
stroke-width: 2;
|
||||
stroke: #4073fa;
|
||||
stroke-linecap: round;
|
||||
}
|
||||
|
||||
@keyframes loading-rotate {
|
||||
100% {
|
||||
transform: rotate(1turn);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes loading-dash {
|
||||
0% {
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -40px;
|
||||
}
|
||||
|
||||
100% {
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -120px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
<div class="preload">
|
||||
<svg viewBox="25 25 50 50" class="circular">
|
||||
<circle cx="50" cy="50" r="20" fill="none" class="path"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
{
|
||||
"name": "vue-project",
|
||||
"version": "0.0.0",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"preview": "vite preview --port 4173",
|
||||
"build": "vite build && node scripts/release.mjs",
|
||||
"type-check": "vue-tsc --noEmit",
|
||||
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore"
|
||||
},
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "^2.3.1",
|
||||
"@highlightjs/vue-plugin": "^2.1.0",
|
||||
"@vue/shared": "^3.4.38",
|
||||
"@vueuse/core": "^11.0.0",
|
||||
"@wangeditor/editor": "^5.1.23",
|
||||
"@wangeditor/editor-for-vue": "^5.1.12",
|
||||
"axios": "^0.27.2",
|
||||
"css-color-function": "^1.3.3",
|
||||
"echarts": "^5.5.1",
|
||||
"element-plus": "2.2.27",
|
||||
"highlight.js": "^11.10.0",
|
||||
"lodash": "^4.17.21",
|
||||
"lodash-es": "^4.17.21",
|
||||
"nprogress": "^0.2.0",
|
||||
"pinia": "^2.2.2",
|
||||
"vue": "^3.4.38",
|
||||
"vue-clipboard3": "^2.0.0",
|
||||
"vue-echarts": "^6.7.3",
|
||||
"vue-router": "^4.4.3",
|
||||
"vue3-video-play": "1.3.1-beta.6",
|
||||
"vuedraggable": "^4.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rushstack/eslint-patch": "^1.10.4",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/node": "^16.18.105",
|
||||
"@types/nprogress": "^0.2.3",
|
||||
"@vitejs/plugin-legacy": "^2.3.1",
|
||||
"@vitejs/plugin-vue": "^3.2.0",
|
||||
"@vitejs/plugin-vue-jsx": "^2.1.1",
|
||||
"@vue/eslint-config-prettier": "^7.1.0",
|
||||
"@vue/eslint-config-typescript": "^11.0.3",
|
||||
"@vue/tsconfig": "^0.1.3",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"consola": "^2.15.3",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-plugin-simple-import-sort": "^12.1.1",
|
||||
"eslint-plugin-vue": "^9.27.0",
|
||||
"execa": "^6.1.0",
|
||||
"fs-extra": "^10.1.0",
|
||||
"postcss": "^8.4.41",
|
||||
"prettier": "^2.8.8",
|
||||
"sass": "^1.77.8",
|
||||
"tailwindcss": "^3.4.10",
|
||||
"terser": "^5.31.6",
|
||||
"typescript": "~4.7.4",
|
||||
"unplugin-auto-import": "^0.9.5",
|
||||
"unplugin-vue-components": "^0.19.9",
|
||||
"vite": "^3.2.10",
|
||||
"vite-plugin-style-import": "^2.0.0",
|
||||
"vite-plugin-svg-icons": "^2.0.1",
|
||||
"vite-plugin-vue-setup-extend": "^0.4.0",
|
||||
"vue-tsc": "^0.38.9"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
import fsExtra from 'fs-extra'
|
||||
import path from 'path'
|
||||
|
||||
const { existsSync, remove, copy } = fsExtra
|
||||
const cwd = process.cwd()
|
||||
//打包发布路径,谨慎改动
|
||||
const releaseRelativePath = '../public/admin'
|
||||
const distPath = path.resolve(cwd, 'dist')
|
||||
const releasePath = path.resolve(cwd, releaseRelativePath)
|
||||
|
||||
async function build() {
|
||||
if (existsSync(releasePath)) {
|
||||
await remove(releasePath)
|
||||
}
|
||||
console.log(`文件正在复制 ==> ${releaseRelativePath}`)
|
||||
try {
|
||||
await copyFile(distPath, releasePath)
|
||||
} catch (error) {
|
||||
console.log(`\n ${error}`)
|
||||
}
|
||||
console.log(`文件已复制 ==> ${releaseRelativePath}`)
|
||||
}
|
||||
|
||||
function copyFile(sourceDir, targetDir) {
|
||||
return new Promise((resolve, reject) => {
|
||||
copy(sourceDir, targetDir, (err) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
build()
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
<script setup lang="ts">
|
||||
import { useDark, useThrottleFn, useWindowSize } from '@vueuse/core'
|
||||
import zhCn from 'element-plus/es/locale/lang/zh-cn'
|
||||
|
||||
import { ScreenEnum } from './enums/appEnums'
|
||||
import useAppStore from './stores/modules/app'
|
||||
import useSettingStore from './stores/modules/setting'
|
||||
|
||||
const appStore = useAppStore()
|
||||
const settingStore = useSettingStore()
|
||||
const elConfig = {
|
||||
zIndex: 3000,
|
||||
locale: zhCn
|
||||
}
|
||||
const isDark = useDark()
|
||||
onMounted(async () => {
|
||||
//设置主题色
|
||||
settingStore.setTheme(isDark.value)
|
||||
})
|
||||
|
||||
const { width } = useWindowSize()
|
||||
watch(
|
||||
width,
|
||||
useThrottleFn((value) => {
|
||||
if (value > ScreenEnum.SM) {
|
||||
appStore.setMobile(false)
|
||||
appStore.toggleCollapsed(false)
|
||||
} else {
|
||||
appStore.setMobile(true)
|
||||
appStore.toggleCollapsed(true)
|
||||
}
|
||||
if (value < ScreenEnum.MD) {
|
||||
appStore.toggleCollapsed(true)
|
||||
}
|
||||
}),
|
||||
{
|
||||
immediate: true
|
||||
}
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-config-provider :locale="elConfig.locale" :z-index="elConfig.zIndex">
|
||||
<router-view />
|
||||
</el-config-provider>
|
||||
</template>
|
||||
|
||||
<style></style>
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 配置
|
||||
export function getConfig() {
|
||||
return request.get({ url: '/config/getConfig' })
|
||||
}
|
||||
|
||||
// 工作台主页
|
||||
export function getWorkbench() {
|
||||
return request.get({ url: '/workbench/index' })
|
||||
}
|
||||
|
||||
//字典数据
|
||||
export function getDictData(params: any) {
|
||||
return request.get({ url: '/config/dict', params })
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
export function getRechargeConfig() {
|
||||
return request.get({ url: '/recharge.recharge/getConfig' })
|
||||
}
|
||||
|
||||
// 设置
|
||||
export function setRechargeConfig(params: any) {
|
||||
return request.post({ url: '/recharge.recharge/setConfig', params })
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 文章分类列表
|
||||
export function articleCateLists(params?: any) {
|
||||
return request.get({ url: '/article.articleCate/lists', params })
|
||||
}
|
||||
// 文章分类列表
|
||||
export function articleCateAll(params?: any) {
|
||||
return request.get({ url: '/article.articleCate/all', params })
|
||||
}
|
||||
|
||||
// 添加文章分类
|
||||
export function articleCateAdd(params: any) {
|
||||
return request.post({ url: '/article.articleCate/add', params })
|
||||
}
|
||||
|
||||
// 编辑文章分类
|
||||
export function articleCateEdit(params: any) {
|
||||
return request.post({ url: '/article.articleCate/edit', params })
|
||||
}
|
||||
|
||||
// 删除文章分类
|
||||
export function articleCateDelete(params: any) {
|
||||
return request.post({ url: '/article.articleCate/delete', params })
|
||||
}
|
||||
|
||||
// 文章分类详情
|
||||
export function articleCateDetail(params: any) {
|
||||
return request.get({ url: '/article.articleCate/detail', params })
|
||||
}
|
||||
|
||||
// 文章分类状态
|
||||
export function articleCateStatus(params: any) {
|
||||
return request.post({ url: '/article.articleCate/updateStatus', params })
|
||||
}
|
||||
|
||||
// 文章列表
|
||||
export function articleLists(params?: any) {
|
||||
return request.get({ url: '/article.article/lists', params })
|
||||
}
|
||||
// 文章列表
|
||||
export function articleAll(params?: any) {
|
||||
return request.get({ url: '/article/all', params })
|
||||
}
|
||||
|
||||
// 添加文章
|
||||
export function articleAdd(params: any) {
|
||||
return request.post({ url: '/article.article/add', params })
|
||||
}
|
||||
|
||||
// 编辑文章
|
||||
export function articleEdit(params: any) {
|
||||
return request.post({ url: '/article.article/edit', params })
|
||||
}
|
||||
|
||||
// 删除文章
|
||||
export function articleDelete(params: any) {
|
||||
return request.post({ url: '/article.article/delete', params })
|
||||
}
|
||||
|
||||
// 文章详情
|
||||
export function articleDetail(params: any) {
|
||||
return request.get({ url: '/article.article/detail', params })
|
||||
}
|
||||
|
||||
// 文章分类状态
|
||||
export function articleStatus(params: any) {
|
||||
return request.post({ url: '/article.article/updateStatus', params })
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// H5渠道配置保存
|
||||
export function setH5Config(params: any) {
|
||||
return request.post({ url: '/channel.web_page_setting/setConfig', params })
|
||||
}
|
||||
|
||||
// H5渠道配置详情
|
||||
export function getH5Config() {
|
||||
return request.get({ url: '/channel.web_page_setting/getConfig' })
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 微信开发平台配置保存
|
||||
export function setOpenSettingConfig(params: any) {
|
||||
return request.post({ url: '/channel.open_setting/setConfig', params })
|
||||
}
|
||||
|
||||
// 微信开发平台配置详情
|
||||
export function getOpenSettingConfig() {
|
||||
return request.get({ url: '/channel.open_setting/getConfig' })
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 微信小程序配置保存
|
||||
export function setWeappConfig(params: any) {
|
||||
return request.post({ url: '/channel.mnp_settings/setConfig', params })
|
||||
}
|
||||
|
||||
// 微信小程序配置详情
|
||||
export function getWeappConfig() {
|
||||
return request.get({ url: '/channel.mnp_settings/getConfig' })
|
||||
}
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 微信公众号配置保存
|
||||
export function setOaConfig(params: any) {
|
||||
return request.post({ url: '/channel.official_account_setting/setConfig', params })
|
||||
}
|
||||
|
||||
// 微信公众号配置详情
|
||||
export function getOaConfig() {
|
||||
return request.get({ url: '/channel.official_account_setting/getConfig' })
|
||||
}
|
||||
|
||||
export interface Menu {
|
||||
name: string
|
||||
has_menu?: boolean
|
||||
type?: string
|
||||
url?: string
|
||||
appid?: string
|
||||
pagepath?: string
|
||||
sub_button: Menu[] | any
|
||||
}
|
||||
|
||||
/**
|
||||
* @return { Promise }
|
||||
* @description 获取菜单
|
||||
*/
|
||||
export function getOaMenu() {
|
||||
return request.get({ url: '/channel.official_account_menu/detail' })
|
||||
}
|
||||
|
||||
/**
|
||||
* @return { Promise }
|
||||
* @param { Menu } Menu
|
||||
* @description 菜单保存
|
||||
*/
|
||||
export function setOaMenuSave(params: Menu | any) {
|
||||
return request.post({ url: '/channel.official_account_menu/save', params })
|
||||
}
|
||||
|
||||
/**
|
||||
* @return { Promise }
|
||||
* @param { Menu } Menu
|
||||
* @description 菜单发布
|
||||
*/
|
||||
export function setOaMenuPublish(params: Menu | any) {
|
||||
return request.post({ url: '/channel.official_account_menu/saveAndPublish', params })
|
||||
}
|
||||
|
||||
/**
|
||||
* @return { Promise }
|
||||
* @param { string } reply_type
|
||||
* @description 获取回复列表
|
||||
*/
|
||||
export function getOaReplyList(params: { reply_type: string }) {
|
||||
return request.get({ url: '/channel.official_account_reply/lists', params })
|
||||
}
|
||||
|
||||
/**
|
||||
* @return { Promise }
|
||||
* @param { number } id
|
||||
* @description 回复列表删除
|
||||
*/
|
||||
export function oaReplyDel(params: { id: number }) {
|
||||
return request.post({ url: '/channel.official_account_reply/delete', params })
|
||||
}
|
||||
|
||||
/**
|
||||
* @return { Promise }
|
||||
* @param { number } id
|
||||
* @description 回复状态修改
|
||||
*/
|
||||
export function changeOaReplyStatus(params: { id: number }) {
|
||||
return request.post({ url: '/channel.official_account_reply/status', params })
|
||||
}
|
||||
|
||||
export interface Reply {
|
||||
content: string // 内容
|
||||
content_type: number // 内容类型: 1=文本
|
||||
keyword?: string // 关键词
|
||||
matching_type?: number // 匹配方式: [1=全匹配, 2=模糊匹配]
|
||||
name: string // 规则名称
|
||||
status: number // 状态: 1=开启, 0=关闭
|
||||
reply_type: number // 类型: 回复类型 1-关注回复 2-关键词回复 3-默认回复
|
||||
reply_num: number // 回复数量`
|
||||
sort: number // 排序
|
||||
}
|
||||
/**
|
||||
* @return { Promise }
|
||||
* @description 回复添加
|
||||
*/
|
||||
export function oaReplyAdd(params: Reply) {
|
||||
return request.post({ url: '/channel.official_account_reply/add', params })
|
||||
}
|
||||
|
||||
/**
|
||||
* @return { Promise }
|
||||
* @description 回复编辑
|
||||
*/
|
||||
export function oaReplyEdit(params: Reply) {
|
||||
return request.post({ url: '/channel.official_account_reply/edit', params })
|
||||
}
|
||||
|
||||
/**
|
||||
* @return { Promise }
|
||||
* @param { string } type
|
||||
* @description 获取回复详情
|
||||
*/
|
||||
export function getOaReplyDetail(params: { id: number }) {
|
||||
return request.get({ url: '/channel.official_account_reply/detail', params })
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 班级列表
|
||||
export function classLists(params?: Record<string, any>) {
|
||||
return request.get({ url: '/class/list', params })
|
||||
}
|
||||
|
||||
// 班级详情
|
||||
export function classDetail(params: Record<string, any>) {
|
||||
return request.get({ url: '/class/detail', params })
|
||||
}
|
||||
|
||||
// 班级新增
|
||||
export function classAdd(params: Record<string, any>) {
|
||||
return request.post({ url: '/class/add', params })
|
||||
}
|
||||
|
||||
// 班级编辑
|
||||
export function classEdit(params: Record<string, any>) {
|
||||
return request.post({ url: '/class/edit', params })
|
||||
}
|
||||
|
||||
// 班级删除
|
||||
export function classDelete(params: Record<string, any>) {
|
||||
return request.post({ url: '/class/del', params })
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 教室列表
|
||||
export function classroomLists(params?: Record<string, any>) {
|
||||
return request.get({ url: '/classroom/list', params })
|
||||
}
|
||||
|
||||
// 教室详情
|
||||
export function classroomDetail(params: Record<string, any>) {
|
||||
return request.get({ url: '/classroom/detail', params })
|
||||
}
|
||||
|
||||
// 教室新增
|
||||
export function classroomAdd(params: Record<string, any>) {
|
||||
return request.post({ url: '/classroom/add', params })
|
||||
}
|
||||
|
||||
// 教室编辑
|
||||
export function classroomEdit(params: Record<string, any>) {
|
||||
return request.post({ url: '/classroom/edit', params })
|
||||
}
|
||||
|
||||
// 教室删除
|
||||
export function classroomDelete(params: Record<string, any>) {
|
||||
return request.post({ url: '/classroom/del', params })
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 学院列表
|
||||
export function collegeLists(params?: Record<string, any>) {
|
||||
return request.get({ url: '/college/list', params })
|
||||
}
|
||||
|
||||
// 学院详情
|
||||
export function collegeDetail(params: Record<string, any>) {
|
||||
return request.get({ url: '/college/detail', params })
|
||||
}
|
||||
|
||||
// 学院新增
|
||||
export function collegeAdd(params: Record<string, any>) {
|
||||
return request.post({ url: '/college/add', params })
|
||||
}
|
||||
|
||||
// 学院编辑
|
||||
export function collegeEdit(params: Record<string, any>) {
|
||||
return request.post({ url: '/college/edit', params })
|
||||
}
|
||||
|
||||
// 学院删除
|
||||
export function collegeDelete(params: Record<string, any>) {
|
||||
return request.post({ url: '/college/del', params })
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 用户列表
|
||||
export function getUserList(params: any) {
|
||||
return request.get({ url: '/user.user/lists', params }, { ignoreCancelToken: true })
|
||||
}
|
||||
|
||||
// 用户详情
|
||||
export function getUserDetail(params: any) {
|
||||
return request.get({ url: '/user.user/detail', params })
|
||||
}
|
||||
|
||||
// 用户编辑
|
||||
export function userEdit(params: any) {
|
||||
return request.post({ url: '/user.user/edit', params })
|
||||
}
|
||||
|
||||
// 用户编辑
|
||||
export function adjustMoney(params: any) {
|
||||
return request.post({ url: '/user.user/adjustMoney', params })
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 课程列表
|
||||
export function courseLists(params?: Record<string, any>) {
|
||||
return request.get({ url: '/course/list', params })
|
||||
}
|
||||
|
||||
// 课程详情
|
||||
export function courseDetail(params: Record<string, any>) {
|
||||
return request.get({ url: '/course/detail', params })
|
||||
}
|
||||
|
||||
// 课程新增
|
||||
export function courseAdd(params: Record<string, any>) {
|
||||
return request.post({ url: '/course/add', params })
|
||||
}
|
||||
|
||||
// 课程编辑
|
||||
export function courseEdit(params: Record<string, any>) {
|
||||
return request.post({ url: '/course/edit', params })
|
||||
}
|
||||
|
||||
// 课程删除
|
||||
export function courseDelete(params: Record<string, any>) {
|
||||
return request.post({ url: '/course/del', params })
|
||||
}
|
||||
|
||||
// 获取导入模板
|
||||
export function courseTemplate() {
|
||||
return request.get({ url: '/course/template' })
|
||||
}
|
||||
|
||||
// 上传导入模板
|
||||
export function courseUpTemplate(formData: FormData) {
|
||||
return request.post({
|
||||
url: '/course/upload.template',
|
||||
data: formData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 上传导入文件
|
||||
export function courseUploadFile(formData: FormData) {
|
||||
return request.post(
|
||||
{
|
||||
url: '/course/batch.add',
|
||||
data: formData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
},
|
||||
{
|
||||
// 配置返回完整响应对象(包含服务器返回的code)
|
||||
isReturnDefaultResponse: true
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 课程类型列表
|
||||
export function typeLists(params?: Record<string, any>) {
|
||||
return request.get({ url: '/course.type/list', params })
|
||||
}
|
||||
|
||||
// 课程类型详情
|
||||
export function typeDetail(params: Record<string, any>) {
|
||||
return request.get({ url: '/course.type/detail', params })
|
||||
}
|
||||
|
||||
// 课程类型新增
|
||||
export function typeAdd(params: Record<string, any>) {
|
||||
return request.post({ url: '/course.type/add', params })
|
||||
}
|
||||
|
||||
// 课程类型编辑
|
||||
export function typeEdit(params: Record<string, any>) {
|
||||
return request.post({ url: '/course.type/edit', params }, { isTransformResponse: false })
|
||||
}
|
||||
|
||||
// 课程类型删除
|
||||
export function typeDelete(params: Record<string, any>) {
|
||||
return request.post({ url: '/course.type/del', params })
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 专业培养计划列表
|
||||
export function curriculumLists(params?: Record<string, any>) {
|
||||
return request.get({ url: '/curriculum/list', params })
|
||||
}
|
||||
|
||||
// 专业培养计划详情
|
||||
export function curriculumDetail(params: Record<string, any>) {
|
||||
return request.get({ url: '/curriculum/detail', params })
|
||||
}
|
||||
|
||||
// 专业培养计划新增
|
||||
export function curriculumAdd(params: Record<string, any>) {
|
||||
return request.post({ url: '/curriculum/add', params })
|
||||
}
|
||||
|
||||
// 专业培养计划编辑
|
||||
export function curriculumEdit(params: Record<string, any>) {
|
||||
return request.post({ url: '/curriculum/edit', params })
|
||||
}
|
||||
|
||||
// 专业培养计划删除
|
||||
export function curriculumDelete(params: Record<string, any>) {
|
||||
return request.post({ url: '/curriculum/del', params })
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 页面装修详情
|
||||
export function getDecoratePages(params: any) {
|
||||
return request.get({ url: '/decorate.page/detail', params }, { ignoreCancelToken: true })
|
||||
}
|
||||
|
||||
// 页面装修保存
|
||||
export function setDecoratePages(params: any) {
|
||||
return request.post({ url: '/decorate.page/save', params })
|
||||
}
|
||||
|
||||
// 获取首页文章数据
|
||||
export function getDecorateArticle(params?: any) {
|
||||
return request.get({ url: '/decorate.data/article', params })
|
||||
}
|
||||
|
||||
// 底部导航详情
|
||||
export function getDecorateTabbar(params?: any) {
|
||||
return request.get({ url: '/decorate.tabbar/detail', params })
|
||||
}
|
||||
|
||||
// 底部导航保存
|
||||
export function setDecorateTabbar(params: any) {
|
||||
return request.post({ url: '/decorate.tabbar/save', params })
|
||||
}
|
||||
|
||||
// pc装修数据
|
||||
export function getDecoratePc() {
|
||||
return request.get({ url: '/decorate.data/pc' })
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
export function fileCateAdd(params: Record<string, any>) {
|
||||
return request.post({ url: '/file/addCate', params })
|
||||
}
|
||||
|
||||
export function fileCateEdit(params: Record<string, any>) {
|
||||
return request.post({ url: '/file/editCate', params })
|
||||
}
|
||||
|
||||
// 文件分类删除
|
||||
export function fileCateDelete(params: Record<string, any>) {
|
||||
return request.post({ url: '/file/delCate', params })
|
||||
}
|
||||
|
||||
// 文件分类列表
|
||||
export function fileCateLists(params: Record<string, any>) {
|
||||
return request.get({ url: '/file/listCate', params })
|
||||
}
|
||||
|
||||
// 文件列表
|
||||
export function fileList(params: Record<string, any>) {
|
||||
return request.get(
|
||||
{ url: '/file/lists', params },
|
||||
{ ignoreCancelToken: true, isOpenRetry: false }
|
||||
)
|
||||
}
|
||||
|
||||
// 文件删除
|
||||
export function fileDelete(params: Record<string, any>) {
|
||||
return request.post({ url: '/file/delete', params })
|
||||
}
|
||||
|
||||
// 文件移动
|
||||
export function fileMove(params: Record<string, any>) {
|
||||
return request.post({ url: '/file/move', params })
|
||||
}
|
||||
|
||||
// 文件重命名
|
||||
export function fileRename(params: { id: number; name: string }) {
|
||||
return request.post({ url: '/file/rename', params })
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 余额明细
|
||||
export function accountLog(params?: any) {
|
||||
return request.get({ url: '/finance.account_log/lists', params })
|
||||
}
|
||||
|
||||
// 充值记录
|
||||
export function rechargeLists(params?: any) {
|
||||
return request.get({ url: '/recharge.recharge/lists', params }, { ignoreCancelToken: true })
|
||||
}
|
||||
|
||||
// 余额变动类型
|
||||
export function getUmChangeType(params?: any) {
|
||||
return request.get({ url: '/finance.account_log/getUmChangeType', params })
|
||||
}
|
||||
|
||||
//退款
|
||||
export function refund(params?: any) {
|
||||
return request.post({ url: '/recharge.recharge/refund', params })
|
||||
}
|
||||
|
||||
//重新退款
|
||||
export function refundAgain(params?: any) {
|
||||
return request.post({ url: '/recharge.recharge/refundAgain', params })
|
||||
}
|
||||
|
||||
//退款记录
|
||||
export function refundRecord(params?: any) {
|
||||
return request.get({ url: '/finance.refund/record', params })
|
||||
}
|
||||
|
||||
//退款日志
|
||||
export function refundLog(params?: any) {
|
||||
return request.get({ url: '/finance.refund/log', params })
|
||||
}
|
||||
|
||||
//退款统计
|
||||
export function refundStat(params?: any) {
|
||||
return request.get({ url: '/finance.refund/stat', params })
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 学生信息列表
|
||||
export function infoLists(params?: Record<string, any>) {
|
||||
return request.get({ url: '/info/list', params })
|
||||
}
|
||||
|
||||
// 学生信息详情
|
||||
export function infoDetail(params: Record<string, any>) {
|
||||
return request.get({ url: '/info/detail', params })
|
||||
}
|
||||
|
||||
// 学生信息新增
|
||||
export function infoAdd(params: Record<string, any>) {
|
||||
return request.post({ url: '/info/add', params })
|
||||
}
|
||||
|
||||
// 学生信息编辑
|
||||
export function infoEdit(params: Record<string, any>) {
|
||||
return request.post({ url: '/info/edit', params })
|
||||
}
|
||||
|
||||
// 学生信息删除
|
||||
export function infoDelete(params: Record<string, any>) {
|
||||
return request.post({ url: '/info/del', params })
|
||||
}
|
||||
|
||||
// 添加随机学生(测试用)
|
||||
export function infoAddStudent(params: Record<string, any>) {
|
||||
return request.post({ url: '/info/create.random.info', params })
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 专业列表
|
||||
export function majorLists(params?: Record<string, any>) {
|
||||
return request.get({ url: '/major/list', params })
|
||||
}
|
||||
|
||||
// 专业详情
|
||||
export function majorDetail(params: Record<string, any>) {
|
||||
return request.get({ url: '/major/detail', params })
|
||||
}
|
||||
|
||||
// 专业新增
|
||||
export function majorAdd(params: Record<string, any>) {
|
||||
return request.post({ url: '/major/add', params })
|
||||
}
|
||||
|
||||
// 专业编辑
|
||||
export function majorEdit(params: Record<string, any>) {
|
||||
return request.post({ url: '/major/edit', params })
|
||||
}
|
||||
|
||||
// 专业删除
|
||||
export function majorDelete(params: Record<string, any>) {
|
||||
return request.post({ url: '/major/del', params })
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 通知设置列表
|
||||
export function noticeLists(params: any) {
|
||||
return request.get({ url: '/notice.notice/settingLists', params })
|
||||
}
|
||||
|
||||
// 通知设置详情
|
||||
export function noticeDetail(params: any) {
|
||||
return request.get({ url: '/notice.notice/detail', params })
|
||||
}
|
||||
|
||||
// 通知设置保存
|
||||
export function setNoticeConfig(params: any) {
|
||||
return request.post({ url: '/notice.notice/set', params })
|
||||
}
|
||||
|
||||
// 短信设置列表
|
||||
export function smsLists() {
|
||||
return request.get({ url: '/notice.sms_config/getConfig' })
|
||||
}
|
||||
|
||||
// 短信设置详情
|
||||
export function smsDetail(params: any) {
|
||||
return request.get({ url: '/notice.sms_config/detail', params })
|
||||
}
|
||||
|
||||
// 短信设置保存
|
||||
export function setSmsConfig(params: any) {
|
||||
return request.post({ url: '/notice.sms_config/setConfig', params })
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 部门列表
|
||||
export function deptLists(params?: any) {
|
||||
return request.get({ url: '/dept.dept/lists', params })
|
||||
}
|
||||
|
||||
// 添加部门
|
||||
export function deptAdd(params: any) {
|
||||
return request.post({ url: '/dept.dept/add', params })
|
||||
}
|
||||
|
||||
// 编辑部门
|
||||
export function deptEdit(params: any) {
|
||||
return request.post({ url: '/dept.dept/edit', params })
|
||||
}
|
||||
|
||||
// 删除部门
|
||||
export function deptDelete(params: any) {
|
||||
return request.post({ url: '/dept.dept/delete', params })
|
||||
}
|
||||
|
||||
// 部门详情
|
||||
export function deptDetail(params: any) {
|
||||
return request.get({ url: '/dept.dept/detail', params })
|
||||
}
|
||||
|
||||
// 部门列表全部
|
||||
export function deptAll() {
|
||||
return request.get({ url: '/dept.dept/all' })
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 岗位列表
|
||||
export function jobsLists(params: any) {
|
||||
return request.get({ url: '/dept.jobs/lists', params }, { ignoreCancelToken: true })
|
||||
}
|
||||
|
||||
// 岗位列表全部
|
||||
export function jobsAll(params: any) {
|
||||
return request.get({ url: '/dept.jobs/all', params })
|
||||
}
|
||||
|
||||
// 添加岗位
|
||||
export function jobsAdd(params: any) {
|
||||
return request.post({ url: '/dept.jobs/add', params })
|
||||
}
|
||||
|
||||
// 编辑岗位
|
||||
export function jobsEdit(params: any) {
|
||||
return request.post({ url: '/dept.jobs/edit', params })
|
||||
}
|
||||
|
||||
// 删除岗位
|
||||
export function jobsDelete(params: any) {
|
||||
return request.post({ url: '/dept.jobs/delete', params })
|
||||
}
|
||||
|
||||
// 岗位详情
|
||||
export function jobsDetail(params: any) {
|
||||
return request.get({ url: '/dept.jobs/detail', params })
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 管理员列表
|
||||
export function adminLists(params: any) {
|
||||
return request.get({ url: '/auth.admin/lists', params }, { ignoreCancelToken: true })
|
||||
}
|
||||
// 管理员列表全部
|
||||
export function adminAll(params: any) {
|
||||
return request.get({ url: '/auth.admin/all', params })
|
||||
}
|
||||
// 管理员添加
|
||||
export function adminAdd(params: any) {
|
||||
return request.post({ url: '/auth.admin/add', params })
|
||||
}
|
||||
|
||||
// 管理员编辑
|
||||
export function adminEdit(params: any) {
|
||||
return request.post({ url: '/auth.admin/edit', params })
|
||||
}
|
||||
|
||||
// 管理员删除
|
||||
export function adminDelete(params: any) {
|
||||
return request.post({ url: '/auth.admin/delete', params })
|
||||
}
|
||||
|
||||
// 管理员详情
|
||||
export function adminDetail(params: any) {
|
||||
return request.get({ url: '/auth.admin/detail', params })
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 菜单列表
|
||||
export function menuLists(params: Record<string, any>) {
|
||||
return request.get({ url: '/auth.menu/lists', params })
|
||||
}
|
||||
// 菜单全部
|
||||
export function menuAll(params?: Record<string, any>) {
|
||||
return request.get({ url: '/auth.menu/all', params })
|
||||
}
|
||||
|
||||
// 添加菜单
|
||||
export function menuAdd(params: Record<string, any>) {
|
||||
return request.post({ url: '/auth.menu/add', params })
|
||||
}
|
||||
|
||||
// 编辑菜单
|
||||
export function menuEdit(params: Record<string, any>) {
|
||||
return request.post({ url: '/auth.menu/edit', params })
|
||||
}
|
||||
|
||||
// 菜单删除
|
||||
export function menuDelete(params: Record<string, any>) {
|
||||
return request.post({ url: '/auth.menu/delete', params })
|
||||
}
|
||||
|
||||
// 菜单详情
|
||||
export function menuDetail(params: Record<string, any>) {
|
||||
return request.get({ url: '/auth.menu/detail', params })
|
||||
}
|
||||
|
||||
|
||||
// 菜单列表
|
||||
export function systemMenuLists(params: Record<string, any>) {
|
||||
return request.get({ url: '/auth.menu/systemMenuLists', params })
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 角色列表
|
||||
export function roleLists(params: any) {
|
||||
return request.get({ url: '/auth.role/lists', params })
|
||||
}
|
||||
// 角色列表全部
|
||||
export function roleAll(params: any) {
|
||||
return request.get({ url: '/auth.role/all', params })
|
||||
}
|
||||
// 添加角色
|
||||
export function roleAdd(params: any) {
|
||||
return request.post({ url: '/auth.role/add', params })
|
||||
}
|
||||
// 编辑角色
|
||||
export function roleEdit(params: any) {
|
||||
return request.post({ url: '/auth.role/edit', params })
|
||||
}
|
||||
// 删除角色
|
||||
export function roleDelete(params: any) {
|
||||
return request.post({ url: '/auth.role/delete', params })
|
||||
}
|
||||
|
||||
// 角色详情
|
||||
export function roleDetail(params: any) {
|
||||
return request.get({ url: '/auth.role/detail', params })
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 设备要求列表
|
||||
export function requirementLists(params?: Record<string, any>) {
|
||||
return request.get({ url: '/requirement/list', params })
|
||||
}
|
||||
|
||||
// 设备要求详情
|
||||
export function requirementDetail(params: Record<string, any>) {
|
||||
return request.get({ url: '/requirement/detail', params })
|
||||
}
|
||||
|
||||
// 设备要求新增
|
||||
export function requirementAdd(params: Record<string, any>) {
|
||||
return request.post({ url: '/requirement/add', params })
|
||||
}
|
||||
|
||||
// 设备要求编辑
|
||||
export function requirementEdit(params: Record<string, any>) {
|
||||
return request.post({ url: '/requirement/edit', params })
|
||||
}
|
||||
|
||||
// 设备要求删除
|
||||
export function requirementDelete(params: Record<string, any>) {
|
||||
return request.post({ url: '/requirement/del', params })
|
||||
}
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 字典类型列表
|
||||
export function dictTypeLists(params: any) {
|
||||
return request.get({ url: '/setting.dict.dict_type/lists', params })
|
||||
}
|
||||
|
||||
// 字典类型列表全部
|
||||
export function dictTypeAll(params: any) {
|
||||
return request.get({ url: '/setting.dict.dict_type/all', params })
|
||||
}
|
||||
|
||||
// 添加字典类型
|
||||
export function dictTypeAdd(params: any) {
|
||||
return request.post({ url: '/setting.dict.dict_type/add', params })
|
||||
}
|
||||
|
||||
// 编辑字典类型
|
||||
export function dictTypeEdit(params: any) {
|
||||
return request.post({ url: '/setting.dict.dict_type/edit', params })
|
||||
}
|
||||
|
||||
// 删除字典类型
|
||||
export function dictTypeDelete(params: any) {
|
||||
return request.post({ url: '/setting.dict.dict_type/delete', params })
|
||||
}
|
||||
|
||||
// 字典类型详情
|
||||
export function dictTypeDetail(params: any) {
|
||||
return request.get({ url: '/setting.dict.dict_type/detail', params })
|
||||
}
|
||||
|
||||
// 字典数据列表
|
||||
export function dictDataLists(params: any) {
|
||||
return request.get(
|
||||
{ url: '/setting.dict.dict_data/lists', params },
|
||||
{
|
||||
ignoreCancelToken: true
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// 添加字典数据
|
||||
export function dictDataAdd(params: any) {
|
||||
return request.post({ url: '/setting.dict.dict_data/add', params })
|
||||
}
|
||||
|
||||
// 编辑字典数据
|
||||
export function dictDataEdit(params: any) {
|
||||
return request.post({ url: '/setting.dict.dict_data/edit', params })
|
||||
}
|
||||
|
||||
// 删除字典数据
|
||||
export function dictDataDelete(params: any) {
|
||||
return request.post({ url: '/setting.dict.dict_data/delete', params })
|
||||
}
|
||||
|
||||
// 字典数据详情
|
||||
export function dictDataDetail(params: any) {
|
||||
return request.get({ url: '/setting.dict.dict_data/detail', params })
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 获取支付方式
|
||||
export function getPayWay() {
|
||||
return request.get({ url: '/setting.pay.pay_way/getPayWay' })
|
||||
}
|
||||
|
||||
// 设置支付方式
|
||||
export function setPayWay(params: any) {
|
||||
return request.post({ url: '/setting.pay.pay_way/setPayWay', params })
|
||||
}
|
||||
|
||||
// 获取支付方式
|
||||
export function getPayConfigLists() {
|
||||
return request.get({ url: '/setting.pay.pay_config/lists' })
|
||||
}
|
||||
|
||||
// 设置支付方式
|
||||
export function setPayConfig(params: any) {
|
||||
return request.post({ url: '/setting.pay.pay_config/setConfig', params })
|
||||
}
|
||||
|
||||
// 设置支付方式
|
||||
export function getPayConfig(params: any) {
|
||||
return request.get({ url: '/setting.pay.pay_config/getConfig', params })
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
* @return { Promise }
|
||||
* @description 获取热门搜索数据
|
||||
*/
|
||||
export function getSearch() {
|
||||
return request.get({ url: '/setting.hot_search/getConfig' })
|
||||
}
|
||||
|
||||
export interface List {
|
||||
name: string // 搜索关键字
|
||||
sort: number // 热门搜索排序
|
||||
}
|
||||
|
||||
export interface Search {
|
||||
status: number // 是否开启搜索0/1
|
||||
data: List[]
|
||||
}
|
||||
/**
|
||||
* @return { Promise }
|
||||
* @param { Search } Search
|
||||
* @description 设置热门搜索
|
||||
*/
|
||||
export function setSearch(params: Search) {
|
||||
return request.post({ url: '/setting.hot_search/setConfig', params })
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 获取存储引擎列表
|
||||
export function storageLists() {
|
||||
return request.get({ url: '/setting.storage/lists' })
|
||||
}
|
||||
|
||||
// 设置存储引擎信息
|
||||
export function storageChange(params: any) {
|
||||
return request.post({ url: '/setting.storage/change', params })
|
||||
}
|
||||
|
||||
// 设置存储引擎信息
|
||||
export function storageSetup(params: any) {
|
||||
return request.post({ url: '/setting.storage/setup', params })
|
||||
}
|
||||
|
||||
// 获取存储配置信息
|
||||
export function storageDetail(params: any) {
|
||||
return request.get({ url: '/setting.storage/detail', params })
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 获取系统环境
|
||||
export function systemInfo() {
|
||||
return request.get({ url: '/setting.system.system/info' })
|
||||
}
|
||||
|
||||
// 获取系统日志列表
|
||||
export function systemLogLists(params: any) {
|
||||
return request.get({ url: '/setting.system.log/lists', params }, { ignoreCancelToken: true })
|
||||
}
|
||||
|
||||
// 清除系统缓存
|
||||
export function systemCacheClear() {
|
||||
return request.post({ url: '/setting.system.cache/clear' })
|
||||
}
|
||||
|
||||
// 定时任务列表
|
||||
export function crontabLists(params: any) {
|
||||
return request.get({ url: '/crontab.crontab/lists', params })
|
||||
}
|
||||
|
||||
// 添加定时任务
|
||||
export function crontabAdd(params: any) {
|
||||
return request.post({ url: '/crontab.crontab/add', params })
|
||||
}
|
||||
|
||||
// 定时任务详情
|
||||
export function crontabDetail(params: any) {
|
||||
return request.get({ url: '/crontab.crontab/detail', params })
|
||||
}
|
||||
|
||||
// 编辑定时任务
|
||||
export function crontabEdit(params: any) {
|
||||
return request.post({ url: '/crontab.crontab/edit', params })
|
||||
}
|
||||
|
||||
// 删除定时任务
|
||||
export function crontabDel(params: any) {
|
||||
return request.post({ url: '/crontab.crontab/delete', params })
|
||||
}
|
||||
|
||||
// 获取规则执行时间
|
||||
export function crontabExpression(params: any) {
|
||||
return request.get({ url: '/crontab.crontab/expression', params })
|
||||
}
|
||||
|
||||
// 操作定时任务
|
||||
export function srontabOperate(params: any) {
|
||||
return request.post({ url: '/crontab.crontab/operate', params })
|
||||
}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
* @return { Promise }
|
||||
* @description 获取用户设置
|
||||
*/
|
||||
export function getUserSetup() {
|
||||
return request.get({ url: '/setting.user.user/getConfig' })
|
||||
}
|
||||
|
||||
/**
|
||||
* @return { Promise }
|
||||
* @param { string } default_avatar 默认用户头像
|
||||
* @description 设置用户设置
|
||||
*/
|
||||
export function setUserSetup(params: { default_avatar: string }) {
|
||||
return request.post({ url: '/setting.user.user/setConfig', params })
|
||||
}
|
||||
|
||||
/**
|
||||
* @return { Promise }
|
||||
* @description 设置登录注册规则
|
||||
*/
|
||||
export function getLogin() {
|
||||
return request.get({ url: '/setting.user.user/getRegisterConfig' })
|
||||
}
|
||||
|
||||
export interface LoginSetup {
|
||||
login_way: number[] | any // 登录方式, 逗号隔开
|
||||
coerce_mobile: number // 强制绑定手机 0/1
|
||||
login_agreement: number // 是否开启协议 0/1
|
||||
third_auth: number // 第三方登录 0/1
|
||||
wechat_auth: number // 微信授权登录 0-关闭 1-开启
|
||||
qq_auth: number // qq授权登录 0-关闭 1-开启
|
||||
}
|
||||
/**
|
||||
* @return { Promise }
|
||||
* @param { LoginSetup } LoginSetup
|
||||
* @description 设置登录注册规则
|
||||
*/
|
||||
export function setLogin(params: LoginSetup) {
|
||||
return request.post({ url: '/setting.user.user/setRegisterConfig', params })
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 获取备案信息
|
||||
export function getCopyright() {
|
||||
return request.get({ url: '/setting.web.web_setting/getCopyright' })
|
||||
}
|
||||
// 设置备案信息
|
||||
export function setCopyright(params: any) {
|
||||
return request.post({ url: '/setting.web.web_setting/setCopyright', params })
|
||||
}
|
||||
// 获取网站信息
|
||||
export function getWebsite() {
|
||||
return request.get({ url: '/setting.web.web_setting/getWebsite' })
|
||||
}
|
||||
// 设置网站信息
|
||||
export function setWebsite(params: any) {
|
||||
return request.post({ url: '/setting.web.web_setting/setWebsite', params })
|
||||
}
|
||||
|
||||
// 获取政策协议
|
||||
export function getProtocol() {
|
||||
return request.get({ url: '/setting.web.web_setting/getAgreement' })
|
||||
}
|
||||
// 设置政策协议
|
||||
export function setProtocol(params: any) {
|
||||
return request.post({ url: '/setting.web.web_setting/setAgreement', params })
|
||||
}
|
||||
|
||||
// 获取站点统计信息
|
||||
export function getSiteStatistics() {
|
||||
return request.get({ url: '/setting.web.web_setting/getSiteStatistics' })
|
||||
}
|
||||
// 设置网站信息
|
||||
export function setSiteStatistics(params: any) {
|
||||
return request.post({ url: '/setting.web.web_setting/setSiteStatistics', params })
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 教师信息扩展列表
|
||||
export function teacherLists(params?: Record<string, any>) {
|
||||
return request.get({ url: '/teacher/list', params })
|
||||
}
|
||||
|
||||
// 教师信息扩展详情
|
||||
export function teacherDetail(params: Record<string, any>) {
|
||||
return request.get({ url: '/teacher/detail', params })
|
||||
}
|
||||
|
||||
// 教师信息扩展新增
|
||||
export function teacherAdd(params: Record<string, any>) {
|
||||
return request.post({ url: '/teacher/add', params })
|
||||
}
|
||||
|
||||
// 教师信息扩展编辑
|
||||
export function teacherEdit(params: Record<string, any>) {
|
||||
return request.post({ url: '/teacher/edit', params })
|
||||
}
|
||||
|
||||
// 教师信息扩展删除
|
||||
export function teacherDelete(params: Record<string, any>) {
|
||||
return request.post({ url: '/teacher/del', params })
|
||||
}
|
||||
|
||||
// 教师可授课程列表
|
||||
export function teacherCourseList(params: Record<string, any>) {
|
||||
return request.get({ url: '/teacher/course/list', params })
|
||||
}
|
||||
|
||||
// 教师可授课程新增
|
||||
export function teacherCourseAdd(params: Record<string, any>) {
|
||||
return request.post({ url: '/teacher/course/add', params })
|
||||
}
|
||||
|
||||
// 教师可授课程删除
|
||||
export function teacherCourseDelete(params: Record<string, any>) {
|
||||
return request.post({ url: '/teacher/course/del', params })
|
||||
}
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 代码生成已选数据表列表接口
|
||||
export function generateTable(params: any) {
|
||||
return request.get({ url: '/gen/list', params })
|
||||
}
|
||||
|
||||
// 数据表列表接口
|
||||
export function dataTable(params: any) {
|
||||
return request.get({ url: '/gen/db', params })
|
||||
}
|
||||
|
||||
// 数据表所有列表接口
|
||||
export function dataTableAll() {
|
||||
return request.get({ url: '/gen/dbAll' })
|
||||
}
|
||||
|
||||
//表名查字段
|
||||
export function dataTableToColumn(params: any) {
|
||||
return request.get({ url: '/gen/dbColumn', params })
|
||||
}
|
||||
//选择要生成代码的数据表
|
||||
export function selectTable(params: any) {
|
||||
return request.post(
|
||||
{ url: '/gen/importTable', params },
|
||||
{
|
||||
isParamsToData: false
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// 已选择的数据表详情
|
||||
export function tableDetail(params: any) {
|
||||
return request.get({ url: '/gen/detail', params })
|
||||
}
|
||||
|
||||
//同步字段
|
||||
export function syncColumn(params: any) {
|
||||
return request.post(
|
||||
{ url: '/gen/syncTable', params },
|
||||
{
|
||||
isParamsToData: false
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
//删除已选择的数据表
|
||||
export function generateDelete(params: any) {
|
||||
return request.post({ url: '/gen/delTable', params })
|
||||
}
|
||||
|
||||
//编辑已选表字段
|
||||
export function generateEdit(params: any) {
|
||||
return request.post({ url: '/gen/editTable', params })
|
||||
}
|
||||
|
||||
//预览代码
|
||||
export function generatePreview(params: any) {
|
||||
return request.get({ url: '/gen/previewCode', params })
|
||||
}
|
||||
|
||||
//生成代码
|
||||
export function generateCode(params: any) {
|
||||
return request.get({ url: '/gen/genCode', params })
|
||||
}
|
||||
|
||||
//下载代码
|
||||
export function downloadCode(params: any) {
|
||||
return request.get(
|
||||
{ responseType: 'blob', url: '/gen/downloadCode', params },
|
||||
{
|
||||
isTransformResponse: false
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 教室类型列表
|
||||
export function typeLists(params?: Record<string, any>) {
|
||||
return request.get({ url: '/type/list', params })
|
||||
}
|
||||
|
||||
// 教室类型详情
|
||||
export function typeDetail(params: Record<string, any>) {
|
||||
return request.get({ url: '/type/detail', params })
|
||||
}
|
||||
|
||||
// 教室类型新增
|
||||
export function typeAdd(params: Record<string, any>) {
|
||||
return request.post({ url: '/type/add', params })
|
||||
}
|
||||
|
||||
// 教室类型编辑
|
||||
export function typeEdit(params: Record<string, any>) {
|
||||
return request.post({ url: '/type/edit', params })
|
||||
}
|
||||
|
||||
// 教室类型删除
|
||||
export function typeDelete(params: Record<string, any>) {
|
||||
return request.post({ url: '/type/del', params })
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 教师不可用时间列表
|
||||
export function unavailableLists(params?: Record<string, any>) {
|
||||
return request.get({ url: '/unavailable/list', params })
|
||||
}
|
||||
|
||||
// 教师不可用时间详情
|
||||
export function unavailableDetail(params: Record<string, any>) {
|
||||
return request.get({ url: '/unavailable/detail', params })
|
||||
}
|
||||
|
||||
// 教师不可用时间新增
|
||||
export function unavailableAdd(params: Record<string, any>) {
|
||||
return request.post({ url: '/unavailable/add', params })
|
||||
}
|
||||
|
||||
// 教师不可用时间编辑
|
||||
export function unavailableEdit(params: Record<string, any>) {
|
||||
return request.post({ url: '/unavailable/edit', params })
|
||||
}
|
||||
|
||||
// 教师不可用时间删除
|
||||
export function unavailableDelete(params: Record<string, any>) {
|
||||
return request.post({ url: '/unavailable/del', params })
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
import config from '@/config'
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 登录
|
||||
export function login(params: Record<string, any>) {
|
||||
return request.post({ url: '/login/account', params: { ...params, terminal: config.terminal } })
|
||||
}
|
||||
|
||||
// 退出登录
|
||||
export function logout() {
|
||||
return request.post({ url: '/login/logout' })
|
||||
}
|
||||
|
||||
// 用户信息
|
||||
export function getUserInfo() {
|
||||
return request.get({ url: '/auth.admin/mySelf' })
|
||||
}
|
||||
|
||||
// 编辑管理员信息
|
||||
export function setUserInfo(params: any) {
|
||||
return request.post({ url: '/auth.admin/editSelf', params })
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 培养方案版本列表
|
||||
export function versionLists(params?: Record<string, any>) {
|
||||
return request.get({ url: '/version/list', params })
|
||||
}
|
||||
|
||||
// 培养方案版本详情
|
||||
export function versionDetail(params: Record<string, any>) {
|
||||
return request.get({ url: '/version/detail', params })
|
||||
}
|
||||
|
||||
// 培养方案版本新增
|
||||
export function versionAdd(params: Record<string, any>) {
|
||||
return request.post({ url: '/version/add', params })
|
||||
}
|
||||
|
||||
// 培养方案版本编辑
|
||||
export function versionEdit(params: Record<string, any>) {
|
||||
return request.post({ url: '/version/edit', params })
|
||||
}
|
||||
|
||||
// 培养方案版本删除
|
||||
export function versionDelete(params: Record<string, any>) {
|
||||
return request.post({ url: '/version/del', params })
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M502.869333 201.408a32.853333 32.853333 0 0 1 0 45.44L276.906667 480h544.384a32 32 0 0 1 0 64H276.885333l225.984 233.130667a32.853333 32.853333 0 0 1 0 45.44 30.485333 30.485333 0 0 1-44.053333 0L179.776 534.741333a32.128 32.128 0 0 1-6.848-10.688 32.213333 32.213333 0 0 1-0.085333-23.808l0.106666-0.32c1.514667-3.861333 3.797333-7.488 6.826667-10.624L458.837333 201.386667a30.485333 30.485333 0 0 1 44.053334 0z" /></svg>
|
||||
|
Before Width: | Height: | Size: 689 B |
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M853.333333 170.666667a85.333333 85.333333 0 0 1 85.333334 85.333333v426.666667a85.333333 85.333333 0 0 1-85.333334 85.333333H576v42.666667h74.666667a32 32 0 0 1 0 64h-277.333334a32 32 0 0 1 0-64H448v-42.666667H170.666667a85.333333 85.333333 0 0 1-85.333334-85.333333V256a85.333333 85.333333 0 0 1 85.333334-85.333333h682.666666z m-127.957333 213.333333c-37.056 0.277333-77.824 17.258667-77.824 58.666667 0 45.12 37.909333 56.042667 78.976 60.928 26.709333 2.88 46.506667 10.666667 46.506667 29.632 0 21.845333-22.4 30.186667-46.229334 30.186666-24.405333 0-47.658667-9.792-56.576-31.914666l-31.573333 16.384c14.933333 36.8 46.506667 49.450667 87.573333 49.450666 44.8 0 84.437333-19.264 84.437334-64.106666 0-46.506667-36.650667-58.24-77.056-63.616l-3.925334-0.512c-24.106667-2.88-44.8-7.765333-44.8-25.301334 0-14.933333 13.504-26.730667 41.642667-26.730666 21.824 0 40.768 10.922667 47.658667 22.421333l30.165333-15.530667C789.12 392.917333 756.672 384 725.376 384z m-280 7.189333H401.706667v201.258667h37.909333v-146.346667l64.042667 87.68h7.466666l65.472-87.381333v146.048h37.909334v-201.258667h-43.370667l-62.890667 86.549334-62.890666-86.549334z m-194.133333-0.298666H213.333333v201.258666h37.909334V503.04l84.138666 89.109333h46.805334v-2.282666l-96.768-101.504 89.301333-96.32v-1.152h-47.082667l-76.394666 85.12v-85.12z" /></svg>
|
||||
|
Before Width: | Height: | Size: 1.6 KiB |
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M385.6 371.242667c12.16 113.578667 92.906667 206.634667 200 236.949333l1.664 0.448-2.453333 2.005333-317.888 237.418667c-12.16 9.066667-28.8 8.533333-40.32-0.917333l-2.410667-2.154667-28.928-28.885333c0.213333 1.898667 0.490667 3.797333 0.810667 5.717333 6.186667 35.754667 31.338667 57.962667 79.808 49.322667 26.986667-4.821333 44.117333-11.242667 63.509333-22.464l6.336-3.776 11.541333-7.168 5.397334-3.285334c35.562667-21.248 64.96-29.909333 117.973333-30.442666 69.909333-0.704 129.088 21.056 175.701333 65.173333a32.853333 32.853333 0 0 1 1.28 46.4 32.746667 32.746667 0 0 1-46.293333 1.28c-33.898667-32.042667-76.608-47.744-130.026667-47.210667-40.597333 0.426667-59.029333 5.632-84.864 21.056l-17.642666 10.88c-28.266667 17.216-53.461333 27.413333-91.413334 34.176-87.808 15.658667-144-33.92-155.882666-102.741333a151.765333 151.765333 0 0 1 4.522666-72.042667l1.066667-2.965333-20.778667-20.736a32.853333 32.853333 0 0 1-3.968-41.706667l2.048-2.688 268.437334-318.72c0.874667-1.045333 1.813333-2.005333 2.773333-2.922666z m4.181333 169.344l-2.474666 2.24-46.357334 46.421333-2.24 2.496a32.853333 32.853333 0 0 0 2.24 43.925333 32.746667 32.746667 0 0 0 43.861334 2.24l2.496-2.24 46.336-46.421333 2.261333-2.496a32.853333 32.853333 0 0 0-2.261333-43.925333 32.746667 32.746667 0 0 0-43.861334-2.24zM661.333333 85.333333c141.376 0 256 114.624 256 256s-114.624 256-256 256-256-114.624-256-256S519.957333 85.333333 661.333333 85.333333z" /></svg>
|
||||
|
Before Width: | Height: | Size: 1.7 KiB |
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M579.2 874.666667a21.333333 21.333333 0 0 1 14.421333 37.056C574.037333 929.685333 546.837333 938.666667 512 938.666667s-62.037333-8.981333-81.621333-26.944A21.333333 21.333333 0 0 1 444.821333 874.666667h134.357334z m28.8-85.333334a32 32 0 0 1 0 64h-192a32 32 0 0 1 0-64h192zM512 85.333333c176.725333 0 320 143.274667 320 320 0 114.090667-59.733333 214.250667-149.610667 270.912A85.333333 85.333333 0 0 1 597.333333 768h-170.666666a85.333333 85.333333 0 0 1-85.098667-91.776C251.733333 619.584 192 519.424 192 405.333333c0-176.725333 143.274667-320 320-320z m29.098667 106.666667a29.098667 29.098667 0 1 0 0 58.176 126.08 126.08 0 0 1 126.058666 126.08 29.098667 29.098667 0 1 0 58.176 0A184.234667 184.234667 0 0 0 541.098667 192z" /></svg>
|
||||
|
Before Width: | Height: | Size: 1008 B |
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M486.570667 97.216a33.130667 33.130667 0 0 1 51.264 0.512c34.709333 43.328 152.064 98.261333 307.776 117.034667 16.576 2.005333 29.056 16 29.056 32.64v372.629333a167.04 167.04 0 0 1-20.096 79.402667C761.813333 871.146667 633.770667 938.666667 511.530667 938.666667l-6.528-0.106667c-118.954667-3.413333-244.586667-70.741333-335.573334-239.125333a167.808 167.808 0 0 1-19.925333-71.914667L149.333333 620.032V247.402667c0-16.64 12.48-30.634667 29.056-32.64 152.426667-18.368 269.077333-72.277333 305.237334-114.005334z m25.408 67.178667l-1.792 1.450666c-52.693333 41.813333-163.456 91.882667-290.389334 109.802667l-4.416 0.597333v342.976l0.149334 5.866667c0.746667 15.104 4.864 29.866667 12.074666 43.221333 80.96 149.845333 188.714667 201.962667 278.826667 204.544l5.568 0.085334c92.522667 0 201.92-51.989333 284.373333-204.629334a101.546667 101.546667 0 0 0 12.224-48.277333V276.245333l-16.277333-2.325333c-120.938667-18.048-227.904-67.690667-278.954667-108.416l-1.386666-1.109333z m161.194666 250.517333a32.853333 32.853333 0 0 1 0 46.186667l-187.306666 190.656a32.256 32.256 0 0 1-45.845334 0l-89.173333-91.157334a32.853333 32.853333 0 0 1 0-46.208 32.256 32.256 0 0 1 45.845333 0l51.029334 52.416a21.333333 21.333333 0 0 0 30.165333 0.426667l0.341333-0.362667 149.077334-151.957333a32.256 32.256 0 0 1 45.866666 0z" /></svg>
|
||||
|
Before Width: | Height: | Size: 1.6 KiB |
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M486.570667 97.216a33.130667 33.130667 0 0 1 51.264 0.512c34.709333 43.328 152.064 98.261333 307.776 117.034667 16.576 2.005333 29.056 16 29.056 32.64v372.629333a167.04 167.04 0 0 1-20.096 79.402667C761.813333 871.146667 633.770667 938.666667 511.530667 938.666667l-6.528-0.106667c-118.954667-3.413333-244.586667-70.741333-335.573334-239.125333a167.808 167.808 0 0 1-19.925333-71.914667L149.333333 620.032V247.402667c0-16.64 12.48-30.634667 29.056-32.64 152.426667-18.368 269.077333-72.277333 305.237334-114.005334z m186.602666 317.696a32.256 32.256 0 0 0-45.866666 0l-149.077334 151.957333-0.341333 0.341334a21.333333 21.333333 0 0 1-30.165333-0.405334l-51.029334-52.416a32.256 32.256 0 0 0-45.866666 0 32.853333 32.853333 0 0 0 0 46.208l89.194666 91.157334a32.256 32.256 0 0 0 45.866667 0l187.285333-190.656a32.853333 32.853333 0 0 0 0-46.186667z" /></svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M486.570667 97.216a33.130667 33.130667 0 0 1 51.264 0.512c34.709333 43.328 152.064 98.261333 307.776 117.034667 16.576 2.005333 29.056 16 29.056 32.64v372.629333a167.04 167.04 0 0 1-20.096 79.402667C761.813333 871.146667 633.770667 938.666667 511.530667 938.666667l-6.528-0.106667c-118.954667-3.413333-244.586667-70.741333-335.573334-239.125333a167.808 167.808 0 0 1-19.925333-71.914667L149.333333 620.032V247.402667c0-16.64 12.48-30.634667 29.056-32.64 152.426667-18.368 269.077333-72.277333 305.237334-114.005334z m186.602666 317.696a32.256 32.256 0 0 0-45.866666 0l-149.077334 151.957333-0.341333 0.341334a21.333333 21.333333 0 0 1-30.165333-0.405334l-51.029334-52.416a32.256 32.256 0 0 0-45.866666 0 32.853333 32.853333 0 0 0 0 46.208l89.194666 91.157334a32.256 32.256 0 0 0 45.866667 0l187.285333-190.656a32.853333 32.853333 0 0 0 0-46.186667z" /></svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 107.136v707.093333l-221.248 99.434667a32 32 0 0 1-44.586667-34.986667l41.834667-227.413333-182.826667-195.84a32 32 0 0 1 18.474667-53.461333l228.586667-35.733334 141.226666-248.298666A21.333333 21.333333 0 0 1 512 107.136z" /></svg>
|
||||
|
Before Width: | Height: | Size: 503 B |
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M486.570667 97.216a33.130667 33.130667 0 0 1 51.264 0.512c34.709333 43.328 152.064 98.261333 307.776 117.034667 16.576 2.005333 29.056 16 29.056 32.64v372.629333a167.04 167.04 0 0 1-20.096 79.402667C761.813333 871.146667 633.770667 938.666667 511.530667 938.666667l-6.528-0.106667c-118.954667-3.413333-244.586667-70.741333-335.573334-239.125333a167.808 167.808 0 0 1-19.925333-71.914667L149.333333 620.032V247.402667c0-16.64 12.48-30.634667 29.056-32.64 152.426667-18.368 269.077333-72.277333 305.237334-114.005334z m-10.026667 256.213333h-122.090667v346.026667h38.442667V389.845333h45.205333c-9.045333 30.997333-21.845333 65.493333-38.058666 104.234667 24.490667 32.170667 36.906667 61.226667 36.906666 87.189333 0 6.186667-1.493333 10.453333-4.117333 12.8-3.029333 2.304-9.045333 3.861333-17.706667 4.629334-5.290667 0-12.053333-0.768-20.352-2.325334l12.437334 40.32c26.752-0.405333 45.589333-5.44 56.874666-15.509333 7.552-8.149333 11.306667-21.333333 11.306667-39.914667-2.261333-26.346667-14.293333-57.344-36.906667-93.397333a1520.768 1520.768 0 0 0 38.037334-104.234667v-30.208z m155.946667 148.8c-11.306667 58.112-24.106667 107.306667-39.168 147.626667h-132.608v38.741333h226.773333v-38.741333h-55.744c15.445333-40.32 28.629333-85.632 39.189333-136.789333l-38.442666-10.837334z m-121.685334 11.221334l-33.514666 11.626666c12.8 34.88 23.722667 71.68 32 110.058667l33.92-8.533333c-9.813333-42.624-20.352-80.213333-32.405334-113.152z m59.904-13.952l-33.514666 11.626666c11.306667 33.706667 20.330667 68.970667 27.861333 106.176l33.536-8.917333c-8.277333-41.066667-17.322667-77.098667-27.882667-108.885333z m21.12-158.869334h-34.688c-23.338667 51.541333-57.258667 93.397333-101.333333 125.930667l19.968 31.786667c13.568-9.685333 26.752-20.928 39.189333-33.322667v20.522667h120.533334v-19.370667a338.133333 338.133333 0 0 0 38.826666 32.554667l21.461334-33.706667c-49.344-35.648-84.010667-77.12-103.978667-124.373333z m-17.344 39.530667a279.530667 279.530667 0 0 0 44.821334 68.970667h-90.026667a370.410667 370.410667 0 0 0 45.205333-68.970667z" /></svg>
|
||||
|
Before Width: | Height: | Size: 2.3 KiB |
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M789.333333 486.250667V746.666667c0 58.901333-124.16 106.666667-277.333333 106.666666-150.570667 0-273.109333-46.144-277.226667-103.68L234.666667 746.666667V486.250667l260.053333 115.285333a42.666667 42.666667 0 0 0 30.848 1.450667l3.733333-1.450667L789.333333 486.250667zM529.28 166.464l398.592 176.704a21.333333 21.333333 0 0 1 0 38.997333L874.666667 405.76 874.666667 603.093333A42.666667 42.666667 0 1 1 832 603.029333v-178.410666l-302.72 134.229333a42.666667 42.666667 0 0 1-34.56 0L96.106667 382.165333a21.333333 21.333333 0 0 1 0-38.997333l398.570666-176.704a42.666667 42.666667 0 0 1 34.602667 0z" /></svg>
|
||||
|
Before Width: | Height: | Size: 880 B |
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M864 832a32 32 0 0 1 0 64h-704a32 32 0 0 1 0-64h704zM710.613333 152.533333l3.541334 3.413334 89.92 89.898666a95.36 95.36 0 0 1 3.370666 131.285334l-3.370666 3.562666-332.309334 332.309334c-9.386667 9.386667-21.077333 16.042667-33.856 19.349333l-4.842666 1.088-178.261334 33.642667a52.970667 52.970667 0 0 1-62.464-57.984l0.576-3.904L226.56 526.933333c2.453333-13.013333 8.362667-25.130667 17.045333-35.072l3.392-3.626666L579.306667 155.946667a95.36 95.36 0 0 1 131.285333-3.370667z m-83.946666 46.165334l-2.410667 2.176-332.309333 332.309333a10.602667 10.602667 0 0 0-2.517334 3.989333l-0.405333 1.536-30.741333 162.986667 119.978666-22.634667-51.968-51.968a31.786667 31.786667 0 1 1 44.949334-44.949333l70.72 70.72 317.141333-317.12a31.786667 31.786667 0 0 0 2.197333-42.538667l-2.197333-2.410666-89.898667-89.92a31.786667 31.786667 0 0 0-42.538666-2.176z" /></svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m0 64C311.701333 149.333333 149.333333 311.701333 149.333333 512s162.368 362.666667 362.666667 362.666667 362.666667-162.368 362.666667-362.666667S712.298667 149.333333 512 149.333333z m-145.173333 471.338667A180.970667 180.970667 0 0 0 512 693.333333a180.650667 180.650667 0 0 0 128.746667-53.653333c5.888-5.930667 11.370667-12.266667 16.384-18.944a32 32 0 0 1 51.2 38.421333c-6.784 9.024-14.186667 17.578667-22.122667 25.6A244.629333 244.629333 0 0 1 512 757.333333c-78.208 0-150.357333-36.906667-196.373333-98.261333a32 32 0 1 1 51.2-38.4zM341.333333 384a42.666667 42.666667 0 1 1 0 85.333333 42.666667 42.666667 0 0 1 0-85.333333z m341.333334 0a42.666667 42.666667 0 1 1 0 85.333333 42.666667 42.666667 0 0 1 0-85.333333z" /></svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB |
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512.042667 213.333333c82.752 0 161.088 24.106667 234.88 71.786667l53.525333-53.482667a32 32 0 1 1 45.248 45.248L287.573333 835.029333a32 32 0 1 1-45.248-45.248l44.693334-44.714666c-62.72-38.528-122.154667-93.909333-178.261334-165.802667a108.522667 108.522667 0 0 1-3.093333-130.56l3.136-4.202667 6.805333-8.64C233.045333 288.533333 365.546667 213.333333 512.042667 213.333333z m334.506666 153.216a842.88 842.88 0 0 1 68.693334 78.08 108.522667 108.522667 0 0 1 3.029333 130.688l-3.136 4.202667-6.826667 8.64C790.570667 735.466667 658.133333 810.666667 512.042667 810.666667a410.88 410.88 0 0 1-97.898667-11.733334l53.013333-52.970666a344.32 344.32 0 0 0 44.885334 2.901333c120.896 0 233.088-62.229333 337.408-189.482667l6.784-8.405333 6.613333-8.341333a49.344 49.344 0 0 0 0-61.226667 787.370667 787.370667 0 0 0-61.205333-69.973333l44.906666-44.885334z m-334.506666-91.413333c-121.28 0-233.493333 62.229333-337.557334 189.44l-6.784 8.405333-6.570666 8.341334a49.344 49.344 0 0 0 0.042666 61.205333c54.954667 70.442667 112.106667 122.581333 171.562667 156.8l92.864-92.885333a128 128 0 1 1 180.842667-180.842667l94.976-94.933333c-60.650667-37.184-123.733333-55.530667-189.376-55.530667zM512 443.072a68.906667 68.906667 0 0 0-44.522667 121.536l97.130667-97.130667A68.778667 68.778667 0 0 0 512 443.072z" /></svg>
|
||||
|
Before Width: | Height: | Size: 1.5 KiB |
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M384 554.666667a85.333333 85.333333 0 0 1 85.333333 85.333333v170.666667a85.333333 85.333333 0 0 1-85.333333 85.333333h-170.666667a85.333333 85.333333 0 0 1-85.333333-85.333333v-170.666667a85.333333 85.333333 0 0 1 85.333333-85.333333h170.666667z m245.333333 213.333333a32 32 0 0 1 32 32v42.666667a32 32 0 0 1-64 0v-42.666667a32 32 0 0 1 32-32z m192-21.333333a32 32 0 0 1 32 32v64a32 32 0 0 1-64 0v-64a32 32 0 0 1 32-32zM384 618.666667h-170.666667a21.333333 21.333333 0 0 0-21.184 18.837333L192 640v170.666667a21.333333 21.333333 0 0 0 18.837333 21.184L213.333333 832h170.666667a21.333333 21.333333 0 0 0 21.184-18.837333L405.333333 810.666667v-170.666667a21.333333 21.333333 0 0 0-18.837333-21.184L384 618.666667z m245.333333-42.666667a32 32 0 0 1 32 32v85.333333a32 32 0 0 1-64 0v-85.333333a32 32 0 0 1 32-32z m192 0a32 32 0 0 1 32 32v64a32 32 0 0 1-64 0v-64a32 32 0 0 1 32-32zM384 128a85.333333 85.333333 0 0 1 85.333333 85.333333v170.666667a85.333333 85.333333 0 0 1-85.333333 85.333333h-170.666667a85.333333 85.333333 0 0 1-85.333333-85.333333v-170.666667a85.333333 85.333333 0 0 1 85.333333-85.333333h170.666667z m426.666667 0a85.333333 85.333333 0 0 1 85.333333 85.333333v170.666667a85.333333 85.333333 0 0 1-85.333333 85.333333h-170.666667a85.333333 85.333333 0 0 1-85.333333-85.333333v-170.666667a85.333333 85.333333 0 0 1 85.333333-85.333333h170.666667zM384 192h-170.666667a21.333333 21.333333 0 0 0-21.184 18.837333L192 213.333333v170.666667a21.333333 21.333333 0 0 0 18.837333 21.184L213.333333 405.333333h170.666667a21.333333 21.333333 0 0 0 21.184-18.837333L405.333333 384v-170.666667a21.333333 21.333333 0 0 0-18.837333-21.184L384 192z m426.666667 0h-170.666667a21.333333 21.333333 0 0 0-21.184 18.837333L618.666667 213.333333v170.666667a21.333333 21.333333 0 0 0 18.837333 21.184L640 405.333333h170.666667a21.333333 21.333333 0 0 0 21.184-18.837333L832 384v-170.666667a21.333333 21.333333 0 0 0-18.837333-21.184L810.666667 192z" /></svg>
|
||||
|
Before Width: | Height: | Size: 2.2 KiB |
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64z m265.9 713.9a377.2 377.2 0 0 1-119.6 80.6 377.5 377.5 0 0 1-292.6 0 377.1 377.1 0 0 1-200.2-200.2 377.5 377.5 0 0 1 0-292.6 377.1 377.1 0 0 1 200.2-200.2 377.5 377.5 0 0 1 292.6 0 377.1 377.1 0 0 1 200.2 200.2 377.5 377.5 0 0 1 0 292.6 377.2 377.2 0 0 1-80.6 119.6zM651.3 258.8a3.9 3.9 0 0 0-5.6 0L512 392.5 378.3 258.8a3.9 3.9 0 0 0-5.6 0l-39.6 39.6a3.9 3.9 0 0 0 0 5.6l102.3 102.4H376a4 4 0 0 0-4 4v56a4 4 0 0 0 4 4h104v80H376a4 4 0 0 0-4 4v56a4 4 0 0 0 4 4h104v148a4 4 0 0 0 4 4h56a4 4 0 0 0 4-4v-148h104a4 4 0 0 0 4-4v-56a4 4 0 0 0-4-4H544v-80h104a4 4 0 0 0 4-4v-56a4 4 0 0 0-4-4h-59.4L690.9 304a3.9 3.9 0 0 0 0-5.6z" /></svg>
|
||||
|
Before Width: | Height: | Size: 981 B |
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M511 64C263.6 64 63 264.6 63 512s200.6 448 448 448 448-200.6 448-448S758.4 64 511 64z m265.9 713.9a377.2 377.2 0 0 1-119.6 80.6 377.5 377.5 0 0 1-292.6 0 377.1 377.1 0 0 1-200.2-200.2 377.5 377.5 0 0 1 0-292.6 377.1 377.1 0 0 1 200.2-200.2 377.5 377.5 0 0 1 292.6 0 377.1 377.1 0 0 1 200.2 200.2 377.5 377.5 0 0 1 0 292.6 377.2 377.2 0 0 1-80.6 119.6zM513.8 288.6a3.9 3.9 0 0 0-5.6 0L287.6 509.2a3.9 3.9 0 0 0 0 5.6l220.6 220.6a3.9 3.9 0 0 0 5.6 0l220.6-220.6a3.9 3.9 0 0 0 0-5.6zM511 636.5L386.5 512 511 387.5 635.5 512z" /></svg>
|
||||
|
Before Width: | Height: | Size: 796 B |
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M285.8 406.9l137.3 83.7a7.7 7.7 0 0 0 11.8-6.6v-51.7h175a68.1 68.1 0 0 1 67.9 64.1 4.1 4.1 0 0 0 4 3.9h56.1a4.1 4.1 0 0 0 4-4.2c-2.2-70.8-60.6-127.8-132-127.8h-175v-51.8a7.7 7.7 0 0 0-11.8-6.6l-137.3 83.7a7.8 7.8 0 0 0 0 13.3z m452.4 210.2l-137.3-83.7a7.7 7.7 0 0 0-11.8 6.6v51.7h-175a68.1 68.1 0 0 1-67.9-64.1 4.1 4.1 0 0 0-4-3.9h-56.1a4.1 4.1 0 0 0-4 4.2c2.2 70.8 60.6 127.8 132 127.8h175v51.8a7.7 7.7 0 0 0 11.8 6.6l137.3-83.7a7.8 7.8 0 0 0 0-13.3zM856 128H168a40 40 0 0 0-40 40v688a40 40 0 0 0 40 40h688a40 40 0 0 0 40-40V168a40 40 0 0 0-40-40z m-32 696H200V200h624z" /></svg>
|
||||
|
Before Width: | Height: | Size: 845 B |
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 106.666667c103.68 0 192.96 61.632 233.194667 150.250666C853.717333 266.944 938.666667 358.186667 938.666667 469.333333c0 95.509333-62.762667 176.362667-149.333334 203.562667V832a85.333333 85.333333 0 0 1-85.333333 85.333333H320a85.333333 85.333333 0 0 1-85.333333-85.333333v-180.437333C148.117333 624.384 85.333333 543.530667 85.333333 448c0-114.986667 90.944-208.704 204.8-213.162667A255.893333 255.893333 0 0 1 512 106.666667z m-104.725333 583.893333a25.557333 25.557333 0 0 0-36.949334 0 27.605333 27.605333 0 0 0 0 38.186667c78.250667 80.789333 205.098667 80.789333 283.349334 0a27.605333 27.605333 0 0 0 0-38.186667 25.557333 25.557333 0 0 0-36.949334 0 144.810667 144.810667 0 0 1-209.450666 0z" /></svg>
|
||||
|
Before Width: | Height: | Size: 981 B |
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M880 184H712v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H384v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H144c-17.7 0-32 14.3-32 32v664c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V216c0-17.7-14.3-32-32-32z m-40 656H184V256h128v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h256v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h128v584zM688 420h-55.2c-5.1 0-10 2.5-13 6.6L468.9 634.4l-64.7-89c-3-4.1-7.8-6.6-13-6.6H336c-6.5 0-10.3 7.4-6.5 12.7l126.4 174c6.4 8.8 19.6 8.8 26 0l212.6-292.7c3.8-5.4 0-12.8-6.5-12.8z" /></svg>
|
||||
|
Before Width: | Height: | Size: 775 B |
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M332.202667 347.136c12.16 12.373333 12.16 32.426667 0 44.821333-12.16 12.373333-31.893333 12.373333-44.053334 0l-151.04-115.584a32.085333 32.085333 0 0 1 0-44.842666l151.04-115.584c12.16-12.373333 31.893333-12.373333 44.053334 0 12.16 12.373333 12.16 32.448 0 44.842666l-85.290667 61.589334H565.333333c182.613333 0 330.666667 146.026667 330.666667 326.144 0 177.92-144.426667 322.538667-323.925333 326.08L565.333333 874.666667h-213.333333a31.786667 31.786667 0 0 1-32-31.573334c0-16.384 12.693333-29.866667 28.928-31.402666l3.072-0.149334h213.333333c147.285333 0 266.666667-117.76 266.666667-263.018666 0-143.082667-115.84-259.477333-260.096-262.933334l-6.570667-0.064-318.442666-0.021333 85.333333 61.632z" /></svg>
|
||||
|
Before Width: | Height: | Size: 982 B |
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M853.333333 338.944V537.6c-32-16.362667-68.266667-25.6-106.666666-25.6-129.6 0-234.666667 105.066667-234.666667 234.666667 0 79.381333 39.424 149.546667 99.754667 192.021333L256 938.666667a85.333333 85.333333 0 0 1-85.333333-85.333334V338.965333a510.229333 510.229333 0 0 0 257.216 123.498667 85.312 85.312 0 0 0 168.192 0 510.165333 510.165333 0 0 0 257.28-123.52zM768 85.333333a85.333333 85.333333 0 0 1 85.333333 85.333334l0.021334 108.778666a468.437333 468.437333 0 0 1-260.842667 140.330667 85.354667 85.354667 0 0 0-161.088 0 468.373333 468.373333 0 0 1-260.778667-140.330667L170.666667 170.666667a85.333333 85.333333 0 0 1 85.333333-85.333334h512z m-21.354667 469.333334a191.957333 191.957333 0 0 1 168.597334 100.053333L746.666667 746.666667l135.765333 135.744A192 192 0 1 1 746.645333 554.666667z m32 106.666666a32 32 0 1 0 0-64 32 32 0 0 0 0 64z" /></svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M103.082667 632.704c1.493333 1.130667 3.093333 2.176 4.778666 3.136l2.56 1.344L490.666667 822.421333a49.066667 49.066667 0 0 0 38.976 1.621334l3.690666-1.621334 380.224-185.237333c2.624-1.28 5.077333-2.773333 7.36-4.458667 17.216 12.650667 22.954667 35.477333 12.544 54.4a45.162667 45.162667 0 0 1-19.904 18.752L533.333333 891.093333a49.024 49.024 0 0 1-42.666666 0L110.442667 705.877333c-22.784-11.093333-31.701333-37.482667-19.904-58.922666 3.072-5.546667 7.338667-10.410667 12.544-14.250667z m0-153.6c1.493333 1.130667 3.093333 2.176 4.778666 3.136l2.56 1.344L490.666667 668.821333a49.066667 49.066667 0 0 0 38.976 1.621334l3.690666-1.621334 380.224-185.237333c2.624-1.28 5.077333-2.773333 7.36-4.458667 17.216 12.650667 22.954667 35.477333 12.544 54.4a45.162667 45.162667 0 0 1-19.904 18.752L533.333333 737.493333a49.024 49.024 0 0 1-42.666666 0L110.442667 552.277333c-22.784-11.093333-31.701333-37.482667-19.904-58.922666 3.072-5.546667 7.338667-10.410667 12.544-14.250667zM533.333333 132.970667l380.224 187.968c22.784 11.264 31.701333 38.037333 19.904 59.776a45.44 45.44 0 0 1-19.904 19.008L533.333333 587.733333c-13.376 6.613333-29.290667 6.613333-42.666666 0L110.442667 399.722667c-22.784-11.264-31.701333-38.016-19.904-59.776a45.44 45.44 0 0 1 19.904-18.986667L490.666667 132.949333a48.362667 48.362667 0 0 1 42.666666 0z" /></svg>
|
||||
|
Before Width: | Height: | Size: 1.6 KiB |
|
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M11.28 9.53L8.81 12l2.47 2.47a.749.749 0 0 1-.326 1.275a.75.75 0 0 1-.734-.215l-3-3a.75.75 0 0 1 0-1.06l3-3a.749.749 0 0 1 1.275.326a.75.75 0 0 1-.215.734"/><path fill="currentColor" d="M3.75 2h16.5c.966 0 1.75.784 1.75 1.75v16.5A1.75 1.75 0 0 1 20.25 22H3.75A1.75 1.75 0 0 1 2 20.25V3.75C2 2.784 2.784 2 3.75 2M3.5 3.75v16.5c0 .138.112.25.25.25H15v-17H3.75a.25.25 0 0 0-.25.25m13 16.75h3.75a.25.25 0 0 0 .25-.25V3.75a.25.25 0 0 0-.25-.25H16.5Z"/></svg>
|
||||
|
Before Width: | Height: | Size: 565 B |
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M857.770667 163.882667c75.157333 75.136 72.448 209.237333 6.122666 346.944-17.792 36.309333-41.130667 72.725333-69.248 107.904a64 64 0 1 0 48.533334 41.792 697.173333 697.173333 0 0 0 51.328-72.682667c33.962667 109.098667 24.277333 208.938667-36.736 269.930667-67.84 67.84-183.701333 72.234667-306.922667 23.658666l-1.642667-0.938666-2.816-1.237334a475.690667 475.690667 0 0 1-34.410666-14.784v-0.021333c-40.170667-19.093333-80.64-44.842667-119.530667-76.288a32 32 0 0 0-40.234667 49.792c26.368 21.312 53.504 40.32 80.96 56.746667-108.842667 33.728-208.426667 23.957333-269.290666-36.906667-73.749333-73.749333-72.533333-204.309333-9.749334-339.328l3.434667-7.253333c19.882667-34.432 45.141333-68.693333 74.986667-101.482667a64 64 0 1 0-43.733334-46.997333 688.085333 688.085333 0 0 0-60.394666 75.093333c-35.477333-110.656-26.304-212.202667 35.456-273.941333 75.136-75.157333 209.237333-72.448 346.944-6.122667 137.706667-66.325333 271.808-69.034667 346.944 6.122667z m-347.306667 261.248a85.333333 85.333333 0 1 0 0 170.666666 85.333333 85.333333 0 0 0 0-170.666666z" /></svg>
|
||||
|
Before Width: | Height: | Size: 1.3 KiB |
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M683.918222 910.222222h-341.333333a227.555556 227.555556 0 0 1-227.555556-227.555555V341.333333a227.555556 227.555556 0 0 1 227.555556-227.555555h341.333333a227.555556 227.555556 0 0 1 227.555556 227.555555v341.333334a227.555556 227.555556 0 0 1-227.555556 227.555555z m-341.333333-728.177778a159.288889 159.288889 0 0 0-159.288889 159.288889v341.333334a159.288889 159.288889 0 0 0 159.288889 159.288889h341.333333a159.288889 159.288889 0 0 0 159.288889-159.288889V341.333333a159.288889 159.288889 0 0 0-159.288889-159.288889z" /><path d="M513.251556 711.111111a199.111111 199.111111 0 1 1 199.111111-199.111111 199.395556 199.395556 0 0 1-199.111111 199.111111z m0-329.955555a130.844444 130.844444 0 1 0 130.844444 130.844444 130.844444 130.844444 0 0 0-130.844444-130.901333z" /></svg>
|
||||
|
Before Width: | Height: | Size: 1.0 KiB |
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m0 64C311.701333 149.333333 149.333333 311.701333 149.333333 512s162.368 362.666667 362.666667 362.666667 362.666667-162.368 362.666667-362.666667S712.298667 149.333333 512 149.333333z" /></svg>
|
||||
|
Before Width: | Height: | Size: 639 B |
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m0 64C311.701333 149.333333 149.333333 311.701333 149.333333 512s162.368 362.666667 362.666667 362.666667 362.666667-162.368 362.666667-362.666667S712.298667 149.333333 512 149.333333z m0 149.333334c117.824 0 213.333333 95.509333 213.333333 213.333333s-95.509333 213.333333-213.333333 213.333333-213.333333-95.509333-213.333333-213.333333 95.509333-213.333333 213.333333-213.333333z" /></svg>
|
||||
|
Before Width: | Height: | Size: 837 B |
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M714.666667 106.666667a74.666667 74.666667 0 0 1 74.56 70.570666L789.333333 181.333333V213.333333h10.666667a117.333333 117.333333 0 0 1 117.248 112.618667L917.333333 330.666667v320a117.333333 117.333333 0 0 1-112.618666 117.248L800 768H789.333333v10.666667a117.333333 117.333333 0 0 1-117.333333 117.333333h-320a117.333333 117.333333 0 0 1-117.333333-117.333333V768h-10.666667a117.333333 117.333333 0 0 1-117.248-112.618667L106.666667 650.666667v-320a117.333333 117.333333 0 0 1 112.618666-117.248L224 213.333333h10.666667V181.333333a74.666667 74.666667 0 0 1 70.570666-74.56L309.333333 106.666667h405.333334z m-42.666667 490.666666h-320a53.333333 53.333333 0 0 0-53.333333 53.333334v128a53.333333 53.333333 0 0 0 53.333333 53.333333h320a53.333333 53.333333 0 0 0 53.333333-53.333333v-128a53.333333 53.333333 0 0 0-53.333333-53.333334z m128-320h-576a53.333333 53.333333 0 0 0-53.226667 49.834667L170.666667 330.666667v320a53.333333 53.333333 0 0 0 49.834666 53.226666L224 704h10.666667v-53.333333a117.333333 117.333333 0 0 1 117.333333-117.333334h320a117.333333 117.333333 0 0 1 117.333333 117.333334V704h10.666667a53.333333 53.333333 0 0 0 53.226667-49.834667L853.333333 650.666667v-320a53.333333 53.333333 0 0 0-49.834666-53.226667L800 277.333333z m-42.666667 64a32 32 0 0 1 0 64h-42.666666a32 32 0 0 1 0-64h42.666666z m-42.666666-170.666666h-405.333334a10.666667 10.666667 0 0 0-10.496 8.746666L298.666667 181.333333V213.333333h426.666666V181.333333a10.666667 10.666667 0 0 0-8.746666-10.496L714.666667 170.666667z" /></svg>
|
||||
|
Before Width: | Height: | Size: 1.8 KiB |