文章封面图的上传

This commit is contained in:
pqcqaq 2024-10-16 00:09:42 +08:00
parent d7c5ec3e38
commit c32efbf3ac
6 changed files with 98 additions and 63 deletions

View File

@ -3,5 +3,6 @@
"error":{
"titleCannotBeEmpty": "文章标题不能为空",
"contentCannotBeEmpty": "文章内容不能为空"
}
},
"setting": "设置"
}

View File

@ -48,4 +48,11 @@
color: #999;
font-size: 12px;
margin-top: 5px;
}
.footer {
display: flex;
justify-content: flex-end;
gap: 10px;
margin-top: 10px;
}

View File

@ -1,4 +1,4 @@
import { Button, Input, message, Modal, Select } from 'antd';
import { Button, Form, Input, message, Modal, Select } from 'antd';
import React, { useState, useEffect, useRef } from 'react';
import Styles from './styles.module.less';
import { RowWithActions, WebComponentProps } from 'oak-frontend-base';
@ -6,6 +6,8 @@ import { EntityDict } from '@project/oak-app-domain';
import Logs from '../log';
import MdEditor from '@project/components/common/byteMD/MdEditor';
import { Image } from 'mdast';
import Crop from 'oak-general-business/es/components/extraFile/crop';
import Commit from 'oak-general-business/es/components/extraFile/commit';
export default function VditorComponent(
props: WebComponentProps<
@ -18,7 +20,7 @@ export default function VditorComponent(
}
>
) {
const { item, isCreation, oakDirty, oakFullpath } = props.data;
const { item, isCreation, oakDirty, oakFullpath, oakEntity } = props.data;
const { update, execute, navigateBack, t } = props.methods;
const [showTitleEdit, setShowTitleEdit] = useState<boolean>(false);
@ -70,6 +72,16 @@ export default function VditorComponent(
)}
<div className={Styles.btns}>
<Logs oakPath={`${oakFullpath}.log$entity`} />
{/* 设置按钮 */}
<div className={Styles.setting}>
<Button
onClick={() => {
setShowTitleEdit(true);
}}
>
{t('setting')}
</Button>
</div>
{/* 保存按钮 */}
<div className={Styles.saveBtn}>
<Button
@ -98,29 +110,70 @@ export default function VditorComponent(
}}
></MdEditor>
<Modal
title='编辑标题'
title={t('setting')}
open={showTitleEdit}
onOk={() => {
if (!item?.title) {
message.error(t('error.titleCannotBeEmpty'));
return;
}
setShowTitleEdit(false);
execute();
navigateBack();
}}
onCancel={() => {
setShowTitleEdit(false);
}}
footer={
<div className={Styles.footer}>
<Button
onClick={() => {
setShowTitleEdit(false);
}}
>
{t('common::action.cancel')}
</Button>
<Commit
entity={oakEntity}
oakPath={oakFullpath}
afterCommit={() => {
if (!item?.title) {
message.error(
t('error.titleCannotBeEmpty')
);
return;
}
setShowTitleEdit(false);
execute();
navigateBack();
}}
executeText={t('common::action.save')}
></Commit>
</div>
}
>
<Input
value={item?.title}
onChange={(e) =>
update({
title: e.target.value,
})
}
/>
<Form>
<Form.Item label={t('essay:attr.title')}>
<Input
value={item?.title}
onChange={(e) =>
update({
title: e.target.value,
})
}
/>
</Form.Item>
<Form.Item label={t('essay:attr.images')}>
<Crop
entity={oakEntity}
entityId={item.id}
oakPath={`${oakFullpath}.extraFile$entity`}
maxNumber={1}
accept='image/*'
tag1='cover'
enableCrop
showRest
showGrid
rotationSlider
aspectSlider
aspect={16 / 9}
cropQuality={0.8}
enableCompross
maxWidth={1920}
maxHeight={1080}
minWidth={1280}
minHeight={720}
></Crop>
</Form.Item>
</Form>
</Modal>
</div>
);

View File

@ -3,6 +3,7 @@ import { EntityDict } from '@project/oak-app-domain';
import { RowWithActions, WebComponentProps } from 'oak-frontend-base';
import Styles from './styles.module.less';
import dayjs from 'dayjs';
import useFeatures from '@project/hooks/useFeatures';
const EssayItem = (props: {
item: RowWithActions<EntityDict, 'essay'>;
@ -10,6 +11,8 @@ const EssayItem = (props: {
t: (key: string) => string;
}) => {
const { item, navigateTo, t } = props;
const features = useFeatures();
// features.extraFile.
return (
<>
@ -46,21 +49,21 @@ const EssayItem = (props: {
{/* 发布于,上一次修改于 */}
<div className={Styles.meta}>
<div className={Styles.updatedAt}>
{t('common::$$updateAt$$') + ": "}
{t('common::$$updateAt$$') + ': '}
{dayjs(item.$$updateAt$$).format(
'YYYY-MM-DD HH:mm:ss'
)}
</div>
<div className={Styles.extra}>
<div className={Styles.publishedAt}>
{t('common::$$createAt$$') + ": "}
{t('common::$$createAt$$') + ': '}
{dayjs(item.$$createAt$$).format(
'YYYY-MM-DD HH:mm:ss'
)}
</div>
{/* 作者信息 */}
<div className={Styles.creator}>
{t('common::creator') + ": "}
{t('common::creator') + ': '}
{item.creator?.name ||
item.creator?.nickname ||
''}

View File

@ -245,7 +245,8 @@ const i18ns: I18n[] = [
"close": "关",
"enter": "请输入",
"change": "修改",
"finish": "完成"
"finish": "完成",
"creator": "创建人"
}
},
{

View File

@ -1,39 +1,9 @@
import { extraFileProjection } from '@project/utils/projection';
import { essayProjection } from '@project/utils/projection';
export default OakComponent({
entity: 'essay',
isList: false,
projection: {
id: 1,
title: 1,
summary: 1,
content: 1,
creator: {
id: 1,
name: 1,
nickname: 1,
},
meta: 1,
extraFile$entity: {
$entity: 'extraFile',
data: extraFileProjection,
filter: {
tag1: 'cover',
},
sorter: [
{
$attr: {
sort: 1,
},
$direction: 'asc',
},
],
},
category: {
id: 1,
name: 1,
}
},
projection: essayProjection,
formData({ data }) {
return {
isCreation: this.isCreation(),
@ -41,13 +11,13 @@ export default OakComponent({
};
},
lifetimes: {
async ready(){
async ready() {
if (this.isCreation()) {
const userId = features.token.getUserId();
this.update({
creatorId: userId,
})
});
}
},
}
},
});