Browse Source

修改 bug

master
王泽彦 7 months ago
parent
commit
6fd7887a1d
  1. 44
      niucloud/app/service/api/apiService/ContractSignFormService.php
  2. 266
      niucloud/app/service/api/student/ContractService.php
  3. 823
      niucloud/app/service/core/sys/CoreFieldMappingService.php
  4. 15
      uniapp/api/apiRoute.js
  5. 4
      uniapp/common/config.js
  6. 30
      uniapp/pages-student/contracts/sign.vue

44
niucloud/app/service/api/apiService/ContractSignFormService.php

@ -11,6 +11,8 @@
namespace app\service\api\apiService;
use app\model\order_table\OrderTable;
use app\service\core\sys\CoreFieldMappingService;
use core\base\BaseApiService;
use think\facade\Db;
use think\facade\Log;
@ -653,7 +655,7 @@ class ContractSignFormService extends BaseApiService
'data_type' => $config['data_type'] ?? 'user_input',
'field_type' => $config['field_type'] ?? 'text',
'is_required' => (int)($config['is_required'] ?? 0),
'default_value' => '',
'default_value' => $config['default_value'],
'validation_rule' => $config['validation_rule'] ?? '',
'sign_party' => $config['sign_party'] ?? '',
];
@ -678,13 +680,13 @@ class ContractSignFormService extends BaseApiService
case 'signature':
// 电子签名类型:无默认值,需要用户手写签名
$field['signature_type'] = 'handwrite';
$field['default_value'] = '';
$field['default_value'] = $config['default_value'] ?? '';
break;
case 'sign_img':
// 签名图片类型:无默认值,需要用户上传或选择
$field['sign_image_source'] = 'upload';
$field['default_value'] = '';
$field['default_value'] = $config['default_value'] ?? '';
break;
default:
@ -733,20 +735,22 @@ class ContractSignFormService extends BaseApiService
switch ($table_name) {
case 'school_student':
// 学员表:直接从学员信息获取
$value = $student[$field_name] ?? '';
$service = new CoreFieldMappingService($config['table_name'], ['id'=>$student['id']]);
$value = $service->getValue($field_name);
break;
case 'school_customer_resources':
// 用户表:通过学员的user_id关联查询
if (!empty($student['user_id'])) {
$value = Db::table('school_customer_resources')
->where('id', $student['user_id'])
->value($field_name) ?? '';
$service = new CoreFieldMappingService($config['table_name'], ['id'=>$student['user_id']]);
$value = $service->getValue($field_name);
}
break;
case 'school_order_table':
// 订单表:查询该学员最新的订单信息
$order = OrderTable::where('contract_sign_id',$config['contract_sign_id'])->find();
$value = Db::table('school_order_table')
->where('student_id', $student['id'])
->order('created_at', 'desc')
@ -866,16 +870,6 @@ class ContractSignFormService extends BaseApiService
throw new \Exception('合同签署记录不存在');
}
// 验证员工是否存在
$personnel = Db::table('school_personnel')
->where('id', $personnel_id)
->where('status', 1)
->find();
if (!$personnel) {
throw new \Exception('员工信息不存在');
}
// 事务处理
Db::startTrans();
try {
@ -1057,8 +1051,7 @@ class ContractSignFormService extends BaseApiService
->where('id', $existing_config['id'])
->update([
'default_value' => (string)$value,
'updated_at' => $now,
'updated_by' => $user_type
'updated_at' => $now
]);
if ($update_result) {
@ -1222,22 +1215,11 @@ class ContractSignFormService extends BaseApiService
$now = date('Y-m-d H:i:s');
$update_data = [
'sign_status' => 1, // 已签署
'status' => 2, // 已签署
'sign_time' => $now,
'updated_at' => $now
];
// 如果是员工签署,记录员工ID
if ($personnel_id) {
$update_data['personnel_id'] = $personnel_id;
$update_data['signed_by'] = 'staff';
}
// 如果是学员签署,确保学员ID正确
if ($student_id) {
$update_data['signed_by'] = 'student';
}
// 如果有签名图片,保存签名图片路径
if (!empty($signature_image)) {
$update_data['signature_image'] = $signature_image;

266
niucloud/app/service/api/student/ContractService.php

@ -158,6 +158,16 @@ class ContractService extends BaseService
// 合同条款(如果有内容的话)
$contractSign['terms'] = $contractSign['contract_content'] ?: $contractSign['remarks'];
// 对于已签署成功的合同(status=3),进行占位符替换
if ($contractSign['status'] == 3 && !empty($contractSign['terms'])) {
$contractSign['terms'] = $this->replacePlaceholdersInTerms(
$contractSign['terms'],
$contractId,
$contractSign['sign_id'],
$studentId
);
}
return $contractSign;
}
@ -867,4 +877,260 @@ class ContractService extends BaseService
return $formData;
}
/**
* 在合同条款中替换占位符
* 使用 school_document_data_source_config 表中的 default_value 数据进行替换
*
* @param string $terms 合同条款内容
* @param int $contractId 合同模板ID
* @param int $contractSignId 合同签署记录ID
* @param int $studentId 学员ID
* @return string 替换后的合同条款
*/
private function replacePlaceholdersInTerms($terms, $contractId, $contractSignId, $studentId)
{
try {
if (empty($terms)) {
return $terms;
}
// 获取该合同的所有占位符配置
$configs = Db::table('school_document_data_source_config')
->where('contract_id', $contractId)
->where(function($query) use ($contractSignId) {
$query->where('contract_sign_id', $contractSignId)
->whereOr('contract_sign_id', 'IS', null);
})
->field('placeholder, data_type, default_value, table_name, field_name, system_function')
->select()
->toArray();
if (empty($configs)) {
return $terms;
}
// 获取学员信息(用于数据库类型查询)
$student = Db::table('school_student')
->where('id', $studentId)
->find();
// 遍历配置,逐个替换占位符
foreach ($configs as $config) {
$placeholder = $config['placeholder'];
$value = '';
// 优先使用 default_value
if (!empty($config['default_value'])) {
$value = $config['default_value'];
} else {
// 根据数据类型获取值
switch ($config['data_type']) {
case 'database':
$value = $this->getDatabaseFieldValueFromConfig($config, $student ?: []);
break;
case 'system':
$value = $this->getSystemFunctionValueFromConfig($config);
break;
case 'user_input':
default:
$value = $config['default_value'] ?: '';
break;
}
}
// 替换占位符(支持 {{placeholder}} 和 {placeholder} 格式)
$patterns = [
'{{' . $placeholder . '}}',
'{' . $placeholder . '}'
];
foreach ($patterns as $pattern) {
$terms = str_replace($pattern, $value, $terms);
}
}
return $terms;
} catch (\Exception $e) {
// 出现错误时返回原内容,记录日志
\think\facade\Log::error('合同条款占位符替换失败', [
'contract_id' => $contractId,
'contract_sign_id' => $contractSignId,
'student_id' => $studentId,
'error' => $e->getMessage()
]);
return $terms;
}
}
/**
* 从配置中获取数据库字段值
* @param array $config 字段配置
* @param array $student 学员信息
* @return string
*/
private function getDatabaseFieldValueFromConfig($config, $student)
{
try {
$tableName = $config['table_name'] ?? '';
$fieldName = $config['field_name'] ?? '';
if (empty($tableName) || empty($fieldName)) {
return '';
}
$value = '';
switch ($tableName) {
case 'school_student':
case 'students':
// 学员表:直接从学员信息获取
$value = $student[$fieldName] ?? '';
break;
case 'school_customer_resources':
// 用户表:通过学员的user_id关联查询
if (!empty($student['user_id'])) {
$value = Db::table('school_customer_resources')
->where('id', $student['user_id'])
->value($fieldName) ?: '';
}
break;
case 'school_order_table':
// 订单表:查询该学员最新的订单信息
$value = Db::table('school_order_table')
->where('student_id', $student['id'])
->order('created_at', 'desc')
->value($fieldName) ?: '';
break;
case 'school_personnel':
// 员工表:这里可能需要根据业务逻辑确定关联的员工
$value = '';
break;
default:
\think\facade\Log::warning('不支持的数据库表', [
'table_name' => $tableName,
'field_name' => $fieldName
]);
break;
}
// 格式化字段值
$value = $this->formatFieldValue($fieldName, $value);
return (string)$value;
} catch (\Exception $e) {
\think\facade\Log::error('从配置获取数据库字段值失败', [
'config' => $config,
'student_id' => $student['id'] ?? 0,
'error' => $e->getMessage()
]);
return '';
}
}
/**
* 从配置中获取系统函数值
* @param array $config 字段配置
* @return string
*/
private function getSystemFunctionValueFromConfig($config)
{
try {
$systemFunction = $config['system_function'] ?? '';
if (empty($systemFunction)) {
return '';
}
$value = '';
switch ($systemFunction) {
case 'current_date':
$value = date('Y-m-d');
break;
case 'current_time':
$value = date('H:i:s');
break;
case 'current_datetime':
$value = date('Y-m-d H:i:s');
break;
case 'current_year':
$value = date('Y');
break;
case 'current_month':
$value = date('m');
break;
case 'current_day':
$value = date('d');
break;
case 'random_number':
$value = mt_rand(100000, 999999);
break;
case 'contract_generate_time':
$value = date('Y-m-d H:i:s');
break;
default:
\think\facade\Log::warning('不支持的系统函数', [
'system_function' => $systemFunction
]);
break;
}
return (string)$value;
} catch (\Exception $e) {
\think\facade\Log::error('从配置获取系统函数值失败', [
'config' => $config,
'error' => $e->getMessage()
]);
return '';
}
}
/**
* 格式化字段值
* 对特定类型的字段值进行格式化处理
*
* @param string $fieldName 字段名
* @param mixed $value 原始值
* @return string 格式化后的值
*/
private function formatFieldValue($fieldName, $value)
{
if (empty($value)) {
return '';
}
// 根据字段名进行特殊处理
switch (true) {
case str_contains($fieldName, 'date') || str_contains($fieldName, '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($fieldName, 'amount') || str_contains($fieldName, 'price'):
// 金额字段格式化
return number_format((float)$value, 2);
case str_contains($fieldName, 'phone'):
// 手机号格式化(可以添加脱敏处理)
return (string)$value;
default:
// 默认返回字符串
return (string)$value;
}
return (string)$value;
}
}

823
niucloud/app/service/core/sys/CoreFieldMappingService.php

@ -0,0 +1,823 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\service\core\sys;
use core\base\BaseCoreService;
use think\facade\Cache;
use think\facade\Db;
use think\Model;
use Exception;
/**
* 字段值包装类,支持链式调用
* Class FieldValue
*/
class FieldValue
{
/**
* 原始值
* @var mixed
*/
protected $value;
/**
* 字段映射服务实例
* @var CoreFieldMappingService
*/
protected $service;
/**
* 字段名
* @var string
*/
protected $field_name;
/**
* 构造函数
* @param mixed $value 原始值
* @param CoreFieldMappingService $service 服务实例
* @param string $field_name 字段名
*/
public function __construct($value, CoreFieldMappingService $service, string $field_name)
{
$this->value = $value;
$this->service = $service;
$this->field_name = $field_name;
}
/**
* 获取原始值
* @return mixed
*/
public function getValue()
{
return $this->value;
}
/**
* 链式调用关系查询
* @param string $relation_table 关系表名
* @param string $display_field 显示字段
* @param string $key_field 关键字段,默认为id
* @param array $conditions 额外查询条件
* @param bool $use_cache 是否使用缓存
* @return mixed
*/
public function withRelation(string $relation_table, string $display_field, string $key_field = 'id', array $conditions = [], bool $use_cache = true)
{
if ($this->value === null) {
return $this->value;
}
try {
// 生成缓存键
$cache_key = "relation_chain_{$this->field_name}_" . md5(serialize([
'value' => $this->value,
'table' => $relation_table,
'display_field' => $display_field,
'key_field' => $key_field,
'conditions' => $conditions
]));
if ($use_cache) {
$cached_value = Cache::get($cache_key);
if ($cached_value !== false && $cached_value !== null) {
return $cached_value;
}
}
// 构建查询
$query = Db::table($relation_table)
->where($key_field, $this->value)
->field($display_field);
// 添加额外条件
if (!empty($conditions)) {
$query->where($conditions);
}
$result = $query->find();
$converted_value = $result ? $result[$display_field] : $this->value;
// 缓存结果
if ($use_cache) {
Cache::tag(CoreFieldMappingService::$cache_tag_name)->set($cache_key, $converted_value, 3600);
}
return $converted_value;
} catch (Exception $e) {
trace($e->getMessage(), 'error');
return $this->value;
}
}
/**
* 转换为字符串时返回原始值
* @return string
*/
public function __toString()
{
return (string)$this->value;
}
/**
* 支持直接访问值的魔术方法
* @param string $name
* @return mixed
*/
public function __get(string $name)
{
if ($name === 'value') {
return $this->value;
}
return null;
}
}
/**
* 数据库字段映射服务层
*
* 支持字段映射、枚举值自动转义、关系查询链式调用等功能
*
* 使用示例:
*
* 1. 基本用法:
* ```php
* $mapping = new CoreFieldMappingService('users', ['id' => 1]);
* $name = $mapping->getValue('name'); // 获取用户名
* ```
*
* 2. 枚举值自动转义:
* ```php
* $mapping = new CoreFieldMappingService('users', ['id' => 1]);
* $mapping->setFieldEnum('status', [1 => '启用', 0 => '禁用']);
* $status = $mapping->getValue('status'); // 直接返回 '启用' 或 '禁用'
* ```
*
* 3. 关系查询链式调用:
* ```php
* $mapping = new CoreFieldMappingService('orders', ['id' => 1]);
* $username = $mapping->getValueWithChain('user_id')
* ->withRelation('users', 'username'); // 获取用户名
* ```
*
* 4. 批量设置枚举和关系:
* ```php
* $mapping = new CoreFieldMappingService('orders');
* $mapping->setFieldEnums([
* 'status' => [1 => '已付款', 2 => '已发货', 3 => '已完成'],
* 'type' => [1 => '普通订单', 2 => '预售订单']
* ]);
* $mapping->setFieldRelation('user_id', 'users', 'username');
* ```
*
* Class CoreFieldMappingService
* @package app\service\core\sys
*/
class CoreFieldMappingService extends BaseCoreService
{
/**
* 缓存标签名
* @var string
*/
public static $cache_tag_name = 'field_mapping';
/**
* 表名
* @var string
*/
protected $table_name;
/**
* 查询条件
* @var array
*/
protected $conditions;
/**
* 字段映射配置
* @var array
*/
protected $field_mapping;
/**
* 枚举映射配置
* @var array
*/
protected $enum_mapping;
/**
* 关系映射配置
* @var array
*/
protected $relation_mapping;
/**
* 构造函数
* @param string $table_name 表名
* @param array $conditions 查询条件
* @param array $field_mapping 字段映射配置
* @param array $enum_mapping 枚举映射配置
* @param array $relation_mapping 关系映射配置
*/
public function __construct(string $table_name, array $conditions = [], array $field_mapping = [], array $enum_mapping = [], array $relation_mapping = [])
{
parent::__construct();
$this->table_name = $table_name;
$this->conditions = $conditions;
$this->field_mapping = $field_mapping;
$this->enum_mapping = $enum_mapping;
$this->relation_mapping = $relation_mapping;
}
/**
* 获取字段映射关系
* @return array
*/
public function getFieldMapping(): array
{
return $this->field_mapping;
}
/**
* 设置字段映射关系
* @param array $field_mapping
* @return $this
*/
public function setFieldMapping(array $field_mapping): self
{
$this->field_mapping = $field_mapping;
return $this;
}
/**
* 设置查询条件
* @param array $conditions
* @return $this
*/
public function setConditions(array $conditions): self
{
$this->conditions = $conditions;
return $this;
}
/**
* 获取查询条件
* @return array
*/
public function getConditions(): array
{
return $this->conditions;
}
/**
* 从查询结果中获取指定字段的值
* @param string $field_name 字段名
* @param mixed $default_value 默认值
* @param bool $use_cache 是否使用缓存
* @param bool $auto_convert_enum 是否自动转义枚举值,默认true
* @param bool $return_wrapper 是否返回FieldValue包装对象以支持链式调用,默认false
* @return mixed|FieldValue
*/
public function getValue(string $field_name, $default_value = null, bool $use_cache = true, bool $auto_convert_enum = true, bool $return_wrapper = false)
{
try {
// 生成缓存键
$cache_key = $this->generateCacheKey($field_name);
if ($use_cache) {
// 尝试从缓存获取
$cached_value = Cache::get($cache_key);
if ($cached_value !== false && $cached_value !== null) {
return $cached_value;
}
}
// 检查字段映射
$actual_field = $this->getActualFieldName($field_name);
// 构建查询
$query = Db::table($this->table_name);
// 添加查询条件
if (!empty($this->conditions)) {
$query->where($this->conditions);
}
// 执行查询
$result = $query->field($actual_field)->find();
if (empty($result)) {
return $default_value;
}
$value = $result[$actual_field] ?? $default_value;
// 自动转义枚举值
if ($auto_convert_enum && $value !== null && $value !== $default_value && isset($this->enum_mapping[$field_name])) {
$enum_config = $this->enum_mapping[$field_name];
$value = $enum_config[$value] ?? $value;
}
// 缓存结果
if ($use_cache && $value !== null) {
Cache::tag(self::$cache_tag_name)->set($cache_key, $value, 3600); // 缓存1小时
}
// 返回包装对象或原始值
if ($return_wrapper) {
return new FieldValue($value, $this, $field_name);
}
return $value;
} catch (Exception $e) {
// 记录错误日志
trace($e->getMessage(), 'error');
return $default_value;
}
}
/**
* 获取字段值并返回支持链式调用的包装对象
* @param string $field_name 字段名
* @param mixed $default_value 默认值
* @param bool $use_cache 是否使用缓存
* @param bool $auto_convert_enum 是否自动转义枚举值,默认true
* @return FieldValue
*/
public function getValueWithChain(string $field_name, $default_value = null, bool $use_cache = true, bool $auto_convert_enum = true): FieldValue
{
return $this->getValue($field_name, $default_value, $use_cache, $auto_convert_enum, true);
}
/**
* 批量获取多个字段的值
* @param array $field_names 字段名数组
* @param bool $use_cache 是否使用缓存
* @return array
*/
public function getValues(array $field_names, bool $use_cache = true): array
{
try {
$result = [];
// 生成缓存键
$cache_key = $this->generateCacheKey(implode(',', $field_names));
if ($use_cache) {
// 尝试从缓存获取
$cached_result = Cache::get($cache_key);
if ($cached_result !== false && $cached_result !== null) {
return $cached_result;
}
}
// 获取实际字段名
$actual_fields = [];
foreach ($field_names as $field_name) {
$actual_fields[] = $this->getActualFieldName($field_name);
}
// 构建查询
$query = Db::table($this->table_name);
// 添加查询条件
if (!empty($this->conditions)) {
$query->where($this->conditions);
}
// 执行查询
$data = $query->field(implode(',', $actual_fields))->find();
if (!empty($data)) {
// 映射回原始字段名
foreach ($field_names as $index => $field_name) {
$actual_field = $actual_fields[$index];
$result[$field_name] = $data[$actual_field] ?? null;
}
}
// 缓存结果
if ($use_cache && !empty($result)) {
Cache::tag(self::$cache_tag_name)->set($cache_key, $result, 3600); // 缓存1小时
}
return $result;
} catch (Exception $e) {
// 记录错误日志
trace($e->getMessage(), 'error');
return [];
}
}
/**
* 获取实际字段名(考虑字段映射)
* @param string $field_name
* @return string
*/
protected function getActualFieldName(string $field_name): string
{
return $this->field_mapping[$field_name] ?? $field_name;
}
/**
* 生成缓存键
* @param string $field_name
* @return string
*/
protected function generateCacheKey(string $field_name): string
{
$conditions_hash = md5(serialize($this->conditions));
return "field_mapping_{$this->table_name}_{$field_name}_{$conditions_hash}";
}
/**
* 清除缓存
* @param string|null $field_name 指定字段名,为空则清除所有相关缓存
* @return bool
*/
public function clearCache(string $field_name = null): bool
{
if ($field_name) {
$cache_key = $this->generateCacheKey($field_name);
return Cache::delete($cache_key);
} else {
return Cache::tag(self::$cache_tag_name)->clear();
}
}
/**
* 检查表是否存在
* @return bool
*/
public function tableExists(): bool
{
try {
$tables = Db::query("SHOW TABLES LIKE '{$this->table_name}'");
return !empty($tables);
} catch (Exception $e) {
trace($e->getMessage(), 'error');
return false;
}
}
/**
* 获取表的字段信息
* @return array
*/
public function getTableFields(): array
{
try {
$cache_key = "table_fields_{$this->table_name}";
// 尝试从缓存获取
$cached_fields = Cache::get($cache_key);
if ($cached_fields !== false && $cached_fields !== null) {
return $cached_fields;
}
$fields = Db::query("DESCRIBE {$this->table_name}");
// 缓存字段信息
Cache::tag(self::$cache_tag_name)->set($cache_key, $fields, 7200); // 缓存2小时
return $fields;
} catch (Exception $e) {
trace($e->getMessage(), 'error');
return [];
}
}
/**
* 验证字段是否存在
* @param string $field_name
* @return bool
*/
public function fieldExists(string $field_name): bool
{
$fields = $this->getTableFields();
$actual_field = $this->getActualFieldName($field_name);
foreach ($fields as $field) {
if ($field['Field'] === $actual_field) {
return true;
}
}
return false;
}
/**
* 设置枚举映射配置
* @param array $enum_mapping
* @return $this
*/
public function setEnumMapping(array $enum_mapping): self
{
$this->enum_mapping = $enum_mapping;
return $this;
}
/**
* 为单个字段设置枚举映射
* @param string $field_name 字段名
* @param array $enum_values 枚举值映射
* @return $this
*/
public function setFieldEnum(string $field_name, array $enum_values): self
{
$this->enum_mapping[$field_name] = $enum_values;
return $this;
}
/**
* 批量设置多个字段的枚举映射
* @param array $field_enums 字段枚举映射数组,格式:['field_name' => ['value' => 'label']]
* @return $this
*/
public function setFieldEnums(array $field_enums): self
{
foreach ($field_enums as $field_name => $enum_values) {
$this->enum_mapping[$field_name] = $enum_values;
}
return $this;
}
/**
* 获取枚举映射配置
* @return array
*/
public function getEnumMapping(): array
{
return $this->enum_mapping;
}
/**
* 设置关系映射配置
* @param array $relation_mapping
* @return $this
*/
public function setRelationMapping(array $relation_mapping): self
{
$this->relation_mapping = $relation_mapping;
return $this;
}
/**
* 为单个字段设置关系映射
* @param string $field_name 字段名
* @param string $relation_table 关系表名
* @param string $display_field 显示字段
* @param string $key_field 关键字段,默认为id
* @param array $conditions 额外查询条件
* @return $this
*/
public function setFieldRelation(string $field_name, string $relation_table, string $display_field, string $key_field = 'id', array $conditions = []): self
{
$this->relation_mapping[$field_name] = [
'table' => $relation_table,
'display_field' => $display_field,
'key_field' => $key_field,
'conditions' => $conditions
];
return $this;
}
/**
* 批量设置多个字段的关系映射
* @param array $field_relations 字段关系映射数组
* @return $this
*/
public function setFieldRelations(array $field_relations): self
{
foreach ($field_relations as $field_name => $relation_config) {
if (is_array($relation_config) && isset($relation_config['table']) && isset($relation_config['display_field'])) {
$this->relation_mapping[$field_name] = $relation_config;
}
}
return $this;
}
/**
* 获取关系映射配置
* @return array
*/
public function getRelationMapping(): array
{
return $this->relation_mapping;
}
/**
* 转换枚举值
* @param string $field_name 字段名
* @param mixed $value 原始值
* @param bool $use_cache 是否使用缓存
* @return mixed
*/
public function convertEnumValue(string $field_name, $value, bool $use_cache = true)
{
try {
// 检查是否配置了枚举映射
if (!isset($this->enum_mapping[$field_name])) {
return $value;
}
$enum_config = $this->enum_mapping[$field_name];
// 生成缓存键
$cache_key = "enum_convert_{$field_name}_" . md5(serialize($value));
if ($use_cache) {
$cached_value = Cache::get($cache_key);
if ($cached_value !== false && $cached_value !== null) {
return $cached_value;
}
}
// 执行枚举转换
$converted_value = $enum_config[$value] ?? $value;
// 缓存结果
if ($use_cache) {
Cache::tag(self::$cache_tag_name)->set($cache_key, $converted_value, 3600);
}
return $converted_value;
} catch (Exception $e) {
trace($e->getMessage(), 'error');
return $value;
}
}
/**
* 转换关系ID值
* @param string $field_name 字段名
* @param mixed $value 关系ID值
* @param bool $use_cache 是否使用缓存
* @return mixed
*/
public function convertRelationValue(string $field_name, $value, bool $use_cache = true)
{
try {
// 检查是否配置了关系映射
if (!isset($this->relation_mapping[$field_name])) {
return $value;
}
$relation_config = $this->relation_mapping[$field_name];
// 验证关系配置
if (!isset($relation_config['table']) || !isset($relation_config['display_field'])) {
return $value;
}
// 生成缓存键
$cache_key = "relation_convert_{$field_name}_" . md5(serialize($value));
if ($use_cache) {
$cached_value = Cache::get($cache_key);
if ($cached_value !== false && $cached_value !== null) {
return $cached_value;
}
}
// 构建查询
$relation_table = $relation_config['table'];
$display_field = $relation_config['display_field'];
$key_field = $relation_config['key_field'] ?? 'id';
$query = Db::table($relation_table)
->where($key_field, $value)
->field($display_field);
// 添加额外条件
if (isset($relation_config['conditions']) && is_array($relation_config['conditions'])) {
$query->where($relation_config['conditions']);
}
$result = $query->find();
$converted_value = $result ? $result[$display_field] : $value;
// 缓存结果
if ($use_cache) {
Cache::tag(self::$cache_tag_name)->set($cache_key, $converted_value, 3600);
}
return $converted_value;
} catch (Exception $e) {
trace($e->getMessage(), 'error');
return $value;
}
}
/**
* 批量转换字段值
* @param array $data 原始数据
* @param array $convert_fields 需要转换的字段列表
* @param bool $use_cache 是否使用缓存
* @return array
*/
public function convertValues(array $data, array $convert_fields = [], bool $use_cache = true): array
{
try {
if (empty($data)) {
return $data;
}
$converted_data = $data;
// 如果未指定转换字段,则根据配置自动确定
if (empty($convert_fields)) {
$convert_fields = array_merge(
array_keys($this->enum_mapping),
array_keys($this->relation_mapping)
);
}
foreach ($convert_fields as $field_name) {
if (!isset($data[$field_name])) {
continue;
}
$original_value = $data[$field_name];
// 枚举转换
if (isset($this->enum_mapping[$field_name])) {
$converted_data[$field_name] = $this->convertEnumValue($field_name, $original_value, $use_cache);
}
// 关系转换
elseif (isset($this->relation_mapping[$field_name])) {
$converted_data[$field_name] = $this->convertRelationValue($field_name, $original_value, $use_cache);
}
}
return $converted_data;
} catch (Exception $e) {
trace($e->getMessage(), 'error');
return $data;
}
}
/**
* 获取带转义的字段值
* @param string $field_name 字段名
* @param mixed $default_value 默认值
* @param bool $convert 是否进行转义
* @param bool $use_cache 是否使用缓存
* @return mixed
*/
public function getConvertedValue(string $field_name, $default_value = null, bool $convert = true, bool $use_cache = true)
{
$value = $this->getValue($field_name, $default_value, $use_cache);
if (!$convert || $value === null || $value === $default_value) {
return $value;
}
// 枚举转换
if (isset($this->enum_mapping[$field_name])) {
return $this->convertEnumValue($field_name, $value, $use_cache);
}
// 关系转换
if (isset($this->relation_mapping[$field_name])) {
return $this->convertRelationValue($field_name, $value, $use_cache);
}
return $value;
}
/**
* 批量获取带转义的字段值
* @param array $field_names 字段名数组
* @param bool $convert 是否进行转义
* @param bool $use_cache 是否使用缓存
* @return array
*/
public function getConvertedValues(array $field_names, bool $convert = true, bool $use_cache = true): array
{
$values = $this->getValues($field_names, $use_cache);
if (!$convert || empty($values)) {
return $values;
}
return $this->convertValues($values, $field_names, $use_cache);
}
}

15
uniapp/api/apiRoute.js

@ -1734,15 +1734,26 @@ export default {
})
},
// 提交合同签署
// 学员提交合同签署
async signStudentContract(data = {}) {
return await http.post('/student/contract/sign', {
return await http.post('/contract/signStudentContract', {
contract_id: data.contract_id,
contract_sign_id: data.contract_sign_id,
student_id: data.student_id,
form_data: data.form_data,
signature_image: data.signature_image,
})
},
// 员工端提交合同签署
async signStaffContract(data = {}) {
return await http.post('/contract/signStaffContract', {
contract_id: data.contract_id,
contract_sign_id: data.contract_sign_id,
form_data: data.form_data,
signature_image: data.signature_image,
})
},
// 下载合同文件
async downloadStudentContract(data = {}) {

4
uniapp/common/config.js

@ -1,6 +1,6 @@
// 环境变量配置
// const env = 'development'
const env = 'prod'
const env = 'development'
// const env = 'prod'
const isMockEnabled = false // 默认禁用Mock优先模式,仅作为回退
const isDebug = false // 默认启用调试模式
const devurl = 'http://localhost:20080/api'

30
uniapp/pages-student/contracts/sign.vue

@ -38,14 +38,13 @@
<view
v-for="(field, index) in filteredFormFields"
:key="index"
class="form_field"
:class="getFieldClass(field)"
:class="['form_field',getFieldClass(field)]"
>
<view class="field_label">
{{ field.name }}
<text v-if="field.is_required" class="required_mark">*</text>
<view v-if="isStaff" class="party_indicator">
<text class="party_tag" :class="getPartyClass(field)">{{ getPartyLabel(field) }}</text>
<text :class="['party_tag',getPartyClass(field)]">{{ getPartyLabel(field) }}</text>
</view>
</view>
@ -600,6 +599,23 @@
}
},
//
getSignatureImage() {
//
const signatureFields = this.formFields.filter(field =>
field.data_type === 'signature' || field.data_type === 'sign_img'
)
//
if (signatureFields.length > 0) {
const signatureField = signatureFields[0]
const fieldKey = signatureField.placeholder || signatureField.name
return this.formData[fieldKey] || ''
}
return ''
},
validateForm() {
//
for (const field of this.formFields) {
@ -637,16 +653,18 @@
//
response = await apiRoute.signStaffContract({
contract_id: this.contractId,
student_id: this.studentId,
contract_sign_id: this.contractSignId,
form_data: this.formData,
personnel_id: this.userInfo?.id || 0
signature_image: this.getSignatureImage()
})
} else {
//
response = await apiRoute.signStudentContract({
contract_id: this.contractId,
contract_sign_id: this.contractSignId,
student_id: this.studentId,
form_data: this.formData
form_data: this.formData,
signature_image: this.getSignatureImage()
})
}

Loading…
Cancel
Save