<reponame>527088995/mblog<filename>web/src/main/java/mblog/web/controller/site/posts/PostController.java
/**
 *
 */
package mblog.web.controller.site.posts;

import com.alibaba.fastjson.JSON;
import mblog.base.data.Data;
import mblog.base.lang.Consts;
import mblog.ds.rabbitConfig.RabbitConfig;
import mblog.modules.blog.data.PostVO;
import mblog.modules.blog.service.ArticleTypeService;
import mblog.modules.blog.service.BlogClassService;
import mblog.modules.blog.service.ChannelService;
import mblog.modules.blog.service.PostService;
import mblog.modules.user.data.AccountProfile;
import mblog.util.JacksonUtil;
import mblog.web.controller.BaseController;
import mblog.web.controller.site.Views;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;

/**
 * 文章操作
 * @author langhsu
 *
 */
@Controller
@RequestMapping("/post")
public class PostController extends BaseController {

    private final Logger logger = LoggerFactory.getLogger(PostController.class);


    @Autowired
    private PostService postService;
    @Autowired
    private ChannelService channelService;
    @Autowired
    private BlogClassService blogClassService;
    @Autowired
    private ArticleTypeService articleTypeService;

    @Resource
    private RabbitTemplate rabbitTemplate;

    /**
     * 发布文章页
     * @return
     */
    @GetMapping("/editing")
    public String view(Long id, ModelMap model) {
        model.put("channels", channelService.findAll(Consts.STATUS_NORMAL));
        model.put("blogClasss", blogClassService.findAll(Consts.STATUS_NORMAL));
        model.put("articleTypes", articleTypeService.findAll(Consts.STATUS_NORMAL));

        if (null != id && id > 0) {
            AccountProfile profile = getSubject().getProfile();
            PostVO view = postService.get(id);

            Assert.notNull(view, "该文章已被删除");
            Assert.isTrue(view.getAuthorId() == profile.getId(), "该文章不属于你");
            model.put("view", view);
        }

        model.put("channels", channelService.findAll(Consts.STATUS_NORMAL));
        return view(Views.ROUTE_POST_EDITING);
    }

    /**
     * 提交发布
     * @param post
     * @return
     */
    @PostMapping("/submit")
    public String post(PostVO post, @RequestParam(value = "file", required = false) MultipartFile file) throws IOException {
        Assert.notNull(post, "参数不完整");
        Assert.state(StringUtils.isNotBlank(post.getTitle()), "标题不能为空");
        Assert.state(StringUtils.isNotBlank(post.getContent()), "内容不能为空");

        AccountProfile profile = getSubject().getProfile();
        post.setAuthorId(profile.getId());
        post.setAuthorName(profile.getName());

        /**
         * 保存预览图片
         */
        if (file != null && !file.isEmpty()) {
            String thumbnail = fileRepo.store(file, appContext.getThumbsDir());

            if (StringUtils.isNotBlank(post.getThumbnail())) {
                fileRepo.deleteFile(post.getThumbnail());
            }

            post.setThumbnail(thumbnail);
        }

        // 修改时, 验证归属
        if (post.getId() > 0) {
            PostVO exist = postService.get(post.getId());
            Assert.notNull(exist, "文章不存在");
            Assert.isTrue(exist.getAuthorId() == profile.getId(), "该文章不属于你");

            postService.update(post);
        } else {
            this.convertAndSend(RabbitConfig.EXCHANGE_B, RabbitConfig.ROUTINGKEY_B,
                    JacksonUtil.toJson(post));

            //postService.post(post);
        }
        return Views.REDIRECT_USER_POSTS;
    }

    /**
     * 发送消息
     *
     * @param exchange        交换机名称
     * @param routingKey      路由key
     * @param message         消息内容
     * @throws AmqpException
     */
    private void convertAndSend(String exchange, String routingKey, final Object message) throws AmqpException {
        try {
            rabbitTemplate.convertAndSend(exchange, routingKey, message);
        } catch (Exception e) {
            logger.error("MQ消息发送异常，消息ID：{}，消息体:{}, exchangeName:{}, routingKey:{}",
                    JSON.toJSONString(message), exchange, routingKey, e);
            // TODO 保存消息到数据库
        }
    }

    /**
     * 删除文章
     * @param id
     * @return
     */
    @RequestMapping("/delete/{id}")
    public @ResponseBody
    Data delete(@PathVariable Long id) {
        Data data = Data.failure("操作失败");
        if (id != null) {
            AccountProfile up = getSubject().getProfile();
            try {
                postService.delete(id, up.getId());
                data = Data.success("操作成功", Data.NOOP);
            } catch (Exception e) {
                data = Data.failure(e.getMessage());
            }
        }
        return data;
    }

}
