搜索结果列表页面开发

This commit is contained in:
付民康
2025-03-12 18:41:20 +08:00
commit 7cebe8fc00
739 changed files with 88149 additions and 0 deletions

View File

@@ -0,0 +1,93 @@
import { ref } from 'vue';
import { useAccountStore } from '@/stores/user';
import { orgInfoStore } from '@/stores/Org/index';
import { repoInfoStore } from '@/stores/Repo/index';
import { getSettingsValues } from '@/api/repo';
import { getOrgDiscussionSettings } from '@/api/org';
import { useRepoId } from '@/utils/hooks/useRepoId';
import type {
repoAndOrgSettingDictType
} from '@/api/discussion/types';
/**
* 获取用户信息+是否登录
*/
export function useDiscussGetUserInfo() {
const { isLogin = false, accountInfo: userInfo = {}} = useAccountStore();
return { isLogin, userInfo };
}
/**
* 查询讨论模块是否开启,返回组织/项目id用于讨论接口请求
* @param source_type 1 组织2项目
* @param orgNamespace 组织 namespace
* 项目使用 useRepoId 获取 namespace
*/
export function useDiscussionOpen(source_type = 1, orgNamespace = '') {
const discussOpen = ref('0'); // 讨论模块是否打开0关闭1打开
const id = ref(''); // 项目/组织id
const project_id = ref(''); // 项目fullpath不带%2F
async function getDiscussionStatus() {
if (source_type === 1) {
// 组织讨论模块状态查询
const { orgInfo } = orgInfoStore();
const { module_setting } = orgInfo;
// 有 store 数据,从 store 取
if (orgNamespace === orgInfo.name && module_setting?.group_id) {
id.value = module_setting.group_id;
discussOpen.value = module_setting.modules.find(
(e: repoAndOrgSettingDictType) => e.key === 'DISCUSSION'
)?.value || '0';
} else {
// 无 store 数据,接口获取
const res = await getOrgDiscussionSettings({ orgId: orgNamespace });
if (!res.error) {
const resData = res?.data;
id.value = resData.group_id;
const discussStatus = resData.modules.find(
(e: repoAndOrgSettingDictType) => e.key === 'DISCUSSION'
).value; // 组织讨论是否开启, '0'关闭,'1'开启
if (discussStatus === '1') {
discussOpen.value = '1';
return;
}
}
}
} else {
const { repoInfo } = repoInfoStore();
const { module_setting } = repoInfo;
// 完整路径,供上传使用
const { repoId: fullRepoPath } = useRepoId('/');
fullRepoPath && (project_id.value = fullRepoPath.value);
// 有 store 数据,从 store 取
if (module_setting?.repo_id) {
id.value = module_setting.repo_id;
discussOpen.value = module_setting.modules.find(
(e: repoAndOrgSettingDictType) => e.key === 'DISCUSSION'
)?.value || '0';
} else {
// 无 store 数据,接口获取
const { repoId } = useRepoId();
const res = await getSettingsValues({
repoId: repoId.value
});
if (!res.error) {
const resData = res?.data?.data;
id.value = resData.repo_id;
const discussStatus = resData.modules.find(
(e: repoAndOrgSettingDictType) => e.key === 'DISCUSSION'
).value; // 项目讨论是否开启, '0'关闭,'1'开启
if (discussStatus === '1') {
discussOpen.value = '1';
return;
}
}
}
}
}
return { id, discussOpen, project_id, getDiscussionStatus };
}

477
src/api/discussion/index.ts Normal file
View File

