import { DataModel, transformArrayDataModel, type KeyValue, type NewDataModel } from '@imengyu/js-request-transform'; import { AppServerRequestModule } from './RequestModules'; import { transformSomeToArray } from './Utils'; import { RequestOptions, requireNotNull, type QueryParams } from '@imengyu/imengyu-utils'; import ApiCofig from '@/common/config/ApiCofig'; export class GetColumListParams extends DataModel { public constructor() { super(GetColumListParams); this.setNameMapperCase('Camel', 'Snake'); } setModelId(val: number) { this.modelId = val; return this; } setMainBodyColumnId(val: number) { this.mainBodyColumnId = val; return this; } setFlag(val: 'hot'|'recommend'|'top') { this.flag = val; return this; } setSize(val: number) { this.size = val; return this; } modelId?: number; /** * 主体栏目id */ mainBodyColumnId: number = 0; /** * 标志:hot=热门,recommend=推荐,top=置顶 */ flag ?: 'hot'|'recommend'|'top'; /** * 内容数量,默认4 */ size?: number; } export class GetContentListParams extends DataModel { public constructor() { super(GetContentListParams); this.setNameMapperCase('Camel', 'Snake'); this._convertTable = { ids: { customToServerFn: (val) => (val as number[]).join(','), customToClientFn: (val) => (val as string).split(',').map((item) => parseInt(item)), }, } } setMainBodyColumnId(val: string|number|number[]|undefined) { if (val === undefined) return this; if (typeof val === 'string') { if (val.includes(',')) { val = val.split(',').map((item) => parseInt(item)); } else { val = parseInt(val); } } this.mainBodyColumnId = val; return this; } setFlag(val: 'hot'|'recommend'|'top') { this.flag = val; return this; } setIds(val: number[]) { this.ids = val; return this; } setType(val: 1|2|3|4) { this.type = val; return this; } setSize(val: number) { this.size = val; return this; } setKeywords(val: string) { this.keywords = val; return this; } setModelId(val: number) { this.modelId = val; return this; } static TYPE_ARTICLE = 1; static TYPE_AUDIO = 2; static TYPE_VIDEO = 3; static TYPE_IMAGE = 4; static TYPE_ARCHIVE = 5; modelId ?: number; /** * 主体栏目id */ mainBodyColumnId: number|number[] = 0; /** * 标志:hot=热门,recommend=推荐,top=置顶 */ flag ?: 'hot'|'recommend'|'top'; /** * 内容id(逗号隔开)如:3 或者 1,2,3 */ ids?: number[]; /** * 类型:1=文章,2=音频,3=视频,4=相册 */ type?: 1|2|3|4; /** * 内容数量,默认4 */ size ?: number; /** * 关键字查询 */ keywords?: string; } export class GetColumContentList extends DataModel { constructor() { super(GetColumContentList, "主体栏目列表"); this.setNameMapperCase('Camel', 'Snake'); this._convertTable = { id: { clientSide: 'number', serverSide: 'number', clientSideRequired: true }, name: { clientSide: 'string', serverSide: 'string', clientSideRequired: true }, content_list: { clientSide: 'array', clientSideRequired: true, clientSideChildDataModel: GetContentListItem, }, } } name = ''; overview = ''; } export class GetModelColumContentList extends DataModel { constructor() { super(GetColumContentList, "模型的主体栏目列表"); this.setNameMapperCase('Camel', 'Snake'); this._convertTable = { id: { clientSide: 'number', serverSide: 'number', clientSideRequired: true }, name: { clientSide: 'string', serverSide: 'string', clientSideRequired: true }, iscontribute: { clientSide: 'boolean' }, } } id = 0; name = ''; modelId = 0; image = ''; diyname = ''; iscontribute = false; statusText = ''; } export class GetContentListItem extends DataModel { constructor() { super(GetContentListItem, "内容列表"); this.setNameMapperCase('Camel', 'Snake'); this._convertTable = { id: { clientSide: 'number', serverSide: 'number', clientSideRequired: true }, mainBodyColumnId: { clientSide: 'number', serverSide: 'number', clientSideRequired: true }, title: { clientSide: 'string', serverSide: 'string', clientSideRequired: true }, isGuest: { clientSide: 'boolean', serverSide: 'number' }, isLogin: { clientSide: 'boolean', serverSide: 'number' }, isComment: { clientSide: 'boolean', serverSide: 'number' }, isLike: { clientSide: 'boolean', serverSide: 'number' }, isCollect: { clientSide: 'boolean', serverSide: 'number' }, latitude: { clientSide: 'number', serverSide: 'number' }, longitude: { clientSide: 'number', serverSide: 'number' }, publishAt: { clientSide: 'date', serverSide: 'string' }, flag: { clientSide: 'splitCommaArray', serverSide: 'commaArrayMerge' }, tags: { clientSide: 'splitCommaArray', serverSide: 'commaArrayMerge' }, keywords: { clientSide: 'splitCommaArray', serverSide: 'commaArrayMerge' }, brandType: { clientSide: 'splitCommaArray', serverSide: 'commaArrayMerge' }, type: { clientSide: 'number', serverSide: 'number' }, }; this._nameMapperServer = { 'column_name': 'mainBodyColumnName', }; this._convertKeyType = (key, direction) => { if (key.endsWith('Time')) return { clientSide: 'date', serverSide: 'string', }; return undefined; }; } id = 0; modelId = 0; modelName = ''; mainBodyColumnId = 0; mainBodyColumnName = ''; latitude = 0; longitude = 0; mapX = ''; mapY = ''; from = ''; title = '!title'; region = 0; image = ''; thumbnail = ''; desc = '!desc'; content = '!content'; type = 0; keywords ?: string[]; flag ?: string[]; tags ?: string[]; views = 0; comments = 0; likes = 0; collects = 0; dislikes = 0; district = ''; publishAt = new Date(); } export class GetContentDetailItem extends DataModel { constructor() { super(GetContentDetailItem, "内容详情"); this.setNameMapperCase('Camel', 'Snake'); this._beforeSolveServer = (data) => { if (!data.id && data.content_id) data.id = Number(data.content_id); return data; } this._convertTable = { id: { clientSide: 'number', serverSide: 'number', clientSideRequired: true }, title: { clientSide: 'string', serverSide: 'string', clientSideRequired: true }, isGuest: { clientSide: 'boolean', serverSide: 'number' }, isLogin: { clientSide: 'boolean', serverSide: 'number' }, isComment: { clientSide: 'boolean', serverSide: 'number' }, isLike: { clientSide: 'boolean', serverSide: 'number' }, isCollect: { clientSide: 'boolean', serverSide: 'number' }, publishAt: { clientSide: 'date', serverSide: 'string' }, flag: { clientSide: 'splitCommaArray', serverSide: 'commaArrayMerge' }, tags: { clientSide: 'splitCommaArray', serverSide: 'commaArrayMerge' }, type: { clientSide: 'number', serverSide: 'number' }, ichSitesList: { clientSide: 'array', clientSideChildDataModel: GetContentDetailItem }, inheritorsList: { clientSide: 'array', clientSideChildDataModel: GetContentDetailItem }, otherLevel: { clientSide: 'array', clientSideChildDataModel: GetContentDetailItem }, } this._nameMapperServer = { 'column_name': 'mainBodyColumnName', }; this._convertKeyType = (key, direction) => { if (key.endsWith('Time')) return { clientSide: 'date', serverSide: 'string', }; else if (key.endsWith('List')) { return [ { clientSide: 'map', serverSide: 'original'}, { clientSide: 'array', clientSideChildDataModel: GetContentDetailItem, serverSide: 'original' }, ] } return undefined; }; this._afterSolveServer = () => { if (!this.image && this.images && this.images && this.images.length > 0 ) { this.image = this.images[0] } if ((!this.images || this.images.length == 0) && this.image) { this.images = [ this.image ] } if (this.publishVideo) { this.video = this.publishVideo } if (this.associationMeList) { this.associationMeFirstTitle = this.associationMeList[0]?.title || '' } if (this.otherLevel) { this.otherLevelCount = this.otherLevel.length + '个' } this.titleBox = Boolean(this.deathBirth); } } id = 0; from = ''; modelId = 0; modelName = ''; mainBodyColumnId = 0; mainBodyColumnName = ''; type = 0; title = ''; region = 0; image = ''; images = [] as string[]; audio = ''; video = ''; archives = ''; publishVideo?: string; desc = ''; flag ?: string[]; tags ?: string[]; views = 0; comments = 0; likes = 0; collects = 0; dislikes = 0; isLogin = false; isGuest = false; isComment = false; isLike = false; isCollect = false; content = ''; publishAt = new Date(); associationMeList = [] as { id: number, title: string, image: string, thumbnail: string, }[]; associationMeFirstTitle = ''; otherLevel : GetContentDetailItem[] = []; } export class CategoryListItem extends DataModel { constructor() { super(CategoryListItem, "分类列表"); this.setNameMapperCase('Camel', 'Snake'); this._convertTable = { id: { clientSide: 'number', serverSide: 'number', clientSideRequired: true }, pid: { clientSide: 'number', serverSide: 'number' }, haschild: { clientSide: 'boolean', serverSide: 'number' }, } } id !: number; pid !: number; title = ''; status = 'normal'; weight = 0; spacer = ''; haschild = false; children?: CategoryListItem[]; } export class FeedBackItem extends DataModel { constructor() { super(FeedBackItem, "内容反馈"); this.setNameMapperCase('Camel', 'Snake'); this._convertTable = {}; this._afterSolveClient = (data) => { data.page_url = `${this.page}?modelId=${data.modelId}&mainBodyColumnId=${data.mainBodyColumnId}&contentId=${data.contentId}`; } } type = null as number|null; content = ''; images = [] as string[]; contact = ''; contentId = 0; title = ''; page = ''; modelId = 0; modelName = ''; mainBodyColumnId = 0; mainBodyColumnName = ''; } export class CommonContentApi extends AppServerRequestModule { constructor( mainBodyId = ApiCofig.mainBodyId, modelId = 0, debugName = 'CommonContent', mainBodyColumnId?: number|number[]) { super(); this.modelId = modelId; this.mainBodyId = mainBodyId; this.mainBodyColumnId = mainBodyColumnId; this.debugName = debugName; this.description = debugName; } public description: string; public mainBodyId: number; public mainBodyColumnId?: number|number[]; public modelId: number; protected debugName: string; private toStringArray(arr: number|number[]|undefined) { if (typeof arr === 'undefined') return ''; return typeof arr === 'object' ? arr.join(',') : arr.toString(); } /** * 获取分类列表 * @param type 根级类型:1=区域、2=级别、3=文物类型、4=非遗类型、42=事件类型 * @param withself 是否返回包含自己:true=是,false=否 ,默认false * @returns */ async getCategoryList( type?: number, withself?: boolean, ) { const res = await (this.get('/content/category/getCategoryList', '获取分类列表', { type, is_tree: false, withself, })) return transformArrayDataModel(CategoryListItem, res.data!, `获取分类列表`, true); } /** * 用于获取某一个分类需要用的子级 * @param pid 父级 * @returns */ async getCategoryChildList(pid?: number) { const res = await this.get('/content/category/getCategoryOnlyChildList', '获取分类子级列表', { pid, }); return transformArrayDataModel( CategoryListItem, transformSomeToArray(res.data), `获取分类列表`, true ); } /** * 模型的主体栏目列表 * @param params 参数 * @param querys 额外参数 * @returns */ async getModelColumList( modelId: number, mainBodyColumnId?: number, page: number = 1, pageSize: number = 50, querys?: QueryParams ) { const res = await this.get('/content/main_body_column/getColumnList', `${this.debugName} 模型的主体栏目列表`, { main_body_id: this.mainBodyId, model_id: modelId ?? this.modelId, main_body_column_id: mainBodyColumnId, page, pageSize, ...querys }); return transformArrayDataModel(GetModelColumContentList, res.data as any, `${this.debugName} 模型的主体栏目列表`, true); } /** * 主体栏目列表 * @param params 参数 * @param querys 额外参数 * @returns */ async getColumList(params: GetColumListParams, modelClassCreator: NewDataModel = GetColumContentList, querys?: QueryParams) { const res = await this.get<{ list: T[], total: number }>('/content/content/getMainBodyColumnContentList', `${this.debugName} 主体栏目列表`, { main_body_id: this.mainBodyId, model_id: this.modelId, ...params.toServerSide(), ...querys, }); return { list: transformArrayDataModel(modelClassCreator, requireNotNull(res.data).list, `${this.debugName} 主体栏目列表`, true), total: requireNotNull(res.data).total as number, }; } /** * 模型内容列表 * @param params 参数 * @param page 页码 * @param pageSize 页大小 * @param querys 额外参数 * @returns */ async getContentList(params: GetContentListParams, page: number, pageSize: number = 10, modelClassCreator: NewDataModel = GetContentListItem, querys?: QueryParams) { const res = await this.get<{ list: T[], total: number }>('/content/content/getContentList', `${this.debugName} 模型内容列表`, { ...params.toServerSide(), model_id: params.modelId || this.modelId, main_body_id: params.mainBodyId || this.mainBodyId, main_body_column_id: this.toStringArray(params.mainBodyColumnId || this.mainBodyColumnId), page, pageSize, ...querys, }); let resList : any = null; let resTotal : any = null; if (res.data?.list && Array.isArray(res.data.list)) { resList = res.data.list; resTotal = res.data.total ?? resList.length; } else if (res.data && Array.isArray(res.data)) { resList = res.data; resTotal = resList.length; } else resList = res.data; if (resList === null) return { list: [], total: 0 }; return { list: transformArrayDataModel(modelClassCreator, resList, `${this.debugName} 模型内容列表`, true), total: resTotal as number, }; } /** * 内容详情 * @param id id * @param querys 额外参数 * @returns */ async getContentDetail(id: number, modelClassCreator: NewDataModel = GetContentDetailItem, modelId?: number, querys?: QueryParams) { const res = await this.get('/content/content/getContentDetail', `${this.debugName} (${id}) 内容详情`, { main_body_id: this.mainBodyId, model_id: modelId ?? this.modelId, id, ...querys, }, modelClassCreator); return res.data as T; } /** * 获取可投稿栏目 * @returns */ async getContributeColumnList(querys?: QueryParams) { const res = await this.get('/content/main_body_column/getColumnList', `获取可投稿栏目`, { main_body_id: this.mainBodyId, model_id: 11, iscontribute: 1, ...querys, }, undefined); return res.data as unknown as GetColumContentList[]; } /** * 上传文件到服务器 */ async uploadFile(file: string, fileType?: "image" | "video" | "audio" | undefined, name = 'file', data?: any) { return new Promise<{ fullurl: string, url: string }>((resolve, reject) => { let url = this.config.baseUrl + '/common/upload'; let req : RequestOptions = { method: 'POST', data: data, headers: {}, } if (this.config.requestInterceptor) { const { newReq, newUrl } = this.config.requestInterceptor(url, req); url = newUrl; data = newReq; } console.log(url); uni.uploadFile({ url: url, name, header: req.headers, filePath: file, formData: data, fileType, success: (result) => { let data = JSON.parse(result.data); if (data.code !== 1) throw new Error(data.msg ?? 'code: ' + data.code); resolve(data.data); }, fail(result) { reject(result); }, }) }) } /** * 内容反馈 * @param data * @returns */ async feedBack(data: FeedBackItem) { return (this.post('/user/feedback', '内容反馈', data.toServerSide())); } } export default new CommonContentApi(undefined, 0, '默认通用内容');