基于SpringBoot 2.x后臺管理系統(tǒng)

此項目地址已在碼云上咖刃,地址:https://gitee.com/youxiaxiaomage/jfl-platform-parent
此項目主要使用了Druid泳炉,MyBatis-Plusredis嚎杨,dubbo花鹅,shiroSpringMVC枫浙,thymeleaf刨肃,layUIBootstrap后臺管理系統(tǒng)箩帚,以及相應的restful接口真友。
1.基類實體類(BaseModel

@Data
public abstract class BaseModel implements Serializable
{
    /**
     * id
     */
    @JsonSerialize(using=ToStringSerializer.class)
    @TableId(value = "id", type = IdType.ID_WORKER)
    private Long id;
    
    /**
     * 狀態(tài)
     */
    @TableField("enable")
    public Integer enable;
    
    /**
     * 備注
     */
    @TableField("remark")
    private String remark;
    
    /**
     * 創(chuàng)建人
     */
    @TableField("create_by")
    private Long createBy;
    
    /**
     * 創(chuàng)建時間
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone="GMT+8")
    @TableField("create_time")
    private Date createTime;
    
    /**
     * 更新時間
     */
    @TableField("update_by")
    private Long updateBy;
    
    /**
     * 更新時間
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone="GMT+8")
    @TableField("update_time")
    private Date updateTime;
    
    /** 請求參數(shù) */
    @TableField(exist=false)
    private Map<String, Object> params;
    
}

此基類實體類主要是基于Mybatis-Plus插件,表名定義紧帕,字段定義都使用了該方式盔然。其中,主鍵id使用長整型是嗜,其長度為20位愈案,頁面展示時,精度會丟失鹅搪,因此該字段序列化為字符串返回站绪。
這些字段都是在定義表時,必須包含的字段丽柿,其中請求參數(shù)params用于接收前端的參數(shù)恢准,非數(shù)據(jù)庫字段。
2.基類Mapper(BaseMapper

public interface BaseMapper<T extends BaseModel> extends com.baomidou.mybatisplus.core.mapper.BaseMapper<T>
{
    List<Long> selectIdPage(@Param("cm") T paramT);
    
    List<Long> selectIdPage(@Param("cm") Map<String, Object> paramMap);
    
    List<Long> selectIdPage(RowBounds paramRowBounds, @Param("cm") Map<String, Object> paramMap);
    
    List<Long> selectIdPage(RowBounds paramRowBounds, @Param("cm") T paramT);
    
    List<T> selectPage(RowBounds paramRowBounds, @Param("cm") Map<String, Object> paramMap);
    
    Integer selectCount(@Param("cm") Map<String, Object> paramMap);
}

分頁重寫了mybatisplusBaseMapper甫题,其中列出的方法需要在***Mapper.xml中實現(xiàn)顷歌,具體參見對應的xml文件。
3.基類Service(BaseService

public interface BaseService<T extends BaseModel> extends IService<T>
{
    /** 
     * 修改
     * @param record
     * @param userId
     * @return
     * @throws BusinessException
     * @throws ValidateException
     * @see [類幔睬、類#方法眯漩、類#成員]
     */
    @Transactional
    T update(T record) throws BusinessException, ValidateException;
    
    /** 
     * 邏輯刪除
     * @param ids 刪除的id
     * @param userId 用戶id
     * @throws BusinessException
     * @throws ValidateException
     * @see [類、類#方法麻顶、類#成員]
     */
    @Transactional
    void del(List<Long> ids, Long userId) throws BusinessException, ValidateException;
    
    /** 
     * 邏輯刪除單條
     * @param id
     * @param userId
     * @throws BusinessException
     * @throws ValidateException
     * @see [類赦抖、類#方法、類#成員]
     */
    @Transactional
     void del(Long id, Long userId)  throws BusinessException, ValidateException;
    
    /** 
     * 物理刪除
     * @param id
     * @throws BusinessException
     * @throws ValidateException
     * @see [類辅肾、類#方法队萤、類#成員]
     */
    @Transactional
     void delete(Long id) throws BusinessException, ValidateException;
    
    /** 
     * 物理刪除
     * @param entity
     * @return
     * @throws BusinessException
     * @throws ValidateException
     * @see [類、類#方法矫钓、類#成員]
     */
    @Transactional
     Integer deleteByEntity(T entity) throws BusinessException, ValidateException;
    
    /** 
     * 物理刪除
     * @param columnMap
     * @return
     * @throws BusinessException
     * @throws ValidateException
     * @see [類要尔、類#方法舍杜、類#成員]
     */
    @Transactional
     Integer deleteByMap(Map<String, Object> columnMap) throws BusinessException, ValidateException;
      ...
}

此類中部分方法未列舉。
4.基類Service實現(xiàn)類(BaseServiceImpl

public class BaseServiceImpl<T extends BaseModel, M extends BaseMapper<T>> extends ServiceImpl<BaseMapper<T>, T> implements BaseService<T>
{
    /**
     * logger 日志
     */
    protected Logger logger = LoggerFactory.getLogger(getClass());
    
    /**
     * mapper
     */
    @Autowired
    protected M mapper;
    

    @Transactional
    @Override
    public T update(T record) throws BusinessException, ValidateException
    {
        if (record.getId() != null)
        {
          record.setUpdateTime(new Date());
          this.mapper.updateById(record);  
        }
        else
        {
            record.setCreateTime(new Date());
            record.setUpdateTime(new Date());
            record.setUpdateBy(record.getCreateBy());
            this.mapper.insert(record);
        }
        return this.mapper.selectById(record.getId());
    }

    /**
     * 邏輯刪除
     * @param ids
     * @param userId
     * @throws BusinessException
     * @throws ValidateException
     * @see com.jfl.base.BaseService#del(java.util.List, java.lang.Long)
     */
    @Override
    @Transactional
    public void del(List<Long> ids, Long userId) throws BusinessException, ValidateException
    {
        // lamda表達式 JDK1.8才支持
        ids.forEach(id -> del(id, userId));
    }

    /**
     * 邏輯刪除
     * @param id
     * @param userId
     * @throws BusinessException
     * @throws ValidateException
     * @see com.jfl.base.BaseService#del(java.lang.Long, java.lang.Long)
     */
    @Override
    @Transactional
    public void del(Long id, Long userId) throws BusinessException, ValidateException
    {
        try
        {
            T record = this.queryById(id);
            record.setEnable(0);
            record.setUpdateBy(userId);
            record.setUpdateTime(new Date());
            this.mapper.updateById(record);
        }
        catch (Exception e)
        {
           throw new RuntimeException(e.getMessage(), e);
        }
        
    }

    /**
     * 物理刪除
     * @param id
     * @throws BusinessException
     * @throws ValidateException
     * @see com.jfl.base.BaseService#delete(java.lang.Long)
     */
    @Override
    @Transactional
    public void delete(Long id) throws BusinessException, ValidateException
    {
        try
        {
            this.mapper.deleteById(id);
        }
        catch (Exception e)
        {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    /**
     * 物理刪除
     * @param entity
     * @return
     * @throws BusinessException
     * @throws ValidateException
     * @see com.jfl.base.BaseService#deleteByEntity(com.jfl.base.BaseModel)
     */
    @Override
    @Transactional
    public Integer deleteByEntity(T entity) throws BusinessException, ValidateException
    {
        Wrapper<T> wrapper = new UpdateWrapper<T>(entity);
        return this.mapper.delete(wrapper);
    }

    /**
     * 物理刪除
     * @param columnMap
     * @return
     * @throws BusinessException
     * @throws ValidateException
     * @see com.jfl.base.BaseService#deleteByMap(java.util.Map)
     */
    @Override
    @Transactional
    public Integer deleteByMap(Map<String, Object> columnMap) throws BusinessException, ValidateException
    {
        return this.mapper.deleteByMap(columnMap);
    }

    /**
     * 根據(jù)Id查詢
     * @param id
     * @return
     * @see com.jfl.base.BaseService#queryById(java.lang.Long)
     */
    @Override
    public T queryById(Long id)
    {   
        return this.mapper.selectById(id);
    }

    /**
     * 分頁查詢
     * @param params 其中params必須為數(shù)據(jù)庫中字段
     * @return
     * @see com.jfl.base.BaseService#query(java.util.Map)
     */
    @Override
    public PageInfo<T> query(Map<String, Object> params)
    {
        // 默認當前頁為1
        int pageNum = 1;
        // 默認頁碼大小為10
        int pageSize = 10;
        // 默認計算count
        String orderBy = null;
        if(params.get("pageNum") != null && StringUtils.isNotBlank(params.get("pageNum") + ""))
        {
            pageNum = Integer.valueOf(params.get("pageNum").toString());
            params.remove("pageNum");
        }
        if(params.get("pageSize") != null && StringUtils.isNotBlank(params.get("pageSize") + ""))
        {
            pageSize = Integer.valueOf(params.get("pageSize").toString());
            params.remove("pageSize");
        }
        if(params.get("orderBy")!= null && StringUtils.isNotBlank(params.get("orderBy") + ""))
        {
            orderBy = params.get("orderBy").toString();
            params.remove("orderBy");
        }
        // 設置分頁的參數(shù)
        PageHelper.startPage(pageNum, pageSize, orderBy);
        // 有效數(shù)據(jù)
        params.put("enable", 1);
        // 根據(jù)條件查詢
        List<T> list = this.mapper.selectByMap(params);
        // 分裝成分頁對象
        return new PageInfo<T>(list);
    }

    /**
     * 根據(jù)實體參數(shù)分頁查詢
     * @param entity
     * @param rowBounds
     * @return
     * @see com.jfl.base.BaseService#query(com.jfl.base.BaseModel, com.github.pagehelper.PageInfo)
     */
    @Override
    public PageInfo<T> query(T entity, PageInfo<T> rowBounds)
    {
        Page<T> page = new Page<T>();
        try
        {
            BeanUtils.copyProperties(page, rowBounds);
        }
        catch (Exception e)
        {
          logger.error(ExceptionUtil.getStackTraceAsString(e));
        }
        // List<Long> ids = this.mapper.selectIdPage(page,entity);
        return new PageInfo<T>(null);
    }

    /**
     * 根據(jù)參數(shù)查詢
     * @param params
     * @return
     * @see com.jfl.base.BaseService#queryList(java.util.Map)
     */
    @Override
    public List<T> queryList(Map<String, Object> params)
    {
        // 根據(jù)參數(shù)獲取全部數(shù)據(jù)的Id 從DB中查詢
        List<Long> ids = this.mapper.selectIdPage(params);
        List<T> list = queryList(ids);
        return list;
    }

    /**
     * 根據(jù)Id查詢 如果緩存中有則從緩存中獲取赵辕,否則從DB中獲取
     * @param ids
     * @return
     * @see com.jfl.base.BaseService#queryList(java.util.List)
     */
    @Override
    public List<T> queryList(List<Long> ids)
    {
        final List<T> list = Lists.newArrayList();
        if (ids != null)
        {
            // lamda表達式
            ids.forEach(id -> list.add(queryById(id)));
        }
        return list;
    }

    @Override
    public <K> List<K> queryList(List<Long> ids, Class<K> clazz)
    {
        final List<K> list = Lists.newArrayList();
        if(ids != null)
        {
            for (int i = 0; i < ids.size(); i++)
            {
                T t = queryById(ids.get(i));
                K k = InstanceUtil.to(t, clazz);
                list.set(i, k);
            }
        }
        return list;
    }

    /**
     * 根據(jù)實體參數(shù)查詢
     * @param entity
     * @return
     * @see com.jfl.base.BaseService#queryList(com.jfl.base.BaseModel)
     */
    @Override
    public List<T> queryList(T entity)
    {
        // 先查出所有有關的id
        List<Long> ids = this.mapper.selectIdPage(entity);
        // 緩存中有則從緩存中取值既绩,否則從數(shù)據(jù)庫取值
        List<T> list = queryList(ids);
        return list;
    }

    /**
     * 從數(shù)據(jù)庫中查詢
     * @param params
     * @return
     * @see com.jfl.base.BaseService#queryFromDB(java.util.Map)
     */
    @Override
    public PageInfo<T> queryFromDB(Map<String, Object> params)
    {
        
        return null;
    }

    @Override
    public PageInfo<T> queryFromDB(T entity, PageInfo<T> rowBounds)
    {
        return null;
    }

    /**
     * 從數(shù)據(jù)庫中查詢
     * @param params 表字段
     * @return
     * @see com.jfl.base.BaseService#queryListFromDB(java.util.Map)
     */
    @Override
    public List<T> queryListFromDB(Map<String, Object> params)
    {
        return this.mapper.selectByMap(params);
    }

    @Override
    public PageInfo<T> selectList(PageRequest request, T record)
    {
        PageHelper.startPage(request.getPageNum(), request.getPageSize(), request.getOrderBy());
        QueryWrapper<T> wrapper = new QueryWrapper<T>();
        if (record != null)
        {
            wrapper = tranform(record);
            if(record.getParams() != null)
            {
                if(StringUtils.isNotBlank(record.getParams().get("beginTime") + "") && StringUtils.isNotBlank(record.getParams().get("endTime") + ""))
                {
                    wrapper.between("create_time", record.getParams().get("beginTime") , record.getParams().get("endTime"));
                }
            }
            
        }
        wrapper.eq("enable", 1);
        List<T> list = this.mapper.selectList(wrapper);
        return new PageInfo<T>(list);
    }

    /** 
     * 轉(zhuǎn)換查詢
     * @param record
     * @return
     * @see [類、類#方法还惠、類#成員]
     */
    private QueryWrapper<T> tranform(T record)
    {
        QueryWrapper<T> wrapper = new QueryWrapper<T>();
        Field[] fields = record.getClass().getDeclaredFields();
        try
        {
            for (Field field : fields)
            {
                field.setAccessible(true);
                String fieldName = field.getName();
                String clazz = field.getType().getTypeName();
                Method method = record.getClass().getDeclaredMethod("get"+ fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1));
                Object obj = method.invoke(record);
                if(obj != null && StringUtils.isNotBlank(obj + ""))
                {
                    if ("java.lang.String".equals(clazz))
                    {
        
                        if("status".equals(fieldName))
                        {
                            wrapper.eq(ConvertUtil.underLine2Camel(fieldName), obj);
                        } 
                        else
                        {
                            wrapper.like(ConvertUtil.underLine2Camel(fieldName), obj);
                        }
                    }
                    else if ("java.lang.Integer".equals(clazz) || "java.lang.Short".equals(clazz) || "java.lang.Long".equals(clazz))
                    {
                        wrapper.eq(ConvertUtil.underLine2Camel(fieldName), obj);
                    } 
                }

                
            }
        }
        catch (Exception e)
        {
            logger.error("轉(zhuǎn)換異常", e);
        }

        return wrapper;
    }
    
    /** 
     * 唯一性統(tǒng)一返回
     * @param record 參數(shù)對象
     * @param id 數(shù)據(jù)庫中數(shù)據(jù)Id
     * @return "0":存在  "1":唯一
     */
    public String result(T record, Long id)
    {
      
        if(record != null && record.getId().longValue() != id.longValue())
        {
            return Constants.DATA_NOT_UNIQUE;
        }
        return Constants.DATA_UNIQUE;
    }

}

主要注意分頁動態(tài)sql的拼接問題饲握,比如精確查詢,模糊查詢等蚕键,這個也可以轉(zhuǎn)化為動態(tài)***Mapper.xml文件救欧。
5.控制器

@Controller
@RequestMapping("${jfl.module.system}/user")
public class SysUserController extends AbstractController
{
    /**
     * dubbo接口 @Reference 通過配置文件連接服務
     */
    @Reference(version = "${jfl.version}")
    private SysUserService sysUserService;
    
    @Reference(version = "${jfl.version}")
    private SysDeptService sysDeptService;
    
    @Reference(version = "${jfl.version}")
    private SysRoleService sysRoleService;
    
    @Reference(version = "${jfl.version}")
    private SysPostService sysPostService;
    
    /**
     * 分隔符
     */
    private static final String SEG_CHAR = ",";
    /**
     * 用戶管理界面
     * 
     * @param modelMap
     * @return
     */
    @RequiresPermissions("system:user:view")
    @GetMapping
    public String user(ModelMap modelMap)
    {
        modelMap.put("user", ShiroUtils.getCurrentUser());
        return Constants.MODULE_SYS_USER_PREFIX + "user";
    }
    
    /**
     * 跳轉(zhuǎn)用戶添加頁面
     * 
     * @param modelMap
     * @return
     */
    @GetMapping("/add")
    public String add(ModelMap modelMap)
    {
        modelMap.put("roles", this.sysRoleService.queryList(Maps.newHashMap()));
        modelMap.put("posts", this.sysPostService.queryList(Maps.newHashMap()));
        return Constants.MODULE_SYS_USER_PREFIX + "add";
    }
    
    /**
     * 添加用戶
     * 
     * @param user
     * @return
     */
    @Log(module = Module.ROLE, value = "添加用戶", type = LogType.INSERT)
    @RequiresPermissions("system:user:add")
    @PostMapping("/add")
    @ResponseBody
    public ResponseEntity<ModelMap> addSave(SysUser user)
    {
        user.setSalt(EncryptUtils.randomSalt());
        user.setPassword(EncryptUtils.encryptPassword(user.getUserName(), user.getPassword(), user.getSalt()));
        user.setCreateBy(ShiroUtils.getCurrentUserId());
        this.sysUserService.saveUser(user);
        return setSuccessModelMap();
    }
    
    /**
     * 分頁查詢
     * 
     * @param sysUser
     * @return
     * @see [類、類#方法锣光、類#成員]
     */
    @RequiresPermissions("system:user:list")
    @PostMapping("/list")
    @ResponseBody
    public ResponseEntity<ModelMap> list(SysUser sysUser)
    {
        PageInfo<SysUser> pageInfo = this.sysUserService.selectList(ConvertRequestUtil.pageRequest(), sysUser);
        return setSuccessModelMap(pageInfo);
    }
    
    /**
     * 跳轉(zhuǎn)用戶編輯頁面
     * 
     * @param userId
     * @param modelMap
     * @return
     */
    @GetMapping("/edit/{userId}")
    public String edit(@PathVariable("userId") Long userId, ModelMap modelMap)
    {
        modelMap.put("user", this.sysUserService.queryById(userId));
        modelMap.put("roles", this.sysRoleService.selectRolesByUserId(userId));
        modelMap.put("posts", this.sysPostService.selectPostsByUserId(userId));
        return Constants.MODULE_SYS_USER_PREFIX + "edit";
    }
    
    /**
     * 修改保存用戶
     * 
     * @param user
     * @return
     */
    @Log(module = Module.ROLE, value = "修改用戶", type = LogType.UPDATE)
    @RequiresPermissions("system:user:edit")
    @PostMapping("/edit")
    @ResponseBody
    public ResponseEntity<ModelMap> editSave(SysUser user)
    {
        if (user.getId() != null && user.getId().longValue() == 1)
        {
            throw new BusinessException("管理員用戶笆怠,不支持修改!");
        }
        return setSuccessModelMap(this.sysUserService.updateUser(user));
    }
    
    /**
     * 跳轉(zhuǎn)用戶重置密碼頁面
     * 
     * @param userId
     * @param modelMap
     * @return
     */
    @RequiresPermissions("system:user:resetPwd")
    @GetMapping("/resetPwd/{userId}")
    public String resetPwd(@PathVariable("userId") Long userId, ModelMap modelMap)
    {
        modelMap.put("user", this.sysUserService.queryById(userId));
        return Constants.MODULE_SYS_USER_PREFIX + "resetPwd";
    }
    
    /**
     * 保存密碼操作
     * 
     * @param user
     * @return
     */
    @Log(module = Module.ROLE, value = "修改密碼", type = LogType.UPDATE)
    @RequiresPermissions("system:user:resetPwd")
    @PostMapping("/resetPwd")
    @ResponseBody
    public ResponseEntity<ModelMap> resetPwdSave(SysUser user)
    {
        // 密碼加密
        user.setSalt(EncryptUtils.randomSalt());
        user.setPassword(EncryptUtils.encryptPassword(user.getUserName(), user.getPassword(), user.getSalt()));
        this.sysUserService.update(user);
        return setSuccessModelMap();
    }
    
    /**
     * 刪除用戶 支持批量刪除
     * 
     * @param ids
     * @return
     */
    @Log(module = Module.ROLE, value = "刪除用戶", type = LogType.DELETE)
    @RequiresPermissions("system:user:remove")
    @PostMapping("/remove")
    @ResponseBody
    public ResponseEntity<ModelMap> remove(String ids)
    {
        String[] idAttr = ids.split(SEG_CHAR);
        List<Long> list = Lists.newArrayList();
        for (String id : idAttr)
        {
            list.add(Long.valueOf(id));
        }
        // 邏輯刪除
        this.sysUserService.deleteUsers(list, ShiroUtils.getCurrentUserId());
        return setSuccessModelMap();
    }
    
    /**
     * 校驗用戶名是否重復
     * 
     * @param user
     * @return
     */
    @PostMapping("/checkUserNameUnique")
    @ResponseBody
    public String checkUserNameUnique(SysUser user)
    {
        return String.valueOf(this.sysUserService.countByUserName(user));
    }
    
    /**
     * 校驗郵箱是否重復
     * 
     * @param user
     * @return
     */
    @PostMapping("/checkEmailUnique")
    @ResponseBody
    public String checkEmailUnique(SysUser user)
    {
        return this.sysUserService.countByEmail(user);
    }
    
    /**
     * 校驗郵箱是否重復
     * 
     * @param user
     * @return
     */
    @PostMapping("/checkPhoneUnique")
    @ResponseBody
    public String checkPhoneUnique(SysUser user)
    {
        return this.sysUserService.countByPhone(user);
    }
    
}

上述以系統(tǒng)用戶控制器為例子誊爹,其中Service都是dubbo的接口骑疆。注意shiro權限的配置以及日志的配置。
6.國際化的配置
主要是一些異常信息的配置message_*.properties文件
7.頁面
主要知道頁面模板的配置替废,以及相應的shiro權限控制的按鈕狀態(tài)的控制箍铭,注意分頁查詢,頁面數(shù)據(jù)渲染等,都可以按照其他已有模塊拷貝修改即可椎镣。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末诈火,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子状答,更是在濱河造成了極大的恐慌冷守,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件惊科,死亡現(xiàn)場離奇詭異拍摇,居然都是意外死亡,警方通過查閱死者的電腦和手機馆截,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進店門充活,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蜡娶,你說我怎么就攤上這事混卵。” “怎么了窖张?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵幕随,是天一觀的道長。 經(jīng)常有香客問我宿接,道長赘淮,這世上最難降的妖魔是什么辕录? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮梢卸,結果婚禮上走诞,老公的妹妹穿的比我還像新娘。我一直安慰自己低剔,他們只是感情好,可當我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布肮塞。 她就那樣靜靜地躺著襟齿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪枕赵。 梳的紋絲不亂的頭發(fā)上猜欺,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天,我揣著相機與錄音拷窜,去河邊找鬼开皿。 笑死,一個胖子當著我的面吹牛篮昧,可吹牛的內(nèi)容都是我干的赋荆。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼懊昨,長吁一口氣:“原來是場噩夢啊……” “哼窄潭!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起酵颁,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤嫉你,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后躏惋,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體幽污,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年簿姨,在試婚紗的時候發(fā)現(xiàn)自己被綠了距误。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡扁位,死狀恐怖深寥,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情贤牛,我是刑警寧澤惋鹅,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站殉簸,受9級特大地震影響闰集,放射性物質(zhì)發(fā)生泄漏沽讹。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一武鲁、第九天 我趴在偏房一處隱蔽的房頂上張望爽雄。 院中可真熱鬧,春花似錦沐鼠、人聲如沸挚瘟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽乘盖。三九已至,卻和暖如春憔涉,著一層夾襖步出監(jiān)牢的瞬間订框,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工兜叨, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留穿扳,地道東北人。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓国旷,卻偏偏與公主長得像矛物,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子跪但,可洞房花燭夜當晚...
    茶點故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內(nèi)容