zoukankan      html  css  js  c++  java
  • Django 项目CRM总结

    0. 项目说明:

    1. 销售自动分配客户资源:
        给销售分配权重及承单数量,创建权重表,通过销售权重进行从大到小进行排序
        以承单数循环添加到列表,承单数是多少列表添加就添加多少次
        考虑到如果服务重启,或多台服务器同时运行,数据分配不统一问题:
        
            将列表中的数据放到redis中,每分配一个客户,就从redis中pop出一个销售id;
            
            
            当从redis中取出所有销售id时,在redis中添加一条状态,判断状态是否为True
            如果为True删除备份数据,重新到数据库中取出销售id并且存放一份备份数据
            并且返回True
        
            
        
        
        销售人员也可以在CRM中自己添加客户信息,如果3天未跟进,15天未成单,这个用户资源将
        变成公共资源,其他销售人员就可以在公共资源中进行抢单更近,但是该销售人员不能再次去
        抢单这个用户,防止3天或15天到期,该销售第一时间去抢该客户公司规定。
        
        公司运营部门和销售总监,可以在CRM中批量导入客户资源信息,CRM程序在后台自动分配到每一个销售人员
        
    2.增加权限系统
        权限系统有5个类七张表,用户表,角色表,菜单表,菜单组表,权限表,用户角色表,角色权限表
        给每一个公司内部用添加角色,每个角色关联一条或多条权限
        通过中间件,当公司人员登录到CRM中,中间件进行登录验证,在session中获取登录用信息,通过ORM
        查询登录用户的权限,在CRM后台中进行页面展示。譬如管理员有所有权限,并且可以添加权限,修改部门用户信息等操作
        运营部门和销售总监可以批量导入客户资源。
    
    3.微信,邮件,等发送消息组件   
        

    1. 为什么开发CRM:

    为了客户的管理
    
    给自己公司用:原来人员少通过excel保存
    给公司客户用:原来人员少通过excel保存
    现在公司人员越来越多,业务量也慢慢增加,使用之前的excel记录数据方式已经远远不能满足现在的工作需求
    操作复杂,想要增加功能也无法增加,所以公司就需要这样的CRM后台进行对公司内部人员的管理,销售业务的
    分配任务管理,用户资源管理,资源分配,公司权限分配等等操作功能。

    2. 开发周期  

    - 开发周期:预计2周,技术点有些不太确定,先进行评估然后再给老大明确答案
    - crm开发周期:开发2个月,2个月持续还在做:修复bug和新功能的开发
    
    开发阶段:
    	- 只开发业务,快速实现想要的功能
    项目维护和扩展
    	- 抽离组件以后方便其他系统快速应用
    	
    

    3. 技术点: 

    - 表和字段

    - 权限控制
    5个类七张表:
      User类,Role类,Menu类菜单,Group类菜单组,Permission类权限
        用户表,角色表,菜单表,菜单组表,权限表,用户角色表,角色权限表
        
    from django.db import models
    
    class Menu(models.Model):
        """
        菜单组
        """
        title = models.CharField(max_length=32)
    
        def __str__(self):
            return self.title
    class Group(models.Model):
        """
        权限组
        """
        caption = models.CharField(verbose_name='组名称',max_length=16)
        menu = models.ForeignKey(verbose_name='所属菜单',to='Menu',default=1)
    
        def __str__(self):
            return self.caption
    class Permission(models.Model):
        """
        权限表
        """
        title = models.CharField(verbose_name='标题',max_length=32)
        url = models.CharField(verbose_name="含正则URL",max_length=64)
    
        menu_gp = models.ForeignKey(verbose_name='组内菜单',to='Permission',null=True,blank=True,related_name='x1')
    
        code = models.CharField(verbose_name="代码",max_length=16)
        group = models.ForeignKey(verbose_name='所属组',to="Group")
    
        class Meta:
            verbose_name_plural = "权限表"
    
        def __str__(self):
            return self.title
    
    class User(models.Model):
        """
        用户表
        """
        username = models.CharField(verbose_name='用户名',max_length=32)
        password = models.CharField(verbose_name='密码',max_length=64)
        email = models.CharField(verbose_name='邮箱',max_length=32)
    
        roles = models.ManyToManyField(verbose_name='具有的所有角色',to="Role",blank=True)
    
        class Meta:
            verbose_name_plural = "用户表"
    
        def __str__(self):
            return self.username
    
    class Role(models.Model):
        """
        角色表
        """
        title = models.CharField(max_length=32)
        permissions = models.ManyToManyField(verbose_name='具有的所有权限',to='Permission',blank=True)
        class Meta:
            verbose_name_plural = "角色表"
    
        def __str__(self):
            return self.title

    - CRM业务
      13个类16张表
      
    from django.db import models
    from rbac import models as rbac_model
    
    class Department(models.Model):
        """
        部门表
        市场部     1000
        销售      1001
        """
        title = models.CharField(verbose_name='部门名称', max_length=16)
        code = models.IntegerField(verbose_name='部门编号',unique=True,null=False)
    
        def __str__(self):
            return self.title
    
    
    class UserInfo(models.Model):
        """
        员工表
        """
        auth = models.OneToOneField(verbose_name='用户权限', to=rbac_model.User,null=True,blank=True)
        name = models.CharField(verbose_name='员工姓名', max_length=16)
        username = models.CharField(verbose_name='用户名', max_length=32)
        password = models.CharField(verbose_name='密码', max_length=64)
        email = models.EmailField(verbose_name='邮箱', max_length=64)
    
        depart = models.ForeignKey(verbose_name='部门', to="Department",to_field="code")
    
        def __str__(self):
            return self.name
    
    
    class Course(models.Model):
        """
        课程表
        如:
            Linux基础
            Linux架构师
            Python自动化开发精英班
            Python自动化开发架构师班
        """
        name = models.CharField(verbose_name='课程名称', max_length=32)
    
        def __str__(self):
            return self.name
    
    
    class School(models.Model):
        """
        校区表
        如:
            北京海淀校区
            北京昌平校区
            上海虹口校区
            广州白云山校区
        """
        title = models.CharField(verbose_name='校区名称', max_length=32)
    
        def __str__(self):
            return self.title
    
    
    class ClassList(models.Model):
        """
        班级表
        如:
            Python全栈  面授班  5期  10000  2017-11-11  2018-5-11
        """
        school = models.ForeignKey(verbose_name='校区', to='School')
        course = models.ForeignKey(verbose_name='课程名称', to='Course')
    
        semester = models.IntegerField(verbose_name="班级(期)")
        price = models.IntegerField(verbose_name="学费")
        start_date = models.DateField(verbose_name="开班日期")
        graduate_date = models.DateField(verbose_name="结业日期", null=True, blank=True)
        memo = models.CharField(verbose_name='说明', max_length=256, blank=True, null=True, )
        teachers = models.ManyToManyField(verbose_name='任课老师', to='UserInfo', related_name='teach_classes')
        tutor = models.ForeignKey(verbose_name='班主任', to='UserInfo', related_name='classes')
    
        def __str__(self):
            return "{0}({1}期)".format(self.course.name, self.semester)
    
    
    class Customer(models.Model):
        """
        客户表
        """
        qq = models.CharField(verbose_name='qq', max_length=64, unique=True, help_text='QQ号必须唯一')
    
        name = models.CharField(verbose_name='学生姓名', max_length=16)
        gender_choices = ((1, ''), (2, ''))
        gender = models.SmallIntegerField(verbose_name='性别', choices=gender_choices)
    
        education_choices = (
            (1, '重点大学'),
            (2, '普通本科'),
            (3, '独立院校'),
            (4, '民办本科'),
            (5, '大专'),
            (6, '民办专科'),
            (7, '高中'),
            (8, '其他')
        )
        education = models.IntegerField(verbose_name='学历', choices=education_choices, blank=True, null=True, )
        graduation_school = models.CharField(verbose_name='毕业学校', max_length=64, blank=True, null=True)
        major = models.CharField(verbose_name='所学专业', max_length=64, blank=True, null=True)
    
        experience_choices = [
            (1, '在校生'),
            (2, '应届毕业'),
            (3, '半年以内'),
            (4, '半年至一年'),
            (5, '一年至三年'),
            (6, '三年至五年'),
            (7, '五年以上'),
        ]
        experience = models.IntegerField(verbose_name='工作经验', blank=True, null=True, choices=experience_choices)
        work_status_choices = [
            (1, '在职'),
            (2, '无业')
        ]
        work_status = models.IntegerField(verbose_name="职业状态", choices=work_status_choices, default=1, blank=True,
                                          null=True)
        company = models.CharField(verbose_name="目前就职公司", max_length=64, blank=True, null=True)
        salary = models.CharField(verbose_name="当前薪资", max_length=64, blank=True, null=True)
    
        source_choices = [
            (1, "qq群"),
            (2, "内部转介绍"),
            (3, "官方网站"),
            (4, "百度推广"),
            (5, "360推广"),
            (6, "搜狗推广"),
            (7, "腾讯课堂"),
            (8, "广点通"),
            (9, "高校宣讲"),
            (10, "渠道代理"),
            (11, "51cto"),
            (12, "智汇推"),
            (13, "网盟"),
            (14, "DSP"),
            (15, "SEO"),
            (16, "其它"),
        ]
        source = models.SmallIntegerField('客户来源', choices=source_choices, default=1)
        referral_from = models.ForeignKey(
            'self',
            blank=True,
            null=True,
            verbose_name="转介绍自学员",
            help_text="若此客户是转介绍自内部学员,请在此处选择内部学员姓名",
            related_name="internal_referral"
        )
        course = models.ManyToManyField(verbose_name="咨询课程", to="Course")
    
        status_choices = [
            (1, "已报名"),
            (2, "未报名")
        ]
        status = models.IntegerField(
            verbose_name="状态",
            choices=status_choices,
            default=2,
            help_text=u"选择客户此时的状态"
        )
        consultant = models.ForeignKey(verbose_name="课程顾问", to='UserInfo', related_name='consultant',limit_choices_to={'depart_id':1001})
        recv_date = models.DateField(verbose_name='接客时间', null=True, blank=True)
        date = models.DateField(verbose_name="咨询日期", auto_now_add=True)
        last_consult_date = models.DateField(verbose_name="最后跟进日期", auto_now_add=True)
    
        def __str__(self):
            return "姓名:{0},QQ:{1}".format(self.name, self.qq, )
    
    class CustomerDistribution(models.Model):
        """
        客户分配表
        """
        user = models.ForeignKey(verbose_name='客户顾问',to='UserInfo',related_name='cds',limit_choices_to={'depart_id':1001})
        customer = models.ForeignKey(verbose_name='客户',to='Customer',related_name='dealers')
        ctime = models.DateField()
        status_choices = (
            (1,'正在跟进'),
            (2,'已成单'),
            (3,'3天未跟进'),
            (4,'15天未跟进'),
        )
        status = models.IntegerField(verbose_name='状态',choices=status_choices,default=1)
        memo = models.CharField(verbose_name='更多信息',max_length=255,null=True)
    
    class SaleRank(models.Model):
        """
        销售权重和数量
        """
        user = models.ForeignKey(to='UserInfo',limit_choices_to={'depart_id':1001})
        num = models.IntegerField(verbose_name='数量')
        weight = models.IntegerField(verbose_name='权重')
    
    
    class ConsultRecord(models.Model):
        """
        客户跟进记录
        """
        customer = models.ForeignKey(verbose_name="所咨询客户", to='Customer')
        consultant = models.ForeignKey(verbose_name="跟踪人", to='UserInfo')
        date = models.DateField(verbose_name="跟进日期", auto_now_add=True)
        note = models.TextField(verbose_name="跟进内容...")
    
    
    class PaymentRecord(models.Model):
        """
        缴费记录
        """
        customer = models.ForeignKey(Customer, verbose_name="客户")
    
        class_list = models.ForeignKey(verbose_name="班级", to="ClassList", blank=True, null=True)
    
        pay_type_choices = [
            (1, "订金/报名费"),
            (2, "学费"),
            (3, "转班"),
            (4, "退学"),
            (5, "退款"),
        ]
        pay_type = models.IntegerField(verbose_name="费用类型", choices=pay_type_choices, default=1)
        paid_fee = models.IntegerField(verbose_name="费用数额", default=0)
        turnover = models.IntegerField(verbose_name="成交金额", blank=True, null=True)
        quote = models.IntegerField(verbose_name="报价金额", blank=True, null=True)
        note = models.TextField(verbose_name="备注", blank=True, null=True)
        date = models.DateTimeField(verbose_name="交款日期", auto_now_add=True)
        consultant = models.ForeignKey(verbose_name="负责老师", to='UserInfo', help_text="谁签的单就选谁")
    
    
    class Student(models.Model):
        """
        学生表(已报名)
        """
        customer = models.OneToOneField(verbose_name='客户信息', to='Customer')
    
        username = models.CharField(verbose_name='用户名', max_length=32)
        password = models.CharField(verbose_name='密码', max_length=64)
        emergency_contract = models.CharField(max_length=32, blank=True, null=True, verbose_name='紧急联系人')
        class_list = models.ManyToManyField(verbose_name="已报班级", to='ClassList', blank=True)
    
        company = models.CharField(verbose_name='公司', max_length=128, blank=True, null=True)
        location = models.CharField(max_length=64, verbose_name='所在区域', blank=True, null=True)
        position = models.CharField(verbose_name='岗位', max_length=64, blank=True, null=True)
        salary = models.IntegerField(verbose_name='薪资', blank=True, null=True)
        welfare = models.CharField(verbose_name='福利', max_length=256, blank=True, null=True)
        date = models.DateField(verbose_name='入职时间', help_text='格式yyyy-mm-dd', blank=True, null=True)
        memo = models.CharField(verbose_name='备注', max_length=256, blank=True, null=True)
    
        def __str__(self):
            return self.username
    
    
    class CourseRecord(models.Model):
        """
        上课记录表
        """
        class_obj = models.ForeignKey(verbose_name="班级", to="ClassList")
        day_num = models.IntegerField(verbose_name="节次", help_text=u"此处填写第几节课或第几天课程...,必须为数字")
        teacher = models.ForeignKey(verbose_name="讲师", to='UserInfo')
        date = models.DateField(verbose_name="上课日期", auto_now_add=True)
    
        course_title = models.CharField(verbose_name='本节课程标题', max_length=64, blank=True, null=True)
        course_memo = models.TextField(verbose_name='本节课程内容概要', blank=True, null=True)
        has_homework = models.BooleanField(default=True, verbose_name="本节有作业")
        homework_title = models.CharField(verbose_name='本节作业标题', max_length=64, blank=True, null=True)
        homework_memo = models.TextField(verbose_name='作业描述', max_length=500, blank=True, null=True)
        exam = models.TextField(verbose_name='踩分点', max_length=300, blank=True, null=True)
    
        def __str__(self):
            return "{0} day{1}".format(self.class_obj, self.day_num)
    
    
    class StudyRecord(models.Model):
        course_record = models.ForeignKey(verbose_name="第几天课程", to="CourseRecord")
        student = models.ForeignKey(verbose_name="学员", to='Student')
        record_choices = (('checked', "已签到"),
                          ('vacate', "请假"),
                          ('late', "迟到"),
                          ('noshow', "缺勤"),
                          ('leave_early', "早退"),
                          )
        record = models.CharField("上课纪录", choices=record_choices, default="checked", max_length=64)
        score_choices = ((100, 'A+'),
                         (90, 'A'),
                         (85, 'B+'),
                         (80, 'B'),
                         (70, 'B-'),
                         (60, 'C+'),
                         (50, 'C'),
                         (40, 'C-'),
                         (0, ' D'),
                         (-1, 'N/A'),
                         (-100, 'COPY'),
                         (-1000, 'FAIL'),
                         )
        score = models.IntegerField("本节成绩", choices=score_choices, default=-1)
        homework_note = models.CharField(verbose_name='作业评语', max_length=255, blank=True, null=True)
        note = models.CharField(verbose_name="备注", max_length=255, blank=True, null=True)
    
        homework = models.FileField(verbose_name='作业文件', blank=True, null=True, default=None)
        stu_memo = models.TextField(verbose_name='学员备注', blank=True, null=True)
        date = models.DateTimeField(verbose_name='提交作业日期', auto_now_add=True)
    
        def __str__(self):
            return "{0}-{1}".format(self.course_record, self.student)

    - 满意度调查
      七个类七张表
      员工表,班级列表,学生列表,问卷调查表,问题表,单选题选项表,回卷表
      
    from django.db import models
    
    
    class UserInfo(models.Model):
        """
        员工表
        """
        username = models.CharField(max_length=32)
        password = models.CharField(max_length=32)
    
        class Meta:
            verbose_name_plural = '员工表'
    
        def __str__(self):
            return self.username
    
    
    class ClassList(models.Model):
        """
        班级表
        """
        title = models.CharField(max_length=32)
    
        class Meta:
            verbose_name_plural = '班级列表'
    
        def __str__(self):
            return self.title
    
    
    class Student(models.Model):
        """
        学生表
        """
        user = models.CharField(max_length=32)
        pwd = models.CharField(max_length=32)
        cls = models.ForeignKey(to='ClassList')
    
        class Meta:
            verbose_name_plural = '学生列表'
    
        def __str__(self):
            return self.user
    
    
    class Questionnaire(models.Model):
        """
        问卷表
        """
        title = models.CharField(max_length=64)
        cls = models.ForeignKey(to=ClassList,verbose_name='所调查问卷班级')
        creator = models.ForeignKey(to='UserInfo',verbose_name='创建人')
    
        count_answer = models.IntegerField(default=0,verbose_name='统计回答问卷的学生数')
    
    
    
        class Meta:
            verbose_name_plural = '问卷调查表'
    
        def __str__(self):
            return self.title
    
    
    class Question(models.Model):
        """
        问题
        """
        caption = models.CharField(max_length=64, verbose_name='问题内容')
    
        question_types = (
            (1, '打分'),
            (2, '单选'),
            (3, 'c'),
        )
        tp = models.IntegerField(choices=question_types)
        naire = models.ForeignKey(to=Questionnaire, default=1)
        class Meta:
            verbose_name_plural = '问题表'
    
        def __str__(self):
            return self.caption
    
    
    class Option(models.Model):
        """
        单选题的选项
        """
        name = models.CharField(verbose_name='选项名称', max_length=32)
        score = models.IntegerField(verbose_name='选项对应的分值')
        qs = models.ForeignKey(to='Question', verbose_name='管理问题')
    
        class Meta:
            verbose_name_plural = '单选题选项'
    
        def __str__(self):
            return self.name
    
    
    class Answer(models.Model):
        """
        回答
        """
        stu = models.ForeignKey(to='Student')
        question = models.ForeignKey(to='Question')
    
        option = models.ForeignKey(to="Option", null=True, blank=True,verbose_name='所回答的问题')
        val = models.IntegerField(null=True, blank=True)
        content = models.CharField(max_length=255, null=True, blank=True)
    
        class Meta:
            verbose_name_plural = '回卷表'

    - 会议室预定
      3个类3张表
      员工表,会议室表,预定表
      
    from django.db import models
    
    # Create your models here.
    class UserInfo(models.Model):
        """
        员工表
        """
        username = models.CharField(max_length=32,verbose_name='用户')
        password = models.CharField(max_length=32,verbose_name='密码')
    
        class Meta:
            verbose_name_plural = '员工表'
    
        def __str__(self):
            return self.username
    
    
    class Room(models.Model):
        '''
        会议室表
        '''
        caption = models.CharField(max_length=32,verbose_name='会议室')
    
    
    
    class Booking(models.Model):
        user = models.ForeignKey(to='UserInfo',verbose_name='用户')
        room = models.ForeignKey(to='Room',verbose_name='会议室')
        booking_date = models.DateField(verbose_name='预定日期')    # 年月日   DateTimeField:年月日 时分秒
        time_choices = (
            (1, '8:00'),
            (2, '9:00'),
            (3, '10:00'),
            (4, '11:00'),
            (5, '12:00'),
            (6, '13:00'),
            (7, '14:00'),
            (8, '15:00'),
            (9, '16:00'),
            (10, '17:00'),
            (11, '18:00'),
            (12, '19:00'),
            (13, '20:00'),
        )
        booking_time = models.IntegerField(verbose_name='预定时间段', choices=time_choices)
    
        class Meta:
            unique_together = (
                ('booking_date', 'booking_time', 'room')    # 一个日期中的时间段只能预定一个会议室
            )
    
    

     

    - 有没有遇到坑?令你印象深刻的事情?你觉得写的比较吊的功能?
        - 组合搜索时,生产URL,__iter__方法
            - requset.GET
            - 深拷贝
            - 可迭代对象
            - yield
            - 面向对象封装
        - popup
            - 回调函数
            - window.open('','name')
            - opener.xxxx回调函数x()
            - FK时,可以使用limit_choice_to(引用另一张表,给另一张添加条件),可以是字典和Q对象
            - related_name和model_name
            - 获取所有的反向关联字典,获取limit_choice_to字段
            - 查询
        - excel批量导入
        - 路由系统
            - 动态的生产url,增删改查
            - 看Admin源码(include)
            - /xx/ -> ([
            'xxx',],namespace)
        - 开发组件时,最开始看admin源码不太理解,但是当和权限系统和配合是,才明白开发的组件用途太广。

    4.其他:

    1. 通过ChangList封装好多数据
    2. 销售中功能资源:Q实现,3天/15天
    3. 使用yield实现:
        - 对数据二次加工处理(生成器函数)
        - 对应对象进行循环__iter__和yield配合
        
    4. 获取Model类中的字段对应的对象
        class Foo(model.Model):
            xx = models.CharField()
        Foo.get_field('xx')
    5. 模糊搜索功能
    6. Type创建类,动态创建ModelForm
    7. 自动派单
        - 根据权重,从大到小进行排序,通过承担量进行循环次数添加到列表中
        - 原来在内存中实现,问题:重启和多进程是都会存在问题
        - 使用redis解决问题,
            - 状态
            - 原来的数据(权重表 权重和数量)
            - pop数据(pop完再copy原来的数据)
    8. 使用 list_display配置
        list_display=[函数名,字段名]
    9. reverse 方向生成URL
    10. 母板
    11. 静态文件查找顺序
    12. 定制ready方法,起始文件
    13. inclusion_tag
    14. 中间件的使用
            中间件最多有几个方法:
                最多5个,常用的就2个process_request,process_response
                使用权限登录,权限验证
                crsf_token,内部使用process_view方法
    15. importlib + getattr
    16. FilterOption,lambda表达式    
    17. QueryDict
            - 原条件的保留
            - filter
    18. ModelForm处理数据保留外键pk
    19. 面向对象的 @property -- 操作不用加括号 @classmethod  自动分配客户id
    20. make_safe() 或在前端 添加safe
    21. xss攻击,抽象方法,抽象类+raise 抛出异常
    22. 组件中的装饰器,实现self.request = request
    23. 封装model类的属性
    24. js自执行函数
            (function(arg)){}('self')
    25. URL的钩子函数
    26. 多继承
    27. 批量插入和批量导入,xlrd
    28. redis连接池
    29. 工厂模式
        settting.py
            MSG_PATH= 'path.Email'
        
        
        class XXFactory(object):
            @classmethod
            def get_msg(cls):
                settting.MSG_PATH
                # rsplit
                # importlib
                # getattr
                return obj
        
            # 示例
            MESSAGE_CLASSES = [
                'utils.message.email.Email',
                'utils.message.msg.Msg',
                'utils.message.wx.WeChat',
                'utils.message.dingding.DingDing',
            ]
            for cls_path in settings.MESSAGE_CLASSES:
            # cls_path是字符串
            module_path,class_name = cls_path.rsplit('.',maxsplit=1)
            m = importlib.import_module(module_path)
            obj = getattr(m,class_name)()
            obj.send(subject,body,to,name,)
        class Email(object):
            def send ....
        class WeChat(object):
            def send ....
        class Msg(object):
            def send ....
                    
    30. Models类中自定义save方法
    
    31. django admin中注册models时候
        from django.contrib import admin
    
        from . import models
    
        # 方式一
        class UserConfig(admin.ModelAdmin):
            pass
    
        admin.site.register(models.UserInfo,UserConfig)
    
        # 方式二
        @admin.register(models.UserInfo)
        class UserConfig(admin.ModelAdmin):
            pass
    
    32. 深浅拷贝

      

  • 相关阅读:
    'Undefined symbols for architecture i386,clang: error: linker command failed with exit code 1
    The codesign tool requires there only be one 解决办法
    XCode iOS project only shows “My Mac 64bit” but not simulator or device
    Provisioning profile XXXX can't be found 的解决办法
    UIView 中的控件事件穿透 Passthrough 的实现
    Xcode4.5出现时的OC新语法
    xcode 快捷键(持续更新)
    打越狱包
    php缓存与加速分析与汇总
    浏览器的判断
  • 原文地址:https://www.cnblogs.com/supery007/p/8183979.html
Copyright © 2011-2022 走看看