import { DataModel, transformArrayDataModel, type KeyValue, type NewDataModel } from '@imengyu/js-request-transform'; import { AppServerRequestModule } from './RequestModules'; import ApiCofig from '@/common/config/ApiCofig'; import { transformSomeToArray } from './Utils'; import { assertNotNull, RequestApiConfig, RequestOptions, requireNotNull, type QueryParams } from '@imengyu/imengyu-utils'; 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: number|number[]) { 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; 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 } } } id = 0; from = ''; modelId = 0; modelName = ''; mainBodyColumnId = 0; mainBodyColumnName = ''; type = 0; title = ''; region = 0; image = ''; images = [] as string[]; audio = ''; video = ''; 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, }[]; 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; } 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, ) { return (this.get('/content/category/getCategoryList', '获取分类列表', { type, is_tree: false, withself, })) .then(res => transformArrayDataModel(CategoryListItem, res.data!, `获取分类列表`, true)) .catch(e => { throw e }); } /** * 用于获取某一个分类需要用的子级 * @param pid 父级 * @returns */ async getCategoryChildList(pid?: number) { return (this.get('/content/category/getCategoryOnlyChildList', '获取分类子级列表', { pid, })) .then(res => transformArrayDataModel( CategoryListItem, transformSomeToArray(res.data), `获取分类列表`, true )) .catch(e => { throw e }); } /** * 模型的主体栏目列表 * @param params 参数 * @param querys 额外参数 * @returns */ getModelColumList(model_id: number, page: number, pageSize: number = 10,querys?: QueryParams) { return this.get('/content/main_body_column/getColumnList', `${this.debugName} 模型的主体栏目列表`, { main_body_id: this.mainBodyId, model_id: model_id ?? this.modelId, page, pageSize, ...querys }) .then(res => transformArrayDataModel(GetModelColumContentList, res.data as any, `${this.debugName} 模型的主体栏目列表`, true)) .catch(e => { throw e }); } /** * 主体栏目列表 * @param params 参数 * @param querys 额外参数 * @returns */ getColumList(params: GetColumListParams, modelClassCreator: NewDataModel = GetColumContentList, querys?: QueryParams) { return this.get<{ list: T[], total: number }>('/content/content/getMainBodyColumnContentList', `${this.debugName} 主体栏目列表`, { main_body_id: this.mainBodyId, model_id: this.modelId, ...params.toServerSide(), ...querys, }) .then(res => ({ list: transformArrayDataModel(modelClassCreator, requireNotNull(res.data).list, `${this.debugName} 主体栏目列表`, true), total: requireNotNull(res.data).total as number, })) .catch(e => { throw e }); } /** * 模型内容列表 * @param params 参数 * @param page 页码 * @param pageSize 页大小 * @param querys 额外参数 * @returns */ getContentList(params: GetContentListParams, page: number, pageSize: number = 10, modelClassCreator: NewDataModel = GetContentListItem, querys?: QueryParams) { return 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, }) .then(res => { 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, } }) .catch(e => { throw e }); } /** * 内容详情 * @param id id * @param querys 额外参数 * @returns */ getContentDetail(id: number, modelClassCreator: NewDataModel = GetContentDetailItem, modelId?: number, querys?: QueryParams) { return this.get('/content/content/getContentDetail', `${this.debugName} (${id}) 内容详情`, { main_body_id: this.mainBodyId, model_id: modelId ?? this.modelId, id, ...querys, }, modelClassCreator) .then(res => res.data as T) .catch(e => { throw e }); } /** * 上传文件到服务器 */ async uploadFile(file: string, fileType?: "image" | "video" | "audio" | undefined, name = 'file', data?: any) { return new Promise<{ fullurl: string, url: string }>((resolve, reject) => { let url = RequestApiConfig.getConfig().BaseUrl + '/common/upload'; let req : RequestOptions = { method: 'POST', data: data, headers: {}, } if (this.config.requestInceptor) { const { newReq, newUrl } = this.config.requestInceptor(url, req); url = newUrl; data = newReq; } 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, '默认通用内容');