|
@@ -0,0 +1,351 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose title="分班情况" width="80%" @ok="handleSubmit">
|
|
|
|
|
+ <BasicTable @register="registerTable">
|
|
|
|
|
+ <template #tableTitle>
|
|
|
|
|
+ <a-button type="primary" @click="createClass">创建分班</a-button>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <template #action="{ record }">
|
|
|
|
|
+ <TableAction :actions="getTableAction(record)" />
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </BasicTable>
|
|
|
|
|
+ <a-modal :open="previewVisible" @cancel="previewVisible = false" width="65%" @ok="submitStudentInfo" :confirmLoading="submitConfirmLoading">
|
|
|
|
|
+ <div class="h-10"></div>
|
|
|
|
|
+ <div class="flex">
|
|
|
|
|
+ <a-form :label-col="{ span: 8 }" :wrapper-col="{ span: 16, style: { maxWidth: '500px' } }">
|
|
|
|
|
+ <a-form-item label="班级名称" :rules="[{ required: true, message: '请输入班级名称' }]">
|
|
|
|
|
+ <a-input v-model:value="formData.className" placeholder="请输入班级名称" :disabled="isDetail" />
|
|
|
|
|
+ </a-form-item>
|
|
|
|
|
+ <a-form-item label="教练" :rules="[{ required: true, message: '请选择教练' }]">
|
|
|
|
|
+ <a-select v-model:value="formData.coachUserId" placeholder="请选择教练" :disabled="isDetail">
|
|
|
|
|
+ <a-select-option v-for="coach in coachList" :key="coach.coachUserId" :value="coach.coachUserId">
|
|
|
|
|
+ {{ coach.name }}
|
|
|
|
|
+ </a-select-option>
|
|
|
|
|
+ </a-select>
|
|
|
|
|
+ </a-form-item>
|
|
|
|
|
+ </a-form>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <BasicTable @register="registerTableSelect" :rowSelection="rowSelection" :pagination="false">
|
|
|
|
|
+ <template #tableTitle>
|
|
|
|
|
+ <div>待分班学员</div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </BasicTable>
|
|
|
|
|
+ </a-modal>
|
|
|
|
|
+ </BasicModal>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script lang="ts" setup>
|
|
|
|
|
+ import { ref, computed, unref, watch, nextTick } from 'vue';
|
|
|
|
|
+ import { BasicModal, useModalInner } from '/src/components/Modal';
|
|
|
|
|
+ import { BasicForm, useForm } from '/src/components/Form';
|
|
|
|
|
+ import { caseList, saveOrUpdate, studentInfoList, queryCoach, addClass, editClass, deleteOne } from '../NmClassGrouping.api';
|
|
|
|
|
+ import { useMessage } from '/src/hooks/web/useMessage';
|
|
|
|
|
+ import { BasicTable, TableAction } from '@/components/Table';
|
|
|
|
|
+ import { useListPage } from '@/hooks/system/useListPage';
|
|
|
|
|
+ import { columns1, columns2, searchFormSchemaModal, formSchema } from '../NmClassGrouping.data';
|
|
|
|
|
+ import { putProfitSharing } from '@/views/orderManagement/order/order.api';
|
|
|
|
|
+
|
|
|
|
|
+ const { createMessage, createWarningModal } = useMessage();
|
|
|
|
|
+ // Emits声明
|
|
|
|
|
+ const emit = defineEmits(['register', 'success']);
|
|
|
|
|
+ const isUpdate = ref(false);
|
|
|
|
|
+ const isDetail = ref(false);
|
|
|
|
|
+ const previewVisible = ref(false);
|
|
|
|
|
+ //注册table数据
|
|
|
|
|
+ const { prefixCls, tableContext } = useListPage({
|
|
|
|
|
+ tableProps: {
|
|
|
|
|
+ title: '',
|
|
|
|
|
+ api: caseList,
|
|
|
|
|
+ columns: columns1,
|
|
|
|
|
+ formConfig: {
|
|
|
|
|
+ //labelWidth: 120,
|
|
|
|
|
+ schemas: searchFormSchemaModal,
|
|
|
|
|
+ autoSubmitOnEnter: true,
|
|
|
|
|
+ showAdvancedButton: true,
|
|
|
|
|
+ fieldMapToNumber: [],
|
|
|
|
|
+ fieldMapToTime: [],
|
|
|
|
|
+ autoAdvancedCol: 4,
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ actionColumn: {
|
|
|
|
|
+ width: 180,
|
|
|
|
|
+ fixed: 'right',
|
|
|
|
|
+ },
|
|
|
|
|
+ beforeFetch: (params) => {
|
|
|
|
|
+ return Object.assign(params, { courseId: currentId.value || '' });
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ });
|
|
|
|
|
+ const currentId = ref(null);
|
|
|
|
|
+ const classGroupingId = ref('');
|
|
|
|
|
+ const { tableContext: tableContext1 } = useListPage({
|
|
|
|
|
+ tableProps: {
|
|
|
|
|
+ title: '',
|
|
|
|
|
+ api: studentInfoList,
|
|
|
|
|
+ columns: columns2,
|
|
|
|
|
+ beforeFetch: (params) => {
|
|
|
|
|
+ if (currentId.value) {
|
|
|
|
|
+ return Object.assign(params, {
|
|
|
|
|
+ coursesId: currentId.value,
|
|
|
|
|
+ classGroupingId: classGroupingId.value || '',
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ return params;
|
|
|
|
|
+ },
|
|
|
|
|
+ afterFetch: (dataSource) => {
|
|
|
|
|
+ const defaultSelectedKeys = dataSource.filter((item) => item.orChoose).map((item) => item.id);
|
|
|
|
|
+
|
|
|
|
|
+ if (defaultSelectedKeys.length > 0) {
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ setSelectedRowKeys(defaultSelectedKeys);
|
|
|
|
|
+ }, 0);
|
|
|
|
|
+ }
|
|
|
|
|
+ return dataSource;
|
|
|
|
|
+ },
|
|
|
|
|
+ rowSelection: {
|
|
|
|
|
+ // 开启多选
|
|
|
|
|
+ type: 'checkbox',
|
|
|
|
|
+ getCheckboxProps: (record) => ({
|
|
|
|
|
+ disabled: isDetail.value,
|
|
|
|
|
+ }),
|
|
|
|
|
+ onChange: (selectedRowKeys, selectedRows) => {
|
|
|
|
|
+ formData.value.familyMemberIds = selectedRowKeys;
|
|
|
|
|
+ console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ formConfig: {
|
|
|
|
|
+ //labelWidth: 120,
|
|
|
|
|
+ autoSubmitOnEnter: false,
|
|
|
|
|
+ showAdvancedButton: false,
|
|
|
|
|
+ fieldMapToNumber: [],
|
|
|
|
|
+ fieldMapToTime: [],
|
|
|
|
|
+ autoAdvancedCol: 4,
|
|
|
|
|
+ },
|
|
|
|
|
+ actionColumn: null,
|
|
|
|
|
+ },
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ function createClass() {
|
|
|
|
|
+ // 重置表单数据
|
|
|
|
|
+ formData.value = {
|
|
|
|
|
+ id: '',
|
|
|
|
|
+ className: '',
|
|
|
|
|
+ courseId: '',
|
|
|
|
|
+ coachUserId: null,
|
|
|
|
|
+ familyMemberIds: null,
|
|
|
|
|
+ };
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ resetFields();
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ console.warn('表单重置失败:', e);
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ setSelectedRowKeys([]);
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ console.warn('表格选中项重置失败:', e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }, 0);
|
|
|
|
|
+ classGroupingId.value = '';
|
|
|
|
|
+ isUpdate.value = false;
|
|
|
|
|
+ isDetail.value = false;
|
|
|
|
|
+ reloadEdit();
|
|
|
|
|
+ previewVisible.value = true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ watch(currentId, async (newId) => {
|
|
|
|
|
+ if (newId) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const coachRes = await queryCoach({ coursesId: newId });
|
|
|
|
|
+ coachList.value = coachRes;
|
|
|
|
|
+ await reloadEdit();
|
|
|
|
|
+ setTimeout(async () => {
|
|
|
|
|
+ const tableData = await studentInfoList({
|
|
|
|
|
+ coursesId: newId,
|
|
|
|
|
+ classGroupingId: classGroupingId.value || '',
|
|
|
|
|
+ });
|
|
|
|
|
+ const defaultSelectedKeys = tableData.filter((item) => item.orChoose).map((item) => item.id);
|
|
|
|
|
+ if (defaultSelectedKeys.length > 0) {
|
|
|
|
|
+ setSelectedRowKeys(defaultSelectedKeys);
|
|
|
|
|
+ }
|
|
|
|
|
+ }, 100);
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('获取数据失败:', error);
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ coachList.value = [];
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ const [registerTable, { reload: reloadlist }] = tableContext;
|
|
|
|
|
+ const [registerTableSelect, { reload: reloadEdit, setSelectedRowKeys }, { rowSelection }] = tableContext1;
|
|
|
|
|
+ const coachList = ref([]);
|
|
|
|
|
+
|
|
|
|
|
+ function handleDelete(record) {
|
|
|
|
|
+ createWarningModal({
|
|
|
|
|
+ title: '提示',
|
|
|
|
|
+ content: '删除后分班信息将不存在,已分班学员需重新进行分配!!!!',
|
|
|
|
|
+ okText: '确认',
|
|
|
|
|
+ cancelText: '取消',
|
|
|
|
|
+ okCancel: true,
|
|
|
|
|
+ onOk: () => {
|
|
|
|
|
+ deleteOne({ classGroupingId: record.id }, () => {
|
|
|
|
|
+ reloadlist();
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+ onCancel: () => {
|
|
|
|
|
+ reloadlist();
|
|
|
|
|
+ },
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 操作栏
|
|
|
|
|
+ */
|
|
|
|
|
+ function getTableAction(record) {
|
|
|
|
|
+ return [
|
|
|
|
|
+ {
|
|
|
|
|
+ label: '修改分班',
|
|
|
|
|
+ onClick: () => {
|
|
|
|
|
+ classGroupingId.value = record.id;
|
|
|
|
|
+ formData.value.className = record.classGroupingName;
|
|
|
|
|
+ if (record.coachName && coachList.value.length > 0) {
|
|
|
|
|
+ const coach = coachList.value.find((item) => item.name === record.coachName);
|
|
|
|
|
+ if (coach) {
|
|
|
|
|
+ formData.value.coachUserId = coach.coachUserId;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ isUpdate.value = true;
|
|
|
|
|
+ isDetail.value = false;
|
|
|
|
|
+ reloadEdit();
|
|
|
|
|
+ previewVisible.value = true;
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: '查看',
|
|
|
|
|
+ onClick: () => {
|
|
|
|
|
+ classGroupingId.value = record.id;
|
|
|
|
|
+ formData.value.className = record.classGroupingName;
|
|
|
|
|
+ if (record.coachName && coachList.value.length > 0) {
|
|
|
|
|
+ const coach = coachList.value.find((item) => item.name === record.coachName);
|
|
|
|
|
+ if (coach) {
|
|
|
|
|
+ formData.value.coachUserId = coach.coachUserId;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ isDetail.value = true;
|
|
|
|
|
+ reloadEdit();
|
|
|
|
|
+ previewVisible.value = true;
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: '删除',
|
|
|
|
|
+ onClick: handleDelete.bind(null, record),
|
|
|
|
|
+ },
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //表单配置
|
|
|
|
|
+ const [registerForm, { setProps, resetFields, setFieldsValue, validate, scrollToField }] = useForm({
|
|
|
|
|
+ labelWidth: 150,
|
|
|
|
|
+ schemas: formSchema,
|
|
|
|
|
+ showActionButtonGroup: false,
|
|
|
|
|
+ baseColProps: { span: 24 },
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ const formData = ref({
|
|
|
|
|
+ id: '',
|
|
|
|
|
+ className: '',
|
|
|
|
|
+ courseId: '',
|
|
|
|
|
+ coachUserId: null,
|
|
|
|
|
+ familyMemberIds: null,
|
|
|
|
|
+ });
|
|
|
|
|
+ const submitConfirmLoading = ref(false);
|
|
|
|
|
+ const submitStudentInfo = async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ if (!formData.value.className) {
|
|
|
|
|
+ createMessage.warning('请输入班级名称');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!formData.value.coachUserId) {
|
|
|
|
|
+ createMessage.warning('请选择教练');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!formData.value.familyMemberIds || formData.value.familyMemberIds.length === 0) {
|
|
|
|
|
+ createMessage.warning('请选择待分班学员');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ submitConfirmLoading.value = true;
|
|
|
|
|
+ formData.value.courseId = currentId.value || '';
|
|
|
|
|
+ if (!isUpdate.value) {
|
|
|
|
|
+ await addClass(formData.value);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ formData.value.id = classGroupingId.value;
|
|
|
|
|
+ await editClass(formData.value);
|
|
|
|
|
+ }
|
|
|
|
|
+ previewVisible.value = false;
|
|
|
|
|
+ await reloadlist();
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('提交失败:', error);
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ submitConfirmLoading.value = false;
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+ //表单赋值
|
|
|
|
|
+ const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
|
|
|
|
+ //重置表单
|
|
|
|
|
+ await resetFields();
|
|
|
|
|
+ setModalProps({
|
|
|
|
|
+ confirmLoading: false,
|
|
|
|
|
+ showCancelBtn: !!data?.showFooter,
|
|
|
|
|
+ showOkBtn: !!data?.showFooter,
|
|
|
|
|
+ });
|
|
|
|
|
+ isUpdate.value = !!data?.isUpdate;
|
|
|
|
|
+ isDetail.value = !!data?.showFooter;
|
|
|
|
|
+ if (data?.record?.id) {
|
|
|
|
|
+ currentId.value = data.record.id;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (unref(isUpdate)) {
|
|
|
|
|
+ //表单赋值
|
|
|
|
|
+ await setFieldsValue({
|
|
|
|
|
+ ...data.record,
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ // 隐藏底部时禁用整个表单
|
|
|
|
|
+ setProps({ disabled: !data?.showFooter });
|
|
|
|
|
+ });
|
|
|
|
|
+ //设置标题
|
|
|
|
|
+ const title = computed(() => (!unref(isUpdate) ? '新增' : !unref(isDetail) ? '详情' : '编辑'));
|
|
|
|
|
+
|
|
|
|
|
+ //表单提交事件
|
|
|
|
|
+ async function handleSubmit(v) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ let values = await validate();
|
|
|
|
|
+ setModalProps({ confirmLoading: true });
|
|
|
|
|
+ //提交表单
|
|
|
|
|
+ await saveOrUpdate(values, isUpdate.value);
|
|
|
|
|
+ //关闭弹窗
|
|
|
|
|
+ closeModal();
|
|
|
|
|
+ //刷新列表
|
|
|
|
|
+ emit('success');
|
|
|
|
|
+ } catch ({ errorFields }) {
|
|
|
|
|
+ if (errorFields) {
|
|
|
|
|
+ const firstField = errorFields[0];
|
|
|
|
|
+ if (firstField) {
|
|
|
|
|
+ scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return Promise.reject(errorFields);
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ setModalProps({ confirmLoading: false });
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style lang="less" scoped>
|
|
|
|
|
+ /** 时间和数字输入框样式 */
|
|
|
|
|
+ :deep(.ant-input-number) {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ :deep(.ant-calendar-picker) {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ }
|
|
|
|
|
+</style>
|