|
@@ -6,9 +6,11 @@ use App\Jobs\ProcessDataJob;
|
|
|
use App\Model\Depart;
|
|
|
use App\Model\Employee;
|
|
|
use App\Model\EmployeeDepartPermission;
|
|
|
+use App\Model\EmployeeIndex;
|
|
|
use App\Model\Product;
|
|
|
use App\Model\RevenueCost;
|
|
|
use App\Model\RevenueCostTotal;
|
|
|
+use App\Model\SalaryEmployee;
|
|
|
use Illuminate\Database\Schema\Blueprint;
|
|
|
use Illuminate\Support\Facades\DB;
|
|
|
use Illuminate\Support\Facades\Schema;
|
|
@@ -46,6 +48,7 @@ class TPlusServerService extends Service
|
|
|
}
|
|
|
|
|
|
private $table = "tmp_revenue_cost_data";
|
|
|
+ private $table_2 = "tmp_salary_employee";
|
|
|
|
|
|
/**
|
|
|
* 同步人员部门
|
|
@@ -741,7 +744,239 @@ class TPlusServerService extends Service
|
|
|
if (Schema::hasTable($this->table)) DB::table($this->table)->truncate();
|
|
|
}
|
|
|
|
|
|
- public function delTableKey(){
|
|
|
- $this->dellimitingSendRequest($this->table);
|
|
|
+ public function delTableKey($type = 1){
|
|
|
+ $key = $this->table;
|
|
|
+ if($type == 2) $key = $this->table_2;
|
|
|
+ $this->dellimitingSendRequest($key);
|
|
|
+ }
|
|
|
+
|
|
|
+ public function synSalaryEmployee($data, $user){
|
|
|
+ if(empty($data['crt_time'][0]) || empty($data['crt_time'][1])) return [false, '同步时间不能为空'];
|
|
|
+ list($start_time, $end_time) = $this->changeDateToTimeStampAboutRange($data['crt_time'],false);
|
|
|
+ if ($start_time === null || $end_time === null || $start_time > $end_time) return [false, "同步时间:时间区间无效"];
|
|
|
+ list($bool, $bool_msg) = $this->isOverThreeMonths($start_time, $end_time);
|
|
|
+ if(! $bool) return [false, $bool_msg];
|
|
|
+ $data['start_timeStamp'] = $start_time;
|
|
|
+ $data['end_timeStamp'] = $end_time;
|
|
|
+ $data['start_time'] = strtotime(date("Y-m-01",$data['start_timeStamp']));
|
|
|
+ $data['end_time'] = strtotime(date("Y-m-01"),$data['end_timeStamp']);
|
|
|
+ $data['operation_time'] = time();
|
|
|
+
|
|
|
+ list($status,$msg) = $this->limitingSendRequest($this->table_2);
|
|
|
+ if(! $status) return [false, '业务员工资同步正在后台运行,请稍后'];
|
|
|
+
|
|
|
+ //同步
|
|
|
+// list($status, $msg) = $this->synSalaryEmployeeFromMine($data, $user);
|
|
|
+// if(! $status) {
|
|
|
+// $this->dellimitingSendRequest($this->table_2);
|
|
|
+// return [false, $msg];
|
|
|
+// }
|
|
|
+
|
|
|
+ //队列
|
|
|
+ ProcessDataJob::dispatch($data, $user, 2)->onQueue(RevenueCost::job2);
|
|
|
+
|
|
|
+ return [true, '业务员工资相关信息同步已进入后台任务'];
|
|
|
+ }
|
|
|
+
|
|
|
+ public function synSalaryEmployeeFromMine($data, $user){
|
|
|
+ //创建临时表 如果不存在
|
|
|
+ $this->createTmpTable2();
|
|
|
+ //清理临时表 如果内容不为空
|
|
|
+ $this->clearTmpTable2();
|
|
|
+
|
|
|
+ //写入临时表
|
|
|
+ DB::table('revenue_cost')
|
|
|
+ ->where('del_time', 0)
|
|
|
+ ->where('order_type', RevenueCost::ORDER_THREE)
|
|
|
+ ->where('order_time','>=',$data['start_timeStamp'])
|
|
|
+ ->where('order_time','<=',$data['end_timeStamp'])
|
|
|
+ ->select([
|
|
|
+ 'employee_id_1',
|
|
|
+ 'employee_id_1_title',
|
|
|
+ DB::raw("DATE_FORMAT(FROM_UNIXTIME(order_time), '%Y-%m-01') as order_time"),
|
|
|
+ DB::raw("SUM(payment_amount) as payment_amount"),
|
|
|
+ DB::raw("SUM(CASE WHEN is_activity = 0 THEN payment_amount ELSE 0 END) as payment_amount_not_include_activity"),
|
|
|
+ DB::raw("SUM(CASE WHEN is_activity = 1 THEN payment_amount ELSE 0 END) as payment_amount_activity"),
|
|
|
+ DB::raw("SUM(CASE WHEN profit_rate < customer_profit_rate and is_activity = 0 THEN payment_amount ELSE 0 END) as payment_amount_lower_than_rate"),
|
|
|
+ DB::raw("SUM(CASE WHEN profit_rate >= customer_profit_rate and is_activity = 0 THEN payment_amount ELSE 0 END) as payment_amount_greater_than_rate"),
|
|
|
+ DB::raw("SUM(CASE WHEN profit_rate >= customer_profit_rate and is_activity = 0 THEN price_4_total ELSE 0 END) as business"),
|
|
|
+ DB::raw("ROW_NUMBER() OVER (ORDER BY MIN(id)) as fake_id")
|
|
|
+ ])
|
|
|
+ ->groupBy('employee_id_1', DB::raw("DATE_FORMAT(FROM_UNIXTIME(order_time), '%Y-%m-01')"))
|
|
|
+ ->orderBy('order_time', 'desc')
|
|
|
+ ->chunkById(500, function ($data){
|
|
|
+ $dataArray = Collect($data)->map(function ($object){
|
|
|
+ return (array)$object;
|
|
|
+ })->toArray();
|
|
|
+
|
|
|
+ $indexes = $this->getEmployeeIndex($dataArray);
|
|
|
+ foreach ($dataArray as $key => $value){
|
|
|
+ $value['index_' . EmployeeIndex::TYPE_ONE] = 0;
|
|
|
+ $value['index_' . EmployeeIndex::TYPE_SIX] = 0;
|
|
|
+ $value['index_' . EmployeeIndex::TYPE_EIGHT] = 0;
|
|
|
+ $this->findIndex($indexes, $value);
|
|
|
+
|
|
|
+ $dataArray[$key]['order_type'] = RevenueCost::ORDER_THREE;
|
|
|
+ $dataArray[$key]['order_time'] = strtotime($value['order_time']);
|
|
|
+ $dataArray[$key]['sale_bonus'] = $value['index_' . EmployeeIndex::TYPE_EIGHT];
|
|
|
+ $dataArray[$key]['index_' . EmployeeIndex::TYPE_ONE] = $value['index_' . EmployeeIndex::TYPE_ONE];
|
|
|
+ $rate = bcdiv($value['index_' . EmployeeIndex::TYPE_ONE],100,2);
|
|
|
+ $pay_in_advance = bcmul($rate, $value['payment_amount_greater_than_rate'],2);
|
|
|
+ $dataArray[$key]['pay_in_advance'] = $pay_in_advance;
|
|
|
+ $dataArray[$key]['basic_salary'] = $value['index_' . EmployeeIndex::TYPE_SIX];
|
|
|
+ $dataArray[$key]['should_pay'] = bcadd(bcadd($value['index_' . EmployeeIndex::TYPE_EIGHT], $pay_in_advance,2),$value['index_' . EmployeeIndex::TYPE_SIX],2);
|
|
|
+
|
|
|
+ unset($dataArray[$key]['fake_id']);
|
|
|
+ }
|
|
|
+
|
|
|
+ DB::table($this->table_2)->insert($dataArray);
|
|
|
+ }, 'fake_id');
|
|
|
+
|
|
|
+ //更新数据
|
|
|
+ list($status,$msg) = $this->updateSalaryEmployee($data);
|
|
|
+ if(! $status) return [false, $msg];
|
|
|
+
|
|
|
+ //清理临时表 如果内容不为空
|
|
|
+ $this->clearTmpTable2();
|
|
|
+ //释放redis
|
|
|
+ $this->delTableKey(2);
|
|
|
+
|
|
|
+ return [true, '同步成功'];
|
|
|
+ }
|
|
|
+
|
|
|
+ private function getEmployeeIndex($existingData)
|
|
|
+ {
|
|
|
+ if (empty($existingData)) {
|
|
|
+ return collect();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 取出所有涉及的 employee_id 和时间区间
|
|
|
+ $employeeIds = array_column($existingData, 'employee_id_2');
|
|
|
+ $time = array_column($existingData, 'order_time');
|
|
|
+ $minStart = ! empty($time) ? min($time) : 0;
|
|
|
+ $maxEnd = ! empty($time) ? max($time) : 0;
|
|
|
+
|
|
|
+ // 一次性查出这些员工在最大区间范围内的所有指标
|
|
|
+ $results = EmployeeIndex::where('del_time', 0)
|
|
|
+ ->whereIn('type', [EmployeeIndex::TYPE_ONE, EmployeeIndex::TYPE_EIGHT])
|
|
|
+ ->whereIn('employee_id', $employeeIds)
|
|
|
+ ->where('start_time', '<=', $maxEnd)
|
|
|
+ ->where('end_time', '>=', $minStart)
|
|
|
+ ->select('start_time','end_time','employee_id','index','type')
|
|
|
+ ->get();
|
|
|
+
|
|
|
+ return $results;
|
|
|
+ }
|
|
|
+
|
|
|
+ private function findIndex($indexes, &$value){
|
|
|
+ // 找到所有符合条件的 index(可能多个 type)
|
|
|
+ $matchedIndexes = $indexes->filter(function ($item) use ($value) {
|
|
|
+ return $item['employee_id'] == $value['employee_id_1']
|
|
|
+ && $item['start_time'] <= $value['end_time']
|
|
|
+ && $item['end_time'] >= $value['start_time'];
|
|
|
+ });
|
|
|
+ // 按 type 去重,只保留第一次出现的
|
|
|
+ $uniqueByType = [];
|
|
|
+ foreach ($matchedIndexes as $item) {
|
|
|
+ $index = "index_" . $item['type'];
|
|
|
+ if (! isset($uniqueByType[$index])) {
|
|
|
+ $uniqueByType[$index] = $item['index'];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ $value = array_merge($value, $uniqueByType);
|
|
|
+ }
|
|
|
+
|
|
|
+ private function createTmpTable2(){
|
|
|
+ $table = $this->table_2;
|
|
|
+ if (! Schema::hasTable($table)) {
|
|
|
+ // 可以通过 migration 创建,或程序启动时检查
|
|
|
+ Schema::create($table, function (Blueprint $table) {
|
|
|
+ $table->bigIncrements('id'); // BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY
|
|
|
+ $table->integer('order_type')->default(0);
|
|
|
+ $table->integer('order_time')->default(0);
|
|
|
+ $table->string('employee_id_1_title', 100)->default('');
|
|
|
+ $table->bigInteger('employee_id_1')->default(0);
|
|
|
+ $table->decimal('payment_amount', 12, 2)->default(0);
|
|
|
+ $table->decimal('payment_amount_not_include_activity', 12, 2)->default(0);
|
|
|
+ $table->decimal('payment_amount_activity', 12, 2)->default(0);
|
|
|
+ $table->decimal('payment_amount_lower_than_rate', 12, 2)->default(0);
|
|
|
+ $table->decimal('payment_amount_greater_than_rate', 12, 2)->default(0);
|
|
|
+ $table->decimal('business', 12, 2)->default(0);
|
|
|
+ $table->decimal('sale_bonus', 12, 2)->default(0);
|
|
|
+ $table->decimal('index_1', 10, 2)->default(0);
|
|
|
+ $table->decimal('pay_in_advance', 12, 2)->default(0);
|
|
|
+ $table->decimal('basic_salary', 12, 2)->default(0);
|
|
|
+ $table->decimal('should_pay', 12, 2)->default(0);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public function clearTmpTable2(){
|
|
|
+ if (Schema::hasTable($this->table_2)) DB::table($this->table_2)->truncate();
|
|
|
+ }
|
|
|
+
|
|
|
+ private function updateSalaryEmployee($data){
|
|
|
+ try {
|
|
|
+ $start_timeStamp = $data['start_time'];
|
|
|
+ $end_timeStamp = $data['end_time'];
|
|
|
+ $tmpTable = $this->table_2;
|
|
|
+ $time = time();
|
|
|
+ $ergs = $data;
|
|
|
+
|
|
|
+ DB::transaction(function () use ($start_timeStamp, $end_timeStamp, $tmpTable,$time, $ergs) {
|
|
|
+ // 1. 先软删除旧数据(你已有)
|
|
|
+ SalaryEmployee::where('del_time', 0)
|
|
|
+ ->where('order_time', '>=', $start_timeStamp)
|
|
|
+ ->where('order_time', '<=', $end_timeStamp)
|
|
|
+ ->update(['del_time' => $time]);
|
|
|
+
|
|
|
+ // 2. 分批从临时表插入新数据
|
|
|
+ $batchSize = 500;
|
|
|
+ $lastId = 0;
|
|
|
+ do {
|
|
|
+ $chunk = DB::table($tmpTable)
|
|
|
+ ->where('id', '>', $lastId)
|
|
|
+ ->orderBy('id')
|
|
|
+ ->limit($batchSize)
|
|
|
+ ->get();
|
|
|
+
|
|
|
+ if ($chunk->isEmpty()) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ $data = $chunk->map(function ($item) use($time){
|
|
|
+ return [
|
|
|
+ 'order_type' => $item->order_type,
|
|
|
+ 'order_time' => $item->order_time,
|
|
|
+ 'employee_id_1_title' => $item->employee_id_1_title,
|
|
|
+ 'employee_id_1' => $item->employee_id_1 ?? 0,
|
|
|
+ 'payment_amount' => $item->payment_amount,
|
|
|
+ 'payment_amount_not_include_activity' => $item->payment_amount_not_include_activity,
|
|
|
+ 'payment_amount_activity' => $item->payment_amount_activity,
|
|
|
+ 'payment_amount_lower_than_rate' => $item->payment_amount_lower_than_rate,
|
|
|
+ 'payment_amount_greater_than_rate' => $item->payment_amount_greater_than_rate,
|
|
|
+ 'business' => $item->business,
|
|
|
+ 'sale_bonus' => $item->sale_bonus,
|
|
|
+ 'index_1' => $item->index_1,
|
|
|
+ 'pay_in_advance' => $item->pay_in_advance,
|
|
|
+ 'basic_salary' => $item->basic_salary,
|
|
|
+ 'should_pay' => $item->should_pay,
|
|
|
+ 'crt_time' => $time,
|
|
|
+ ];
|
|
|
+ })->toArray();
|
|
|
+
|
|
|
+ // 每批单独插入(可选:加小事务)
|
|
|
+ SalaryEmployee::insert($data);
|
|
|
+
|
|
|
+ // 更新 lastId
|
|
|
+ $lastId = $chunk->last()->id;
|
|
|
+
|
|
|
+ } while ($chunk->count() == $batchSize);
|
|
|
+ });
|
|
|
+ }catch (\Throwable $exception){
|
|
|
+ return [false, "单据明细同步异常" . $exception->getMessage() . "|" . $exception->getLine() . "|" . $exception->getFile()];
|
|
|
+ }
|
|
|
+
|
|
|
+ return [true, ''];
|
|
|
}
|
|
|
}
|