diff --git a/app/Admin.php b/app/Admin.php index f26526e..0f46077 100644 --- a/app/Admin.php +++ b/app/Admin.php @@ -68,7 +68,7 @@ class Admin extends Authenticatable implements Auditable * @var array */ protected $fillable = [ - 'name', 'username', 'password', + 'name', 'username', 'password','project_ids' ]; /** diff --git a/app/Console/Commands/SyncAlipayRechargeState.php b/app/Console/Commands/SyncAlipayRechargeState.php index 1f7e9b6..5695cac 100644 --- a/app/Console/Commands/SyncAlipayRechargeState.php +++ b/app/Console/Commands/SyncAlipayRechargeState.php @@ -42,7 +42,7 @@ class SyncAlipayRechargeState extends Command { $threshold = 5; $offset_seconds = 40; //支付发起后多少秒开始轮询 - $due_minutes = 10; //支付发起后第一次开始轮询的时间往后延迟5分钟后不再轮询 + $due_minutes = 10; //支付发起后第一次开始轮询的时间往后延迟若干分钟后不再轮询 $last_id = cache("last_sync_alipay_recharge_id", 0); DB::enableQueryLog(); diff --git a/app/Customer.php b/app/Customer.php index 981f758..c6ba5dd 100644 --- a/app/Customer.php +++ b/app/Customer.php @@ -3,6 +3,7 @@ namespace App; use App\Models\Balance; +use App\Models\Orders; use App\Models\Patient; use App\Models\Recharge; use Illuminate\Foundation\Auth\User as Authenticatable; @@ -53,7 +54,7 @@ class Customer extends Authenticatable implements JWTSubject { use Notifiable; - CONST GUARD_NAME = "customer"; + const GUARD_NAME = "customer"; public function guardName() { @@ -120,9 +121,19 @@ class Customer extends Authenticatable implements JWTSubject return $this->hasMany(Balance::class, "customer_id"); } + public function oneBalance() + { + return $this->hasOne(Balance::class, "customer_id"); + } + public function recharges() { return $this->hasMany(Recharge::class, "customer_id")->whereNotNull("paid_at"); } + public function orders() + { + return $this->hasMany(Orders::class, "customer_id"); + } + } diff --git a/app/Exports/OrdersExport.php b/app/Exports/OrdersExport.php new file mode 100644 index 0000000..ead439a --- /dev/null +++ b/app/Exports/OrdersExport.php @@ -0,0 +1,39 @@ +data = $data; + } + + /** + * @return \Illuminate\Support\Collection + */ + public function collection() + { + $res = []; + foreach ($this->data as $row) { + $res[] = [ + "订单编号" => " ".$row->serial, + "所属项目/医院" => $row->project->name, + "客户姓名" => $row->customer->name ?: $row->patient->name, + "联系电话" => " ".$row->customer->mobile, + "被护理人" => $row->patient->name, + "开始服务日期" => $row->from_date, + "结束服务日期" => $row->to_date, + "总计" => $row->total, + "状态" => $row->getStatusLabelAttribute(), + ]; + } + if (count($res)) { + array_unshift($res, array_keys($res[0])); + } + return collect($res); + } +} diff --git a/app/Forms/AdminForm.php b/app/Forms/AdminForm.php index c1e514f..c4d38d4 100755 --- a/app/Forms/AdminForm.php +++ b/app/Forms/AdminForm.php @@ -2,6 +2,7 @@ namespace App\Forms; +use App\Models\Project; use Kris\LaravelFormBuilder\Form; use Kris\LaravelFormBuilder\Field; @@ -12,6 +13,7 @@ class AdminForm extends Form $this->add("name", Field::TEXT, ["label" => "姓名", "rules" => "required"]); $this->add("username", Field::TEXT, ["label" => "用户名", "rules" => "required", "attr" => ["autocomplete" => "off"]]); $this->add("password", Field::PASSWORD, ["label" => "密码", "rules" => "min:6", "value" => "", "attr" => ["autocomplete" => "off"]]); + $this->add("project_id", Field::SELECT, ["label" => "管辖项目/医院", "rules" => "required", "attr" => ["multiple" => true, "data-plugin" => "select2"], "choices" => (new Project())->get()->pluck("name", "id")->toArray()]); $this->add('buttons', 'buttongroup', ["splitted" => true, "buttons" => [ ["label" => "保存", "attr" => ["class" => "btn btn-primary mr-1", "type" => "submit"]], ["label" => "返回", "attr" => ["class" => "btn btn-light btn-back", "type" => "button"]] diff --git a/app/Forms/ManagerForm.php b/app/Forms/ManagerForm.php index 2abb5e8..08ebeed 100755 --- a/app/Forms/ManagerForm.php +++ b/app/Forms/ManagerForm.php @@ -14,6 +14,10 @@ class ManagerForm extends Form "teacher" => "管理老师", "manager" => "项目经理" ]]); + $this->add("order_status_ability", Field::SELECT, ["label" => "订单恢复权限", "choices" => [ + "0" => "不开放", + "1" => "开放" + ]]); $this->add("project_id", Field::SELECT, ["label" => "管辖项目/医院", "rules" => "required", "attr" => ["multiple" => true, "data-plugin" => "select2"], "choices" => (new Project())->get()->pluck("name", "id")->toArray()]); $this->add("name", Field::TEXT, ["label" => "姓名", "rules" => "required"]); diff --git a/app/Forms/ParamedicForm.php b/app/Forms/ParamedicForm.php index b8ffceb..9c07649 100755 --- a/app/Forms/ParamedicForm.php +++ b/app/Forms/ParamedicForm.php @@ -14,6 +14,8 @@ class ParamedicForm extends Form $this->add("mobile", Field::TEXT, ["label" => "电话", "rules" => "required"]); $this->add("serial", Field::TEXT, ["label" => "编号", "rules" => "required"]); $this->add("avatar", Field::TEXT, ["label" => "照片", "attr" => ["data-plugin" => "uploader"]]); + $this->add("health_certificate", Field::TEXT, ["label" => "健康证", "attr" => ["data-plugin" => "uploader"]]); + $this->add("work_certificate", Field::TEXT, ["label" => "护理员证", "attr" => ["data-plugin" => "uploader"]]); $this->add("id_card_number", Field::TEXT, ["label" => "身份证号"]); $this->add("sex", Field::SELECT, ["label" => "性别", "choices" => [ "男" => "男", diff --git a/app/Forms/ProjectForm.php b/app/Forms/ProjectForm.php index 84de7c2..503192a 100755 --- a/app/Forms/ProjectForm.php +++ b/app/Forms/ProjectForm.php @@ -13,6 +13,7 @@ class ProjectForm extends Form $this->add("longitude", Field::HIDDEN); $this->add("name", Field::TEXT, ["label" => "名称", "rules" => "required"]); $this->add("address", Field::TEXT, ["label" => "地址", "rules" => "required"]); + $this->add("percent_first_party", Field::NUMBER, ["label" => "院方结算百分比"]); $this->add("logo", Field::TEXT, ["label" => "logo", "attr" => ["data-plugin" => "uploader"]]); $this->add("banners", Field::TEXT, ["label" => "banner", "attr" => ["data-plugin" => "uploader", "data-multiple-multiple" => 1]]); $this->add("profile", Field::TEXTAREA, ["label" => "简介"]); diff --git a/app/Http/Controllers/Admin/AdminController.php b/app/Http/Controllers/Admin/AdminController.php index 4a612dc..3ced192 100644 --- a/app/Http/Controllers/Admin/AdminController.php +++ b/app/Http/Controllers/Admin/AdminController.php @@ -4,6 +4,7 @@ namespace App\Http\Controllers\Admin; use App\Admin; use App\Forms\AdminForm; +use App\Models\Project; use Illuminate\Http\Request; use Kris\LaravelFormBuilder\FormBuilder; use Spatie\Permission\Models\Role; @@ -19,6 +20,9 @@ class AdminController extends CommonController public function index(Request $request) { $data = $this->model->paginate(20); + foreach ($data as $item) { + $item->projects = Project::whereIn("id", explode(",", $item->project_ids))->get(); + } $roles = (new Role())->where("guard_name", $this->guardName)->get(); return view($this->bladePath . ".index", compact("data", "roles")); @@ -47,4 +51,29 @@ class AdminController extends CommonController return $this->ajaxError("授权失败:" . $exception->getMessage()); } } + + public function stored($model) + { + if (request()->project_id) { + $model->update([ + "project_ids" => implode(",", request()->project_id)]); + } else { + $model->update([ + "project_ids" => null + ]); + } + } + + public function updated($model) + { + if (request()->project_id) { + $model->update([ + "project_ids" => implode(",", request()->project_id) + ]); + } else { + $model->update([ + "project_ids" => null + ]); + } + } } diff --git a/app/Http/Controllers/Admin/CommonController.php b/app/Http/Controllers/Admin/CommonController.php index b1bc340..f75ec71 100644 --- a/app/Http/Controllers/Admin/CommonController.php +++ b/app/Http/Controllers/Admin/CommonController.php @@ -155,7 +155,7 @@ class CommonController extends Controller public function update($id = null, Request $request) { try { - $data = $data = (new CommonModel())->setTable($this->model->getTable())->filterRequestColumns($request, ["id"]); + $data = (new CommonModel())->setTable($this->model->getTable())->filterRequestColumns($request, ["id"]); $model = $this->model->find($id ?: $request->id); $model->update($data); $this->updated($model); diff --git a/app/Http/Controllers/Admin/HomeController.php b/app/Http/Controllers/Admin/HomeController.php index 28fc751..6da2c6f 100644 --- a/app/Http/Controllers/Admin/HomeController.php +++ b/app/Http/Controllers/Admin/HomeController.php @@ -10,20 +10,20 @@ class HomeController extends CommonController public function index() { - $month = date("Y-m"); - $order_items = OrderItems::whereHas("order")->whereRaw("DATE_FORMAT(`service_date`,'%Y-%m') = '{$month}'") - ->where("total", ">", 0)->get(); - $order_items_count = $order_items->count(); - $total = $order_items->sum("total"); - $orders_count = $order_items->groupBy("order_id")->count(); +// $month = date("Y-m"); +// $order_items = OrderItems::whereHas("order")->whereRaw("DATE_FORMAT(`service_date`,'%Y-%m') = '{$month}'") +// ->where("total", ">", 0)->get(); +// $order_items_count = $order_items->count(); +// $total = $order_items->sum("total"); +// $orders_count = $order_items->groupBy("order_id")->count(); +// +// foreach ($order_items as &$item) { +// $item = $item->calculateFee(); +// } +// $total_paramedic = $order_items->sum("paramedic_total"); +// $fee = $total - $total_paramedic; +// $laravel_duration = microtime(true) - LARAVEL_START; - foreach ($order_items as &$item) { - $item = $item->calculateFee(); - } - $total_paramedic = $order_items->sum("paramedic_total"); - $fee = $total - $total_paramedic; - $laravel_duration = microtime(true) - LARAVEL_START; - - return view($this->bladePath . ".home", compact("orders_count", "order_items_count", "total", "total_paramedic", "fee", "laravel_duration")); + return view($this->bladePath . ".home"); } } diff --git a/app/Http/Controllers/Admin/OrdersController.php b/app/Http/Controllers/Admin/OrdersController.php index c6e6324..ec922b4 100755 --- a/app/Http/Controllers/Admin/OrdersController.php +++ b/app/Http/Controllers/Admin/OrdersController.php @@ -8,11 +8,13 @@ namespace App\Http\Controllers\Admin; +use App\Exports\OrdersExport; use App\Models\OrderItems; use App\Models\Orders; use App\Models\Project; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; +use Maatwebsite\Excel\Facades\Excel; class OrdersController extends CommonController { @@ -66,12 +68,18 @@ class OrdersController extends CommonController $query->with(["room", "building"]); } ]) - ->orderBy("id", "desc") - ->paginate(10); + ->orderBy("id", "desc"); + + if (request()->is_export) { + $data = $data->get(); + return Excel::download(new OrdersExport($data), "订单导出.xlsx"); + } + + $data = $data->paginate(10); foreach ($data as $order) { $order = $order->refreshTotal(); } - + dd($data); return view($this->bladePath . ".index", compact("data", "project_id", "month", "project")); } @@ -129,4 +137,36 @@ class OrdersController extends CommonController $order_item = $order_item->calculateFee(); return $this->ajaxResponse($order_item); } + + public function score() + { + $projects = (new StatisticsController())->_checkProjects(); + if (!$projects->count()) { + return $this->error($this->noProjects); + } + $project_id = request()->project_id ?? $projects->first()->id; + $this->model = $this->model->where("project_id", $project_id)->whereNotNull("scored_at"); + if (request()->keyword) { + $this->model = $this->model->where(function ($query) { + $query->where("serial", "like", "%" . request()->keyword . "%") + ->orWhere("contact", "like", "%" . request()->keyword . "%") + ->orWhere("mobile", "like", "%" . request()->keyword . "%"); + }); + } + + $data = $this->model + ->with([ + "orderItems", + "project", + "product", + "customer", + "manager", + "bed" => function ($query) { + $query->with(["room", "building"]); + } + ]) + ->orderBy("id", "desc") + ->paginate(10); + return view($this->bladePath . ".score", compact("data", "project_id")); + } } diff --git a/app/Http/Controllers/Admin/ParamedicController.php b/app/Http/Controllers/Admin/ParamedicController.php index 24011f1..0040ce6 100755 --- a/app/Http/Controllers/Admin/ParamedicController.php +++ b/app/Http/Controllers/Admin/ParamedicController.php @@ -37,7 +37,7 @@ class ParamedicController extends CommonController ->orWhere("id_card_number", "like", "%" . request()->keyword . "%"); }); } - $data = $data->paginate(10); + $data = $data->orderBy("updated_at","desc")->paginate(10); return view($this->bladePath . ".index", compact("data")); } diff --git a/app/Http/Controllers/Admin/ProjectController.php b/app/Http/Controllers/Admin/ProjectController.php index 99a3040..877f399 100755 --- a/app/Http/Controllers/Admin/ProjectController.php +++ b/app/Http/Controllers/Admin/ProjectController.php @@ -63,14 +63,28 @@ class ProjectController extends CommonController public function beds($id) { - $project = (new Project())->with(["buildings" => function ($query) { - $query->with(["areas" => function ($query) { - $query->with("rooms"); - }]); - }])->find($id); - - $data = (new Bed())->where("project_id", $id)->orderBy("id", "desc")->with(["project", "building", "area", "room"])->paginate(10); + $project = (new Project())->with(["buildings"])->find($id); + $data = (new Bed())->where("project_id", $id)->orderBy("id", "desc")->with(["project", "building", "area", "room"]); + if (request()->room_id) { + $data = $data->where("room_id", request()->room_id); + $room = (new Room())->find(request()->room_id); + $rooms = (new Room())->where("area_id", $room->area_id)->get(); + $area = (new Area())->where("id", $room->area_id)->first(); + $areas = (new Area())->where("building_id", $area->building_id)->get(); + view()->share(compact("rooms", "areas")); + } elseif (request()->area_id) { + $data = $data->where("area_id", request()->area_id); + $area = (new Area())->find(request()->area_id); + $areas = (new Area())->where("building_id", $area->building_id)->get(); + $rooms = (new Room())->where("area_id", $area->id)->get(); + view()->share(compact("areas", "rooms")); + } elseif (request()->building_id) { + $areas = (new Area())->where("building_id", request()->building_id)->get(); + $data = $data->where("building_id", request()->building_id); + view()->share(compact("areas")); + } + $data = $data->paginate(10); return view($this->bladePath . ".beds", compact("project", "data")); } @@ -125,6 +139,21 @@ class ProjectController extends CommonController return $this->success("添加成功!", '', $res); } + public function getSubs(Request $request) + { + switch ($request->type) { + case "building": + $res = (new Area())->where("building_id", $request->id)->get(); + break; + case "area": + $res = (new Room())->where("area_id", $request->id)->get(); + break; + default: + $res = []; + } + return $this->ajaxResponse($res); + } + public function editDepartment(Request $request) { $data = [ diff --git a/app/Http/Controllers/Admin/StatisticsController.php b/app/Http/Controllers/Admin/StatisticsController.php index 968f673..2139b2e 100755 --- a/app/Http/Controllers/Admin/StatisticsController.php +++ b/app/Http/Controllers/Admin/StatisticsController.php @@ -34,11 +34,21 @@ class StatisticsController extends CommonController public function _checkProjects() { - $projects = (new Project())->adminProject()->get(); + $projects = (new Project())->adminProject()->orderBy("id","desc")->get(); view()->share(compact("projects")); return $projects; } + public function getYears() + { + $start_year = config("start_year"); + $years = []; + for ($i = date("Y"); $i >= $start_year; $i--) { + $years[] = $i; + } + view()->share(compact("years")); + } + public function _getMonths() { $months = []; @@ -126,8 +136,9 @@ class StatisticsController extends CommonController return $this->error($this->noProjects); } $this->_getMonthData(); + $laravel_duration = microtime(true) - LARAVEL_START; - return view($this->urlPrefix . "/salary"); + return view($this->urlPrefix . "/salary", compact("laravel_duration")); } public function overview(Request $request) @@ -248,31 +259,32 @@ class StatisticsController extends CommonController return $this->error($this->noProjects); } $project_id = request()->project_id ?? $projects->first()->id; - $before_date = $request->before_date ?: date("Y-m-d"); $before_datetime = strtotime($before_date . " 23:59:59"); DB::enableQueryLog(); - //todo:子订单的数量增加,用更省查询时间的方式获取项目相关数据 $customers = (new Customer()) + ->whereNull("deleted_at") ->with([ "patients" => function ($query) use ($before_datetime) { $query->whereRaw("UNIX_TIMESTAMP(`created_at`) <= {$before_datetime}")->orderBy("id", "desc"); }, - "balances" => function ($query) use ($before_datetime) { - $query->whereRaw("UNIX_TIMESTAMP(`created_at`) <= {$before_datetime}")->orderBy("id", "desc"); - } +// "oneBalance" => function ($query) use ($before_datetime) { +// $query->whereRaw("UNIX_TIMESTAMP(`created_at`) <= {$before_datetime}")->orderBy("id", "desc"); +// } ]) - ->whereHas("balances", function ($query) use ($before_datetime, $project_id) { +// ->whereHas("oneBalance", function ($query) use ($before_datetime) { +// $query->whereRaw("UNIX_TIMESTAMP(`created_at`) <= {$before_datetime}")->where("balance", ">", 0)->orderBy("id", "desc"); +// }) + ->whereHas("orders", function ($query) use ($before_datetime, $project_id) { $query - ->whereRaw("UNIX_TIMESTAMP(`created_at`) <= {$before_datetime}") - ->whereHas("order", function ($query) use ($project_id) { - $query->where("project_id", $project_id); - }); +// ->whereRaw("UNIX_TIMESTAMP(`created_at`) <= {$before_datetime}") + ->where("project_id", $project_id); }) ->get(); - return view($this->bladePath . ".customer-balance", compact("customers", "before_datetime")); + $laravel_duration = microtime(true) - LARAVEL_START; + return view($this->bladePath . ".customer-balance", compact("customers", "before_datetime", "project_id", "laravel_duration")); } public function fixMonthLastDayCheckout(Request $request) diff --git a/app/Http/Controllers/Customer/OrdersController.php b/app/Http/Controllers/Customer/OrdersController.php index 04e63af..06fb6d6 100644 --- a/app/Http/Controllers/Customer/OrdersController.php +++ b/app/Http/Controllers/Customer/OrdersController.php @@ -13,10 +13,14 @@ use App\Models\Product; use App\Models\ProductItems; use App\Models\ProductParamedicLevel; use App\Models\Recharge; +use App\Notifications\CustomerOrderCreated; +use App\Notifications\RechargePaid; use Carbon\Carbon; use Illuminate\Database\Eloquent\Relations\MorphTo; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Log; +use Illuminate\Support\Facades\Notification; class OrdersController extends CommonController { @@ -428,6 +432,12 @@ class OrdersController extends CommonController ]); $order->getSerial(); + if ($order->project->managers) { + foreach ($order->project->managers as $manager) { + Notification::send($manager, new CustomerOrderCreated($order)); + } + } + DB::commit(); return $this->getOrder($order->id); } catch (\Exception $exception) { @@ -505,6 +515,7 @@ class OrdersController extends CommonController public function cancelOrder($id) { $order = (new Orders())->with("orderItems")->find($id); + Log::info($order); if ($order->status !== Orders::STATUS_UNCONFIRMED) { return response()->json([ "errorcode" => 50001, @@ -662,4 +673,106 @@ class OrdersController extends CommonController ])->select("id", "customer_id", "money", "balance", "belongs_type", "belongs_id", "remark", "order_id", "created_at")->orderBy("id", "desc")->paginate(10); return response()->json($balances->toArray()); } + + /** + * @OA\POST( + * path="/customer/score-order/{id}", + * tags={"用户端订单处理"}, + * summary="评价订单", + * description="评价订单", + * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), + * @OA\Parameter(name="id", in="path", @OA\Schema(type="integer"), required=true, description="订单id"), + * @OA\Parameter(name="score", in="query", @OA\Schema(type="number"), required=true, description="分数,5分制,0.5分为一个阶梯"), + * @OA\Parameter(name="comment", in="query", @OA\Schema(type="string"), required=false, description="评语,不超过255字节"), + * @OA\Response( + * response="200", + * description="评价订单" + * ) + * ) + */ + + public function scoreOrder($id) + { + $order = (new Orders())->where("customer_id", $this->customer->id)->find($id); + if (!$order) { + return response()->json([ + "errorcode" => 40004, + "errormsg" => "没找到订单" + ]); + } + + if ($order->status !== Orders::STATUS_FINISHED) { + return response()->json([ + "errorcode" => 50001, + "errormsg" => "订单状态不适配" + ]); + } + + DB::beginTransaction(); + try { + $order->update([ + "score" => request()->score, + "comment" => request()->comment, + "scored_at" => date("Y-m-d H:i:s"), + ]); + DB::commit(); + return response()->json($order); + } catch (\Exception $exception) { + DB::rollBack(); + return response()->json([ + "errorcode" => $exception->getCode(), + "errormsg" => $exception->getMessage() + ]); + } + } + + /** + * @OA\POST( + * path="/customer/delete-score-order/{id}", + * tags={"用户端订单处理"}, + * summary="删除订单评价", + * description="删除订单评价", + * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), + * @OA\Parameter(name="id", in="path", @OA\Schema(type="integer"), required=true, description="订单id"), + * @OA\Response( + * response="200", + * description="删除订单评价" + * ) + * ) + */ + + public function deleteScoreOrder($id) + { + $order = (new Orders())->where("customer_id", $this->customer->id)->find($id); + if (!$order) { + return response()->json([ + "errorcode" => 40004, + "errormsg" => "没找到订单" + ]); + } + + if ($order->status !== Orders::STATUS_FINISHED) { + return response()->json([ + "errorcode" => 50001, + "errormsg" => "订单状态不适配" + ]); + } + + DB::beginTransaction(); + try { + $order->update([ + "score" => null, + "comment" => null, + "scored_at" =>null + ]); + DB::commit(); + return response()->json($order); + } catch (\Exception $exception) { + DB::rollBack(); + return response()->json([ + "errorcode" => $exception->getCode(), + "errormsg" => $exception->getMessage() + ]); + } + } } diff --git a/app/Http/Controllers/Customer/PublicController.php b/app/Http/Controllers/Customer/PublicController.php index 3781cfe..a79bafc 100644 --- a/app/Http/Controllers/Customer/PublicController.php +++ b/app/Http/Controllers/Customer/PublicController.php @@ -22,10 +22,11 @@ class PublicController extends Controller * ) * ) */ - public function getOrdersCount() { + public function getOrdersCount() + { $orders_count = Orders::count(); $order_items_count = OrderItems::whereHas("order")->count(); - return response()->json(compact("orders_count","order_items_count")); + return response()->json(compact("orders_count", "order_items_count")); } /** @@ -43,7 +44,7 @@ class PublicController extends Controller public function getProjects() { - $projects = Project::select("id", "name", "address","logo","banners")->get(); + $projects = Project::select("id", "name", "address", "logo", "banners")->orderBy("id", "desc")->get(); return response()->json($projects->toArray()); } diff --git a/app/Http/Controllers/Manager/OrdersController.php b/app/Http/Controllers/Manager/OrdersController.php index 1ad1554..a025416 100644 --- a/app/Http/Controllers/Manager/OrdersController.php +++ b/app/Http/Controllers/Manager/OrdersController.php @@ -30,6 +30,7 @@ use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; use Intervention\Image\Facades\Image; use SimpleSoftwareIO\QrCode\Facades\QrCode; +use function GuzzleHttp\Psr7\str; class OrdersController extends CommonController { @@ -131,6 +132,11 @@ class OrdersController extends CommonController * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Parameter(name="project_id", in="path", @OA\Schema(type="integer"), required=false, description="医院ID"), * @OA\Parameter(name="keyword", in="query", @OA\Schema(type="string"), required=false, description="查询关键词"), + * @OA\Parameter(name="building_id", in="query", @OA\Schema(type="integer"), required=false, description="楼栋ID"), + * @OA\Parameter(name="area_id", in="query", @OA\Schema(type="integer"), required=false, description="病区ID"), + * @OA\Parameter(name="start_date_from", in="query", @OA\Schema(type="string"), required=false, description="开始服务日期区间查询的第一个值"), + * @OA\Parameter(name="start_date_to", in="query", @OA\Schema(type="string"), required=false, description="开始服务日期区间查询的第二个值"), + * @OA\Parameter(name="days", in="query", @OA\Schema(type="integer"), required=false, description="服务天数,以实际生成的to_date和from_date比对为准,改价为0的也算"), * @OA\Parameter(name="page", in="query", @OA\Schema(type="integer"), required=false, description="当前页码,默认为1"), * @OA\Parameter(name="page_size", in="query", @OA\Schema(type="integer"), required=false, description="每页数量,默认为5"), * @OA\Parameter(name="status", in="query", @OA\Schema(type="string"), required=false, description="订单状态:[pending=>待处理,ongoing=>进行中,finished=>已完成]"), @@ -152,12 +158,32 @@ class OrdersController extends CommonController ->where("serial", "like", "%{$keyword}%") ->orWhereHas("patient", function ($query) use ($keyword) { $query->where("name", "like", "%{$keyword}%"); + })->orWhereHas("customer", function ($query) use ($keyword) { + $query->where("mobile", "like", "%{$keyword}%"); })->orWhereHas("paramedic", function ($query) use ($keyword) { $query->where("name", "like", "%{$keyword}%"); }); }); } + if (request()->area_id) { + $model = $model->whereHas("bed", function ($query) { + $query->where("area_id", request()->area_id); + }); + } elseif (request()->building_id) { + $model = $model->whereHas("bed", function ($query) { + $query->where("building_id", request()->building_id); + }); + } + + if (request()->days) { + $model = $model->whereRaw(DB::raw("datediff(`to_date`,`from_date`) = " . (request()->days - 1))); + } + + if (request()->start_date_from && request()->start_date_to) { + $model = $model->whereRaw(DB::raw("UNIX_TIMESTAMP(`from_date`) between " . strtotime(request()->start_date_from) . " and " . strtotime(request()->start_date_to))); + } + switch (request()->status) { case "pending": $model = $model->whereIn("status", [Orders::STATUS_UNCONFIRMED, Orders::STATUS_UNASSIGNED]); @@ -384,7 +410,7 @@ class OrdersController extends CommonController $query->select("id", "name"); }, "bed" => function ($query) { - $query->select("bed.id", "bed.name") + $query->select("bed.id", "bed.name", "bed.building_id", "bed.area_id") ->leftJoin("building", "building.id", "=", "bed.building_id") ->leftJoin("area", "area.id", "=", "bed.area_id") ->leftJoin("room", "room.id", "=", "bed.room_id") @@ -763,7 +789,7 @@ class OrdersController extends CommonController * @OA\POST( * path="/manager/update-order-items", * tags={"管理端订单处理"}, - * summary="V2-子订单修改(覆盖单条修改)", + * summary="V2-子订单修改(覆盖单条修改),20230618更新:对早于过上月的价格锁定", * description="子订单修改", * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Parameter(name="ids", in="query", @OA\Schema(type="integer"), required=true, description="子订单id,可传单个id或数组"), @@ -839,6 +865,15 @@ class OrdersController extends CommonController $warnings[] = "将对" . $price_changed_paid_items->count() . "天已付款的子订单进行价格更改"; } + $manager = $this->guard()->user(); + if (!$manager->no_lock_ability) { + foreach ($order_items as $_item) { + if (date("Ym", strtotime($_item->service_date)) < date("Ym", strtotime("-1 month", time()))) { + $errors[] = "子订单{$_item->id}已锁定"; + } + } + } + if ($total_increased > $customer->balance) { $errors[] = "价格补差{$total_increased}超过了客户余额{$customer->balance},请先充值"; } @@ -988,6 +1023,20 @@ class OrdersController extends CommonController } $to_generate_days = max(0, $to_generate_days); + for ($i = 0; $i < $to_generate_days; $i++) { + if ($i > 0) { + $service_date = Carbon::parse($to_generate_start_date)->addDays($i)->toDateString(); + } else { + $service_date = $to_generate_start_date; + } + if (strtotime($service_date) >= strtotime("+1 month", strtotime(date("Y-m") . "-01"))) { + return response()->json([ + "errorcode" => 30003, + "errormsg" => "中途结算最大时限不能超过当月月底" + ]); + } + } + $prepay_total = $unpaid_order_items->sum("total") + $to_generate_days * $order->price; $to_recharge_total = $prepay_total - $order->customer->balance; @@ -1045,6 +1094,13 @@ class OrdersController extends CommonController } else { $service_date = $to_generate_start_date; } + if (strtotime($service_date) >= strtotime("+1 month", strtotime(date("Y-m") . "-01"))) { + return response()->json([ + "errorcode" => 30003, + "errormsg" => "中途结算最大时限不能超过当月月底,已收的多余款项将于下月使用" + ]); + } + $order_item = (new OrderItems())->createItem($order->id, $service_date); //更新子订单支付状态 @@ -1661,6 +1717,13 @@ class OrdersController extends CommonController //更新用户余额,创建流水记录 $customer_balance = $refund->customer->balance - $refund->money; + if ($customer_balance < 0) { + return response()->json([ + "errorcode" => "0", + "errormsg" => "客户余额为负异常,存在重复退款操作。" + ]); + } + $refund->customer->update([ "balance" => $customer_balance ]); @@ -1710,10 +1773,9 @@ class OrdersController extends CommonController * @OA\Post( * path="/manager/change-order-status/{id}", * tags={"管理端订单处理"}, - * summary="V2-更新订单状态", + * summary="V2-更新订单状态,20230618更新:鉴定是否权限是否开启", * description="更新订单状态", * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), - * @OA\Parameter(name="id", in="query", @OA\Schema(type="integer"), required=true, description="订单ID"), * @OA\Parameter(name="from_status", in="query", @OA\Schema(type="integer"), required=true, description="原状态"), * @OA\Parameter(name="to_status", in="query", @OA\Schema(type="integer"), required=true, description="更新状态"), * @OA\Response( @@ -1726,6 +1788,14 @@ class OrdersController extends CommonController public function changeOrderStatus($id) { try { + $manager = $this->guard()->user(); + if (!$manager->order_status_ability) { + return response()->json([ + "errorcode" => "4003", + "errormsg" => "权限不足" + ]); + } + $order = (new Orders())->find($id); if (request()->to_status == Orders::STATUS_ONGOING) { $other_ongoing_order = Orders::where("status", Orders::STATUS_ONGOING)->where("customer_id", $order->customer_id)->count(); diff --git a/app/Http/Controllers/Manager/StatisticsController.php b/app/Http/Controllers/Manager/StatisticsController.php index e9ea1f8..bd9666b 100644 --- a/app/Http/Controllers/Manager/StatisticsController.php +++ b/app/Http/Controllers/Manager/StatisticsController.php @@ -249,6 +249,17 @@ class StatisticsController extends CommonController $checkout = $model_checkout->sum("total"); $refund = $model_refund->sum("money"); + + $refund_by_payment = $model_refund->select("payment", "paid_at", "money", "order_id")->addSelect(DB::raw("sum(`money`) as total"))->groupBy("payment")->get()->keyBy("payment")->toArray(); + $refund_methods = (new Refund())->groupBy("payment")->get()->keyBy("payment")->toArray(); + foreach ($refund_methods as $k => $refund_method) { + if (isset($refund_by_payment[$k])) { + $refund_by_methods[$k] = $refund_by_payment[$k]["total"]; + } else { + $refund_by_methods[$k] = 0; + } + } + $payment_methods = (new Recharge())->payment_methods; $payment_online_methods = (new Recharge())->payment_online_methods; @@ -267,7 +278,7 @@ class StatisticsController extends CommonController $recharge[$k] = $val; } - return response()->json(compact("checkout", "refund", "recharge", "payment_methods")); + return response()->json(compact("checkout", "refund", "recharge", "payment_methods", "refund_by_methods")); } public function _getDuration() diff --git a/app/Http/Controllers/Worker/AuthController.php b/app/Http/Controllers/Worker/AuthController.php new file mode 100644 index 0000000..b40b4f3 --- /dev/null +++ b/app/Http/Controllers/Worker/AuthController.php @@ -0,0 +1,138 @@ +authModel = new Worker(); + } + + /** + * Create a new AuthController instance. + * + * @return void + */ + + public function guard() + { + return auth()->guard($this->guardName); + } + + public function guardName() + { + return $this->guardName; + } + + /** + * @OA\Post( + * path="/worker/login-by-username", + * tags={"护工端用户相关"}, + * summary="V2-通过用户名密码登录", + * description="", + * @OA\Parameter(name="username", in="query", @OA\Schema(type="string"), required=true, description="用户名(身份证号)"), + * @OA\Parameter(name="password", in="query", @OA\Schema(type="string"), required=true, description="密码"), + * @OA\Response( + * response="200", + * description="护工通过用户名(身份证号)密码登录" + * ) + * ) + */ + public function loginByUsername() + { + $credentials = [ + "id_card_number" => request()->username, + "password" => request()->password + ]; + if (!$token = $this->guard()->attempt($credentials)) { + return response()->json([ + 'errorcode' => '401', + 'errormsg' => '登录失败' + ], 401); + } + + return $this->respondWithToken($token); + } + + /** + * @OA\Get( + * path="/worker/me", + * tags={"护工端用户相关"}, + * summary="V2-获取登录者信息", + * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), + * description="", + * @OA\Response( + * response="200", + * description="获取登录者信息" + * ) + * ) + */ + public function me() + { + $id = $this->guard()->id(); + $paramedic = (new Paramedic())->find($id); + return response()->json($paramedic->toArray()); + } + + /** + * @OA\Post( + * path="/worker/logout", + * tags={"护工端用户相关"}, + * summary="V2 退出登录", + * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), + * description="", + * @OA\Response( + * response="200", + * description="退出登录" + * ) + * ) + */ + public function logout() + { + DB::beginTransaction(); + try { + $this->guard()->logout(); + DB::commit(); + return response()->json([ + 'errormsg' => "退出登录成功!" + ]); + } catch (\Exception $exception) { + DB::rollBack(); + return response()->json([ + 'errorcode' => '402', + 'errormsg' => $exception->getMessage() + ]); + } + } + + + /** + * Get the token array structure. + * + * @param string $token + * + * @return \Illuminate\Http\JsonResponse + */ + protected function respondWithToken($token) + { + $user = $this->guard()->user(); + $user = $user->toArray(); + + return response()->json([ + 'access_token' => $token, + 'token_type' => 'bearer', + 'expires_in' => $this->guard()->factory()->getTTL() * 60, + 'user_info' => $user + ]); + } +} diff --git a/app/Http/Controllers/Worker/CommonController.php b/app/Http/Controllers/Worker/CommonController.php new file mode 100644 index 0000000..df24d7e --- /dev/null +++ b/app/Http/Controllers/Worker/CommonController.php @@ -0,0 +1,27 @@ +guard()->user(); + $this->worker = $worker; + } + + public function guard() + { + return auth()->guard($this->guardName); + } + + public function guardName() + { + return $this->guardName; + } +} diff --git a/app/Http/Controllers/Worker/OrdersController.php b/app/Http/Controllers/Worker/OrdersController.php new file mode 100644 index 0000000..67ece84 --- /dev/null +++ b/app/Http/Controllers/Worker/OrdersController.php @@ -0,0 +1,183 @@ +待处理,ongoing=>进行中,finished=>已完成]"), + * @OA\Response( + * response="200", + * description="获取订单列表" + * ) + * ) + */ + + public function list() + { + $worker = $this->guard()->user(); + $model = $this->_getOrderModel(); + + $ids = OrderItems::where("paramedic_id", $worker->id)->where("total", ">", 0)->pluck("order_id")->toArray(); + $model = $model->whereIn("id", $ids); + + if (request()->keyword) { + $keyword = request()->keyword; + $model = $model->where(function ($query) use ($keyword) { + $query + ->where("serial", "like", "%{$keyword}%") + ->orWhereHas("patient", function ($query) use ($keyword) { + $query->where("name", "like", "%{$keyword}%"); + })->orWhereHas("customer", function ($query) use ($keyword) { + $query->where("mobile", "like", "%{$keyword}%"); + })->orWhereHas("paramedic", function ($query) use ($keyword) { + $query->where("name", "like", "%{$keyword}%"); + }); + }); + } + + if (request()->start_date_from && request()->start_date_to) { + $model = $model->whereRaw(DB::raw("UNIX_TIMESTAMP(`from_date`) between " . strtotime(request()->start_date_from) . " and " . strtotime(request()->start_date_to))); + } + + switch (request()->status) { + case "pending": + $model = $model->whereIn("status", [Orders::STATUS_UNCONFIRMED, Orders::STATUS_UNASSIGNED]); + break; + case "ongoing": + case "finished": + $model = $model->where("status", constant(Orders::class . "::STATUS_" . strtoupper(request()->status))); + break; + default: + //do nothing + } + + $page_size = request()->page_size ?? 5; + $data = $model->orderBy("id", "desc")->paginate($page_size); + + return response()->json($data->toArray()); + } + + /** + * @OA\Get( + * path="/worker/get-order/{id}", + * tags={"护工端订单处理"}, + * summary="V2-获取订单详情", + * description="获取订单详情", + * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), + * @OA\Parameter(name="id", in="path", @OA\Schema(type="integer"), required=true, description="id"), + * @OA\Response( + * response="200", + * description="获取订单详情" + * ) + * ) + */ + + public function getOrder($id) + { + $worker = $this->guard()->user(); + $model = $this->_getOrderModel(); + $ids = OrderItems::where("order_id", $id)->where("paramedic_id", $worker->id)->where("total", ">", 0)->pluck("order_id")->toArray(); + if (!$ids) { + return response()->json([ + "errorcode" => "40004", + "errormsg" => "没找到订单" + ]); + } + + $order = $model->with([ + "orderItems" => function ($query) use ($worker) { + $query->where("paramedic_id", $worker->id)->where("total", ">", 0)->orderBy("service_date", "desc"); + } + ])->find($id); + + return response()->json($order->toArray()); + } + + public function _getOrderModel() + { + $model = $order = (new Orders()) + ->select( + "orders.id", + "orders.serial", + "orders.customer_id", + "orders.manager_id", + "orders.bed_id", + "orders.patient_id", + "orders.project_id", + "orders.product_id", + "orders.product_item_id", + "orders.product_paramedic_level_id", + "orders.from_date", + "orders.to_date", + "orders.status", + "orders.total", + "orders.paid_total", + "orders.contact", + "orders.mobile", + "orders.paramedic_id", + "orders.price", + "orders.factors", + "orders.patient_quantity", + "orders.created_at" + ) + ->with([ + "project" => function ($query) { + $query->select("id", "name"); + }, + "bed" => function ($query) { + $query->select("bed.id", "bed.name", "bed.building_id", "bed.area_id") + ->leftJoin("building", "building.id", "=", "bed.building_id") + ->leftJoin("area", "area.id", "=", "bed.area_id") + ->leftJoin("room", "room.id", "=", "bed.room_id") + ->addSelect("room.name as room_name", "area.name as area_name", "building.name as building_name"); + }, + "customer" => function ($query) { + $query->select("id", "name", "balance"); + }, + "patient" => function ($query) { + $query->select("id", "name", "sex", "age", "mobile"); + } + ]); + return $model; + } +} diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php index 454152c..fbf5dfc 100644 --- a/app/Http/Middleware/VerifyCsrfToken.php +++ b/app/Http/Middleware/VerifyCsrfToken.php @@ -13,6 +13,7 @@ class VerifyCsrfToken extends Middleware */ protected $except = [ 'customer/*', - 'manager/*' + 'manager/*', + 'worker/*', ]; } diff --git a/app/Libs/AlipayF2F.class.php b/app/Libs/AlipayF2F.class.php index 026d67d..4e499a5 100644 --- a/app/Libs/AlipayF2F.class.php +++ b/app/Libs/AlipayF2F.class.php @@ -35,6 +35,13 @@ class AlipayF2F return [ "status" => true ]; + } elseif ($result->code == "10003") { + Log::info("支付宝状态:" . $result->code . ";" . $result->msg . ";" . $result->subMsg); + return [ + "status" => false, + "code" => $result->code, + "msg" => "正在支付中,请稍后查询支付到账状态" + ]; } else { Log::info("支付宝错误:" . $result->code . ";" . $result->msg . ";" . $result->subMsg); return [ @@ -62,7 +69,7 @@ class AlipayF2F $responseChecker = new ResponseChecker(); //处理响应或异常 if ($responseChecker->success($query_result)) { - if($query_result->tradeStatus !== "TRADE_SUCCESS") { + if ($query_result->tradeStatus !== "TRADE_SUCCESS") { return false; } if (!$recharge->paid_at) { diff --git a/app/Libs/WxMicroPay.class.php b/app/Libs/WxMicroPay.class.php index 073726f..3c8960f 100644 --- a/app/Libs/WxMicroPay.class.php +++ b/app/Libs/WxMicroPay.class.php @@ -34,6 +34,9 @@ class WxMicroPay extends WxPayCommon } elseif (!$this->parameters["auth_code"]) { throw new Exception("缺少必填参数auth_code!"); } elseif (strlen((string)$this->parameters["auth_code"]) != 18) { + \Log::info("支付码不正确"); + \Log::info($this->parameters); + \Log::info(request()->all()); throw new Exception("支付码不正确!"); } diff --git a/app/Manager.php b/app/Manager.php index a321153..e000fd8 100644 --- a/app/Manager.php +++ b/app/Manager.php @@ -121,7 +121,7 @@ class Manager extends Authenticatable implements JWTSubject * @var array */ protected $fillable = [ - 'type', 'name', 'sex', 'username', 'password', 'openid', 'unionid', 'mobile', 'birthday', 'avatar' + 'type', 'name', 'sex', 'username', 'password', 'openid', 'unionid', 'mobile', 'birthday', 'avatar', 'order_status_ability' ]; /** diff --git a/app/Models/Notifications.php b/app/Models/Notifications.php index caf0393..5930a9a 100644 --- a/app/Models/Notifications.php +++ b/app/Models/Notifications.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Notifications\CustomerOrderCreated; use App\Notifications\RechargePaid; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Request; @@ -26,6 +27,9 @@ class Notifications extends CommonModel $title = "有一笔新的收款到账,请注意查看。"; } break; + case CustomerOrderCreated::class: + $title = "有用户通过小程序进行了下单,订单编号:{$data["order_serial"]},请注意及时处理。"; + break; default: $title = "创建于{$this->created_at}的通知"; } diff --git a/app/Models/OrderItems.php b/app/Models/OrderItems.php index 378f2d3..3a906f4 100755 --- a/app/Models/OrderItems.php +++ b/app/Models/OrderItems.php @@ -20,7 +20,8 @@ class OrderItems extends SoftDeletesModel return "未服务"; } if ($this->paid_at) { - return "已扣款"; + $next_month = date("m", strtotime("+1 month", strtotime(date("Y-m", strtotime($this->paid_at))))); + return "已扣款,{$next_month}月结工资"; } else { return "未扣款"; } diff --git a/app/Notifications/CustomerOrderCreated.php b/app/Notifications/CustomerOrderCreated.php new file mode 100644 index 0000000..399754b --- /dev/null +++ b/app/Notifications/CustomerOrderCreated.php @@ -0,0 +1,65 @@ +order = $order; + } + + /** + * Get the notification's delivery channels. + * + * @param mixed $notifiable + * @return array + */ + public function via($notifiable) + { + return ['database']; + } + + /** + * Get the mail representation of the notification. + * + * @param mixed $notifiable + * @return \Illuminate\Notifications\Messages\MailMessage + */ + public function toMail($notifiable) + { + return (new MailMessage) + ->line('The introduction to the notification.') + ->action('Notification Action', url('/')) + ->line('Thank you for using our application!'); + } + + /** + * Get the array representation of the notification. + * + * @param mixed $notifiable + * @return array + */ + public function toArray($notifiable) + { + return [ + "order_id" => $this->order->id, + "order_serial" => $this->order->serial + ]; + } +} diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 9a16fb0..af7f298 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -20,6 +20,7 @@ class EventServiceProvider extends ServiceProvider ], "App\Events\FactorSaved" => ["App\Listeners\FactorSavedListener"], "App\Events\ManagerSaved" => ["App\Listeners\ManagerSavedListener"], + "App\Events\AdminSaved" => ["App\Listeners\AdminSavedListener"], "App\Events\ProjectSaved" => ["App\Listeners\ProjectSavedListener"], "App\Events\ProductSaved" => ["App\Listeners\ProductSavedListener"], "App\Events\RechargeSucceed" => ["App\Listeners\RechargeSucceedListener"], diff --git a/app/Worker.php b/app/Worker.php new file mode 100644 index 0000000..d9a7115 --- /dev/null +++ b/app/Worker.php @@ -0,0 +1,88 @@ +secure() ? "https" : "http"; + if (!$this->avatar) { + switch ($this->sex) { + case "男": + $this->avatar = "/images/male.png"; + break; + case "女": + $this->avatar = "/images/female.png"; + break; + } + } + return $this->avatar ? $protocol . "://" . request()->getHost() . $this->avatar : $this->avatar; + } + + public function guardName() + { + return self::GUARD_NAME; + } + + // Rest omitted for brevity + + /** + * Get the identifier that will be stored in the subject claim of the JWT. + * + * @return mixed + */ + public function getJWTIdentifier() + { + return $this->getKey(); + } + + /** + * Return a key value array, containing any custom claims to be added to the JWT. + * + * @return array + */ + public function getJWTCustomClaims() + { + return []; + } + + /** + * The attributes that are mass assignable. + * + * @var array + */ + protected $fillable = []; + + /** + * The attributes that should be hidden for arrays. + * + * @var array + */ + protected $hidden = [ + 'password', 'remember_token', + ]; + + /** + * The attributes that should be cast to native types. + * + * @var array + */ + protected $casts = [ + 'verified_at' => 'datetime', + ]; +} diff --git a/config/app.php b/config/app.php index 4c2cf5f..99d7613 100644 --- a/config/app.php +++ b/config/app.php @@ -39,7 +39,7 @@ return [ | */ - 'debug' => (bool) env('APP_DEBUG', false), + 'debug' => (bool)env('APP_DEBUG', false), /* |-------------------------------------------------------------------------- @@ -56,6 +56,8 @@ return [ 'asset_url' => env('ASSET_URL', null), + 'start_year' => env('START_YEAR', 2017), + /* |-------------------------------------------------------------------------- | Application Timezone diff --git a/config/auth.php b/config/auth.php index 287c850..a6b5d38 100644 --- a/config/auth.php +++ b/config/auth.php @@ -50,6 +50,11 @@ return [ 'provider' => 'manager', ], + 'worker' => [ + 'driver' => 'jwt', + 'provider' => 'worker', + ], + // 'api' => [ // 'driver' => 'token', // 'provider' => 'users', @@ -90,6 +95,11 @@ return [ 'model' => App\Manager::class, ], + 'worker' => [ + 'driver' => 'eloquent', + 'model' => App\Worker::class, + ], + // 'users' => [ // 'driver' => 'database', // 'table' => 'users', diff --git a/database/migrations/2023_07_11_111443_update_orders_add_score.php b/database/migrations/2023_07_11_111443_update_orders_add_score.php new file mode 100644 index 0000000..55e479a --- /dev/null +++ b/database/migrations/2023_07_11_111443_update_orders_add_score.php @@ -0,0 +1,32 @@ +decimal("score")->nullable(); + $table->timestamp("scored_at")->nullable(); + $table->string("comment")->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +} diff --git a/database/migrations/2023_07_14_093851_update_paramedic_add_auth_fields.php b/database/migrations/2023_07_14_093851_update_paramedic_add_auth_fields.php new file mode 100644 index 0000000..2618294 --- /dev/null +++ b/database/migrations/2023_07_14_093851_update_paramedic_add_auth_fields.php @@ -0,0 +1,31 @@ +string("remember_token")->nullable(); + $table->string("password")->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +} diff --git a/database/migrations/2023_07_16_144532_update_project_add_percent_first_party.php b/database/migrations/2023_07_16_144532_update_project_add_percent_first_party.php new file mode 100644 index 0000000..6a5f14a --- /dev/null +++ b/database/migrations/2023_07_16_144532_update_project_add_percent_first_party.php @@ -0,0 +1,30 @@ +decimal("percent_first_party", 5, 2)->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +} diff --git a/database/migrations/2023_08_02_114733_update_managers_add_no_lock_ability.php b/database/migrations/2023_08_02_114733_update_managers_add_no_lock_ability.php new file mode 100644 index 0000000..720fbdf --- /dev/null +++ b/database/migrations/2023_08_02_114733_update_managers_add_no_lock_ability.php @@ -0,0 +1,30 @@ +tinyInteger("no_lock_ability")->default(0)->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +} diff --git a/public/dashboard/skin/default/images/head.png b/public/dashboard/skin/default/images/head.png index 9f60153..506a6a8 100644 Binary files a/public/dashboard/skin/default/images/head.png and b/public/dashboard/skin/default/images/head.png differ diff --git a/public/js/common.js b/public/js/common.js index 6bd4431..2cf95db 100755 --- a/public/js/common.js +++ b/public/js/common.js @@ -325,7 +325,7 @@ function initUploader(obj, index) { var li = ''; $(".uploader-list[data-uploader-index=" + index + "]").append(li); $(".uploader-list[data-uploader-index=" + index + "]").children(":last").find(".close").click(function () { @@ -346,7 +346,7 @@ function initUploader(obj, index) { for (var i = 0; i < ids.length; i++) { var li = ''; $(".uploader-list[data-uploader-index=" + index + "]").append(li); $(".uploader-list[data-uploader-index=" + index + "]").children(":last").find(".close").click(function () { @@ -439,7 +439,7 @@ function initUploader(obj, index) { var index = this.options.uploaderIndex; $('#' + file.id).addClass("alert-success").attr("data-id", data.id); - $('#' + file.id).find("a").attr("href", "/storage/" + (data.folder ? data.folder + "/" : "") + data.name).attr("target", "_blank").addClass("text-success"); + $('#' + file.id).find("a").attr("href", "/storage/" + (data.folder && data.folder != "public" ? data.folder + "/" : "") + data.name).attr("target", "_blank").addClass("text-success"); if (typeof uploaderCallback === "function") { var res = uploaderCallback(file, data, index); diff --git a/resources/views/admin/admin/index.blade.php b/resources/views/admin/admin/index.blade.php index 0ce8e73..eb079e9 100755 --- a/resources/views/admin/admin/index.blade.php +++ b/resources/views/admin/admin/index.blade.php @@ -19,6 +19,7 @@ 用户名 角色 + 项目 操作 @@ -32,6 +33,9 @@ {{ $row->roles ? implode(",",array_column($row->roles->toArray(),"name")) : "" }} + + {{ implode(",",$row->projects->pluck("name")->toArray()) }} + -
-
-
-
-

- -
本月护理人天数/订单数
- {{ $order_items_count }} / {{ $orders_count }} -

-
-
-
-
+{{--
--}} +{{--
--}} +{{--
--}} +{{--
--}} +{{--
--}} +{{--

--}} +{{-- --}} +{{--
本月护理人天数/订单数
--}} +{{-- {{ $order_items_count }} / {{ $orders_count }}--}} +{{--

--}} +{{--
--}} +{{--
--}} +{{--
--}} +{{--
--}} -
-
-
-
-

- -
本月应扣款
- {{ $total }} -

-
-
-
-
+{{--
--}} +{{--
--}} +{{--
--}} +{{--
--}} +{{--

--}} +{{-- --}} +{{--
本月应扣款
--}} +{{-- {{ $total }}--}} +{{--

--}} +{{--
--}} +{{--
--}} +{{--
--}} +{{--
--}} -
-
-
-
-

- -
本月应发护工酬劳
- {{ $total_paramedic }} -

-
-
-
-
+{{--
--}} +{{--
--}} +{{--
--}} +{{--
--}} +{{--

--}} +{{-- --}} +{{--
本月应发护工酬劳
--}} +{{-- {{ $total_paramedic }}--}} +{{--

--}} +{{--
--}} +{{--
--}} +{{--
--}} +{{--
--}} -
-
-
-
-

- -
本月管理费
- {{ $fee }} -

-
-
-
-
-
+{{--
--}} +{{--
--}} +{{--
--}} +{{--
--}} +{{--

--}} +{{-- --}} +{{--
本月管理费
--}} +{{-- {{ $fee }}--}} +{{--

--}} +{{--
--}} +{{--
--}} +{{--
--}} +{{--
--}} +{{-- --}} @endsection diff --git a/resources/views/admin/orders/index.blade.php b/resources/views/admin/orders/index.blade.php index 2ea0035..0749d78 100755 --- a/resources/views/admin/orders/index.blade.php +++ b/resources/views/admin/orders/index.blade.php @@ -28,6 +28,8 @@ + + @@ -35,6 +37,7 @@ + @@ -250,5 +253,13 @@ var item_id = $("#modal-box form input[name=item_id]").val(); $("#data-table tbody tr[data-item-id='" + item_id + "']").find("td[data-field=total]").html(total); } + + function doExport(ele) { + var url = "{{ url("admin/orders") }}"; + url += "?is_export=1"; + var params = $(ele).closest("form").serialize(); + url += "&" + params; + window.open(url); + } @endpush diff --git a/resources/views/admin/orders/score.blade.php b/resources/views/admin/orders/score.blade.php new file mode 100755 index 0000000..e52a6f8 --- /dev/null +++ b/resources/views/admin/orders/score.blade.php @@ -0,0 +1,110 @@ +@extends("admin.layouts.layout") + +@section("content") +
+
+
+
+
+
+ + + +
+
订单编号 所属项目/医院客户科室 客户姓名 客户余额 联系电话
+ + + + + + + + + + + + + + + @foreach ($data as $row) + + + + + + + + + + + + + + + @endforeach + +
订单编号所属项目/医院客户姓名联系电话被护理人开始服务日期评分评价操作
+ {{ $row->serial }} + {{ $row->project->name }}{{ $row->customer->name ?: $row->patient->name }}{{ $row->customer->mobile }}{{ $row->patient->name }}{{ $row->from_date }}{{ $row->score }}{{ $row->comment }} + 查看 +
+ + + + + + + + + + + @foreach($row->orderItems as $item) + + + + + + + @endforeach + +
所在床位护理日期护工单价
{{ $item->building->name }}-{{ $item->room->name }} + -{{ $item->bed->name }}床 + {{ $item->service_date }}{{ $item->paramedic ? $item->paramedic->name : "" }}{{ $item->total }}
+
+ @include("public._pages") + + + + + + +@endsection + +@push("footer") + +@endpush diff --git a/resources/views/admin/paramedic/create.blade.php b/resources/views/admin/paramedic/create.blade.php index 621e566..68bb134 100755 --- a/resources/views/admin/paramedic/create.blade.php +++ b/resources/views/admin/paramedic/create.blade.php @@ -35,7 +35,7 @@ } function uploaderCallback(file, data, index) { - $('input[data-uploader-index=' + index + ']').val("/storage/" + (data.folder ? data.folder + "/" : "") + data.name); + $('input[data-uploader-index=' + index + ']').val("/storage/" + (data.folder && data.folder != "public" ? data.folder + "/" : "") + data.name); return true; } diff --git a/resources/views/admin/paramedic/index.blade.php b/resources/views/admin/paramedic/index.blade.php index 92c6794..605c77c 100755 --- a/resources/views/admin/paramedic/index.blade.php +++ b/resources/views/admin/paramedic/index.blade.php @@ -6,7 +6,6 @@
-
@lang("icons.action_create") @lang('actions.create'){{$modelName}} @@ -34,9 +33,9 @@ {{ $row->project->name }} - 专属二维码 +{{-- 专属二维码--}} @lang("icons.action_edit") @lang("actions.edit") + href="{{url("{$urlPrefix}/edit?id={$row['id']}")}}">@lang("icons.action_edit") 查看 @lang("icons.action_delete") @lang("actions.delete") diff --git a/resources/views/admin/project/beds.blade.php b/resources/views/admin/project/beds.blade.php index 6ed8347..a3f219e 100755 --- a/resources/views/admin/project/beds.blade.php +++ b/resources/views/admin/project/beds.blade.php @@ -10,98 +10,83 @@ @section("content")
-
+
-
- - - - - - @foreach($project->buildings as $building) - - - - @foreach($building->areas as $area) - - - - @foreach($area->rooms as $room) - - - - @endforeach - @endforeach - @endforeach - -
- {{ $project->name }} - - - - 返回 -
- {{$building->name}} - - + +
+ - +
+ + +
+ +
+ +
+
+ +
+
+ +
+ +
+ +
+
+ +
+
+ + + + 返回 + + -
- {{$area->name}} - - - - -
- {{$room->name}} - - - - -
-
-
-
-
-
-
@@ -110,6 +95,7 @@ + @@ -124,10 +110,10 @@ - + @@ -188,24 +174,74 @@ - - @include("plugins.treetable") @endsection @push("footer")
医院/项目 楼栋 病区/楼层排序 操作
{{ $row->project->name }} {{ $row->building ? $row->building->name : "已删除" }} {{ $row->area ? $row->area->name : "已删除" }}{{ $row->myindex }} @lang("icons.action_edit") + href="javascript:;" onclick="editBed(this)">@lang("icons.action_edit") @lang("icons.action_delete")