對用戶分配權(quán)限,和權(quán)限管理

權(quán)限這個(gè)問題有些麻煩凉逛,
角色對應(yīng)權(quán)限馍驯,人物分配角色(一個(gè)人物可以有多個(gè)角色阁危,一個(gè)角色也可以有多個(gè)人物)

    
 權(quán)限管理,
    
       - 動態(tài)菜單(關(guān)系存在數(shù)據(jù)庫)
       - 基于角色分配(RBAC)Role Based Access Control
       
       流程:
            a. 用戶登陸
            b. 根據(jù)用戶獲取所有的權(quán)限(url+action)
            c. 根據(jù)用戶獲取所有的權(quán)限(url+action)根據(jù)URL去重()
            d. 放在左側(cè)菜單()

            1. 登陸汰瘫,獲取所有權(quán)限(url+action)
                ORM
                
                
            2. 所有菜單()
                v = models.Menus.objects.values('id','caption','parent_id')
                [
                    {id:'1','caption': '菜單1','parent_id':None},
                    {'caption': '菜單1.1','parent_id':1},
                    {'caption': '菜單1.2'},
                    {'caption': '菜單1.2.1'},
                    {'caption': '菜單2'},
                    {'caption': '菜單3'},
                    {'caption': '菜單3.1'},
                ]
                ==>
                [
                    {'caption': '菜單1','child': [{'caption': '菜單1.1'},{'caption': '菜單1.2','child':[{'caption': '菜單1.2.1'},]}]}
                    {'caption': '菜單2'}
                    {'caption': '菜單3'}
                ]
                
                # 遞歸
                # python中:字典狂打,列表(引用類型)

        思考:
            a. 用遞歸的形式講所有菜單的等級管理列
            b. 不顯示無權(quán)限的菜單
            c. 僅展開當(dāng)前訪問的菜單,其他閉合


models.py 表格ORM

from django.db import models

class User(models.Model):
    username = models.CharField(max_length=32,verbose_name="用戶名")
    password = models.CharField(max_length=64,verbose_name="密碼")
    class Meta:
        verbose_name_plural = '用戶表' # 這個(gè)修改的是admin中顯示的表名
    def __str__(self):
        return self.username

class Role(models.Model):
    caption = models.CharField(max_length=32,verbose_name="角色")
    class Meta:
        verbose_name_plural = '角色表'
    def __str__(self):
        return self.caption

class User2Role(models.Model):
    u = models.ForeignKey(User,on_delete=models.CASCADE,verbose_name="用戶")
    r = models.ForeignKey(Role,on_delete=models.CASCADE,verbose_name="角色")
    class Meta:
        verbose_name_plural = '用戶分配角色'
    def __str__(self):
        return "%s-%s" %(self.u.username,self.r.caption)  # 使得顯示的時(shí)候?yàn)?   libai-按摩

class Action(models.Model):
    # get    獲取用戶信息 1
    # post   創(chuàng)建用戶 2
    # delete 刪除用戶 3
    # put    修改用戶 4
    caption = models.CharField(max_length=32,verbose_name="操作")
    code = models.CharField(max_length=32)
    class Meta:
        verbose_name_plural = '操作表'
    def __str__(self):
        return self.caption

class Menu(models.Model):
    caption = models.CharField(max_length=32)
    parent = models.ForeignKey('self',related_name='p',null=True,blank=True,on_delete=models.CASCADE)
    # blank = True 是在 admin 中可以為空
    def __str__(self):
        return self.caption

class Permission(models.Model):
    # http://127.0.0.1:8889/user.html 用戶管理 1
    # http://127.0.0.1:8889/order.html 訂單管理 2
    caption = models.CharField(max_length=32,verbose_name="標(biāo)題")
    url = models.CharField(max_length=32)
    menu = models.ForeignKey(Menu,null=True,blank=True,on_delete=models.CASCADE)
    class Meta:
        verbose_name_plural = "URL表"
    def __str__(self):
        return "%s--%s" %(self.caption,self.url)

