上次徵集了HTML視覺化編輯工具的意見,扎心了,暫時先放一放,作為我專案的一個控制元件用好了。
我現在想重啟另外一個專案,大家幫忙看看可行不?
用Vuetify + laravel實現一個後臺管理框架,同時支援移動版跟PC版。現在實現了一大部分了,只是沒有釋出。
目標是,通過簡單的PHP程式碼,就可以做成一個應用。一些,目前實現供功能:
1、登陸
2、使用者管理
角色及許可權管理
相應程式碼:
class AdminList extends DataTablePage{
protected $title = '管理員列表';
function editPage(){
return AdminEdit::make();
}
function register(){
parent::register();
$this->breadcrumbs->textItem('系統管理')
->textItem('使用者管理')
->textItem('管理員');
$this->hiddenBy('users_module');
$this->hiddenBy('admin_setting');
}
function columns(){
return [
//VularTableColumn::make('id','ID'),
VularTableColumn::make('login_name','登入名')
->searchable(),
VularTableColumn::make('name', '名稱')
->sortable()
->searchable(),
VularTableColumn::make('email', '郵箱')
->sortable()
->searchable(),
//->class('text-xs-right'),
//->class('text-xs-right'),
VularTableColumn::make('forbid','狀態'),
VularTableColumn::make('rolesShow','角色'),
VularTableColumn::make('created_at','時間')
->sortable()
//->classes('text-xs-right')
];
}
function onRow($row){
parent::onRow($row);
$normalChip = VularNode::make()//VularNode的屬性會被賦予單元格
->children(VChip::make('正常')
->color('light-blue')
->textColor('white')
->small()
);
$forbidChip = VularNode::make()
->children(VChip::make('禁用')
->color('red')
->textColor('white')
->small()
);
$row->forbid = $row->forbid ? $forbidChip : $normalChip;
$roleChips = VularNode::make();
foreach ($row->roles as $role) {
$roleChips->children(
VChip::make($role->name)
//->color("transparent")
->small()
);
}
// \Log::notice(json_encode($roleChips));
$row->rolesShow = $roleChips;
//return $row;
}
class RoleEdit extends SimpleFormPage{
protected $modelClass = \Water\Vular\Models\Role::class;
protected $newTitle = '新建角色';
protected $editTitle = '角色編輯';
function register(){
parent::register();
$this->breadcrumbs->textItem('系統管理')
->textItem('使用者管理')
->textItem('角色');
}
function fields(){
return [
VTextField::make()
->field('name')
->label('角色名')
->requried()
->unique()
->maxLength(20),
VTextArea::make()
->field('description')
->label('描述')
->rows(3)
->maxLength('500'),
VularTreeSelect::make()
->field('permissions')
->label('許可權選擇')
->flat()
->tile()
->activatable()
->selectable()
->hoverable()
->openOnClick()
->items($this->permissions())
->itemKey('slug')
->style('border-bottom','solid #bbb 1px')
->showFilter(function($value){
return explode(",", $value);
})
->saveFilter(function($value){
$value = array_filter($value, function($slug){
return ($slug & 'vular-per-group-') !== 'vular-per-group-';
});
return implode(",", $value);
}),
VSwitch::make()
->field('forbid')
->label('禁用')
];
}
function permissions(){
$permissions = [];
$permissionClasses = config('vular.permissions');
foreach ($permissionClasses as $permissionClass) {
$permissions = array_merge_recursive($permissions, (new $permissionClass)->toNodes());
}
return $permissions;
}
}
3、訂單管理
相應程式碼:
class OrderList extends DataTablePage{
protected $title = '訂單列表';
function editPage(){
return OrderEdit::make();
}
function register(){
parent::register();
$this->breadcrumbs->textItem('訂單管理')
->textItem('訂單');
$this->filter(TableFilter::make()
->item(function($item){
$item->input(
VTextField::make()
->field('startTime')
->type('date')
->label('最早合同日期')
)
->field('cotract_date')
->min()
->halfWidth();
//->field('name')
})
->item(function($item){
$item->input(
VTextField::make()
->type('date')
->field('endTime')
->label('最晚合同日期')
)
->field('cotract_date')
->max()
->halfWidth();
//->field('name')
})
);
$this->batchMenu()->itemOfDelete()->hiddenBy('order_delete');
}
function columns(){
return [
//VularTableColumn::make('id','ID'),
VularTableColumn::make('cotract_no', '合同號')
->sortable()
->searchable(),
//->class('text-xs-right'),
VularTableColumn::make('customers.name','客戶')
->sortable()
->searchable(),
//->class('text-xs-right'),
VularTableColumn::make('contract_amount','合同金額')
->sortable(),
//VularTableColumn::make('collection_value','已收賬款'),
VularTableColumn::make('collection_percent','收款比例')
->sortable(),
VularTableColumn::make('royalty_amount','已付提成')
->sortable(),
VularTableColumn::make('cotract_date','合同日期')
->sortable(),
VularTableColumn::make('passed','狀態')
->sortable(),
VularTableColumn::make('user','業務員')
->hiddenBy('order_user_column')
->sortable(),
];
}
function onRow($row){
parent::onRow($row);
$normalChip = VularNode::make()//VularNode的屬性會被賦予單元格
->children(VChip::make('完成')
->light()
->textColor('white')
->small()
);
$waitingChip = VularNode::make()
->children(VChip::make('未完成')
->color('red')
->textColor('white')
->small()
);
//\Log::notice(json_encode($row));
$row->passed = $row->passed ? $normalChip : $waitingChip;
$row->collection_percent = number_format($row->collection_percent,0);
$row->collection_percent = $row->collection_percent > 99?100: $row->collection_percent;
$row->collection_percent = $row->collection_percent . '%';
}
function queryBuilder(){
return \DB::table('orders')
->join('customers', 'customers.id', '=', 'orders.customer_id')
->leftJoin('admins', 'admins.id', '=', 'orders.user_id')
->select('orders.*','customers.name as customers.name','admins.name as user')
->selectRaw('
(orders.first_collection_amount + ifnull(orders.second_collection_amount,0))*100/orders.contract_amount as collection_percent
'
);
}
function appendToQuery($queryBuilder){
$queryBuilder->orderBy('passed','asc')
->orderBy('cotract_date','desc');
$user = user();
if($user->isPermitted('order_all_data')){
return $queryBuilder;
}
return $queryBuilder->where('orders.user_id', $user->id);
}
function rowEditButton($btn, $row){
//$btn->hiddenBy('order_edit')
return $btn->disabled($row->passed && !user()->isPermitted('order_edit_passed'));
}
function rowDeleteButton($btn, $row){
return $btn->hiddenBy('order_delete');
}
}
class OrderEdit extends OneColumnFormPage{
protected $modelClass = \Water\Vular\Order\Models\Order::class;
protected $newTitle = '新建訂單';
protected $editTitle = '訂單編輯';
function register(){
parent::register();
$this->breadcrumbs->textItem('訂單管理')
->textItem('訂單');
//$dbModel = $this->dbModel();
$this->bottomButton(
VBtn::make(trans('vular.finished'))
->large()
->round()
->light()
->valid()
->color('orange')
//->disabled(!$dbModel || ($dbModel&&$dbModel->passed))
->hiddenBy('order_pass')
//->disabledBy('order_pass')
->click(
VularAction::make()
->action('pass')
->post()
->valid()
->bindsTo($this->form)
)
);
//$this->permitActionBy('save','order_save');
//$this->permitActionBy('saveAndContinue','order_save');
}
function cards(){
return[
VularFormGridCard::make()
->title('客戶合同')
->flex(
VSelect::make()
->field('customer')
->label('客戶')
->items($this->customers())
->prependInnerIcon('account_box')
//->belongsTo()
->requried(),
'xs4'
)
->flex(
VTextField::make()
->field('cotract_date')
->label('合同日期')
->prependInnerIcon("today")
->type('date')
->requried(),
'xs4'
)
->flex(
VTextField::make()
->field('cotract_no')
->label('合同號')
->prefix("#")
->requried()
->unique()
->maxLength(20),
'xs4'
)
->flex(
VSelect::make()
->field('payment_mode')
->label('付款方式')
->prependInnerIcon('payment')
->items(['T/T 100%/0%','T/T 30%/70%','T/T 20%/80%','T/T 10%/90%','T/T 0%/100%','LC at sight', 'DP at sight'])
->requried(),
'xs4'
)
->flex(
VSelect::make()
->field('currency')
->label('幣種')
->prependInnerIcon('monetization_on')
->items([
['id'=>'Dollar', 'name'=>'美元'],
['id'=>'Euro', 'name'=>'歐元'],
['id'=>'RMB', 'name'=>'人民幣']
])
->requried()
,
'xs4'
)
->flex(
VTextField::make()
->field('contract_amount')
->label('合同金額')
->prependInnerIcon("attach_money")
->float()
->requried(),
'xs4'
)
->flex(
VTextArea::make()
->field('goods_description')
//->prependInnerIcon('description')
->label('貨物描述')
->rows(3)
->requried(),
'xs12'
)
->flex(
VTextField::make()
->field('estimated_shipping_date')
->label('預計發貨日期')
->prependInnerIcon("today")
->type('date'),
'xs3'
)
->flex(
VTextField::make()
->field('estimated_arrival_date')
->label('預計到港日期')
->prependInnerIcon("today")
->type('date'),
'xs3'
)
->flex(
VTextField::make()
->field('shipping_date')
->label('實際發貨日期')
->prependInnerIcon("today")
->type('date'),
'xs3'
)
->flex(
VTextField::make()
->field('arrival_date')
->label('實際到港日期')
->prependInnerIcon("today")
->type('date'),
'xs3'
)
->flex(
VTextField::make()
->field('first_collection_date')
->label('第一次收匯日期')
->prependInnerIcon("today")
->type('date'),
'xs4'
)
->flex(
VTextField::make()
->field('first_collection_amount')
->label('第一次收匯金額')
->prependInnerIcon("attach_money")
->float(),
'xs4'
)
->flex(
VTextField::make()
->field('first_exchange_rate')
->label('結匯匯率')
->prependInnerIcon('trending_up')
->float(),
'xs4'
)
->flex(
VTextField::make()
->field('second_collection_date')
->label('第二次收匯日期')
->prependInnerIcon("today")
->type('date')
,
'xs4'
)
->flex(
VTextField::make()
->field('second_collection_amount')
->label('第二次收匯金額')
->prependInnerIcon("attach_money")
->float(),
'xs4'
)
->flex(
VTextField::make()
->field('second_exchange_rate')
->label('結匯匯率')
->prependInnerIcon('trending_up')
->float()
,
'xs4'
)
->flex(
VTextArea::make()
->field('remarks')
->label('備註')
->rows(2),
'xs12'
)
,
VularFormHasManyCard::make()
->title('工廠合同')
->field('factoryOrders')
->flex(
VSelect::make()
->field('supplier')
->label('工廠')
->items(Supplier::orderBy('name')->get())
->prependInnerIcon('portrait')
//->belongsTo()
->requried(),
'xs4'
)
->flex(
VTextField::make()
->field('cotract_date')
->label('合同日期')
->prependInnerIcon('today')
->type('date')
->requried(),
'xs4'
)
->flex(
VTextField::make()
->field('cotract_no')
->label('合同號')
->prefix('#')
->requried()
->unique()
->maxLength(20),
'xs4'
)
->flex(
VSelect::make()
->field('payment_mode')
->label('付款方式')
->prependInnerIcon('payment')
->items(['T/T 100%/0%','T/T 30%/70%','T/T 20%/80%','T/T 10%/90%','T/T 0%/100%'])
->requried(),
'xs4'
)
->flex(
VSelect::make()
->field('currency')
->label('幣種')
->prependInnerIcon('monetization_on')
->items([
['id'=>'RMB', 'name'=>'人民幣'],
['id'=>'Dollar', 'name'=>'美元'],
['id'=>'Euro', 'name'=>'歐元']
])
->requried(),
'xs4'
)
->flex(
VTextField::make()
->field('contract_amount')
->prependInnerIcon("attach_money")
->label('合同金額')
->float()
->requried(),
'xs4'
)
->flex(
VTextArea::make()
->field('goods_description')
->label('貨物描述')
->rows(3)
->maxLength(500)
->requried(),
'xs12'
)
->flex(
VTextField::make()
->field('estimated_delivery_date')
->label('預計發貨時間')
->prependInnerIcon("today")
->type('date')
,
'xs6'
)
->flex(
VTextField::make()
->field('delivery_date')
->label('實際發貨時間')
->prependInnerIcon("today")
->type('date')
,
'xs6'
)
->flex(
VTextField::make()
->field('first_pay_date')
->label('第一次付款日期')
->prependInnerIcon("today")
->type('date')
,
'xs4'
)
->flex(
VTextField::make()
->field('first_pay_amount')
->label('第一次付款金額')
->prependInnerIcon("attach_money")
->float(),
'xs4'
)
->flex(
VTextField::make()
->field('first_pay_exchange_rate')
->label('匯率')
->prependInnerIcon('trending_up')
->float()
,
'xs4'
)
->flex(
VTextField::make()
->field('second_pay_date')
->label('第二次付款日期')
->prependInnerIcon("today")
->type('date')
,
'xs4'
)
->flex(
VTextField::make()
->field('second_pay_amount')
->label('第二次付款金額')
->prependInnerIcon("attach_money")
->float(),
'xs4'
)
->flex(
VTextField::make()
->field('second_pay_exchange_rate')
->label('匯率')
->prependInnerIcon('trending_up')
->float()
,
'xs4'
)
->flex(
VTextField::make()
->field('export_rebate')
->label('退稅金額')
->prependInnerIcon("attach_money")
->float(),
'xs12'
)
->flex(
VTextArea::make()
->field('remarks')
->label('備註')
->maxLength(500)
->rows(2),
'xs12'
),
VularFormHasManyCard::make('table')
->title('訂單費用')
->field('fees')
->flex(
VTextField::make()
->field('pay_date')
->label('付款日期')
->prependInnerIcon("today")
->type('date')
,
'xs6'
)
->flex(
VTextField::make()
->field('name')
->label('名稱')
->prependInnerIcon('payment')
->requried()
,
'xs6'
)
->flex(
VSelect::make()
->field('currency')
->label('幣種')
->prependInnerIcon('monetization_on')
->items([
['id'=>'RMB', 'name'=>'人民幣'],
['id'=>'Dollar', 'name'=>'美元'],
['id'=>'Euro', 'name'=>'歐元']
])
->requried()
,
'xs4'
)
->flex(
VTextField::make()
->field('amount')
->label('金額')
->prependInnerIcon("attach_money")
->requried()
->float()
,
'xs4'
)
->flex(
VTextField::make()
->field('exchange_rate')
->label('匯率')
->prependInnerIcon('trending_up')
->float()
,
'xs4'
)
->flex(
VTextArea::make()
->field('remarks')
->label('備註')
->rows(2)
,
'xs12'
)
,
VularFormGridCard::make()
->title('提成核算')
->flex(
VTextField::make()
//->field('xxx')
->label('毛利')
->disabled()
->defaultValue(number_format($this->grossProfit(),2)),
'xs6'
)
->flex(
VSlider::make()
->field('royalty_rate')
->label('提成比例')
->thumbLabel('always')
->step(5),
'xs6'
)
->flex(
VTextField::make()
//->field('')
->label('應付提成')
->disabled()
->defaultValue(number_format($this->royalty(),2)),
'xs6'
)
->flex(
VTextField::make()
->field('royalty_amount')
->label('實付提成')
->float(),
'xs6'
)
];
}
function pass($viewModel){
return $this->doSave($viewModel, function($dbModel){
$dbModel->passed = true;
})
->success()
->closePage();
}
function beforeSave($dbModel){
$dbModel->passed = false;
if(!$dbModel->id){
$dbModel->user()->associate(user());
}
return $dbModel;
}
function customers(){
$user = user();
if($user->isPermitted('customer_all_data')){
return Customer::orderBy('name')->get();
}
return Customer::where('user_id', $user->id)->orderBy('name')->get();
}
//計算毛利
protected function grossProfit($model = null){
if(!$this->modelId()){
return 0;
}
$model = $model ? $model : $this->dbModel();
//<----------------
//已收RMB賬款
$firstRmbAmount = $model->first_exchange_rate? $model->first_collection_amount * $model->first_exchange_rate: $model->first_collection_amount;
$secondRmbAmount = $model->second_exchange_rate? $model->second_collection_amount * $model->second_exchange_rate: $model->second_collection_amount;
$collectionRmbAmount = $firstRmbAmount + $secondRmbAmount;
//<------------
//已付RMB貨款
$rmbPayment = 0;
foreach ($model->factoryOrders as $factoryOrder) {
$firstPayment = $factoryOrder->first_pay_exchange_rate? $factoryOrder->first_pay_amount * $factoryOrder->first_pay_exchange_rate : $factoryOrder->first_pay_amount;
$secondPayment = $factoryOrder->second_pay_exchange_rate? $factoryOrder->second_pay_amount * $factoryOrder->second_pay_exchange_rate : $factoryOrder->second_pay_amount;
$rmbPayment += ($firstPayment + $secondPayment - $factoryOrder->export_rebate);
}
//已付RMB費用
$rmbFee = 0;
foreach ($model->fees as $fee) {
$feeAmount = $fee->exchange_rate ? $fee->amount * $fee->exchange_rate : $fee->amount;
$rmbFee += $feeAmount;
}
return $collectionRmbAmount - $rmbPayment - $rmbFee;
}
//己算提成
protected function royalty(){
if(!$this->modelId()){
return 0;
}
$model = $this->dbModel();
return ($this->grossProfit($model) * $model->royalty_rate)/100;
}
protected function modelId(){
return request('id');
}
protected function dbModel(){
$modelClass =$this->modelClass;
//\Log::notice($modelClass);
return $modelClass::find($this->modelId());
}
}
4、文章管理
程式碼我就不貼了,基於Vuetify的特性,還可以做移動版應用。
這個框架,我要是把它整理好,釋出出來,有用嗎?
支援關聯編輯,跟編輯屬性一樣方便。
本作品採用《CC 協議》,轉載必須註明作者和本文連結