三级分销系统

版权声明:本文为CSDN博主「水沟小鱼」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_20964509/article/details/84341438

关于为何要写-分销
第一次看到这个分销这个词的时候,脑海里就蹦出了传销,在新闻联播等等媒体的传播下,让我对其有着极奇的排斥和生恶的感觉,传销固然可恶,但在三级分销下国家还是允许的,好吧!工具是给人用的,是作恶还是行善,在于的是使用人的思量。为什么要写它,还不是领导有要求的,没办法人家有需求,那就先写个试试手吧!

第一步是先思考下逻辑
所谓的分销就是成员与成员的层级关系,与写评论功能的时候评论人和回复人的关系差不多吧!每个评论都可以有无数个回复者,我要做的就是在知道其中一个成员的情况下知道它的“爸爸”或“爷爷”是谁就行了,刚开始是想在user表中加个父级成员的字段,然后就可以用递归的方法知道它的祖宗十八代了,好吧怎么感觉在写族谱呢?最后我还是抛弃了这个想法,因为我用的是mysql数据库,这么频繁的访问操作数据库,由于成员数量可能成指数增长,我不敢想象这将对我的电脑造成多大的负担,谁要是拿这样的代码去运行,嘿嘿!好期待结果是怎么样!行吧,我的运行环境直接用的是phpStudy搭建的本地环境,用thinkcmf5.0一键生成了可以用的站点,不用自己再写后台会员中心什么的了。

先建个表吧,用来存放层级关系,开始写代码后,发现还要有各个成员的一些信息,本来可以多表分级查询的,但是为了省事,我一股脑的放在一个表里了,到时直接一个id,要什么就拿什么,牺牲空间,换来了更少的代码,还是很划算的,至于性能呵呵就行。
在这里插入图片描述

找到个人用户中心,直接用后台管理员的用户就可以登上去了。至于前端页面什么的就不写了。。
直接上代码吧,不写废话了:
根目录\app\user\controller\DistributeController.php