class Permission2Action(models.Model):
    """
        對應(yīng)權(quán)限
    """
    p = models.ForeignKey(Permission,on_delete=models.CASCADE)
    a = models.ForeignKey(Action,on_delete=models.CASCADE)
    class Meta:
        verbose_name_plural = '權(quán)限表'
    def __str__(self):
        return "%s--%s--%s?t=%s" %(self.p.caption,self.a.caption,self.p.url,self.a.code)

class Permission2Action2Role(models.Model):
    p2a = models.ForeignKey(Permission2Action,on_delete=models.CASCADE)
    r = models.ForeignKey(Role,on_delete=models.CASCADE)
    class Meta:
        verbose_name_plural = '角色分配權(quán)限'
    def __str__(self):
        return "%s==>%s" %(self.r.caption,self.p2a)


views.py 視圖函數(shù)

from django.shortcuts import render
from django.shortcuts import redirect
from django.shortcuts import HttpResponse
from app01 import models

from django import forms
from django.forms import fields
from django.forms import widgets
from django.core.exceptions import ValidationError


class LoginForm(forms.Form):
    username = fields.CharField(
        max_length=32,
        required=True,
        error_messages={
            'required':'請輸入用戶名',
            'max_length':'最長輸入32個(gè)字符',
        },
        widget=widgets.TextInput()
    )
    # def clean_username(self):
    #     v1 = self.cleaned_data['username']
    #     v2 = models.User.objects.filter(username=v1).first()
    #     if not v2:
    #         raise ValidationError("用戶名錯誤") # 這個(gè)引發(fā)的錯誤會在errors.username顯示
    #     return v1

    password = fields.CharField(
        max_length=32,
        required=True,
        error_messages={
            'required':'請輸入密碼',
            'max_length':'最長輸入32個(gè)字符'
        },
        widget=widgets.PasswordInput()
    )

    def clean(self):
        v1 = self.cleaned_data.get('username')
        v2 = self.cleaned_data.get('password')
        obj = models.User.objects.filter(username=v1).first()
        if not obj:
            raise ValidationError("用戶名錯誤")
        elif obj.password != v2:
            raise ValidationError("密碼錯誤")
        return self.cleaned_data

from django.core.exceptions import NON_FIELD_ERRORS
def login(request):
    if request.method == "GET":
        obj = LoginForm()
        return render(request,"login.html",{"obj":obj})
    else:
        obj = LoginForm(request.POST)
        all_code = None
        if obj.is_valid():
            print(obj.cleaned_data)
            request.session["username"] = obj.cleaned_data['username']
            return redirect('/index.html')
        else:
            print(obj.errors)
            all_code = obj.errors[NON_FIELD_ERRORS]
        return render(request,"login.html",{"obj":obj,"all_code":all_code})

