Ansichten verbessert - 1. Teil

This commit is contained in:
2024-03-17 20:29:53 +01:00
parent 25b201a9c6
commit 2b27ab8ba5
24 changed files with 322 additions and 108 deletions

View File

@@ -6,9 +6,14 @@ import { FileService } from '../file/file.service.js';
export class AccountController {
constructor(private fileService:FileService){}
@Post('uploadPhoto/:id')
@Post('uploadProfile/:id')
@UseInterceptors(FileInterceptor('file'),)
uploadFile(@UploadedFile() file: Express.Multer.File,@Param('id') id:string) {
this.fileService.storeFile(file,id);
uploadProfile(@UploadedFile() file: Express.Multer.File,@Param('id') id:string) {
this.fileService.storeProfilePicture(file,id);
}
@Post('uploadCompanyLogo/:id')
@UseInterceptors(FileInterceptor('file'),)
uploadCompanyLogo(@UploadedFile() file: Express.Multer.File,@Param('id') id:string) {
this.fileService.storeCompanyLogo(file,id);
}
}

View File

@@ -31,7 +31,7 @@ const __dirname = path.dirname(__filename);
@Module({
imports: [ConfigModule.forRoot(), MailModule, AuthModule,
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..', 'public'), // `public` ist das Verzeichnis, wo Ihre statischen Dateien liegen
rootPath: join(__dirname, '..', 'pictures'), // `public` ist das Verzeichnis, wo Ihre statischen Dateien liegen
}),
WinstonModule.forRoot({
transports: [

View File

@@ -4,6 +4,7 @@ import { join } from 'path';
import { fileURLToPath } from 'url';
import path from 'path';
import fs from 'fs-extra';
import { ImageProperty } from 'src/models/main.model.js';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
@@ -13,6 +14,10 @@ export class FileService {
private subscriptions: any;
constructor() {
this.loadSubscriptions();
fs.ensureDirSync(`./pictures`);
fs.ensureDirSync(`./pictures/profile`);
fs.ensureDirSync(`./pictures/logo`);
fs.ensureDirSync(`./pictures/property`);
}
private loadSubscriptions(): void {
const filePath = join(__dirname,'..', 'assets', 'subscriptions.json');
@@ -22,8 +27,49 @@ export class FileService {
getSubscriptions() {
return this.subscriptions
}
async storeFile(file: Express.Multer.File,id: string){
async storeProfilePicture(file: Express.Multer.File,userId: string){
const suffix = file.mimetype.includes('png')?'png':'jpg'
await fs.outputFile(`./public/profile_${id}`,file.buffer);
await fs.outputFile(`./pictures/profile/${userId}`,file.buffer);
}
async storeCompanyLogo(file: Express.Multer.File,userId: string){
const suffix = file.mimetype.includes('png')?'png':'jpg'
await fs.outputFile(`./pictures/logo/${userId}`,file.buffer);
}
async getPropertyImages(listingId: string):Promise<ImageProperty[]>{
const result:ImageProperty[]=[]
const directory = `./pictures/property/${listingId}`
if (fs.existsSync(directory)){
const files = await fs.readdir(directory);
files.forEach(f=>{
const image:ImageProperty={name:f,id:'',code:''};
result.push(image)
})
return result;
} else {
return []
}
}
async storePropertyPicture(file: Express.Multer.File,listingId: string){
const suffix = file.mimetype.includes('png')?'png':'jpg'
const directory = `./pictures/property/${listingId}`
fs.ensureDirSync(`${directory}`);
const imageName = await this.getNextImageName(directory);
await fs.outputFile(`${directory}/${imageName}`,file.buffer);
}
async getNextImageName(directory) {
try {
const files = await fs.readdir(directory);
const imageNumbers = files
.map(file => parseInt(file, 10)) // Dateinamen direkt in Zahlen umwandeln
.filter(number => !isNaN(number)) // Sicherstellen, dass die Konvertierung gültig ist
.sort((a, b) => a - b); // Aufsteigend sortieren
const nextNumber = imageNumbers.length > 0 ? Math.max(...imageNumbers) + 1 : 1;
return `${nextNumber}`; // Keine Endung für den Dateinamen
} catch (error) {
console.error('Fehler beim Lesen des Verzeichnisses:', error);
return null;
}
}
}

View File

@@ -0,0 +1,21 @@
import { Body, Controller, Delete, Get, Inject, Param, Post, Put } from '@nestjs/common';
import { FileService } from '../file/file.service.js';
import { convertStringToNullUndefined } from '../utils.js';
import { ListingsService } from './listings.service.js';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { Logger } from 'winston';
import { UserService } from '../user/user.service.js';
@Controller('listings/professionals_brokers')
export class BrokerListingsController {
constructor(private readonly userService:UserService,@Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger) {
}
@Post('search')
find(@Body() criteria: any): any {
return this.userService.findUser(criteria);
}
}

View File

@@ -5,7 +5,7 @@ import { ListingsService } from './listings.service.js';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { Logger } from 'winston';
@Controller('business-listings')
@Controller('listings/business')
export class BusinessListingsController {
constructor(private readonly listingsService:ListingsService,@Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger) {

View File

@@ -1,12 +1,14 @@
import { Body, Controller, Delete, Get, Inject, Param, Post } from '@nestjs/common';
import { Body, Controller, Delete, Get, Inject, Param, Post, UploadedFile, UseInterceptors } from '@nestjs/common';
import { ListingsService } from './listings.service.js';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { Logger } from 'winston';
import { FileInterceptor } from '@nestjs/platform-express';
import { FileService } from '../file/file.service.js';
@Controller('commercial-property-listings')
@Controller('listings/commercialProperty')
export class CommercialPropertyListingsController {
constructor(private readonly listingsService:ListingsService,@Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger) {
constructor(private readonly listingsService:ListingsService,private fileService:FileService,@Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger) {
}
@Get()
@@ -40,5 +42,15 @@ export class CommercialPropertyListingsController {
deleteById(@Param('id') id:string){
this.listingsService.deleteCommercialPropertyListing(id)
}
@Post('uploadPropertyPicture/:id')
@UseInterceptors(FileInterceptor('file'),)
uploadFile(@UploadedFile() file: Express.Multer.File,@Param('id') id:string) {
this.fileService.storePropertyPicture(file,id);
}
@Get('images/:id')
getPropertyImagesById(@Param('id') id:string): any {
return this.fileService.getPropertyImages(id);
}
}

View File

@@ -3,10 +3,15 @@ import { BusinessListingsController } from './business-listings.controller.js';
import { ListingsService } from './listings.service.js';
import { CommercialPropertyListingsController } from './commercial-property-listings.controller.js';
import { RedisModule } from '../redis/redis.module.js';
import { FileService } from '../file/file.service.js';
import { UnknownListingsController } from './unknown-listings.controller.js';
import { UserModule } from '../user/user.module.js';
import { BrokerListingsController } from './broker-listings.controller.js';
import { UserService } from '../user/user.service.js';
@Module({
imports: [RedisModule],
controllers: [BusinessListingsController, CommercialPropertyListingsController],
providers: [ListingsService]
controllers: [BusinessListingsController, CommercialPropertyListingsController,UnknownListingsController,BrokerListingsController],
providers: [ListingsService,FileService,UserService]
})
export class ListingsModule {}

View File

@@ -67,6 +67,7 @@ export class ListingsService {
async saveListing(listing: BusinessListing | CommercialPropertyListing) {
const repo=listing.listingsCategory==='business'?this.businessListingRepository:this.commercialPropertyListingRepository;
let result
listing.temporary=false;
if (listing.id){
result = await repo.save(listing.id,listing as any)
} else {

View File

@@ -0,0 +1,26 @@
import { Body, Controller, Delete, Get, Inject, Param, Post, Put } from '@nestjs/common';
import { FileService } from '../file/file.service.js';
import { convertStringToNullUndefined } from '../utils.js';
import { ListingsService } from './listings.service.js';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { Logger } from 'winston';
@Controller('listings/undefined')
export class UnknownListingsController {
constructor(private readonly listingsService:ListingsService,@Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger) {
}
@Get(':id')
async findById(@Param('id') id:string): Promise<any> {
const result = await this.listingsService.getBusinessListingById(id);
if (result.id){
return result
} else {
return await this.listingsService.getCommercialPropertyListingById(id);
}
}
}

View File

@@ -12,6 +12,7 @@ export class SelectOptionsController {
listingCategories:this.selectOptionsService.listingCategories,
categories:this.selectOptionsService.categories,
locations:this.selectOptionsService.locations,
typesOfCommercialProperty:this.selectOptionsService.typesOfCommercialProperty,
}
}
}

View File

@@ -20,6 +20,15 @@ export class SelectOptionsService {
{ name: 'Manufacturing', value: '12' , icon:'fa-solid fa-industry',bgColorClass:'bg-red-100',textColorClass:'text-red-600'},
{ name: 'Food and Restaurant', value: '13' , icon:'fa-solid fa-utensils',bgColorClass:'bg-primary-100',textColorClass:'text-primary-600'},
];
public typesOfCommercialProperty: Array<KeyValueStyle> = [
{ name: 'Retail', value: '100' , icon:'fa-solid fa-money-bill-wave',bgColorClass:'bg-pink-100',textColorClass:'text-pink-600'},
{ name: 'Land', value: '101' , icon:'pi pi-building',bgColorClass:'bg-blue-100',textColorClass:'text-blue-600'},
{ name: 'Industrial', value: '102', icon:'fa-solid fa-industry',bgColorClass:'bg-yellow-100',textColorClass:'text-yellow-600'},
{ name: 'Office', value: '103' , icon:'fa-solid fa-umbrella',bgColorClass:'bg-teal-100',textColorClass:'text-teal-600'},
{ name: 'Mixed Use', value: '104' , icon:'fa-solid fa-rectangle-ad',bgColorClass:'bg-orange-100',textColorClass:'text-orange-600'},
{ name: 'Multifamily', value: '105' , icon:'pi pi-star',bgColorClass:'bg-purple-100',textColorClass:'text-purple-600'},
{ name: 'Uncategorized', value: '106' , icon:'pi pi-question',bgColorClass:'bg-cyan-100',textColorClass:'text-cyan-600'},
];
public prices: Array<KeyValue> = [
{ name: '$100K', value: '100000' },
{ name: '$250K', value: '250000' },

View File

@@ -1,7 +1,7 @@
import { Get, Inject, Injectable, Param } from '@nestjs/common';
import { createClient } from 'redis';
import { Entity, Repository, Schema } from 'redis-om';
import { User } from '../models/main.model.js';
import { ListingCriteria, User } from '../models/main.model.js';
import { REDIS_CLIENT } from '../redis/redis.module.js';
import { UserEntity } from '../models/server.model.js';
@@ -26,6 +26,7 @@ export class UserService {
})
constructor(@Inject(REDIS_CLIENT) private readonly redis: any){
this.userRepository = new Repository(this.userSchema, redis)
this.userRepository.createIndex();
}
async getUserById( id:string){
return await this.userRepository.fetch(id);
@@ -33,5 +34,8 @@ export class UserService {
async saveUser(user:any):Promise<UserEntity>{
return await this.userRepository.save(user.id,user) as UserEntity
}
async findUser(criteria:ListingCriteria){
return await this.userRepository.search().return.all();
}
}