diff --git a/src/main/kotlin/controller/api/TagApiController.kt b/src/main/kotlin/controller/api/TagApiController.kt index 2c2621f..0388caf 100644 --- a/src/main/kotlin/controller/api/TagApiController.kt +++ b/src/main/kotlin/controller/api/TagApiController.kt @@ -67,4 +67,13 @@ tagService.deleteTagFromAudioList(slug, request) return ResponseEntity.ok(null) } + + @PutMapping("audio/{slug}") + fun updateAudioList( + @PathVariable("slug") slug: String, + @Valid @RequestBody request: TagAudioRequest + ): ResponseEntity { + tagService.updateTagAudioList(slug, request) + return ResponseEntity.ok(null) + } } \ No newline at end of file diff --git a/src/main/kotlin/dao/AudioDao.kt b/src/main/kotlin/dao/AudioDao.kt index 654dd5d..5fb32cf 100644 --- a/src/main/kotlin/dao/AudioDao.kt +++ b/src/main/kotlin/dao/AudioDao.kt @@ -143,7 +143,7 @@ .leftOuterJoin(AudioTagEntity::class, "audio.id = audio_tag.audio_id") .toSql() .WHERE_IN("audio_tag.tag_id", "tagIds", tagIds.size) - .ORDER_BY("audio.album_id, audio.sequence") + .ORDER_BY("audio_tag.tag_id, audio_tag.sequence") .toString() @JvmStatic diff --git a/src/main/kotlin/dao/AudioTagDao.kt b/src/main/kotlin/dao/AudioTagDao.kt index c85688b..b22e2ba 100644 --- a/src/main/kotlin/dao/AudioTagDao.kt +++ b/src/main/kotlin/dao/AudioTagDao.kt @@ -6,6 +6,7 @@ import net.piedpiper.bremer.entity.AudioTagEntity import net.piedpiper.bremer.utils.DaoUtils +import net.piedpiper.bremer.utils.WHERE_IN import org.apache.ibatis.annotations.* import org.springframework.stereotype.Repository @@ -15,14 +16,23 @@ @ResultMap("net.piedpiper.bremer.AudioTagEntity") @Select("SELECT * FROM audio_tag WHERE audio_id = #{audioId} AND tag_id = #{tagId}") - fun findByAudioIdAndTagId( + fun findOneByAudioIdAndTagId( @Param("audioId") audioId: Long, @Param("tagId") tagId: Long ): AudioTagEntity? + @ResultMap("net.piedpiper.bremer.AudioTagEntity") + @Select("SELECT * FROM audio_tag WHERE tag_id = #{tagId}") + fun findAllByTagId( + @Param("tagId") tagId: Long + ): List + @UpdateProvider(type = Sql::class, method = "insertOne") fun insertOne(@Param("entity") entity: AudioTagEntity): Boolean + @DeleteProvider(type = Sql::class, method = "deleteAllByIds") + fun deleteAllByIds(@Param("ids") ids: List) + @Delete("DELETE FROM audio_tag WHERE audio_id = #{audioId} AND tag_id = #{tagId}") fun deleteOneByAudioIdAndTagId( @Param("audioId") audioId: Long, @@ -35,6 +45,12 @@ @Options(useGeneratedKeys = true, keyColumn = "id") fun insertOne(@Param("entity") entity: AudioTagEntity): String = DaoUtils.insertOne(entity) + + @JvmStatic + fun deleteAllByIds(@Param("ids") ids: List): String = + DaoUtils.deleteQuery(AudioTagEntity::class) + .WHERE_IN("id", "ids", ids.size) + .toString() } } } \ No newline at end of file diff --git a/src/main/kotlin/entity/Entity.kt b/src/main/kotlin/entity/Entity.kt index ce6e7dc..d2e3136 100644 --- a/src/main/kotlin/entity/Entity.kt +++ b/src/main/kotlin/entity/Entity.kt @@ -64,7 +64,9 @@ @property:Column("audio_id") var audioId: Long = 0L, @property:Column("tag_id") - var tagId: Long = 0L + var tagId: Long = 0L, + @property:Column("sequence") + var sequence: Int = 0, ) @Table("user") diff --git a/src/main/kotlin/service/PlaylistService.kt b/src/main/kotlin/service/PlaylistService.kt index 5bd58b7..ae890eb 100644 --- a/src/main/kotlin/service/PlaylistService.kt +++ b/src/main/kotlin/service/PlaylistService.kt @@ -110,15 +110,15 @@ throw BadRequestException() } audioList.forEachIndexed { index, audio -> - val a = if (index < oldPlaylistAudioList.count()) { + val playlistAudio = if (index < oldPlaylistAudioList.count()) { oldPlaylistAudioList[index] } else { PlaylistAudioEntity() } - a.playlistId = playlist.id - a.sequence = index - a.audioId = audio.id - playlistAudioDao.insertOne(a) + playlistAudio.playlistId = playlist.id + playlistAudio.sequence = index + playlistAudio.audioId = audio.id + playlistAudioDao.insertOne(playlistAudio) } } ?: throw NotFoundException() } diff --git a/src/main/kotlin/service/TagService.kt b/src/main/kotlin/service/TagService.kt index c35c8cc..2e82e80 100644 --- a/src/main/kotlin/service/TagService.kt +++ b/src/main/kotlin/service/TagService.kt @@ -16,6 +16,7 @@ import net.piedpiper.bremer.model.api.AllTagsResponse import org.springframework.beans.factory.annotation.Qualifier import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional import java.util.* @Service("bremer.service.TagService") @@ -27,12 +28,15 @@ @Qualifier("bremer.dao.TagDao") private val tagDao: TagDao ) { + @Transactional fun getAllTags(): AllTagsResponse = AllTagsResponse(tagDao.findAll()) + @Transactional fun createTag(request: TagRequest) { tagDao.insertOne(TagEntity(slug = UUID.randomUUID().toString(), name = request.name)) } + @Transactional fun updateTag(tagSlug: String, request: TagRequest) { tagDao.findOneBySlugWithLock(tagSlug) ?.let { @@ -41,11 +45,13 @@ } ?: throw NotFoundException() } + @Transactional fun deleteTag(slug: String) = tagDao.findOneBySlugWithLock(slug) ?.let { tagDao.deleteById(it.id) } ?: throw NotFoundException() + @Transactional fun getAudioListByTagSlug(tagSlug: String): TagAudioResponse = tagDao.findOneBySlug(tagSlug) ?.let { tag -> @@ -55,12 +61,13 @@ ) } ?: throw NotFoundException() + @Transactional fun addTagToAudioList(tagSlug: String, request: TagAudioRequest) { tagDao.findOneBySlug(tagSlug) ?.let { tag -> audioDao.findAllBySlugIn(request.audioSlugs) .forEach { audio -> - if (audioTagDao.findByAudioIdAndTagId(audio.id, tag.id) != null) { + if (audioTagDao.findOneByAudioIdAndTagId(audio.id, tag.id) != null) { return@forEach } audioTagDao.insertOne( @@ -73,6 +80,34 @@ } ?: throw NotFoundException() } + @Transactional + fun updateTagAudioList(tagSlug: String, request: TagAudioRequest) { + + tagDao.findOneBySlug(tagSlug) + ?.let { tag -> + audioTagDao.deleteAllByIds(audioTagDao.findAllByTagId(tag.id) + .map { it.id }) + val audioMap = audioDao.findAllBySlugIn(request.audioSlugs).associateBy { + it.slug + } + request.audioSlugs + .forEachIndexed { index, slug -> + audioMap[slug]?.let { audio -> + if (audioTagDao.findOneByAudioIdAndTagId(audio.id, tag.id) != null) { + return@forEachIndexed + } + audioTagDao.insertOne( + AudioTagEntity( + audioId = audio.id, + tagId = tag.id, + sequence = index + ) + ) + } + } + } ?: throw NotFoundException() + } + fun deleteTagFromAudioList(tagSlug: String, request: TagAudioRequest) { tagDao.findOneBySlug(tagSlug) ?.let { tag ->