def index(request):
    username = 'libai'
    # ########## 獲取角色列表 ##########
    # 方式一 : role_list
    # 前提:m = models.ManyToManyField("Role")
    # user_obj = models.User.objects.get(username=username)
    # role_list = user_obj.m.all() # [Role(),Role]

    # 方式二 : user2role_list
    # user_obj = models.User.objects.get(username=username)
    # user2role_list = models.User2Role.objects.filter(u=user_obj) #[User2Role,User2Role,]
    # print(user2role_list)
    #<QuerySet [<User2Role: libai-搬磚者>, <User2Role: libai-按摩>, <User2Role: libai-技師>]>
    # 循環(huán)混弥,把所有role_id, [1,2,3,4]

    # 方式三: role_list
    # user_obj = models.User.objects.get(username=username)
    # role_list = models.Role.objects.filter(user2role__u=user_obj)
    # print(role_list)
    # <QuerySet [<Role: 搬磚者>, <Role: 按摩>, <Role: 技師>]>

    # 方式四: role_list
    role_list = models.Role.objects.filter(user2role__u__username=username)
    print(role_list)
    # <QuerySet [<Role: 搬磚者>, <Role: 按摩>, <Role: 技師>]>


    # l = models.Permission2Action2Role.objects.filter(r__in=role_list)
    # print(l)
    # permission2action_list = models.Permission2Action.objects.filter(permission2action2role__r__in=role_list)
    # print(permission2action_list)
    # <QuerySet [<Permission2Action: 報(bào)表管理--獲取--/report.html?t=get>, <Permission2Action: 姑娘管理--添加--/gril.html?t=post>,
    # <Permission2Action: 姑娘管理--獲取--/gril.html?t=get>, <Permission2Action: 姑娘管理--修改--/gril.html?t=put>,
    # <Permission2Action: 姑娘管理--修改--/gril.html?t=put>]>

    # 獲取個(gè)人所有權(quán)限列表趴乡,放置在 session 中,缺點(diǎn):無法獲取實(shí)時(shí)權(quán)限信息剑逃,需重新登陸
    # 去重
    # permission2action_list = models.Permission2Action.objects.\
    #     filter(permission2action2role__r__in=role_list).\
    #     values("p__url","a__code").distinct()
    # for item in permission2action_list:
    #     print(item)
    # {'p__url': '/report.html', 'a__code': 'get'}
    # {'p__url': '/gril.html', 'a__code': 'post'}
    # {'p__url': '/gril.html', 'a__code': 'get'}
    # {'p__url': '/gril.html', 'a__code': 'put'}

    # return render(request,"index.html",{"user_role":role_list})

    # 將權(quán)限信息放到session中浙宜,不用每次請求都去檢索數(shù)據(jù)庫
    # 如果服務(wù)器給角色新添加了權(quán)限就會使得更新不及時(shí),這時(shí)候就要提示用戶重新登陸生效


    # 應(yīng)該在菜單中顯示的 權(quán)限 --- 在最后一層(exclude 排除不能顯示的)
    menu_leaf_list = models.Permission2Action.objects.\
        filter(permission2action2role__r__in=role_list).\
        exclude(p__menu__isnull=True).\
        values("p_id","p__url","p__caption","p__menu").distinct()

    menu_leaf_dict = {
        # 2:[
        #   {'p__url': '/report.html', 'p__caption': '報(bào)表管理', 'p__menu': 2},
        #   {'p__url': '/gril.html', 'p__caption': '姑娘管理', 'p__menu': 2},
        # ],
        # 3: [{'p__url': '/userinfo.html', 'p__caption': '用戶管理', 'p__menu': 3},]
    }
    for item in menu_leaf_list:
        # [{'p_id': 1, 'p__url': '/userinfo.html', 'p__caption': '用戶管理', 'p__menu': 3}]
        item = {
            'id': item['p_id'],
            'url': item['p__url'],
            "caption": item['p__caption'],
            "parent_id": item['p__menu'],
            'child': [],
        }
        if item['parent_id'] in menu_leaf_dict:
            menu_leaf_dict[item['parent_id']].append(item)
        else:
            menu_leaf_dict[item['parent_id']] = [item,]
    for k,v in menu_leaf_dict.items():
        print(k,v)
    # {'p__url': '/report.html', 'p__caption': '報(bào)表管理'}
    # {'p__url': '/gril.html', 'p__caption': '姑娘管理'}


    menu_list = models.Menu.objects.values("id","caption","parent_id")
    menu_dic = {}
    for item in menu_list:
        item['child'] = []
        menu_dic[item['id']] = item

    for k,v in menu_leaf_dict.items():
        menu_dic[k]['child'] = v

    # ##################### 處理等級關(guān)系
    # menu_dict: 應(yīng)用:評論(models.xx.objects.values('...'))
    result = []
    for k,v in menu_dic.items():  # 注意:這里操作的是內(nèi)存地址,
        if not v['parent_id']:
            result.append(v)
        else:
            menu_dic[v['parent_id']]['child'] = v
    for i in result:
        print('------------------------',i)
    # 剩下主菜單板甘,包含子菜單
    #------------------------ {'id': 1, 'caption': '菜單1', 'parent_id': None, 'child': {'id': 5, 'caption': '菜單1.2', 'parent_id': 1, 'child': {'
    # id': 6, 'caption': '菜單1.2.1', 'parent_id': 5, 'child': []}}}
    # ------------------------ {'id': 2, 'caption': '菜單2', 'parent_id': None, 'child': [{'id': 3, 'url': '/report.html', 'caption': '報(bào)表管理', 'p
    # arent_id': 2, 'child': []}, {'id': 4, 'url': '/gril.html', 'caption': '姑娘管理', 'parent_id': 2, 'child': []}]}
    # ------------------------ {'id': 3, 'caption': '菜單3', 'parent_id': None, 'child': [{'id': 1, 'url': '/userinfo.html', 'caption': '用戶管理',
    # 'parent_id': 3, 'child': []}]}

    return render(request,"index.html",{"user_role":role_list})


