昨天在写Code的时候一不注意时间就超过了
其实我本来是很懒惰容易放弃的人
在之前的参赛中我也是写了几篇就放弃了
但是这次希望可以坚持完成
完成一件事情不只是技术磨练及进步
而是对一个自我认同跟坚持的展现!!
真的很感谢IT邦跟永丰的机会
在我参赛的期间
我除了学习到了金流系统的交易(从未碰过)
我也加深了对Laravel的技能
之前我也是看教学影片而已
但是在实际做系统时才会发现许多细节要调整~
(Laravel 的MVC还有资料库设计)
好啦我的心得分享差不多就到此结束了我们来完成最後的部分吧!
虽然有许多遗珠之憾
不过这个系统是我有兴趣的
我希望以後可以把这个side project完成!!
今天的目标有点多!
我们来把它完成吧
我在写文章的时候也会遇到失败的地方
我希望可以把这些纪录忠实呈现
除了可以提醒自我需要加强的地方外
也想跟大家分享
工程师没有一开始就做出完美的系统
随者patch的update我们才会与生活的改变进步!!
先上成果给大家看吧
我们首先要先制作修改首页
在这之前我们先制作一个名为layout的样板
也就是我们上方的navbar为主要样式
其他的组件都可以套用上方列表
这样我们就不用在每页都制作导览列(这也是许多现代前端框架会用的方法)
Layout.blade.php
<head>
<!-- Scripts -->
<script src="{{ asset('js/app.js') }}" defer></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"> </script>
<!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<div class="container">
<ul class="nav justify-content-center">
<li class="nav-item">
<a class="nav-link active" href="{{ url('/') }}">
<H2>首页</H2>
</a>
</li>
<li class="nav-item">
<a class="nav-link active" href="{{ url('/skills') }}">
<H2>全技能列表</H2>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url('profile') }}">
<H2>个人档案</H2>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url('/points')}}">
<h2>评分系统</h2>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url('/trades/record')}}">
<h2>订单编号</h2>
</a>
</li>
<li class=" nav-item">
<a class="nav-link" href="{{ url('/skills/tree')}}">
<h2>技能树</h2>
</a>
</li>
</ul>
<div class="container">
@yield('content')
</div>
</div>
这边的样板代表我可以把导览列建立好作为我系统的主要样板
yeild函数就是可以给其他blade填充的页面
里面的变数就是要填聪在哪个相对应的变数里 -> 我这边叫做content
再来大家看我简单的首页吧就会比较理解我说什麽了
Home.blade.php
@extends('layout')
@section('content')
<div class="jumbotron jumbotron-fluid">
<div class="container">
<h1 class="display-4">技能交换平台</h1>
<p class="lead">交换你的技能是放潜能吧!!</p>
</div>
</div>
@endsection
@extend 是代表我要延伸哪个样板 我这边选择的是名叫layout的样板
layout是我的 Layout.blade.php的名字喔 blade.php可以不加上去
接者使用 @section 跟@endsection包起来 变数就使用contnent包进去
聪民的你应该发现了!这样的作法 我们可以用不同变数包在不同区域
比如说footer或是sidebar等等~~~
有了这样的概念後我们把其他叶面都补上这个layout搂
user/profile.blade.php
@extends('layout')
<head>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"> </script>
<!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
<style>
.box {
display: flex;
/* align-items: center; */
justify-content: center;
height: 100%;
}
</style>
</head>
@section('content')
<div class="box">
<div>
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col">id</th>
<th scope="col">姓名</th>
<th scope="col">email</th>
<th scope="col">会员建立时间</th>
</tr>
</thead>
<tbody>
<tr>
<td>
{{$user->id}}
</td>
<td>
{{$user->name}}
</td>
<td>
{{$user->email}}
</td>
<td>
{{$user->created_at}}
</td>
</tr>
</tbody>
</table>
</div>
</div>
@endsection
以此类推
依照我前面的习惯
我们先建立Model跟migration吧
php artisan make:Trade -m
create_trades_table.php
接者在mirgration里面增加这些栏位
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateTradesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('trades', function (Blueprint $table) {
$table->id();
$table->string('target_user_id'); // 交换者的User ID
$table->integer('skill_id'); // 对方的技能ID
$table->integer('user_id'); // 自己的User ID
$table->string('my_skill_id'); // 自己的技能ID
$table->string('shopNo'); // 建立订单的编号
$table->integer('amount'); // 价钱 (前方说的技能相减分数*1000)
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('trades');
}
}
建立这些栏位的解释麻烦帮我看注解喔
接者我们定义route吧!
Route::resource('trades', 'TradeController');
Trade Model fillable也要修改一下喔
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Trade extends Model
{
use HasFactory;
protected $fillable = [
'target_user_id',
'user_id', 'skill_id',
'my_skill_id', 'shopNo', 'amount'
];
}
为了让大家了解我的系统流程
先让大家看图吧!
在评分表里我们除了秀出个人对该技能的评分以外
我们也多了交易的按钮
我们来看一下接下来会跳到哪个画面喽!
接者跳到这画面
说明 我现在是admin的使用者 我目标是roni的微积分作技能交换
那们作为交换我目前只有化学可以选
点击过去就可以做交换搂!!
@extends('layout')
@section('content')
<div>
<table class="table table-bordered">
<thead>
<tr>
<th>ID</th>
<th>标题</th>
<th>使用者ID</th>
<th>技能评分</th>
<th>分数</th>
<th>交换技能</th>
</tr>
</thead>
<tbody>
@foreach($skills as $skill )
<tr>
<td>{{$skill->id}}</td>
<td>{{$skill->title}}</td>
<td>{{$skill->user_id}}</td>
<td><button type="button" class="btn btn-primary" onclick="myFunction('{{$skill->id}}','{{$skill->user_id}}')">进入评分</button></td>
<td>{{$skill->point}}</td>
<td><button class="btn btn-primary" onclick="goTrade('{{$skill->id}}','{{$skill->user_id}}','{{$my_id}}')">进行技能交换</button></td>
</tr>
@endforeach
</tbody>
</table>
<!-- {{$skills}} -->
<!-- {{$my_id}} -->
</div>
<script>
function myFunction(skill_id, user_id) {
var data = {
skill_id,
user_id
}
$.ajax({
method: "POST",
url: "/points",
dataType: 'json',
data
})
.done(function(msg) {
console.log(msg)
});
}
function goTrade(skill_id, user_id, my_id) {
var data = {
skill_id,
user_id: my_id,
target_user_id: user_id
}
window.location.replace(`/trades?skill_id=${data.skill_id}&user_id=${data.user_id}&target_user_id=${data.target_user_id}`)
}
</script>
@endsection
我们在评分上面goTrade function上动手角
把一些使用者参数跟技能ID
对方ID带过去
那麽为了要带到
交换的选择页面我们参数可以用query string的方式导向别的页面
query string就是网址後面? 接变数然後用&接起来
像是youtube影片 可以接?t=10m20s 这些参数可以让页面读取到指定的参数做api请求
或是js操作
在Controller/TradeController.php里的index function
public function index(Request $request)
{
//
$data = $request->all();
$user = Auth::user();
$skill_id = $request->query('skill_id');
$user_id = $request->query('user_id');
$target_user_id = $request->query('target_user_id');
$myskills = Skill::where('user_id', $user->id)->get();
// dd($myskills);
return view('trade.index', [
'skill_id' => $skill_id,
'user_id' => $user_id,
'target_user_id' => $target_user_id,
'myskills' => $myskills
]);
}
我们可以用Auth::user先把登入者也就是自己抓出来
然後把query()抓取query string的参数
然後我们要把自己的技能抓出来
在丢回去
自己的技能丢回去是要给作为交换的技能
才会有我们看到的这个画面
对了这边有小提醒!我们在开发时php可以用dd()把变数印出来
前端也可以找个位置用{{}}花括号印在旁边来参考
接者我们有了这些参数後
选择化学跟roni的微积分进行技能交换吧
在看code之前我要提醒大家一件事
我们除了存进资料库外还有一些是要做
比如说我们要新建一笔订单
那麽我们要先跟nodejs的服务沟通
在跟永丰API 沟通完建立完成後
如果有成功我们再把这笔交易存进资料库里
为了沟通我们先使用这个Class吧
use Illuminate\Support\Facades\Http;
Controller/TradeController.php
public function store(Request $request)
{
$targetPoint = Point::find($request->point_id);
$myskillsPoint = Point::query()->where('skill_id', $request->my_skill_id)->get()->first();
$ScoreGap = abs($myskillsPoint->point - $targetPoint['point']);
// 这边是要 计算分数差
$datenow = date('YmdHis');
$OrderNo = "A$datenow" . "1";
$Amount = $ScoreGap * 1000;
// 这边data是php内建函数 可以抓现在时间 我把这当作订单编号
// 最後前面补上A字串最後加上1防止订单错误 (永丰尾数是9会模拟交易失败)
// . 点 是php在接字串的方法 跟javascript + 一样
// amount 的分数差 乘上 一千代表要交易的钱
$result = Http::post('http://localhost:8888/createOrder', [
'OrderNo' => $OrderNo,
'Amount' => $Amount * 100,
]);
// 对了这边补上100是因为永丰会把尾数去掉两个0
// 我们这边把 可以在laravel做post
// 这个是我们nodejs的建立订单的api
// 最後我们简单判断如果result有回传version == 1.0.0代表我们有建立订单成功
// 接者再把订单存进资料库的动作
if ($result['Version'] == "1.0.0") {
$trade = Trade::create([
'target_user_id' => $targetPoint['user_id'],
'user_id' => $myskillsPoint->user_id,
'skill_id' => $targetPoint['skill_id'],
'my_skill_id' => $myskillsPoint->skill_id, 'shopNo' => $OrderNo, 'amount' => $Amount
]);
return response(['trade' => $trade, 'nonce' => $result['Nonce'], 'msg' => $result['Message']]);
// return response($response);
}
// dd($response);
return "交易失败";
}
补充
我们可以观察这个表
透过这两个分数表的技能分数相减
可以得到2喔
(roni 的微积分 跟admin的化学)
好啦我们来看结果吧!!
画面有点长XD
但是为了表现有成功
把network教出来给大家看
小提醒: Chrome开发工具打开network可以帮助我们看APi 是否有叫成功喔!!
接者使用者就可以进到付款画面喽
我们先新建一个纪录个人所有交易的路由
Route::get('trades/record', 'TradeController@record');
接者去调整controller
public function record(Request $request)
{
if (!Auth::check()) {
return view('user.login');
}
$user = Auth::user();
$myresult = DB::table('trades')
->join('users', 'trades.target_user_id', '=', 'users.id')
->join('skills', 'skills.id', '=', 'trades.skill_id')
->where('trades.user_id', $user->id)->select('trades')
->select(
'users.name as target_user_name',
'skills.title as tatget_skill_title',
'ShopNo',
'amount',
'trades.created_at'
)
->get();
// $target_user_id = $myresult['target_user_id'];
// $target_user = User::find($target_user_id);
return view('trade.record', ['result' => $myresult]);
}
这边用query builder的功能把sql串在一起
我们要把对方使用者名称跟技能做联表查询
回传的名称可以用as就可以变更名称
最後再把订单编号、价钱、订单日期回传回来
我们可以先用dd来看回传资料
给大家看对照比较好懂
接者我们就把index画面补上吧
@extends('layout')
@section('content')
<div>
<table class="table table-bordered">
<thead>
<tr>
<th>交易对象</th>
<th>交易技能名称</th>
<th>订单编号</th>
<th>价钱</th>
<th>交易时间</th>
</tr>
</thead>
<tbody>
@foreach($result as $res)
<tr>
<td>{{$res->target_user_name}}</td>
<td>{{$res->tatget_skill_title}}</td>
<td>{{$res->ShopNo}}</td>
<td>{{$res->amount}}</td>
<td>{{$res->created_at}}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
@endsection
接者就是成果拉
接者让大家看一下
我本来是希望可以把自己有的技能以技能树呈现出来给跟别人交换
但是案於时间关系没有把它串完
可以让大家看一下用d3js做的图
使用d3js可以把既能呈现成这种形状并且无限延伸
好啦
今天总结突然爆了一堆程序码
相信大家也看得头昏眼花了
先给大家程序码联结有兴趣的可以玩看看喔
Laravel 的程序码
这边有一些地方可以跟大家分享
今天你得主服务可能是laravel可能是spring
但是其他小的服务比如说machine用python我们使用flask接
或是使用nodejs来串
那这些小型的微服务好处是把耦合性分离
不会因为一个service坏了整个系统
也很好把逻辑分开
但缺点是需要有人去维护处理
还有沟通之间的资安风险喔!!
最後如果要看每一天的篇章可以回到首篇来参考喔感谢大家!!
感谢这几天有follow我的观众们!
看完我整包专案
应该可以对以下概念有所了解
我把一些重点篇章整理出来可以
由下方参考找到篇章喔
最後真的很感谢大家观看
最後一篇章1万5千多字的超长文XD
有兴趣陪我一起技术可以透过我github找我信箱写信喔!
如果喜欢我的分享可以帮我按赞喔XD
<<: Angular 深入浅出三十天:表单与测试 Day30 - 表单原理
Vulnerability assessment tools用於保护组织的系统或网络 我们可以使用这...
前言 昨日我们介绍函式组件如何使用,并且学会了JSX灵活的操作。 今天我们来学习很重要的传递资料Pr...
JQuery是由JavaScript所开发的开源函式库,主要有以下功能大受好评而列入主流。 被简化的...
上偏加入字串空的 String all =""; 这里多了餐选的,饮料选的,全部...
附codepen网址: https://codepen.io/pwbzvqja/pen/GRWNV...