Explorar el Código

外部设备租赁

李浩杰 hace 4 años
padre
commit
727df534df
Se han modificado 42 ficheros con 1359 adiciones y 189 borrados
  1. 2 1
      app/Http/Controllers/Admin/TestController.php
  2. 128 6
      app/Http/Controllers/Api/mini/OrderController.php
  3. 4 2
      app/Http/Controllers/Api/mini/WorkPointController.php
  4. 34 0
      app/Models/Order.php
  5. 28 1
      app/Models/ProjectRole.php
  6. 31 0
      database/migrations/2020_12_11_031046_add_can_check_to_project_roles.php
  7. 30 0
      database/migrations/2020_12_11_031532_add_key_to_project_roles.php
  8. 31 0
      database/migrations/2020_12_11_074108_add_date_to_order_devices.php
  9. 107 31
      database/seeds/MiniSeeder.php
  10. 16 3
      database/seeds/ProjectRoleSeeder.php
  11. 8 1
      mini/app.js
  12. 26 4
      mini/app.json
  13. 25 0
      mini/app.wxss
  14. 0 39
      mini/components/navbar/index.js
  15. 0 9
      mini/components/navbar/index.wxml
  16. 0 32
      mini/components/navbar/index.wxss
  17. 38 0
      mini/custom-tab-bar/index.js
  18. 4 0
      mini/custom-tab-bar/index.json
  19. 5 0
      mini/custom-tab-bar/index.wxml
  20. 71 0
      mini/pages/account/index.js
  21. 0 1
      mini/pages/account/index.json
  22. 4 0
      mini/pages/account/index.wxml
  23. 1 0
      mini/pages/account/index.wxss
  24. 151 10
      mini/pages/create-order/index.js
  25. 39 17
      mini/pages/create-order/index.wxml
  26. 7 1
      mini/pages/create-order/index.wxss
  27. 66 0
      mini/pages/data/index.js
  28. 3 0
      mini/pages/data/index.json
  29. 2 0
      mini/pages/data/index.wxml
  30. 1 0
      mini/pages/data/index.wxss
  31. 1 0
      mini/pages/index/index.js
  32. 1 2
      mini/pages/index/index.wxml
  33. 215 0
      mini/pages/order-detail/index.js
  34. 4 0
      mini/pages/order-detail/index.json
  35. 100 0
      mini/pages/order-detail/index.wxml
  36. 54 0
      mini/pages/order-detail/index.wxss
  37. 73 5
      mini/pages/order/index.js
  38. 17 8
      mini/pages/order/index.wxml
  39. 4 2
      mini/pages/project/index.js
  40. 3 3
      mini/utils/http.js
  41. 20 11
      mini/utils/util.js
  42. 5 0
      routes/api.php

+ 2 - 1
app/Http/Controllers/Admin/TestController.php

xqd xqd
@@ -4,6 +4,7 @@ namespace App\Http\Controllers\Admin;
 
 use App\Models\Order;
 use App\Models\OrderDevice;
+use App\Models\ProjectRole;
 use App\Models\ProjectUser;
 use App\Models\User;
 use Carbon\Carbon;
@@ -15,7 +16,7 @@ class TestController extends Controller
 {
     public function index(Request $request)
     {
-        dd(Order::all()->random());
+        dd(ProjectRole::getByKey('machine', 'id'));
     	return view('admin.test.index');
     }
 }

+ 128 - 6
app/Http/Controllers/Api/mini/OrderController.php

xqd xqd xqd xqd xqd
@@ -7,6 +7,8 @@ use App\Models\Option;
 use App\Models\Order;
 use App\Models\OrderDevice;
 use App\Models\Project;
+use App\Models\ProjectRole;
+use App\Models\ProjectUser;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Log;
@@ -25,12 +27,14 @@ class OrderController extends BaseController
         $project = Project::find($request->input('project_id'));
         if(!$project) return $this->error(['msg' => '找不到项目']);
         $user = Auth::guard('mini')->user();
-        $project_role_id = $project->getCreateProjectRoleId($user, $request->input('is_draft'));
+        $project_role_id = $request->input('is_draft') == 1 ? ProjectRole::getByKey('work', 'id') : ProjectRole::getByKey('machine', 'id');
+        $option = Option::get('orders', 'status', 'checking');
+
         $order = Order::create([
             'work_point_id' => $request->input('work_point_id'),
             'remark' => $request->input('remark'),
             'is_draft' => $request->input('is_draft'),
-            'status' => $this->model->getOrderStatus($project, $user, $request->input('is_draft')),
+            'status' => $option,
             'order_number' => $this->model->createOrderNumber(),
             'project_id' => $project->id,
             'user_id' => $user->id,
@@ -46,7 +50,46 @@ class OrderController extends BaseController
                 'order_id' => $order->id,
                 'device_id' => $device['type_id'],
                 'quantity' => $device['quantity'],
-                'price' => $price
+                'price' => $price,
+                'start_date' => $device['start_date'],
+                'end_date' => $device['end_date']
+            ]);
+            $total = $total + ($price * (int)$device['quantity']);
+        }
+        $order->update(['money' => $total]);
+        return $this->success();
+    }
+
+    public function update(Request $request)
+    {
+        $order = $this->model->find($request->input('id'));
+        if(!$order) return $this->error(['msg' => '找不到订单']);
+        $user = Auth::guard('mini')->user();
+        $project_role_id = $request->input('is_draft') == 1 ? ProjectRole::getByKey('work', 'id') : ProjectRole::getByKey('machine', 'id');
+        $option = Option::get('orders', 'status', 'checking');
+        $res = $order->update([
+            'work_point_id' => $request->input('work_point_id'),
+            'remark' => $request->input('remark'),
+            'is_draft' => $request->input('is_draft'),
+            'status' => $option,
+            'order_number' => $this->model->createOrderNumber(),
+            'user_id' => $user->id,
+            'project_role_id' => $project_role_id
+        ]);
+        if(!$res) return $this->error(['msg' => '订单修改失败']);
+        $devices = $request->input('devices');
+        $total = 0;
+        OrderDevice::where('order_id', '=', $order->id)->delete();
+        foreach($devices as $device) {
+            $price = $this->transMoney($device['price']);
+            OrderDevice::create([
+                'name' => $device['name'],
+                'order_id' => $order->id,
+                'device_id' => $device['type_id'],
+                'quantity' => $device['quantity'],
+                'price' => $price,
+                'start_date' => $device['start_date'],
+                'end_date' => $device['end_date']
             ]);
             $total = $total + ($price * (int)$device['quantity']);
         }
@@ -56,7 +99,7 @@ class OrderController extends BaseController
 
     public function get(Request $request)
     {
-        $items = $this->model->where('project_id', $request->input('project_id'));
+        $items = $this->model->where('project_id', $request->input('project_id'))->where('is_draft', 2);
         if($request->input('status')) {
             $status = Option::get('orders', 'status', $request->input('status'));
             if($status) $items = $items->where('status', $status);
@@ -75,10 +118,89 @@ class OrderController extends BaseController
                 $device->type = $device->device ? $device->device->name : '';
             }
             $item->user_name = $item->user ? $item->user->name : '';
-            $item->status = Option::getById($item->status, 'name');
-            $item->date_time = substr($item->created_at, 0, 16);
+            $this->formatOrder($item);
             $item->work_point_name = $item->workPoint ? $item->workPoint->name : '';
         }
         return $this->success(['data' => $items->items()]);
     }
+
+
+    public function formatOrder($item)
+    {
+        $option = Option::find($item->status);
+        $item->status = $item->getStatusName();
+        $item->status_key = $option ? $option['key'] : '';
+        $item->color = $option ? $option['color'] : '';
+        $item->date_time = substr($item->created_at, 0, 16);
+    }
+
+    public function detail(Request $request)
+    {
+        $order = $this->model->with('project', 'workPoint', 'devices', 'user')->find($request->input('id'));
+        if(!$order) return $this->error(['msg' => '找不到订单']);
+        $this->formatOrder($order);
+        return $this->success(['data' => $order]);
+    }
+
+    public function getRole(Request $request)
+    {
+        $user = Auth::guard('mini')->user();
+        $order = $this->model->find($request->input('id'));
+        if(!$order) return $this->error(['msg' => '找不到订单']);
+        $project_user = ProjectUser::where([
+            ['project_id', '=', $order->project_id],
+            ['user_id', '=', $user->id]
+        ])->with('projectRole')->first();
+        return $this->success(['data' => $project_user]);
+    }
+
+    public function check(Request $request)
+    {
+        $user = Auth::guard('mini')->user();
+        $order = $this->model->find($request->input('id'));
+        if(!$order) return $this->error(['msg' => '找不到订单']);
+        $project_user = ProjectUser::where([
+            ['project_id', '=', $order->project_id],
+            ['user_id', '=', $user->id]
+        ])->first();
+        if(!$project_user) return $this->error(['msg' => '找不到用户']);
+        $project_role = ProjectRole::find($project_user->project_role_id);
+        if(!$project_role) return $this->error(['msg' => '找不到角色']);
+        $status = Option::get('orders', 'status', $request->input('type'));
+
+        // 工区负责人确认通过
+        if($request->input('type') == 'confirm') {
+            $status = Option::get('orders', 'status', 'pass');
+            $next_project_role_id = $project_role->id;
+        } else if($request->input('type') == 're-submit') {
+            $status = Option::get('orders', 'status', 'checking');
+            $next_project_role_id = $project_role->getNext('id');
+        } else {
+            if($request->input('type') == 'reject' || $project_role->key == 'manager') {
+                $next_project_role_id = ProjectRole::getByKey('work', 'id');
+            } else {
+                $next_project_role_id = $project_role->getNext('id');
+            }
+        }
+        $res = $order->update([
+            'status' => $status,
+            'last_project_role_id' => $project_role->id,
+            'project_role_id' => $next_project_role_id
+        ]);
+        if($res) return $this->success();
+        return $this->error(['msg' => '操作失败']);
+    }
+
+    public function changePrice(Request $request)
+    {
+        $order_device = OrderDevice::find($request->input('id'));
+        if(!$order_device) return $this->error(['msg' => '找不到设备']);
+        $order_device->update([
+            'price' => $this->transMoney($request->input('price'))
+        ]);
+        $order = $this->model->find($order_device['order_id']);
+        if(!$order) return $this->error(['msg' => '找不到订单']);
+        $order->updateMoney();
+        return $this->success();
+    }
 }

