|
@@ -0,0 +1,369 @@
|
|
|
+<script setup lang="ts">
|
|
|
+ import BasicModal from '/@/components/Modal/src/BasicModal.vue';
|
|
|
+ import { useModal, useModalInner } from '/@/components/Modal';
|
|
|
+ import { Steps } from 'ant-design-vue';
|
|
|
+ import { ref, unref } from 'vue';
|
|
|
+ import { useTable } from '/@/components/Table';
|
|
|
+ import BasicForm from '/@/components/Form/src/BasicForm.vue';
|
|
|
+ import { useForm } from '/@/components/Form';
|
|
|
+ import { textbookColumns } from './data.config';
|
|
|
+ import BasicTable from '/@/components/Table/src/BasicTable.vue';
|
|
|
+ import addTextbook from './addTextbook.vue';
|
|
|
+ import selectModalVue from './selectModal.vue';
|
|
|
+ import { getTextbookListSubscription } from '/@/services/apis/TextbookController';
|
|
|
+ import { useMessage } from '/@/hooks/web/useMessage';
|
|
|
+ import historyView from './historyView.vue';
|
|
|
+ import { requestMagicApi } from '/@/api/magicApi';
|
|
|
+ import {
|
|
|
+ getTextbookSubscriptionInfo,
|
|
|
+ postTextbookTextbookSubscription,
|
|
|
+ putTextbookTextbookSubscription,
|
|
|
+ } from '/@/services/apis/TextbookSubscriptionController';
|
|
|
+ const step = Steps.Step;
|
|
|
+ const selectRow = ref<any>([]);
|
|
|
+ const thisStep = ref(0);
|
|
|
+ const dataInfo = ref<any>({});
|
|
|
+ const selectUserList = ref<any>([]);
|
|
|
+ const isUpdate = ref(true);
|
|
|
+ const modelRef = ref({});
|
|
|
+
|
|
|
+ const [addReg, { openModal: addModelOpen }] = useModal();
|
|
|
+ const [historyViewReg, { openModal: historyViewOpen }] = useModal();
|
|
|
+ const emits = defineEmits(['success']);
|
|
|
+ const [formReg, { validate, resetFields, setFieldsValue }] = useForm({
|
|
|
+ labelWidth: 120,
|
|
|
+ schemas: [
|
|
|
+ {
|
|
|
+ label: '学期',
|
|
|
+ field: 'baseSemesterId',
|
|
|
+ component: 'ApiSelect',
|
|
|
+ colProps: { span: 24 },
|
|
|
+ componentProps: () => {
|
|
|
+ return {
|
|
|
+ api: requestMagicApi,
|
|
|
+ getPopupContainer: () => document.body,
|
|
|
+ params: {
|
|
|
+ url: '/baseData/semester/option',
|
|
|
+ },
|
|
|
+ showSearch: true,
|
|
|
+ filterOption: (input: string, option: any) => {
|
|
|
+ return (
|
|
|
+ option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
|
|
|
+ option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
|
|
+ );
|
|
|
+ },
|
|
|
+ onChange: () => {
|
|
|
+ handleChange();
|
|
|
+ },
|
|
|
+ };
|
|
|
+ },
|
|
|
+ required: true,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '征订方式',
|
|
|
+ field: 'subscriptionMethod',
|
|
|
+ component: 'Select',
|
|
|
+ required: true,
|
|
|
+ componentProps: () => {
|
|
|
+ return {
|
|
|
+ options: [
|
|
|
+ {
|
|
|
+ label: '按班级征订',
|
|
|
+ value: 1,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '按教材征订',
|
|
|
+ value: 2,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ onChange: () => {
|
|
|
+ handleChange();
|
|
|
+ },
|
|
|
+ };
|
|
|
+ },
|
|
|
+ colProps: { span: 24 },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '备注',
|
|
|
+ field: 'remark',
|
|
|
+ component: 'InputTextArea',
|
|
|
+ colProps: { span: 24 },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ showActionButtonGroup: false,
|
|
|
+ });
|
|
|
+
|
|
|
+ const handleChangeDiscount = (record) => {
|
|
|
+ if (record.discount < 1) {
|
|
|
+ record.discount = 1;
|
|
|
+ }
|
|
|
+ if (record.discount > 10) {
|
|
|
+ record.discount = 10;
|
|
|
+ }
|
|
|
+ record.price = Number((Number(record.sourcePrice || 0) * record.discount) / 10).toFixed(2);
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleChangePrice = (record) => {
|
|
|
+ if (record.price !== 0) {
|
|
|
+ record.discount = Number(((record.price / record.sourcePrice) * 10).toFixed(1));
|
|
|
+ } else {
|
|
|
+ record.discount = 0;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const [modalReg, { closeModal }] = useModalInner(async (data) => {
|
|
|
+ isUpdate.value = !!data?.isUpdate;
|
|
|
+ modelRef.value = { ...data.baseData };
|
|
|
+
|
|
|
+ if (unref(isUpdate)) {
|
|
|
+ const resData = await getTextbookSubscriptionInfo({ id: data.baseData.id });
|
|
|
+ modelRef.value = { ...resData };
|
|
|
+ setFieldsValue(resData);
|
|
|
+
|
|
|
+ resData.textbookSubscriptionItemList.forEach((item: any) => {
|
|
|
+ item.studentSubscriptionNumber = item.studentNum;
|
|
|
+ item.teacherSubscriptionNumber = item.teacherNum;
|
|
|
+ item.courseName = item.courseSubjectIdCn;
|
|
|
+ item.sourcePrice = item.pricing;
|
|
|
+ });
|
|
|
+
|
|
|
+ setTableData(resData.textbookSubscriptionItemList);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ const handleChange = () => {
|
|
|
+ setTableData([]);
|
|
|
+ selectUserList.value = [];
|
|
|
+ setSelectedRowKeys([]);
|
|
|
+ };
|
|
|
+ const handleNext = () => {
|
|
|
+ validate().then((res) => {
|
|
|
+ dataInfo.value = res;
|
|
|
+ thisStep.value++;
|
|
|
+ });
|
|
|
+ };
|
|
|
+ const handleClose = () => {
|
|
|
+ thisStep.value = 0;
|
|
|
+ resetFields();
|
|
|
+ closeModal();
|
|
|
+ };
|
|
|
+ const [selectModalReg, { openModal: selectModalOpen }] = useModal();
|
|
|
+ const [tableRef, { setTableData, getDataSource, redoHeight, setSelectedRowKeys }] = useTable({
|
|
|
+ title: '征订列表',
|
|
|
+ columns: textbookColumns,
|
|
|
+ bordered: true,
|
|
|
+ rowKey: 'id',
|
|
|
+ resizeHeightOffset: 200,
|
|
|
+ rowSelection: {
|
|
|
+ type: 'checkbox',
|
|
|
+ onChange: (selectedRowKeys) => {
|
|
|
+ selectRow.value = selectedRowKeys;
|
|
|
+ },
|
|
|
+ },
|
|
|
+ pagination: false,
|
|
|
+ });
|
|
|
+ const handleAdd = () => {
|
|
|
+ addModelOpen(true, {
|
|
|
+ baseSemesterId: dataInfo.value.baseSemesterId,
|
|
|
+ });
|
|
|
+ };
|
|
|
+ const handleSuccess = (e) => {
|
|
|
+ const data = getDataSource();
|
|
|
+ const addList: any[] = [];
|
|
|
+ e.forEach((item: any) => {
|
|
|
+ if (!data.find((i: any) => i.id === item.id)) {
|
|
|
+ item.sourcePrice = item.price;
|
|
|
+ item.textbookId = item.id;
|
|
|
+ handleChangeDiscount(item);
|
|
|
+ addList.push(item);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ setTableData(data.concat(addList));
|
|
|
+ redoHeight();
|
|
|
+ };
|
|
|
+ const handleClear = (id) => {
|
|
|
+ const data = getDataSource();
|
|
|
+ if (id) {
|
|
|
+ setTableData(data.filter((item: any) => item.id !== id));
|
|
|
+ } else {
|
|
|
+ setTableData(data.filter((item: any) => !selectRow.value.includes(item.id)));
|
|
|
+ }
|
|
|
+ };
|
|
|
+ const handleSelect = async (e) => {
|
|
|
+ selectUserList.value = e.classList;
|
|
|
+ const ids = selectUserList.value.map((item: any) => item.id);
|
|
|
+ const data = await getTextbookListSubscription({
|
|
|
+ classIds: ids.join(','),
|
|
|
+ baseSemesterId: dataInfo.value.baseSemesterId,
|
|
|
+ });
|
|
|
+
|
|
|
+ data.forEach((item: any) => {
|
|
|
+ item.sourcePrice = item.price;
|
|
|
+ handleChangeDiscount(item);
|
|
|
+ });
|
|
|
+ setTableData(data);
|
|
|
+ };
|
|
|
+ const { createMessage } = useMessage();
|
|
|
+ const handleSubmit = async () => {
|
|
|
+ const dataSoruce = getDataSource();
|
|
|
+
|
|
|
+ if (dataSoruce.length === 0) {
|
|
|
+ createMessage.warning('至少征订一本教材');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ dataSoruce.forEach((item: any) => {
|
|
|
+ item.studentNum = item.studentSubscriptionNumber;
|
|
|
+ item.teacherNum = item.teacherSubscriptionNumber;
|
|
|
+ });
|
|
|
+
|
|
|
+ const postParams = unref(modelRef);
|
|
|
+ Object.assign(postParams, {
|
|
|
+ remark: dataInfo.value?.remark,
|
|
|
+ subscriptionMethod: dataInfo.value.subscriptionMethod,
|
|
|
+ baseSemesterId: dataInfo.value.baseSemesterId,
|
|
|
+ textbookSubscriptionItemList: getDataSource(),
|
|
|
+ baseClassIds: dataSoruce[0].classIds,
|
|
|
+ });
|
|
|
+
|
|
|
+ // const params = {
|
|
|
+ // remark: dataInfo.value?.remark,
|
|
|
+ // subscriptionMethod: dataInfo.value.subscriptionMethod,
|
|
|
+ // baseSemesterId: dataInfo.value.baseSemesterId,
|
|
|
+ // textbookSubscriptionItemList: getDataSource(),
|
|
|
+ // baseClassIds: dataSoruce[0].classIds,
|
|
|
+ // };
|
|
|
+ try {
|
|
|
+ if (isUpdate.value) {
|
|
|
+ await putTextbookTextbookSubscription(postParams, 'none');
|
|
|
+ } else {
|
|
|
+ await postTextbookTextbookSubscription(postParams, 'none');
|
|
|
+ }
|
|
|
+ createMessage.success('新增成功');
|
|
|
+ emits('success');
|
|
|
+ thisStep.value = 0;
|
|
|
+ await resetFields();
|
|
|
+ setTableData([]);
|
|
|
+ selectUserList.value = [];
|
|
|
+ closeModal();
|
|
|
+ } catch {
|
|
|
+ createMessage.error('新增失败');
|
|
|
+ }
|
|
|
+ };
|
|
|
+ const handleViewHistory = (id) => {
|
|
|
+ historyViewOpen(true, { textbookId: id, baseSemesterId: dataInfo.value.baseSemesterId });
|
|
|
+ };
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <BasicModal
|
|
|
+ @cancel="handleClose"
|
|
|
+ :footer="null"
|
|
|
+ :canFullscreen="false"
|
|
|
+ defaultFullscreen
|
|
|
+ v-bind="$attrs"
|
|
|
+ @register="modalReg"
|
|
|
+ title="教材征订"
|
|
|
+ >
|
|
|
+ <div class="full flex flex-col">
|
|
|
+ <div class="w-2/3">
|
|
|
+ <Steps v-model:current="thisStep">
|
|
|
+ <step disabled title="基础信息" />
|
|
|
+ <step disabled title="教材征订" />
|
|
|
+ </Steps>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div v-show="thisStep === 0" class="mt-[24px] w-full">
|
|
|
+ <BasicForm @register="formReg" />
|
|
|
+ </div>
|
|
|
+ <div v-show="thisStep === 1" class="mt-[24px] w-full">
|
|
|
+ <div v-if="dataInfo && dataInfo.subscriptionMethod == 2">
|
|
|
+ <span class="required">征订教材</span>
|
|
|
+ <a-button type="primary" class="ml-[12px]" @click="handleAdd">选择教材</a-button>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ @click="selectModalOpen(true, { classList: selectUserList })"
|
|
|
+ class="flex flex-row items-center mt-[24px]"
|
|
|
+ v-if="dataInfo && dataInfo.subscriptionMethod == 1"
|
|
|
+ >
|
|
|
+ <span class="required">用书班级</span>
|
|
|
+ <div
|
|
|
+ class="flex ml-[12px] items-center"
|
|
|
+ style="
|
|
|
+ width: 94%;
|
|
|
+ justify-content: space-between;
|
|
|
+ height: 32px;
|
|
|
+ border: 1px solid #ccc;
|
|
|
+ border-radius: 2px;
|
|
|
+ cursor: pointer;
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <div class="flex flex-row">
|
|
|
+ <div
|
|
|
+ class="ml-[4px]"
|
|
|
+ v-for="(items, indexs) in selectUserList.slice(0, 3)"
|
|
|
+ :key="indexs"
|
|
|
+ >
|
|
|
+ {{ items.name }}
|
|
|
+ </div>
|
|
|
+ <div class="ml-[4px]" v-if="selectUserList.length > 3">
|
|
|
+ 剩余{{ selectUserList.length - 3 }}个班级
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <span class="mr-[12px]">添加+</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="flex">
|
|
|
+ <BasicTable @register="tableRef">
|
|
|
+ <template #toolbar>
|
|
|
+ <a-button type="primary" @click="handleClear(null)">批量移出</a-button>
|
|
|
+ </template>
|
|
|
+ <template #studentSubscriptionNumber="{ record }">
|
|
|
+ <a-input-number :step="1" :min="0" v-model:value="record.studentSubscriptionNumber" />
|
|
|
+ </template>
|
|
|
+ <template #teacherSubscriptionNumber="{ record }">
|
|
|
+ <a-input-number :step="1" :min="0" v-model:value="record.teacherSubscriptionNumber" />
|
|
|
+ </template>
|
|
|
+ <template #discount="{ record }">
|
|
|
+ <a-input-number
|
|
|
+ :step="1"
|
|
|
+ :min="0"
|
|
|
+ v-model:value="record.discount"
|
|
|
+ @change="handleChangeDiscount(record)"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ <template #price="{ record }">
|
|
|
+ <a-input-number
|
|
|
+ :step="1"
|
|
|
+ :min="0"
|
|
|
+ v-model:value="record.price"
|
|
|
+ @change="handleChangePrice(record)"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ <template #action="{ record }">
|
|
|
+ <a-button type="link" @click="handleClear(record.id)">移出</a-button>
|
|
|
+ <a-button type="link" @click="handleViewHistory(record.textbookId)">
|
|
|
+ 历史征订
|
|
|
+ </a-button>
|
|
|
+ </template>
|
|
|
+ </BasicTable>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="mt-[24px] ml-[120px]">
|
|
|
+ <a-button @click="handleClose">取消</a-button>
|
|
|
+ <a-button v-show="thisStep === 1" @click="thisStep = 0" class="ml-[24px]">上一步</a-button>
|
|
|
+ <a-button v-show="thisStep === 0" type="primary" @click="handleNext" class="ml-[24px]">
|
|
|
+ 下一步
|
|
|
+ </a-button>
|
|
|
+ <a-button v-show="thisStep === 1" type="primary" class="ml-[24px]" @click="handleSubmit">
|
|
|
+ 提交
|
|
|
+ </a-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <addTextbook @register="addReg" @success="handleSuccess" />
|
|
|
+ <selectModalVue @register="selectModalReg" @success="handleSelect" />
|
|
|
+ <historyView @register="historyViewReg" />
|
|
|
+ </BasicModal>
|
|
|
+</template>
|
|
|
+
|
|
|
+<style scoped lang="less"></style>
|