urls.py 文件

from django.contrib import admin
from django.urls import path
from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path("login.html/", views.login),
    path("index.html/", views.index),
]

admin 注冊表格

from django.contrib import admin
from app01 import models

admin.site.register(models.Role)
admin.site.register(models.Action)
admin.site.register(models.Permission)
admin.site.register(models.Permission2Action)
admin.site.register(models.Permission2Action2Role)
admin.site.register(models.User)
admin.site.register(models.User2Role)
admin.site.register(models.Menu)

最終的權(quán)限程序并闲,這東西十分繞腦子,

from django.shortcuts import render,HttpResponse,redirect
from . import models
import re

class MenuHelper(object):

    def __init__(self,request,username):
        # 當(dāng)前請求的request對象
        self.request = request
        # 當(dāng)前用戶名
        self.username = username
        # 獲取當(dāng)前URL
        self.current_url = request.path_info

        # 獲取當(dāng)前用戶的所有權(quán)限
        self.permission2action_dict = None
        # 獲取在菜單中顯示的權(quán)限
        self.menu_leaf_list = None
        # 獲取所有菜單
        self.menu_list = None

        self.session_data()

    def session_data(self):
        permission_dict = self.request.session.get('permission_info')
        if permission_dict:
            self.permission2action_dict = permission_dict['permission2action_dict']
            self.menu_leaf_list = permission_dict['menu_leaf_list']
            self.menu_list = permission_dict['menu_list']
        else:
            # 獲取當(dāng)前用戶的角色列表
            role_list = models.Role.objects.filter(user2role__u__username=self.username)

            # 獲取當(dāng)前用戶的權(quán)限列表(URL+Action)
            # v = [
            #     {'url':'/inde.html','code':'GET'},
            #     {'url':'/inde.html','code':'POST'},
            #     {'url':'/order.html','code':'PUT'},
            #     {'url':'/order.html','code':'GET'},
            # ]
            # v = {
            #     '/inde.html':['GET']
            # }
            permission2action_list = models.Permission2Action.objects. \
                filter(permission2action2role__r__in=role_list). \
                values('p__url', 'a__code').distinct()

            permission2action_dict={}
            for item in permission2action_list:
                if item['p__url'] in permission2action_dict:
                    permission2action_dict[item['p__url']].append(item['a__code'])
                else:
                    permission2action_dict[item['p__url']] = [item['a__code'],]

            # 獲取菜單的葉子節(jié)點(diǎn)裙品,即:菜單的最后一層應(yīng)該顯示的權(quán)限
            menu_leaf_list = list(models.Permission2Action.objects. \
                filter(permission2action2role__r__in=role_list).exclude(p__menu__isnull=True). \
                values('p_id', 'p__url', 'p__caption', 'p__menu').distinct())

            # 獲取所有的菜單列表
            menu_list = list(models.Menu.objects.values('id', 'caption', 'parent_id'))

            self.request.session['permission_info'] = {
                'permission2action_dict': permission2action_dict,
                'menu_leaf_list': menu_leaf_list,
                'menu_list': menu_list,
            }

            # self.permission2action_list = permission2action_list
            # self.menu_leaf_list = menu_leaf_list
            # self.menu_list = menu_list

    def menu_data_list(self):

        menu_leaf_dict = {}
        open_leaf_parent_id = None

        # 歸并所有的葉子節(jié)點(diǎn)
        for item in self.menu_leaf_list:
            item = {
                'id': item['p_id'],
                'url': item['p__url'],
                'caption': item['p__caption'],
                'parent_id': item['p__menu'],
                'child': [],
                'status': True,  # 是否顯示
                'open': False
            }
            if item['parent_id'] in menu_leaf_dict:
                menu_leaf_dict[item['parent_id']].append(item)
            else:
                menu_leaf_dict[item['parent_id']] = [item, ]
            if re.match(item['url'], self.current_url):
                item['open'] = True
                open_leaf_parent_id = item['parent_id']

        # 獲取所有菜單字典
        menu_dict = {}
        for item in self.menu_list:
            item['child'] = []
            item['status'] = False
            item['open'] = False
            menu_dict[item['id']] = item

        # 講葉子節(jié)點(diǎn)添加到菜單中
        for k, v in menu_leaf_dict.items():
            menu_dict[k]['child'] = v
            parent_id = k
            # 將后代中有葉子節(jié)點(diǎn)的菜單標(biāo)記為【顯示】
            while parent_id:
                menu_dict[parent_id]['status'] = True
                parent_id = menu_dict[parent_id]['parent_id']

        # 將已經(jīng)選中的菜單標(biāo)記為【展開】
        while open_leaf_parent_id:
            menu_dict[open_leaf_parent_id]['open'] = True
            open_leaf_parent_id = menu_dict[open_leaf_parent_id]['parent_id']

        # 生成樹形結(jié)構(gòu)數(shù)據(jù)
        result = []
        for row in menu_dict.values():
            if not row['parent_id']:
                result.append(row)
            else:
                menu_dict[row['parent_id']]['child'].append(row)

        return result

    def menu_content(self,child_list):
        response = ""
        tpl = """
            <div class="item %s">
                <div class="title">%s</div>
                <div class="content">%s</div>
            </div>
        """
        for row in child_list:
            if not row['status']:
                continue
            active = ""
            if row['open']:
                active = "active"
            if 'url' in row:
                response += "<a class='%s' href='%s'>%s</a>" % (active, row['url'], row['caption'])
            else:
                title = row['caption']
                content = self.menu_content(row['child'])
                response += tpl % (active, title, content)
        return response

    def menu_tree(self):
        response = ""
        tpl = """
        <div class="item %s">
            <div class="title">%s</div>
            <div class="content">%s</div>
        </div>
        """
        for row in self.menu_data_list():
            if not row['status']:
                continue
            active = ""
            if row['open']:
                active = "active"
            # 第一層第一個(gè)
            title = row['caption']
            # 第一層第一個(gè)的后代
            content = self.menu_content(row['child'])
            response += tpl % (active, title, content)
        return response

    def actions(self):
        """
        檢查當(dāng)前用戶是否對當(dāng)前URL有權(quán)訪問俗批,并獲取對當(dāng)前URL有什么權(quán)限
        """
        action_list = []
        # 當(dāng)前所有權(quán)限
        # {
        #     '/index.html': ['GET',POST,]
        # }
        for k,v in self.permission2action_dict.items():
            if re.match(k,self.current_url):
                action_list = v # ['GET',POST,]
                break

        return action_list


