cqp 1 月之前
父節點
當前提交
07334e5073
共有 4 個文件被更改,包括 239 次插入62 次删除
  1. 64 0
      app/Model/EmployeeIndex.php
  2. 68 43
      app/Service/EmployeeService.php
  3. 6 6
      app/Service/ProductService.php
  4. 101 13
      app/Service/Service.php

+ 64 - 0
app/Model/EmployeeIndex.php

@@ -0,0 +1,64 @@
+<?php
+
+namespace App\Model;
+
+use Illuminate\Database\Eloquent\Model;
+
+class EmployeeIndex extends Model
+{
+    protected $guarded = [];
+    protected $table = "employee_index"; //指定表
+    const CREATED_AT = 'crt_time';
+    const UPDATED_AT = 'upd_time';
+    protected $dateFormat = 'U';
+
+    //指标类型
+    const TYPE_ONE = 1;
+    const TYPE_TWO = 2;
+    const TYPE_THREE = 3;
+    const TYPE_FOUR = 4;
+    const TYPE_FIVE = 5;
+    const TYPE_SIX = 6;
+    const TYPE_SEVEN = 7;
+    const TYPE_EIGHT = 8;
+    const TYPE_NINE = 9;
+    const TYPE_TEN = 10;
+    const TYPE_EVE = 11;
+    const TYPE_TWL = 12;
+
+    public static $type_name = [
+        Self::TYPE_ONE => '预支分红比例',
+        Self::TYPE_TWO => '月度指标金额',
+        Self::TYPE_THREE => '季度指标金额',
+        Self::TYPE_FOUR => '指标比例',
+        Self::TYPE_FIVE => '分红比例',
+        Self::TYPE_SIX => '基本工资',
+        Self::TYPE_SEVEN => '退损比例',
+        Self::TYPE_EIGHT => '销售奖金',
+        Self::TYPE_NINE => '其他补贴1',
+        Self::TYPE_TEN => '其他补贴2',
+        Self::TYPE_EVE => '其他补贴3',
+        Self::TYPE_TWL => '销售工资',
+    ];
+
+    public static $positive = [
+        Self::TYPE_ONE => '预支分红比例',
+        Self::TYPE_TWO => '月度指标金额',
+        Self::TYPE_THREE => '季度指标金额',
+        Self::TYPE_FOUR => '指标比例',
+        Self::TYPE_FIVE => '分红比例',
+        Self::TYPE_SIX => '基本工资',
+        Self::TYPE_SEVEN => '退损比例',
+        Self::TYPE_EIGHT => '销售奖金',
+    ];
+
+    public static $positive_2 = [
+        Self::TYPE_TWL => '销售工资',
+    ];
+
+    public static $null = [
+        Self::TYPE_NINE => '其他补贴1',
+        Self::TYPE_TEN => '其他补贴2',
+        Self::TYPE_EVE => '其他补贴3',
+    ];
+}

+ 68 - 43
app/Service/EmployeeService.php

@@ -9,6 +9,7 @@ use App\Model\DepartWithDHF;
 use App\Model\Employee;
 use App\Model\EmployeeDepartPermission;
 use App\Model\EmployeeFile;
+use App\Model\EmployeeIndex;
 use App\Model\EmployeeManagerDepart;
 use App\Model\EmployeeMenuPermission;
 use App\Model\EmployeeRole;
@@ -135,33 +136,15 @@ class EmployeeService extends Service
             DB::beginTransaction();
             $model = new Employee();
             $model = $model->where('id',$data['id'])->first();
-            $model->number = $data['number'];
-            $model->emp_name = $data['emp_name'];
-            $model->mobile = $data['mobile'] ?? '';
-            $model->leave_time = $data['leave_time'] ?? '';
-            $model->entry_time = $data['entry_time'] ?? '';
-            $model->state = empty($data['leave_time']) ? Employee::USE : Employee::NOT_USE;
             $model->is_admin = $data['is_admin'];
             $model->account = $data['number'];
             if($model->is_admin == 1){
                 if($data['password'] !== '******'){
-                    $model->password   = Hash::make($data['password']);
+                    $model->password = Hash::make($data['password']);
                 }
             }
             $model->save();
 