@@ -0,0 +1,477 @@
import request from '@/utils/request';
import * as types from '@/api/discussion/types';
import { reqCatch } from '@/utils/catch';
import type { categoryType } from '@/api/discussion/types';
// ---------------------------- discussion CRUD ----------------------------- //
// 新增讨论
export function discussSave(data: types.commonDiscussionReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss',
method: 'post',
data
}), data);
}
// discussion 列表
export function discussList(data: types.commonDiscussionReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/page',
method: 'post',
data
}), data);
}
// 删除讨论
export function discussDelete(data: {id:string}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss',
method: 'delete',
data
}), data);
}
// 更新讨论
export function discussUpdate(data: types.commonDiscussionReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss',
method: 'put',
data
}), data);
}
// ---------------------------- discussion 详情操作 ----------------------------- //
// discuss 详情
export function discussDetail(data: {source_id: string, source_type:number, serial_number:string}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/detail',
method: 'post',
data
}), data);
}
// 讨论新建-组织可 @ 成员列表
// TODO: 暂未提供
export function discussOrgMembers(data: types.commonDiscussionReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/org/v1/member/list',
method: 'post',
data
}), data);
}
// 讨论新建 - 项目可 @ 成员列表
export function discussRepoMembers(params: { repoId: string, page?: number, per_page?: number }): Promise<any> {
const { repoId, ...param } = params;
return reqCatch(() => request({
url: `/api/v1/projects/${repoId}/members/all`,
method: 'get',
params: Object.assign({ page: 1, per_page: 10 }, param)
}), params);
}
// 讨论详情,更改 discuss 关联标签
export function discussChangeRelatedLabels(data:{discuss_id:string;label:string[]}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/label',
method: 'post',
data
}), data);
}
// 查询讨论关联用户列表,需要登录
export function discussDetailRelatedUsers(params:{source_id:string}) {
const { source_id } = params;
return reqCatch(() => request({
url: `/api/v1/discuss/relateUser/${source_id}`,
method: 'get'
}), params);
}
// 查询讨论最近活动用户,不需要登录
export function discussDetailRecentActiveUsers(params:{source_id:string}) {
const { source_id } = params;
return reqCatch(() => request({
url: `/api/v1/discuss/recentActivity/${source_id}`,
method: 'get'
}), params);
}
// discussion 讨论-总列表置顶/取消置顶
export function discussPin(data:{id: string;is_pin: 0|1}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/changePin',
method: 'post',
data
}), data);
}
// discussion 分类置顶/取消置顶
export function disussTypePin(data:{id: string;is_pin: 0|1}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/changeCatePin',
method: 'post',
data
}), data);
}
// 关闭/重新打开 讨论
export function discussClose(data:{id: string;state: number}): Promise<any> {
// 讨论的状态0打开1正常关闭2过期关闭3:重复关闭
return reqCatch(() => request({
url: '/api/v1/discuss/changeState',
method: 'post',
data
}), data);
}
// 讨论锁定/解锁
export function disussionLock(data:{id: string;is_lock: 0|1}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/changeLock',
method: 'post',
data
}), data);
}
// 更换已创建讨论的分类 - 侧边栏操作
export function discussChangeType(data:{id: string;category_id: string}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/changeCate',
method: 'post',
data
}), data);
}
// 讨论-投票
export function discussVote(data:{discuss_id:string;option_id:string}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/vote',
method: 'post',
data
}), data);
}
// 讨论 - 点赞
// targetType - 点赞的主体类型1讨论2评论3:评论回复
export function discussLike(data:{target_id:string; target_type:number}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/like',
method: 'post',
data
}), data);
}
// 讨论 - 取消点赞
// targetType - 点赞的主体类型1讨论2评论3:评论回复
export function discussUnLike(data:{target_id:string; target_type:number}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/unlike',
method: 'post',
data
}), data);
}
// ---------------------------- discussion 评论操作 ----------------------------- //
// 评论列表
export function commentList(data:{discuss_id: string}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/comment/page',
method: 'post',
data
}), data);
}
// 新增评论
export function commentSave(data:types.commonDiscussionReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/comment',
method: 'post',
data
}), data);
}
// 编辑评论
export function commentUpdate(data:types.commonDiscussionReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/comment',
method: 'put',
data
}), data);
}
// 删除评论
export function commentDelete(data:{id:string}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/comment',
method: 'delete',
data
}), data);
}
// 标记评论或者回复为答案
export function commentRemark(data:{id: string}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/comment/remark',
method: 'post',
data
}), data);
}
// 取消标记评论或者回复为答案
export function commentUnremark(data:{id: string}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/comment/unremark',
method: 'post',
data
}), data);
}
// ---------------------------- discussion 评论-回复 操作 ----------------------------- //
// 查询评论的回复列表
export function replyList(data:{parent_id: string, page:number; size:number }): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/comment/reply/page',
method: 'post',
data
}), data);
}
// 新增回复
export function replySave(data:types.commonDiscussionReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/comment/reply',
method: 'post',
data
}), data);
}
// 编辑回复
export function replyUpdate(data:types.commonDiscussionReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/comment/reply',
method: 'put',
data
}), data);
}
// 删除回复
export function replyDelete(data:{id:string}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/comment/reply',
method: 'delete',
data
}), data);
}
// ---------------------------- 分类type CRUD ----------------------------- //
// 获取讨论分类的基础类型(字典)
export function categoryBasicType(params:types.commonDiscussionReqType) {
return reqCatch(() => request({
url: `/api/v1/discuss/category/type`,
method: 'get'
}), params);
}
// 获取某个项目或仓库下的所有讨论分类
export function getAllTypes(params: {id: string;source_type:number}) {
const { id, source_type } = params;
return reqCatch(() => request({
url: `/api/v1/discuss/category/list/${id}/${source_type}`,
method: 'get'
}), params);
}
// 获取某个项目或者仓库下的所有讨论分类和分组
// 用于「管理内容分类」页
export function getAllSectionAndTypes(params: {source_id: string, source_type:number}) {
const { source_id, source_type } = params;
return reqCatch(() => request({
url: `/api/v1/discuss/category/all/${source_id}/${source_type}`,
method: 'get'
}), params);
}
// 新增讨论分类 type
export function typeSave(data:types.commonDiscussionReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/category',
method: 'post',
data
}), data);
}
// 讨论分类 type 详情
export function typeDetail(params: {id: string|undefined}):Promise<any> {
const { id } = params;
return reqCatch(() => request({
url: `/api/v1/discuss/category/detail/${id}`,
method: 'get'
}), params);
}
// 更新 type
export function typeUpdate(data:types.commonDiscussionReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/category',
method: 'put',
data
}), data);
}
// 删除讨论分类 type
export function typeDelete(data:{id: string, transfer_id?:string}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/category',
method: 'delete',
data
}), data);
}
// ---------------------------- section CRUD ----------------------------- //
// 新增 section
export function sectionSave(data:types.commonDiscussionReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/section',
method: 'post',
data
}), data);
}
// section 详情
export function sectionDetail(params: {id: string|undefined}) {
const { id } = params;
return reqCatch(() => request({
url: `/api/v1/discuss/section/detail/${id}`,
method: 'get'
}), params);
}
// 更新 section
export function sectionUpdate(data:types.commonDiscussionReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/section',
method: 'put',
data
}), data);
}
// 删除 section
export function sectionDelete(data:{id: string}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/section',
method: 'delete',
data
}), data);
}
// 根据分组 id 获取下面所有内容分类
export function sectionOwnCategory(params: {section_id: string}) {
const { section_id } = params;
return reqCatch(() => request({
url: `/api/v1/discuss/category/section/${section_id}`,
method: 'get'
}), params);
}
// 查询仓库/组织下的讨论分组
export function getAllSections(params: {source_id: string; source_type:number}) {
const { source_id, source_type } = params;
return reqCatch(() => request({
url: `/api/v1/discuss/section/list/${source_id}/${source_type}`,
method: 'get'
}), params);
}
// ----------------------------------- else --------------------------//
// 组织标签列表
// TODO: 组织还没有标签
export function orgLabelList(params: {group_id:string}): Promise<any> {
const { group_id } = params;
return reqCatch(() => request({
url: `/api/v4/groups/${group_id}/labels`,
method: 'get',
params: { page: 1, per_page: 20 }
}), params);
}
// 仓库标签列表
export function repoLabelList(params: {project_id:string}): Promise<any> {
const { project_id } = params;
return reqCatch(() => request({
url: `/api/v1/projects/${project_id}/labels`,
method: 'get',
params: { page: 1, per_page: 20 }
}), params);
}
// 当前用户-项目权限
export function getRepoPermission(params: { repo_id: string }) {
const { repo_id } = params;
return reqCatch(() => request({
url: `/api/v1/projects/${repo_id}/role`,
method: 'get'
}), params);
}
// 当前用户-组织权限
export function getOrgPermission(params:{group_id:string}): Promise<any> {
const { group_id } = params;
return reqCatch(() => request({
url: `/api/v2/groups/${group_id}`,
method: 'get',
params
}, {
customError: true
}));
}
// 获取社区热心榜单
export function getAnswerRank(params: {source_id: string, source_type:number}): Promise<any> {
const { source_id, source_type } = params;
return reqCatch(() => request({
url: `/api/v1/discuss/answerSort/${source_id}/${source_type}`,
method: 'get'
}), params);
}
// ------------------------------ Dashboard 我的讨论,我参与的讨论 ---------------------------------------------------//
// 我创建的讨论列表
export function myCreatedDiscuss(data:types.commonDiscussionReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/my/page',
method: 'post',
data
}), data);
}
// 我参与的讨论列表
export function myJoineddDiscuss(data:types.commonDiscussionReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/join/page',
method: 'post',
data
}), data);
}
// 获取评论原始数据
export function getDiscussionOriginalData(id: string) {
return reqCatch(() => request({
url: `/api/v1/discuss/comment/origin_detail/${id}`,
method: 'get',
params: {}
}));
}
// 获取评论详情, 子评论的话, 同时获取父级评论信息
export function getDiscussionDetail(id: string) {
return reqCatch(() => request({
url: `/api/v1/discuss/comment/detail/${id}`,
method: 'get',
params: {}
}));
}

