Browse Source

Merge branch 'master' of http://gitlab.frkj.cc/php/zhjwxt

master
李双庆 10 months ago
parent
commit
beaf707b84
  1. 12
      admin/src/app/api/customer_resources.ts
  2. 8
      admin/src/app/views/customer_resource_changes/customer_resource_changes.vue
  3. 69
      admin/src/app/views/customer_resources/components/UserProfile.vue
  4. 122
      admin/src/app/views/customer_resources/components/log.vue
  5. 118
      admin/src/app/views/customer_resources/components/order_table.vue
  6. 131
      admin/src/app/views/customer_resources/components/student_courses.vue
  7. 29
      niucloud/app/adminapi/controller/customer_resources/CustomerResources.php
  8. 5
      niucloud/app/adminapi/route/customer_resources.php
  9. 119
      niucloud/app/api/controller/apiController/CustomerResourcesAuth.php
  10. 65
      niucloud/app/api/controller/apiController/PhysicalTest.php
  11. 46
      niucloud/app/api/controller/apiController/Test.php
  12. 53
      niucloud/app/api/controller/apiController/UserFeedback.php
  13. 12
      niucloud/app/api/controller/upload/Upload.php
  14. 34
      niucloud/app/api/route/route.php
  15. 19
      niucloud/app/common.php
  16. 7
      niucloud/app/model/customer_resources/CustomerResources.php
  17. 7
      niucloud/app/model/physical_test/PhysicalTest.php
  18. 156
      niucloud/app/service/admin/customer_resources/CustomerResourcesService.php
  19. 24
      niucloud/app/service/api/apiService/CommonService.php
  20. 117
      niucloud/app/service/api/apiService/CustomerResourcesService.php
  21. 115
      niucloud/app/service/api/apiService/PhysicalTestService.php
  22. 95
      niucloud/app/service/api/apiService/TestService.php

12
admin/src/app/api/customer_resources.ts