+ 4 - 2
app/Http/Controllers/Api/mini/WorkPointController.php

xqd
@@ -19,10 +19,12 @@ class WorkPointController extends BaseController
         $this->model = new WorkPoint();
     }
 
-    public function get()
+    public function get(Request $request)
     {
         $items = $this->model->get();
-        $items = $items->prepend(collect(['id' => '0', 'name' => '所有需求工点']));
+        if($request->has('is_search')) {
+            $items = $items->prepend(collect(['id' => '0', 'name' => '所有需求工点']));
+        }
         return $this->success(['data' => $items]);
     }
 }

+ 34 - 0
app/Models/Order.php

xqd xqd
@@ -25,11 +25,21 @@ class Order extends BaseModel
         return $this->belongsTo('App\Models\User', 'user_id');
     }
 
+    public function project()
+    {
+        return $this->belongsTo('App\Models\Project', 'project_id');
+    }
+
     public function workPoint()
     {
         return $this->belongsTo('App\Models\WorkPoint', 'work_point_id');
     }
 
+    public function devices()
+    {
+        return $this->belongsToMany('App\Models\Device', 'order_devices', 'order_id', 'device_id')->withPivot('name', 'quantity', 'price', 'start_date', 'end_date', 'id');
+    }
+
     public function getOrderStatus(Project $project, $user, $is_draft)
     {
         if($is_draft) {
@@ -40,4 +50,28 @@ class Order extends BaseModel
         }
         return Option::get('orders', 'status', 'checking');
     }
+
+    public function getStatusName()
+    {
+        $option = Option::find($this['status']);
+        if(!$option) return '';
+        if($option['key'] == 'checking') return $option['name'];
+        else if(in_array($option['key'], ['checked', 'reject'])) {
+            $project_role = ProjectRole::find($this['last_project_role_id']);
+            return $project_role ? $project_role->name . ' - ' . $option['name'] : $option['name'];
+        } else if($option['key'] == 'pass') {
+            return '提交人 - 已确定';
+        }
+        return '';
+    }
+
+    public function updateMoney()
+    {
+        $total = 0;
+        $devices = OrderDevice::where('order_id', '=', $this['id'])->get();
+        foreach($devices as $device) {
+            $total = $total + ($device['price'] * (int)$device['quantity']);
+        }
+        $this->update(['money' => $total]);
+    }
 }

+ 28 - 1
app/Models/ProjectRole.php

xqd
@@ -4,5 +4,32 @@ namespace App\Models;
 
 class ProjectRole extends BaseModel
 {
-    //
+    /**
+     * @param $key
+     * 工区负责人(work)
+     * 机电负责人(machine)
+     * 项目副经理(assist)
+     * 项目经理(manager)
+     * 管理员子账号(sub)
+     * 领导账号(leader)
+     * 管理员(admin)
+     * @param $column
+     * @return mixed
+     */
+    public static function getByKey($key, $column = null)
+    {
+        $role = self::where('key', $key)->first();
+        if($column) return $role ? $role[$column] : '';
+        return $role;
+    }
+
+    public function getNext($column = null, $inner = false)
+    {
+        $need_check = $inner ? 'need_check_inner' : 'need_check';
+        $item = $this->where([
+            [$need_check, '=', 1],
+            ['id', '>', $this['id']]
+        ])->first();
+        return $column ? ($item ? $item[$column] : '') : $item;
+    }
 }

+ 31 - 0
database/migrations/2020_12_11_031046_add_can_check_to_project_roles.php

xqd
@@ -0,0 +1,31 @@
+<?php
+
+use Illuminate\Support\Facades\Schema;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Migrations\Migration;
+
+class AddCanCheckToProjectRoles extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('project_roles', function (Blueprint $table) {
+            $table->tinyInteger('need_check')->nullable()->before('created_at')->comment('需要审核外部租赁1是,2否');
+            $table->tinyInteger('need_check_inner')->nullable()->before('created_at')->comment('需要审核内部借用1是,2否');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        //
+    }
+}

+ 30 - 0
database/migrations/2020_12_11_031532_add_key_to_project_roles.php

xqd
@@ -0,0 +1,30 @@
+<?php
+
+use Illuminate\Support\Facades\Schema;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Migrations\Migration;
+
+class AddKeyToProjectRoles extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('project_roles', function (Blueprint $table) {
+            $table->string('key', 50)->nullable()->before('created_at');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        //
+    }
+}

+ 31 - 0
database/migrations/2020_12_11_074108_add_date_to_order_devices.php

xqd
@@ -0,0 +1,31 @@
+<?php
+
+use Illuminate\Support\Facades\Schema;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Migrations\Migration;
+
+class AddDateToOrderDevices extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('order_devices', function (Blueprint $table) {
+            $table->date('start_date')->nullable()->before('created_at');
+            $table->date('end_date')->nullable()->before('created_at');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        //
+    }
+}

+ 107 - 31
database/seeds/MiniSeeder.php

xqd xqd
@@ -31,19 +31,15 @@ class MiniSeeder extends Seeder
         }
 
         // 创建项目角色
-        \App\Models\ProjectRole::truncate();
-        for($i = 1; $i < $total; ++$i) {
-            \App\Models\ProjectRole::create([
-                'name' => '项目角色' . $i,
-                'level' => $i
-            ]);
-        }
+        $this->call([
+            ProjectRoleSeeder::class
+        ]);
 
         // 创建项目,为项目分配用户和项目角色
         \App\Models\Project::truncate();
         \App\Models\ProjectUser::truncate();
