Browse Source

修改 bug

master
王泽彦 7 months ago
parent
commit
b54b68b4f6
  1. 89
      niucloud/app/api/controller/apiController/Contract.php
  2. 3
      niucloud/app/api/route/route.php
  3. 524
      niucloud/app/service/api/apiService/ContractSignFormService.php
  4. 25
      uniapp/api/apiRoute.js
  5. 29
      uniapp/api/member.js
  6. 4
      uniapp/common/config.js
  7. 4
      uniapp/pages-market/clue/clue_info.vue
  8. 212
      uniapp/pages-student/contracts/sign.vue
  9. 73
      uniapp/pages-student/messages/index.vue
  10. 18
      uniapp/pages/student/home/index.vue

89
niucloud/app/api/controller/apiController/Contract.php

@ -336,4 +336,93 @@ class Contract extends BaseApiService
return fail('合同签署失败:' . $e->getMessage());
}
}
/**
* 员工端合同签署
* @param Request $request
* @return mixed
*/
public function signStaffContract(Request $request)
{
$contract_id = $request->param('contract_id', 0);
$contract_sign_id = $request->param('contract_sign_id', 0);
$form_data = $request->param('form_data', []);
$signature_image = $request->param('signature_image', '');
if (empty($contract_id)) {
return fail('合同ID不能为空');
}
if (empty($contract_sign_id)) {
return fail('合同签署记录ID不能为空');
}
$params = [
'contract_id' => $contract_id,
'contract_sign_id' => $contract_sign_id,
'personnel_id' => $this->member_id,
'form_data' => $form_data,
'signature_image' => $signature_image
];
try {
$service = new ContractSignFormService();
$res = $service->submitStaffContractSign($params);
if (!$res['code']) {
return fail($res['msg']);
}
return success($res['data'], '合同签署成功');
} catch (\Exception $e) {
return fail('合同签署失败:' . $e->getMessage());
}
}
/**
* 学员端合同签署
* @param Request $request
* @return mixed
*/
public function signStudentContract(Request $request)
{
$contract_id = $request->param('contract_id', 0);
$contract_sign_id = $request->param('contract_sign_id', 0);
$student_id = $request->param('student_id', 0);
$form_data = $request->param('form_data', []);
$signature_image = $request->param('signature_image', '');
if (empty($contract_id)) {
return fail('合同ID不能为空');
}
if (empty($contract_sign_id)) {
return fail('合同签署记录ID不能为空');
}
if (empty($student_id)) {
return fail('学生ID不能为空');
}
$params = [
'contract_id' => $contract_id,
'contract_sign_id' => $contract_sign_id,
'student_id' => $student_id,
'form_data' => $form_data,
'signature_image' => $signature_image
];
try {
$service = new ContractSignFormService();
$res = $service->submitStudentContractSign($params);
if (!$res['code']) {
return fail($res['msg']);
}
return success($res['data'], '合同签署成功');
} catch (\Exception $e) {
return fail('合同签署失败:' . $e->getMessage());
}
}
}

3
niucloud/app/api/route/route.php

