Merge branch 'master' of ssh://47.101.48.251:/data/git/wx.sstbc.com

master
lion 3 months ago
commit 5086db3ac3

@ -75,13 +75,19 @@ class CourseSignController extends BaseController
{
$all = request()->all();
$clear = request('clear', 1);
$list = $this->model->with(['course.typeDetail', 'user' => function ($query) use ($all, $clear) {
if ($clear) {
$query->with(['company', 'courseSigns' => function ($q) {
$q->where('status', 1)->with('course');
}]);
$list = $this->model->with([
'course.typeDetail',
'user' => function ($query) use ($all, $clear) {
if ($clear) {
$query->with([
'company',
'courseSigns' => function ($q) {
$q->where('status', 1)->with('course.typeDetail');
}
]);
}
}
}])->whereHas('user', function ($query) use ($all) {
])->whereHas('user', function ($query) use ($all) {
if (isset($all['is_vip'])) {
$query->where('is_vip', $all['is_vip']);
}
@ -146,7 +152,7 @@ class CourseSignController extends BaseController
if (isset($all['course_type_id'])) {
$course_type_id = explode(',', $all['course_type_id']);
$courses = Course::where(function ($query) use ($all) {
// if (isset($all['start_date'])) {
// if (isset($all['start_date'])) {
// $query->where('start_date', '>=', $all['start_date']);
// }
// if (isset($all['end_date'])) {
@ -280,7 +286,8 @@ class CourseSignController extends BaseController
// 检测手机号是否存在
if (isset($all['mobile'])) {
$otherUser = User::where('mobile', $all['mobile'])->where('id', '!=', $model->id)->first();
if ($otherUser) return $this->fail([ResponseCode::ERROR_BUSINESS, '该手机号已存在']);
if ($otherUser)
return $this->fail([ResponseCode::ERROR_BUSINESS, '该手机号已存在']);
}
} else {
$model = $this->model;
@ -289,7 +296,8 @@ class CourseSignController extends BaseController
// 检测手机号是否存在
if (isset($all['mobile'])) {
$otherUser = User::where('mobile', $all['mobile'])->first();
if ($otherUser) return $this->fail([ResponseCode::ERROR_BUSINESS, '该手机号已存在']);
if ($otherUser)
return $this->fail([ResponseCode::ERROR_BUSINESS, '该手机号已存在']);
}
}
$original = $model->getOriginal();
@ -436,7 +444,8 @@ class CourseSignController extends BaseController
} else {
if (in_array($k, ['company_type', 'type'])) {
$list[$key][$k] = str_replace('、', ',', $value[$v]);
$list[$key][$k] = str_replace('', ',', $list[$key][$k]);;
$list[$key][$k] = str_replace('', ',', $list[$key][$k]);
;
} else {
$list[$key][$k] = $value[$v];
}
@ -542,7 +551,8 @@ class CourseSignController extends BaseController
}
$course = Course::find($course_id);
$fee_status = $course->is_fee;
if ($item['status'] == 0) $fee_status = 0;
if ($item['status'] == 0)
$fee_status = 0;
$courseSign = CourseSign::updateOrCreate($signWhere, ['is_import' => 1, 'user_id' => $user->id, 'status' => $item['status'], 'fee_status' => $fee_status, 'course_id' => $course_id, 'data' => $signData]);
// 加预约次数
if ($item['status'] == 1) {
@ -600,7 +610,8 @@ class CourseSignController extends BaseController
$idsArray = explode(',', $all['ids']);
foreach ($idsArray as $id) {
$model = $this->model->find($id);
if (empty($model)) continue;
if (empty($model))
continue;
$data = ['course_id' => $all['course_id'], 'course_sign_id' => $id, 'status_text' => CourseSign::$intToString['status'][$all['status']]];
$model->status = $all['status'];
$model->reason = $all['reason'] ?? '';
@ -689,7 +700,8 @@ class CourseSignController extends BaseController
try {
foreach ($idsArray as $id) {
$model = $this->model->find($id);
if (empty($model)) continue;
if (empty($model))
continue;
if ($model->fee_status == 0) {
Notification::send(User::find($model->user_id), new FeeNotify($data));
}

@ -57,79 +57,79 @@ class UserController extends BaseController
$all = request()->all();
$list = $this->model->with(underlineToHump($all['show_relation'] ?? []))
->with([
'courseSigns' => function ($query) use ($all) {
$query->where('status', 1)->with('course.teacher', 'course.typeDetail');
}
])->where(function ($query) use ($all) {
if (isset($all['keyword'])) {
$query->whereHas('courses', function ($q) use ($all) {
$q->where('name', 'like', '%' . $all['keyword'] . '%');
})->orWhere('name', 'like', '%' . $all['keyword'] . '%');
}
if (isset($all['has_course']) && $all['has_course'] == 1) {
$query->whereHas('courseSigns', function ($q) {
$q->where('status', 1);
});
}
if (isset($all['filter']) && !empty($all['filter'])) {
foreach ($all['filter'] as $condition) {
$key = $condition['key'] ?? null;
$op = $condition['op'] ?? null;
$value = $condition['value'] ?? null;
if (!isset($key) || !isset($op) || !isset($value)) {
continue;
}
// 等于
if ($op == 'eq') {
$query->where($key, $value);
}
// 不等于
if ($op == 'neq') {
$query->where($key, '!=', $value);
}
// 大于
if ($op == 'gt') {
$query->where($key, '>', $value);
}
// 大于等于
if ($op == 'egt') {
$query->where($key, '>=', $value);
}
// 小于
if ($op == 'lt') {
$query->where($key, '<', $value);
}
// 小于等于
if ($op == 'elt') {
$query->where($key, '<=', $value);
}
// 模糊搜索
if ($op == 'like') {
$query->where($key, 'like', '%' . $value . '%');
}
// 否定模糊搜索
if ($op == 'notlike') {
$query->where($key, 'not like', '%' . $value . '%');
}
// null搜索
if ($op == 'null') {
$query->whereNull($key);
}
// notnull搜索
if ($op == 'notnull') {
$query->whereNotNull($key);
}
// 范围搜索
if ($op == 'range') {
list($from, $to) = explode(',', $value);
if (empty($from) || empty($to)) {
'courseSigns' => function ($query) use ($all) {
$query->where('status', 1)->with('course.teacher', 'course.typeDetail');
}
])->where(function ($query) use ($all) {
if (isset($all['keyword'])) {
$query->whereHas('courses', function ($q) use ($all) {
$q->where('name', 'like', '%' . $all['keyword'] . '%');
})->orWhere('name', 'like', '%' . $all['keyword'] . '%');
}
if (isset($all['has_course']) && $all['has_course'] == 1) {
$query->whereHas('courseSigns', function ($q) {
$q->where('status', 1);
});
}
if (isset($all['filter']) && !empty($all['filter'])) {
foreach ($all['filter'] as $condition) {
$key = $condition['key'] ?? null;
$op = $condition['op'] ?? null;
$value = $condition['value'] ?? null;
if (!isset($key) || !isset($op) || !isset($value)) {
continue;
}
$query->whereBetween($key, [$from, $to]);
// 等于
if ($op == 'eq') {
$query->where($key, $value);
}
// 不等于
if ($op == 'neq') {
$query->where($key, '!=', $value);
}
// 大于
if ($op == 'gt') {
$query->where($key, '>', $value);
}
// 大于等于
if ($op == 'egt') {
$query->where($key, '>=', $value);
}
// 小于
if ($op == 'lt') {
$query->where($key, '<', $value);
}
// 小于等于
if ($op == 'elt') {
$query->where($key, '<=', $value);
}
// 模糊搜索
if ($op == 'like') {
$query->where($key, 'like', '%' . $value . '%');
}
// 否定模糊搜索
if ($op == 'notlike') {
$query->where($key, 'not like', '%' . $value . '%');
}
// null搜索
if ($op == 'null') {
$query->whereNull($key);
}
// notnull搜索
if ($op == 'notnull') {
$query->whereNotNull($key);
}
// 范围搜索
if ($op == 'range') {
list($from, $to) = explode(',', $value);
if (empty($from) || empty($to)) {
continue;
}
$query->whereBetween($key, [$from, $to]);
}
}
}
}
})->orderBy($all['sort_name'] ?? 'id', $all['sort_type'] ?? 'desc');
})->orderBy($all['sort_name'] ?? 'id', $all['sort_type'] ?? 'desc');
if (isset($all['is_export']) && !empty($all['is_export'])) {
$list = $list->get()->toArray();
$export_fields = $all['export_fields'] ?? [];
@ -187,6 +187,7 @@ class UserController extends BaseController
* @OA\Parameter(name="is_black", in="query", @OA\Schema(type="string"), required=true, description="是否黑名单0否1是"),
* @OA\Parameter(name="is_yh_invested", in="query", @OA\Schema(type="string"), required=true, description="是否元和已投企业0否1是"),
* @OA\Parameter(name="company_tag", in="query", @OA\Schema(type="string"), required=true, description="企业标签"),
* @OA\Parameter(name="talent_tags", in="query", @OA\Schema(type="string"), required=false, description="人才标签,多个英文逗号分隔"),
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Response(
* response="200",
@ -209,10 +210,10 @@ class UserController extends BaseController
'company'
)
->with([
'courseSigns' => function ($query) {
$query->with('course.typeDetail')->orderBy('fee_status', 'desc');
}
])->withCount([
'courseSigns' => function ($query) {
$query->with('course.typeDetail')->orderBy('fee_status', 'desc');
}
])->withCount([
'appointments' => function ($query) {
$query->whereIn('status', [0, 1]);
}
@ -379,6 +380,14 @@ class UserController extends BaseController
->orWhere('speciality', 'like', '%' . $all['keyword'] . '%')
->orWhere('introduce', 'like', '%' . $all['keyword'] . '%');
}
if (isset($all['talent_tags'])) {
$talentTags = explode(',', $all['talent_tags']);
$query->where(function ($q) use ($talentTags) {
foreach ($talentTags as $tag) {
$q->orWhereRaw('FIND_IN_SET(?, talent_tags)', [trim($tag)]);
}
});
}
})->orderBy($all['sort_name'] ?? 'id', $all['sort_type'] ?? 'desc');
if (isset($all['is_export']) && !empty($all['is_export'])) {
$list = $list->limit(5000)->get()->toArray();
@ -812,13 +821,28 @@ class UserController extends BaseController
$tableName = $this->model->getTable();
$rowTableFieldByComment = (new CustomFormField)->getRowTableFieldsByComment($tableName);
// 获取 Excel 文件中的表头(从第一行数据中提取)
$excelHeaders = [];
if (!empty($dataArray)) {
$firstRow = reset($dataArray);
$excelHeaders = array_keys($firstRow);
}
// 只保留 Excel 中存在的字段的表头信息
$filteredHeaders = [];
foreach ($rowTableFieldByComment as $fieldName => $comment) {
if (in_array($comment, $excelHeaders)) {
$filteredHeaders[$fieldName] = $comment;
}
}
$list = [];
$unmatchedUsers = []; // 记录未匹配到的用户
foreach ($dataArray as $key => $value) {
// 获取姓名、公司名称、职位
$name = $value['姓名'] ?? $value['name'] ?? '';
$companyName = $value['公司名称'] ?? $value['company_name'] ?? '';
$companyPosition = $value['职位'] ?? $value['company_position'] ?? '';
$companyName = $value['公司'] ?? $value['company_name'] ?? '';
$companyPosition = $value['职'] ?? $value['company_position'] ?? '';
// 通过姓名、公司名称、职位匹配用户
$matchedUser = null;
@ -839,18 +863,17 @@ class UserController extends BaseController
];
}
// 构建返回数据(使用手机号作为唯一标识)
// 构建返回数据(使用ID作为唯一标识)
$list[$key] = [
'name' => $name,
'company_name' => $companyName,
'company_position' => $companyPosition,
'matched' => $matchedUser ? true : false,
'mobile' => $matchedUser ? $matchedUser->mobile : null, // 使用手机号作为唯一标识
'id' => $matchedUser ? $matchedUser->id : null, // 使用ID作为唯一标识
'existing_data' => $matchedUser ? [
'id' => $matchedUser->id,
'username' => $matchedUser->username,
'name' => $matchedUser->name,
'mobile' => $matchedUser->mobile,
'company_name' => $matchedUser->company_name,
'company_position' => $matchedUser->company_position,
] : null,
@ -876,6 +899,7 @@ class UserController extends BaseController
// 构建返回结果
$result = [
'headers' => $filteredHeaders, // 表头信息,只包含 Excel 中存在的字段,键为字段名,值为中文注释
'list' => $list,
'matched_count' => count($list) - count($unmatchedUsers),
'unmatched_count' => count($unmatchedUsers),
@ -922,109 +946,80 @@ class UserController extends BaseController
$filteredRecords = $all['data'];
$suc = 0;
$updateCount = 0;
$unmatchedUsers = []; // 记录未匹配到的用户
$failedRecords = []; // 记录导入失败的记录
DB::beginTransaction();
try {
foreach ($filteredRecords as $index => $record) {
// 获取匹配的手机号(如果预览时已匹配到)
$mobile = $record['mobile'] ?? null;
// 如果没有mobile尝试通过姓名、公司、职位再次匹配
if (!$mobile) {
$name = $record['name'] ?? '';
$companyName = $record['company_name'] ?? '';
$companyPosition = $record['company_position'] ?? '';
if (!empty($name) && !empty($companyName) && !empty($companyPosition)) {
$matchedUser = $this->model->where('username', $name)
->where('company_name', $companyName)
->where('company_position', $companyPosition)
->first();
if ($matchedUser) {
$mobile = $matchedUser->mobile;
}
}
}
// 获取匹配的用户ID如果预览时已匹配到
$userId = $record['id'] ?? null;
// 如果仍未匹配到手机号,记录并跳过
if (!$mobile) {
$unmatchedUsers[] = [
// 如果没有ID记录失败并跳过
if (!$userId) {
$failedRecords[] = [
'row' => $index + 1,
'name' => $record['name'] ?? '',
'company_name' => $record['company_name'] ?? '',
'company_position' => $record['company_position'] ?? '',
'reason' => '缺少用户ID'
];
continue;
}
// 去除匹配相关的字段,避免更新到数据库
unset($record['matched'], $record['existing_data']);
unset($record['matched'], $record['existing_data'], $record['id']);
// 去除空值
$record = array_filter($record, function ($value) {
return $value != '';
});
// 通过手机号查找并更新用户
$user = $this->model->where('mobile', $mobile)->first();
if ($user) {
// 设置username如果name字段存在
if (isset($record['name'])) {
$record['username'] = $record['name'];
}
// 所有数据通过追加的形式更新参考importStudy的逻辑
foreach ($record as $k => &$v) {
if (!in_array($k, User::$coverFields)) {
// 追加更新
$tempArray = explode(',', ($user->$k ?? '') . ',' . $v);
$tempArray = array_unique(array_filter($tempArray));
$v = implode(',', $tempArray);
}
}
$user->fill($record);
$user->save();
$updateCount++;
$suc++;
// 通过ID查找并更新用户
$user = $this->model->find($userId);
if (!$user) {
// 用户不存在,记录失败并跳过
$failedRecords[] = [
'row' => $index + 1,
'name' => $record['name'] ?? '',
'company_name' => $record['company_name'] ?? '',
'company_position' => $record['company_position'] ?? '',
'reason' => '用户不存在ID: ' . $userId . ''
];
continue;
}
// 写入报名表(如果有课程信息)
if (isset($record['course_id']) && !empty($record['course_id'])) {
$whereSign = ['course_id' => $record['course_id'], 'user_id' => $user->id];
$dataSign = [
'course_id' => $record['course_id'],
'user_id' => $user->id,
'is_import' => 1,
'status' => $record['status'] ?? 1,
'fee_status' => $record['fee_status'] ?? 0
];
$courseSign = CourseSign::updateOrCreate($whereSign, $dataSign);
// 加导入次数,加预约次数
if ($courseSign->status == 1) {
CourseAppointmentTotal::add($courseSign->user_id, $courseSign->id);
}
}
// 设置username如果name字段存在
if (isset($record['name'])) {
$record['username'] = $record['name'];
}
}
// 如果有未匹配到的用户,返回错误
if (count($unmatchedUsers) > 0) {
DB::rollBack();
$unmatchedNames = array_map(function ($user) {
return "第{$user['row']}行:{$user['name']}{$user['company_name']} - {$user['company_position']}";
}, $unmatchedUsers);
return $this->fail([
ResponseCode::ERROR_BUSINESS,
'以下用户未匹配到,无法更新:' . implode('', $unmatchedNames)
]);
// 直接覆盖更新
$user->fill($record);
$user->save();
$updateCount++;
$suc++;
}
DB::commit();
return $this->success([
// 构建返回结果
$result = [
'total' => count($filteredRecords),
'suc' => $suc,
'update_count' => $updateCount
]);
'update_count' => $updateCount,
'failed_count' => count($failedRecords),
'failed_records' => $failedRecords
];
// 如果有失败的记录,添加提示信息
if (count($failedRecords) > 0) {
$failedNames = array_map(function ($record) {
return "第{$record['row']}行:{$record['name']}{$record['company_name']} - {$record['company_position']}- {$record['reason']}";
}, $failedRecords);
$result['message'] = '以下记录导入失败:' . implode('', $failedNames);
}
return $this->success($result);
} catch (\Exception $exception) {
DB::rollBack();
return $this->fail([$exception->getCode(), $exception->getMessage()]);

@ -83,7 +83,6 @@ class User extends Authenticatable implements Auditable
public static $coverFields = [
'name',
'sex',
'mobile',
'company_has_share',
'company_name',
'school',

@ -0,0 +1,51 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('users', function (Blueprint $table) {
// 修改 from 字段注释为 '学员标签'
$table->string('from')->nullable()->comment('学员标签')->change();
// 修改 talent_tags 字段注释为 '人才标签'
$table->string('talent_tags')->nullable()->comment('人才标签')->change();
// 修改 company_area 字段注释为 '公司所属区域'
$table->string('company_area')->nullable()->comment('公司所属区域')->change();
// 修改 type 字段注释为 '个人荣誉'
$table->string('type')->nullable()->comment('个人荣誉')->change();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('users', function (Blueprint $table) {
// 回滚 from 字段注释
$table->string('from')->nullable()->comment('来源')->change();
// 回滚 talent_tags 字段注释
$table->string('talent_tags')->nullable()->comment('人才标签,多个值用英文逗号分隔')->change();
// 回滚 company_area 字段注释
$table->string('company_area')->nullable()->comment('公司区域')->change();
// 回滚 type 字段注释
$table->string('type')->nullable()->comment('人才类型')->change();
});
}
};
Loading…
Cancel
Save