2026-09-17 16:25:31 +08:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace app\api\controller;
|
|
|
|
|
|
|
|
|
|
use app\common\controller\Api;
|
|
|
|
|
use app\common\service\CommonService;
|
|
|
|
|
use app\common\service\ContractService;
|
|
|
|
|
use app\common\service\DemandBiddingService;
|
|
|
|
|
use app\common\service\DemandService;
|
2026-09-30 14:56:56 +08:00
|
|
|
use app\common\service\OrderShipService;
|
2026-09-17 16:25:31 +08:00
|
|
|
use think\exception\HttpResponseException;
|
|
|
|
|
use think\Lang;
|
|
|
|
|
use think\Validate;
|
|
|
|
|
|
|
|
|
|
class Demand extends Api
|
|
|
|
|
{
|
|
|
|
|
protected $noNeedLogin = [];
|
|
|
|
|
protected $noNeedRight = ['*'];
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 提交需求
|
|
|
|
|
*
|
|
|
|
|
* @ApiMethod (POST)
|
|
|
|
|
* @param string $desc 需求描述
|
|
|
|
|
* @param array $images 图片数组
|
|
|
|
|
* @param array $files 文件数组
|
|
|
|
|
* @param string $contact 联系方式
|
|
|
|
|
*/
|
|
|
|
|
public function submit()
|
|
|
|
|
{
|
|
|
|
|
try {
|
|
|
|
|
if (!$this->auth->isLogin()) {
|
|
|
|
|
$this->error('请先登录');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$params = $this->request->post();
|
|
|
|
|
// 定义验证规则
|
|
|
|
|
$validate = new Validate([
|
|
|
|
|
'desc' => 'require|min:10',
|
|
|
|
|
'contact' => 'require',
|
|
|
|
|
], [
|
|
|
|
|
'desc.require' => '需求描述不能为空',
|
|
|
|
|
'desc.min' => '需求描述至少10个字符',
|
|
|
|
|
'contact.require' => '联系方式不能为空'
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
// 验证数据
|
|
|
|
|
if (!$validate->check($params)) {
|
|
|
|
|
$this->error($validate->getError());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 验证图片数量
|
|
|
|
|
if (isset($params['images']) && count($params['images']) > 9) {
|
|
|
|
|
$this->error('图片数量不能超过9张');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 验证文件数量
|
|
|
|
|
if (isset($params['files']) && count($params['files']) > 5) {
|
|
|
|
|
$this->error('文件数量不能超过5个');
|
|
|
|
|
}
|
|
|
|
|
$develop_types = explode(',', config('site.general_config_develop_types') ?? '');
|
|
|
|
|
$params['develop_type'] = $develop_types[$params['develop_type']];
|
|
|
|
|
$params['images'] = array_filter($params['images']);
|
|
|
|
|
$params['files'] = array_filter(array_column($params['files'], 'url'));
|
|
|
|
|
DemandService::create($params, $this->auth->id);
|
|
|
|
|
$this->success('需求提交成功');
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
if ($e instanceof HttpResponseException) {
|
|
|
|
|
throw $e;
|
|
|
|
|
}
|
|
|
|
|
$this->error($e->getMessage());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 列表
|
|
|
|
|
*
|
|
|
|
|
* @ApiMethod (POST)
|
|
|
|
|
* @param string $desc 需求描述
|
|
|
|
|
* @param array $images 图片数组
|
|
|
|
|
* @param array $files 文件数组
|
|
|
|
|
* @param string $contact 联系方式
|
|
|
|
|
*/
|
|
|
|
|
public function list()
|
|
|
|
|
{
|
|
|
|
|
try {
|
|
|
|
|
$user_id = $this->auth->id ?? -1;
|
|
|
|
|
$params = $this->request->param();
|
|
|
|
|
$page_size = $params['pageSize'] ?? 10;
|
|
|
|
|
$status = $params['status'] ?? -1;
|
|
|
|
|
$type = $params['type'] ?? 0;
|
|
|
|
|
$opType = $params['opType'] ?? '';
|
|
|
|
|
$keywords = $params['keywords'] ?? '';
|
|
|
|
|
$where = [
|
|
|
|
|
'publish_status' => CommonService::SUCCESS
|
|
|
|
|
];
|
|
|
|
|
if ($opType == 'my') {
|
|
|
|
|
$where['user_id'] = $user_id;
|
|
|
|
|
unset($where['publish_status']);
|
|
|
|
|
} elseif ($opType == 'myQuote') {
|
|
|
|
|
$demand_ids = DemandBiddingService::where(['user_id' => $user_id])->column('demand_id');
|
|
|
|
|
$where['id'] = ['in', $demand_ids];
|
|
|
|
|
}
|
|
|
|
|
if ($keywords) {
|
|
|
|
|
$where['desc'] = ['like', "%$keywords%"];
|
|
|
|
|
}
|
|
|
|
|
if ($type) {
|
|
|
|
|
$where['type'] = $type;
|
|
|
|
|
}
|
|
|
|
|
if ($status != -1) {
|
|
|
|
|
if ($opType == 'all') {
|
|
|
|
|
$develop_types = explode(',', config('site.general_config_develop_types') ?? '');
|
|
|
|
|
$where['develop_type'] = $develop_types[$status];
|
|
|
|
|
} else {
|
|
|
|
|
$where['status'] = $status;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$btnNameFun = function ($opType, $item) {
|
|
|
|
|
$button = ['name' => '查看详情', 'theme' => 'light'];
|
2026-10-08 21:39:12 +08:00
|
|
|
// key 为按钮动作标识(复用 DemandService::BUTTON_* 常量),
|
|
|
|
|
// 前端据此判断按钮类型,避免依赖中文文案;无动作的展示型按钮 key 为空
|
2026-09-17 16:25:31 +08:00
|
|
|
if ($opType == 'all') {
|
|
|
|
|
if ($item->status == 1 && $item->isMyWin && $item->winBidding->bidding_status == 2 && $item->winBidding->process_status == 1) {
|
2026-10-08 21:39:12 +08:00
|
|
|
$button = ['key' => DemandService::BUTTON_CONFIRM, 'name' => '确认接单', 'theme' => 'danger'];
|
2026-09-17 16:25:31 +08:00
|
|
|
} elseif ($item->status == 2 && $item->isMyWin && $item->winBidding->bidding_status == 2 && $item->winBidding->process_status == 2) {
|
2026-09-30 11:28:43 +08:00
|
|
|
if ($item->demand_contracts && $item->demand_contracts->status == ContractService::STATUS_FINISHED && $item->demand_contracts->status2 == ContractService::STATUS_ONGOING) {
|
|
|
|
|
// 开发者已签约,等待客户签约
|
2026-10-08 21:39:12 +08:00
|
|
|
$button = ['key' => '', 'name' => '签约中', 'theme' => 'light'];
|
2026-09-30 11:28:43 +08:00
|
|
|
} else {
|
2026-10-08 21:39:12 +08:00
|
|
|
$button = ['key' => DemandService::BUTTON_CONTRACT_DEV, 'name' => '合同签约', 'theme' => 'danger'];
|
2026-09-30 11:28:43 +08:00
|
|
|
}
|
2026-09-17 16:25:31 +08:00
|
|
|
} elseif ($item->status == 3 && $item->isMyWin && $item->winBidding->bidding_status == 2 && $item->winBidding->process_status == 2) {
|
2026-10-08 21:39:12 +08:00
|
|
|
$button = ['key' => DemandService::BUTTON_COMPLETE_WORK, 'name' => '工作完成', 'theme' => 'danger'];
|
2026-09-30 14:56:56 +08:00
|
|
|
} elseif ($item->status == 5 && $item->isMyWin && $item->winBidding->bidding_status == 2 && $item->winBidding->process_status == 2) {
|
|
|
|
|
//客户支付尾款后,开发者发货交付
|
|
|
|
|
if ($item->hasDelivery) {
|
2026-10-08 21:39:12 +08:00
|
|
|
$button = ['key' => '', 'name' => '已发货', 'theme' => 'light'];
|
2026-09-30 14:56:56 +08:00
|
|
|
} else {
|
2026-10-08 21:39:12 +08:00
|
|
|
$button = ['key' => DemandService::BUTTON_DELIVER_GOODS, 'name' => '去发货', 'theme' => 'danger'];
|
2026-09-30 14:56:56 +08:00
|
|
|
}
|
2026-09-17 16:25:31 +08:00
|
|
|
} elseif ($item->is_bid) {
|
2026-10-08 21:39:12 +08:00
|
|
|
$button = ['key' => '', 'name' => '已投标', 'theme' => 'light'];
|
2026-09-17 16:25:31 +08:00
|
|
|
} elseif ($item->status == 1) {
|
2026-10-08 21:39:12 +08:00
|
|
|
$button = ['key' => 'bid', 'name' => '参与投标', 'theme' => 'danger'];
|
2026-09-17 16:25:31 +08:00
|
|
|
}
|
|
|
|
|
} elseif ($opType == 'myQuote') {
|
|
|
|
|
if ($item->status == 1 && $item->isMyWin && $item->winBidding->bidding_status == 2 && $item->winBidding->process_status == 1) {
|
2026-10-08 21:39:12 +08:00
|
|
|
$button = ['key' => DemandService::BUTTON_CONFIRM, 'name' => '确认接单', 'theme' => 'danger'];
|
2026-09-17 16:25:31 +08:00
|
|
|
} elseif ($item->status == 2 && $item->isMyWin && $item->winBidding->bidding_status == 2 && $item->winBidding->process_status == 2) {
|
2026-09-30 11:28:43 +08:00
|
|
|
if ($item->demand_contracts && $item->demand_contracts->status == ContractService::STATUS_FINISHED && $item->demand_contracts->status2 == ContractService::STATUS_ONGOING) {
|
|
|
|
|
// 开发者已签约,等待客户签约
|
2026-10-08 21:39:12 +08:00
|
|
|
$button = ['key' => '', 'name' => '签约中', 'theme' => 'light'];
|
2026-09-30 11:28:43 +08:00
|
|
|
} else {
|
2026-10-08 21:39:12 +08:00
|
|
|
$button = ['key' => DemandService::BUTTON_CONTRACT_DEV, 'name' => '合同签约', 'theme' => 'danger'];
|
2026-09-30 11:28:43 +08:00
|
|
|
}
|
2026-09-17 16:25:31 +08:00
|
|
|
} elseif ($item->status == 3 && $item->isMyWin && $item->winBidding->bidding_status == 2 && $item->winBidding->process_status == 2) {
|
2026-10-08 21:39:12 +08:00
|
|
|
$button = ['key' => DemandService::BUTTON_COMPLETE_WORK, 'name' => '工作完成', 'theme' => 'danger'];
|
2026-09-17 16:25:31 +08:00
|
|
|
} elseif ($item->status == 4 && $item->accept_status == 1) {
|
2026-10-08 21:39:12 +08:00
|
|
|
$button = ['key' => '', 'name' => '待验收', 'theme' => 'light'];
|
2026-09-30 14:56:56 +08:00
|
|
|
} elseif ($item->status == 5 && $item->isMyWin && $item->winBidding->bidding_status == 2 && $item->winBidding->process_status == 2) {
|
|
|
|
|
//客户支付尾款后,开发者发货交付
|
|
|
|
|
if ($item->hasDelivery) {
|
2026-10-08 21:39:12 +08:00
|
|
|
$button = ['key' => '', 'name' => '已发货', 'theme' => 'light'];
|
2026-09-30 14:56:56 +08:00
|
|
|
} else {
|
2026-10-08 21:39:12 +08:00
|
|
|
$button = ['key' => DemandService::BUTTON_DELIVER_GOODS, 'name' => '去发货', 'theme' => 'danger'];
|
2026-09-30 14:56:56 +08:00
|
|
|
}
|
2026-09-17 16:25:31 +08:00
|
|
|
} elseif ($item->status == 5 && $item->accept_status == 2) {
|
2026-10-08 21:39:12 +08:00
|
|
|
$button = ['key' => '', 'name' => '待收货', 'theme' => 'light'];
|
2026-09-17 16:25:31 +08:00
|
|
|
}
|
|
|
|
|
} elseif ($opType == 'my') {
|
|
|
|
|
if ($item->status == 2 && $item->demand_contracts && $item->demand_contracts->status2 == 1) {
|
2026-10-08 21:39:12 +08:00
|
|
|
$button = ['key' => DemandService::BUTTON_CONTRACT_CUSTOMER, 'name' => '合同签约', 'theme' => 'danger'];
|
2026-09-17 16:25:31 +08:00
|
|
|
} elseif ($item->status == 2) {
|
2026-10-08 21:39:12 +08:00
|
|
|
$button = ['key' => '', 'name' => '详聊沟通', 'theme' => 'danger'];
|
2026-09-17 16:25:31 +08:00
|
|
|
} elseif ($item->status == 3 && $item->work_status == 1) {
|
2026-10-08 21:39:12 +08:00
|
|
|
$button = ['key' => '', 'name' => '工作中', 'theme' => 'light'];
|
2026-09-17 16:25:31 +08:00
|
|
|
} elseif ($item->status == 4 && $item->accept_status == 1) {
|
2026-10-08 21:39:12 +08:00
|
|
|
$button = ['key' => DemandService::BUTTON_ACCEPT_PASSED, 'name' => '前去验收', 'theme' => 'danger'];
|
2026-09-17 16:25:31 +08:00
|
|
|
} elseif ($item->status == 5 && $item->accept_status == 2) {
|
2026-09-30 15:16:09 +08:00
|
|
|
//开发者发货后客户才能确认收货
|
|
|
|
|
if ($item->hasDelivery) {
|
2026-10-08 21:39:12 +08:00
|
|
|
$button = ['key' => DemandService::BUTTON_CONFIRM_RECEIPT, 'name' => '确认收货', 'theme' => 'danger'];
|
2026-09-30 15:16:09 +08:00
|
|
|
} else {
|
2026-10-08 21:39:12 +08:00
|
|
|
$button = ['key' => '', 'name' => '待发货', 'theme' => 'light'];
|
2026-09-30 15:16:09 +08:00
|
|
|
}
|
2026-09-17 16:25:31 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return $button;
|
|
|
|
|
};
|
|
|
|
|
$list = DemandService::getList($where, $page_size, 'id desc', '', ['user', 'demandContracts', 'demandBiddings', 'winBidding']);
|
2026-09-30 14:56:56 +08:00
|
|
|
//已发货的需求集合(发货表),用于开发者视角的发货按钮展示
|
2026-09-30 16:57:26 +08:00
|
|
|
$deliveredDemandIds = OrderShipService::getDeliveredDemandIds($list->column('id'));
|
2026-09-30 14:56:56 +08:00
|
|
|
$list = $list->each(function ($item, $key) use ($user_id, $opType, $btnNameFun, $deliveredDemandIds) {
|
2026-09-17 16:25:31 +08:00
|
|
|
$demand_bidding = $item->demand_biddings;
|
|
|
|
|
$bidUserIds = array_column($demand_bidding, 'user_id');
|
|
|
|
|
$item->demand_biddings_count = count($demand_bidding);
|
|
|
|
|
$item->is_bid = in_array($user_id, $bidUserIds);
|
|
|
|
|
$item->isMyWin = $item->winBidding && $item->winBidding->user_id == $user_id;
|
2026-09-30 14:56:56 +08:00
|
|
|
$item->hasDelivery = in_array($item->id, $deliveredDemandIds);
|
2026-09-17 16:25:31 +08:00
|
|
|
$item->button = $btnNameFun($opType, $item);
|
|
|
|
|
});
|
|
|
|
|
$this->success('', $list);
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
if ($e instanceof HttpResponseException) {
|
|
|
|
|
throw $e;
|
|
|
|
|
}
|
|
|
|
|
$this->error($e->getMessage());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function detail()
|
|
|
|
|
{
|
|
|
|
|
try {
|
|
|
|
|
$user_id = $this->auth->id ?? -1;
|
|
|
|
|
$userInfo = $this->auth->getUserinfo();
|
|
|
|
|
$id = $this->request->param('id', 0);
|
|
|
|
|
$where = [
|
|
|
|
|
'id' => $id,
|
|
|
|
|
];
|
|
|
|
|
$info = DemandService::getOne($where, ['demandContracts', 'winBidding', 'demandGroupChat'], [], ['withCount' => 'demandBiddings']);
|
|
|
|
|
if (!$info) {
|
|
|
|
|
throw new \Exception('该需求不存在');
|
|
|
|
|
}
|
|
|
|
|
//更新浏览次数
|
|
|
|
|
DemandService::where($where)->setInc('views');
|
|
|
|
|
$steps = [
|
|
|
|
|
['status' => 1, 'status_name' => '招标', 'status_text' => '招标'],
|
|
|
|
|
['status' => 2, 'status_name' => '签约', 'status_text' => '签约'],
|
|
|
|
|
['status' => 3, 'status_name' => '工作', 'status_text' => '工作'],
|
|
|
|
|
['status' => 4, 'status_name' => '验收', 'status_text' => '验收'],
|
|
|
|
|
['status' => 5, 'status_name' => '收货', 'status_text' => '收货'],
|
|
|
|
|
];
|
|
|
|
|
$ins = $info->status;
|
|
|
|
|
foreach ($steps as &$step) {
|
|
|
|
|
$step['status_text'] = $step['status'] == $ins ? ($step['status_text'] . '中') : ($step['status'] < $ins ? $step['status_text'] . '完成' : '待' . $step['status_text']);
|
|
|
|
|
}
|
|
|
|
|
$info->stepList = [
|
|
|
|
|
'steps' => $steps,
|
|
|
|
|
'current' => max($ins - 1, 0)
|
|
|
|
|
];
|
|
|
|
|
//我的报价
|
|
|
|
|
$info->myBidding = DemandBiddingService::getOne(['demand_id' => $id, 'user_id' => $user_id]);
|
|
|
|
|
//中标报价
|
|
|
|
|
// $info->winBidding = DemandBiddingService::getOne(['demand_id' => $id, 'bidding_status' => DemandBiddingService::STATUS_BIDDING_WIN]);
|
|
|
|
|
$info->isMy = $user_id == $info->user_id;//我发布
|
|
|
|
|
$info->isMyWin = $info->winBidding && $info->winBidding->user_id == $user_id;//我中标
|
2026-10-09 16:59:09 +08:00
|
|
|
//小程序内无法直接识别二维码,需先长按保存再用微信扫一扫
|
2026-10-09 17:04:45 +08:00
|
|
|
$qrcodeText = '请使用微信扫码进群沟通';
|
2026-09-17 16:25:31 +08:00
|
|
|
if ($user_id == $info->user_id) {
|
2026-10-09 16:59:09 +08:00
|
|
|
$info->contactText = !empty($info->demand_group_chat->qr_code) ? $qrcodeText : '******开发接单后可见';
|
2026-09-17 16:25:31 +08:00
|
|
|
} else {
|
2026-10-09 16:59:09 +08:00
|
|
|
$info->contactText = $info->isMyWin && !empty($info->demand_group_chat->qr_code) ? $qrcodeText : '******确认接单后可见';
|
2026-09-17 16:25:31 +08:00
|
|
|
}
|
|
|
|
|
$info->images = array_filter($info->images);
|
|
|
|
|
$info->files = array_map(fn($fl) => [
|
|
|
|
|
'url' => $fl,
|
|
|
|
|
'name' => urldecode(basename($fl))
|
|
|
|
|
], $info->files);
|
2026-09-30 14:56:56 +08:00
|
|
|
//交付内容(订单发货表,开发者发货后展示)
|
2026-09-30 16:57:26 +08:00
|
|
|
$info->delivery = OrderShipService::getDemandDelivery($id);
|
2026-09-17 16:25:31 +08:00
|
|
|
|
|
|
|
|
$this->success('', $info);
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
if ($e instanceof HttpResponseException) {
|
|
|
|
|
throw $e;
|
|
|
|
|
}
|
|
|
|
|
$this->error($e->getMessage());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function contractDetail()
|
|
|
|
|
{
|
|
|
|
|
try {
|
|
|
|
|
$demandId = $this->request->param('demandId', 0);
|
|
|
|
|
$info = ContractService::getWinBiddingContract($demandId);
|
|
|
|
|
if (empty($info->data_json['customData']) && ($firstContract = ContractService::getFirstContract($demandId))) {
|
|
|
|
|
$data_json = $info->data_json;
|
|
|
|
|
$data_json['customData'] = $firstContract->data_json['customData'] ?? [];
|
|
|
|
|
$info->data_json = $data_json;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->success('', $info);
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
if ($e instanceof HttpResponseException) {
|
|
|
|
|
throw $e;
|
|
|
|
|
}
|
|
|
|
|
$this->error($e->getMessage());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function joinBidding()
|
|
|
|
|
{
|
|
|
|
|
try {
|
|
|
|
|
if (!$this->auth->isLogin()) {
|
|
|
|
|
$this->error('请先登录');
|
|
|
|
|
}
|
|
|
|
|
$user_id = $this->auth->id ?? -1;
|
|
|
|
|
$params = $this->request->post();
|
|
|
|
|
// 定义验证规则
|
|
|
|
|
$validate = new Validate([
|
|
|
|
|
'demand_id' => 'require',
|
|
|
|
|
'quoted_price' => 'require',
|
|
|
|
|
'need_days' => 'require',
|
|
|
|
|
], [
|
|
|
|
|
'demand_id.require' => '需求id不能为空',
|
|
|
|
|
'quoted_price.require' => '报价不能为空',
|
|
|
|
|
'need_days.require' => '预计工时不能为空'
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
// 验证数据
|
|
|
|
|
if (!$validate->check($params)) {
|
|
|
|
|
$this->error($validate->getError());
|
|
|
|
|
}
|
|
|
|
|
$demand = DemandService::getOne(['id' => $params['demand_id']]);
|
|
|
|
|
if (!$demand) {
|
|
|
|
|
$this->error('该需求不能为空');
|
|
|
|
|
}
|
|
|
|
|
if ($demand->status != 1) {
|
|
|
|
|
$this->error('该需求招标已结束,不能参与报名');
|
|
|
|
|
}
|
|
|
|
|
if ($demand->user_id == $user_id) {
|
|
|
|
|
exception('不能投标自己发布的需求');
|
|
|
|
|
}
|
|
|
|
|
DemandBiddingService::instance()->create($params, $user_id);
|
|
|
|
|
$this->success('报名成功');
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
if ($e instanceof HttpResponseException) {
|
|
|
|
|
throw $e;
|
|
|
|
|
}
|
|
|
|
|
$this->error($e->getMessage());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param
|
|
|
|
|
*/
|
|
|
|
|
public function demandOperate()
|
|
|
|
|
{
|
|
|
|
|
try {
|
|
|
|
|
$param = $this->request->param();
|
|
|
|
|
$userId = $this->auth->id ?? 0;
|
|
|
|
|
$res = DemandService::operateDemand($param, $userId);
|
|
|
|
|
|
|
|
|
|
$this->success('', $res);
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
if ($e instanceof HttpResponseException) {
|
|
|
|
|
throw $e;
|
|
|
|
|
}
|
|
|
|
|
$this->error($e->getMessage());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|