208
src/api/discussion/types.ts Normal file
View File

@@ -0,0 +1,208 @@
import { type errorType } from '@/api/types/common';
export interface commonDiscussionReqType {
[propName: string]: any;
}
export interface commonDiscussionResType extends errorType {
[propName: string]: any;
}
export interface commonDictType {
label: string;
value: string;
desc?: string; // 描述
color?: string;
hover_color?: string;
children?: any[];
}
export interface commonPaginationType {
page: number;
size: number;
}
export interface discussionListItemType {
id: string; // 讨论id
title: string;
section_id?: string;
category_id?: string;
category_type?: number; // 讨论类型4种,1-开放讨论2-问答3-公告4-投票
category_icon?:string;
category_name?: string;
comment_total?: number; // 评论总数
reply_total?: number; // 回复总数
like_total?: number | null;
is_like?: boolean; // 是否已点赞: true 已点赞false 未点赞
is_lock?: number; // 是否锁定01
is_pin?: number; // 是否置顶01
pin_date?: string;
is_category_pin?: number; // 是否分类置顶
pin_category_date?: string;
is_closed?: number; // 是否关闭
closed_date?: string;
is_answered?: number; // 回答是否采纳,01
label?: string[]; // labels
serial_number?: number; // 顺序号
created_by?: string; // 创建者id
created_by_user_name?: string;
created_by_user_photo?: string;
created_date?: string;
last_modified_date?: string;
category:categoryType; // 分类信息
source_type?:number; // 组织1项目2
source_id?:string;
}
export interface RadioOption<T> {
value: T;
label: string;
}
export interface repoAndOrgSettingDictType {
key:string;
type:string;
value:string;
};
// 讨论分类 || 讨论分组 itemType
export interface discussionTypeOrSection {
id: string;
icon: string;
title: string;
desc?: string;
answerAcceptEnable?: boolean;
isGroup: boolean;
categoryType?:number;
}
export interface categoryType {
id: string; // categoryId
category_name: string;
category_desc?: string;
category_type: number; // 讨论类型4种,1-开放讨论2-问答3-公告4-投票,不过现在有个专门的接口来查
section_id?: string; // 所属分组
category_icon: string; // icon
}
export interface sectionType {
id:string;
section_name:string;
section_icon:string;
}
export interface sectionOwnCategoryType extends sectionType {
category_list: categoryType[];
}
export interface sectionItemType {
unSection?: categoryType[];
section: sectionOwnCategoryType[];
}
export interface discussDetailType {
id:string;
category_id:string;
category?:categoryType;
created_by?:string;
created_date?:string;
created_by_user_name?:string;
created_by_user_photo?:string;
serial_number:number;
title:string;
content:string;
md_content:string;
is_lock:number; // 是否锁定10
is_pin:number;
pin_date?:string;
is_category_pin:number;
pin_category_date?:string;
is_closed:number; // 是否关闭10
closed_date?:string;
is_answered:number;
comment_total:number;
reply_total?:number;
like_total?:number;
is_like?:boolean;
question?:questionInfoType;
options?:quesitonOptionType[];
is_vote?:boolean; // 是否投过票
option_id?:string; // 投过票的id
label?:string[]; // 关联的 labels
is_edit?:boolean; // 投票类型的讨论 - 更新时是否变更了投票内容(标题 + 选项)
}
export interface commentType {
id:string;
content?:string;
md_content:string;
discuss_id?:string;
parent_id?:string;
serial_number?:number;
source_id?:string;
source_type?:number;
last_modified_date?:string;
last_modified_by?:string;
created_by?:string;
created_date?:string;
created_by_user_name?:string;
created_by_user_photo?:string;
ip?:string;
is_hide?:number; // 是否隐藏评论
reply_total?:number;
like_total?:number;
is_like?:boolean; // true:已点赞false:未点赞
is_deleted?:number;
is_remark?: number; // 是否采纳为答案10:否
replyCover?: any;
}
export interface questionInfoType {
created_by:string;
created_date:string;
id:string;
last_modified_by?:string;
last_modified_date?:string;
question:string; // 投票的标题
vote_total:number; // 投票参与总人数
}
// 投票选项信息
export interface quesitonOptionType {
created_by:string;
created_date:string;
id:string; // 投票选项id
last_modified_by?:string;
last_modified_date?:string;
option_order:number; // 投票选项顺序
vote_id:string;
vote_option:string;
vote_total:number;
vote_total_percent:number; // 选项投票百分比
}
export interface ISidebar {
id?:string; // discuss id,详情页才显示参与者和操作按钮组
labelDicts?:commonDictType[]; // 标签字典
checkedLabelIds?:string[]; // 已关联 label ids
checkedLabels?:commonDictType[]; // 要渲染的已选label list
setLabels?:Function; // emit 关联标签
categoryDicts?:commonDictType[];
checkedCategoryId?:string;
checkedCategory?:commonDictType;
changeCategory?:Function;
participators?:any[];
}
export interface userInfoType {
domain_id?: string
email?: string
id?: string
mobile?: string
nickname?: string
username?: string
access_token?: string
refresh_token?: string
xauth_token?: string
[x: string]: any
}