diff --git a/admin/src/app/views/setting/system.vue b/admin/src/app/views/setting/system.vue index f0d4ccc3..3fe6659d 100644 --- a/admin/src/app/views/setting/system.vue +++ b/admin/src/app/views/setting/system.vue @@ -117,6 +117,30 @@ clearable /> + + +

单位:元,设置赠品可以减免的现金金额

+
+ + +

单位:节,设置赠品可以赠送的课程节数

+
@@ -166,6 +190,8 @@ const formData = reactive>({ enterprise_wechat: '', tel: '', auto_distribution_time: '', + gift_cash_amount: '', + gift_course_quantity: '', }) const setFormData = async () => { diff --git a/niucloud/app/adminapi/controller/sys/Config.php b/niucloud/app/adminapi/controller/sys/Config.php index 406a5280..e4c6574e 100644 --- a/niucloud/app/adminapi/controller/sys/Config.php +++ b/niucloud/app/adminapi/controller/sys/Config.php @@ -51,6 +51,8 @@ class Config extends BaseAdminController [ "front_end_icon", "" ], [ "icon", "" ], [ "auto_distribution_time", "" ], + [ "gift_cash_amount", "" ], // 赠品减现金额 + [ "gift_course_quantity", "" ], // 赠品赠课数量 ]); (new ConfigService())->setWebSite($data); diff --git a/niucloud/app/service/admin/campus/CampusService.php b/niucloud/app/service/admin/campus/CampusService.php index 58f15842..b5403d52 100644 --- a/niucloud/app/service/admin/campus/CampusService.php +++ b/niucloud/app/service/admin/campus/CampusService.php @@ -124,7 +124,7 @@ class CampusService extends BaseAdminService // 更新校区签章 $this->model->where([['id', '=', $campus_id]])->update([ 'seal_image' => $seal_image, - 'update_time' => time() + 'update_time' => date('Y-m-d H:i:s') ]); return true; diff --git a/niucloud/app/service/admin/sys/ConfigService.php b/niucloud/app/service/admin/sys/ConfigService.php index f48f0a2f..428eb91e 100644 --- a/niucloud/app/service/admin/sys/ConfigService.php +++ b/niucloud/app/service/admin/sys/ConfigService.php @@ -88,6 +88,8 @@ class ConfigService extends BaseAdminService 'front_end_logo' => '', 'front_end_icon' => '', 'icon' => '', + 'gift_cash_amount' => '', // 赠品减现金额 + 'gift_course_quantity' => '', // 赠品赠课数量 ]; } return $info[ 'value' ]; diff --git a/niucloud/app/service/api/apiService/OrderTableService.php b/niucloud/app/service/api/apiService/OrderTableService.php index 6cab81d1..7361c6b7 100644 --- a/niucloud/app/service/api/apiService/OrderTableService.php +++ b/niucloud/app/service/api/apiService/OrderTableService.php @@ -457,19 +457,47 @@ class OrderTableService extends BaseApiService $insert_data = []; $now = date('Y-m-d H:i:s'); - // 为每个占位符配置创建数据源记录,关联到具体的签署记录 - foreach ($placeholder_config as $config) { + // 获取学员信息,用于数据库字段值处理 + $student_info = $this->getStudentInfoForContract($orderData['student_id']); + if (!$student_info) { + \think\facade\Log::warning('获取学员信息失败', ['student_id' => $orderData['student_id']]); + return false; + } + + \think\facade\Log::info('开始处理占位符配置', [ + 'contract_id' => $contract_id, + 'config_structure' => array_keys($placeholder_config), + 'config_count' => count($placeholder_config) + ]); + + // 处理JSON对象格式的占位符配置:{"占位符名": {配置}} + foreach ($placeholder_config as $placeholder_name => $config) { + // 确保$config是数组 + if (!is_array($config)) { + \think\facade\Log::warning('跳过无效配置项', [ + 'placeholder' => $placeholder_name, + 'config' => $config + ]); + continue; + } + + // 处理实际值:根据数据类型获取对应的值 + $processed_value = $this->getProcessedFieldValue($config, $student_info, $orderData); + + // 获取占位符的显示名称,如果配置中有label则使用label,否则使用键名 + $placeholder_display_name = $config['label'] ?? $config['placeholder'] ?? $placeholder_name; + $data_source_record = [ 'contract_id' => $contract_id, - 'contract_sign_id' => $contract_sign_id, // 新增:关联到具体的签署记录 - 'placeholder' => $config['placeholder'] ?? '', + 'contract_sign_id' => $contract_sign_id, // 关联到具体的签署记录 + 'placeholder' => $placeholder_display_name, // 使用配置的显示名称或键名 'data_type' => $config['data_type'] ?? 'user_input', 'system_function' => $config['system_function'] ?? '', 'table_name' => $config['table_name'] ?? '', 'field_name' => $config['field_name'] ?? '', 'field_type' => $config['field_type'] ?? 'text', 'is_required' => $config['is_required'] ?? 0, - 'default_value' => $config['default_value'] ?? '', + 'default_value' => $processed_value, // 使用处理过的实际值 'sign_party' => $config['sign_party'] ?? '', 'validation_rule' => $config['validation_rule'] ?? '', 'created_at' => $now, @@ -477,6 +505,13 @@ class OrderTableService extends BaseApiService ]; $insert_data[] = $data_source_record; + + \think\facade\Log::info('处理占位符字段', [ + 'placeholder_key' => $placeholder_name, + 'placeholder_display' => $placeholder_display_name, + 'data_type' => $config['data_type'] ?? 'user_input', + 'processed_value' => $processed_value + ]); } if (!empty($insert_data)) { @@ -507,6 +542,223 @@ class OrderTableService extends BaseApiService } } + /** + * 获取学员信息用于合同处理 + * @param int $student_id 学员ID + * @return array|null + */ + private function getStudentInfoForContract($student_id) + { + try { + $student = Db::table('school_student') + ->where('id', $student_id) + ->where('status', 1) + ->field([ + 'id', 'name', 'gender', 'age', 'birthday', + 'emergency_contact', 'contact_phone', 'member_label', + 'user_id', 'campus_id', 'created_at' + ]) + ->find(); + + return $student ? $student : null; + + } catch (\Exception $e) { + \think\facade\Log::error('获取学员信息失败', [ + 'student_id' => $student_id, + 'error' => $e->getMessage() + ]); + return null; + } + } + + /** + * 获取处理过的字段值 + * 根据字段的数据类型获取相应的值 + * @param array $config 字段配置 + * @param array $student_info 学员信息 + * @param array $order_data 订单数据 + * @return string + */ + private function getProcessedFieldValue($config, $student_info, $order_data) + { + try { + $data_type = $config['data_type'] ?? 'user_input'; + + switch ($data_type) { + case 'database': + // 数据库类型:从相关表获取数据 + return $this->getDatabaseFieldValueForConfig($config, $student_info, $order_data); + + case 'system': + // 系统函数类型:调用系统函数获取值 + return $this->getSystemFunctionValueForConfig($config); + + case 'user_input': + // 用户输入类型:使用配置的默认值 + return $config['default_value'] ?? ''; + + case 'signature': + case 'sign_img': + // 签名类型:无默认值,需要用户操作 + return ''; + + default: + return $config['default_value'] ?? ''; + } + + } catch (\Exception $e) { + \think\facade\Log::error('获取处理字段值失败', [ + 'config' => $config, + 'error' => $e->getMessage() + ]); + return ''; + } + } + + /** + * 从数据库获取字段值 + * @param array $config 字段配置 + * @param array $student_info 学员信息 + * @param array $order_data 订单数据 + * @return string + */ + private function getDatabaseFieldValueForConfig($config, $student_info, $order_data) + { + try { + $table_name = $config['table_name'] ?? ''; + $field_name = $config['field_name'] ?? ''; + + if (empty($table_name) || empty($field_name)) { + return ''; + } + + $value = ''; + + switch ($table_name) { + case 'school_student': + // 学员表:直接从学员信息获取 + $value = $student_info[$field_name] ?? ''; + break; + + case 'school_customer_resources': + // 用户表:通过学员的user_id关联查询 + if (!empty($student_info['user_id'])) { + $value = Db::table('school_customer_resources') + ->where('id', $student_info['user_id']) + ->value($field_name) ?? ''; + } + break; + + case 'school_order_table': + // 订单表:使用当前订单数据 + $value = $order_data[$field_name] ?? ''; + break; + + default: + \think\facade\Log::warning('不支持的数据库表', [ + 'table_name' => $table_name, + 'field_name' => $field_name + ]); + break; + } + + // 对特殊字段进行格式化处理 + $value = $this->formatFieldValueForContract($field_name, $value); + + return (string)$value; + + } catch (\Exception $e) { + \think\facade\Log::error('获取数据库字段值失败', [ + 'config' => $config, + 'error' => $e->getMessage() + ]); + return ''; + } + } + + /** + * 获取系统函数值 + * @param array $config 字段配置 + * @return string + */ + private function getSystemFunctionValueForConfig($config) + { + try { + $system_function = $config['system_function'] ?? ''; + + if (empty($system_function)) { + return ''; + } + + // 预定义的系统函数 + switch ($system_function) { + case 'current_date': + return date('Y-m-d'); + case 'current_time': + return date('H:i:s'); + case 'current_datetime': + return date('Y-m-d H:i:s'); + case 'current_year': + return date('Y'); + case 'current_month': + return date('m'); + case 'current_day': + return date('d'); + default: + \think\facade\Log::warning('未知的系统函数', [ + 'function_name' => $system_function + ]); + return ''; + } + + } catch (\Exception $e) { + \think\facade\Log::error('获取系统函数值失败', [ + 'config' => $config, + 'error' => $e->getMessage() + ]); + return ''; + } + } + + /** + * 格式化字段值 + * @param string $field_name 字段名 + * @param mixed $value 原始值 + * @return string + */ + private function formatFieldValueForContract($field_name, $value) + { + if (empty($value)) { + return ''; + } + + // 根据字段名进行特殊处理 + switch (true) { + case str_contains($field_name, 'date') || str_contains($field_name, 'time'): + // 日期时间字段格式化 + if (is_numeric($value)) { + return date('Y-m-d', $value); + } elseif (strtotime($value)) { + return date('Y-m-d', strtotime($value)); + } + break; + + case str_contains($field_name, 'amount') || str_contains($field_name, 'price'): + // 金额字段格式化 + return number_format((float)$value, 2); + + case str_contains($field_name, 'phone'): + // 手机号格式化 + return (string)$value; + + default: + // 默认返回字符串 + return (string)$value; + } + + return (string)$value; + } + /** * 支付成功后创建支付记录 * @param array $orderData 订单数据 diff --git a/uniapp/pages-common/contract/contract_sign.vue b/uniapp/pages-common/contract/contract_sign.vue index ad405d2a..d4106bff 100644 --- a/uniapp/pages-common/contract/contract_sign.vue +++ b/uniapp/pages-common/contract/contract_sign.vue @@ -498,7 +498,7 @@ export default { }, // 返回签名数据给表单页面 - returnSignatureData() { + async returnSignatureData() { if (!this.signatureImageUrl) { uni.showToast({ title: '签名生成失败,请重试', @@ -507,31 +507,51 @@ export default { return } - // 获取前一个页面的实例 - const pages = getCurrentPages() - const prevPage = pages[pages.length - 2] + this.submitting = true - if (prevPage) { - // 将签名数据传递给前一个页面 - if (!prevPage.data) { - prevPage.data = {} + try { + // 先上传签名图片到服务器 + const uploadResult = await this.uploadSignatureFile() + + if (!uploadResult.success) { + throw new Error(uploadResult.message || '上传签名文件失败') } - prevPage.data.newSignature = { - fieldPlaceholder: this.fieldPlaceholder, - signatureData: this.signatureImageUrl + // 获取前一个页面的实例 + const pages = getCurrentPages() + const prevPage = pages[pages.length - 2] + + if (prevPage) { + // 将签名数据传递给前一个页面,使用服务器返回的URL + if (!prevPage.data) { + prevPage.data = {} + } + + prevPage.data.newSignature = { + fieldPlaceholder: this.fieldPlaceholder, + signatureData: uploadResult.url // 使用服务器URL而不是临时文件路径 + } } + + uni.showToast({ + title: '签名完成', + icon: 'success', + duration: 1500 + }) + + setTimeout(() => { + uni.navigateBack() + }, 1500) + + } catch (error) { + console.error('上传签名失败:', error) + uni.showToast({ + title: error.message || '上传签名失败,请重试', + icon: 'none' + }) + } finally { + this.submitting = false } - - uni.showToast({ - title: '签名完成', - icon: 'success', - duration: 1500 - }) - - setTimeout(() => { - uni.navigateBack() - }, 1500) }, // 上传签名文件 diff --git a/uniapp/pages-student/contracts/sign.vue b/uniapp/pages-student/contracts/sign.vue index 14beb9af..f5045954 100644 --- a/uniapp/pages-student/contracts/sign.vue +++ b/uniapp/pages-student/contracts/sign.vue @@ -427,7 +427,7 @@ uni.uploadFile({ url: Api_url + '/file/image', filePath: tempFilePath, - name: 'image', + name: 'file', header: { 'Authorization': uni.getStorageSync('token') || '' },