public function index(){
$distribute = new DistributeModel();
$data = $distribute->level_one(); //在模型里具体实现数据库操作
$user = cmf_get_current_user(); //获取前台当前登录用户信息,如果没有登,就返回空
t h i s − > a s s i g n ( this->assign( this>assign(user);
//cmf自带的模板分页渲染方法,将获取分类好数组传给前端去处理
/* 儿级 /
$this->assign(“page”, $data[‘page’]);//当前页码
$this->assign(“lists”, $data[‘lists’]); //所有的数据及分类
/
孙级 /
$this->assign(“page2”, $data[‘page2’]);
$this->assign(“lists2”, $data[‘lists2’]);
/
曾孙级 /
$this->assign(“page3”, $data[‘page3’]);
$this->assign(“lists3”, $data[‘lists3’]);
return $this->fetch(‘index’);
}
/
*
* @Notes:查询下一级的成员
/
public function next(){
$distribute = new DistributeModel();
//获取前端传来的参数,这是当前儿子成员,当儿子成为父级,那它的儿子自然是之前父级成员的孙子,也就是下一级了
$distribute = new DistributeModel();
$id = $this->request->param(“id”, 0, “intval”);
$data = d i s t r i b u t e − > n e x t d i s t r i b u t e ( distribute->next_distribute( distribute>nextdistribute(id);
$user = cmf_get_current_user();
t h i s − > a s s i g n ( this->assign( this>assign(user);
/
一级 /
$this->assign(“page”, $data[‘page’]);
$this->assign(“lists”, $data[‘lists’]);
/
二级 /
$this->assign(“page2”, $data[‘page2’]);
$this->assign(“lists2”, $data[‘lists2’]);
/
三级 */
$this->assign(“page3”, $data[‘page3’]);
$this->assign(“lists3”, $data[‘lists3’]);
return $this->fetch(‘index’);
}

/**
 *   @Notes:取消层级关系
 */

public function negate(){
$data = $this->request->param();
$distribute = new DistributeModel();
//看看获取到的参数是几号,毕竟如果父亲拒绝儿子的供养,不代表爷爷也愿意,所以更新下表字段就行,将父级id改成0就行了。
$ret = d i s t r i b u t e − > n e g a t e d i s t i n c t ( distribute->negate_distinct( distribute>negatedistinct(data[‘id’], d a t a [ ′ n e g a t e o b j ′ ] ) ; / / data['negate_obj']);// data[negateobj]);//data[‘negate_obj’]:1父级;2祖级;3太级;
if ($ret) {
$this->success(“取消关系成功!你再也获取不到他的分成了!”);
} else {
$this->error(“取消失败了!”);
}

}

下面是模型代码了:
public function level_one($data = null)
{
$oneself_id = cmf_get_current_user_id(); //获取当前用户的id
$oneself = Db::name(‘distribute’);
/* 一级 /
$level_one = $oneself->where([‘father_id’ => $oneself_id])->order(‘id desc’)->paginate(10);
$data[‘page’] = $level_one->render();
$data[‘lists’] = $level_one->items();
/
二级 /
$level_two = $oneself->where([‘grandpa_id’ => $oneself_id])->order(‘id desc’)->paginate(10);
$data[‘page2’] = $level_two->render();
$data[‘lists2’] = $level_two->items();
/
三级 */
$level_there = $oneself->where([‘great_grandpa_id’ => $oneself_id])->order(‘id desc’)->paginate(10);
$data[‘page3’] = $level_there->render();
$data[‘lists3’] = $level_there->items();

    return $data;
}

/**
 *   @Notes: $negate_obj ?=1(父级:father) ?=2(祖级:grandpa) ?=3(太级:great_grandpa)
 */
public function negate_distinct($id, $negate_obj)
{
    switch ($negate_obj) {
        case 1:
            $obj = 'father_id';
            break;
        case 2:
            $obj = 'grandpa_id';
            break;
        case 3:
            $obj = 'great_grandpa_id';
            break;
        default:
            return false;
    }
    $ret = Db::name('distribute')->where('id', $id)->update([$obj => 0]);
    return $ret;
}

/**
 *   @Notes:有点的冗余了,不过可以让的逻辑清楚些,用来知道子级,
 * 用递归应该可以实现无限级分销,
 * 但是这个应该是违法的,不过拿去用做无级分类还是很好的嘛。
 */
public function next_distribute($id){
 $oneself = Db::name('distribute');
  /* 一级 */
  $level_one = $oneself->where(['father_id' => $id])->order('id desc')->paginate(10);
  $data['page'] = $level_one->render();
  $data['lists'] = $level_one->items();
  /* 二级 */
  $level_two = $oneself->where(['grandpa_id' => $id])->order('id desc')->paginate(10);
  $data['page2'] = $level_two->render();
  $data['lists2'] = $level_two->items();
  /* 三级 */
  $level_there = $oneself->where(['great_grandpa_id' => $id])->order('id desc')->paginate(10);
  $data['page3'] = $level_there->render();
  $data['lists3'] = $level_there->items();
  return $data;
}

基本上就这些了,后面就是对各级的分成进行划分了。

第二步是要获取层级关系写入表中
打算在第三步的时候,直接在域名地址后面加参数,可以用get方法取到值了,所以现在假设有个地址直接是指向注册页面的,后面还跟个它的推荐人的id号,这样就不用在注册信息里让用户手动填写它的推荐人是哪个了,万一这个用户来到注册页面没有注册而是去首页看看的话,嗯!?好吧可能性很大,所以我就先将获取到的参数存到cookie中就行了,一天后失效。用户注册成功后,再看看有没有父级,为了以后测试,给每个注册成功的用户赠送100个积分,随便给其推荐人奖励一些积分,后面是代码了
这段直接插在注册页面控制器里的:

/* 获取邀请码 ,并转存下,简单明了 /
$request = t h i s − > r e q u e s t − > g e t ( ′ i n v i t e k e y ′ ) ; i f ( this->request->get('invite_key'); if( this>request>get(invitekey);if(request){
setcookie(“invite_key”, $request, time()+(3600
24));
}

/**
* @Notes: 获取邀请码,如果没有就不做处理,有的话将数据写入层级关系表里面distribute
*/
public function collect_invite( u s e r I d = n u l l , userId = null, userId=null,name = null)
{
$request = Request::instance();//都封装在\think\Request,上面use下
$invite_key = r e q u e s t − > g e t ( ′ i n v i t e k e y ′ ) ; i f ( e m p t y ( request->get('invite_key'); if (empty( request>get(invitekey);if(empty(invite_key)) {
//这里好像有点啰嗦,但是可以预防可能多种不确定情况,可能吧!我也不知道
$invite_key = KaTeX parse error: Expected 'EOF', got '}' at position 40: …key'); }̲ if (!e…invite_key)) {
r e t = D b : : n a m e ( ′ d i s t r i b u t e ′ ) − > w h e r e ( ′ u s e r i d ′ , ret = Db::name('distribute')->where('user_id', ret=Db::name(distribute)>where(userid,invite_key)->find();
if($ret){
//咱不用时间戳,虽然这样可能发生时区问题,可是这仅仅是给我自己看的方便,所以就无视吧。
$time = date(“Y-m-d H:i:s”,time());
$data = [
‘user_id’ => u s e r I d , ′ f a t h e r i d ′ = > e m p t y ( userId, 'father_id' => empty( userId,fatherid=>empty(ret[‘user_id’])?’’: r e t [ ′ u s e r i d ′ ] , ′ g r a n d p a i d ′ = > e m p t y ( ret['user_id'], 'grandpa_id' => empty( ret[userid],grandpaid=>empty(ret[‘father_id’])?’’: r e t [ ′ f a t h e r i d ′ ] , ′ g r e a t g r a n d p a i d ′ = > e m p t y ( ret['father_id'], 'great_grandpa_id' => empty( ret[fatherid],greatgrandpaid=>empty(ret[‘grandpa_id’])?’’:$ret[‘grandpa_id’],
‘create_time’ => t i m e , ′ u s e r n a m e ′ = > e m p t y ( time, 'user_name' => empty( time,username=>empty(name)?’’: n a m e , ′ f a t h e r n a m e ′ = > e m p t y ( name, 'father_name' => empty( name,fathername=>empty(ret[‘user_name’])?’’: r e t [ ′ u s e r n a m e ′ ] , ′ g r a n d p a n a m e ′ = > e m p t y ( ret['user_name'], 'grandpa_name' => empty( ret[username],grandpaname=>empty(ret[‘father_name’])?’’: r e t [ ′ f a t h e r n a m e ′ ] , ′ g r e a t g r a n d p a n a m e ′ = > e m p t y ( ret['father_name'], 'great_grandpa_name' => empty( ret[fathername],greatgrandpaname=>empty(ret[‘grandpa_name’])?’’: r e t [ ′ g r a n d p a n a m e ′ ] , ] ; D b : : n a m e ( ′ d i s t r i b u t e ′ ) − > i n s e r t ( ret['grandpa_name'], ]; Db::name('distribute')->insert( ret[grandpaname],];Db::name(distribute)>insert(data);
}else{return false;}

   }else{return false;}
}

在这里插入图片描述

2.如果user表中没有积分字段的话,就去加个。顺便我加了个推荐码字段,目前用不到,可是第三步应该用到。下面的代码有点多,有点杂,我自己写完后也都不想看了~~

/**
* @Notes:给新注册的用户赠送些积分,顺便给其父级们奖励下些
*/
public function share_out($user_id){
s h a r e d a t a = D b : : n a m e ( ′ s h a r e o u t ′ ) − > s e l e c t ( ) ; / / 这 个 用 来 给 后 台 设 置 分 成 百 分 比 的 i f ( ! share_data = Db::name('share_out')->select();//这个用来给后台设置分成百分比的 if(! sharedata=Db::name(shareout)>select();//if(!share_data){//可能是空的,如果是的话提醒下我自己
$time = time();
$china_time = date(“Y-m-d H:i:s”,time());
$result = ‘share_out,这个表数据已经不能用了’;
$address = FILE.‘行号:’.LINE;
$data=[
‘time’ => $time,
‘china_time’ => $china_time,
‘result’ => $result,
‘address’ => a d d r e s s , ] ; D b : : n a m e ( ′ e r r o r l o g ′ ) − > i n s e r t ( address, ]; Db::name('error_log')->insert( address,];Db::name(errorlog)>insert(data);//感觉很多余,应该是没用的东西
}
d a t a u s e r = D b : : n a m e ( ′ u s e r ′ ) − > w h e r e ( ′ i d ′ , data_user = Db::name('user')->where('id', datauser=Db::name(user)>where(id,user_id)->find();
if($data_user){
$data = $data_user[‘score’] + 100; //在这里给注册用户加积分
Db::table(‘user’)->where(‘id’, $user_id)->update([‘score’ => $data]);
}else{
$time = time();
$china_time = date(“Y-m-d H:i:s”,time());
$result = ‘给新注册用户赠送一些积分的时候出错了’;
$address = FILE.‘行号:’.LINE;
$data=[
‘time’ => $time,
‘china_time’ => $china_time,
‘result’ => $result,
‘address’ => a d d r e s s , ] ; D b : : n a m e ( ′ e r r o r l o g ′ ) − > i n s e r t ( address, ]; Db::name('error_log')->insert( address,];Db::name(errorlog)>insert(data);
}
//后面是给推荐人们分的积分
//先去层级关系中查好关系
d a t a o u t = D b : : n a m e ( ′ d i s t r i b u t e ′ ) − > w h e r e ( ′ u s e r i d ′ , data_out = Db::name('distribute')->where('user_id', dataout=Db::name(distribute)>where(userid,user_id)->find();
if($data_out){
d a t a f a t h e r = D b : : n a m e ( ′ u s e r ′ ) − > w h e r e ( ′ i d ′ , data_father = Db::name('user')->where('id', datafather=Db::name(user)>where(id,data_out[‘father_id’])->find();
d a t a g r a n d p a = D b : : n a m e ( ′ u s e r ′ ) − > w h e r e ( ′ i d ′ , data_grandpa = Db::name('user')->where('id', datagrandpa=Db::name(user)>where(id,data_out[‘grandpa_id’])->find();
d a t a g r e a t g r a n d p a = D b : : n a m e ( ′ u s e r ′ ) − > w h e r e ( ′ i d ′ , data_great_grandpa = Db::name('user')->where('id', datagreatgrandpa=Db::name(user)>where(id,data_out[‘great_grandpa_id’])->find();
$data_father_con = $data_out[‘father_contribute’];
$data_grandpa_con = $data_out[‘grandpa_contribute’];
$data_great_grandpa_con = d a t a o u t [ ′ g r e a t g r a n d p a c o n t r i b u t e ′ ] ; / ∗ 父 级 奖 励 ∗ / i f ( data_out['great_grandpa_contribute']; /* 父级奖励*/ if( dataout[greatgrandpacontribute];//if(data_father){
v a r = 100 ∗ var = 100* var=100share_data[2][‘share_out_num’]/100;
$data_father = d a t a f a t h e r [ ′ s c o r e ′ ] + data_father['score']+ datafather[score]+var;
Db::table(‘user’)->where(‘id’, $data_out[‘father_id’])->update([‘score’ => $data_father]);
d a t a = [ ′ u s e r i d ′ = > data =[ 'user_id' => data=[userid=>data_out[‘father_id’],
‘change_score’ => $var,
‘score’ => d a t a f a t h e r , ′ r e m a r k ′ = > ′ 新 用 户 : ′ . data_father, 'remark' => '新用户:'. datafather,remark=>:.data_user[‘user_login’].‘注册奖励积分-1级’,
];
Db::name(‘tc_user_balance_log’)->insert($data);
Db::name(‘distribute’)->where(‘user_id’, u s e r i d ) − > u p d a t e ( [ ′ f a t h e r c o n t r i b u t e ′ = > ( user_id)->update(['father_contribute' => ( userid)>update([fathercontribute=>(data_father_con+KaTeX parse error: Expected 'EOF', got '}' at position 21: …); }̲ /*…data_grandpa){
v a r = 100 ∗ var = 100* var=100share_data[3][‘share_out_num’]/100;
$data_grandpa = d a t a g r a n d p a [ ′ s c o r e ′ ] + data_grandpa['score']+ datagrandpa[score]+var;
Db::table(‘user’)->where(‘id’, $data_out[‘grandpa_id’])->update([‘score’ => $data_grandpa]);
d a t a = [ ′ u s e r i d ′ = > data =[ 'user_id' => data=[userid=>data_out[‘grandpa_id’],
‘change_score’ => $var,
‘score’ => d a t a g r a n d p a , ′ r e m a r k ′ = > ′ 新 用 户 : ′ . data_grandpa, 'remark' => '新用户:'. datagrandpa,remark=>:.data_user[‘user_login’].‘注册奖励积分-2级’,
];
Db::name(‘tc_user_balance_log’)->insert($data);
Db::name(‘distribute’)->where(‘user_id’, u s e r i d ) − > u p d a t e ( [ ′ g r a n d p a c o n t r i b u t e ′ = > ( user_id)->update(['grandpa_contribute' => ( userid)>update([grandpacontribute=>(data_grandpa_con+$var)]);

        }
        /* 太级奖励*/
        if($data_great_grandpa){
            $var = 100*$share_data[4]['share_out_num']/100;
            $data_great_grandpa = $data_great_grandpa['score']+ $var;
            Db::table('user')->where('id', $data_out['great_grandpa_id'])->update(['score' => $data_great_grandpa]);
            $data =[
                'user_id' =>$data_out['great_grandpa_id'],
                'change_score' => $var,
                'score' => $data_great_grandpa,
                'remark' => '新用户:'.$data_user['user_login'].'注册奖励积分-3级',
            ];
            Db::name('tc_user_balance_log')->insert($data);
            Db::name('distribute')->where('user_id', $user_id)->update(['great_grandpa_contribute' => ($data_great_grandpa_con+$var)]);
        }
    }
}

这一段代码还是很简单的,没有啥子复杂的,可以再优化下的,精简些,可我懒,码一次对我来说就够,反正以后还要重新写,到时再说吧!

第三步就是制作推荐码!
这个就更简单了,由于在我的数据库中user表的id号是唯一不重复的,直接拿来用就行,这样之前在user中添加的 推荐码 字段算是费掉了,当然也可以对其加密让别人不知道是什么,可我认为这个知道就知道了呗!难不成这也会被黑客攻击?将注册页面地址后面加上id就是推荐码了,然后将推荐码制作成二维码,这样可以方便用户注册,在前端的个人页面下加个:

点击生成

如果已经有这个二维码图片了自热会在页面里显示出来,如果没有就点击生成下不就好了。
新建控制器CreateInviteKey:

public function index(){
/* http://phpqrcode.sourceforge.net/ 这是人家的官网 下载下来*/
vendor(‘phpqrcode.phpqrcode’,‘simplewind/Core/Library/Vendor’,’.php’);;//导入类库
include_once(CMF_ROOT.’/simplewind/vendor/phpqrcode/qrlib.php’);
$user_id = cmf_get_current_user_id();//获取当前登录的用户id
w e b = c m f g e t d o m a i n ( ) ; i f ( web = cmf_get_domain(); if( web=cmfgetdomain();if(user_id){
$web_path = str_replace( ‘\’ , ‘/’ , realpath(dirname(CMF_ROOT).’/…/’));//网站根目录
$tempDir = w e b p a t h . " / p u b l i c / s t a t i c / q r c o d e / " . web_path."/public/static/qrcode/". webpath."/public/static/qrcode/".user_id."/";//以用户id做目录名
$codeContents = w e b . ′ / u s e r / r e g i s t e r / i n d e x . h t m l ? i n v i t e k e y = ′ . web.'/user/register/index.html?invite_key='. web./user/register/index.html?invitekey=.user_id; //推荐码 ,就是网站注册url,加上该用户id,也用来当做二维码的内容
$fileName = $user_id.’.png’; //生成的二维码图片名
$pngAbsoluteFilePath = t e m p D i r . tempDir. tempDir.fileName; //合并成最终存储地址
/* 为每个用户创建一个目录 /
//iconv方法是为了防止中文乱码,保证可以创建识别中文目录,不用iconv方法格式的话,将无法创建中文目录
$dir = iconv(“UTF-8”, “GBK”, t e m p D i r ) ; i f ( ! f i l e e x i s t s ( tempDir); if (!file_exists( tempDir);if(!fileexists(dir)){
mkdir (KaTeX parse error: Expected 'EOF', got '}' at position 29: …); }̲ \Q…codeContents, p n g A b s o l u t e F i l e P a t h , Q R E C L E V E L Q , 5 ) ; / / 生 成 二 维 码 / ∗ 生 成 成 功 ∗ / / / e c h o ′ < i m g s r c = " ′ . pngAbsoluteFilePath, QR_ECLEVEL_Q ,5);//生成二维码 /* 生成成功 */ // echo '<img src="'. pngAbsoluteFilePath,QRECLEVELQ,5);//////echo<imgsrc=".tempDir.’" />’;
// exit();
a v a t a r = c m f g e t c u r r e n t u s e r ( ) ; / / 获 取 当 前 登 录 的 前 台 用 户 的 信 息 , 未 登 录 时 , 返 回 f a l s e i f ( avatar = cmf_get_current_user();//获取当前登录的前台用户的信息,未登录时,返回false if( avatar=cmfgetcurrentuser();//falseif(avatar){
$avatar = $avatar[‘avatar’];
$logo = w e b p a t h . ′ / p u b l i c / u p l o a d / ′ . web_path.'/public/upload/'. webpath./public/upload/.avatar;//获取用户头像地址
/
判断下该目录下可有头像,如果没有就给个默认的头像 */
l o g o = i s f i l e ( logo = is_file ( logo=isfile(logo) ? $logo : w e b p a t h . ′ / p u b l i c / t h e m e s / t o n g c / p u b l i c / a s s e t s / i m a g e s / h e a d i c o n 5 0. p n g ′ ; / ∗ 如 果 生 成 的 二 维 码 图 片 存 在 , 就 给 他 中 间 加 个 用 户 的 头 像 的 ∗ / i f ( f i l e e x i s t s ( web_path.'/public/themes/tongc/public/assets/images/headicon_50.png'; /* 如果生成的二维码图片存在,就给他中间加个用户的头像的 */ if (file_exists( webpath./public/themes/tongc/public/assets/images/headicon50.png;//if(fileexists(tempDir)){
$QR = p n g A b s o l u t e F i l e P a t h ; / / 已 经 生 成 的 原 始 二 维 码 图 i f ( pngAbsoluteFilePath;//已经生成的原始二维码图 if ( pngAbsoluteFilePath;//if(logo !== FALSE) {
Q R = i m a g e c r e a t e f r o m s t r i n g ( f i l e g e t c o n t e n t s ( QR = imagecreatefromstring(file_get_contents( QR=imagecreatefromstring(filegetcontents(QR));
l o g o = i m a g e c r e a t e f r o m s t r i n g ( f i l e g e t c o n t e n t s ( logo = imagecreatefromstring(file_get_contents( logo=imagecreatefromstring(filegetcontents(logo));
Q R w i d t h = i m a g e s x ( QR_width = imagesx( QRwidth=imagesx(QR);//二维码图片宽度
Q R h e i g h t = i m a g e s y ( QR_height = imagesy( QRheight=imagesy(QR);//二维码图片高度
l o g o w i d t h = i m a g e s x ( logo_width = imagesx( logowidth=imagesx(logo);//logo图片宽度
l o g o h e i g h t = i m a g e s y ( logo_height = imagesy( logoheight=imagesy(logo);//logo图片高度
$logo_qr_width = $QR_width / 5;
$scale = l o g o w i d t h / logo_width/ logowidth/logo_qr_width;
$logo_qr_height = l o g o h e i g h t / logo_height/ logoheight/scale;
f r o m w i d t h = ( from_width = ( fromwidth=(QR_width - l o g o q r w i d t h ) / 2 ; / / 重 新 组 合 图 片 并 调 整 大 小 i m a g e c o p y r e s a m p l e d ( logo_qr_width) / 2; //重新组合图片并调整大小 imagecopyresampled( logoqrwidth)/2;//imagecopyresampled(QR, $logo, $from_width, $from_width, 0, 0, $logo_qr_width,
$logo_qr_height, $logo_width, KaTeX parse error: Expected 'EOF', got '}' at position 35: … }̲ …QR, $pngAbsoluteFilePath);

            }
        }
            $this->success('成功生成推荐码');

    }else{$this->error("出现问题了!可以重新登录试试!");}

}

这样在/网站根目录/public/static/qrcode/用户id/ 下就会生成一个带logo的二维码图片。
好像没有什么了,基本的功能都实现了

第四步 测试代码
贴出来的代码已经在测试过了,应该没什么遗漏的,后期还能根据层级关系表做其他的操作,比如用户购买网站商品后,给父级一点分成?如果要做商城的话,在后台添加控制分成比例的,等等了,那应该都简单了,懒得再做了。就这样吧!拜拜喽

thinkphp开源商城 含支付宝微信支付 三级分销商城: (一) 系统管理:菜单权限、前台菜单、角色管理、职员管理、登录日志、操作日志、图片空间、商城消息、风格设置、计划任务 (二) 基础设置:商城配置、导航管理、广告管理、广告位置、银行管理、支付管理、地区管理、友情链接、快递管理、消息模板 (三) 会员管理:会员等级、会员管理、账号管理 (四) 文章管理:文章管理、文章分类 (五) 运营管理:推荐管理、商品推荐、店铺推荐、品牌推荐、财务管理、资金管理、提现申请、结算管理、商家结算 (六) 订单管理:订单管理、订单管理、投诉管理、退款管理 (七) 店铺管理:店铺认证、开店申请、店铺管理、停用店铺 (八) 商品管理:商品管理、已上架商品、待审核商品、违规商品、商品分类、商品属性、品牌管理、商品规格、评价管理 (九) 虚拟物品自动发货:虚拟商品上架、卡密管理、自动发货 (十) 扩展管理:插件管理、钩子管理 (十一) 分销管理分销管理菜单、分销商家列表、分销商品列表、佣金分成列表、推广用户列表 (十二) 数据分析:商品销售排行、店铺销售统计、销售额统计、销售订单统计、新增会员统计、会员登录统计 (十三) 营销管理三级分销,商品团购,限时拍卖、微砍价、优惠券、满减、满送、满包邮、签到送积分、积分商城 (十四) 微信管理:公众号设置、自定义菜单、用户管理、主动回复文本信息、主动回复图文信息、微信消息模板 (十五) 支付管理:支付宝支付,微信支付、银联支付、货到付款、积分支付、余额支付 (十六) 短信接口:中国网建、阿里大于 (十七) 登录接口:QQ登录、微信登录、微博登录 (十八) 物流接口:快递100接口 (十九) 其他接口:UCenter通信接口(可与社区论坛等同步登录退出)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值