def login(request):
    if request.method == "GET":
        return render(request,'login.html')
    else:
        username = request.POST.get('username')
        pwd = request.POST.get('pwd')
        obj = models.User.objects.filter(username=username,password=pwd).first()
        if obj:
            # obj.id,  obj.username
            # 當(dāng)前用戶信息放置session中
            request.session['user_info'] = {'nid':obj.id,'username':obj.username}

            # 獲取當(dāng)前用戶的所有權(quán)限
            # 獲取在菜單中顯示的權(quán)限
            # 獲取所有菜單
            # 放置session中
            MenuHelper(request,obj.username)
            return redirect('/index.html')
        else:
            return redirect('/login.html')

def logout(request):
    request.session.clear()
    return redirect('/login.html')

def permission(func):
    def inner(request,*args,**kwargs):
        user_info = request.session.get("user_info")
        if not user_info:
            return redirect("/login.html")
        obj = MenuHelper(request, user_info['username'])
        action_list = obj.actions()
        if not action_list:
            return HttpResponse("沒有權(quán)限")

        kwargs["menu_string"] = obj.menu_tree()
        kwargs['action_list'] = action_list
        return func(request,*args,**kwargs)
    return inner

@permission
def index(request,*args,**kwargs):
    action_list = kwargs.get('action_list')
    menu_string = kwargs.get('menu_string')

    return render(request,"index.html",{"menu_string":menu_string,"action_list":action_list})