@ -76,3 +76,15 @@ export function fpEdit(params: Record<string, any>) {
export function getWithCoachList(params: Record<string, any>) {
return request.get('customer_resources/coach_person', { params })
}
export function getLogList(params: Record<string, any>) {
return request.get('customer_resources/log_list', { params })
}
export function getStudentCoursesList(params: Record<string, any>) {
return request.get('customer_resources/student_courses', { params })
}
export function getOrderTableList(params: Record<string, any>) {
return request.get('customer_resources/order_table', { params })
}

8
admin/src/app/views/customer_resource_changes/customer_resource_changes.vue

@ -76,6 +76,12 @@ import { useRoute } from 'vue-router'
const route = useRoute()
const pageName = route.meta.title
const props = defineProps({
value: Number
})
console.log(props.value);
let customerResourceChangesTable = reactive({
page: 1,
limit: 10,
@ -83,7 +89,7 @@ let customerResourceChangesTable = reactive({
loading: true,
data: [],
searchParam: {
customer_resource_id: route.query.id,
customer_resource_id: props.value ? props.value : route.query.id,
},
})

69
admin/src/app/views/customer_resources/components/UserProfile.vue

@ -10,11 +10,14 @@
<!-- 顶部用户信息 -->
<el-card class="mb-4">
<div class="flex items-center">
<el-avatar :size="60" class="mr-4" />
<el-avatar :size="60" class="mr-4" :src="user.headimg"/>
<div>
<h2 class="text-xl font-bold">{{ user.name }}</h2>
<p>ID: {{ user.id }}</p>
<p>电话: {{ user.phone }}</p>
<h2 class="text-xl font-bold">{{ user.nickname }}</h2>
<div style="display: flex; gap: 200px;margin-top: 10px;">
<p>ID: U{{ user.member_id }}</p>
<p>电话: {{ user.mobile }}</p>
<p>住址: {{ user.address }}</p>
</div>
</div>
</div>
</el-card>
@ -25,25 +28,28 @@
<el-tab-pane label="修改日志" name="log" />
<el-tab-pane label="学生情况" name="student" />
<el-tab-pane label="订单列表" name="orders" />
<el-tab-pane label="课程列表" name="courses" />
</el-tabs>
<!-- 六要素信息卡片 -->
<el-card v-if="activeTab === 'six-elements'">
<h3 class="text-lg font-bold mb-4">六要素信息</h3>
<el-row :gutter="20" class="mb-2">
<el-col :span="8">需求购买力<el-tag>{{ info.purchasePower }}</el-tag></el-col>
<el-col :span="8">认知理念<el-tag>{{ info.knowledge }}</el-tag></el-col>
<el-col :span="8">距离<span>{{ info.distance }}</span></el-col>
<el-col :span="12">需求购买力<el-tag>{{ info.purchasePower }}</el-tag></el-col>
<el-col :span="12">认知理念<el-tag>{{ info.knowledge }}</el-tag></el-col>
</el-row>
<el-row :gutter="20" class="mb-2">
<el-col :span="8">可谈上课时间<span>{{ info.canTalkDate }}</span></el-col>
<el-col :span="8">承诺到访时间<span>{{ info.promisedVisitDate }}</span></el-col>
<el-col :span="8">实际到访时间<span>{{ info.actualVisitDate }}</span></el-col>
<el-col :span="12">距离<span>{{ info.distance }}</span></el-col>
<el-col :span="12">可谈上课时间<span>{{ info.canTalkDate }}</span></el-col>
</el-row>
<el-row :gutter="20" class="mb-2">
<el-col :span="8">电话后的意向程度<el-tag>{{ info.phoneIntention }}</el-tag></el-col>
<el-col :span="8">是否关单
<el-col :span="12">承诺到访时间<span>{{ info.promisedVisitDate }}</span></el-col>
<el-col :span="12">实际到访时间<span>{{ info.actualVisitDate }}</span></el-col>
</el-row>
<el-row :gutter="20" class="mb-2">
<el-col :span="12">电话后的意向程度<el-tag>{{ info.phoneIntention }}</el-tag></el-col>
<el-col :span="12">是否关单
<el-tag :type="info.isClosed ? 'success' : 'danger'">{{ info.isClosed ? '是' : '否' }}</el-tag>
</el-col>
</el-row>
@ -61,22 +67,41 @@
</el-form-item>
</el-form>
</el-card>
<el-card v-if="activeTab === 'log'">
<log :value="user.id"/>
</el-card>
<el-card v-if="activeTab === 'student'">
<student :value="user.id"/>
</el-card>
<el-card v-if="activeTab === 'orders'">
<orders :value="user.id"/>
</el-card>
</el-dialog>
</template>
<script setup>
import { useDictionary } from '@/app/api/dict'
import { ref, reactive, computed, watch } from 'vue'
import Log from '@/app/views/customer_resources/components/log.vue'
import Student from '@/app/views/customer_resources/components/student_courses.vue'
import Orders from '@/app/views/customer_resources/components/order_table.vue'
let showDialog = ref(false)
const activeTab = ref('six-elements')
const user = reactive({
name: '王五1',
id: 'U001',
phone: '13914556707'
id: '',
member_id:'',
nickname: '',
headimg: '',
mobile:'',
address:''
})
const info = reactive({
@ -110,9 +135,15 @@
await useDictionary('cognitive_concept')
).data.dictionary
user.name = row.name;
user.id = row.id;
user.phone = row.phone_number;
user.nickname = row.member_info.nickname;
user.member_id = row.member_info.member_id;
user.headimg = row.member_info.headimg;
user.mobile = row.member_info.mobile;
user.address = row.member_info.address;
info.purchasePower = purchase_powerList.value.flat().find(item => item.value == row.six.purchase_power)?.name || '';
info.knowledge = concept_awarenessList.value.flat().find(item => item.value == row.six.concept_awareness)?.name || '';
info.distance = row.six.distance;

122
admin/src/app/views/customer_resources/components/log.vue

@ -0,0 +1,122 @@
<template>
<div class="main-container">
<el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
</div>
<div class="mt-[10px]">
<el-table
:data="customerResourceChangesTable.data"
size="large"
v-loading="customerResourceChangesTable.loading"
>
<template #empty>
<span>{{
!customerResourceChangesTable.loading ? t('emptyData') : ''
}}</span>
</template>
<el-table-column prop="created_at" label="时间" />
<el-table-column prop="name" label="操作人员" />
<el-table-column prop="type" label="操作类型">
<template #default="scope">
<div v-html="scope.row.type"></div>
</template>
</el-table-column>
<el-table-column prop="values" label="详细信息">
<template #default="scope">
<div v-html="scope.row.values"></div>
</template>
</el-table-column>
</el-table>
<div class="mt-[16px] flex justify-end">
<el-pagination
v-model:current-page="customerResourceChangesTable.page"
v-model:page-size="customerResourceChangesTable.limit"
layout="total, sizes, prev, pager, next, jumper"
:total="customerResourceChangesTable.total"
@size-change="loadCustomerResourceChangesList()"
@current-change="loadCustomerResourceChangesList"
/>
</div>
</div>
</el-card>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref, watch } from 'vue'
import { t } from '@/lang'
import { useDictionary } from '@/app/api/dict'
import {
getLogList,
} from '@/app/api/customer_resources'
import { img } from '@/utils/common'
import { ElMessageBox, FormInstance } from 'element-plus'
import { useRoute } from 'vue-router'
const route = useRoute()
const pageName = route.meta.title
const props = defineProps({
value: Number
})
let customerResourceChangesTable = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {
customer_resource_id: props.value,
},
})
/**
* 获取客户资源表变更记录列表
*/
const loadCustomerResourceChangesList = (page: number = 1) => {
customerResourceChangesTable.loading = true
customerResourceChangesTable.page = page
getLogList({
page: customerResourceChangesTable.page,
limit: customerResourceChangesTable.limit,
...customerResourceChangesTable.searchParam,
})
.then((res) => {
customerResourceChangesTable.loading = false
customerResourceChangesTable.data = res.data.data
customerResourceChangesTable.total = res.data.total
})
.catch(() => {
customerResourceChangesTable.loading = false
})
}
loadCustomerResourceChangesList()
</script>
<style lang="scss" scoped>
/* 多行超出隐藏 */
.multi-hidden {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
</style>

118
admin/src/app/views/customer_resources/components/order_table.vue

@ -0,0 +1,118 @@
<template>
<div class="main-container">
<el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
</div>
<div class="mt-[10px]">
<el-table
:data="customerResourceChangesTable.data"
size="large"
v-loading="customerResourceChangesTable.loading"
>
<template #empty>
<span>{{
!customerResourceChangesTable.loading ? t('emptyData') : ''
}}</span>
</template>
<el-table-column prop="payment_id" label="订单号" />
<el-table-column prop="course_name" label="课程名称" />
<el-table-column prop="order_amount" label="金额" />
<el-table-column prop="order_status" label="状态" />
<el-table-column prop="created_at" label="下单时间" />
<el-table-column prop="type" label="支付方式" />
</el-table>
<div class="mt-[16px] flex justify-end">
<el-pagination
v-model:current-page="customerResourceChangesTable.page"
v-model:page-size="customerResourceChangesTable.limit"
layout="total, sizes, prev, pager, next, jumper"
:total="customerResourceChangesTable.total"
@size-change="loadCustomerResourceChangesList()"
@current-change="loadCustomerResourceChangesList"
/>
</div>
</div>
</el-card>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref, watch } from 'vue'
import {
getOrderTableList,
} from '@/app/api/customer_resources'
import { useRoute } from 'vue-router'
const route = useRoute()
const props = defineProps({
value: Number
})
let customerResourceChangesTable = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {
customer_resource_id: props.value,
},
})
const getProgress = (row) => {
if (!row.total) return 0;
return Math.round((row.used / row.total) * 100);
}
/**
* 获取客户资源表变更记录列表
*/
const loadCustomerResourceChangesList = (page: number = 1) => {
customerResourceChangesTable.loading = true
customerResourceChangesTable.page = page
getOrderTableList({
page: customerResourceChangesTable.page,
limit: customerResourceChangesTable.limit,
...customerResourceChangesTable.searchParam,
})
.then((res) => {
customerResourceChangesTable.loading = false
customerResourceChangesTable.data = res.data.data
customerResourceChangesTable.total = res.data.total
})
.catch(() => {
customerResourceChangesTable.loading = false
})
}
loadCustomerResourceChangesList()
</script>
<style lang="scss" scoped>
/* 多行超出隐藏 */
.multi-hidden {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
</style>

131
admin/src/app/views/customer_resources/components/student_courses.vue

@ -0,0 +1,131 @@
<template>
<div class="main-container">
<el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
</div>
<div class="mt-[10px]">
<el-table
:data="customerResourceChangesTable.data"
size="large"
v-loading="customerResourceChangesTable.loading"
>
<template #empty>
<span>{{
!customerResourceChangesTable.loading ? t('emptyData') : ''
}}</span>
</template>
<el-table-column prop="course_name" label="课程名称" />
<el-table-column label="学习进度">
<template #default="{ row }">
<div style="display: flex; align-items: center; justify-content: space-between;">
<el-progress
:percentage="getProgress(row)"
:text-inside="true"
stroke-width="18"
status="success"
style="flex: 1; max-width: 80%;"
/>
<span style="margin-left: 2px; white-space: nowrap; font-size: 14px; color: #666;">
{{ row.used }}/{{ row.total }}
</span>
</div>
</template>
</el-table-column>
<el-table-column prop="status" label="状态" />
<el-table-column prop="start_date" label="开始时间" />
</el-table>
<div class="mt-[16px] flex justify-end">
<el-pagination
v-model:current-page="customerResourceChangesTable.page"
v-model:page-size="customerResourceChangesTable.limit"
layout="total, sizes, prev, pager, next, jumper"
:total="customerResourceChangesTable.total"
@size-change="loadCustomerResourceChangesList()"
@current-change="loadCustomerResourceChangesList"
/>
</div>
</div>
</el-card>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref, watch } from 'vue'
import {
getStudentCoursesList,
} from '@/app/api/customer_resources'
import { useRoute } from 'vue-router'
const route = useRoute()
const props = defineProps({
value: Number
})
let customerResourceChangesTable = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {
customer_resource_id: props.value,
},
})
const getProgress = (row) => {
if (!row.total) return 0;
return Math.round((row.used / row.total) * 100);
}
/**
* 获取客户资源表变更记录列表
*/
const loadCustomerResourceChangesList = (page: number = 1) => {
customerResourceChangesTable.loading = true
customerResourceChangesTable.page = page
getStudentCoursesList({
page: customerResourceChangesTable.page,
limit: customerResourceChangesTable.limit,
...customerResourceChangesTable.searchParam,
})
.then((res) => {
customerResourceChangesTable.loading = false
customerResourceChangesTable.data = res.data.data
customerResourceChangesTable.total = res.data.total
})
.catch(() => {
customerResourceChangesTable.loading = false
})
}
loadCustomerResourceChangesList()
</script>
<style lang="scss" scoped>
/* 多行超出隐藏 */
.multi-hidden {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
</style>

29
niucloud/app/adminapi/controller/customer_resources/CustomerResources.php

@ -41,6 +41,8 @@ class CustomerResources extends BaseAdminController
return success((new CustomerResourcesService())->getPage($data));
}
/**
* 客户资源详情
* @param int $id
@ -196,4 +198,31 @@ class CustomerResources extends BaseAdminController
{
return success((new CustomerResourcesService())->getResourceByCourse($schedule));
}
public function log_list()
{
$data = $this->request->params([
["customer_resource_id", ""]
]);
return success((new CustomerResourcesService())->log_list($data));
}
public function student_courses()
{
$data = $this->request->params([
["customer_resource_id", ""]
]);
return success((new CustomerResourcesService())->student_courses($data));
}
public function order_table()
{
$data = $this->request->params([
["customer_resource_id", ""]
]);
return success((new CustomerResourcesService())->order_table($data));
}
}

5
niucloud/app/adminapi/route/customer_resources.php

@ -47,6 +47,11 @@ Route::group('customer_resources', function () {
Route::get('getResourceByCourse/:schedule/students', 'customer_resources.CustomerResources/getResourceByCourse');
Route::get('log_list','customer_resources.CustomerResources/log_list');
Route::get('student_courses','customer_resources.CustomerResources/student_courses');
Route::get('order_table','customer_resources.CustomerResources/order_table');
})->middleware([
AdminCheckToken::class,
AdminCheckRole::class,

119
niucloud/app/api/controller/apiController/CustomerResourcesAuth.php

@ -0,0 +1,119 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\api\controller\apiController;
use app\dict\member\MemberLoginTypeDict;
use app\model\member\Member;
use app\Request;
use app\service\api\apiService\CustomerResourcesService;
use app\service\api\login\LoginService;
use core\base\BaseApiService;
/**
* 学员登陆控制器相关接口
* Class Personnel
* @package app\api\controller\apiController
*/
class customerResourcesAuth extends BaseApiService
{
//获取字典
public function login(Request $request)
{
$phone = $request->param('phone', ''); //手机号
$password = $request->param('password', ''); //密码
$openid = $request->param('openid', ''); //微信小程序openid
if (empty($phone)) {
return fail('请输入手机号');
}
if (empty($password)) {
return fail('请输入密码');
}
$member_info = Member::where('mobile', $phone)->find();//查账户表信息是否存在
if (!$member_info) {
return fail('账户手机号有误');
}
$customerResources = \app\model\customer_resources\CustomerResources::where('member_id', $member_info['member_id'])->find();//查客户资源表信息是否存在
if (!$customerResources) {
return fail('账户信息有误');
}
//创建密码
//$a = create_password($password);
//验证密码
if (!check_password($password, $member_info->password)) {
return fail('手机号或密码不正确');
}
$res = (new LoginService())->login($member_info, MemberLoginTypeDict::MOBILE);
if (!$res) {
return fail('账户信息有误');
}
$res['user_type'] = '3';//用户类型|3=学员
return success($res);
}
//学生详情
public function info(){
$member_id = $this->member_id;
$where = [
'member_id'=>$member_id
];
$res = (new CustomerResourcesService())->getInfo($where);
if (!$res['code']) {
return fail($res['msg']);
}
return success($res['data']);
}
//学生详情-修改
public function edit(Request $request){
$member_id = $this->member_id;
$where = [
'member_id'=>$member_id
];
$data = [
'headimg' => $request->param('headimg', ''),
'name' => $request->param('name', ''),
'gender' => $request->param('gender', ''),
'age' => $request->param('age', ''),
'phone_number' => $request->param('phone_number', ''),
];
// 验证必填字段
if (empty($data['name'])) {
return fail('姓名不能为空');
}
if (empty($data['gender'])) {
return fail('性别不能为空');
}
if (empty($data['age'])) {
return fail('年龄不能为空');
}
if (empty($data['phone_number'])) {
return fail('手机号不能为空');
}
$res = (new CustomerResourcesService())->editInfo($where,$data);
if (!$res['code']) {
return fail($res['msg']);
}
return success([]);
}
}