-        $users = \App\Models\User::limit(3)->get();
-        $project_roles = \App\Models\ProjectRole::limit(3)->get();
+        $users = \App\Models\User::limit(7)->get();
+        $project_roles = \App\Models\ProjectRole::limit(7)->get();
         for($i = 1; $i < $total; ++$i) {
             $project = \App\Models\Project::create([
                 'name' => '项目' . ($i + 2)
@@ -83,39 +79,119 @@ class MiniSeeder extends Seeder
         \App\Models\Order::truncate();
         \App\Models\OrderDevice::truncate();
         $project = \App\Models\Project::first();
-        $statuses = \App\Models\Option::get('orders', 'status');
         $work_points = \App\Models\WorkPoint::all();
         $user = \App\Models\User::first();
         $devices = \App\Models\Device::all();
-        for($i = 1; $i < $total * 2; ++$i) {
-            $project_role = $project_roles->random();
-            $is_draft = collect([1, 2])->random();
-            $status = $statuses->random()->id;
+
+        // 草稿
+        for($i = 1; $i < $total; ++$i) {
             $order = \App\Models\Order::create([
                 'work_point_id' => $work_points->random()->id,
-                'is_draft' => $is_draft,
-                'status' => $status,
+                'is_draft' => 1,
+                'status' => \App\Models\Option::get('orders', 'status', 'checking'),
                 'order_number' => \App\Models\Order::createOrderNumber(),
                 'project_id' => $project->id,
                 'user_id' => $user->id,
-                'project_role_id' => $project_role->id
+                'project_role_id' => $project_roles->first()->id,
             ]);
 
-            $money = 0;
-
-            for($j = 1; $j < 3; ++$j) {
-                $quantity = mt_rand(1, 5);
-                $price = mt_rand(1, 10) * 1000;
-                $money = $money + $quantity * $price;
-                \App\Models\OrderDevice::create([
-                    'name' => '设备' . $j,
-                    'order_id' => $order->id,
-                    'device_id' => $devices->random()->id,
-                    'quantity' => $quantity,
-                    'price' => $price
-                ]);
+            $this->createOrderDevice($order, $devices);
+        }
+
+        // 待审核,checking
+        for($i = 1; $i < $total; ++$i) {
+            $order = \App\Models\Order::create([
+                'work_point_id' => $work_points->random()->id,
+                'is_draft' => 2,
+                'status' => \App\Models\Option::get('orders', 'status', 'checking'),
+                'order_number' => \App\Models\Order::createOrderNumber(),
+                'project_id' => $project->id,
+                'user_id' => $user->id,
+                'project_role_id' => $project_roles->first()->id,
+            ]);
+
+            $this->createOrderDevice($order, $devices);
+        }
+
+        // 已审核,checked
+        for($i = 1; $i < $total; ++$i) {
+            $last_project_role = $project_roles->whereIn('key', ['machine', 'assist', 'manager'])->random();
+            $project_role = $project_roles->where('key', 'work')->first();
+            if($last_project_role->key != 'manager') {
+                $project_role = $project_roles->where('need_check', 1)->where('level', '>', $last_project_role->level)->first();
             }
-            $order->update(['money' => $money]);
+            $order = \App\Models\Order::create([
+                'work_point_id' => $work_points->random()->id,
+                'is_draft' => 2,
+                'status' => \App\Models\Option::get('orders', 'status', 'checked'),
+                'order_number' => \App\Models\Order::createOrderNumber(),
+                'project_id' => $project->id,
+                'user_id' => $user->id,
+                'project_role_id' => $project_role->id,
+                'last_project_role_id' => $last_project_role->id,
+            ]);
+
+            $this->createOrderDevice($order, $devices);
+        }
+
+        // 已完成,pass
+        for($i = 1; $i < $total; ++$i) {
+
+            $last_project_role = $project_roles->where('key', 'manager')->first();
+            $project_role = $project_roles->where('key', 'work')->first();
+            $order = \App\Models\Order::create([
+                'work_point_id' => $work_points->random()->id,
+                'is_draft' => 2,
+                'status' => \App\Models\Option::get('orders', 'status', 'pass'),
+                'order_number' => \App\Models\Order::createOrderNumber(),
+                'project_id' => $project->id,
+                'user_id' => $user->id,
+                'project_role_id' => $project_role->id,
+                'last_project_role_id' => $last_project_role->id
+            ]);
+
+            $this->createOrderDevice($order, $devices);
+        }
+
+        // 已驳回,pass
+        for($i = 1; $i < $total; ++$i) {
+            $last_project_role = $project_roles->whereIn('key', ['machine', 'assist', 'manager'])->random();
+            $project_role = $project_roles->where('key', 'work')->first();
+            $order = \App\Models\Order::create([
+                'work_point_id' => $work_points->random()->id,
+                'is_draft' => 2,
+                'status' => \App\Models\Option::get('orders', 'status', 'reject'),
+                'order_number' => \App\Models\Order::createOrderNumber(),
+                'project_id' => $project->id,
+                'user_id' => $user->id,
+                'project_role_id' => $project_role->id,
+                'last_project_role_id' => $last_project_role->id
+            ]);
+
+            $this->createOrderDevice($order, $devices);
+        }
+    }
+
+    public function createOrderDevice(\App\Models\Order $order, \Illuminate\Support\Collection $devices)
+    {
+        $money = 0;
+
+        for($j = 1; $j < 3; ++$j) {
+            $start_date = \Carbon\Carbon::now()->addDay(mt_rand(1, 4))->toDateString();
+            $end_date = \Carbon\Carbon::now()->addDay(mt_rand(5, 10))->toDateString();
+            $quantity = mt_rand(1, 5);
+            $price = mt_rand(1, 10) * 1000;
+            $money = $money + $quantity * $price;
+            \App\Models\OrderDevice::create([
+                'name' => '设备' . $j,
+                'order_id' => $order['id'],
+                'device_id' => $devices->random()->id,
+                'quantity' => $quantity,
+                'price' => $price,
+                'start_date' => $start_date,
+                'end_date' => $end_date
+            ]);
         }
+        $order->update(['money' => $money]);
     }
 }

+ 16 - 3
database/seeds/ProjectRoleSeeder.php

xqd
@@ -11,11 +11,24 @@ class ProjectRoleSeeder extends Seeder
      */
     public function run()
     {
+        $roles = [
+            ['name' => '工区负责人', 'key' => 'work', 'need_check' => 2, 'need_check_inner' => 2],
+            ['name' => '机电负责人', 'key' => 'machine', 'need_check' => 1, 'need_check_inner' => 2],
+            ['name' => '项目副经理', 'key' => 'assist', 'need_check' => 1, 'need_check_inner' => 1],
+            ['name' => '项目经理', 'key' => 'manager', 'need_check' => 1, 'need_check_inner' => 1],
+            ['name' => '管理员子账号', 'key' => 'sub', 'need_check' => 2, 'need_check_inner' => 2],
+            ['name' => '领导账号', 'key' => 'leader', 'need_check' => 2, 'need_check_inner' => 2],
+            ['name' => '管理员', 'key' => 'admin', 'need_check' => 2, 'need_check_inner' => 1]
+        ];
+
         \App\Models\ProjectRole::truncate();
-        for($i = 0; $i < 10; ++$i) {
+        foreach ($roles as $key => $role) {
             \App\Models\ProjectRole::create([
-                'name' => '角色' . ($i + 2),
-                'level' => ($i + 1)
+                'name' => $role['name'],
+                'level' => ($key + 1),
+                'key' => $role['key'],
+                'need_check' => $role['need_check'],
+                'need_check_inner' => $role['need_check_inner']
             ]);
         }
     }

+ 8 - 1
mini/app.js

xqd
@@ -48,12 +48,19 @@ App({
   },
   loginCallback: function(data) {
     this.updateUserInfo(data)
-    wx.redirectTo({
+    wx.switchTab({
       url: '/pages/index/index',
     })
   },
   updateUserInfo: function(info) {
     this.globalData.userInfo = info
     wx.setStorageSync('sg-userinfo', info)
+  },
+  logout: function(res) {
+    this.globalData.userInfo = null
+    wx.setStorageSync('sg-userinfo', null)
+    wx.navigateTo({
+      url: '/pages/login/index'
+    })
   }
 })

+ 26 - 4
mini/app.json

xqd xqd
@@ -1,15 +1,35 @@
 {
   "pages": [
-    "pages/order/index",
     "pages/index/index",
     "pages/project/index",
+    "pages/order/index",
+    "pages/order-detail/index",
+    "pages/account/index",
     "pages/create-order/index",
     "pages/create-project-role/index",
     "pages/project-user/index",
     "pages/create-project/index",
     "pages/login/index",
-    "pages/logs/logs"
+    "pages/logs/logs",
+    "pages/data/index"
   ],
+  "tabBar": {
+    "custom": true,
+		"color": "#000000",
+		"selectedColor": "#5693FC",
+		"backgroundColor": "#000000",
+    "list": [
+      {
+        "pagePath": "pages/index/index"
+      },
+      {
+        "pagePath": "pages/data/index"
+      },
+      {
+        "pagePath": "pages/account/index"
+      }
+    ]
+  },
   "window": {
     "backgroundTextStyle": "light",
     "navigationBarBackgroundColor": "#5693FC",
@@ -21,10 +41,12 @@
     "van-button": "@vant/weapp/button/index",
     "van-field": "@vant/weapp/field/index",
     "van-divider": "@vant/weapp/divider/index",
-    "navbar": "/components/navbar",
     "van-icon": "@vant/weapp/icon/index",
     "van-search": "@vant/weapp/search/index",
     "van-dialog": "@vant/weapp/dialog/index",
-    "van-popup": "@vant/weapp/popup/index"
+    "van-popup": "@vant/weapp/popup/index",
+    "van-calendar": "@vant/weapp/calendar/index",
+    "van-tabbar": "@vant/weapp/tabbar/index",
+		"van-tabbar-item": "@vant/weapp/tabbar-item/index"
   }
 }

+ 25 - 0
mini/app.wxss

xqd xqd xqd xqd xqd xqd
@@ -42,6 +42,9 @@
 .sg-bold {
   font-weight: bold;
 }
+.sg-border {
+  border: 1px solid #ebedf0;
+}
 .sg-bottom-border {
   border-bottom: 1px solid #ebedf0;
 }
@@ -51,6 +54,9 @@
 .sg-border-right {
   border-right: 1px solid #ebedf0;
 }
+.sg-margin {
+  margin: 30rpx;
+}
 .sg-margin-top-sm {
   margin-top: 30rpx;
 }
@@ -63,6 +69,9 @@
 .sg-margin-tb {
   margin: 30rpx 0;
 }
+.sg-pad-tb {
+  padding: 30rpx 0;
+}
 .sg-margin-tb-sm {
   margin: 15rpx 0;
 }
@@ -72,6 +81,9 @@
 .sg-icon-img {
   width: 50rpx;
 }
+.sg-font-lg {
+  font-size: 1.2rem;
+}
 .sg-font-xs {
   font-size: 0.8rem;
 }
@@ -134,6 +146,10 @@
   background: #ee0a24;
   color: white;
 }
+.sg-green-bg {
+  background: #07c160;
+  color: white;
+}
 .sg-fix-bottom {
   width: 100%;
   position: fixed;
@@ -149,4 +165,13 @@
   left: 0;
   top: 0;
   width: 100%;
+}
+.sg-calendar .van-calendar {
+  z-index: 3000;
+}
+.sg-flex-column {
+  flex-direction: column;
+}
+.sg-block {
+  width: 100%;
 }

+ 0 - 39
mini/components/navbar/index.js

xqd
@@ -1,39 +0,0 @@
-// components/navbar/index.js
-Component({
-  /**
-   * 组件的属性列表
-   */
-  properties: {
-
-  },
-
-  /**
-   * 组件的初始数据
-   */
-  data: {
-    activeMenu: 'index',
-    menus: [{
-      name: '首页',
-      img: 'https://t18.9026.com/mini/index',
-      key: 'index',
-      url: '/pages/index/index'
-    }, {
-      name: '数据中心',
-      img: 'https://t18.9026.com/mini/data',
-      key: 'data',
-      url: '/pages/data/index'
-    }, {
-      name: '个人中心',
-      img: 'https://t18.9026.com/mini/account',
-      key: 'account',
-      url: '/pages/account/index'
-    }]
-  },
-
-  /**
-   * 组件的方法列表
-   */
-  methods: {
-
-  }
-})

+ 0 - 9
mini/components/navbar/index.wxml

xqd
@@ -1,9 +0,0 @@
-<!--components/navbar/index.wxml-->
-<view class="sg-nav-box">
-  <view class="sg-nav-list">
-    <view class="sg-nav-item {{ activeMenu == item.key ? 'sg-selected sg-primary-color' : '' }}" wx:for="{{ menus }}" wx:key="index" data-url="{{ item.url }}" data-index="{{index}}" data-key="{{item.key}}">
-      <image src="{{ activeMenu == item.key ? item.img + '-selected.png' : item.img + '.png' }}" mode="widthFix" class="sg-img"></image>
-      <view class="sg-name">{{ item.name }}</view>
-    </view>
-  </view>
-</view>

+ 0 - 32
mini/components/navbar/index.wxss

xqd
@@ -1,32 +0,0 @@
-/* components/navbar/index.wxss */
-.sg-nav-box .sg-img {
-  width: 40rpx;
-}
-.sg-nav-box {
-  position: fixed;
-  bottom: 0;
-  left: 0;
-  width: 100%;
-  padding: 10rpx 0;
-  border-top: 1px solid #ebedf0;
-  font-size: 0.8rem;
-  z-index: 1000;
-  background: white;
-}
-.sg-nav-box .sg-nav-list {
-  display: flex;
-  align-items: center;
-  justify-content: space-around;
-}
-.sg-nav-box .sg-nav-list .sg-nav-item {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  justify-content: center;
-}
-.sg-nav-item .sg-name {
-  margin-top: 5rpx;
-}
-.sg-nav-item.sg-selected {
-  color: #5693FC;
-}

+ 38 - 0
mini/custom-tab-bar/index.js

xqd
@@ -0,0 +1,38 @@
+Component({
+	data: {
+		active: 2,
+		list: [
+			{
+				icon: 'home-o',
+				text: '首页',
+				url: '/pages/index/index'
+			},
+			{
+				icon: 'bar-chart-o',
+				text: '数据中心',
+				url: '/pages/data/index'
+			},
+			{
+				icon: 'user-o',
+				text: '个人中心',
+				url: '/pages/account/index'
+			}
+		]
+	},
+
+	methods: {
+		onChange(event) {
+			this.setData({ active: event.detail });
+			wx.switchTab({
+				url: this.data.list[event.detail].url
+			});
+		},
+
+		init() {
+			const page = getCurrentPages().pop();
+			this.setData({
+				active: this.data.list.findIndex(item => item.url === `/${page.route}`)
+			});
+		}
+	}
+});

+ 4 - 0
mini/custom-tab-bar/index.json

xqd
@@ -0,0 +1,4 @@
+{
+	"component": true,
+	"usingComponents": {}
+}

+ 5 - 0
mini/custom-tab-bar/index.wxml

xqd
@@ -0,0 +1,5 @@
+<van-tabbar active="{{ active }}" bind:change="onChange">
+  <van-tabbar-item wx:for="{{ list }}" wx:key="index" icon="{{ item.icon }}">{{
+    item.text
+  }}</van-tabbar-item>
+</van-tabbar>

+ 71 - 0
mini/pages/account/index.js

xqd
@@ -0,0 +1,71 @@
+// pages/account/index.js
+var app = getApp()
+Page({
+
+  /**
+   * 页面的初始数据
+   */
+  data: {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面加载
+   */
+  onLoad: function (options) {
+
+  },
+
+  logout() {
+    app.logout()
+  },
+
+  /**
+   * 生命周期函数--监听页面初次渲染完成
+   */
+  onReady: function () {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面显示
+   */
+  onShow: function () {
+    this.getTabBar().init();
+  },
+
+  /**
+   * 生命周期函数--监听页面隐藏
+   */
+  onHide: function () {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面卸载
+   */
+  onUnload: function () {
+
+  },
+
+  /**
+   * 页面相关事件处理函数--监听用户下拉动作
+   */
+  onPullDownRefresh: function () {
+
+  },
+
+  /**
+   * 页面上拉触底事件的处理函数
+   */
+  onReachBottom: function () {
+
+  },
+
+  /**
+   * 用户点击右上角分享
+   */
+  onShareAppMessage: function () {
+
+  }
+})

+ 0 - 1
mini/components/navbar/index.json → mini/pages/account/index.json

xqd
@@ -1,4 +1,3 @@
 {
-  "component": true,
   "usingComponents": {}
 }

+ 4 - 0
mini/pages/account/index.wxml

xqd
@@ -0,0 +1,4 @@
+<!--pages/account/index.wxml-->
+<view class="sg-container">
+  <van-button type="primary" block bind:click="logout">退出登录</van-button>
+</view>

+ 1 - 0
mini/pages/account/index.wxss

xqd
@@ -0,0 +1 @@
+/* pages/account/index.wxss */

+ 151 - 10
mini/pages/create-order/index.js

xqd xqd xqd xqd xqd
@@ -21,25 +21,94 @@ Page({
     typeIndex: -1,
     device_name: '',
     device_quantity: '',
-    device_price: ''
+    device_price: '',
+    showDate: false,
+    start_date: '',
+    end_date: '',
+    order_id: '',
+    // create/edit
+    type: 'create',
+    order: {},
+    selectIndex: -1,
+    // create/edit
+    dialog_type: 'create',
+    default_dates: []
   },
 
   /**
    * 生命周期函数--监听页面加载
    */
   onLoad: function (options) {
+    options = {
+      id: 1,
+      order_id: 99,
+      type: 'edit'
+    }
     var id = options.id ? options.id : 1
+    var type = options.type ? options.type : 'create'
+    var order_id = options.order_id ? options.order_id : ''
     this.setData({
-      id
+      id,
+      type,
+      order_id
     })
     api.getProject(this)
     api.getByName(this, 'work-points/get', 'work_points');
     api.getByName(this, 'devices/get', 'device_types');
+    if(order_id) {
+      var that = this
+      api.getByName(this, 'orders/detail', 'order', {id: order_id}, function(res) {
+        that.initData()
+      });
+      wx.setNavigationBarTitle({
+        title: '修订订单',
+      })
+    }
+  },
+
+  selectDevice: function(e) {
+    var newIndex = e.currentTarget.dataset.index == this.data.selectIndex ? -1 : e.currentTarget.dataset.index
+    this.setData({
+      selectIndex: newIndex
+    })
+  },
+  
+  initData: function() {
+    var order = this.data.order,
+    work_points = this.data.work_points,
+    pointIndex = this.data.pointIndex
+
+    for(var i = 0; i < work_points.length; ++i) {
+      if(work_points[i].id == order.work_point_id) {
+        pointIndex = i;
+        break;
+      }
+    }
+    var devices = order.devices
+    var local_devices = []
+    for(var i = 0; i < devices.length; ++i) {
+      var device = devices[i]
+      local_devices.push({
+        name: device.pivot.name,
+        type_name: device.name,
+        type_id: device.id,
+        quantity: device.pivot.quantity,
+        price: device.pivot.price / 100,
+        start_date: device.pivot.start_date,
+        end_date: device.pivot.end_date
+      })
+    }
+    this.setData({
+      pointIndex,
+      remark: order.remark,
+      devices: local_devices
+    })
   },
 
   submit: function(e) {
     var type = e.currentTarget.dataset.type
     var is_draft = type == 'draft' ? 1 : 2
+    var submit_type = this.data.type
     if(this.data.pointIndex < 0) {
       util.error('需求工点必填');
       return false;
@@ -49,9 +118,11 @@ Page({
       return false;
     }
     var work_point = this.data.work_points[this.data.pointIndex]
+    var url = submit_type == 'create' ? 'orders/create' : 'orders/update'
     http({
-      url: 'orders/create',
+      url: url,
       data: {
+        id: this.data.order_id,
         project_id: this.data.id,
         work_point_id: work_point.id,
         remark: this.data.remark,
@@ -72,12 +143,40 @@ Page({
     })
   },
 
-  deleteDevice: function(e) {
+  deleteDevice: function() {
     var devices = this.data.devices
-    var index = e.currentTarget.dataset.index
+    var index = this.data.selectIndex
     devices.splice(index, 1)
     this.setData({
-      devices
+      devices,
+      selectIndex: -1
+    })
+  },
+
+  editDevice: function() {
+    var devices = this.data.devices
+    var index = this.data.selectIndex
+    if(index < 0) return false
+    var device = devices[index]
+    var typeIndex = -1
+    var device_types = this.data.device_types
+    var default_dates = [device.start_date, device.end_date]
+    for(var i = 0; i < device_types.length; ++i) {
+      if(device_types[i].id == device.type_id) {
+        typeIndex = i;
+        break;
+      }
+    }
+    this.setData({
+      device_name: device.name,
+      typeIndex,
+      start_date: device.start_date,
+      end_date: device.end_date,
+      device_quantity: device.quantity,
+      device_price: device.price,
+      showAdd: true,
+      dialog_type: 'edit',
+      default_dates: default_dates
     })
   },
 
@@ -98,15 +197,27 @@ Page({
       util.error('设备单价必填')
       return false
     }
+    if(!this.data.start_date) {
+      util.error('租赁时间必填')
+      return false
+    }
     var devices = this.data.devices
     var type = this.data.device_types[this.data.typeIndex]
-    devices.push({
+    var device = {
       name: this.data.device_name,
       type_name: type.name,
       type_id: type.id,
       quantity: this.data.device_quantity,
-      price: this.data.device_price
-    })
+      price: this.data.device_price,
+      start_date: this.data.start_date,
+      end_date: this.data.end_date
+    }
+    var dialog_type = this.data.dialog_type
+    if(dialog_type == 'create') {
+      devices.push(device)
+    } else {
+      devices[this.data.selectIndex] = device
+    }
     this.setData({
       devices
     })
@@ -120,8 +231,38 @@ Page({
   },
 
   switchShowAdd: function(e) {
+    var show = e.currentTarget.dataset.show
+    if(show) {
+      this.setData({
+        device_name: '',
+        typeIndex: -1,
+        start_date: '',
+        end_date: '',
+        device_quantity: '',
+        device_price: '',
+        default_dates: []
+      })
+    }
+    this.setData({
+      showAdd: show,
+      dialog_type: 'create'
+    })
+  },
+
+  switchShowDate: function(e) {
+    this.setData({
+      showDate: e.currentTarget.dataset.show
+    })
+  },
+
+  confirmDate: function(e) {
+    this.switchShowDate(e)
+    var [start_date, end_date] = e.detail;
+    start_date = util.formatDate(start_date)
+    end_date = util.formatDate(end_date)
     this.setData({
-      showAdd: e.currentTarget.dataset.show
+      start_date,
+      end_date
     })
   },
 

+ 39 - 17
mini/pages/create-order/index.wxml

xqd xqd xqd
@@ -2,7 +2,8 @@
 <view class="sg-container">
   <view class="sg-tabs sg-flex sg-align-center sg-space-around">
     <block wx:for="{{tabs}}" wx:key="index">
-      <view class="sg-tab sg-pad {{index == tabIndex ? 'sg-seleted' : 'sg-gray-color'}}" bindtap="switchTab" data-index="{{index}}">{{item}}</view>
+      <view class="sg-tab sg-pad {{index == tabIndex ? 'sg-seleted' : 'sg-gray-color'}}" bindtap="switchTab"
+        data-index="{{index}}">{{item}}</view>
     </block>
   </view>
   <view class="sg-order-box" wx:if="{{tabIndex == 0}}">
@@ -26,32 +27,42 @@
       </view>
     </view>
   </view>
+  <van-calendar show="{{ showDate }}" bind:close="switchShowDate" bind:confirm="confirmDate" data-show="{{false}}"
+    type="range" class="sg-calendar" default-date="{{default_dates}}"/>
   <view class="sg-device-box" wx:if="{{tabIndex == 1}}">
     <view class="sg-device-list sg-top-border">
       <block wx:if="{{devices.length <= 0}}">
         <view class="sg-center sg-pad">暂无设备</view>
       </block>
       <block wx:else>
-        <view class="sg-item sg-flex sg-align-center sg-bottom-border" wx:for="{{devices}}" wx:key="index" bindtap="selectDevice" data-index="{{index}}">
-          <view class="sg-left sg-flex sg-justify-center sg-space-between sg-flex-grow sg-pad">
-            <view class="sg-name">{{item.type_name}}-{{item.name}}</view>
-            <view class="sg-quantity-price sg-gray-color">
-              ¥<text>{{item.price}}</text> × <text>{{item.quantity}}</text>
+        <view class="sg-item sg-flex sg-align-center sg-bottom-border" wx:for="{{devices}}" wx:key="index"
+          bindtap="selectDevice" data-index="{{index}}">
+          <view class="sg-left sg-flex-grow sg-pad sg-flex-column">
+            <view class="sg-left-top sg-flex sg-justify-center sg-space-between">
+              <view class="sg-name">{{item.type_name}}-{{item.name}}</view>
+              <view class="sg-left-right sg-quantity-price sg-gray-color">
+                ¥<text>{{item.price}}</text> × <text>{{item.quantity}}</text>
+              </view>
             </view>
+            <view class="sg-left-bottom sg-gray-color sg-font-xs">{{item.start_date}}至{{item.end_date}}</view>
           </view>
-          <view class="sg-right sg-red-bg sg-pad" bindtap="deleteDevice" data-index="{{index}}">删除</view>
+          <view class="sg-right sg-pad sg-flex sg-align-center sg-icon" bindtap="selectDevice">
+            <van-icon name="passed" wx:if="{{selectIndex == index}}" class="sg-index-color" />
+            <van-icon name="circle" wx:else />
+          </view>
+          <!-- <view class="sg-right sg-red-bg sg-pad sg-flex sg-align-center" bindtap="deleteDevice" data-index="{{index}}">删除</view> -->
         </view>
       </block>
     </view>
   </view>
-  <van-dialog show="{{ showAdd }}" use-slot title="添加设备" show-cancel-button bind:confirm="addDevice">
-    <view class="sg-add-device-box sg-pad">
-      <view class="sg-form-item sg-pad sg-top-border">
+  <van-dialog show="{{ showAdd }}" use-slot title="{{dialog_type == 'create' ? '添加设备' : '修改设备'}}" show-cancel-button bind:confirm="addDevice" z-index="1">
+    <view class="sg-add-device-box sg-pad sg-font-small">
+      <view class="sg-form-item sg-pad-tb sg-top-border">
         <view class="sg-label">设备名称</view>
         <input value="{{device_name}}" class="sg-input" bindinput="onChange" data-name="device_name"
           placeholder="请输入设备名称"></input>
       </view>
-      <view class="sg-form-item sg-pad sg-top-border">
+      <view class="sg-form-item sg-pad-tb sg-top-border">
         <view class="sg-label">设备类型</view>
         <picker bindchange="onChange" value="{{typeIndex}}" range="{{device_types}}" range-key="name"
           data-name="typeIndex" class="sg-input">
@@ -60,22 +71,33 @@
           </view>
         </picker>
       </view>
-      <view class="sg-form-item sg-pad sg-top-border">
+      <view class="sg-form-item sg-pad-tb sg-top-border">
+        <view class="sg-label">租赁时间</view>
+        <input value="{{ start_date ? start_date + '至' + end_date : '' }}" placeholder="请选择租赁时间" class="sg-input"
+          disabled="true" bindtap="switchShowDate" data-show="{{true}}"></input>
+      </view>
+      <view class="sg-form-item sg-pad-tb sg-top-border">
         <view class="sg-label">设备数量</view>
         <input value="{{device_quantity}}" class="sg-input" bindinput="onChange" data-name="device_quantity"
           placeholder="请输入设备数量"></input>
       </view>
-      <view class="sg-form-item sg-pad sg-top-border">
+      <view class="sg-form-item sg-pad-tb sg-top-border">
         <view class="sg-label">设备单价</view>
         <input value="{{device_price}}" class="sg-input" bindinput="onChange" data-name="device_price"
           placeholder="请输入设备单价"></input>
       </view>
     </view>
   </van-dialog>
-  <view class="sg-submit-box sg-pad sg-fix-bottom sg-flex sg-align-center sg-center" wx:if="{{tabIndex == 1}}"
-    bindtap="switchShowAdd" data-show="true">
-    <van-icon name="plus" /><text>立即添加</text>
-  </view>
+  <block wx:if="{{tabIndex == 1}}">
+    <view class="sg-submit-box sg-pad sg-fix-bottom sg-flex sg-align-center sg-center" wx:if="{{selectIndex == -1}}"
+      bindtap="switchShowAdd" data-show="true">
+      <van-icon name="plus" /><text>立即添加</text>
+    </view>
+    <view class="sg-submit-box sg-fix-bottom sg-flex sg-align-center sg-center" wx:else>
+      <view class="sg-action sg-draft sg-pad sg-border-right sg-index-bg sg-white" bindtap="editDevice">编辑</view>
+      <view class="sg-action sg-pad sg-white sg-red-bg" bindtap="deleteDevice">删除</view>
+    </view>
+  </block>
   <view class="sg-submit-box sg-fix-bottom sg-flex sg-align-center sg-center" wx:if="{{tabIndex == 0}}">
     <view class="sg-action sg-draft sg-pad sg-border-right" bindtap="submit" data-type='draft'>暂存</view>
     <view class="sg-action sg-pad sg-index-bg sg-white" bindtap="submit" data-type='save'>提交</view>

+ 7 - 1
mini/pages/create-order/index.wxss

xqd
@@ -36,8 +36,14 @@
 }
 .sg-device-list .sg-item .sg-left {
   display: flex;
-  align-items: center;
+  height: 80rpx;
+}
+.sg-device-list .sg-item .sg-right {
+  height: 80rpx;
 }
 .sg-submit-box .sg-action {
   width: 50%;
+}
+.sg-submit-box.sg-fix-bottom {
+  z-index: 1;
 }

+ 66 - 0
mini/pages/data/index.js

xqd
@@ -0,0 +1,66 @@
+// pages/data/index.js
+Page({
+
+  /**
+   * 页面的初始数据
+   */
+  data: {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面加载
+   */
+  onLoad: function (options) {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面初次渲染完成
+   */
+  onReady: function () {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面显示
+   */
+  onShow: function () {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面隐藏
+   */
+  onHide: function () {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面卸载
+   */
+  onUnload: function () {
+
+  },
+
+  /**
+   * 页面相关事件处理函数--监听用户下拉动作
+   */
+  onPullDownRefresh: function () {
+
+  },
+
+  /**
+   * 页面上拉触底事件的处理函数
+   */
+  onReachBottom: function () {
+
+  },
+
+  /**
+   * 用户点击右上角分享
+   */
+  onShareAppMessage: function () {
+
+  }
+})

+ 3 - 0
mini/pages/data/index.json

xqd
@@ -0,0 +1,3 @@
+{
+  "usingComponents": {}
+}

+ 2 - 0
mini/pages/data/index.wxml

xqd
@@ -0,0 +1,2 @@
+<!--pages/data/index.wxml-->
+<text>pages/data/index.wxml</text>

+ 1 - 0
mini/pages/data/index.wxss

xqd
@@ -0,0 +1 @@
+/* pages/data/index.wxss */

+ 1 - 0
mini/pages/index/index.js

xqd
@@ -22,6 +22,7 @@ Page({
     })
   },
   onShow: function() {
+    this.getTabBar().init();
     this.setData({
       list: []
     })

+ 1 - 2
mini/pages/index/index.wxml

xqd xqd
@@ -10,7 +10,7 @@
       <view class="sg-top-name">成员添加</view>
     </view>
     <view class="sg-top-item sg-font-xs">
-      <van-icon name="delete" class="sg-icon"/>
+      <van-icon name="description" class="sg-icon"/>
       <view class="sg-top-name">草稿箱</view>
     </view>
     <view class="sg-top-item sg-font-xs sg-right-border">
@@ -43,5 +43,4 @@
       </view>
     </view>
   </view>
-  <navbar></navbar>
 </view>

+ 215 - 0
mini/pages/order-detail/index.js

xqd
@@ -0,0 +1,215 @@
+// pages/create-order/index.js
+import http from '../../utils/http'
+import util from '../../utils/util'
+import api from '../../utils/api'
+import Dialog from '../../miniprogram_npm/@vant/weapp/dialog/dialog';
+
+Page({
+
+  /**
+   * 页面的初始数据
+   */
+  data: {
+    tabs: ['设备租赁订单', '租赁设备添加'],
+    tabIndex: 1,
+    id: -1,
+    order: null,
+    device_total: 0,
+    role: null,
+    // 审核(check)|确认(pass)|重新提交(re-submit)
+    actionType: null,
+    changePrice: false,
+    remark: '',
+    order_device: {},
+    showPrice: false,
+    device_price: ''
+  },
+
+  /**
+   * 生命周期函数--监听页面加载
+   */
+  onLoad: function (options) {
+    var id = options.id ? options.id : 49
+    this.setData({
+      id
+    })
+    this.init()
+  },
+
+  onChange: function(e) {
+    var name = e.currentTarget.dataset.name
+    this.setData({
+      [name]: e.detail.value
+    })
+  },
+
+  init() {
+    var that = this
+    var id = this.data.id
+    api.getByName(this, 'orders/detail', 'order', {
+      id: id
+    }, function (res) {
+      that.setData({
+        remark: that.data.order.remark
+      })
+      that.updateDeviceTotal()
+      api.getByName(that, 'orders/getRole', 'role', {
+        id: id
+      }, function (res) {
+        that.updateActionType()
+      });
+    });
+  },
+
+  updateActionType: function () {
+    var actionType = ''
+    var role = this.data.role
+    var order = this.data.order
+    if (order.project_role_id == role.id) {
+      if (['machine', 'assist', 'manager'].indexOf(role.project_role.key) != -1) actionType = 'check'
+      if(order.status_key == 'checked' && role.project_role.key == 'work') actionType = 'pass'
+      if(order.status_key == 'reject' && role.project_role.key == 'work') actionType = 're-submit'
+    }
+    var changePrice = actionType == 'pass' || (actionType == 'check' && role.project_role.key == 'machine')
+    this.setData({
+      actionType,
+      changePrice
+    })
+  },
+
+  changePrice: function() {
+    var order_device = this.data.order_device
+    var price = this.data.device_price
+    var that = this
+    http({
+      url: 'orders/changePrice',
+      data: {
+        id: order_device.pivot.id,
+        price: price
+      },
+      success: function (res) {
+        if (res.code == 0) {
+          that.init()
+        }
+      }
+    })
+  },
+
+  switchShowPrice: function(e) {
+    var data =  e.currentTarget.dataset
+    var show = data.show
+    var item = data.item
+    if(show) {
+      this.setData({
+        order_device: item,
+        device_price: item.pivot.price / 100
+      })
+    }
+    this.setData({
+      showPrice: e.currentTarget.dataset.show
+    })
+  },
+
+  updateDeviceTotal: function () {
+    var total = 0
+    var order = this.data.order
+    var devices = order.devices ? order.devices : []
+    for (var i = 0; i < devices.length; ++i) {
+      total = total + devices[i].pivot.quantity
+    }
+    this.setData({
+      device_total: total,
+      devices: devices
+    })
+  },
+
+  switchTab: function (e) {
+    this.setData({
+      tabIndex: e.currentTarget.dataset.index
+    })
+  },
+
+  check: function(e) {
+    var type = e.currentTarget.dataset.type
+    var that = this
+    var msg = '确认通过审核吗?'
+    if(type == 'reject') msg = '确认驳回申请吗?'
+    else if(type == 'confirm' || type == 're-submit') msg = '确认提交吗?'
+    Dialog.confirm({
+      title: '提示',
+      message: msg,
+    })
+      .then(() => {
+        that.submitCheck(e)
+      })
+  },
+  submitCheck: function (e) {
+    var type = e.currentTarget.dataset.type
+    var that = this
+    http({
+      url: 'orders/check',
+      data: {
+        id: this.data.id,
+        type: type,
+        remark: this.data.remark
+      },
+      success: function (res) {
+        if (res.code == 0) {
+          util.success('操作成功')
+          setTimeout(function() {
+            that.init()
+          }, 1000)
+        }
+      }
+    })
+  },
+
+  /**
+   * 生命周期函数--监听页面初次渲染完成
+   */
+  onReady: function () {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面显示
+   */
+  onShow: function () {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面隐藏
+   */
+  onHide: function () {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面卸载
+   */
+  onUnload: function () {
+
+  },
+
+  /**
+   * 页面相关事件处理函数--监听用户下拉动作
+   */
+  onPullDownRefresh: function () {
+
+  },
+
+  /**
+   * 页面上拉触底事件的处理函数
+   */
+  onReachBottom: function () {
+
+  },
+
+  /**
+   * 用户点击右上角分享
+   */
+  onShareAppMessage: function () {
+
+  }
+})

+ 4 - 0
mini/pages/order-detail/index.json

xqd
@@ -0,0 +1,4 @@
+{
+  "navigationBarTitleText": "订单详情",
+  "usingComponents": {}
+}

+ 100 - 0
mini/pages/order-detail/index.wxml

xqd
@@ -0,0 +1,100 @@
+<!--pages/create-order/index.wxml-->
+<view class="sg-container">
+  <view class="sg-tabs sg-flex sg-align-center sg-space-around">
+    <block wx:for="{{tabs}}" wx:key="index">
+      <view class="sg-tab sg-pad {{index == tabIndex ? 'sg-seleted' : 'sg-gray-color'}}" bindtap="switchTab"
+        data-index="{{index}}">{{item}}</view>
+    </block>
+  </view>
+  <view class="sg-order-box" wx:if="{{tabIndex == 0}}">
+    <view class="sg-form">
+      <view class="sg-form-item sg-pad sg-top-border">
+        <view class="sg-label">项目名称</view>
+        <view class="sg-input sg-gray-color">{{order.project ? order.project.name : ''}}</view>
+      </view>
+      <view class="sg-form-item sg-pad sg-top-border">
+        <view class="sg-label">需求工点</view>
+        <view class="sg-input sg-gray-color">{{order.work_point ? order.work_point.name : ''}}</view>
+      </view>
+      <view class="sg-form-item sg-pad sg-top-border">
+        <view class="sg-label">租赁设备</view>
+        <view class="sg-input sg-gray-color">{{device_total}}个</view>
+      </view>
+      <view class="sg-form-item sg-pad sg-top-border">
+        <view class="sg-label">租赁总金额</view>
+        <view class="sg-input sg-gray-color">¥{{order.money/100}}</view>
+      </view>
+      <view class="sg-form-item sg-pad sg-top-border">
+        <view class="sg-label">填单人</view>
+        <view class="sg-input sg-gray-color">{{order.user ? order.user.name : ''}}</view>
+      </view>
+      <view class="sg-form-item sg-pad sg-top-border">
+        <view class="sg-label">创建时间</view>
+        <view class="sg-input sg-gray-color">{{order.created_at}}</view>
+      </view>
+      <view class="sg-form-item sg-pad sg-top-border">
+        <view class="sg-label">订单状态</view>
+        <view class="sg-input sg-gray-color sg-bold" style="color:{{order.color}}">{{order.status}}</view>
+      </view>
+      <view class="sg-form-item sg-pad sg-top-border">
+        <view class="sg-label">备注</view>
+        <input value="{{remark}}" class="sg-input" bindinput="onChange" data-name="remark" placeholder="订单备注填写"></input>
+      </view>
+    </view>
+  </view>
+  <van-calendar show="{{ showDate }}" bind:close="switchShowDate" bind:confirm="confirmDate" data-show="{{false}}"
+    type="range" class="sg-calendar" />
+  <view class="sg-device-box" wx:if="{{tabIndex == 1}}">
+    <view class="sg-device-list sg-top-border">
+      <block wx:if="{{devices.length <= 0}}">
+        <view class="sg-center sg-pad">暂无设备</view>
+      </block>
+      <block wx:else>
+        <view class="sg-item sg-pad sg-margin" wx:for="{{devices}}" wx:key="index" bindtap="selectDevice"
+          data-index="{{index}}">
+          <view class="sg-title sg-bold">{{index+1}}. 租赁设备详情:{{item.name}} - {{item.pivot ? item.pivot.name : ''}}
+          </view>
+          <view class="sg-content sg-gray-color sg-font-small">
+            <view class="sg-margin-tb-sm">租赁方式:按天计费</view>
+            <view class="sg-margin-tb-sm sg-flex sg-align-center sg-space-between">
+              <view>租赁单价:¥{{item.pivot ? item.pivot.price / 100 : ''}}</view>
+              <view>数量:{{item.pivot ? item.pivot.quantity : ''}}</view>
+            </view>
+            <view class="sg-margin-tb-sm">租赁时间:<text
+                class="sg-rent-date sg-border">{{item.pivot ? (item.pivot.start_date + '至' + item.pivot.end_date) : ''}}</text>
+            </view>
+          </view>
+          <view class="sg-footer sg-flex sg-align-center sg-space-between sg-margin-top-sm">
+            <view class="sg-font-lg sg-bold">总金额:¥{{item.pivot.price * item.pivot.quantity / 100}}</view>
+            <view class="sg-btn sg-index-bg sg-pad-sm sg-white" hidden="{{!changePrice}}" bindtap="switchShowPrice"
+              data-item="{{item}}" data-show="{{true}}">修改价格</view>
+          </view>
+        </view>
+      </block>
+    </view>
+  </view>
+  <view class="sg-submit-box sg-fix-bottom sg-flex sg-align-center sg-center">
+    <block wx:if="{{actionType == 'check'}}">
+      <view class="sg-action sg-draft sg-pad sg-border-right sg-red-bg" bindtap="check" data-type='reject'>驳回申请</view>
+      <view class="sg-action sg-pad sg-index-bg sg-green-bg" bindtap="check" data-type='pass'>通过审核</view>
+    </block>
+    <block wx:if="{{actionType == 'pass'}}">
+      <view class="sg-action sg-draft sg-pad sg-border-right sg-index-bg sg-white sg-block" bindtap="check"
+        data-type='confirm' style="width: 100%">提交确认</view>
+    </block>
+    <block wx:if="{{actionType == 're-submit'}}">
+      <view class="sg-action sg-draft sg-pad sg-border-right sg-index-bg sg-white sg-block" bindtap="check"
+        data-type='re-submit' style="width: 100%">重新提交</view>
+    </block>
+  </view>
+  <van-dialog id="van-dialog" />
+  <van-dialog show="{{ showPrice }}" use-slot title="修改价格" show-cancel-button bind:confirm="changePrice" z-index="1">
+    <view class="sg-box sg-pad">
+      <view class="sg-form-item sg-pad-tb sg-top-border">
+        <view class="sg-label">设备单价</view>
+        <input value="{{device_price}}" class="sg-input" bindinput="onChange" data-name="device_price"
+          placeholder="请输入设备单价" type="number"></input>
+      </view>
+    </view>
+  </van-dialog>
+</view>

+ 54 - 0
mini/pages/order-detail/index.wxss

xqd
@@ -0,0 +1,54 @@
+/* pages/create-order/index.wxss */
+.sg-tabs {
+  background: white;
+}
+.sg-tab {
+  width: 50%;
+  box-sizing: border-box;
+  text-align: center;
+}
+.sg-tab:first-child {
+  border-right: 1px solid #ebedf0;
+}
+.sg-form-item {
+  display: flex;
+  width: 100%;
+  box-sizing: border-box;
+}
+.sg-form-item .sg-label {
+  padding-right: 30rpx;
+  min-width: 150rpx;
+}
+.sg-form-item .sg-input {
+  flex-grow: 1;
+  text-align: right;
+}
+.sg-order-box {
+  background: white;
+}
+.sg-submit-box {
+  justify-content: center;
+  background: white;
+}
+.sg-device-list .sg-item {
+  background: white;
+  align-items: center;
+}
+.sg-device-list .sg-item .sg-left {
+  display: flex;
+  height: 80rpx;
+}
+.sg-device-list .sg-item .sg-right {
+  height: 80rpx;
+}
+.sg-submit-box .sg-action {
+  width: 50%;
+}
+.sg-submit-box.sg-fix-bottom {
+  z-index: 1;
+}
+.sg-rent-date {
+  padding: 5rpx 50rpx;
+  border-radius: 40rpx;
+  border-color: #BFC7D1;
+}

+ 73 - 5
mini/pages/order/index.js

xqd xqd xqd xqd xqd xqd xqd
@@ -2,6 +2,8 @@
 import http from '../../utils/http'
 import util from '../../utils/util'
 import api from '../../utils/api'
+import Dialog from '../../miniprogram_npm/@vant/weapp/dialog/dialog';
+
 Page({
 
   /**
@@ -23,7 +25,11 @@ Page({
     tabIndex: 0,
     touchBottom: [false, false, false, false, false],
     work_points: [],
-    pointIndex: -1
+    pointIndex: -1,
+    isSearch: false,
+    role: '',
+    // list|check
+    type: 'list'
   },
 
   /**
@@ -31,13 +37,57 @@ Page({
    */
   onLoad: function (options) {
     var id = options.id ? options.id : 1
+    var type = options.type ? options.type : 'list'
+    var tabIndex = options.index ? options.index : 0
     this.setData({
-      id
+      id,
+      type,
+      tabIndex
     })
     api.getProject(this)
-    api.getByName(this, 'work-points/get', 'work_points');
+    api.getByName(this, 'work-points/get', 'work_points', {is_search: true});
+    api.getByName(this, 'orders/getRole', 'role', {id: id});
     this.getList();
   },
+  doAction: function(e) {
+    var type = e.currentTarget.dataset.type
+    if(type == 'edit' || type == 'detail') {
+      this.navigate(e)
+    } else if(type == 'confirm') {
+      var that = this
+      var order = e.currentTarget.dataset.order
+      Dialog.confirm({
+        title: '提示',
+        message: '确定订单吗',
+      })
+        .then(() => {
+          that.submitCheck(order)
+        })
+    }
+  },
+
+  submitCheck(order) {
+    var that = this
+    http({
+      url: 'orders/check',
+      data: {
+        id: order.id,
+        type: 'confirm',
+        remark: order.remark
+      },
+      success: function (res) {
+        if (res.code == 0) {
+          that.search()
+        }
+      }
+    })
+  },
+
+  navigate: function(e) {
+    wx.navigateTo({
+      url: e.currentTarget.dataset.url,
+    })
+  },
 
   search() {
     this.setData({
@@ -50,6 +100,7 @@ Page({
       ],
       pages: [1, 1, 1, 1, 1],
       touchBottom: [false, false, false, false, false],
+      isSearch: true
     })
     this.getList()
   },
@@ -81,7 +132,8 @@ Page({
           }
           that.setData({
             touchBottom,
-            list
+            list,
+            isSearch: false
           })
         }
       }
@@ -93,6 +145,11 @@ Page({
     this.setData({
       tabIndex: index
     })
+    wx.pageScrollTo({
+      scrollTop: 0,
+      duration: 300
+    })
+    this.search()
   },
 
   onChange: function (e) {
@@ -141,7 +198,18 @@ Page({
    * 页面上拉触底事件的处理函数
    */
   onReachBottom: function () {
-
+    var index = this.data.tabIndex
+    if(!this.data.isSearch && !this.data.touchBottom[index]) {
+      var pages = this.data.pages
+      pages[index] = pages[index] + 1;
+      this.setData({
+        pages
+      })
+      this.getList()
+    }
+    if(this.data.touchBottom[index]) {
+      util.error('没有更多数据了')
+    }
   },
 
   /**

+ 17 - 8
mini/pages/order/index.wxml

xqd xqd xqd
@@ -1,8 +1,8 @@
 <!--pages/order/index.wxml-->
 <view class="sg-container">
   <view class="sg-top-box sg-fix-top">
-    <view class="sg-search-box sg-pad sg-flex sg-align-center sg-margin">
-      <view class="sg-left sg-flex-grow sg-border">
+    <view class="sg-search-box sg-pad sg-flex sg-align-center">
+      <view class="sg-left sg-flex-grow">
         <picker bindchange="onChange" value="{{pointIndex}}" range="{{work_points}}" range-key="name"
           data-name="pointIndex" class="sg-input">
           <view class="picker sg-gray-color sg-center">
@@ -14,17 +14,17 @@
     </view>
     <view class="sg-tabs sg-flex sg-align-center sg-white-bg sg-pad sg-bottom-border sg-top-border sg-font-small">
       <view wx:for="{{tabs}}" wx:key="index" class="sg-tab {{tabIndex == index ? 'sg-selected' : ''}}"
-        bindtap="switchTab" data-index="{{index}}">{{ item }}</view>
+        bindtap="switchTab" data-index="{{index}}" hidden="{{ type=='check' && index > 2 }}">{{ item }}</view>
     </view>
   </view>
   <view class="sg-list-box sg-pad">
-    <view class="sg-list" wx:for="{{list}}" wx:if="{{tabIndex == index}}" wx:key="index">
+    <view class="sg-list" wx:for="{{list}}" hidden="{{tabIndex != index}}" wx:key="index">
       <view class="sg-item sg-white-bg sg-pad sg-margin-bottom sg-font-small" wx:for="{{item}}" wx:for-item="i_item"
-        wx:for-index="i_index" wx:key="i_index">
+        wx:for-index="i_index" wx:key="i_index" data-url="/pages/order-detail/index?id={{i_item.id}}" bindtap="navigate">
         <view class="sg-top sg-bottom-border">
-          <view class="sg-order-status sg-flex sg-align-center sg-space-between sg-margin-bottom">
+          <view class="sg-order-status sg-flex sg-align-center sg-space-between sg-margin-bottom sg-font-xs">
             <view class="sg-order sg-gray-color">订单号:{{i_item.order_number}}</view>
-            <view class="sg-status">{{i_item.status}}</view>
+            <view class="sg-status sg-bold" style="color: {{i_item.color}}">{{i_item.status}}</view>
           </view>
           <view class="sg-device-info">
             <view class="sg-label">租借设备概要:</view>
@@ -42,9 +42,18 @@
             <view class="sg-left-item sg-margin-tb-sm">提交人:{{i_item.user_name}}</view>
             <view class="sg-left-item sg-margin-tb-sm">创建时间:{{i_item.date_time}}</view>
           </view>
-          <view class="sg-right sg-index-bg sg-pad-sm sg-white">查看详情</view>
+          <block wx:if="{{i_item.status=='项目经理 - 已审核' && role && role.project_role.key == 'work'}}">
+            <view class="sg-right sg-green-bg sg-pad-sm sg-white" catchtap="doAction" data-type="confirm" data-order="{{i_item}}">确认订单</view>
+          </block>
+          <block wx:elif="{{i_item.status_key=='reject'}}">
+            <view class="sg-right sg-red-bg sg-pad-sm sg-white" catchtap="doAction" data-type="edit" data-url="/pages/create-order/index?id={{i_item.project_id}}&order_id={{i_item.id}}&type=edit">重新修订</view>
+          </block>
+          <block wx:else>
+            <view class="sg-right sg-index-bg sg-pad-sm sg-white" catchtap="doAction" data-type="detail" data-url="/pages/order-detail/index?id={{i_item.id}}">查看详情</view>
+          </block>
         </view>
       </view>
     </view>
   </view>
+  <van-dialog id="van-dialog" />
 </view>

+ 4 - 2
mini/pages/project/index.js

xqd
@@ -19,11 +19,13 @@ Page({
     }, {
       img: 'http://t18.9026.com/mini/rent-check.png',
       title: '租赁审核',
-      desc: '设备租赁订单审核'
+      desc: '设备租赁订单审核',
+      url: '/pages/order/index?type=check'
     }, {
       img: 'http://t18.9026.com/mini/error-handle.png',
       title: '异常处理',
-      desc: '订单流程变更审核处理'
+      desc: '订单流程变更审核处理',
+      url: '/pages/order/index?index=4'
     }, {
       img: 'http://t18.9026.com/mini/all-order.png',
       title: '所有订单',

+ 3 - 3
mini/utils/http.js

xqd
@@ -41,9 +41,9 @@ const http = (data) => {
           icon: 'none'
         })
         if(res.data.code == -100) {
-          wx.navigateTo({
-            url: '/pages/login/index',
-          })
+          // wx.navigateTo({
+          //   url: '/pages/login/index',
+          // })
         }
       }
       typeof data.success === "function" && data.success(res.data)

+ 20 - 11
mini/utils/util.js

xqd xqd
@@ -1,12 +1,21 @@
-const formatTime = date => {
-  const year = date.getFullYear()
-  const month = date.getMonth() + 1
-  const day = date.getDate()
-  const hour = date.getHours()
-  const minute = date.getMinutes()
-  const second = date.getSeconds()
-
-  return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
+const formatDate = (date, fmt = 'yyyy-MM-dd') => {
+  
+  var o = {
+    "M+": date.getMonth() + 1, //月份
+    "d+": date.getDate(), //日
+    "h+": date.getHours() % 12 == 0 ? 12 : date.getHours() % 12, //小时
+    "H+": date.getHours(), //小时
+    "m+": date.getMinutes(), //分
+    "s+": date.getSeconds(), //秒
+    "q+": Math.floor((date.getMonth() + 3) / 3), //季度
+    "S": date.getMilliseconds() //毫秒
+  };
+  if (/(y+)/.test(fmt))
+    fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
+  for (var k in o)
+    if (new RegExp("(" + k + ")").test(fmt))
+      fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
+  return fmt;
 }
 
 const formatNumber = n => {
@@ -32,8 +41,8 @@ const success = msg => {
 }
 
 module.exports = {
-  formatTime: formatTime,
+  formatDate,
   checkMobile: checkMobile,
   error,
   success
-}
+}

+ 5 - 0
routes/api.php

xqd
@@ -43,5 +43,10 @@ $api->version('v1', ['namespace' => 'App\Http\Controllers\Api\mini', 'prefix' =>
     $api->any('devices/get', 'DeviceController@get');
 
     $api->any('orders/create', 'OrderController@create');
+    $api->any('orders/update', 'OrderController@update');
     $api->any('orders/get', 'OrderController@get');
+    $api->any('orders/detail', 'OrderController@detail');
+    $api->any('orders/getRole', 'OrderController@getRole');
+    $api->any('orders/check', 'OrderController@check');
+    $api->any('orders/changePrice', 'OrderController@changePrice');
 });