使用thinkphp搞了一個簡單的三級分銷
阿新 • • 發佈:2019-01-12
關於為何要寫-分銷
第一次看到這個分銷這個詞的時候,腦海裡就蹦出了傳銷,在新聞聯播等等媒體的傳播下,讓我對其有著極奇的排斥和生惡的感覺,傳銷固然可惡,但在三級分銷下國家還是允許的,好吧!工具是給人用的,是作惡還是行善,在於的是使用人的思量。為什麼要寫它,還不是領導有要求的,沒辦法人家有需求,那就先寫個試試手吧!
第一步是先思考下邏輯
所謂的分銷就是成員與成員的層級關係,與寫評論功能的時候評論人和回覆人的關係差不多吧!每個評論都可以有無數個回覆者,我要做的就是在知道其中一個成員的情況下知道它的“爸爸”或“爺爺”是誰就行了,剛開始是想在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(); //獲取前臺當前登入使用者資訊,如果沒有登,就返回空
$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("user_id", 0, "intval");
$data = $distribute->next_distribute($id);
$user = cmf_get_current_user();
$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 = $distribute->negate_distinct($data['id'],$data['negate_obj']);//$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 = $this->request->get('invite_key');
if($request){
setcookie("invite_key", $request, time()+(3600*24));
}
- 然後找到其模型方法裡,在各類驗證完成後加上獲取推薦碼方法:
/**
* @Notes: 獲取邀請碼,如果沒有就不做處理,有的話將資料寫入層級關係表裡面distribute
*/
public function collect_invite($userId = null,$name = null)
{
$request = Request::instance();//都封裝在\think\Request,上面use下
$invite_key = $request->get('invite_key');
if (empty($invite_key)) {
//這裡好像有點囉嗦,但是可以預防可能多種不確定情況,可能吧!我也不知道
$invite_key = $request->cookie('invite_key');
}
if (!empty($invite_key)) {
$ret = Db::name('distribute')->where('user_id',$invite_key)->find();
if($ret){
//咱不用時間戳,雖然這樣可能發生時區問題,可是這僅僅是給我自己看的方便,所以就無視吧。
$time = date("Y-m-d H:i:s",time());
$data = [
'user_id' => $userId,
'father_id' => empty($ret['user_id'])?'':$ret['user_id'],
'grandpa_id' => empty($ret['father_id'])?'':$ret['father_id'],
'great_grandpa_id' => empty($ret['grandpa_id'])?'':$ret['grandpa_id'],
'create_time' => $time,
'user_name' => empty($name)?'':$name,
'father_name' => empty($ret['user_name'])?'':$ret['user_name'],
'grandpa_name' => empty($ret['father_name'])?'':$ret['father_name'],
'great_grandpa_name' => empty($ret['grandpa_name'])?'':$ret['grandpa_name'],
];
Db::name('distribute')->insert($data);
}else{return false;}
}else{return false;}
}
層級關係什麼的已經找到了,下面就是獎勵積分了,人人有份啊!在那之前去加個新表吧!
1.積分操作日誌表:
2.如果user表中沒有積分欄位的話,就去加個。順便我加了個推薦碼欄位,目前用不到,可是第三步應該用到。下面的程式碼有點多,有點雜,我自己寫完後也都不想看了~~
/**
* @Notes:給新註冊的使用者贈送些積分,順便給其父級們獎勵下些
*/
public function share_out($user_id){
$share_data = Db::name('share_out')->select();//這個用來給後臺設定分成百分比的
if(!$share_data){//可能是空的,如果是的話提醒下我自己
$time = time();
$china_time = date("Y-m-d H:i:s",time());
$result = 'share_out,這個表資料已經不能用了';
$address = cmf_asset_relative_url();
$data=[
'time' => $time,
'china_time' => $china_time,
'result' => $result,
'address' => $address,
];
Db::name('error_log')->insert($data);//感覺很多餘,應該是沒用的東西
}
$data_user = 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 = cmf_asset_relative_url();
$data=[
'time' => $time,
'china_time' => $china_time,
'result' => $result,
'address' => $address,
];
Db::name('error_log')->insert($data);
}
//後面是給推薦人們分的積分
//先去層級關係中查好關係
$data_out = Db::name('distribute')->where(