65
niucloud/app/api/controller/apiController/PhysicalTest.php

@ -0,0 +1,65 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\api\controller\apiController;
use app\Request;
use app\service\api\apiService\ChatService;
use app\service\api\apiService\PhysicalTestService;
use core\base\BaseApiService;
/**
* 体测报告-控制器相关接口
* Class Personnel
* @package app\api\controller\apiController
*/
class PhysicalTest extends BaseApiService
{
//列表
public function index(Request $request)
{
$resource_id = $request->param('resource_id', '');//学生资源表id
if (empty($resource_id)) {
return fail('缺少参数');
}
$where = [
'resource_id' => $resource_id,
];
$res = (new PhysicalTestService())->getList($where);
return success($res);
}
//详情
public function info(Request $request)
{
$id = $request->param('id', '');//体测报告的id
if (empty($id)) {
return fail('缺少参数');
}
$where = [
'id' => $id,
];
$res = (new PhysicalTestService())->getInfo($where);
if(!$res['code']){
return fail($res['msg']);
}
return success($res['data']);
}
}

46
niucloud/app/api/controller/apiController/Test.php

@ -0,0 +1,46 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\api\controller\apiController;
use app\Request;
use app\service\api\apiService\CampusService;
use app\service\api\apiService\ChatService;
use app\service\api\apiService\CommonService;
use core\base\BaseApiService;
/**
* 测试控制器相关接口
* Class Personnel
* @package app\api\controller\apiController
*/
class Test extends BaseApiService
{
//测试控制器Demo
public function index(Request $request)
{
$personnel_id = $request->param('personnel_id', '');//员工人力资源表id(两个参数2选1)
$customer_resources_id = $request->param('customer_resources_id', '');//学生资源表id(两个参数2选1)
if (empty($personnel_id) && empty($customer_resources_id)) {
return fail('缺少参数');
}
$where = [
'personnel_id' => $personnel_id,
'customer_resources_id' => $customer_resources_id,
];
$res = (new ChatService())->getChatFriendsPage($where);
return success($res);
}
}