-            EmployeeDepartPermission::where('employee_id',$data['id'])->delete();
-            if(isset($data['depart'])){
-                $insert = [];
-                foreach ($data['depart'] as $value){
-                    $insert[] = [
-                        'employee_id' => $model->id,
-                        'depart_id' => $value,
-                    ];
-                }
-                EmployeeDepartPermission::insert($insert);
-            }
-
             EmployeeRole::where('employee_id',$data['id'])->update([
                 'del_time' => time()
             ]);
@@ -178,6 +161,10 @@ class EmployeeService extends Service
                 EmployeeRole::insert($insert);
             }
 
+            if(! empty($data['index_array'])){
+
+            }
+
             DB::commit();
         }catch (\Exception $exception){
             DB::rollBack();
@@ -375,32 +362,69 @@ class EmployeeService extends Service
      * @return array
      */
     public function employeeRule($data,$is_add = true){
-        if($this->isEmpty($data,'number')) return [false,'工号不存在!'];
-        if($this->isEmpty($data,'emp_name')) return [false,'姓名不存在!'];
-        if(empty($data['depart'])) return [false,'部门不能为空'];
+        if(empty($data['id'])) return [false,'人员ID不能为空'];
+
+        if(! empty($data['index_array'])){
+            $typeIntervals = []; // 用于收集每个 type 的时间区间,用于后续不相交校验
+            foreach ($data['index_array'] as $key => $value){
+                if(empty($value['type'])) return [false, '人员指标类型不能为空'];
+                if(! isset(EmployeeIndex::$type_name[$value['type']])) return [false, '人员指标类型不存在'];
+                $name = EmployeeIndex::$type_name[$value['type']];
+                if(empty($value['crt_time']) || ! is_array($value['crt_time'])) return [false, $name . ":时间区间不能为空"];
+                list($start_time, $end_time) = $this->changeDateToTimeStampAboutRange($value['crt_time']);
+                $data['index_array'][$key]['start_time'] = $start_time;
+                $data['index_array'][$key]['end_time'] = $end_time;
+                if ($start_time === null || $end_time === null || $start_time > $end_time) return [false, $name . ":时间区间无效"];
+                // 收集每个 type 的时间区间,用于后续不相交校验
+                $type = $value['type'];
+                $typeIntervals[$type][] = [
+                    'start' => $start_time,
+                    'end' => $end_time,
+                    'index' => $key, // 用于报错定位
+                ];
 
-        $mobile = $data['mobile'] ?? "";
-        $number = $data['number'] ?? "";
-        if(! $is_add){
-            if($this->isEmpty($data,'id')) return [false,'ID不能为空!'];
-            $bool = Employee::where('del_time',0)
-                ->where('id','<>',$data['id'])
-                ->where(function ($query) use ($mobile, $number){
-                    $query->where('number', $number);
-                    $query->when(! empty($mobile), function ($query) use ($mobile) {
-                        return $query->orWhere('mobile', $mobile);
-                    });
-                })->exists();
-        }else{
-            $bool = Employee::where('del_time',0)
-                ->where(function ($query) use ($mobile, $number){
-                    $query->where('number', $number);
-                    $query->when(! empty($mobile), function ($query) use ($mobile) {
-                        return $query->orWhere('mobile', $mobile);
-                    });
-                })->exists();
+                if(! isset($value['index'])) return [false, 'index不存在'];
+                if(isset(EmployeeIndex::$positive[$value['type']])){
+                    $name_string = EmployeeIndex::$positive[$value['type']];
+                    $res = $this->checkNumber($value['index'],2,'non-negative');
+                    if(! $res['valid']) return [false, $name_string . ":" . $res['error']];
+                }elseif(isset(EmployeeIndex::$null[$value['type']])){
+                    $name_string = EmployeeIndex::$positive[$value['type']];
+                    $res = $this->checkNumber($value['index']);
+                    if(! $res['valid']) return [false, $name_string . ":" . $res['error']];
+                }elseif(isset(EmployeeIndex::$positive_2[$value['type']])){
+                    if(! isset($value['index_2'])) return [false, 'index_2不存在'];
+                    if(! isset($value['index_3'])) return [false, 'index_3不存在'];
+                    $name_string = EmployeeIndex::$positive[$value['type']];
+                    $res = $this->checkNumber($value['index'],2,'positive');
+                    if(! $res['valid']) return [false, $name_string . "基数:" . $res['error']];
+                    $res = $this->checkNumber($value['index_2'],2,'positive');
+                    if(! $res['valid']) return [false, $name_string . "比例:" . $res['error']];
+                    $res = $this->checkNumber($value['index_3'],2,'positive');
+                    if(! $res['valid']) return [false, $name_string . ":" . $res['error']];
+                }
+            }
+
+            //在校验循环之后
+            foreach ($typeIntervals as $type => $intervals) {
+                if (count($intervals) < 2) continue;
+
+                usort($intervals, function($a, $b) {
+                    return $a['start'] <=> $b['start'];
+                });
+
+                for ($i = 1; $i < count($intervals); $i++) {
+                    $prev = $intervals[$i - 1];
+                    $curr = $intervals[$i];
+
+                    // 方式1:闭区间 [start, end] —— 推荐大多数场景
+                    if ($prev['end'] >= $curr['start']) {
+                        $typeName = EmployeeIndex::$type_name[$type] ?? $type;
+                        return [false, "{$typeName}的时间区间存在重叠,请检查"];
+                    }
+                }
+            }
         }
-        if($bool) return [false,'工号或手机号码已存在!'];
 
         return [true,''];
     }
@@ -691,6 +715,7 @@ class EmployeeService extends Service
         if(isset($data['parent_id'])) $model->where('parent_id', $data['parent_id']);
         if(! empty($data['title'])) $model->where('title', 'LIKE', '%'.$data['title'].'%');
         if(! empty($data['code'])) $model->where('code', 'LIKE', '%'.$data['code'].'%');
+        if(isset($data['is_use'])) $model->where('is_use', $data['is_use']);
 
         $list = $model->get()->toArray();
         $list = $this->fillDepartList($list, $user);

+ 6 - 6
app/Service/ProductService.php

@@ -327,24 +327,24 @@ class ProductService extends Service
         if(! isset($data['cost'])) return [false, '请填写成本'];
         if(! isset($data['business_cost'])) return [false, '请填写业务成本'];
         $res = $this->checkNumber($data['cost']);
-        if(! $res) return [false,'成本请输入不超过两位小数并且大于等于0的数值'];
+        if(! $res['valid']) return [false,'成本:' . $res['error']];
         $res = $this->checkNumber($data['business_cost']);
-        if(! $res) return [false,'业务成本请输入不超过两位小数并且大于等于0的数值'];
+        if(! $res['valid']) return [false,'业务成本:' . $res['error']];
         if(! empty($data['write_off_price'])){
             $res = $this->checkNumber($data['write_off_price']);
-            if(! $res) return [false,'核销单价请输入不超过两位小数并且大于等于0的数值'];
+            if(! $res['valid']) return [false,'核销单价:' . $res['error']];
         }
         if(! empty($data['major_client_settlement_price'])){
             $res = $this->checkNumber($data['major_client_settlement_price']);
-            if(! $res) return [false,'大客户结算单价请输入不超过两位小数并且大于等于0的数值'];
+            if(! $res['valid']) return [false,'大客户结算单价:' . $res['error']];
         }
         if(! empty($data['return_change_price'])){
             $res = $this->checkNumber($data['return_change_price']);
-            if(! $res) return [false,'退货损耗单价请输入不超过两位小数并且大于等于0的数值'];
+            if(! $res['valid']) return [false,'退货损耗单价:' . $res['error']];
         }
         if(! empty($data['freight_price'])){
             $res = $this->checkNumber($data['freight_price']);
-            if(! $res) return [false,'运费单价请输入不超过两位小数并且大于等于0的数值'];
+            if(! $res['valid']) return [false,'运费单价:' . $res['error']];
         }
 
         if($is_add){

+ 101 - 13
app/Service/Service.php

@@ -371,7 +371,7 @@ class Service
 
     //前端传来的时间 转为时间戳
     //精确到日
-    function changeDateToDate($time){
+    function changeDateToDate($time, $is_end = false){
         if(empty($time)) return '';
 
         // 创建一个 DateTime 对象并设置时区为 UTC
@@ -380,29 +380,117 @@ class Service
         // 将时区设置为 PRC
         $dateTime->setTimezone(new \DateTimeZone('Asia/Shanghai'));
 
+        $str = "00:00:00";
+        if($is_end) $str = "23:59:59";
+
         // 将日期时间格式化为特定格式
-        $formattedDate = $dateTime->format('Y-m-d 00:00:00');
+        $formattedDate = $dateTime->format('Y-m-d ' . $str);
 
         return strtotime($formattedDate);
     }
 
     /**
-     * 用于用户行为操作日志记录
-     * @param $insert
-     * @return void
+     * 检查数字是否合法,并可验证其正负性和小数位数
+     *
+     * @param mixed $number 要检查的值
+     * @param int $decimals 允许的最大小数位数(默认 2)
+     * @param string|null $sign 要求的符号:'positive', 'negative', 'zero', 'non-negative', 'non-positive' null 表示不限制
+     * @param bool $strict 是否严格模式(不允许整数传字符串等)
+     * @return array ['valid' => bool, 'error' => string|null, 'info' => array]
      */
-    public function insertLog($insert){
+    public function checkNumber($number, $decimals = 2, $sign = null, $strict = false)
+    {
+        $result = [
+            'valid' => false,
+            'error' => null,
+            'info' => []
+        ];
+
+        // 1. 类型检查
+        if ($strict) {
+            if (!is_numeric($number) || is_bool($number)) {
+                $result['error'] = '必须是数字类型';
+                return $result;
+            }
+        } else {
+            // 宽松模式:允许字符串数字
+            if (!is_numeric($number)) {
+                $result['error'] = '不是有效数字';
+                return $result;
+            }
+        }
 
-        OperationLog::dispatch($insert);
+        $num = (float)$number; // 统一转为浮点数处理
 
-    }
+        // 2. 正负号检查
+        if ($sign !== null) {
+            switch ($sign) {
+                case 'positive':
+                    if ($num <= 0) {
+                        $result['error'] = '数字必须大于 0';
+                        return $result;
+                    }
+                    break;
+                case 'negative':
+                    if ($num >= 0) {
+                        $result['error'] = '数字必须小于 0';
+                        return $result;
+                    }
+                    break;
+                case 'zero':
+                    if ($num != 0) {
+                        $result['error'] = '数字必须等于 0';
+                        return $result;
+                    }
+                    break;
+                case 'non-negative': // 大于等于 0
+                    if ($num < 0) {
+                        $result['error'] = '数字必须大于或等于 0';
+                        return $result;
+                    }
+                    break;
+                case 'non-positive': // 小于等于 0
+                    if ($num > 0) {
+                        $result['error'] = '数字必须小于或等于 0';
+                        return $result;
+                    }
+                    break;
+                default:
+                    $result['error'] = "不支持的符号类型: '{$sign}'";
+                    return $result;
+            }
+        }
 
-    public function checkNumber($number, $decimals = 2){
-        if(! is_numeric($number) || $number < 0)  return false;
-        $formattedNumber = number_format($number, $decimals, '.', '');
-        if($formattedNumber != $number) return false;
+        // 3. 小数位数检查
+        // 将数字转为标准格式,避免科学计数法
+        $numStr = rtrim(rtrim(sprintf('%.10F', $num), '0'), '.'); // 去除末尾无意义的0
+        if ($numStr === '' || $numStr === '-') {
+            $numStr = '0';
+        }
 
-        return true;
+        // 检查是否有小数点
+        if (strpos($numStr, '.') === false) {
+            $decimalPlaces = 0;
+        } else {
+            $parts = explode('.', $numStr);
+            $decimalPlaces = strlen($parts[1]);
+        }
+
+        if ($decimalPlaces > $decimals) {
+            $result['error'] = "小数位数超过 {$decimals} 位(实际 {$decimalPlaces} 位)";
+            return $result;
+        }
+
+        // 4. 附加信息
+        $result['valid'] = true;
+        $result['info'] = [
+            'original' => $number,
+            'value' => $num,
+            'decimal_places' => $decimalPlaces,
+            'sign' => $num > 0 ? 'positive' : ($num < 0 ? 'negative' : 'zero'),
+        ];
+
+        return $result;
     }
 
     public function getDepart($user){