@ -468,6 +468,9 @@ Route::group(function () {
Route::get('contract/getStudentContractSignFormBySignId', 'apiController.Contract/getStudentContractSignFormBySignId');
// 前端期望的路由路径(映射到相同的控制器方法)
Route::get('student/contract/sign-form', 'apiController.Contract/getStudentContractSignForm');
// 员工端和学员端合同签署接口
Route::post('contract/signStaffContract', 'apiController.Contract/signStaffContract');
Route::post('contract/signStudentContract', 'apiController.Contract/signStudentContract');
//服务管理

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

@ -581,79 +581,6 @@ class ContractSignFormService extends BaseApiService
return (string)$value;
}
/**
* 提交学员合同签署数据
* 处理移动端提交的合同签署表单数据
* 验证数据完整性并保存到数据库
*
* @param array $params 提交参数
* - contract_id: 合同模板ID
* - student_id: 学员ID
* - form_data: 表单数据数组
* @return array 提交结果
*/
public function submitStudentContractSign(array $params)
{
try {
// 验证必要参数
if (empty($params['contract_id']) || empty($params['student_id']) || empty($params['form_data'])) {
throw new \Exception('缺少必要参数');
}
$contract_id = (int)$params['contract_id'];
$student_id = (int)$params['student_id'];
$form_data = $params['form_data'];
Log::info('开始处理学员合同签署提交', [
'contract_id' => $contract_id,
'student_id' => $student_id,
'form_data_keys' => array_keys($form_data)
]);
// 验证合同和学员是否存在
$contract = $this->getContractInfo($contract_id);
if (!$contract) {
throw new \Exception('合同模板不存在');
}
$student = $this->getStudentInfo($student_id);
if (!$student) {
throw new \Exception('学员信息不存在');
}
// 保存签署记录
$sign_id = $this->saveContractSignRecord($contract_id, $student_id, $form_data);
if ($sign_id) {
Log::info('学员合同签署成功', [
'contract_id' => $contract_id,
'student_id' => $student_id,
'sign_id' => $sign_id
]);
return [
'code' => 1,
'msg' => '合同签署成功',
'data' => ['sign_id' => $sign_id]
];
} else {
throw new \Exception('保存签署记录失败');
}
} catch (\Exception $e) {
Log::error('学员合同签署失败', [
'params' => $params,
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
return [
'code' => 0,
'msg' => $e->getMessage(),
'data' => []
];
}
}
/**
* 保存合同签署记录
@ -895,4 +822,455 @@ class ContractSignFormService extends BaseApiService
return '';
}
}
/**
* 员工端合同签署提交
* 处理员工端提交的合同签署表单数据,员工可以填写甲乙双方所有字段
*
* @param array $params 提交参数
* - contract_id: 合同模板ID
* - contract_sign_id: 合同签署记录ID
* - personnel_id: 员工ID
* - form_data: 表单数据数组
* - signature_image: 签名图片数据
* @return array 提交结果
*/
public function submitStaffContractSign(array $params)
{
try {
// 验证必要参数
if (empty($params['contract_id']) || empty($params['contract_sign_id']) || empty($params['personnel_id'])) {
throw new \Exception('缺少必要参数:contract_id、contract_sign_id、personnel_id');
}
$contract_id = (int)$params['contract_id'];
$contract_sign_id = (int)$params['contract_sign_id'];
$personnel_id = (int)$params['personnel_id'];
$form_data = $params['form_data'] ?? [];
$signature_image = $params['signature_image'] ?? '';
Log::info('开始处理员工端合同签署提交', [
'contract_id' => $contract_id,
'contract_sign_id' => $contract_sign_id,
'personnel_id' => $personnel_id,
'form_data_keys' => array_keys($form_data)
]);
// 验证合同签署记录是否存在
$sign_record = Db::table('school_contract_sign')
->where('id', $contract_sign_id)
->where('contract_id', $contract_id)
->find();
if (!$sign_record) {
throw new \Exception('合同签署记录不存在');
}
// 验证员工是否存在
$personnel = Db::table('school_personnel')
->where('id', $personnel_id)
->where('status', 1)
->find();
if (!$personnel) {
throw new \Exception('员工信息不存在');
}
// 事务处理
Db::startTrans();
try {
// 1. 保存表单数据到 school_document_data_source_config 表
$this->saveFormDataToConfig($contract_id, $contract_sign_id, $form_data, 'staff');
// 2. 更新合同签署记录状态
$this->updateContractSignStatus($contract_sign_id, $personnel_id, $signature_image);
Db::commit();
Log::info('员工端合同签署成功', [
'contract_id' => $contract_id,
'contract_sign_id' => $contract_sign_id,
'personnel_id' => $personnel_id
]);
return [
'code' => 1,
'msg' => '合同签署成功',
'data' => ['contract_sign_id' => $contract_sign_id]
];
} catch (\Exception $e) {
Db::rollback();
throw $e;
}
} catch (\Exception $e) {
Log::error('员工端合同签署失败', [
'params' => $params,
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
return [
'code' => 0,
'msg' => $e->getMessage(),
'data' => []
];
}
}
/**
* 学员端合同签署提交(新版本)
* 处理学员端提交的合同签署表单数据,学员只能填写乙方字段
*
* @param array $params 提交参数
* - contract_id: 合同模板ID
* - contract_sign_id: 合同签署记录ID
* - student_id: 学员ID
* - form_data: 表单数据数组
* - signature_image: 签名图片数据
* @return array 提交结果
*/
public function submitStudentContractSign(array $params)
{
try {
// 验证必要参数
if (empty($params['contract_id']) || empty($params['contract_sign_id']) || empty($params['student_id'])) {
throw new \Exception('缺少必要参数:contract_id、contract_sign_id、student_id');
}
$contract_id = (int)$params['contract_id'];
$contract_sign_id = (int)$params['contract_sign_id'];
$student_id = (int)$params['student_id'];
$form_data = $params['form_data'] ?? [];
$signature_image = $params['signature_image'] ?? '';
Log::info('开始处理学员端合同签署提交', [
'contract_id' => $contract_id,
'contract_sign_id' => $contract_sign_id,
'student_id' => $student_id,
'form_data_keys' => array_keys($form_data)
]);
// 验证合同签署记录是否存在
$sign_record = Db::table('school_contract_sign')
->where('id', $contract_sign_id)
->where('contract_id', $contract_id)
->where('student_id', $student_id)
->find();
if (!$sign_record) {
throw new \Exception('合同签署记录不存在');
}
// 验证学员是否存在
$student = Db::table('school_student')
->where('id', $student_id)
->where('status', 1)
->find();
if (!$student) {
throw new \Exception('学员信息不存在');
}
// 事务处理
Db::startTrans();
try {
// 1. 过滤学员端只能填写的字段(乙方字段)
$filtered_form_data = $this->filterStudentFormData($contract_id, $contract_sign_id, $form_data);
// 2. 保存表单数据到 school_document_data_source_config 表
$this->saveFormDataToConfig($contract_id, $contract_sign_id, $filtered_form_data, 'student');
// 3. 更新合同签署记录状态
$this->updateContractSignStatus($contract_sign_id, null, $signature_image, $student_id);
Db::commit();
Log::info('学员端合同签署成功', [
'contract_id' => $contract_id,
'contract_sign_id' => $contract_sign_id,
'student_id' => $student_id
]);
return [
'code' => 1,
'msg' => '合同签署成功',
'data' => ['contract_sign_id' => $contract_sign_id]
];
} catch (\Exception $e) {
Db::rollback();
throw $e;
}
} catch (\Exception $e) {
Log::error('学员端合同签署失败', [
'params' => $params,
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
return [
'code' => 0,
'msg' => $e->getMessage(),
'data' => []
];
}
}
/**
* 保存表单数据到 school_document_data_source_config 表的 default_value 字段
* 这是核心方法,确保数据正确写入到指定表中
*
* @param int $contract_id 合同模板ID
* @param int $contract_sign_id 合同签署记录ID
* @param array $form_data 表单数据
* @param string $user_type 用户类型(staff/student)
* @return bool
*/
private function saveFormDataToConfig($contract_id, $contract_sign_id, $form_data, $user_type)
{
try {
Log::info('开始保存表单数据到 school_document_data_source_config', [
'contract_id' => $contract_id,
'contract_sign_id' => $contract_sign_id,
'user_type' => $user_type,
'form_data_count' => count($form_data)
]);
$now = date('Y-m-d H:i:s');
$success_count = 0;
$total_count = count($form_data);
foreach ($form_data as $placeholder => $value) {
// 检查该字段配置是否已存在
$existing_config = Db::table('school_document_data_source_config')
->where('contract_id', $contract_id)
->where('contract_sign_id', $contract_sign_id)
->where('placeholder', $placeholder)
->find();
if ($existing_config) {
// 更新已存在的配置记录的 default_value 字段
$update_result = Db::table('school_document_data_source_config')
->where('id', $existing_config['id'])
->update([
'default_value' => (string)$value,
'updated_at' => $now,
'updated_by' => $user_type
]);
if ($update_result) {
$success_count++;
Log::info('更新字段配置成功', [
'config_id' => $existing_config['id'],
'placeholder' => $placeholder,
'value' => $value
]);
} else {
Log::warning('更新字段配置失败', [
'config_id' => $existing_config['id'],
'placeholder' => $placeholder,
'value' => $value
]);
}
} else {
// 创建新的配置记录(这种情况说明配置数据可能缺失)
$config_data = [
'contract_id' => $contract_id,
'contract_sign_id' => $contract_sign_id,
'placeholder' => $placeholder,
'data_type' => 'user_input', // 默认为用户输入类型
'field_type' => 'text', // 默认为文本类型
'default_value' => (string)$value,
'is_required' => 0,
'sign_party' => '', // 需要根据字段名推断甲乙方
'created_at' => $now,
'updated_at' => $now,
'created_by' => $user_type,
'updated_by' => $user_type,
'deleted_at' => 0
];
$insert_result = Db::table('school_document_data_source_config')->insertGetId($config_data);
if ($insert_result) {
$success_count++;
Log::info('创建字段配置成功', [
'config_id' => $insert_result,
'placeholder' => $placeholder,
'value' => $value
]);
} else {
Log::warning('创建字段配置失败', [
'placeholder' => $placeholder,
'value' => $value
]);
}
}
}
Log::info('表单数据保存完成', [
'contract_id' => $contract_id,
'contract_sign_id' => $contract_sign_id,
'user_type' => $user_type,
'total_count' => $total_count,
'success_count' => $success_count
]);
// 如果所有数据都保存成功,返回 true
return $success_count === $total_count;
} catch (\Exception $e) {
Log::error('保存表单数据到配置表失败', [
'contract_id' => $contract_id,
'contract_sign_id' => $contract_sign_id,
'user_type' => $user_type,
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
throw $e;
}
}
/**
* 过滤学员端表单数据,只保留乙方字段
*
* @param int $contract_id 合同模板ID
* @param int $contract_sign_id 合同签署记录ID
* @param array $form_data 原始表单数据
* @return array 过滤后的表单数据
*/
private function filterStudentFormData($contract_id, $contract_sign_id, $form_data)
{
try {
// 获取该签署记录的字段配置
$configs = Db::table('school_document_data_source_config')
->where('contract_id', $contract_id)
->where('contract_sign_id', $contract_sign_id)
->select()
->toArray();
$filtered_data = [];
foreach ($form_data as $placeholder => $value) {
// 查找对应的字段配置
$config = array_filter($configs, function($c) use ($placeholder) {
return $c['placeholder'] === $placeholder;
});
if (!empty($config)) {
$config = array_values($config)[0];
$sign_party = $config['sign_party'] ?? '';
// 学员只能填写乙方字段
if (in_array($sign_party, ['second_party', 'party_b', '乙方', ''])) {
$filtered_data[$placeholder] = $value;
Log::info('学员字段通过过滤', [
'placeholder' => $placeholder,
'sign_party' => $sign_party,
'value' => $value
]);
} else {
Log::warning('学员字段被过滤', [
'placeholder' => $placeholder,
'sign_party' => $sign_party,
'reason' => '学员只能填写乙方字段'
]);
}
} else {
// 如果没有找到配置,保守处理:允许提交但记录警告
$filtered_data[$placeholder] = $value;
Log::warning('未找到字段配置,默认允许', [
'placeholder' => $placeholder,
'value' => $value
]);
}
}
Log::info('学员表单数据过滤完成', [
'original_count' => count($form_data),
'filtered_count' => count($filtered_data)
]);
return $filtered_data;
} catch (\Exception $e) {
Log::error('过滤学员表单数据失败', [
'contract_id' => $contract_id,
'contract_sign_id' => $contract_sign_id,
'error' => $e->getMessage()
]);
// 出现异常时返回原始数据,避免阻断流程
return $form_data;
}
}
/**
* 更新合同签署记录状态
*
* @param int $contract_sign_id 合同签署记录ID
* @param int|null $personnel_id 员工ID(员工签署时传入)
* @param string $signature_image 签名图片
* @param int|null $student_id 学员ID(学员签署时传入)
* @return bool
*/
private function updateContractSignStatus($contract_sign_id, $personnel_id = null, $signature_image = '', $student_id = null)
{
try {
$now = date('Y-m-d H:i:s');
$update_data = [
'sign_status' => 1, // 已签署
'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;
}
$result = Db::table('school_contract_sign')
->where('id', $contract_sign_id)
->update($update_data);
if ($result) {
Log::info('合同签署记录状态更新成功', [
'contract_sign_id' => $contract_sign_id,
'personnel_id' => $personnel_id,
'student_id' => $student_id,
'signature_image_length' => strlen($signature_image)
]);
return true;
} else {
Log::warning('合同签署记录状态更新失败', [
'contract_sign_id' => $contract_sign_id,
'update_data' => $update_data
]);
return false;
}
} catch (\Exception $e) {
Log::error('更新合同签署记录状态失败', [
'contract_sign_id' => $contract_sign_id,
'personnel_id' => $personnel_id,
'student_id' => $student_id,
'error' => $e->getMessage()
]);
throw $e;
}
}
}

25
uniapp/api/apiRoute.js

@ -1757,9 +1757,12 @@ export default {
// 获取学员基本信息
async getStudentInfo(data = {}) {
return await http.get('/student/student-info', {
student_id: data.student_id,
})
return await http.get(`/student/info/${data.student_id}`)
},
// 获取当前用户的学员列表
async getMyStudentList() {
return await http.get('/student/mychild')
},
// 获取学员基本信息
@ -2167,7 +2170,7 @@ export default {
keyword: data.keyword,
is_read: data.is_read,
}
const response = await http.get(`/message-test/list/${data.student_id}`, params)
const response = await http.get(`/message/list/${data.student_id}`, params)
return response
} catch (error) {
console.error('获取学员消息列表错误:', error)
@ -2182,7 +2185,7 @@ export default {
const params = {
student_id: data.student_id,
}
const response = await http.get(`/message-test/detail/${data.message_id}`, params)
const response = await http.get(`/message/detail/${data.message_id}`, params)
return response
} catch (error) {
console.error('获取消息详情错误:', error)
@ -2194,7 +2197,7 @@ export default {
// 标记消息已读
async markStudentMessageRead(data = {}) {
try {
const response = await http.post('/message-test/mark-read', {
const response = await http.post('/message/mark-read', {
message_id: data.message_id,
student_id: data.student_id,
})
@ -2213,7 +2216,7 @@ export default {
// 批量标记消息已读
async markStudentMessageBatchRead(data = {}) {
try {
const response = await http.post('/message-test/mark-batch-read', {
const response = await http.post('/message/mark-batch-read', {
student_id: data.student_id,
message_ids: data.message_ids,
message_type: data.message_type,
@ -2233,7 +2236,7 @@ export default {
// 获取学员消息统计
async getStudentMessageStats(data = {}) {
try {
const response = await http.get(`/message-test/stats/${data.student_id}`)
const response = await http.get(`/message/stats/${data.student_id}`)
return response
} catch (error) {
console.error('获取消息统计错误:', error)
@ -2252,7 +2255,7 @@ export default {
page: data.page || 1,
limit: data.limit || 20,
}
const response = await http.get('/message-test/conversation', params)
const response = await http.get('/message/conversation', params)
return response
} catch (error) {
console.error('获取对话消息错误:', error)
@ -2275,7 +2278,7 @@ export default {
// 学员回复消息
async replyMessage(data = {}) {
try {
const response = await http.post('/message-test/reply', {
const response = await http.post('/message/reply', {
student_id: data.student_id,
to_type: data.to_type,
to_id: data.to_id,
@ -2314,7 +2317,7 @@ export default {
page: data.page || 1,
limit: data.limit || 10,
}
const response = await http.get(`/message-test/search/${data.student_id}`, params)
const response = await http.get(`/message/search/${data.student_id}`, params)
return response
} catch (error) {
console.error('搜索消息错误:', error)

29
uniapp/api/member.js

@ -28,15 +28,34 @@ export default {
return await http.post('/student/avatar', data);
},
// 获取未读消息数量(如果有接口的话,暂时模拟)
async getUnreadMessageCount(data = {}) {
// 这里可以调用真实的消息接口,暂时返回模拟数据
// 获取未读消息数量
async getUnreadMessageCount(studentId) {
try {
if (!studentId) {
throw new Error('学员ID不能为空')
}
// 调用消息统计API
const response = await http.get(`/message/stats/${studentId}`)
if (response && response.code === 1) {
return {
code: 1,
data: {
unread_count: response.data.unread_messages || 0
}
}
} else {
throw new Error(response?.msg || 'API调用失败')
}
} catch (error) {
console.error('获取未读消息数量失败:', error)
// 降级到0未读消息
return {
code: 1,
data: {
unread_count: Math.floor(Math.random() * 5)
unread_count: 0
}
}
}
};
},
//↓↓↓↓↓↓↓↓↓↓↓↓-----体测数据管理接口-----↓↓↓↓↓↓↓↓↓↓↓↓

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'

4
uniapp/pages-market/clue/clue_info.vue

@ -1596,7 +1596,7 @@ ${orderInfo.paid_at ? '支付时间:' + this.formatOrderTime(orderInfo.paid_at
}
//
let url = `/pages-student/contracts/sign?contract_id=${contractId}&student_id=${studentId}&contract_name=${encodeURIComponent(order.product_name + '合同')}`
let url = `/pages-student/contracts/sign?contract_id=${contractId}&student_id=${studentId}&contract_name=${encodeURIComponent(order.product_name + '合同')}&user_role=staff`
// ID
if (contractSignId) {
@ -1626,7 +1626,7 @@ ${orderInfo.paid_at ? '支付时间:' + this.formatOrderTime(orderInfo.paid_at
const contractInfo = res.data
//
uni.navigateTo({
url: `/pages-student/contracts/sign?contract_id=${contractInfo.contract_id}&student_id=${studentId}&contract_name=${encodeURIComponent(contractInfo.contract_name || order.product_name + '合同')}`
url: `/pages-student/contracts/sign?contract_id=${contractInfo.contract_id}&student_id=${studentId}&contract_name=${encodeURIComponent(contractInfo.contract_name || order.product_name + '合同')}&user_role=staff`
})
} else {
uni.showToast({

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

@ -36,13 +36,17 @@
<view class="form_title">请填写以下信息</view>
<view class="form_content">
<view
v-for="(field, index) in formFields"
v-for="(field, index) in filteredFormFields"
:key="index"
class="form_field"
:class="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>
</view>
</view>
<!-- 手写签名字段 -->
@ -85,8 +89,8 @@
type="text"
:placeholder="field.placeholder || '请输入' + field.name"
v-model="formData[field.placeholder]"
:disabled="field.data_type !== 'user_input'"
:class="field.data_type !== 'user_input' ? 'disabled' : ''"
:disabled="!canEditField(field)"
:class="!canEditField(field) ? 'disabled' : ''"
/>
</view>
@ -115,8 +119,8 @@
type="number"
:placeholder="field.placeholder || '请输入' + field.name"
v-model="formData[field.placeholder]"
:disabled="field.data_type !== 'user_input'"
:class="field.data_type !== 'user_input' ? 'disabled' : ''"
:disabled="!canEditField(field)"
:class="!canEditField(field) ? 'disabled' : ''"
/>
</view>
@ -125,8 +129,8 @@
<textarea
:placeholder="field.placeholder || '请输入' + field.name"
v-model="formData[field.placeholder]"
:disabled="field.data_type !== 'user_input'"
:class="field.data_type !== 'user_input' ? 'disabled' : ''"
:disabled="!canEditField(field)"
:class="!canEditField(field) ? 'disabled' : ''"
></textarea>
</view>
@ -176,11 +180,38 @@
formFields: [],
formData: {},
loading: true,
submitting: false
submitting: false,
//
userInfo: null,
userRole: 'student', //
isStaffMode: false
}
},
computed: {
//
isStaff() {
return this.userRole === 'staff' || this.isStaffMode
},
//
filteredFormFields() {
if (!this.formFields || this.formFields.length === 0) {
return []
}
//
if (this.isStaff) {
return this.formFields
}
//
return this.formFields.filter(field => {
const signParty = field.sign_party || ''
return signParty === 'second_party' || signParty === 'party_b' || signParty === '乙方'
})
},
//
renderContractContent() {
if (!this.contractContent) return ''
@ -268,6 +299,13 @@
// ID
this.contractSignId = parseInt(options.contract_sign_id) || 0
//
this.userRole = options.user_role || 'student'
this.isStaffMode = options.user_role === 'staff'
//
this.getUserInfo()
if (this.contractId && this.studentId) {
this.loadSignForm()
} else {
@ -298,6 +336,82 @@
uni.navigateBack()
},
//
getUserInfo() {
try {
const userInfo = uni.getStorageSync('userInfo')
if (userInfo) {
this.userInfo = JSON.parse(userInfo)
// URLURL
if (this.userInfo.user_type && this.userRole === 'student') {
this.userRole = this.userInfo.user_type === 'staff' ? 'staff' : 'student'
this.isStaffMode = this.userRole === 'staff'
}
}
} catch (error) {
console.error('获取用户信息失败:', error)
}
},
//
canEditField(field) {
//
if (field.data_type !== 'user_input') {
return false
}
//
if (this.isStaff) {
return true
}
//
const signParty = field.sign_party || ''
return signParty === 'second_party' || signParty === 'party_b' || signParty === '乙方'
},
//
getFieldClass(field) {
const classes = []
if (this.isStaff) {
const signParty = field.sign_party || ''
if (signParty === 'first_party' || signParty === 'party_a' || signParty === '甲方') {
classes.push('first_party_field')
} else if (signParty === 'second_party' || signParty === 'party_b' || signParty === '乙方') {
classes.push('second_party_field')
}
}
if (!this.canEditField(field)) {
classes.push('readonly_field')
}
return classes.join(' ')
},
//
getPartyClass(field) {
const signParty = field.sign_party || ''
if (signParty === 'first_party' || signParty === 'party_a' || signParty === '甲方') {
return 'party_first'
} else if (signParty === 'second_party' || signParty === 'party_b' || signParty === '乙方') {
return 'party_second'
}
return 'party_unknown'
},
//
getPartyLabel(field) {
const signParty = field.sign_party || ''
if (signParty === 'first_party' || signParty === 'party_a' || signParty === '甲方') {
return '甲方'
} else if (signParty === 'second_party' || signParty === 'party_b' || signParty === '乙方') {
return '乙方'
}
return '未知'
},
async loadSignForm() {
this.loading = true
try {
@ -517,12 +631,24 @@
formData: this.formData
})
//
const response = await apiRoute.signStudentContract({
//
let response
if (this.isStaff) {
//
response = await apiRoute.signStaffContract({
contract_id: this.contractId,
student_id: this.studentId,
form_data: this.formData,
personnel_id: this.userInfo?.id || 0
})
} else {
//
response = await apiRoute.signStudentContract({
contract_id: this.contractId,
student_id: this.studentId,
form_data: this.formData
})
}
if (response.code === 1) {
uni.showToast({
@ -863,6 +989,72 @@
100% { transform: rotate(360deg); }
}
//
.party_indicator {
display: inline-flex;
align-items: center;
margin-left: 12rpx;
.party_tag {
font-size: 20rpx;
padding: 4rpx 8rpx;
border-radius: 6rpx;
font-weight: 500;
&.party_first {
background: rgba(255, 152, 0, 0.1);
color: #ff9800;
border: 1rpx solid rgba(255, 152, 0, 0.3);
}
&.party_second {
background: rgba(76, 175, 80, 0.1);
color: #4caf50;
border: 1rpx solid rgba(76, 175, 80, 0.3);
}
&.party_unknown {
background: rgba(158, 158, 158, 0.1);
color: #9e9e9e;
border: 1rpx solid rgba(158, 158, 158, 0.3);
}
}
}
//
.form_field {
&.first_party_field {
border-left: 4rpx solid #ff9800;
background: linear-gradient(90deg, rgba(255, 152, 0, 0.02) 0%, transparent 100%);
.field_label {
color: #e65100;
}
}
&.second_party_field {
border-left: 4rpx solid #4caf50;
background: linear-gradient(90deg, rgba(76, 175, 80, 0.02) 0%, transparent 100%);
.field_label {
color: #2e7d32;
}
}
&.readonly_field {
background: #f8f9fa;
.field_label {
color: #6c757d;
}
input, textarea {
background: #f8f9fa !important;
color: #6c757d !important;
}
}
}
//
.submit_section {
position: fixed;

73
uniapp/pages-student/messages/index.vue

@ -228,9 +228,9 @@
{ value: 'all', text: '全部', count: 0 },
{ value: 'system', text: '系统消息', count: 0 },
{ value: 'notification', text: '通知公告', count: 0 },
{ value: 'homework', text: '作业任务', count: 0 },
{ value: 'feedback', text: '反馈评价', count: 0 },
{ value: 'reminder', text: '课程提醒', count: 0 }
// { value: 'homework', text: '', count: 0 },
// { value: 'feedback', text: '', count: 0 },
// { value: 'reminder', text: '', count: 0 }
]
}
},
@ -241,12 +241,12 @@
}
},
onLoad(options) {
async onLoad(options) {
// 使
const userInfo = uni.getStorageSync('userInfo')
if (userInfo && userInfo.id) {
this.studentId = parseInt(userInfo.id)
this.initPage()
// userInfo.id IDID
await this.findStudentIdByMemberId(parseInt(userInfo.id))
} else {
// 使
this.studentId = parseInt(options.student_id) || 0
@ -267,6 +267,33 @@
uni.navigateBack()
},
async findStudentIdByMemberId(memberId) {
try {
console.log('查找会员ID对应的学员ID:', memberId)
// API
const response = await apiRoute.getMyStudentList()
if (response && response.code === 1 && response.data && response.data.list && response.data.list.length > 0) {
// 使
const firstStudent = response.data.list[0]
this.studentId = firstStudent.id || firstStudent.student_id
console.log('找到学员ID:', this.studentId, '学员姓名:', firstStudent.name)
this.initPage()
} else {
console.warn('当前用户没有关联的学员,使用会员ID作为学员ID')
// 使IDID
this.studentId = memberId
this.initPage()
}
} catch (error) {
console.error('查找学员ID失败:', error)
// 使IDID
this.studentId = memberId
this.initPage()
}
},
async initPage() {
await this.loadStudentInfo()
await this.loadMessages()
@ -275,14 +302,37 @@
async loadStudentInfo() {
try {
//
const mockStudentInfo = {
console.log('加载学员信息:', this.studentId)
// API
const response = await apiRoute.getStudentInfo({
student_id: this.studentId
})
if (response && response.code === 1 && response.data && response.data.student_info) {
this.studentInfo = {
id: response.data.student_info.id,
name: response.data.student_info.name,
gender_text: response.data.student_info.gender_text,
birthday: response.data.student_info.birthday,
headimg: response.data.student_info.headimg
}
console.log('学员信息加载成功:', this.studentInfo)
} else {
console.warn('API返回失败,使用Mock数据:', response?.msg)
// Mock
this.studentInfo = {
id: this.studentId,
name: '小明'
name: '学员'
}
}
this.studentInfo = mockStudentInfo
} catch (error) {
console.error('获取学员信息失败:', error)
// Mock
this.studentInfo = {
id: this.studentId,
name: '学员'
}
}
},
@ -845,12 +895,13 @@
.search_box {
.search_input {
width: 100%;
padding: 16rpx 20rpx;
padding: 16rpx;
border: 1px solid #e0e0e0;
border-radius: 8rpx;
font-size: 28rpx;
background: #f8f9fa;
margin-bottom: 16rpx;
height: 60rpx;
&::placeholder {
color: #999;

18
uniapp/pages/student/home/index.vue

@ -216,12 +216,14 @@
this.setCurrentWeekDay()
await this.loadUserInfo()
await this.loadStudentList()
this.loadUnreadMessageCount()
//
await this.loadUnreadMessageCount()
},
async refreshData() {
await this.loadStudentList()
this.loadUnreadMessageCount()
//
await this.loadUnreadMessageCount()
},
setCurrentWeekDay() {
@ -307,8 +309,18 @@
async loadUnreadMessageCount() {
try {
// ID
if (!this.selectedStudent || !this.selectedStudent.id) {
console.warn('没有选中的学员,无法获取未读消息数量')
this.unreadCount = 0
return
}
const studentId = this.selectedStudent.student_id || this.selectedStudent.id
console.log('获取学员未读消息数量:', studentId)
// API
const response = await apiRoute.getUnreadMessageCount()
const response = await apiRoute.getUnreadMessageCount(studentId)
console.log('未读消息数量API响应:', response)
if (response.code === 1) {

Loading…
Cancel
Save