登陸頁面

# login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/login.html" method="POST">
        {% csrf_token %}
        <input type="text" name="username" />
        <input type="text" name="pwd" />
        <input type="submit" value="提交" />
    </form>
</body>
</html>

跳轉(zhuǎn)頁面

# index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .content{
            margin-left: 20px;
            display: none;
        }
        .content a{
            display: block;
        }
        .active > .content{
            display: block;
        }
    </style>
</head>
<body>
    <div style="float: left;width: 20%;">
        {{ menu_string|safe }}
    </div>
    <div style="float: left;width: 80px;">
        {% if 'POST' in action_list %}
            <a >添加</a>
        {% endif %}
    </div>

    {{ action_list }}
</body>
</html>

urls.py 路徑文件

from django.conf.urls import url
from django.contrib import admin
from rbac import views
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^login.html$', views.login),
    url(r'^logout.html$', views.logout),

    url(r'^index.html$', views.index),
]

models.py 文件和上面一樣的

效果圖:

1.png

鏈接:https://pan.baidu.com/s/1eY0iIF8H-jKs6ICZS9_x3w 密碼:gj1e

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市市怎,隨后出現(xiàn)的幾起案子岁忘,更是在濱河造成了極大的恐慌,老刑警劉巖区匠,帶你破解...
    沈念sama閱讀 211,948評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件干像,死亡現(xiàn)場離奇詭異,居然都是意外死亡驰弄,警方通過查閱死者的電腦和手機(jī)麻汰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來戚篙,“玉大人五鲫,你說我怎么就攤上這事〔砝蓿” “怎么了位喂?”我有些...
    開封第一講書人閱讀 157,490評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長乱灵。 經(jīng)常有香客問我塑崖,道長,這世上最難降的妖魔是什么痛倚? 我笑而不...
    開封第一講書人閱讀 56,521評論 1 284
  • 正文 為了忘掉前任弃舒,我火速辦了婚禮,結(jié)果婚禮上状原,老公的妹妹穿的比我還像新娘聋呢。我一直安慰自己,他們只是感情好颠区,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,627評論 6 386
  • 文/花漫 我一把揭開白布削锰。 她就那樣靜靜地躺著,像睡著了一般毕莱。 火紅的嫁衣襯著肌膚如雪器贩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,842評論 1 290
  • 那天朋截,我揣著相機(jī)與錄音蛹稍,去河邊找鬼。 笑死部服,一個(gè)胖子當(dāng)著我的面吹牛唆姐,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播廓八,決...
    沈念sama閱讀 38,997評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼奉芦,長吁一口氣:“原來是場噩夢啊……” “哼赵抢!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起声功,我...
    開封第一講書人閱讀 37,741評論 0 268
  • 序言:老撾萬榮一對情侶失蹤烦却,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后先巴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體其爵,經(jīng)...
    沈念sama閱讀 44,203評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,534評論 2 327
  • 正文 我和宋清朗相戀三年伸蚯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了醋闭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,673評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡朝卒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出乐埠,到底是詐尸還是另有隱情抗斤,我是刑警寧澤,帶...
    沈念sama閱讀 34,339評論 4 330
  • 正文 年R本政府宣布丈咐,位于F島的核電站瑞眼,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏棵逊。R本人自食惡果不足惜伤疙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,955評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望辆影。 院中可真熱鬧徒像,春花似錦、人聲如沸蛙讥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽次慢。三九已至旁涤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間迫像,已是汗流浹背劈愚。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留闻妓,地道東北人菌羽。 一個(gè)月前我還...
    沈念sama閱讀 46,394評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像由缆,于是被迫代替她去往敵國和親算凿。 傳聞我的和親對象是個(gè)殘疾皇子份蝴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,562評論 2 349

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