123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- import { ActionType, BetaSchemaForm, PageContainer, ProFormInstance } from "@ant-design/pro-components"
- import { columns } from "./tableConfig"
- import { useAjax } from "@/Hook/useAjax"
- import { useModel } from "@umijs/max"
- import { longBookInfoList, longBookInfoChapterContent, longBookInfoBookConfig, longBookInfoConfig, longBookInfoChapterAllList, sysRechargeGetInfo, sysRechargeAddOrEdit, longBookInfoShelve } from "@/services/miniApp/bookManage"
- import { useCallback, useEffect, useMemo, useRef, useState } from "react"
- import { Button, Drawer, message, Popconfirm, Space, Tag } from "antd"
- import ReadText from "../components/readText"
- import formConfig from "./formConfig"
- import ReadBook from "../components/readBook"
- import { ColumnHeightOutlined, EditFilled } from "@ant-design/icons"
- import MyProTable from "@/components/MyProTable"
- const wordCountRanges: any = {
- "": { start: null, end: null }, // 全部
- "0-2": { start: 0, end: 2 * 10000 },
- "2-5": { start: 2 * 10000, end: 5 * 10000 },
- "5-10": { start: 5 * 10000, end: 10 * 10000 },
- "10-20": { start: 10 * 10000, end: 20 * 10000 },
- "20-40": { start: 20 * 10000, end: 40 * 10000 },
- "40-100": { start: 40 * 10000, end: 100 * 10000 },
- "100-150": { start: 100 * 10000, end: 150 * 10000 },
- "150-200": { start: 150 * 10000, end: 200 * 10000 },
- "200-300": { start: 200 * 10000, end: 300 * 10000 },
- "300-0": { start: 300 * 10000, end: null }, // 300万以上
- };
- type DataItem = {
- name: string;
- state: string;
- };
- type Props = {
- value?: any,
- onChange?: (v: any) => void
- closeDrawer?: (v: any) => void
- }
- /**
- * 关于props的值和bookId的操作都是为了在被当做组件选择书籍使用时的逻辑处理
- * */
- const Page: React.FC = (props: Props) => {
- let { initialState } = useModel("@@initialState")
- let { state, getLabelAndClassList } = useModel('global')
- let { tabs } = useModel("appPageConifg", modal => ({ tabs: modal.state.tabs }))
- let [open, setOpen] = useState<any>(null)//付费配置
- let [editValues, setEditValues] = useState<any>({})
- let paymentType = useState(0)
- let paymentCategory = useState(0)//收费货币
- let [bookId, setBookId] = useState<any>(props?.value?.bookId || props?.value)//当组件选择时使用
- let [isGlobalConfig, setIsGlobalConfig] = useState(false)//
- let [workDirection, setWorkDirection] = useState<any>(null)
- const [openBook, setOpneBook] = useState<any>(null)//阅读小说
- const [editSelectedRow, setEditSelectedRow] = useState<any[]>([]); //小说列表选择
- let getList = useAjax((params) => longBookInfoList(params), { type: 'table' })//获取书列表
- let getChapterContent = useAjax((params) => longBookInfoChapterContent(params))//获取章节内容信息
- let getChapterAllList = useAjax((params) => longBookInfoChapterAllList(params))//获取全部章节
- let add = useAjax((params) => longBookInfoBookConfig(params))//新增配置
- let configInfo = useAjax((params) => longBookInfoConfig(params))//获取配置信息
- let globaleConfig = useAjax((params) => sysRechargeGetInfo(params))//获取全局配置信息
- let globaleAddOrEdit = useAjax((params) => sysRechargeAddOrEdit(params))//全局配置信息修改
- let LongBookInfoShelve = useAjax((params) => longBookInfoShelve(params))//长篇小说批量上下架
- const formRef = useRef<ProFormInstance>();
- const actionRef = useRef<ActionType>();
- // 获取标签和分类
- useEffect(() => {
- getLabelAndClassList({ workDirection })
- getGlobalInfo()
- }, [workDirection])
- // 接口公共参数
- let publicData = useMemo(() => {
- let pramas = {
- appId: initialState?.selectApp?.id || "",
- distributorId: initialState?.currentUser?.distributorId,
- appType: initialState?.selectApp?.appType || "",
- }
- return bookId ? {
- appId: initialState?.selectApp?.id || "",
- appType: initialState?.selectApp?.appType || "",
- bookId
- } : pramas
- }, [initialState?.selectApp, bookId])
- //获取全局收费配置
- const getGlobalInfo = useCallback(() => {
- globaleConfig.run(publicData).then(res => {
- console.log(res)
- })
- }, [publicData])
- // 看小说列表
- const lookBookList = (params: any) => {
- let { id, pageNum, pageSize } = params
- return getChapterAllList.run({ bookId: id, ...publicData }).then(res => {
- setOpneBook({ list: res.data, ...params })
- })
- }
- // 看小说
- const lookBook = (params: any) => {
- return getChapterContent.run(params).then(res => {
- return res.data
- })
- }
- // 提交表单
- const submit = async (values: any) => {
- if (editValues?.id) {
- values.id = editValues?.id
- }
- if (editValues?.bookId) {
- values.bookId = editValues?.bookId
- }
- if (values.paymentType === 0) {//假如免费,设置vip也免费
- values.vipFree = true
- }
- add.run({ ...values, ...publicData }).then(res => {
- if (res.code === 200) {
- actionRef?.current?.reload()
- message.success("付费配置成功!")
- closeForm(false)
- }
- })
- }
- // 全局配置弹窗
- const closeGlobalForm = () => {
- setIsGlobalConfig(true)
- setOpen(true)//弹窗开启
- let data = globaleConfig?.data?.data
- setEditValues({ ...data })
- paymentType[1](data?.paymentType || 0)
- paymentCategory[1](data?.paymentCategory || 0)
- setTimeout(() => {
- formRef?.current?.setFieldsValue({ ...data })
- }, 100)
- }
- // 关闭表单弹窗和重置表单内容
- const closeForm = (b: boolean, values?: any) => {
- if (!b) {
- setEditValues({})
- paymentType[1](0)
- formRef?.current?.resetFields?.()
- setOpen(b)
- } else {
- // 获取书全部章节
- getChapterAllList.run({ bookId: values.bookId, ...publicData }).then(res => {
- if (res.code === 200) {
- setOpen(b)//弹窗开启
- if (values) {
- // 获取书付费配置
- configInfo.run({ bookId: values.bookId, ...publicData }).then(res => {
- if (res.code === 200) {
- let data = { ...res.data }
- setEditValues(data)
- paymentType[1](data?.paymentType || 0)
- formRef?.current?.setFieldsValue({ ...data, paymentType: data?.paymentType || 0, vipFree: data?.vipFree === null ? true : data?.vipFree })
- }
- })
- }
- }
- })
- }
- }
- // 批量上下架
- const shelveAll = (ids: any[], shelve: 0 | 1) => {
- LongBookInfoShelve.run({ ...publicData, ids, shelve }).then((res) => {
- if (res.code === 200) {
- actionRef?.current?.reload();
- message.success('批量' + (shelve === 0 ? '上架成功' : '下架成功'));
- setEditSelectedRow([])
- }
- });
- };
- return <PageContainer title={false}
- tabProps={{ type: 'card' }}
- >
- <MyProTable<any, any>
- // params={publicData}
- actionRef={actionRef}
- headerTitle={"小说列表"}
- rowKey={(r) => r.bookId}
- scroll={{ x: true, y: 500 }}
- tableAlertRender={!!props?.onChange ? false : ({ selectedRowKeys, selectedRows }) => {
- let { paymentType, paymentOption, paymentCategory, paymentAmount, paymentCoin, beginPayNo } = globaleConfig?.data?.data || {}
- let enumList: any = state?.enumList
- let PAYMENT_TYPE_Map: Map<any, any> = new Map(enumList?.PAYMENT_TYPE?.values?.map(({ value, description }: any) => [value, description]))
- let PAYMENT_OPTION_Map: Map<any, any> = new Map(enumList?.PAYMENT_OPTION?.values?.map(({ value, description }: any) => [value, description]))
- return <div>
- <div>
- <Tag bordered={false} style={{ cursor: 'pointer' }} onClick={closeGlobalForm}>
- <Space>
- <Tag bordered={false} color="processing" style={{ cursor: 'pointer' }}>收费类型:<span style={{ color: '#f64747' }}>{PAYMENT_TYPE_Map?.get(paymentType)}</span></Tag>
- <Tag bordered={false} color="processing" style={{ cursor: 'pointer' }}>付费起始段落/章节:<span style={{ color: "#f64747" }}>{beginPayNo}</span></Tag>
- {paymentType === 2 && <Tag bordered={false} color="processing" style={{ cursor: 'pointer' }}>段落/章节收费类型:<span style={{ color: '#f64747' }}>{PAYMENT_OPTION_Map?.get(paymentOption)}</span></Tag>}
- <Tag bordered={false} color="processing" style={{ cursor: 'pointer' }}>付费价格:
- <span style={{ color: "#f64747" }}>{paymentCategory === 0 && '¥'}{paymentCategory === 0 ? paymentAmount : paymentCoin}</span>
- {paymentCategory === 1 && '书币'}</Tag>
- </Space>
- <EditFilled />
- </Tag>
- </div>
- <div>
- {
- selectedRows?.length > 0 && <Space size={0} style={{ marginTop: 10 }}>
- <span style={{ width: 90, display: 'inline-block' }}>
- 已选{selectedRowKeys.length} 项
- </span>
- <span style={{ color: 'red' }}>
- {selectedRows
- ?.map((item: { shortBookInfoVO?: any, longBookInfo?: any, bookId: any }) => <Tag
- closable
- key={item?.bookId}
- color="red"
- onClose={() => {
- let newArr = selectedRows?.filter((i) => i?.bookId != item?.bookId)
- setEditSelectedRow(newArr)
- }}>{item?.shortBookInfoVO?.bookName || item?.longBookInfo?.bookName}</Tag>)
- }
- </span>
- </Space>
- }
- </div>
- </div>
- }}
- //多选
- rowSelection={!!props?.onChange ? {
- hideSelectAll: true,
- type: 'radio',
- selectedRowKeys: [props?.value?.bookId || props?.value],
- onSelect: (record, selected) => {
- props?.onChange?.({ ...record?.longBookInfo, ...record })
- props?.closeDrawer?.(false)
- },
- } : {
- alwaysShowAlert: true,//总是展示 alert,默认无选择不展示
- selectedRowKeys: editSelectedRow?.map((item: { bookId: any }) => item.bookId),
- onSelect: (record, selected) => {
- if (selected) {
- setEditSelectedRow([...editSelectedRow, record]);
- } else {
- setEditSelectedRow(
- editSelectedRow?.filter((item: { bookId: any }) => item.bookId !== record.bookId),
- );
- }
- },
- onSelectAll: (selected, rows, changeRows) => {
- if (selected) {
- setEditSelectedRow([...editSelectedRow, ...changeRows]);
- } else {
- let newArr = editSelectedRow?.filter((item: { bookId: any }) =>
- changeRows.every((i) => i?.bookId !== item?.bookId),
- );
- setEditSelectedRow(newArr);
- }
- },
- }}
- // 多选后的按钮操作
- tableAlertOptionRender={!!props?.onChange ? false : ({ selectedRowKeys }) => {
- return (
- <Space>
- <Popconfirm
- title={null}
- icon={null}
- onConfirm={() => {
- shelveAll(
- editSelectedRow?.map((item) => item.bookId),
- 0,
- );
- }}
- onCancel={() => {
- shelveAll(
- editSelectedRow?.map((item) => item.bookId),
- 1,
- );
- }}
- okText="全部上架"
- cancelText="全部下架"
- >
- <Button type="primary" disabled={selectedRowKeys.length === 0}>
- <ColumnHeightOutlined />
- 批量上下架
- </Button>
- </Popconfirm>
- </Space>
- );
- }}
- // 点击行
- onRow={(record) => ({
- onClick: () => {
- props?.onChange?.({ ...record?.longBookInfo, ...record })
- props?.closeDrawer?.(false)
- }
- })}
- search={{
- labelWidth: 90,
- searchGutter: [10, 15],
- }}
- loading={getChapterAllList?.loading || configInfo?.loading || getList.loading}
- // ghost={true}//去除表格的背景一些配置改变ui
- beforeSearchSubmit={(params) => {//处理搜索数据
- let newParams = Object.entries(params).reduce((acc: any, [key, value]) => {
- // 过滤掉空值,包括空字符串和 null
- if (value !== '' && value != null) {
- acc[key] = value;
- }
- if (key === 'wordCount' && value) {
- let obj = wordCountRanges[value]
- acc['startWordCount'] = obj.start
- acc['endWordCount'] = obj.end
- delete acc[key]
- }
- return acc;
- }, {});
- return newParams
- }}
- request={async (params) => {
- return await getList.run({ ...params, ...publicData }).then(res => {
- setBookId(null)
- return res
- })
- }}
- columns={columns({ authList: state?.authList, labelList: state.labelList, categoryList: state.categoryList, enumList: state?.enumList, lookBook: lookBookList, closeForm, setWorkDirection, isModal: !!props?.onChange })}
- />
- {/* 付费配置 */}
- <BetaSchemaForm<DataItem>
- title={(isGlobalConfig ? "全局" : "《" + editValues?.bookName + "》") + "付费配置"}
- formRef={formRef}
- open={open}
- onOpenChange={(b) => { !b && closeForm(b) }}
- layoutType={"ModalForm"}
- labelCol={{ span: 6 }}
- wrapperCol={{ span: 14 }}
- // grid={true}
- layout='horizontal'
- onFinish={submit}
- columns={formConfig({ isGlobalConfig, enumList: state?.enumList, paymentType, paymentCategory, paragraphList: getChapterAllList?.data?.data?.map((item: { chapterInfo: any }) => item.chapterInfo) })}
- loading={add?.loading}
- />
- {/* 阅读小说 */}
- <Drawer
- open={!!openBook}
- placement="right"
- onClose={() => { setOpneBook(null) }}
- footer={null}
- width={'65%'}
- destroyOnClose={true}
- // getContainer={false}
- styles={{ body: { padding: 0 } }}
- closeIcon={false}
- title={<div style={{ fontSize: 20 }}>{openBook?.bookName ? openBook?.bookName : ""}</div>}
- >
- <ReadBook listData={openBook} next={lookBook} />
- </Drawer>
- </PageContainer>
- }
- export default Page
|