收藏功能
This commit is contained in:
parent
d336c9eafd
commit
ab734742ef
|
|
@ -574,6 +574,20 @@ const i18ns: I18n[] = [
|
|||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "deabf32f550dba8ce03111112ef588ce",
|
||||
namespace: "collect",
|
||||
language: "zh-CN",
|
||||
module: "",
|
||||
position: "oak-app-domain/Collect",
|
||||
data: {
|
||||
"name": "收藏记录",
|
||||
"attr": {
|
||||
"essay": "文章",
|
||||
"user": "用户"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "f70261a2fc23af2a9f459353e5ac1ea3",
|
||||
namespace: "comment",
|
||||
|
|
@ -664,7 +678,9 @@ const i18ns: I18n[] = [
|
|||
"setTop": "置顶",
|
||||
"cancelTop": "取消置顶",
|
||||
"like": "点赞",
|
||||
"unlike": "取消点赞"
|
||||
"unlike": "取消点赞",
|
||||
"collect": "收藏",
|
||||
"uncollect": "取消收藏"
|
||||
},
|
||||
"v": {
|
||||
"iState": {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
import { EntityDesc, EntityShape } from 'oak-domain/lib/types';
|
||||
import { Schema as Essay } from './Essay';
|
||||
import { Schema as User } from 'oak-general-business/lib/entities/User';
|
||||
|
||||
//Collect.ts
|
||||
//关联文章和用户,表示收藏记录
|
||||
export interface Schema extends EntityShape {
|
||||
essay: Essay;
|
||||
user: User;
|
||||
}
|
||||
export const entityDesc: EntityDesc<Schema> = {
|
||||
locales: {
|
||||
zh_CN: {
|
||||
name: '收藏记录',
|
||||
attr: {
|
||||
essay: '文章',
|
||||
user: '用户',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -38,7 +38,8 @@ export type TopAction = 'setTop' | 'cancelTop';
|
|||
|
||||
//点赞操作
|
||||
export type LikeAction = 'like' | 'unlike';
|
||||
|
||||
//收藏操作
|
||||
export type CollectAction = 'collect' | 'uncollect';
|
||||
|
||||
export const TopActionDef: ActionDef<TopAction, TopState> = {
|
||||
stm: {
|
||||
|
|
@ -54,7 +55,7 @@ export const TopActionDef: ActionDef<TopAction, TopState> = {
|
|||
// export type Action = IAction | CommonAction|TopAction;
|
||||
|
||||
export type State = IState | TopState;
|
||||
export type Action = IAction | TopAction|LikeAction;
|
||||
export type Action = IAction | TopAction|LikeAction|CollectAction;
|
||||
|
||||
|
||||
export const entityDesc: EntityDesc<
|
||||
|
|
@ -88,7 +89,9 @@ export const entityDesc: EntityDesc<
|
|||
setTop: '置顶',
|
||||
cancelTop: '取消置顶',
|
||||
like: '点赞',
|
||||
unlike:'取消点赞'
|
||||
unlike: '取消点赞',
|
||||
collect: '收藏',
|
||||
uncollect:'取消收藏'
|
||||
},
|
||||
v: {
|
||||
iState: {
|
||||
|
|
|
|||
|
|
@ -5,10 +5,16 @@ export default OakComponent({
|
|||
isList: false,
|
||||
projection: essayProjection,
|
||||
formData({ data }) {
|
||||
//点赞的数据
|
||||
const isLiked = data?.like$essay?.some(item => {
|
||||
return item.user.id === this.features.token.getUserId();
|
||||
})
|
||||
const likeNums = data?.like$essay?.length || 0;
|
||||
//收藏的数据
|
||||
const isCollected = data?.collect$essay?.some(item => {
|
||||
return item.user.id === this.features.token.getUserId();
|
||||
})
|
||||
const collectNums = data?.collect$essay?.length || 0;
|
||||
const fileIndex = data?.extraFile$entity?.findIndex(
|
||||
(item) => item.tag1 === 'cover'
|
||||
);
|
||||
|
|
@ -21,14 +27,18 @@ export default OakComponent({
|
|||
// 获取封面的url地址
|
||||
cover: url,
|
||||
isLiked,
|
||||
likeNums
|
||||
likeNums,
|
||||
isCollected,
|
||||
collectNums
|
||||
};
|
||||
}
|
||||
return {
|
||||
item: data,
|
||||
cover: '',
|
||||
isLiked,
|
||||
likeNums
|
||||
likeNums,
|
||||
isCollected,
|
||||
collectNums
|
||||
};
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -116,12 +116,24 @@
|
|||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.likearea{
|
||||
.likes{
|
||||
float: left;
|
||||
.threeComponts{
|
||||
float: right;
|
||||
.likearea{
|
||||
.likes{
|
||||
float: left;
|
||||
}
|
||||
.nums{
|
||||
float: right;
|
||||
margin: 2.5px 10px;
|
||||
}
|
||||
}
|
||||
.nums{
|
||||
float: right;
|
||||
margin: 2.5px 10px;
|
||||
.collectarea{
|
||||
.collects{
|
||||
float: left;
|
||||
}
|
||||
.nums{
|
||||
float: right;
|
||||
margin: 2.5px 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,12 +19,14 @@ const EssayDetails = (
|
|||
cover: string;
|
||||
isLiked: boolean;
|
||||
likeNums: number;
|
||||
isCollected: boolean;
|
||||
collectNums: number;
|
||||
}
|
||||
>
|
||||
) => {
|
||||
const { oakFullpath } = props.data;
|
||||
|
||||
const { item, cover, isLiked, likeNums } = props.data;
|
||||
const { item, cover, isLiked, likeNums ,isCollected,collectNums} = props.data;
|
||||
const [showScrollTop, setShowScrollTop] = useState(false);
|
||||
const { t, update, execute } = props.methods;
|
||||
|
||||
|
|
@ -81,29 +83,71 @@ const EssayDetails = (
|
|||
>
|
||||
返回
|
||||
</Button>
|
||||
<div className={Styles.threeComponts}>
|
||||
<div className={Styles.likearea}>
|
||||
<div className={Styles.likes}>
|
||||
{isLiked ? (<Button
|
||||
shape='circle'
|
||||
onClick={() => {
|
||||
update({
|
||||
}, 'unlike');
|
||||
execute();
|
||||
}}>
|
||||
<OakIcon name='praise_fill' size={24} />
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
shape='circle'
|
||||
onClick={() => {
|
||||
update({}, 'like')
|
||||
execute();
|
||||
}}>
|
||||
<OakIcon name='praise' size={24} />
|
||||
</Button>)}
|
||||
<div className={Styles.nums}>{likeNums}</div>
|
||||
</div>
|
||||
<div className={Styles.likes}>
|
||||
{isLiked ? (
|
||||
<Button
|
||||
shape='circle'
|
||||
onClick={() => {
|
||||
update({}, 'unlike');
|
||||
execute();
|
||||
}}
|
||||
>
|
||||
<OakIcon
|
||||
name='praise_fill'
|
||||
size={24}
|
||||
/>
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
shape='circle'
|
||||
onClick={() => {
|
||||
update({}, 'like');
|
||||
execute();
|
||||
}}
|
||||
>
|
||||
<OakIcon name='praise' size={24} />
|
||||
</Button>
|
||||
)}
|
||||
<div className={Styles.nums}>
|
||||
{likeNums}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={Styles.collectarea}>
|
||||
<div className={Styles.collects}>
|
||||
{isCollected ? (
|
||||
<Button
|
||||
shape='circle'
|
||||
onClick={() => {
|
||||
update({}, 'uncollect');
|
||||
execute();
|
||||
}}
|
||||
>
|
||||
<OakIcon
|
||||
name='collection_fill'
|
||||
size={24}
|
||||
/>
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
shape='circle'
|
||||
onClick={() => {
|
||||
update({}, 'collect');
|
||||
execute();
|
||||
}}
|
||||
>
|
||||
<OakIcon
|
||||
name='collection'
|
||||
size={24}
|
||||
/>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
<div className={Styles.nums}>{collectNums}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<MdViewer md={item.content!} />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -111,6 +111,60 @@ const triggers: Trigger<EntityDict, 'essay', BackendRuntimeContext>[] = [
|
|||
return opers.like?.remove||0;
|
||||
},
|
||||
},
|
||||
// 调用collect的action的时候,创建收藏的记录
|
||||
{
|
||||
name: '调用collect的action的时候,创建收藏的记录',
|
||||
entity: 'essay',
|
||||
action: 'collect',
|
||||
when: 'before',
|
||||
|
||||
fn: async ({ operation }, context, option) => {
|
||||
const { filter } = operation;
|
||||
assert(filter && filter.id, "filter is required");
|
||||
const essayId = filter.id;
|
||||
const userId = context.getCurrentUserId();
|
||||
//创建收藏记录
|
||||
const opers=await context.operate("collect", {
|
||||
id: await generateNewIdAsync(),
|
||||
action: "create",
|
||||
data: {
|
||||
id: await generateNewIdAsync(),
|
||||
essayId : essayId as string,
|
||||
userId,
|
||||
|
||||
}
|
||||
},option)
|
||||
|
||||
return opers.collect?.create||0;
|
||||
},
|
||||
},
|
||||
// 调用uncollect的action的时候,移除收藏的记录
|
||||
{
|
||||
name: '调用uncollect的action的时候,移除收藏的记录',
|
||||
entity: 'essay',
|
||||
action: 'uncollect',
|
||||
when: 'before',
|
||||
|
||||
fn: async ({ operation }, context, option) => {
|
||||
const { filter, data} = operation;
|
||||
assert(filter && filter.id, "filter is required");
|
||||
const essayId = filter.id;
|
||||
const userId = context.getCurrentUserId();
|
||||
//创建点赞记录
|
||||
const opers=await context.operate("collect", {
|
||||
id: await generateNewIdAsync(),
|
||||
action: "remove",
|
||||
data: {
|
||||
},
|
||||
filter: {
|
||||
essayId,
|
||||
userId,
|
||||
}
|
||||
},option)
|
||||
|
||||
return opers.collect?.remove||0;
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export default triggers;
|
||||
|
|
|
|||
|
|
@ -81,17 +81,28 @@ export const essayProjection: EntityDict['essay']['Selection']['data'] = {
|
|||
},
|
||||
count: 1,
|
||||
},
|
||||
//点赞相关的记录
|
||||
like$essay: {
|
||||
$entity: "like",
|
||||
//点赞相关的记录
|
||||
like$essay: {
|
||||
$entity: 'like',
|
||||
data: {
|
||||
user: {
|
||||
id: 1,
|
||||
name: 1,
|
||||
nickname: 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
//收藏相关的记录
|
||||
collect$essay: {
|
||||
$entity: 'collect',
|
||||
data: {
|
||||
user: {
|
||||
id: 1,
|
||||
name: 1,
|
||||
nickname: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const categoryProjection: EntityDict['category']['Selection']['data'] = {
|
||||
|
|
|
|||
Loading…
Reference in New Issue