53
niucloud/app/api/controller/apiController/UserFeedback.php

@ -0,0 +1,53 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\api\controller\apiController;
use app\Request;
use core\base\BaseApiService;
/**
* 学生用户反馈控制器相关接口
* Class Personnel
* @package app\api\controller\apiController
*/
class UserFeedback extends BaseApiService
{
//学生用户反馈-添加
public function add(Request $request)
{
// 接受参数
$user_id = $request->post('user_id', ''); // 用户ID(对应school_customer_resources表id)
$feedback_text = $request->post('feedback_text', ''); // 反馈内容
$attachment_url = $request->post('attachment_url', null); // 附件URL(OSS对象存储),允许为空
//验证必填
if (empty($user_id) || empty($feedback_text)) {
return fail('必填参数不能为空');
}
$data = [
'user_id' => $user_id,
'feedback_text' => $feedback_text,
'attachment_url' => $attachment_url ?? null,
];
$add = \app\model\user_feedback\UserFeedback::create($data);
if (!$add) {
return fail('添加失败');
}
return success([]);
}
}

12
niucloud/app/api/controller/upload/Upload.php

@ -33,7 +33,17 @@ class Upload extends BaseApiController
['file', 'file'],
]);
$upload_service = new UploadService();
return success($upload_service->image($data['file'],$extraData));
$res = $upload_service->image($data['file'],$extraData);
$res['ext'] = ''; // 初始化文件扩展名
$res['name'] = ''; // 初始化文件名称
if (isset($res['url'])) {
$res['ext'] = pathinfo($res['url'], PATHINFO_EXTENSION);
$res['name'] = basename($res['url']);
}
return success($res);
}
/**

34
niucloud/app/api/route/route.php

@ -318,10 +318,11 @@ Route::group(function () {
//↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑-----员工端相关-----↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
//↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓-----用户端相关-----↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
//↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓-----学生用户端相关-----↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
//无需token验证的
Route::group(function () {
// Route::post('personnelLogin', 'login.Login/personnelLogin');
//学生登录
Route::post('customerResourcesAuth/login', 'apiController.CustomerResourcesAuth/login');
})->middleware(ApiChannel::class)
->middleware(ApiCheckToken::class)
->middleware(ApiLog::class);
@ -329,12 +330,37 @@ Route::group(function () {
//需要token验证的
Route::group(function () {
// Route::get('personnel/info', 'apiController.Personnel/info');
//员工端-上传图片
Route::post('memberUploadImage', 'upload.Upload/image');
//学生详情
Route::get('customerResourcesAuth/info', 'apiController.CustomerResourcesAuth/info');
//学生详情-修改
Route::post('customerResourcesAuth/edit', 'apiController.CustomerResourcesAuth/edit');
//学生用户反馈-添加
Route::post('userFeedback/add', 'apiController.UserFeedback/add');
//学生端-用户聊天-好友关系列表
Route::get('xy/chat/getChatFriendsList', 'apiController.Chat/getChatFriendsList');
//学生端-用户聊天-好友关系详情
Route::get('xy/chat/getChatFriendsInfo', 'apiController.Chat/getChatFriendsInfo');
//学生端-用户聊天-获取聊天记录
Route::get('xy/chat/getChatMessagesList', 'apiController.Chat/getChatMessagesList');
//学生端-用户聊天-发送聊天内容
Route::post('xy/chat/sendChatMessages', 'apiController.Chat/sendChatMessages');
//学生端-体测报告-列表
Route::get('xy/physicalTest', 'apiController.PhysicalTest/index');
//学生端-体测报告-详情
Route::get('xy/physicalTest/info', 'apiController.PhysicalTest/info');
})->middleware(ApiChannel::class)
->middleware(ApiCheckToken::class, true)
->middleware(ApiLog::class);
//↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑-----用户端相关-----↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
//↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑-----学生用户端相关-----↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
//加载插件路由

19
niucloud/app/common.php

@ -1214,3 +1214,22 @@ function calculateChildHealthScore($age, $gender, $height, $weight) {
// 四舍五入取整
return round($total_score);
}
function get_dict_value($key,$value){
$dict = new \app\model\dict\Dict();
$field = 'id,name,key,dictionary,memo,create_time,update_time';
$info = $dict->field($field)->where([['key', '=', $key]])->findOrEmpty()->toArray();
if($info['dictionary'] == null)
{
$info['dictionary'] = [];
}
$map = [];
foreach ($info['dictionary'] as $item) {
$map[$item['value']] = $item['name'];
}
return $map[$value];
}

7
niucloud/app/model/customer_resources/CustomerResources.php

@ -89,6 +89,7 @@ class CustomerResources extends BaseModel
'updated_at' => '更新时间',
'deleted_at' => '逻辑删除时间',
'status' => '客户状态',
'member_label' => '资源标签'
];
public function orderTable()
@ -162,6 +163,12 @@ class CustomerResources extends BaseModel
return $this->hasMany(ResourceSharing::class, 'resource_id', 'id');
}
//一对一关联"用户账号登陆表"
public function memberHasOne()
{
return $this->hasOne(Member::class, 'member_id', 'member_id');
}

7
niucloud/app/model/physical_test/PhysicalTest.php

@ -81,6 +81,13 @@ class PhysicalTest extends BaseModel
return $this->hasOne(CustomerResources::class, 'id', 'resource_id')->joinType('left')->withField('name,id')->bind(['resource_id_name'=>'name']);
}
//获取学生资源一对一
public function customerResourcesHasOne(){
return $this->hasOne(CustomerResources::class, 'id', 'resource_id');
}
public function student(){
return $this->hasOne(Student::class, 'id', 'student_id')->joinType('left')->withField('name,id')->bind(['student_id_name'=>'name']);
}

156
niucloud/app/service/admin/customer_resources/CustomerResourcesService.php

@ -15,6 +15,8 @@ use app\model\campus_person_role\CampusPersonRole;
use app\model\course_schedule\CourseSchedule;
use app\model\customer_resource_changes\CustomerResourceChanges;
use app\model\customer_resources\CustomerResources;
use app\model\member\Member;
use app\model\member\MemberLabel;
use app\model\order_table\OrderTable;
use app\model\personnel\Personnel;
use app\model\campus\Campus;
@ -22,6 +24,7 @@ use app\model\campus\Campus;
use app\model\resource_sharing\ResourceSharing;
use app\model\six_speed\SixSpeed;
use app\model\six_speed_modification_log\SixSpeedModificationLog;
use app\model\student_courses\StudentCourses;
use app\service\admin\member\MemberLabelService;
use core\base\BaseAdminService;
@ -99,9 +102,17 @@ class CustomerResourcesService extends BaseAdminService
$sixSpeed = new SixSpeed();
$data = $sixSpeed->where(['resource_id' => $item['id']])->findOrEmpty()->toArray();
$item['six'] = $data;
$member = new Member();
$member_info = $member->where(['member_id' => $item['member_id']])->findOrEmpty()->toArray();
$item['member_info'] = $member_info;
});
}
/**
* 获取客户资源信息
* @param int $id
@ -419,4 +430,149 @@ class CustomerResourcesService extends BaseAdminService
return $all;
}
public function log_list(array $data = [])
{
$customer_resource_changes = new CustomerResourceChanges();
$where = [];
if ($data['customer_resource_id']) {
$where[] = ['a.customer_resource_id', '=', $data['customer_resource_id']];
}
$search_model = $customer_resource_changes
->alias("a")
->join(['school_personnel' => 'b'], 'a.operator_id = b.id', 'left')
->where($where)
->field("a.*,b.name")
->order("a.id asc");
return $this->pageQuery($search_model, function ($item, $key) {
$fieldZhArr = CustomerResources::FieldZh;
$modified_fields = json_decode($item['modified_fields'], true);
$type = [];
foreach ($modified_fields as $key => $value) {
$type[] = $fieldZhArr[$value];
}
$item['type'] = implode("<br>",$type);
$old_values = json_decode($item['old_values'], true);
$new_values = json_decode($item['new_values'], true);
$values = [];
foreach ($old_values as $key => $value) {
$old_value = $this->fields($key,$value);
$new_value = $this->fields($key,$new_values[$key]);
$values[] = $old_value.'->'.$new_value;
}
$item['values'] = implode("<br>",$values);
});
}
public function student_courses(array $data = [])
{
$studentCourses = new StudentCourses();
$where = [];
if ($data['customer_resource_id']) {
$where[] = ['b.user_id', '=', $data['customer_resource_id']];
}
$search_model = $studentCourses
->alias("a")
->join(['school_student' => 'b'], 'a.student_id = b.id', 'left')
->join(['school_course' => 'c'], 'a.course_id = c.id', 'left')
->where($where)
->field("a.*,c.course_name")
->order("a.id desc");
return $this->pageQuery($search_model, function ($item, $key) {
$item['total'] = $item['total_hours'] + $item['gift_hours'];
$item['used'] = $item['use_total_hours'] + $item['use_gift_hours'];
$now = date('Y-m-d'); // 当前日期
if ($now < $item['start_date']) {
$item['status'] = '未进行';
} elseif ($now > $item['end_date']) {
$item['status'] = '已结束';
} else {
$item['status'] = '进行中';
}
});
}
public function order_table(array $data = [])
{
$orderTable = new OrderTable();
$where = [];
if ($data['customer_resource_id']) {
$where[] = ['a.resource_id', '=', $data['customer_resource_id']];
}
$search_model = $orderTable
->alias("a")
->join(['school_course' => 'b'], 'a.course_id = b.id', 'left')
->where($where)
->field("a.*,b.course_name")
->order("a.id desc");
return $this->pageQuery($search_model, function ($item, $key) {
$arr = ['cash' => '现金支付','scan_code' => '扫码支付','subscription' => '订阅支付'];
$item['type'] = $arr[$item['payment_type']];
$item['order_status'] = $item['order_status'] == 'pending' ? '待支付' : '已支付';
});
}
public function fields($filed,$value){
if(!$value){
return '空';
}
$campus = new Campus();
$member_label = new MemberLabel();
switch ($filed) {
case 'initial_intent':
return get_dict_value('preliminarycustomerintention',$value);
break;
case 'source':
return get_dict_value('source',$value);
break;
case 'purchasing_power':
return get_dict_value('customer_purchasing_power',$value);
break;
case 'cognitive_idea':
return get_dict_value('cognitive_concept',$value);
break;
case 'source_channel':
return get_dict_value('SourceChannel',$value);
break;
case 'status':
return get_dict_value('kh_status',$value);
break;
case 'member_label':
$label_name = $member_label->where('label_id','in',$value)->column('label_name');
return implode("-",$label_name);
break;
case 'campus':
return $campus->where(['id' => $value])->value("campus_name");
break;
default:
return $value;
}
}
}

24
niucloud/app/service/api/apiService/CommonService.php

@ -54,6 +54,15 @@ class CommonService extends BaseApiService
*/
public function forgetPassword($phone, $new_password, $user_type){
if($user_type == 'personnel'){
$data = SysUser::where('username', $phone)->find();
if (!$data){
$res = [
'code' => 0,
'msg' => '用户不存在',
'data' => []
];
return $res;
}
//重置员工(销售/教师)密码
$update = SysUser::where('username', $phone)->update([
'password' => create_password($new_password),//创建密码
@ -74,6 +83,15 @@ class CommonService extends BaseApiService
}
return $res;
}else{
$data = Member::where('username', $phone)->find();
if (!$data){
$res = [
'code' => 0,
'msg' => '用户不存在',
'data' => []
];
return $res;
}
//重置用户(学生)密码
$update = Member::where('username', $phone)->update([
'password' => create_password($new_password),//创建密码
@ -125,12 +143,18 @@ class CommonService extends BaseApiService
}
return [
// 返回发生更改的字段名数组
'changed_fields' => $changedFields,
// 返回旧数据中的更改字段及其值
'old_values' => $oldChanges,
// 返回新数据中的更改字段及其值
'new_values' => $newChanges,
// 将 changed_fields 转换为 JSON 格式,保留中文字符
'changed_fields_json' => json_encode($changedFields, JSON_UNESCAPED_UNICODE),
// 将 old_changes 转换为 JSON 格式,保留中文字符
'old_values_json' => json_encode($oldChanges, JSON_UNESCAPED_UNICODE),
// 将 new_changes 转换为 JSON 格式,保留中文字符
'new_values_json' => json_encode($newChanges, JSON_UNESCAPED_UNICODE)
];
}

117
niucloud/app/service/api/apiService/CustomerResourcesService.php

@ -36,6 +36,37 @@ class CustomerResourcesService extends BaseApiService
parent::__construct();
}
//获取客户资源详情
public function getInfo(array $where,string $field = '*'){
$res = [
'code' => 0,
'msg' => '操作失败',
'data' => []
];
$model = new CustomerResources();
if(!empty($where['member_id'])){
$model = $model->where('member_id', $where['member_id']);
}
$data = $model->field($field)
->with([
'memberHasOne',
'resourceSharingHasMany'
])
->append([
'gender_name',
'initial_intent_name'
])
->find();
if ($data){
$data = $data->toArray();
$res['code'] = 1;
$res['data'] = $data;
}else{
$res['msg'] = '暂无数据';
}
return $res;
}
//获取全部客户资源数据
public function getAll(array $where,string $field = '*')
{
@ -280,6 +311,92 @@ class CustomerResourcesService extends BaseApiService
}
}
//客户资源(学生个人资料)-编辑
public function editInfo(array $where, array $data)
{
$res = [
'code' => 0,
'msg' => '操作失败',
'data' => []
];
if (!$where) {
$res['msg'] = '查询条件不能为空';
return $res;
}
$customer_resources_data = [
'name' => $data['name'], // 姓名
'gender' => $data['gender'], // 性别(male:男, female:女)
'age' => $data['age'], // 年龄
'phone_number' => $data['phone_number'], // 手机号
];
$date = date('Y-m-d H:i:s');
$customer_resources_data['updated_at'] = $date;
//开启事物
Db::startTrans();
try {
$customer_resources = CustomerResources::where('member_id', $where['member_id'])->find();
if ($customer_resources) {
$customer_resources = $customer_resources->toArray();
}
$update_1 = CustomerResources::where('id', $customer_resources['id'])->update($customer_resources_data);//客户资源表
if (!$update_1) {
Db::rollback();
return $res;
}
//更新学生账户登录表
$member_data = [
'username' => $data['phone_number'],
'mobile' => $data['phone_number'],
'update_time' => time()
];
if (!empty($data['headimg'])) {
$member_data['headimg'] = $data['headimg'];
}
$update_member = Member::where('member_id', $where['member_id'])->update($member_data);
if (!$update_member) {
Db::rollback();
return $res;
}
//更近客户资源日志表
$compareData = (new CommonService)->compareData($customer_resources, $customer_resources_data);
if ($compareData['changed_fields']) {
$data = [
"customer_resource_id" => $customer_resources['id'],//客户资源的ID
"operator_id" => 0,//操作人的ID
"campus_id" => 0,//操作人校区的ID|如果这人有2校区就填0
"modified_fields" => $compareData['changed_fields_json'],//修改的哪些字段
"old_values" => $compareData['old_values_json'],//修改前的值
"new_values" => $compareData['new_values_json'],//修改后的值
];
$id = CustomerResourceChanges::insertGetId($data);
if (!$id) {
Db::rollback();
return $res;
}
}
Db::commit();
$res = [
'code' => 1,
'msg' => '操作成功'
];
return $res;
} catch (\Exception $exception) {
Db::rollback();
return $res;
}
}
//客户资源-获取客户资源修改记录列表
public function getCustomerResourceChangesEditLog(array $where)
{

115
niucloud/app/service/api/apiService/PhysicalTestService.php

@ -0,0 +1,115 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\service\api\apiService;
use app\model\campus\Campus;
use app\model\campus_person_role\CampusPersonRole;
use app\model\chat_friends\ChatFriends;
use app\model\physical_test\PhysicalTest;
use core\base\BaseApiService;
/**
* 体测报告-控制器服务层
* Class MemberService
* @package app\service\api\member
*/
class PhysicalTestService extends BaseApiService
{
public function __construct()
{
parent::__construct();
}
//查询列表
public function getList(array $where,string $field = '*')
{
$page_params = $this->getPageParam();//获取请求参数中的页码+分页数
$page = $page_params['page'];
$limit = $page_params['limit'];
$model = new PhysicalTest();
//判断用没有员工id
if (!empty($where['resource_id'])) {
$model = $model->where('resource_id', $where['resource_id']);
}
$data = $model
->field($field)
->order('id','desc')
->append([
'customerResources'
])
->with([
'customerResourcesHasOne'
])
->paginate([
'list_rows' => $limit,
'page' => $page,
])->toArray();
foreach ($data['data'] as &$v) {
$age = $v['customerResourcesHasOne']['age'];//年龄
$gender = $v['customerResourcesHasOne']['gender'] == 'female' ? 2:1 ;//性别( 1:男,2:女)
$height = $v['height'];//身高
$weight = $v['weight'];//体重
$v['calculateChildHealthScore'] = calculateChildHealthScore($age, $gender, $height, $weight);//综合评分
}
return $data;
}
//查询详情
public function getInfo(array $where,string $field = '*')
{
$model = new PhysicalTest();
//判断用没有体测报告id
if (!empty($where['id'])) {
$model = $model->where('id', $where['id']);
}
$data = $model
->field($field)
->append([
'customerResources'
])
->with([
'customerResourcesHasOne'
])
->find();
if ($data) {
$data = $data->toArray();
$age = $data['customerResourcesHasOne']['age'];//年龄
$gender = $data['customerResourcesHasOne']['gender'] == 'female' ? 2 : 1;//性别( 1:男,2:女)
$height = $data['height'];//身高
$weight = $data['weight'];//体重
$data['calculateChildHealthScore'] = calculateChildHealthScore($age, $gender, $height, $weight);//综合评分
$res = [
'code' => 1,
'msg' => '操作成功',
'data' => $data
];
return $res;
} else {
$res = [
'code' => 0,
'msg' => '暂无数据',
'data' => []
];
return $res;
}
}
}

95
niucloud/app/service/api/apiService/TestService.php

@ -0,0 +1,95 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\service\api\apiService;
use app\model\campus\Campus;
use app\model\campus_person_role\CampusPersonRole;
use app\model\chat_friends\ChatFriends;
use app\model\chat_messages\ChatMessages;
use app\model\dict\Dict;
use core\base\BaseApiService;
use think\facade\Db;
/**
* 测试-控制器服务层
* Class MemberService
* @package app\service\api\member
*/
class TestService extends BaseApiService
{
public function __construct()
{
parent::__construct();
}
//查询列表
public function getTestList(array $where)
{
$page_params = $this->getPageParam();//获取请求参数中的页码+分页数
$page = $page_params['page'];
$limit = $page_params['limit'];
$model = new ChatFriends();
//判断用没有员工id
if (!empty($where['personnel_id'])) {
$model = $model->where('personnel_id', $where['personnel_id']);
}
if (!empty($where['customer_resources_id'])) {
$model = $model->where('customer_resources_id', $where['customer_resources_id']);
}
$data = $model
->with([
'personnel',
'customer',
])
->paginate([
'list_rows' => $limit,
'page' => $page,
])->toArray();
return $data;
}
//查询详情
public function getTestInfo(array $where)
{
$model = new ChatFriends();
//判断用没有员工id
if (!empty($where['personnel_id'])) {
$model = $model->where('personnel_id', $where['personnel_id']);
}
if (!empty($where['customer_resources_id'])) {
$model = $model->where('customer_resources_id', $where['customer_resources_id']);
}
$data = $model->find();
if ($data) {
$data = $data->toArray();
$res = [
'code' => 1,
'msg' => '操作成功',
'data' => $data
];
return $res;
} else {
$res = [
'code' => 0,
'msg' => '暂无数据',
'data' => []
];
return $res;
}
}
}
Loading…
Cancel
Save