123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427 |
- <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, reactive } 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 SelectClass from '/@/views/educational/class/components/ClassModal.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';
- import { cloneDeep, uniqueId } from 'lodash-es';
- 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<Recordable>({});
- const state = reactive<{ isSearch: boolean; sourceData: any[] }>({
- isSearch: false,
- sourceData: [],
- });
- const [addReg, { openModal: addModelOpen }] = useModal();
- const [historyViewReg, { openModal: historyViewOpen }] = useModal();
- const emits = defineEmits(['success', 'register']);
- const [formReg, { validate, resetFields, setFieldsValue, setProps }] = 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 updateSourceData = (record) => {
- const index = state.sourceData.findIndex((item) => item.uuid === record.uuid);
- if (index > -1) {
- state.sourceData[index] = cloneDeep(record);
- }
- };
- 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);
- updateSourceData(record);
- };
- const handleChangePrice = (record) => {
- if (record.price !== 0) {
- record.discount = Number(((record.price / record.sourcePrice) * 10).toFixed(1));
- } else {
- record.discount = 0;
- }
- updateSourceData(record);
- };
- const [modalReg, { closeModal, setModalProps }] = useModalInner(async (data) => {
- isUpdate.value = !!data?.isUpdate;
- modelRef.value = { ...data.baseData };
- getForm().resetFields();
- setModalProps({ loading: true });
- if (unref(isUpdate)) {
- const resData = await getTextbookSubscriptionInfo({ id: data.baseData.id });
- modelRef.value = { ...resData };
- setFieldsValue(resData);
- dataInfo.value = { ...resData };
- resData.textbookSubscriptionItemList.forEach((item: any) => {
- item.studentSubscriptionNumber = item.studentNum;
- item.teacherSubscriptionNumber = item.teacherNum;
- item.courseName = item.courseSubjectIdCn;
- item.sourcePrice = item.pricing;
- item.uuid = uniqueId();
- });
- state.sourceData = resData.textbookSubscriptionItemList;
- setTableData(resData.textbookSubscriptionItemList);
- thisStep.value = 1;
- } else {
- thisStep.value = 0;
- state.sourceData = [];
- }
- state.isSearch = false;
- setProps({ disabled: unref(isUpdate) });
- setModalProps({ loading: false });
- });
- 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, { getForm, setTableData, getDataSource, setSelectedRowKeys }] = useTable({
- title: '征订列表',
- columns: textbookColumns,
- bordered: true,
- rowKey: 'uuid',
- rowSelection: {
- type: 'checkbox',
- onChange: (selectedRowKeys) => {
- selectRow.value = selectedRowKeys;
- },
- },
- pagination: false,
- actionColumn: {
- width: 170,
- title: '操作',
- dataIndex: 'action',
- slots: { customRender: 'action' },
- fixed: 'right',
- },
- resizeHeightOffset: 80,
- useSearchForm: true,
- formConfig: {
- labelWidth: 100,
- schemas: [
- {
- label: '书名',
- field: 'bookName',
- component: 'Input',
- colProps: { span: 8 },
- },
- {
- label: '书号',
- field: 'issn',
- component: 'Input',
- colProps: { span: 8 },
- },
- {
- label: '课程',
- field: 'courseName',
- component: 'Input',
- colProps: { span: 8 },
- },
- ],
- submitFunc: async () => {
- const values = getForm().getFieldsValue();
- let searchData: any[] = cloneDeep(state.sourceData);
- if (values.bookName || values.issn || values.courseName) {
- if (values.bookName) {
- searchData = searchData.filter((item) => item.bookName.includes(values.bookName));
- }
- if (values.issn) {
- searchData = searchData.filter((item) => item.issn.includes(values.issn));
- }
- if (values.courseName) {
- searchData = searchData.filter((item) => item.courseName.includes(values.courseName));
- }
- state.isSearch = true;
- } else {
- state.isSearch = false;
- }
- setTableData(searchData);
- },
- },
- });
- const handleAdd = () => {
- addModelOpen(true, {
- baseSemesterId: dataInfo.value.baseSemesterId,
- });
- };
- const handleSuccess = (e) => {
- const data = cloneDeep(state.sourceData);
- const addList: any[] = [];
- e.forEach((item: any) => {
- if (!data.find((i: any) => i.textbookId === item.id)) {
- item.sourcePrice = item.price;
- item.textbookId = item.id;
- item.uuid = uniqueId();
- item.id = '';
- handleChangeDiscount(item);
- addList.push(item);
- }
- });
- state.sourceData = data.concat(addList);
- setTableData(data.concat(addList));
- // redoHeight();
- };
- const handleClear = (uuid) => {
- const keys = uuid ? [uuid] : selectRow.value;
- const data = getDataSource();
- setTableData(data.filter((item: any) => !keys.includes(item.uuid)));
- state.sourceData = state.sourceData.filter((item: any) => !keys.includes(item.uuid));
- };
- const handleSelect = async (e) => {
- selectUserList.value = e.list;
- const ids = selectUserList.value.map((item: any) => item.id);
- const data = await getTextbookListSubscription({
- classIds: ids.join(','),
- baseSemesterId: dataInfo.value.baseSemesterId,
- textbookSubscriptionId: modelRef.value.id,
- });
- data.forEach((item: any) => {
- item.sourcePrice = item.price;
- item.uuid = uniqueId();
- handleChangeDiscount(item);
- });
- state.sourceData = data;
- setTableData(data);
- };
- const { createMessage } = useMessage();
- const handleSubmit = async () => {
- const dataSoruce = cloneDeep(state.sourceData);
- if (dataSoruce.length === 0) {
- createMessage.warning('至少征订一本教材');
- return;
- }
- dataSoruce.forEach((item: any) => {
- item.studentNum = item.studentSubscriptionNumber || 0;
- item.teacherNum = item.teacherSubscriptionNumber || 0;
- });
- const postParams = unref(modelRef);
- Object.assign(postParams, {
- remark: dataInfo.value?.remark,
- subscriptionMethod: dataInfo.value.subscriptionMethod,
- baseSemesterId: dataInfo.value.baseSemesterId,
- textbookSubscriptionItemList: dataSoruce,
- 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"
- :canFullscreen="false"
- defaultFullscreen
- v-bind="$attrs"
- @register="modalReg"
- title="教材征订"
- >
- <div class="full flex flex-col">
- <div class="w-2/3 h-[50px]">
- <Steps v-model:current="thisStep">
- <step disabled title="基础信息" />
- <step disabled title="教材征订" />
- </Steps>
- </div>
- <div style="height: calc(100% - 50px)">
- <BasicForm @register="formReg" v-show="thisStep === 0" />
- <BasicTable @register="tableRef" v-show="thisStep === 1">
- <template #toolbar>
- <a-button
- v-if="dataInfo && dataInfo.subscriptionMethod == 2"
- type="primary"
- class="ml-[12px]"
- @click="handleAdd"
- >
- 选择教材
- </a-button>
- <a-button
- v-if="dataInfo && dataInfo.subscriptionMethod == 1"
- type="primary"
- class="ml-[12px]"
- @click="selectModalOpen(true, { baseData: { list: selectUserList } })"
- >
- 选择班级
- </a-button>
- <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"
- @change="updateSourceData(record)"
- />
- </template>
- <template #teacherSubscriptionNumber="{ record }">
- <a-input-number
- :step="1"
- :min="0"
- v-model:value="record.teacherSubscriptionNumber"
- @change="updateSourceData(record)"
- />
- </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.uuid)">移出</a-button>
- <a-button type="link" @click="handleViewHistory(record.textbookId)">
- 历史征订
- </a-button>
- </template>
- </BasicTable>
- </div>
- </div>
- <addTextbook @register="addReg" @success="handleSuccess" />
- <SelectClass @register="selectModalReg" @success="handleSelect" />
- <historyView @register="historyViewReg" />
- <template #footer>
- <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>
- </template>
- </BasicModal>
- </template>
- <style scoped lang="less"></style>
|