李双庆 11 months ago
parent
commit
62a3c86086
  1. 18
      api/agreement.js
  2. 49
      api/apiRoute.js
  3. 70
      api/common.js
  4. 171
      api/market.js
  5. 211
      api/member.js
  6. 6
      common/config.js
  7. 2
      common/util.js
  8. 32
      components/AQ/AQTabber.vue
  9. 8
      manifest.json
  10. 123
      pages.json
  11. 642
      pages/coach/class/info.vue
  12. 190
      pages/coach/class/list.vue
  13. 9
      pages/coach/course/info.vue
  14. 459
      pages/coach/course/info_list.vue
  15. 430
      pages/coach/course/list.vue
  16. 440
      pages/coach/home/index.vue
  17. 318
      pages/coach/job/add.vue
  18. 215
      pages/coach/job/list.vue
  19. 220
      pages/coach/my/arrival_statistics.vue
  20. 8
      pages/coach/my/due_soon.vue
  21. 64
      pages/coach/my/index.vue
  22. 245
      pages/coach/my/info.vue
  23. 497
      pages/coach/my/my_attendance.vue
  24. 112
      pages/coach/my/schooling_statistics.vue
  25. 331
      pages/coach/student/info.vue
  26. 41
      pages/coach/student/physical_examination.vue
  27. 152
      pages/coach/student/work_details.vue
  28. 129
      pages/common/article_info.vue
  29. 262
      pages/common/contract_list.vue
  30. 329
      pages/common/im_chat_info.vue
  31. 498
      pages/common/my_attendance.vue
  32. 262
      pages/common/my_message.vue
  33. 225
      pages/common/sys_msg_list.vue
  34. 1645
      pages/market/clue/add_clues.vue
  35. 713
      pages/market/clue/clue_info.vue
  36. 760
      pages/market/clue/index.vue
  37. 491
      pages/market/clue/new_task.vue
  38. 1279
      pages/market/clue/writing_followUp.vue
  39. 149
      pages/market/data/index.vue
  40. 226
      pages/market/index/index.vue
  41. 49
      pages/market/my/firm_info.vue
  42. 112
      pages/market/my/index.vue
  43. 245
      pages/market/my/info.vue
  44. 275
      pages/market/my/signed_client_list.vue
  45. 411
      pages/student/index/index.vue
  46. 220
      pages/student/index/job_list.vue
  47. 159
      pages/student/index/physical_examination.vue
  48. 65
      pages/student/index/work_details.vue
  49. 2
      pages/student/login/forgot.vue
  50. 324
      pages/student/login/login.vue
  51. 190
      pages/student/my/lesson_consumption.vue
  52. 49
      pages/student/my/my.vue
  53. 275
      pages/student/timetable/index.vue
  54. 194
      pages/student/timetable/info.vue
  55. 230
      pages/student/timetable/list.vue
  56. BIN
      static/images/common/fa_song.png
  57. BIN
      static/images/common/xi_tong_xiao_xi.png
  58. BIN
      static/images/common/yong_hu.png
  59. BIN
      static/images/index/zan_wu.png
  60. BIN
      static/images/tabbar/banji.png
  61. BIN
      static/images/tabbar/banjis.png
  62. 30
      uni_modules/uni-calendar/changelog.md
  63. 544
      uni_modules/uni-calendar/components/uni-calendar/calendar.js
  64. 12
      uni_modules/uni-calendar/components/uni-calendar/i18n/en.json
  65. 8
      uni_modules/uni-calendar/components/uni-calendar/i18n/index.js
  66. 12
      uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hans.json
  67. 12
      uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hant.json
  68. 187
      uni_modules/uni-calendar/components/uni-calendar/uni-calendar-item.vue
  69. 567
      uni_modules/uni-calendar/components/uni-calendar/uni-calendar.vue
  70. 360
      uni_modules/uni-calendar/components/uni-calendar/util.js
  71. 86
      uni_modules/uni-calendar/package.json
  72. 103
      uni_modules/uni-calendar/readme.md
  73. 42
      uni_modules/uni-icons/changelog.md
  74. 91
      uni_modules/uni-icons/components/uni-icons/uni-icons.uvue
  75. 110
      uni_modules/uni-icons/components/uni-icons/uni-icons.vue
  76. 664
      uni_modules/uni-icons/components/uni-icons/uniicons.css
  77. BIN
      uni_modules/uni-icons/components/uni-icons/uniicons.ttf
  78. 664
      uni_modules/uni-icons/components/uni-icons/uniicons_file.ts
  79. 649
      uni_modules/uni-icons/components/uni-icons/uniicons_file_vue.js
  80. 89
      uni_modules/uni-icons/package.json
  81. 8
      uni_modules/uni-icons/readme.md

18
api/agreement.js

@ -1,15 +1,11 @@
import http from '../common/axios.js'
//获取学员信息
function userAgreement(data) {
let url = '/agreement/'+data
return http.get(url,data).then(res => {
return res;
})
}
export default {
userAgreement,
//获取用户协议
userAgreement(data) {
let url = '/agreement/' + data
return http.get(url, data).then(res => {
return res;
})
}
}

49
api/apiRoute.js

@ -0,0 +1,49 @@
import http from '../common/axios.js'
//全部api接口
export default {
// getDemo(data = {}) {
// let url = '/member/member_edit'
// return http.get(url, data).then(res => {
// return res;
// })
// },
// postDemo(data = {}) {
// let url = '/member/member_edit'
// return http.post(url, data).then(res => {
// return res;
// })
// },
//公共接口相关
//教师/销售端登陆
personnelLogin(data = {}) {
let url = '/personnelLogin'
return http.post(url, data).then(res => {
return res;
})
},
//教师/销售端详情
getPersonnelInfo(data = {}) {
let url = '/personnel/info'
return http.get(url, data).then(res => {
return res;
})
},
//教练接口相关
//销售接口相关
//学生接口相关
}

70
api/common.js

@ -9,4 +9,74 @@ export default {
})
},
//获取字典数据
getDictionary(data) {
let url = `/member/dictionary/type/${data}`
return http.get(url,data).then(res => {
return res;
})
},
//获取联系人列表
getContactList(data) {
let url = `/member/contact_list`
return http.get(url,data).then(res => {
return res;
})
},
//获取消息列表
getContactMessage(data) {
let url = `/member/contact_message`
return http.get(url,data).then(res => {
return res;
})
},
//发送站内信
sendMessage(data) {
let url = `/member/send_message`
return http.get(url,data).then(res => {
return res;
})
},
//获取课程头日期
getDate(data) {
let url = '/member/get_date'
return http.get(url, data).then(res => {
return res;
})
},
//获取课表日历打点信息
getMonthDate(data) {
let url = `/member/get_month_date`
return http.get(url,data).then(res => {
return res;
})
},
//考勤列表 --分页
clockingList(data) {
let url = `/member/clocking_list`
return http.get(url, data).then(res => {
return res;
})
},
//考勤-请假
clockingRest(data) {
let url = `/member/clocking_rest`
return http.get(url, data).then(res => {
return res;
})
},
}

171
api/market.js

@ -0,0 +1,171 @@
import http from '../common/axios.js'
//销售相关接口
export default {
//获取销售人员详情
member(data = {}) {
let url = '/member/member'
return http.get(url, data).then(res => {
return res;
})
},
//修改销售人员详情
memberEdit(data = {}) {
let url = '/member/member_edit'
return http.post(url, data).then(res => {
return res;
})
},
//线索列表
salesList(data = {}) {
let url = '/member/sales_list'
return http.get(url, data).then(res => {
return res;
})
},
//转移跟进任务
createTask(data = {}) {
let url = '/member/create_task'
return http.post(url, data).then(res => {
return res;
})
},
//写新跟进
createFollow(data = {}) {
let url = '/member/create_follow'
return http.post(url, data).then(res => {
return res;
})
},
//小区列表
getCampusesList(data = {}) {
let url = '/member/get_campuses_list'
return http.get(url, data).then(res => {
return res;
})
},
//添加线索
setSales(data) {
let url = '/member/set_sales'
return http.post(url, data).then(res => {
return res;
})
},
//我的客户
myClient(data) {
let url = '/member/my_client'
return http.post(url, data).then(res => {
return res;
})
},
//客户详情
clientInfo(data={}) {
let url = '/member/client_info'
return http.get(url, data).then(res => {
return res;
})
},
//跟进记录
followList(data={}) {
let url = '/member/follow_list'
return http.get(url, data).then(res => {
return res;
})
},
//拨打电话记录列表
listCallUp(data={}) {
let url = '/member/list_call_up'
return http.get(url, data).then(res => {
return res;
})
},
//公海-领取客户
getSales(data = {}) {
let url = '/member/get_sales'
return http.get(url, data).then(res => {
return res;
})
},
//客户列表-- 查重
clientList(data = {}) {
let url = '/member/client_list'
return http.get(url, data).then(res => {
return res;
})
},
//数据页面
performance(data = {}) {
let url = '/member/performance'
return http.get(url, data).then(res => {
return res;
})
},
//已签客户列表
signClient(data = {}) {
let url = '/member/sign_client'
return http.get(url, data).then(res => {
return res;
})
},
//添加拨打电话记录
setCallUp(data = {}) {
let url = '/member/set_call_up'
return http.get(url, data).then(res => {
return res;
})
},
//销售端首页
xsIndex(data = {}) {
let url = '/member/xs_index'
return http.get(url, data).then(res => {
return res;
})
},
//销售端首页
selectCourseList(data = {}) {
let url = '/member/select_course_list'
return http.get(url, data).then(res => {
return res;
})
},
//合同列表
contractsList(data = {}) {
let url = '/member/contracts_list'
return http.get(url, data).then(res => {
return res;
})
},
}

211
api/member.js

@ -1,7 +1,17 @@
import http from '../common/axios.js'
export default {
//学员详情
//学员首页
memberIndex(data = {}) {
let url = '/member/index'
return http.get(url, data).then(res => {
return res;
})
},
//学员详情(个人中心-教练详情)
member(data) {
let url = '/member/member'
return http.get(url,data).then(res => {
@ -50,4 +60,203 @@ export default {
return res;
})
},
//课程详情
courseInfo(data) {
let url = '/member/course_info'
return http.get(url, data).then(res => {
return res;
})
},
//场地列表
venuesList(data) {
let url = '/member/venues_list'
return http.get(url, data).then(res => {
return res;
})
},
//作业列表
assignmentsList(data) {
let url = '/member/assignments_list'
return http.get(url, data).then(res => {
return res;
})
},
//学员-体测列表
surveyList(data) {
let url = '/member/survey_list'
return http.get(url, data).then(res => {
return res;
})
},
//提交作业
assignmentsSubmit(data) {
let url = '/member/assignments_submit'
return http.post(url, data).then(res => {
return res;
})
},
//作业详情
assignmentsInfo(data) {
let url = '/member/assignments_info'
return http.get(url, data).then(res => {
return res;
})
},
//学员发送请假申请
askForLeave(data) {
let url = '/member/ask_for_leave'
return http.post(url, data).then(res => {
return res;
})
},
//学员取消请假申请
delAskForLeave(data) {
let url = '/member/del_ask_for_leave'
return http.post(url, data).then(res => {
return res;
})
},
//获取课时列表
studentsSignList(data) {
let url = '/member/students_sign_list'
return http.post(url, data).then(res => {
return res;
})
},
//人员列表
staffList(data) {
let url = '/member/staff_list'
return http.get(url, data).then(res => {
return res;
})
},
//企业信息
getEnterpriseInformation(data = {}) {
let url = '/member/get_enterprise_information'
return http.get(url, data).then(res => {
return res;
})
},
//##################### 教练端 ######################
//教练端-首页
jlIndex(data = {}) {
let url = '/member/jl_index'
return http.get(url, data).then(res => {
return res;
})
},
//教练端-发布作业
jlPublishJob(data = {}) {
let url = '/member/publish_job'
return http.post(url, data).then(res => {
return res;
})
},
//教练端-获取班级列表
jlGetClassesList(data = {}) {
let url = '/member/get_classes_list'
return http.get(url, data).then(res => {
return res;
})
},
//教练端-获取班级列表
jlGetCoursesList(data = {}) {
let url = '/member/get_courses_list'
return http.get(url, data).then(res => {
return res;
})
},
//教练端-获取学员列表
jlGetStudentList(data = {}) {
let url = '/member/student_list'
return http.get(url, data).then(res => {
return res;
})
},
//教练端-获取班级详情
jlClassInfo(data = {}) {
let url = '/member/class_info'
return http.get(url, data).then(res => {
return res;
})
},
//教练端-获取班级列表
jlClassList(data = {}) {
let url = '/member/class_list'
return http.get(url, data).then(res => {
return res;
})
},
//教练端-获取学员详情
jlStudentsInfo(data = {}) {
let url = '/member/students_info'
return http.get(url, data).then(res => {
return res;
})
},
//教练端-评测详情
jlSurveyInfo(data = {}) {
let url = '/member/survey_info'
return http.get(url, data).then(res => {
return res;
})
},
//教练端-授课统计
jlSktj(data = {}) {
let url = '/member/sktj'
return http.get(url, data).then(res => {
return res;
})
},
//教练端-作业列表
jsGetAssignmentsList(data = {}) {
let url = '/member/get_assignments_list'
return http.get(url, data).then(res => {
return res;
})
},
}

6
common/config.js

@ -1,6 +1,6 @@
// 线上地址
// const Api_url='http://146.56.228.75:20021/api'
// const img_domian = 'http://146.56.228.75:20021/'
// 线上测试地址
// const Api_url='http://aaaaaaaa.hksywl.cn/api'
// const img_domian = 'http://aaaaaaaa.hksywl.cn/'
//本地测试地址
const Api_url='http://zhjw.cc/api'

2
common/util.js

@ -1,4 +1,5 @@
import {img_domian} from "./config";
import marketApi from '@/api/market.js';
function formatTime(time) {
if (typeof time !== 'number' || time < 0) {
@ -171,6 +172,7 @@ function formatToDateTime(dateTime, fmt = 'Y-m-d H:i:s') {
}
//跳转首页
function openHomeView() {
//获取用户类型缓存

32
components/AQ/AQTabber.vue

@ -10,16 +10,16 @@
<view class="but-style-top">
<view class="left" @click="writingFollowUp">
<image src="@/static/images/index/writing.png" class="drop-image-x"></image>
<view class="title-x">写作跟进</view>
<view class="title-x">添加跟进记录</view>
</view>
<view class="right" @click="newTask">
<image src="@/static/images/index/task.png" class="drop-image-x"></image>
<view class="title-x">新建任务</view>
<view class="title-x">转交跟进任务</view>
</view>
</view>
<view class="but-style-below" @click="addClues">
<image src="@/static/images/index/addto.png" class="drop-image-x"></image>
<view class="title-x">添加线索</view>
<view class="title-x">添加客户</view>
</view>
</view>
</view>
@ -44,7 +44,7 @@
},
created() {
console.log(123)
// console.log(123)
this.init()
},
@ -64,20 +64,20 @@
this.tabBar = [{
text: "首页",
urlPath: '/pages/coach/home/index', //
iconPath: "/static/images/tabbar/home.png",
selectedIconPath: "/static/images/tabbar/home_selected.png"
iconPath: "/static/images/tabbar/index.png",
selectedIconPath: "/static/images/tabbar/indexs.png"
},
{
text: "课表",
urlPath: '/pages/coach/course/list', //
iconPath: "/static/images/tabbar/my.png",
selectedIconPath: "/static/images/tabbar/my.png"
iconPath: "/static/images/tabbar/timetable.png",
selectedIconPath: "/static/images/tabbar/timetables.png"
},
{
text: "班级",
urlPath: '/pages/coach/class/list', //
iconPath: "/static/images/tabbar/my.png",
selectedIconPath: "/static/images/tabbar/my.png"
iconPath: "/static/images/tabbar/banji.png",
selectedIconPath: "/static/images/tabbar/banjis.png"
},
{
text: "我的",
@ -124,7 +124,8 @@
]
break;
case "3": //
this.tabBar = [{
this.tabBar = [
{
text: "首页",
urlPath: '/pages/student/index/index', //
iconPath: "/static/images/tabbar/index.png",
@ -145,8 +146,9 @@
]
break;
}
// console.log(111,this.tabBar)
},
openView(e) {
async openView(e) {
console.log('点击跳转', e)
if (e.text != '') {
//tabBar
@ -162,19 +164,19 @@
closePopup(type) {
this.show = false
},
//
//
writingFollowUp(){
uni.navigateTo({
url: '/pages/market/clue/writing_followUp'
})
},
//
//
newTask(){
uni.navigateTo({
url: '/pages/market/clue/new_task'
})
},
//线
//
addClues(){
uni.navigateTo({
url: '/pages/market/clue/add_clues'

8
manifest.json

@ -1,6 +1,6 @@
{
"name" : "用药提醒",
"appid" : "__UNI__86A3E16",
"name" : "智慧教务",
"appid" : "__UNI__530CC7A",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
@ -62,7 +62,7 @@
"quickapp" : {},
/* */
"mp-weixin" : {
"appid" : "wx42762c713f7bfa2e",
"appid" : "wx675f2696abf932c5",
"setting" : {
"urlCheck" : false,
"minified" : true,
@ -74,7 +74,7 @@
"desc" : "你的位置信息将用于小程序位置接口的效果展示"
}
},
"requiredPrivateInfos" : [ "getFuzzyLocation" ]
"requiredPrivateInfos" : [ "getLocation", "chooseLocation" ]
},
"mp-alipay" : {
"usingComponents" : true

123
pages.json

@ -69,7 +69,7 @@
"navigationBarTitleText": "课表详情",
"navigationStyle": "default",
"navigationBarBackgroundColor": "#292929",
"navigationBarTextStyle": "black"
"navigationBarTextStyle": "white"
}
},
{
@ -90,15 +90,6 @@
"navigationBarTextStyle": "black"
}
},
{
"path" : "pages/common/privacy_agreement",
"style": {
"navigationBarTitleText": "隐私协议",
"navigationStyle": "default",
"navigationBarBackgroundColor": "#fff",
"navigationBarTextStyle": "black"
}
},
{
"path" : "pages/student/my/update_pass",
"style": {
@ -108,15 +99,6 @@
"navigationBarTextStyle": "black"
}
},
{
"path" : "pages/common/feedback",
"style": {
"navigationBarTitleText": "意见反馈",
"navigationStyle": "default",
"navigationBarBackgroundColor": "#292929",
"navigationBarTextStyle": "white"
}
},
{
"path" : "pages/student/my/lesson_consumption",
"style": {
@ -158,6 +140,83 @@
{
"path" : "pages/common/privacy_agreement",
"style": {
"navigationBarTitleText": "隐私协议",
"navigationStyle": "default",
"navigationBarBackgroundColor": "#fff",
"navigationBarTextStyle": "black"
}
},
{
"path" : "pages/common/my_message",
"style": {
"navigationBarTitleText": "我的消息",
"navigationStyle": "default",
"navigationBarBackgroundColor": "#292929",
"navigationBarTextStyle": "white"
}
},
{
"path" : "pages/common/im_chat_info",
"style": {
"navigationBarTitleText": "",
"navigationStyle": "default",
"navigationBarBackgroundColor": "#292929",
"navigationBarTextStyle": "white"
}
},
{
"path" : "pages/common/sys_msg_list",
"style": {
"navigationBarTitleText": "系统消息",
"navigationStyle": "default",
"navigationBarBackgroundColor": "#292929",
"navigationBarTextStyle": "white"
}
},
{
"path" : "pages/common/article_info",
"style": {
"navigationBarTitleText": "文章详情",
"navigationStyle": "default",
"navigationBarBackgroundColor": "#292929",
"navigationBarTextStyle": "white"
}
},
{
"path" : "pages/common/feedback",
"style": {
"navigationBarTitleText": "意见反馈",
"navigationStyle": "default",
"navigationBarBackgroundColor": "#292929",
"navigationBarTextStyle": "white"
}
},
{
"path" : "pages/common/contract_list",
"style": {
"navigationBarTitleText": "合同列表",
"navigationStyle": "default",
"navigationBarBackgroundColor": "#292929",
"navigationBarTextStyle": "white"
}
},
{
"path": "pages/common/my_attendance",
"style": {
"navigationBarTitleText": "我的考勤",
"navigationStyle": "default",
"navigationBarBackgroundColor": "#292929",
"navigationBarTextStyle": "white"
}
},
{
@ -196,6 +255,15 @@
"navigationBarTextStyle": "black"
}
},
{
"path": "pages/coach/course/info_list",
"style": {
"navigationBarTitleText": "课时详情",
"navigationStyle": "default",
"navigationBarBackgroundColor": "#292929",
"navigationBarTextStyle": "white"
}
},
{
"path": "pages/coach/course/info",
"style": {
@ -262,7 +330,7 @@
{
"path": "pages/coach/my/arrival_statistics",
"style": {
"navigationBarTitleText": "到统计",
"navigationBarTitleText": "到统计",
"navigationStyle": "default",
"navigationBarBackgroundColor": "#292929",
"navigationBarTextStyle": "white"
@ -322,7 +390,7 @@
{
"path": "pages/market/clue/writing_followUp",
"style": {
"navigationBarTitleText": "写新跟进",
"navigationBarTitleText": "添加跟进",
"navigationStyle": "default",
"navigationBarBackgroundColor": "#fff",
"navigationBarTextStyle": "black"
@ -331,7 +399,7 @@
{
"path": "pages/market/clue/new_task",
"style": {
"navigationBarTitleText": "新建任务",
"navigationBarTitleText": "转交跟进任务",
"navigationStyle": "default",
"navigationBarBackgroundColor": "#fff",
"navigationBarTextStyle": "black"
@ -340,7 +408,7 @@
{
"path": "pages/market/clue/add_clues",
"style": {
"navigationBarTitleText": "添加线索",
"navigationBarTitleText": "添加客户",
"navigationStyle": "default",
"navigationBarBackgroundColor": "#fff",
"navigationBarTextStyle": "black"
@ -382,6 +450,15 @@
"navigationBarTextStyle": "black"
}
},
{
"path": "pages/market/my/signed_client_list",
"style": {
"navigationBarTitleText": "已签客户",
"navigationStyle": "default",
"navigationBarBackgroundColor": "#292929",
"navigationBarTextStyle": "white"
}
},
{
"path": "pages/market/my/info",
"style": {

642
pages/coach/class/info.vue

@ -2,70 +2,71 @@
<template>
<view class="main_box">
<!--自定义导航栏-->
<view class="navbar_section">
<view class="title">班级详情</view>
</view>
<!-- <view class="navbar_section">-->
<!-- <view class="title">班级详情</view>-->
<!-- </view>-->
<view class="main_section">
<view class="section_1">
<view class="left">
<image class="pic" src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<view class="name">包皮子</view>
</view>
<!-- <view class="left">-->
<!-- <image class="pic" src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>-->
<!-- <view class="name">包皮子</view>-->
<!-- </view>-->
<view class="right">
<view class="item">
班级少年班
班级{{classInfo.name}}
</view>
<view class="item">
地点XXXX体育馆 302
地点{{classInfo.address}}
</view>
<view class="item">
课程篮球少儿课
</view>
<!-- <view class="item">-->
<!-- 课程篮球少儿课-->
<!-- </view>-->
<view class="item">
人数30
人数{{classInfo.max_students}}
</view>
<view class="item">
时间2020.05:25 15:30 - 17:30
</view>
</view>
</view>
<view class="section_2">
<view class="title_box">
<view>最近课程</view>
</view>
<view class="tag_list">
<view class="item" @click="openViewCourseInfo({id:1})">
<view class="title">
篮球少儿课
</view>
<view>
2020.05.30 15:30 - 17:30
</view>
</view>
<view class="item" @click="openViewCourseInfo({id:2})">
<view class="title">
篮球少儿课
</view>
<view>
2020.05.30 15:30 - 17:30
</view>
时间{{classInfo.start_date}} - {{classInfo.end_date}}
</view>
</view>
</view>
<!-- <view class="section_2">-->
<!-- <view class="title_box">-->
<!-- <view>最近课程</view>-->
<!-- </view>-->
<!-- <view class="tag_list">-->
<!-- <view class="item" @click="openViewCourseInfo({id:1})">-->
<!-- <view class="title">-->
<!-- 篮球少儿课-->
<!-- </view>-->
<!-- <view>-->
<!-- 2020.05.30 15:30 - 17:30-->
<!-- </view>-->
<!-- </view>-->
<!-- <view class="item" @click="openViewCourseInfo({id:2})">-->
<!-- <view class="title">-->
<!-- 篮球少儿课-->
<!-- </view>-->
<!-- <view>-->
<!-- 2020.05.30 15:30 - 17:30-->
<!-- </view>-->
<!-- </view>-->
<!-- </view>-->
<!-- </view>-->
<view class="section_3">
<view class="btn_box">
<view :class="['btn', tabType=='1'?'select':'']" @click="tabChange(1)">
班级成员(30)
班级成员
</view>
<view :class="['btn', tabType=='2'?'select':'']" @click="tabChange(2)">
作业任务
课程计划
</view>
</view>
</view>
@ -73,310 +74,102 @@
<!-- 班级成员列表-->
<view class="section_4" v-if="tabType=='1'">
<view class="ul">
<view class="li" @click="openViewStudentInfo({id:1})">
<view class="left">
<view class="box_1">
<image class="pic" src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<view class="tag_box">
即将到期
</view>
</view>
<view class="box_2">
<view class="name">黄明明</view>
<view class="date">课程截止时间2020.05:25</view>
</view>
</view>
<view class="right">
<view class="item">
<view>24</view>
<view>已上课时</view>
</view>
<view class="item">
<view>24</view>
<view>剩余课时</view>
</view>
</view>
</view>
<view class="li" @click="openViewStudentInfo({id:1})">
<view
class="li"
v-for="(v,k) in classMemberList"
:key="k"
@click="openViewStudentInfo(v)"
>
<view class="left">
<view class="box_1">
<image class="pic" src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<view class="tag_box">
<image class="pic" :src="$util.img(v.header)"></image>
<view class="tag_box" v-if="v.expire">
即将到期
</view>
</view>
<view class="box_2">
<view class="name">黄明明</view>
<view class="date">课程截止时间2020.05:25</view>
<view class="name">{{ v.name }}</view>
<view class="date">课程截止时间{{ $util.formatToDateTime(v.expire_time, 'Y-m-d') }}</view>
</view>
</view>
<view class="right">
<view class="item">
<view>24</view>
<view>{{ v.have_study_time }}</view>
<view>已上课时</view>
</view>
<view class="item">
<view>24</view>
<view>{{ v.end_study_time }}</view>
<view>剩余课时</view>
</view>
</view>
</view>
<view class="li" @click="openViewStudentInfo({id:1})">
<view class="left">
<view class="box_1">
<image class="pic" src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<view class="tag_box">
即将到期
</view>
</view>
<view class="box_2">
<view class="name">黄明明</view>
<view class="date">课程截止时间2020.05:25</view>
</view>
</view>
<!--课程计划-->
<scroll-view
v-if="tabType=='2'"
class="section_5"
scroll-y="true"
:lower-threshold="lowerThreshold"
@scrolltolower="loadMoreData"
style="height: 65vh;"
>
<view class="ul">
<view
class="li"
v-for="(v,k) in courseList"
:key="k"
@click="openViewCourseInfo(v)"
>
<view class="top_box">
<view class="title">
课程{{v.courses_name}}
</view>
<view class="title">
时间{{v.date}}
</view>
<view class="title">
地点{{v.address}}
</view>
</view>
<view class="right">
<view class="item">
<view>24</view>
<view>已上课时</view>
</view>
<view class="bottom_box">
<view class="item">
<view>24</view>
<view>剩余课时</view>
</view>
</view>
</view>
<view class="li" @click="openViewStudentInfo({id:1})">
<view class="left">
<view class="box_1">
<image class="pic" src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<view class="tag_box">
即将到期
<view class="left">应到学员{{v.max_students}}</view>
<view class="right">
查看
<fui-icon size="35" color="#fff" name="arrowright"></fui-icon>
</view>
</view>
<view class="box_2">
<view class="name">黄明明</view>
<view class="date">课程截止时间2020.05:25</view>
</view>
</view>
<view class="right">
<view class="item">
<view>24</view>
<view>已上课时</view>
</view>
<view class="item">
<view>24</view>
<view>剩余课时</view>
</view>
</view>
</view>
<view class="li" @click="openViewStudentInfo({id:1})">
<view class="left">
<view class="box_1">
<image class="pic" src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<view class="tag_box">
即将到期
<view class="left">已签到学生{{v.has_sign_count}}/{{v.max_students}}</view>
<view class="right">
查看
<fui-icon size="35" color="#fff" name="arrowright"></fui-icon>
</view>
</view>
<view class="box_2">
<view class="name">黄明明</view>
<view class="date">课程截止时间2020.05:25</view>
</view>
</view>
<view class="right">
<view class="item">
<view>24</view>
<view>已上课时</view>
</view>
<view class="item">
<view>24</view>
<view>剩余课时</view>
</view>
</view>
</view>
<view class="li" @click="openViewStudentInfo({id:1})">
<view class="left">
<view class="box_1">
<image class="pic" src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<!-- <view class="tag_box">-->
<!-- 即将到期-->
<!-- <view class="item">-->
<!-- <view class="left">作业完成率80%</view>-->
<!-- <view class="right">-->
<!-- 查看-->
<!-- <fui-icon size="35" color="#fff" name="arrowright"></fui-icon>-->
<!-- </view>-->
</view>
<view class="box_2">
<view class="name">黄明明</view>
<view class="date">课程截止时间2020.05:25</view>
</view>
<!-- </view>-->
</view>
<view class="right">
<view class="item">
<view>24</view>
<view>已上课时</view>
</view>
<view class="item">
<view>24</view>
<view>剩余课时</view>
</view>
</view>
</view>
</view>
</view>
<!--作业列表-->
<view class="section_5" v-if="tabType=='2'">
<view class="ul">
<view class="li">
<view class="left">
<view class="box_1">
<fui-circle
:percent="75"
:width="140"
:show="false"
color="#FFB703"
background="#e9e9e9"
foreground="#58a3f7"
gradient="#58a3f7"
:strokeWidth="4"
:size="16"
>
<!-- 自定义显示内容 -->
<template #default>
<view class="custom_content">
<text>12</text>
<text>/</text>
<text>34</text>
</view>
</template>
</fui-circle>
</view>
<view class="box_2">
完成率80%
</view>
</view>
<view class="right">
<view class="box_1">
任务内容任务内容任务内容任务内容任务内容任务内容任务内容任务内容任务内容任务内容
</view>
<view class="box_2">
<view class="date">发布时间2021.05.25</view>
<view class="btn">详情</view>
</view>
</view>
</view>
<view class="li">
<view class="left">
<view class="box_1">
<fui-circle
:percent="75"
:width="140"
:show="false"
color="#FFB703"
background="#e9e9e9"
foreground="#58a3f7"
gradient="#58a3f7"
:strokeWidth="4"
:size="16"
>
<!-- 自定义显示内容 -->
<template #default>
<view class="custom_content">
<text>12</text>
<text>/</text>
<text>34</text>
</view>
</template>
</fui-circle>
</view>
<view class="box_2">
完成率80%
</view>
</view>
<view class="right">
<view class="box_1">
任务内容任务内容任务内容任务内容任务内容任务内容任务内容任务内容任务内容任务内容
</view>
<view class="box_2">
<view class="date">发布时间2021.05.25</view>
<view class="btn">详情</view>
</view>
</view>
</view>
<view class="li">
<view class="left">
<view class="box_1">
<fui-circle
:percent="75"
:width="140"
:show="false"
color="#FFB703"
background="#e9e9e9"
foreground="#58a3f7"
gradient="#58a3f7"
:strokeWidth="4"
:size="16"
>
<!-- 自定义显示内容 -->
<template #default>
<view class="custom_content">
<text>12</text>
<text>/</text>
<text>34</text>
</view>
</template>
</fui-circle>
</view>
<view class="box_2">
完成率80%
</view>
</view>
<view class="right">
<view class="box_1">
任务内容任务内容任务内容任务内容任务内容任务内容任务内容任务内容任务内容任务内容
</view>
<view class="box_2">
<view class="date">发布时间2021.05.25</view>
<view class="btn">详情</view>
</view>
<view class="tag" v-if="!(['1','2'].includes(String(v.status)))" style="background-color:#20CAAF;">
未开始
</view>
</view>
<view class="li">
<view class="left">
<view class="box_1">
<fui-circle
:percent="75"
:width="140"
:show="false"
color="#FFB703"
background="#e9e9e9"
foreground="#58a3f7"
gradient="#58a3f7"
:strokeWidth="4"
:size="16"
>
<!-- 自定义显示内容 -->
<template #default>
<view class="custom_content">
<text>12</text>
<text>/</text>
<text>34</text>
</view>
</template>
</fui-circle>
</view>
<view class="box_2">
完成率80%
</view>
<view class="tag" v-if="v.status == 1" style="background-color:#fad24e;">
上课中
</view>
<view class="right">
<view class="box_1">
任务内容任务内容任务内容任务内容任务内容任务内容任务内容任务内容任务内容任务内容
</view>
<view class="box_2">
<view class="date">发布时间2021.05.25</view>
<view class="btn">详情</view>
</view>
<view class="tag" v-if="v.status == 2" style="background-color:#e2e2e2;">
已结束
</view>
</view>
</view>
</view>
</scroll-view>
</view>
<!-- 底部导航-->
@ -385,7 +178,7 @@
</template>
<script>
// import user from '@/api/user.js';
import memberApi from '@/api/member.js';
import AQTabber from "@/components/AQ/AQTabber.vue"
@ -395,13 +188,125 @@ export default {
},
data() {
return {
formData:{},
tabType:'1',//1=,2=
class_id:'',//id
classInfo:{},//
classMemberList:{},//
tabType:'1',//1=,2=
loading: false,//
lowerThreshold: 100,//
isReachedBottom: false,//|true=|false=
//
filteredData: {
page: 1,//
limit: 10,//
total: 10,//
class_id: '',//id
},
courseList:[],//
}
},
onLoad() {
onLoad(options) {
this.class_id = options.class_id//id
},
onShow() {
this.init()
},
//
async onPullDownRefresh() {
//
await this.loadData()
await this.getCourseList()
},
methods: {
async init(){
// member/course_list//
// member/class_info//+
this.getClassInfo()//
await this.getCourseList()//
},
//-
async getClassInfo(){
let res = await memberApi.jlClassInfo({class_id:this.class_id})//
if(res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
console.log('获取班级列表',res.data)
this.classInfo = res.data
this.classMemberList = res.data.students_list
},
//()
loadMoreData() {
//
if (!this.isReachedBottom) {
this.isReachedBottom = true;//
this.getCourseList();
}
},
//
async loadData() {
this.isReachedBottom = false; // 便
this.filteredData.page = 1//
this.filteredData.limit = 10//
this.filteredData.total = 10//
},
//-
async getCourseList(){
let data = {...this.filteredData}
data.class_id = this.class_id
console.log(12123,this.courseList)
if(data.page == 1){
this.courseList = []
}
//
if (this.filteredData.page * this.filteredData.limit > this.filteredData.total || this.filteredData.limit > this.filteredData.total) {
this.loading = false
uni.showToast({
title: '暂无更多',
icon: 'none'
})
return
}
let res = await memberApi.courseList(data)
this.loading = false
this.isReachedBottom = false;
if (res.code != 1) {
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.courseList = this.courseList.concat(res.data.list.data)// 使 concat
this.filteredData.total = res.data.list.total
console.log('获取课程列表',this.courseList)
this.filteredData.page++
},
//tab
tabChange(tabType) {
this.tabType = tabType
@ -409,14 +314,16 @@ export default {
//
openViewCourseInfo(item){
let id= item.id
uni.navigateTo({
url: '/pages/coach/course/info'
url: `/pages/coach/course/info_list?id=${id}`
})
},
//
openViewStudentInfo(item){
let students_id = item.id
uni.navigateTo({
url: '/pages/coach/student/info'
url: `/pages/coach/student/info?students_id=${students_id}`
})
},
}
@ -436,7 +343,14 @@ export default {
align-items: center;
background: #292929;
.title{
padding: 20rpx 0;
padding: 40rpx 0rpx;
/* 小程序端样式 */
// #ifdef MP-WEIXIN
padding: 80rpx 0rpx;
// #endif
font-size: 30rpx;
color: #fff;
}
@ -508,23 +422,25 @@ export default {
justify-content: center;
align-items: center;
.btn_box{
border: 1px solid #d7d7d7;
border-radius: 25rpx;
width: 500rpx;
width: 698rpx;
border-radius: 8rpx;
background-color: rgba(22,132,252,1);
border: 1rpx solid rgba(22,132,252,1);
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
.btn{
width: 250rpx;
width: 100%;
height: 76rpx;
line-height: 76rpx;
text-align: center;
color: #7F7F7F;
color: #fff;
font-size: 26rpx;
}
.select{
color: #29D3B4;
color: #1684fc;
background-color: #fff;
}
}
@ -615,61 +531,61 @@ export default {
}
//
.section_5{
margin-top: 36rpx;
.ul{
display: flex;
flex-direction: column;
gap: 30rpx;
.li{
padding-top: 32rpx;
padding-bottom: 36rpx;
border-bottom: 2px solid #D7D7D7;
position: relative;
border-radius: 10rpx;
background-color: rgba(63,63,67,1);
border: 2rpx solid rgba(0,229,187,1);
padding: 20rpx 14rpx;
display: flex;
justify-content: space-between;
.left{
flex-direction: column;
.top_box{
display: flex;
flex-direction: column;
align-items: center;
gap: 12rpx;
.box_1{
.custom_content{
font-size: 32rpx;
color: #AAAAAA;
}
}
.box_2{
color: #AAAAAA;
font-size: 26rpx;
gap: 10rpx;
.title{
color: rgba(255,255,255,1);
font-size: 24rpx;
}
}
.right{
width: 510rpx;
.bottom_box{
padding-top: 10rpx;
margin-top: 20rpx;
border-top: 1px dashed #F2F2F2;
display: flex;
flex-direction: column;
gap: 16rpx;
.box_1{
color: #fff;
font-size: 28rpx;
}
.box_2{
gap: 10rpx;
.item{
display: flex;
align-items: center;
justify-content: space-between;
.date{
color: #AAAAAAFF;
font-size: 24rpx;
text-align: right;
}
.btn{
width: 120rpx;
height: 48rpx;
line-height: 40rpx;
border-radius: 8rpx;
background-color: #FFFFFF00;
color: #FAD04DFF;
font-size: 26rpx;
text-align: center;
border: 2rpx solid #FAD04DFF;
}
color: rgba(215,215,215,1);
font-size: 24rpx;
}
}
.tag{
position: absolute;
right: 0rpx;
top: 0rpx;
width: 110rpx;
height: 60rpx;
line-height: 58rpx;
border-radius: 0rpx 8rpx 0rpx 24rpx;
background-color: rgba(32,202,175,1);
color: rgba(255,255,255,1);
font-size: 24rpx;
text-align: center;
border: 0rpx solid rgba(121,121,121,1);
}
}
}
}

190
pages/coach/class/list.vue

@ -8,90 +8,47 @@
<view class="main_section">
<view class="section_1">
<fui-input class="input_item" borderTop placeholder="搜索"></fui-input>
<fui-input class="input_item" borderTop clearable="true" placeholder="搜索" v-model="filteredData.name" @confirm="search" @input="search"></fui-input>
</view>
<view class="section_2">
<view class="ul">
<view class="li" @click="openViewClassInfo({id:1})">
<scroll-view
class="ul"
scroll-y="true"
:lower-threshold="lowerThreshold"
@scrolltolower="loadMoreData"
style="height: 80vh;"
>
<view
class="li"
v-for="(v,k) in tableList"
:key="k"
@click="openViewClassInfo(v)"
>
<view class="left">
<image class="pic" src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<!-- <image class="pic" src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>-->
</view>
<view class="right">
<view class="box_1">
<view class="name">
少年班
{{v.name}}
</view>
<view class="btn_box">
<view>2人即将到期</view>
<view v-if="v.end_count">{{v.end_count}}人即将到期</view>
</view>
</view>
<view class="box_2">
<view class="user_list">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<view class="user_list" v-for="(v2,k2) in v.students_list" :key="k2">
<image
:src="$util.img(v2.header)"></image>
</view>
<view class="num">34</view>
<view class="num">{{v.students_count}}</view>
</view>
</view>
</view>
<view class="li" @click="openViewClassInfo({id:2})">
<view class="left">
<image class="pic" src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
</view>
<view class="right">
<view class="box_1">
<view class="name">
少年班
</view>
<view class="btn_box">
<view>2人即将到期</view>
</view>
</view>
<view class="box_2">
<view class="user_list">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
</view>
<view class="num">34</view>
</view>
</view>
</view>
<view class="li" @click="openViewClassInfo({id:3})">
<view class="left">
<image class="pic" src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
</view>
<view class="right">
<view class="box_1">
<view class="name">
少年班
</view>
<view class="btn_box">
<!-- <view>2人即将到期</view>-->
</view>
</view>
<view class="box_2">
<view class="user_list">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
</view>
<view class="num">34</view>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
</view>
<!-- 底部导航-->
@ -100,7 +57,7 @@
</template>
<script>
// import user from '@/api/user.js';
import memberApi from '@/api/member.js';
import AQTabber from "@/components/AQ/AQTabber.vue"
@ -110,16 +67,97 @@ export default {
},
data() {
return {
formData:{},
loading:false,//
lowerThreshold: 100,//
isReachedBottom: false,//|true=|false=
//
filteredData:{
page:1,//
limit:10,//
total:10,//
name: '',//
},
tableList:[],//
}
},
onLoad() {
onLoad(options) {},
onShow(){
this.init()//
},
methods: {
//
async init(){
this.getList()
},
//()
loadMoreData() {
//
if (!this.isReachedBottom) {
this.isReachedBottom = true;//
this.getList();
}
},
//
async resetFilteredData() {
this.isReachedBottom = false; // 便
this.filteredData.page = 1//
this.filteredData.limit = 10//
this.filteredData.total = 10//
},
//
async getList(){
this.loading = true
let data = {...this.filteredData}
console.log(111,(this.filteredData.page * this.filteredData.limit) ,(this.filteredData.total))
//
if(this.filteredData.page * this.filteredData.limit > this.filteredData.total){
this.loading = false
uni.showToast({
title: '暂无更多',
icon: 'none'
})
return
}
if(data.page == 1){
this.tableList = []
}
let res = await memberApi.jlClassList(data)
this.loading = false
this.isReachedBottom = false;
if (res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.tableList = this.tableList.concat(res.data.data); // 使 concat
console.log('列表',this.tableList)
this.filteredData.total = res.data.total
this.filteredData.page++
},
async search(e){
await this.resetFilteredData()
this.filteredData.name = e
await this.getList()
},
//
openViewClassInfo(item){
let class_id = item.class_id
uni.navigateTo({
url: '/pages/coach/class/info'
url: `/pages/coach/class/info?class_id=${class_id}`
})
},
}
@ -139,7 +177,14 @@ export default {
align-items: center;
background: #292929;
.title{
padding: 20rpx 0;
padding: 40rpx 0rpx;
/* 小程序端样式 */
// #ifdef MP-WEIXIN
padding: 80rpx 0rpx;
// #endif
font-size: 30rpx;
color: #fff;
}
@ -184,8 +229,9 @@ export default {
.ul{
display: flex;
flex-direction: column;
gap: 24rpx;
//gap: 24rpx;
.li{
margin-bottom: 24rpx;
background: #404045;
padding: 50rpx 36rpx 46rpx;
border-radius: 16rpx;

9
pages/coach/course/info.vue

@ -158,7 +158,14 @@ export default {
align-items: center;
background: #292929;
.title{
padding: 20rpx 0;
padding: 40rpx 0rpx;
/* 小程序端样式 */
// #ifdef MP-WEIXIN
padding: 80rpx 0rpx;
// #endif
font-size: 30rpx;
color: #fff;
}

459
pages/coach/course/info_list.vue

@ -0,0 +1,459 @@
<!--课程-详情列表-->
<template>
<view class="main_box">
<view class="main_section">
<view class="section_1">
<view class="title">班级{{courseInfo.classes_name}}</view>
<view class="title">时间{{courseInfo.date_time}} {{courseInfo.time_slot.replace(',', ' - ')}}</view>
<view class="title">地点{{courseInfo.address}}</view>
<view class="title">课程{{courseInfo.courses_name}}</view>
<view class="title">教练{{courseInfo.staff_name}}</view>
<view class="title">人数{{courseInfo.students_count}}</view>
<view
v-if="courseInfo.status == 1"
class="tag"
style="background-color: #FAD24E;">上课中
</view>
<view
v-if="courseInfo.status == 2"
class="tag"
style="background-color: #e2e2e2;">已结束
</view>
</view>
<view class="section_2">
<view :class="['table', tableType==1 ? 'select':'']" @click="switchTag(1)">签到情况</view>
<view :class="['table', tableType==2 ? 'select':'']" @click="switchTag(2)">作业情况</view>
</view>
<!--签到情况-->
<view class="section_3" v-if="tableType == 1">
<view class="tip_title" v-if="courseInfo.sign_list.length == 0">暂无数据</view>
<view class="item" v-for="(v,k) in courseInfo.sign_list" :key="k">
<view class="left">
<image class="pic" model="aspectFit" :src="$util.img(v.header)"></image>
<view class="box">
<view class="title">{{v.name}}</view>
<view class="title">课程截止时间{{v.create_time}}</view>
</view>
</view>
<view class="right">
<view class="tag" v-if="v.status == 2">请假</view>
</view>
</view>
</view>
<!--作业情况-->
<view class="section_4" v-if="tableType == 2">
<view class="item_box">
<!-- 待批改-->
<fui-collapse-item @change="changeCollapse(1)" open="true" isBorder="false" contentBg="#434544">
<view class="title_box">
<text>待批改{{courseInfo.assignments.dpg_list.length}}</text>
</view>
<template v-slot:content>
<view class="ul">
<view
v-for="(v,k) in courseInfo.assignments.dpg_list"
:key="k"
class="li"
@click="openViewWorkDetails(v)"
>
<view class="left">
<image class="pic" model="aspectFit" :src="$util.img(v.header)"></image>
<view class="box">
<view class="title">{{v.name}}</view>
<view class="title">课程截止时间{{v.tj_time}}</view>
</view>
</view>
<view class="right">
<view class="btn">查看并批改</view>
</view>
</view>
</view>
</template>
</fui-collapse-item>
</view>
<!-- 未提交-->
<view class="item_box">
<fui-collapse-item @change="changeCollapse(2)" isBorder="false" contentBg="#434544">
<view class="title_box">
<text>未提交{{courseInfo.assignments.wtj_list.length}}</text>
</view>
<template v-slot:content>
<view class="ul">
<view
class="li"
v-for="(v,k) in courseInfo.assignments.wtj_list"
:key="k"
@click="openViewWorkDetails(v)"
>
<view class="left">
<image class="pic" model="aspectFit" :src="$util.img(v.header)"></image>
<view class="box">
<view class="title">{{v.name}}</view>
<!-- <view class="title">课程截止时间2025-05-25</view>-->
</view>
</view>
<view class="right">
<!-- <view class="btn">查看并批改</view>-->
</view>
</view>
</view>
</template>
</fui-collapse-item>
</view>
<!-- 已提交-->
<view class="item_box">
<fui-collapse-item @change="changeCollapse(3)" isBorder="false" contentBg="#434544">
<view class="title_box">
<text>已提交{{courseInfo.assignments.ypg_list.length}}</text>
</view>
<template v-slot:content>
<view class="ul">
<view
class="li"
v-for="(v,k) in courseInfo.assignments.ypg_list"
:key="k"
@click="openViewWorkDetails(v)">
<view class="left">
<image class="pic" model="aspectFit" :src="$util.img(v.header)"></image>
<view class="box">
<view class="title">{{v.name}}</view>
<!-- <view class="title">课程截止时间2025-05-25</view>-->
</view>
</view>
<view class="right">
<!-- <view class="btn">查看并批改</view>-->
</view>
</view>
</view>
</template>
</fui-collapse-item>
</view>
</view>
</view>
</view>
</template>
<script>
import memberApi from '@/api/member.js';
import AQTabber from "@/components/AQ/AQTabber.vue"
export default {
components: {
AQTabber,
},
data() {
return {
course_id: '',//id
courseInfo: {
sign_list: [],//
assignments: {
dpg_list: [], //
wtj_list: [], //
ypg_list: [] //
},
},//
tableType: 1,//1=2=
}
},
onLoad(options) {
this.course_id = options.id
},
onShow(){
this.init()
},
methods: {
//
async init(){
this.getCourseInfo()
},
//-
async getCourseInfo(){
let res = await memberApi.courseInfo({id:this.course_id})
if(res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.courseInfo = res.data
console.log('课程详情',this.courseInfo)
},
//
switchTag(type) {
this.tableType = type
},
//
openViewCourseInfo(item){
uni.navigateTo({
url: '/pages/coach/course/info'
})
},
//
changeCollapse(type){},
//-
openViewWorkDetails(item){
let id = item.id
uni.navigateTo({
url: `/pages/coach/student/work_details?id=${id}`
})
},
}
}
</script>
<style lang="less" scoped>
.main_box{
background: #292929 ;
}
//
.navbar_section{
display: flex;
justify-content: center;
align-items: center;
background: #292929;
.title{
padding: 40rpx 0rpx;
/* 小程序端样式 */
// #ifdef MP-WEIXIN
padding: 80rpx 0rpx;
// #endif
font-size: 30rpx;
color: #fff;
}
}
.main_section{
min-height: 100vh;
background: #292929 100%;
padding: 30rpx 24rpx;
padding-top: 40rpx;
padding-bottom: 150rpx;
font-size: 24rpx;
color: #FFFFFF;
.section_1{
position: relative;
padding: 18rpx 34rpx 50rpx;
display: flex;
flex-direction: column;
gap: 15rpx;
color: #fff;
font-size: 24rpx;
background-color: #434544;
border-radius: 22rpx;
.tag{
position: absolute;
top: 0;
right: 0;
width: 110rpx;
height: 60rpx;
line-height: 55rpx;
border-radius: 0rpx 24rpx 0rpx 24rpx;
color: #fff;
font-size: 24rpx;
text-align: center;
}
}
.section_2{
margin-top: 44rpx;
color: #fff;
font-size: 30rpx;
display: flex;
justify-content: center;
align-items: center;
.table{
width: 50%;
height: 64rpx;
background-color: #1684FCFF;
line-height: 62rpx;
text-align: center;
}
.table:nth-child(1){
border-top-left-radius: 8rpx;
border-bottom-left-radius: 8rpx;
}
.table:nth-child(2){
border-top-right-radius: 8rpx;
border-bottom-right-radius: 8rpx;
}
.select{
background-color: #fff;
color: #1684FCFF;
}
}
.section_3{
margin-top: 44rpx;
min-height: 20vh;
padding: 30rpx 0;
border-radius: 22rpx;
background-color: #434544;
display: flex;
flex-direction: column;
//
.tip_title{
text-align: center;
font-size: 30rpx;
color: #FFFFFF;
}
.item{
border-top: 1px solid #D7D7D7;
padding: 20rpx 33rpx 20rpx 14rpx;
display: flex;
justify-content: space-between;
align-items: center;
.left{
width: 80%;
display: flex;
align-items: center;
gap: 26rpx;
.pic{
width: 92rpx;
height: 92rpx;
border-radius: 50%;
background-color: #797979FF;
}
.box{
display: flex;
flex-direction: column;
gap: 10rpx;
.title{
color: #fff;
font-size: 24rpx;
}
}
}
.right{
.tag{
width: 93rpx;
height: 93rpx;
border-radius: 50%;
line-height: 90rpx;
font-size: 26rpx;
background-color: rgba(254,250,131,0.62);
color: rgba(255,255,255,1);
text-align: center;
border: 0rpx solid rgba(254,250,131,0.62);
//45°
transform: rotate(-30deg);
}
}
}
.item:nth-child(1){
border-top: 0px;
}
}
.section_4{
margin-top: 44rpx;
padding: 30rpx 0;
border-radius: 22rpx;
background-color: #434544;
display: flex;
flex-direction: column;
.item_box{
margin-bottom: 30rpx;
padding-left: 24rpx;
padding-right: 32rpx;
font-size: 28rpx;
color: #fff;
background-color: #434544;
::v-deep .fui-collapse-item__title{
background-color: #434544 !important;
}
::v-deep .fui-collapse__border-color{
border-top: none !important; /* 取消上边框 */
background: #434544 !important;
}
.title_box{
}
.ul{
background-color: #434544;
.li{
background-color: #434544;
border-top: 1px solid #D7D7D7;
padding: 20rpx 33rpx 20rpx 14rpx;
display: flex;
justify-content: space-between;
align-items: center;
.left{
width: 80%;
display: flex;
align-items: center;
gap: 26rpx;
.pic{
width: 92rpx;
height: 92rpx;
border-radius: 50%;
background-color: #797979FF;
}
.box{
display: flex;
flex-direction: column;
gap: 10rpx;
.title{
color: #fff;
font-size: 24rpx;
}
}
}
.right{
.btn{
background-color: #a4adb3;
color: #fff;
width: 160rpx;
height: 60rpx;
line-height: 60rpx;
border-radius: 8rpx;
background-color: rgba(164,173,179,1);
color: rgba(255,255,255,1);
font-size: 24rpx;
text-align: center;
}
}
}
.li:nth-child(1){
border-top: none !important; /* 取消上边框 */
}
}
}
}
}
</style>

430
pages/coach/course/list.vue

@ -9,142 +9,83 @@
<view class="main_section">
<view class="section_1">
<view class="ul">
<view class="li">
<text>周日</text>
<text>14</text>
<text></text>
</view>
<view class="li">
<text>周一</text>
<text>14</text>
<text></text>
</view>
<view class="li">
<text>周二</text>
<text>14</text>
<text></text>
</view>
<view class="li">
<text>周日</text>
<text class="today"></text>
<text class=""></text>
</view>
<view class="li">
<text>周一</text>
<text>14</text>
<text class="select_plan"></text>
</view>
<view class="li">
<text>周二</text>
<text>14</text>
<text></text>
</view>
<view class="li">
<text>周二</text>
<text>14</text>
<text></text>
<view class="li" v-for="(v,k) in dateList" :key="k" @click="selectDate(v.date)">
<text>{{v.week}}</text>
<text :class="[filteredData.schedule_date == v.date ? 'today':'']">{{today == v.date ? '今':v.today}}</text>
<text :class="[v.status == 2 ?'select_plan':'']"></text>
</view>
</view>
<view class="btn" @click="show_calendar=true">
查看更多 <fui-icon name="arrowdown" color="#A4ADB3" size="45"></fui-icon>
</view>
</view>
<view class="section_2">
<view class="item_box">
<fui-dropdown-menu :size="28" selectedColor="#465CFF" :options="options_course" @click="clickCourse" @close="show_course=false" ref="ref_course">
<view class="fui-filter__item" @tap="filterTapCourse">
<text>{{course_name}}</text>
<view class="fui-filter__icon" :class="{'fui-icon__ani':show_course}">
<fui-icon name="turningdown" :size="32" color="#FFF"></fui-icon>
</view>
</view>
</fui-dropdown-menu>
</view>
<view class="item_box">
<fui-dropdown-menu :size="28" selectedColor="#465CFF" :options="options_classroom" @click="clickClassroom" @close="show_classroom=false" ref="ref_classroom">
<view class="fui-filter__item" @tap="filterTapClassroom">
<text>{{classroom_name}}</text>
<view class="fui-filter__icon" :class="{'fui-icon__ani':show_classroom}">
<fui-icon name="turningdown" :size="32" color="#FFF"></fui-icon>
</view>
</view>
</fui-dropdown-menu>
</view>
<!-- <view class="section_2">-->
<!-- <view class="item_box">-->
<!-- <fui-dropdown-menu :size="28" selectedColor="#465CFF" :options="options_course" @click="clickCourse" @close="show_course=false" ref="ref_course">-->
<!-- <view class="fui-filter__item" @tap="filterTapCourse">-->
<!-- <text>{{course_name}}</text>-->
<!-- <view class="fui-filter__icon" :class="{'fui-icon__ani':show_course}">-->
<!-- <fui-icon name="turningdown" :size="32" color="#FFF"></fui-icon>-->
<!-- </view>-->
<!-- </view>-->
<!-- </fui-dropdown-menu>-->
<!-- </view>-->
<!-- <view class="item_box">-->
<!-- <fui-dropdown-menu :size="28" selectedColor="#465CFF" :options="options_classroom" @click="clickClassroom" @close="show_classroom=false" ref="ref_classroom">-->
<!-- <view class="fui-filter__item" @tap="filterTapClassroom">-->
<!-- <text>{{classroom_name}}</text>-->
<!-- <view class="fui-filter__icon" :class="{'fui-icon__ani':show_classroom}">-->
<!-- <fui-icon name="turningdown" :size="32" color="#FFF"></fui-icon>-->
<!-- </view>-->
<!-- </view>-->
<!-- </fui-dropdown-menu>-->
<!-- </view>-->
<!-- </view>-->
</view>
<view class="section_3">
<scroll-view
class="section_3"
scroll-y="true"
:lower-threshold="lowerThreshold"
@scrolltolower="loadMoreData"
style="height: 100vh;"
>
<view class="ul">
<view class="li" @click="openViewCourseInfo({id:1})">
<view class="top_box">
<view class="center_box">
<view>班级少年班</view>
<view>时间2020-05-25 15:30 - 17:30</view>
<view>课室302
</view>
<view>课程篮球少儿课
</view>
</view>
<view class="right_box">
<view class="tag" style="background:#fad24e;">上课中</view>
<!-- <view class="tag" style="background:#1cd188;">待上课</view>-->
</view>
</view>
<view class="bottom_box">
<view class="hint">
已签到学生 (15/34)
</view>
<view class="list_box">
<view class="list">
<view class="itme">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
</view>
<view class="itme">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
</view>
<view class="itme">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
</view>
<view class="itme">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
</view>
</view>
<view class="btn">
详情
</view>
</view>
</view>
</view>
<view class="li" @click="openViewCourseInfo({id:2})">
<view
class="li"
v-for="(v,k) in tableList"
:key="k"
@click="openViewCourseInfoList(v)"
>
<view class="top_box">
<view class="center_box">
<view>班级少年班</view>
<view>时间2020-05-25 15:30 - 17:30</view>
<view>课室302
<view>班级{{v.classes_name}}</view>
<view>时间{{v.date}}</view>
<view>课室{{v.address}}
</view>
<view>课程篮球少儿课
<view>课程{{v.courses_name}}
</view>
</view>
<view class="right_box">
<view class="tag" style="background:#fad24e;">上课中</view>
<!-- v.status|1=未开始,2=进行中,3=已结束-->
<view class="tag" :style="{background: v.status == 1 ? '#1cd188' : v.status == 2 ? '#fad24e' : '#ff4d4f'}">
{{ v.status === 1 ? '未开始' : v.status === 2 ? '上课中' : '已结束' }}</view>
<!-- <view class="tag" style="background:#1cd188;">待上课</view>-->
</view>
</view>
<view class="bottom_box">
<view class="hint">
已签到学生 (15/34)
已签到学生 ({{v.sign_list.length }}/{{v.max_students.split(',').length }})
</view>
<view class="list_box">
<view class="list">
<view class="itme">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
</view>
<view class="itme">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
</view>
<view class="itme">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
</view>
<view class="itme">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<view class="itme" v-for="(item,index) in v.sign_list || 0" :key="index">
<image :src="$util.img(item.header)"></image>
</view>
</view>
<view class="btn">
@ -154,9 +95,24 @@
</view>
</view>
</view>
</view>
</scroll-view>
</view>
<!-- 日历选择-->
<fui-bottom-popup :show="show_calendar" @close="show_calendar=false">
<view class="fui-custom__wrap">
<uni-calendar
:insert="true"
:lunar="false"
:selected="calendarSelected"
:startDate="startDate"
:endDate="endDate"
@change="changeCalendar"
/>
</view>
</fui-bottom-popup>
<!-- 底部导航-->
<AQTabber/>
</view>
@ -164,6 +120,8 @@
<script>
// import user from '@/api/user.js';
import memberApi from '@/api/member.js';
import commonApi from '@/api/common.js';
import AQTabber from "@/components/AQ/AQTabber.vue"
@ -173,6 +131,21 @@ export default {
},
data() {
return {
loading: false,//
lowerThreshold: 100,//
isReachedBottom: false,//|true=|false=
//
filteredData: {
page: 1,//
limit: 10,//
total: 10,//
schedule_date: '',//
venue_id: '',//id
},
tableList: [],//
venuesInfo: {},//
formData:{},
//
@ -210,11 +183,42 @@ export default {
value: '2'
}
],
//
today: '',
dateList: [],//
//
show_calendar:false,//
startDate:'',//
endDate:'',//
calendarSelected: [],//
}
},
onLoad() {
},
onShow(){
this.init()//
},
//
async onPullDownRefresh() {
//
let schedule_date = this.filteredData.schedule_date
await this.loadData()
this.filteredData.schedule_date = schedule_date
await this.getList()
},
methods: {
//
async init(){
await this.getThisDate()
await this.getHeadDate()
await this.getList()
this.getDateRange()
this.setCalendarSelected()
},
//
clickCourse(e){
console.log(e)
@ -244,11 +248,184 @@ export default {
},
//
openViewCourseInfo(item){
openViewCourseInfoList(item){
let id = item.id
uni.navigateTo({
url: '/pages/coach/course/info'
url: `/pages/coach/course/info_list?id=${id}`
})
},
//
async getHeadDate() {
let res = await commonApi.getDate()
if (res.code != 1) {
//
uni.showToast({
title: res.msg,
icon: 'none',
})
return
}
this.dateList = []
res.data.forEach((v, k) => {
let today = v.date.split("-")[2]; // "09"
this.dateList.push({
date: v.date,
status: v.status,//1 2
week: v.week,
today: today,
})
})
console.log('xxx', res)
},
//
async getThisDate() {
let date = new Date();
let year = date.getFullYear();
let month = String(date.getMonth() + 1).padStart(2, '0'); //
let day = String(date.getDate()).padStart(2, '0'); //
let hour = date.getHours();
let minute = date.getMinutes();
let second = date.getSeconds();
let res = `${year}-${month}-${day}`; //
this.today = res;
this.filteredData.schedule_date = res;
},
//
async selectDate(date) {
this.loadData()
this.filteredData.schedule_date = date
this.getList()
},
//()
loadMoreData() {
//
if (!this.isReachedBottom) {
this.isReachedBottom = true;//
this.getList();
}
},
//
async loadData() {
this.isReachedBottom = false; // 便
this.filteredData.page = 1//
this.filteredData.limit = 10//
this.filteredData.total = 10//
},
//
async getList() {
this.loading = true
let data = {...this.filteredData}
//
if (this.filteredData.page * this.filteredData.limit > this.filteredData.total || this.filteredData.limit > this.filteredData.total) {
this.loading = false
uni.showToast({
title: '暂无更多',
icon: 'none'
})
return
}
let res = await memberApi.courseList(data)
this.loading = false
this.isReachedBottom = false;
if (res.code != 1) {
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.tableList = res.data.list.data
//
this.venuesInfo = res.data.venues_info
this.filteredData.total = res.data.list.total
this.filteredData.page++
},
//
//
getDateRange() {
const today = new Date(); //
const startDate = new Date(today); //
const endDate = new Date(today); //
// startDate 1
startDate.setMonth(today.getMonth() - 1);
// endDate 1
endDate.setMonth(today.getMonth() + 2);
// YYYY-MM-DD
const formatDate = (date) => {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
};
// data startDate endDate
this.startDate = formatDate(startDate);
this.endDate = formatDate(endDate);
console.log([this.startDate,this.endDate])
},
//
async setCalendarSelected(){
//
let month = new Date().getMonth() + 1;
let res = await commonApi.getMonthDate({month:month})
if (res.code != 1){
//
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
})
return
}
this.calendarSelected = []
res.data.forEach((v,k)=>{
this.calendarSelected.push({
date: v.date,
})
})
// this.calendarSelected = [
// {
// date: '2025-04-07',
// },
// {
// date: '2025-04-08',
// },
// {
// date: '2025-04-09',
// }
// ]
},
//
changeCalendar(e){
console.log('日历',e)
this.show_calendar = false
this.loadData()
this.filteredData.schedule_date = e.fulldate
this.getList()
},
}
}
</script>
@ -266,7 +443,13 @@ export default {
align-items: center;
background: #292929;
.title{
padding: 20rpx 0;
padding: 40rpx 0rpx;
/* 小程序端样式 */
// #ifdef MP-WEIXIN
padding: 80rpx 0rpx;
// #endif
font-size: 30rpx;
color: #fff;
}
@ -284,6 +467,7 @@ export default {
background: #333333 100%;
width: 100%;
padding: 30rpx 28rpx;
padding-bottom: 15rpx;
.ul{
display: flex;
justify-content: space-between;
@ -319,6 +503,13 @@ export default {
}
}
}
.btn{
margin-top: 20rpx;
display: flex;
justify-content: center;
align-items: center;
color: #A4ADB3;
}
}
.section_2{
@ -350,6 +541,7 @@ export default {
border-radius: 22rpx;
background: #434544 100%;
padding: 14rpx 0;
padding-bottom: 30rpx;
display: flex;
flex-direction: column;
.top_box{

440
pages/coach/home/index.vue

@ -2,55 +2,58 @@
<view class="main_box">
<!--自定义导航栏-->
<view class="navbar_section">
<view class="title">首页</view>
<view class="left"></view>
<view class="title">待办</view>
<view class="right" @click="openObjAddView()">发布作业</view>
</view>
<view class="main_section">
<view class="section_1">
<view class="top">
<view class="user">
<view class="pic">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
</view>
<view class="name">包子皮</view>
</view>
<view class="right">
<view>
<text class="title">到课率统计</text>
<text>28%</text>
</view>
<view>
<text class="title" @click="openObjAddView()">发布作业</text>
<text></text>
</view>
</view>
</view>
<view class="bottom"></view>
<view class="text_box">
<text>月授课数</text>
<text>12</text>
<text>月负责学员</text>
<text>188</text>
<text></text>
</view>
</view>
<!-- <view class="section_1">-->
<!-- <view class="top">-->
<!-- <view class="user">-->
<!-- <view class="pic">-->
<!-- <image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>-->
<!-- </view>-->
<!-- <view class="name">包子皮</view>-->
<!-- </view>-->
<!-- <view class="right">-->
<!-- <view>-->
<!-- <text class="title">到课率统计</text>-->
<!-- <text>28%</text>-->
<!-- </view>-->
<!-- <view>-->
<!-- <text class="title" @click="openObjAddView()">发布作业</text>-->
<!-- <text></text>-->
<!-- </view>-->
<!-- </view>-->
<!-- </view>-->
<!-- <view class="bottom"></view>-->
<!-- <view class="text_box">-->
<!-- <text>月授课数</text>-->
<!-- <text>12</text>-->
<!-- <text>月负责学员</text>-->
<!-- <text>188</text>-->
<!-- <text></text>-->
<!-- </view>-->
<!-- </view>-->
<view class="section_2">
<view class="left_box">
<view>
<text>课程</text>
<text>预告</text>
</view>
<view>
<text>5/28周五 15:30~17:30</text>
<text>301室篮球少儿课程</text>
</view>
</view>
<view class="rigth_box">
<view>详情</view>
</view>
</view>
<!-- <view class="section_2">-->
<!-- <view class="left_box">-->
<!-- <view>-->
<!-- <text>课程</text>-->
<!-- <text>预告</text>-->
<!-- </view>-->
<!-- <view>-->
<!-- <text>5/28周五 15:30~17:30</text>-->
<!-- <text>301室篮球少儿课程</text>-->
<!-- </view>-->
<!-- </view>-->
<!-- <view class="rigth_box">-->
<!-- <view>详情</view>-->
<!-- </view>-->
<!-- </view>-->
<!--最近课程-->
<view class="section_3">
<view class="title_box">
<view class="top_box">
@ -60,58 +63,55 @@
<view class="line"></view>
</view>
<view class="ul">
<view class="li">
<view class="left_box">
<view class="date_box">
<text>12</text>
<text>/</text>
<text>24</text>
</view>
<view class="ratio">
到课率80%
<!-- 上课中-->
<view class="li" v-for="(v,k) in infoData.course_list" :key="k" @click="openViewCourseInfoList(v)">
<view class="top_box">
<view class="title">课程{{ v.courses_name }}</view>
<view class="title">时间{{ v.date_time }} {{ v.time_slot.split(',')[0] }}-{{ v.time_slot.split(',')[1] }}
</view>
<view class="title">地点{{ v.address }}</view>
</view>
<view class="center_box">
<view>班级少年班</view>
<view>时间2020-05-25 15:30 - 17:30</view>
<view>课室302
</view>
<view>课程篮球少儿课
<view class="botton_box" v-if="v.status == 1">
<view class="box">
<view>已签到学生{{ v.sign_count }}/{{ v.students_count }}</view>
<view>
查看
<fui-icon size="35" color="#fff" name="arrowright"></fui-icon>
</view>
</view>
<!-- <view class="box">-->
<!-- <view>尚未发布作业</view>-->
<!-- <view></view>-->
<!-- </view>-->
</view>
<view class="right_box">
<view class="tag" style="background:#fad24e;">上课中</view>
<!-- <view class="tag" style="background:#1cd188;">待上课</view>-->
</view>
</view>
<view class="li">
<view class="left_box">
<view class="date_box">
<text>12</text>
<text>/</text>
<text>24</text>
</view>
<view class="ratio">
到课率80%
<view class="botton_box" v-else>
<view class="box">
<view>应到学生{{ v.students_count }}</view>
<view>
查看
<fui-icon size="35" color="#fff" name="arrowright"></fui-icon>
</view>
</view>
</view>
<view class="center_box">
<view>班级少年班</view>
<view>时间2020-05-25 15:30 - 17:30</view>
<view>课室302
</view>
<view>课程篮球少儿课
</view>
<view
v-if="v.status == 1"
class="tag"
style="background:#fad24e;">上课中
</view>
<view class="right_box">
<!-- <view class="tag" style="background:#fad24e;">上课中</view>-->
<view class="tag" style="background:#1cd188;">待上课</view>
<view
v-else
class="tag"
style="background:#1cd188;">待上课
</view>
</view>
</view>
</view>
<view class="section_3">
<!--作业批改-->
<view class="section_4">
<view class="title_box">
<view class="top_box">
<text>作业批改</text>
@ -120,43 +120,21 @@
<view class="line"></view>
</view>
<view class="ul">
<view class="li">
<view class="li" v-for="(v,k) in infoData.task_list" :key="k" @click="openViewWorkDetails(v)">
<view class="left_box">
<view class="date_box">
<text>12</text>
<text>{{v.wc_count}}</text>
<text>/</text>
<text>24</text>
<text>{{v.student_count}}</text>
</view>
<view class="ratio">
完成率80%
完成率{{v.rate}}%
</view>
</view>
<view class="center_box">
<view>班级少年班</view>
<view>时间2020-05-25 15:30 - 17:30</view>
<view>课程篮球少儿课
</view>
</view>
<view class="right_box">
<!-- <view class="tag" style="background:#fad24e;">上课中</view>-->
<view class="tag" style="background:#1cd188;">待批改</view>
</view>
</view>
<view class="li">
<view class="left_box">
<view class="date_box">
<text>12</text>
<text>/</text>
<text>24</text>
</view>
<view class="ratio">
完成率80%
</view>
</view>
<view class="center_box">
<view>班级少年班</view>
<view>时间2020-05-25 15:30 - 17:30</view>
<view>课程篮球少儿课
<view>班级{{v.class_name}}</view>
<view>时间{{v.send_time}}</view>
<view>课程{{v.courses_name}}
</view>
</view>
<view class="right_box">
@ -164,6 +142,7 @@
<view class="tag" style="background:#1cd188;">待批改</view>
</view>
</view>
</view>
</view>
</view>
@ -176,7 +155,7 @@
</template>
<script>
// import user from '@/api/user.js';
import memberApi from '@/api/member.js';
import AQTabber from "@/components/AQ/AQTabber.vue"
@ -186,27 +165,38 @@ export default {
},
data() {
return {
list: [],
likes: 0,
type: 1,
type1: 1,
activity_id: 0,
um_id: 0,
urls: 'http://medication.zeyan.wang/'
//
infoData:{
course_list:[],//
task_list:[],//
},
}
},
onLoad() {
const um_id = uni.getStorageSync('um_id');
this.um_id = um_id
if (um_id == '') {
uni.navigateTo({
url: '/pages/login/login'
})
}
this.fetchData(this.um_id)
onLoad() {},
onShow() {
this.init()//
},
methods: {
//
async init(){
await this.getInfo()
},
//
async getInfo(){
let res = await memberApi.jlIndex({})
if(res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.infoData = res.data
},
//-
openObjAddView(){
uni.navigateTo({
@ -221,90 +211,22 @@ export default {
})
},
fetchData(um_id) {
user.activity_index({
um_id: um_id
}).then(res => {
console.log(res)
if (res.status == 200) {
if (res.data == null) {
this.list = []
} else {
this.list = res.data
}
} else {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
});
},
onPullDownRefresh() {
this.fetchData(this.um_id)
},
publishing() {
//-
openViewCourseInfoList(item){
let id = item.id
uni.navigateTo({
url: '/pages/index/publishing'
url: `/pages/coach/course/info_list?id=${id}`
})
},
like(id, um_id) {
user.activity_like({um_id: um_id, activity_id: id, type: 1}).then(res => {
if (res.status == 200) {
user.activity_index({
um_id: um_id
}).then(res => {
console.log(res)
if (res.status == 200) {
this.list = res.data
}
});
this.type = res.data.type
this.activity_id = res.data.activity_id
} else {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
});
},
collection(id, um_id) {
user.activity_like({um_id: um_id, activity_id: id, type: 2}).then(res => {
if (res.status == 200) {
console.log(res)
this.fetchData(this.um_id)
this.type1 = res.data.type
this.activity_id = res.data.activity_id
} else {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
});
},
coninfo(item) {
// user.coninfo({id:id}).then(res => {
// if(res.status == 200){
uni.setStorageSync('coninfo', item);
//-
openViewWorkDetails(item){
let id = item.id
uni.navigateTo({
url: '/pages/index/coninfo'
url: `/pages/coach/student/work_details?id=${id}`
})
// }else{
// uni.showToast({
// title: res.msg,
// icon: 'none'
// })
// }
// });
},
Comment(id) {
uni.setStorageSync('actid', id);
uni.navigateTo({
url: '/pages/index/Comment'
})
}
}
}
</script>
@ -317,14 +239,34 @@ export default {
//
.navbar_section{
padding: 0 40rpx;
display: flex;
justify-content: center;
justify-content: space-between;
align-items: center;
background: #29d3b4;
view{
width: 30%;
text-align: center;
}
.left{
text-align: left;
}
.title{
padding: 20rpx 0;
padding: 40rpx 0rpx;
/* 小程序端样式 */
// #ifdef MP-WEIXIN
padding: 80rpx 0rpx;
// #endif
font-size: 30rpx;
color: #315d55;
color: #fff;
}
.right{
padding: 20rpx 0;
font-size: 26rpx;
color: #fff;
text-align: right;
}
}
@ -421,6 +363,80 @@ export default {
}
.section_3{
margin-top: 36rpx;
color: #fff;
font-size: 24rpx;
.title_box{
display: flex;
flex-direction: column;
.top_box{
display: flex;
justify-content: space-between;
align-items: center;
text{
font-size: 30rpx;
}
}
.line{
width: 90rpx;
height: 2px;
background: #29D3B4;
}
}
.ul{
margin-top: 30rpx;
display: flex;
flex-direction: column;
gap: 20rpx;
.li{
border: 1px solid #00E5BB;
position: relative;
border-radius: 22rpx;
background: #434544 100%;
padding: 14rpx 20rpx;
padding-bottom: 44rpx;
display: flex;
flex-direction: column;
.top_box{
padding-bottom: 18rpx;
border-bottom: 1px dashed #F2F2F2;
display: flex;
flex-direction: column;
gap: 18rpx;
.title{}
}
.botton_box{
padding-top: 18rpx;
display: flex;
flex-direction: column;
gap: 18rpx;
color: #D7D7D7;
.box{
display: flex;
justify-content: space-between;
view{
display: flex;
align-items: center;
}
}
}
.tag{
position:absolute;
top: 0rpx;
right: 0rpx;
padding: 10rpx;
width: 102rpx;
text-align: center;
font-size: 24rpx;
border-bottom-left-radius: 20rpx;
border-top-right-radius: 20rpx;
}
}
}
}
.section_4{
margin-top: 36rpx;
color: #fff;
font-size: 24rpx;
@ -450,7 +466,7 @@ export default {
position: relative;
border-radius: 22rpx;
background: #434544 100%;
padding: 14rpx 0;
padding: 32rpx 0;
display: flex;
align-items: center;
.left_box{

318
pages/coach/job/add.vue

@ -1,9 +1,9 @@
<!--发布作业-->
<template>
<view class="main_section">
<view class="formData">
<fui-form class="formData" ref="form">
<view class="radio_input">
<fui-form-item label="作业类型" asterisk>
<fui-form-item label="发布类型" asterisk>
<fui-radio-group name="radio" v-model="formData.type" @change="changeType">
<view class="fui-list__item">
<fui-label>
@ -24,34 +24,102 @@
</view>
<view class="radio_input">
<fui-form-item label="作业类型" asterisk>
<fui-radio-group name="radio" v-model="formData.content_type" @change="changeContentType">
<view class="fui-list__item">
<fui-label>
<view class="fui-align__center">
<fui-radio value="1" checked></fui-radio>
<text class="fui-text">图片作业</text>
</view>
</fui-label>
<fui-label :margin="['0','0','0','40rpx']">
<view class="fui-align__center">
<fui-radio value="2"></fui-radio>
<text class="fui-text">视频作业</text>
</view>
</fui-label>
</view>
</fui-radio-group>
</fui-form-item>
</view>
<view v-if="formData.type == 1">
<fui-input required label="班级" borderTop placeholder="请选择班级" v-model="formData.classes_id_name"
@click="show_class=true"></fui-input>
<fui-picker layer="1" :linkage="true" :options="options_class_arr" :show="show_class" @change="changeClass"
@cancel="show_class=false"></fui-picker>
</view>
<view v-if="formData.type != 1">
<fui-input required label="学员" borderTop placeholder="请选择学员" v-model="formData.students_ids_name"
@click="show_student=true"></fui-input>
<!--下拉多选-->
<fui-select
:show="show_student"
:options="options_student_arr"
title="请选择学员"
multiple
isReverse
checkboxColor="#FFC529"
btnBackground="#FFC529"
btnColor="#1A1D26"
closeColor="#6D758A"
@confirm="changeStudent"
@close="show_student=false">
</fui-select>
<view>
<fui-input required label="班级" borderTop placeholder="请选择班级" v-model="formData.class_name" @click="show_class=true"></fui-input>
<fui-picker layer="1" :linkage="true" :options="options_class_arr" :show="show_class" @change="changeClass" @cancel="show_class=false"></fui-picker>
</view>
<view>
<fui-input required label="课程" borderTop placeholder="请选择课程" v-model="formData.course_name" @click="show_course=true"></fui-input>
<fui-input required label="课程" borderTop placeholder="请选择课程" v-model="formData.course_id_name"
@click="show_course=true"></fui-input>
<fui-picker
layer="1"
:linkage="true"
:options="options_course_arr" :show="show_course" @change="changeCourse" @cancel="show_course=false"></fui-picker>
:options="options_course_arr" :show="show_course" @change="changeCourse"
@cancel="show_course=false"></fui-picker>
</view>
<view>
<fui-textarea required flexStart label="作业" placeholder="请输入内容" v-model="formData.homework"></fui-textarea>
<fui-textarea required flexStart label="作业" placeholder="请输入内容" v-model="formData.content_text"></fui-textarea>
</view>
</view>
<view class="submet_btn" @click="submetForm">提交</view>
</fui-form>
<!--吸顶消息提示-->
<fui-message ref="msg" :background="`#ff2b2b`"></fui-message>
<!-- 底部导航-->
<AQTabber/>
</view>
</template>
<script>
// import user from '@/api/user.js';
import memberApi from '@/api/member.js';
import AQTabber from "@/components/AQ/AQTabber.vue"
//
const rules = [
// {
// name: "classes_id_name",
// rule: ["required"],
// msg: [""]
// },
{
name: "course_id_name",
rule: ["required"],
msg: ["请选择课程"]
},
{
name: "content_text",
rule: ["required"],
msg: ["请输入作业内容"]
},
];
export default {
components: {
AQTabber,
@ -60,53 +128,233 @@ export default {
return {
show_class:false,
show_course:false,
show_student:false,
//
options_class_arr:[
{ value: 1, text: '班级1' },
{ value: 2, text: '班级2' },
{ value: 3, text: '班级3' }
// { value: 1, text: '1' },
],
//
options_course_arr:[
{ value: 1, text: '课程1' },
{ value: 2, text: '课程2' },
{ value: 3, text: '课程3' }
// { value: 1, text: '1' },
],
//
options_student_arr:[
// {
// text: '3',
// value: '3',
// checked: false,//
// }
],
//
formData: {
type: '1',//()|1,2
course_id: '',//id()
course_id_name: '',//id()
content_type: '1',//()|1,2
content_text: '',//
formData:{
type:'1',//()
class_name:'',//()
class_id:'',//()
course_name:'',//()
course_id:'',//()
homework:'',//()
classes_id: '',//id()
classes_id_name: '',//id()
students_ids: '',//id
students_ids_name:'',//id()
}
}
},
onLoad() {
},
onShow() {
this.init()
},
methods: {
//
async init() {
// -()
this.getClassesList()
//
this.getCoursesList()
//
this.getStudentList()
},
//
async getClassesList(){
let res = await memberApi.jlGetClassesList({})
if(res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.options_class_arr = []
res.data.forEach((v,k)=>{
this.options_class_arr.push({
text: v.name,
value: v.id,
})
})
},
//
async getCoursesList(){
let res = await memberApi.jlGetCoursesList({})
if(res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.options_course_arr = []
res.data.forEach((v,k)=>{
this.options_course_arr.push({
text: v.name,
value: v.id,
})
})
},
//
async getStudentList() {
let res = await memberApi.jlGetStudentList({})
if (res.code != 1) {
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.options_student_arr = []
res.data.forEach((v, k) => {
this.options_student_arr.push({
text: v.name,
value: v.id,
checked: false,//
})
})
},
//-
changeClass(e) {
console.log('选择器-班级', e);
this.formData.class_id = e.value; // class_id
this.formData.class_name = e.text; // class_name
this.formData.classes_id = e.value; // class_id
this.formData.classes_id_name = e.text; // class_name
this.show_class = false; //
},
//-
changeCourse(e) {
console.log('选择器-课程', e);
this.formData.course_id = e.value; // course_id
this.formData.course_name = e.text; // course_name
this.formData.course_id_name = e.text; // course_name
this.show_course = false; //
},
//-
changeStudent(e) {
console.log('选择器-学员', e);
let id_arr = []
let name_arr = []
e.options.forEach((v,k)=>{
id_arr.push(v.value)
name_arr.push(v.text)
})
//
this.formData.students_ids = id_arr.join(',')
this.formData.students_ids_name = name_arr.join(',')
this.show_student = false; //
},
//-
//-
changeType(e) {
console.log('选择器-作业类型', e);
this.formData.type = e.value; // type
this.formData.type = e.detail.value; // type
//1=
if(e.detail.value == 1){
//
this.formData.students_ids = ''
this.formData.students_ids_name = ''
}else{
// 2=
this.formData.classes_id = ''
this.formData.classes_id_name = ''
}
},
//-
changeContentType(e) {
console.log('选择器-作业类型', e);
this.formData.content_type = e.detail.value; // type
},
//
async validatorForm(data) {
let res = await this.$refs.form.validator(data, rules)
return res
},
//
showMsg(msg) {
let options = {}
//text
options.text = msg
this.$refs.tips.show(options)
},
//
async submetForm(){
let data = {...this.formData}
console.log('提交',data)
let vf = await this.validatorForm(data)//
if(data.type == 1){
//
if(!data.classes_id){
this.showMsg('请选择班级')
return
}
}else{
//
if(!data.students_ids){
this.showMsg('请选择学员')
return
}
}
if(!vf.isPassed){
console.log('验证',vf)
return
}
//
let res = await memberApi.jlPublishJob(data)
if (res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
uni.showToast({
title: res.msg,
icon: 'success'
})
//1s
setTimeout(() => {
uni.navigateTo({
url: '/pages/coach/home/index'
})
}, 1000)
},
}
}
@ -134,6 +382,20 @@ export default {
align-items: center;
}
}
.submet_btn{
margin: 0 auto;
margin-top: 40rpx;
display: flex;
justify-content: center;
align-items: center;
background-color: #29d3b4;
border-radius: 8rpx;
width: 648rpx;
height: 88rpx;
color: rgba(255,255,255,1);
font-size: 32rpx;
}
}

215
pages/coach/job/list.vue

@ -2,54 +2,38 @@
<template>
<view class="main_section">
<view class="section_3">
<scroll-view
class="section_3"
scroll-y="true"
:lower-threshold="lowerThreshold"
@scrolltolower="loadMoreData"
style="height: 80vh;"
>
<view class="ul">
<view class="li">
<view class="li" v-for="(v,k) in tableList" :key="k" @click="openViewWorkDetails(v)">
<view class="left_box">
<view class="date_box">
<text>12</text>
<text>{{v.wc_count}}</text>
<text>/</text>
<text>24</text>
<text>{{v.student_count}}</text>
</view>
<view class="ratio">
完成率80%
完成率{{v.rate}}%
</view>
</view>
<view class="center_box">
<view>班级少年班</view>
<view>时间2020-05-25 15:30 - 17:30</view>
<view>课程篮球少儿课
</view>
</view>
<view class="right_box">
<!-- <view class="tag" style="background:#fad24e;">上课中</view>-->
<view class="tag" style="background:#1cd188;">待批改</view>
</view>
</view>
<view class="li">
<view class="left_box">
<view class="date_box">
<text>12</text>
<text>/</text>
<text>24</text>
</view>
<view class="ratio">
完成率80%
</view>
</view>
<view class="center_box">
<view>班级少年班</view>
<view>时间2020-05-25 15:30 - 17:30</view>
<view>课程篮球少儿课
<view>班级{{v.class_name}}</view>
<view>时间{{v.send_time}}</view>
<view>课程{{v.courses_name}}
</view>
</view>
<view class="right_box">
<!-- <view class="tag" style="background:#fad24e;">上课中</view>-->
<view class="tag" style="background:#1cd188;">待批改</view>
<view class="tag" v-if="v.dpg_count == 0" style="background:#1cd188;">待批改</view>
</view>
</view>
</view>
</view>
</scroll-view>
<!-- 底部导航-->
<AQTabber/>
@ -57,7 +41,7 @@
</template>
<script>
// import user from '@/api/user.js';
import memberApi from '@/api/member.js';
import AQTabber from "@/components/AQ/AQTabber.vue"
@ -67,110 +51,89 @@ export default {
},
data() {
return {
list: [],
likes: 0,
type: 1,
type1: 1,
activity_id: 0,
um_id: 0,
urls: 'http://medication.zeyan.wang/'
loading:false,//
lowerThreshold: 100,//
isReachedBottom: false,//|true=|false=
//
filteredData:{
page:1,//
limit:10,//
total:10,//
},
tableList:[],//
}
},
onLoad() {
const um_id = uni.getStorageSync('um_id');
this.um_id = um_id
if (um_id == '') {
uni.navigateTo({
url: '/pages/login/login'
})
}
this.fetchData(this.um_id)
onLoad() {},
onShow() {
this.init()
},
methods: {
fetchData(um_id) {
user.activity_index({
um_id: um_id
}).then(res => {
console.log(res)
if (res.status == 200) {
if (res.data == null) {
this.list = []
} else {
this.list = res.data
}
} else {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
});
async init(){
this.getList()
},
onPullDownRefresh() {
this.fetchData(this.um_id)
},
publishing() {
uni.navigateTo({
url: '/pages/index/publishing'
})
//()
loadMoreData() {
//
if (!this.isReachedBottom) {
this.isReachedBottom = true;//
this.getList();
}
},
like(id, um_id) {
user.activity_like({um_id: um_id, activity_id: id, type: 1}).then(res => {
if (res.status == 200) {
user.activity_index({
um_id: um_id
}).then(res => {
console.log(res)
if (res.status == 200) {
this.list = res.data
}
});
this.type = res.data.type
this.activity_id = res.data.activity_id
} else {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
});
//
async resetFilteredData() {
this.isReachedBottom = false; // 便
this.filteredData.page = 1//
this.filteredData.limit = 10//
this.filteredData.total = 10//
},
collection(id, um_id) {
user.activity_like({um_id: um_id, activity_id: id, type: 2}).then(res => {
if (res.status == 200) {
console.log(res)
this.fetchData(this.um_id)
this.type1 = res.data.type
this.activity_id = res.data.activity_id
} else {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
});
//
async getList(){
this.loading = true
let data = {...this.filteredData}
//
if(this.filteredData.page * this.filteredData.limit > this.filteredData.total){
this.loading = false
uni.showToast({
title: '暂无更多',
icon: 'none'
})
return
}
if(data.page == 1){
this.tableList = []
}
let res = await memberApi.jsGetAssignmentsList(data)
this.loading = false
this.isReachedBottom = false;
if (res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.tableList = this.tableList.concat(res.data.data); // 使 concat
console.log('列表',this.tableList)
this.filteredData.total = res.data.total
this.filteredData.page++
},
coninfo(item) {
// user.coninfo({id:id}).then(res => {
// if(res.status == 200){
uni.setStorageSync('coninfo', item);
//-
openViewWorkDetails(item){
let id = item.id
uni.navigateTo({
url: '/pages/index/coninfo'
url: `/pages/coach/student/work_details?id=${id}`
})
// }else{
// uni.showToast({
// title: res.msg,
// icon: 'none'
// })
// }
// });
},
Comment(id) {
uni.setStorageSync('actid', id);
uni.navigateTo({
url: '/pages/index/Comment'
})
}
}
}
</script>

220
pages/coach/my/arrival_statistics.vue

@ -3,64 +3,53 @@
<view class="main_box">
<view class="main_section">
<view class="section_3">
<scroll-view
class="section_3"
scroll-y="true"
:lower-threshold="lowerThreshold"
@scrolltolower="loadMoreData"
style="height: 90vh;"
>
<view class="ul">
<view class="li">
<view class="left_box">
<view class="date_box">
<text>12</text>
<text>/</text>
<text>24</text>
</view>
<view class="ratio">
到课率80%
</view>
</view>
<view class="center_box">
<view>班级少年班</view>
<view>时间2020-05-25 15:30 - 17:30</view>
<view>课室302
</view>
<view>课程篮球少儿课
</view>
</view>
<view class="right_box">
<view class="tag" style="background:#fad24e;">上课中</view>
<!-- <view class="tag" style="background:#1cd188;">待上课</view>-->
</view>
</view>
<view class="li">
<view class="li"
v-for="(v,k) in courseList"
:key="k"
@click="openViewCourseInfo(v)"
>
<view class="left_box">
<view class="date_box">
<text>12</text>
<text>{{v.has_sign_count}}</text>
<text>/</text>
<text>24</text>
<text>{{v.students_count}}</text>
</view>
<view class="ratio">
到课率80%
到课率{{v.attendance_rate}}%
</view>
</view>
<view class="center_box">
<view>班级少年班</view>
<view>时间2020-05-25 15:30 - 17:30</view>
<view>课室302
<view>班级{{v.classes_name}}</view>
<view>时间{{v.date_time}} {{v.time_slot ? v.time_slot.replace(",", " - ") : ""}}</view>
<view>课室{{v.address}}
</view>
<view>课程篮球少儿课
<view>课程{{v.courses_name}}
</view>
</view>
<view class="right_box">
<!-- <view class="tag" style="background:#fad24e;">上课中</view>-->
<view class="tag" style="background:#1cd188;">待上课</view>
<view v-if="!(['1','2'].includes(String(v.status)))" class="tag" style="background:#20CAAF;">未开始</view>
<view v-if="v.status == 1" class="tag" style="background:#fad24e;">上课中</view>
<view v-if="v.status == 2" class="tag" style="background:#e2e2e2;">已结束</view>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
</view>
</template>
<script>
// import user from '@/api/user.js';
import memberApi from '@/api/member.js';
import AQTabber from "@/components/AQ/AQTabber.vue"
@ -70,80 +59,105 @@ export default {
},
data() {
return {
formData:{},
//
show_course:false,//
//
course_name:'课程',//
options_course: [
{
text: '请选择课程',
value: '',
checked: true
}, {
text: '羽毛球课程1',
value: '1'
}, {
text: '篮球课程2',
value: '2'
}
],
//
show_classroom:false,//
//
classroom_name:'课室',//
options_classroom: [
{
text: '请选择课室',
value: '',
checked: true
}, {
text: '羽毛球201',
value: '1'
}, {
text: '篮球室101',
value: '2'
}
],
loading: false,//
lowerThreshold: 100,//
isReachedBottom: false,//|true=|false=
//
filteredData: {
page: 1,//
limit: 10,//
total: 10,//
class_id: '',//id
},
courseList:[],//
}
},
onLoad() {
},
onShow(){
this.init()
},
methods: {
//
clickCourse(e){
console.log(e)
this.course_name = e.text
this.show_course = true
//
async init(){
this.getCourseList()
},
//
filterTapCourse() {
//
this.$refs.ref_course.show()
this.show_course = true;
// .courseList
//()
loadMoreData() {
//
if (!this.isReachedBottom) {
this.isReachedBottom = true;//
this.getCourseList();
}
},
//
async loadData() {
this.isReachedBottom = false; // 便
this.filteredData.page = 1//
this.filteredData.limit = 10//
this.filteredData.total = 10//
},
//-
async getCourseList(){
let data = {...this.filteredData}
data.class_id = this.class_id
console.log(12123,this.courseList)
if(data.page == 1){
this.courseList = []
}
//
if (this.filteredData.page * this.filteredData.limit > this.filteredData.total || this.filteredData.limit > this.filteredData.total) {
this.loading = false
uni.showToast({
title: '暂无更多',
icon: 'none'
})
return
}
let res = await memberApi.courseList(data)
this.loading = false
this.isReachedBottom = false;
if (res.code != 1) {
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
let arr = []
res.data.list.data.forEach((v,k)=>{
let item = v
item.attendance_rate = (v.students_count && !isNaN(v.students_count) && v.students_count > 0) ?
parseFloat(((v.has_sign_count / v.students_count) * 100).toFixed(1)) : 0;
arr.push(item)
})
this.courseList = this.courseList.concat(res.data.list.data)// 使 concat
this.filteredData.total = res.data.list.total
console.log('获取课程列表',this.courseList)
this.filteredData.page++
//
clickClassroom(e){
console.log(e)
this.classroom_name = e.text
this.show_classroom = true
},
//
filterTapClassroom() {
//
this.$refs.ref_classroom.show()
this.show_classroom = true;
},
//
//
openViewCourseInfo(item){
let id= item.id
uni.navigateTo({
url: '/pages/coach/course/info'
url: `/pages/coach/course/info_list?id=${id}`
})
},
}
@ -163,7 +177,13 @@ export default {
align-items: center;
background: #29d3b4;
.title{
padding: 20rpx 0;
padding: 40rpx 0rpx;
/* 小程序端样式 */
// #ifdef MP-WEIXIN
padding: 80rpx 0rpx;
// #endif
font-size: 30rpx;
color: #315d55;
}
@ -210,7 +230,7 @@ export default {
align-items: center;
.left_box{
margin-left: 28rpx;
width: 146rpx;
width: 175rpx;
display: flex;
flex-direction: column;
gap: 10rpx;
@ -226,7 +246,7 @@ export default {
}
}
.center_box{
margin-left: 52rpx;
margin-left: 22rpx;
display: flex;
flex-direction: column;
gap: 10rpx;

8
pages/coach/my/due_soon.vue

@ -215,7 +215,13 @@ export default {
align-items: center;
background: #292929;
.title{
padding: 20rpx 0;
padding: 40rpx 0rpx;
/* 小程序端样式 */
// #ifdef MP-WEIXIN
padding: 80rpx 0rpx;
// #endif
font-size: 30rpx;
color: #fff;
}

64
pages/coach/my/index.vue

@ -11,11 +11,12 @@
<view class="user_section">
<view class="box">
<view class="left" @click="openViewMyInfo()">
<image class="pic" src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<view class="name">包子皮</view>
<image class="pic" :src="$util.img(memberInfo.headimg)"></image>
<view class="name">{{memberInfo.name}}</view>
</view>
<view class="right">
<view class="btn">切换身份</view>
<view class="btn"></view>
<!-- <view class="btn">切换身份</view>-->
<view class="btn" @click="openViewArrivalStatistics()">到课率统计</view>
<view class="btn"></view>
</view>
@ -28,15 +29,15 @@
<view class="course_box">
<view class="top">
<view class="item">
<view class="num">1234</view>
<view class="num">{{memberInfo.zsks}}</view>
<view class="intro">总授课数/</view>
</view>
<view class="item">
<view class="num">4</view>
<view class="num">{{memberInfo.zsbj}}</view>
<view class="intro">总授班级/</view>
</view>
<view class="item">
<view class="num">1234</view>
<view class="num">{{memberInfo.zfzxy}}</view>
<view class="intro">总负责学员/
</view>
</view>
@ -74,6 +75,16 @@
<view></view>
</view>
<view class="item" @click="openViewMyAttendance()">
<view>我的考勤</view>
<view></view>
</view>
<view class="item" @click="openViewSchoolingStatistics()">
<view>我的消息</view>
<view></view>
</view>
</view>
<view class="section_box">
@ -95,7 +106,7 @@
</template>
<script>
// import user from '@/api/user.js';
import memberApi from '@/api/member.js';
import AQTabber from "@/components/AQ/AQTabber.vue"
@ -105,12 +116,32 @@ export default {
},
data() {
return {
formData:{},
memberInfo:{},
}
},
onLoad() {
},
onShow() {
this.init();
},
methods: {
async init(){
this.getMemberInfo()
},
//()
async getMemberInfo(){
let res = await memberApi.member({})
if (res.code != 1) {
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.memberInfo = res.data
},
//
openViewArrivalStatistics(){
uni.navigateTo({
@ -151,7 +182,14 @@ export default {
uni.navigateTo({
url: '/pages/coach/my/set_up'
})
}
},
//-
openViewMyAttendance(){
uni.navigateTo({
url: '/pages/common/my_attendance'
})
},
}
}
</script>
@ -171,7 +209,13 @@ export default {
align-items: center;
background: #29D3B4;
.title{
padding: 20rpx 0;
padding: 40rpx 0rpx;
/* 小程序端样式 */
// #ifdef MP-WEIXIN
padding: 80rpx 0rpx;
// #endif
font-size: 30rpx;
color: #fff;
}

245
pages/coach/my/info.vue

@ -1,11 +1,16 @@
<!--授课统计-详情-->
<!--销售-个人资料-详情-->
<template>
<view class="main_box">
<view class="main_section">
<view class="section">
<view class="item">
<image @click="changeAvatar()" class="pic" src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<image
@click="changeAvatar()"
class="pic"
:src="$util.img(formData.header)"
></image>
<view class="btn" @click="changeAvatar()">修改头像</view>
</view>
</view>
@ -25,7 +30,7 @@
账号 <text class="required"></text>
</view>
<view class="input">
<input disabled placeholder="暂无" />
<input v-model="formData.username" disabled placeholder="暂无" />
</view>
</view>
@ -43,7 +48,7 @@
等级 <text class="required"></text>
</view>
<view class="input">
<input disabled placeholder="暂无" />
<input v-model="formData.member_level_name" disabled placeholder="暂无" />
</view>
</view>
</view>
@ -54,7 +59,7 @@
性别 <text class="required">*</text>
</view>
<view class="input">
<input placeholder="请选择性别" v-model="sex_name" @click="picker_show_sex=true"/>
<input placeholder="请选择性别" v-model="formData.gender" @click="picker_show_sex=true"/>
<fui-picker
layer="1"
:linkage="true"
@ -97,7 +102,7 @@
手机 <text class="required">*</text>
</view>
<view class="input">
<input v-model="formData.tel" placeholder="请输入手机" />
<input v-model="formData.phone" placeholder="请输入手机" />
</view>
</view>
@ -111,14 +116,16 @@
</view>
</view>
<view class="submet_btn">提交</view>
<view class="submet_btn" @click="submit">提交</view>
</view>
</view>
</template>
<script>
// import user from '@/api/user.js';
import {Api_url} from "@/common/config.js";
import marketApi from '@/api/market.js';
import {
Api_url
} from "@/common/config.js";
import AQTabber from "@/components/AQ/AQTabber"
@ -129,30 +136,43 @@ export default {
data() {
return {
formData:{
images_arr:[],
header:'',//
name:'',//
email:'',//
tel:'',//
wx:'',//
sex:'',//
username:'',//
address:'',//
gender:'',//|,
birthday:'',//
email:'',//
phone:'',//
wx:'',//
},
userInfo: {},
//APi
uploadUrl: `${Api_url}/salesmanapi/common/uploadFile`,
uploadUrl: `${Api_url}/file/image`,
//
picker_show_sex: false,
sex_name:'请选择',
options_sex_arr:[
{ value: 1, text: '男' },
{ value: 2, text: '女' },
options_sex_arr: [
{
value: 1,
text: '男'
},
{
value: 2,
text: '女'
},
],
//
minDate:'',
maxDate:'',
picker_show_birthday:false,
minDate: '',
maxDate: '',
picker_show_birthday: false,
upload_type: 1,
uploadHeadimg: '',
editHeadimg: '',
}
},
onLoad() {
@ -163,7 +183,44 @@ export default {
methods: {
async init(){
this.getBirthday()
// this.getBirthday()
this.setDateYear()
await this.getUserInfo()
},
//
setDateYear() {
let currentYear = new Date().getFullYear();
this.minDate = String(currentYear - 100);
this.maxDate = String(currentYear + 1);
},
//
async getUserInfo(){
let res = await marketApi.member({})
if (res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
//
this.formData = {
header: res.data.headimg,//
name: res.data.name,//
username: res.data.username,//
address: res.data.address,//
gender: res.data.gender,//|,
birthday: res.data.birthday,//
email: res.data.email,//
phone: res.data.phone,//
wx: res.data.wx || '',//
member_level_name: res.data.member_level_name || '',//
}
console.log(123,this.formData);
},
//
@ -179,33 +236,30 @@ export default {
}
})
},
async uploadFilePromise(url) {
console.log('AQ',this.uploadUrl,url)
return new Promise((resolve, reject) => {
let a = uni.uploadFile({
url: this.uploadUrl, //
filePath: url,
name: "file",
formData: {
token: this.$store.state.token,
},
success: (e) => {
console.log('上传成功1',e)
let res = JSON.parse(e.data.replace(/\ufeff/g, "") || "{}")
console.log('上传成功2',res)
if (res.code >= 0){
this.userInfo.pic = res.data.pic_path
this.editPic(res.data.pic_path)
}else{
this.$util.showToast({
title: res.message
});
}
setTimeout(() => {
resolve(res.data.data);
}, 1000);
},
});
uploadFilePromise(url) {
let token = uni.getStorageSync('token') || ''
let a = uni.uploadFile({
url: this.uploadUrl, //
filePath: url,
name: 'file',
header: {
'token': `${token}`, //token
},
success: (e) => {
let res = JSON.parse(e.data.replace(/\ufeff/g, "") || "{}")
console.log('上传成功2', res)
if (res.code == 1) {
this.upload_type = 2
this.formData.header = res.data.path
// this.editHeadimg = res.data.path
// this.uploadHeadimg = res.data.url
} else {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
},
});
},
//Api
@ -223,16 +277,15 @@ export default {
},
//
changePickerSex(e){
console.log('监听选择',e)
this.sex_name = e.text
this.formData.sex = e.value
changePickerSex(e) {
console.log('监听选择', e)
this.formData.gender = e.text
this.picker_show_sex = false
},
//
//+30
getBirthday(){
getBirthday() {
let date = new Date();
let year = date.getFullYear();
let month = date.getMonth() + 1;
@ -265,18 +318,88 @@ export default {
year_30 = year_30 + 1;
}
let minDate = year_30 + "-" + month_30 + "-" + day_30
let maxDate = year + "-" + month + "-" + day
let maxDate = year + "-" + month + "-" + day
this.minDate = minDate
this.maxDate = maxDate
},
//
changePickerBirthday(e){
console.log('监听生日选择',e)
changePickerBirthday(e) {
console.log('监听生日选择', e)
this.formData.birthday = e.result
this.picker_show_birthday = false
},
//
async submit() {
let data = {...this.formData}
if(!data.header){
uni.showToast({
title: '请上传头像',
icon: 'none'
})
return
}
if(!data.name){
uni.showToast({
title: '请填写',
icon: 'none'
})
return
}
if(!data.gender){
uni.showToast({
title: '请选择性别',
icon: 'none'
})
return
}
if(!data.birthday){
uni.showToast({
title: '请选择生日',
icon: 'none'
})
return
}
if(!data.email){
uni.showToast({
title: '请填写邮箱',
icon: 'none'
})
return
}
if(!data.phone){
uni.showToast({
title: '请填写手机',
icon: 'none'
})
return
}
let res = await marketApi.memberEdit(data)
if(res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
uni.showToast({
title: res.msg,
icon: 'success'
})
this.getUserInfo()
},
}
}
</script>
@ -294,7 +417,13 @@ export default {
align-items: center;
background: #29d3b4;
.title{
padding: 20rpx 0;
padding: 40rpx 0rpx;
/* 小程序端样式 */
// #ifdef MP-WEIXIN
padding: 80rpx 0rpx;
// #endif
font-size: 30rpx;
color: #315d55;
}

497
pages/coach/my/my_attendance.vue

@ -0,0 +1,497 @@
<!--我的考勤-详情-->
<template>
<view class="main_box">
<fui-segmented-control
:values="optionTable"
type="text"
activeColor="#29d3b4"
color="#fff"
@click="segmented">
</fui-segmented-control>
<view class="main_section">
<!--考勤-->
<scroll-view
class="section_1"
v-if="filteredData.type == '1'"
scroll-y="true"
:lower-threshold="lowerThreshold"
@scrolltolower="loadMoreData"
style="height: 100vh;"
>
<view class="ul">
<view class="li">
<view class="left">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image>
</view>
<view class="right">
<view class="content">篮球课</view>
<view class="content">考勤正常</view>
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view>
</view>
</view>
<view class="li">
<view class="left">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image>
</view>
<view class="right">
<view class="content">篮球课</view>
<view class="content">考勤正常</view>
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view>
</view>
</view>
<view class="li">
<view class="left">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image>
</view>
<view class="right">
<view class="content">篮球课</view>
<view class="content">考勤正常</view>
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view>
</view>
</view>
</view>
<view class="title_box">普通考勤</view>
<view class="subhead_box">请假</view>
<view class="subhead_box">2025-01-01 00:00:00 - 2505-01-01 00:00:00</view>
<view class="ul">
<view class="li">
<view class="left">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image>
</view>
<view class="right">
<view class="content">普通考勤</view>
<view class="content">迟到</view>
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view>
</view>
</view>
<view class="li">
<view class="left">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image>
</view>
<view class="right">
<view class="content">普通考勤</view>
<view class="content">早退</view>
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view>
</view>
</view>
<view class="li">
<view class="left">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image>
</view>
<view class="right">
<view class="content">普通记录</view>
<view class="content">本周考勤情况周一到周五均按时打卡未请假综合表现良好
</view>
</view>
</view>
</view>
</scroll-view>
<!--请假-->
<scroll-view
class="section_1"
v-if="filteredData.type == '2'"
scroll-y="true"
:lower-threshold="lowerThreshold"
@scrolltolower="loadMoreData"
style="height: 100vh;"
>
<view class="ul">
<view class="li">
<view class="left">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image>
</view>
<view class="right">
<view class="content">篮球课</view>
<view class="content">考勤正常</view>
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view>
</view>
</view>
<view class="li">
<view class="left">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image>
</view>
<view class="right">
<view class="content">篮球课</view>
<view class="content">考勤正常</view>
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view>
</view>
</view>
<view class="li">
<view class="left">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image>
</view>
<view class="right">
<view class="content">篮球课</view>
<view class="content">考勤正常</view>
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view>
</view>
</view>
</view>
<view class="title_box">普通考勤</view>
<view class="subhead_box">请假</view>
<view class="subhead_box">2025-01-01 00:00:00 - 2505-01-01 00:00:00</view>
<view class="ul">
<view class="li">
<view class="left">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image>
</view>
<view class="right">
<view class="content">普通考勤</view>
<view class="content">迟到</view>
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view>
</view>
</view>
<view class="li">
<view class="left">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image>
</view>
<view class="right">
<view class="content">普通考勤</view>
<view class="content">早退</view>
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view>
</view>
</view>
<view class="li">
<view class="left">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image>
</view>
<view class="right">
<view class="content">普通记录</view>
<view class="content">本周考勤情况周一到周五均按时打卡未请假综合表现良好
</view>
</view>
</view>
</view>
</scroll-view>
<!--异常-->
<scroll-view
class="section_1"
v-if="filteredData.type == '3'"
scroll-y="true"
:lower-threshold="lowerThreshold"
@scrolltolower="loadMoreData"
style="height: 100vh;"
>
<view class="ul">
<view class="li">
<view class="left">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image>
</view>
<view class="right">
<view class="content">篮球课</view>
<view class="content">考勤正常</view>
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view>
</view>
</view>
<view class="li">
<view class="left">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image>
</view>
<view class="right">
<view class="content">篮球课</view>
<view class="content">考勤正常</view>
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view>
</view>
</view>
<view class="li">
<view class="left">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image>
</view>
<view class="right">
<view class="content">篮球课</view>
<view class="content">考勤正常</view>
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view>
</view>
</view>
</view>
<view class="title_box">普通考勤</view>
<view class="subhead_box">请假</view>
<view class="subhead_box">2025-01-01 00:00:00 - 2505-01-01 00:00:00</view>
<view class="ul">
<view class="li">
<view class="left">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image>
</view>
<view class="right">
<view class="content">普通考勤</view>
<view class="content">迟到</view>
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view>
</view>
</view>
<view class="li">
<view class="left">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image>
</view>
<view class="right">
<view class="content">普通考勤</view>
<view class="content">早退</view>
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view>
</view>
</view>
<view class="li">
<view class="left">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image>
</view>
<view class="right">
<view class="content">普通记录</view>
<view class="content">本周考勤情况周一到周五均按时打卡未请假综合表现良好
</view>
</view>
</view>
</view>
</scroll-view>
<view class="section_btn">
<view class="btn">请假</view>
</view>
</view>
</view>
</template>
<script>
import marketApi from '@/api/market.js';
import AQTabber from "@/components/AQ/AQTabber.vue"
export default {
components: {
AQTabber,
},
data() {
return {
//tab
optionTable: [
{
id: 1,
name: '考勤'
},
{
id: 2,
name: '请假'
},
{
id: 3,
name: '异常'
}
],
loading:false,//
lowerThreshold: 100,//
isReachedBottom: false,//|true=|false=
//
filteredData:{
page:1,//
limit:10,//
total:10,//
type: '1',//1=,2=,3=
},
tableList:[],//
}
},
onLoad(options) {},
onShow(){
this.init()//
},
methods: {
//
async init(){
await this.getList();
},
//tag
async segmented(e) {
//
await this.resetFilteredData()
this.filteredData.type = e.id//1=,2=,3=
await this.getList()
},
//()
loadMoreData() {
//
if (!this.isReachedBottom) {
this.isReachedBottom = true;//
this.getList();
}
},
//
async resetFilteredData() {
this.isReachedBottom = false; // 便
this.filteredData.page = 1//
this.filteredData.limit = 10//
this.filteredData.total = 10//
},
//
async getList(){
this.loading = true
let data = {...this.filteredData}
//
if(this.filteredData.page * this.filteredData.limit > this.filteredData.total){
this.loading = false
uni.showToast({
title: '暂无更多',
icon: 'none'
})
return
}
if(data.page == 1){
this.tableList = []
}
let res = await marketApi.myClient(data)
this.loading = false
this.isReachedBottom = false;
if (res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.tableList = this.tableList.concat(res.data.list.data); // 使 concat
console.log('列表',this.tableList)
this.filteredData.total = res.data.list.total
this.filteredData.page++
this.countArr = {
type_0:res.data.count[0],
type_1:res.data.count[1],
type_2:res.data.count[2],
type_3:res.data.count[3],
max_count:res.data.gh.max_count,
lq_count:res.data.gh.lq_count,
}
},
}
}
</script>
<style lang="less" scoped>
.main_box{
background: #292929 ;
}
//
.navbar_section{
display: flex;
justify-content: center;
align-items: center;
background: #29d3b4;
.title{
padding: 40rpx 0rpx;
/* 小程序端样式 */
// #ifdef MP-WEIXIN
padding: 80rpx 0rpx;
// #endif
font-size: 30rpx;
color: #315d55;
}
}
.main_section{
min-height: 100vh;
background: #292929 100%;
padding: 0 24rpx;
padding-top: 32rpx;
padding-bottom: 150rpx;
font-size: 28rpx;
.section_1{
color: #fff;
font-size: 28rpx;
.ul{
margin-top: 23rpx;
display: flex;
flex-direction: column;
gap: 24rpx;
.li{
display: flex;
align-items: center;
gap: 43rpx;
.left{
image{
width: 174rpx;
height: 174rpx;
border-radius: 24rpx;
background-color: #333333;
}
}
.right{
display: flex;
flex-direction: column;
gap: 18rpx;
.content{
font-size: 24rpx;
}
.content:nth-child(1){
font-size: 28rpx;
}
}
}
}
.title_box{
margin-top: 46rpx;
font-size: 28rpx;
}
.subhead_box{
margin-top: 22rpx;
font-size: 24rpx;
}
}
.section_btn{
display: flex;
justify-content: center;
.btn{
width: 722rpx;
height: 64rpx;
line-height: 64rpx;
border-radius: 8rpx;
background-color: rgba(32,202,175,1);
color: rgba(255,255,255,1);
font-size: 28rpx;
text-align: center;
}
}
}
</style>

112
pages/coach/my/schooling_statistics.vue

@ -5,8 +5,8 @@
<view class="main_section">
<view class="section_1">
<view class="ul">
<view class="li">
<view class="title">2021年3月</view>
<view class="li" v-for="(v,k) in sktjlist" :key="k">
<view class="title">{{v.month_date}}</view>
<view class="box">
<view class="top">
<view class="top_item">
@ -14,85 +14,20 @@
<view class="explain">月授课数/</view>
</view>
<view class="top_item">
<view class="num">4</view>
<view class="num">{{v.zsbj}}</view>
<view class="explain">总授班级/</view>
</view>
<view class="top_item">
<view class="num">1234</view>
<view class="num">{{v.yfzxy}}</view>
<view class="explain">月负责学员/</view>
</view>
</view>
<view class="bottom">
月到课率<text>88%</text>
</view>
</view>
</view>
<view class="li">
<view class="title">2021年3月</view>
<view class="box">
<view class="top">
<view class="top_item">
<view class="num">34</view>
<view class="explain">月授课数/</view>
</view>
<view class="top_item">
<view class="num">4</view>
<view class="explain">总授班级/</view>
</view>
<view class="top_item">
<view class="num">1234</view>
<view class="explain">月负责学员/</view>
</view>
</view>
<view class="bottom">
月到课率<text>88%</text>
</view>
</view>
</view>
<view class="li">
<view class="title">2021年3月</view>
<view class="box">
<view class="top">
<view class="top_item">
<view class="num">34</view>
<view class="explain">月授课数/</view>
</view>
<view class="top_item">
<view class="num">4</view>
<view class="explain">总授班级/</view>
</view>
<view class="top_item">
<view class="num">1234</view>
<view class="explain">月负责学员/</view>
</view>
</view>
<view class="bottom">
月到课率<text>88%</text>
</view>
</view>
</view>
<view class="li">
<view class="title">2021年3月</view>
<view class="box">
<view class="top">
<view class="top_item">
<view class="num">34</view>
<view class="explain">月授课数/</view>
</view>
<view class="top_item">
<view class="num">4</view>
<view class="explain">总授班级/</view>
</view>
<view class="top_item">
<view class="num">1234</view>
<view class="explain">月负责学员/</view>
</view>
</view>
<view class="bottom">
月到课率<text>88%</text>
月到课率<text>{{v.ydkl}}%</text>
</view>
</view>
</view>
</view>
</view>
</view>
@ -100,7 +35,7 @@
</template>
<script>
// import user from '@/api/user.js';
import memberApi from '@/api/member.js';
import AQTabber from "@/components/AQ/AQTabber.vue"
@ -110,6 +45,7 @@ export default {
},
data() {
return {
sktjlist:[],//
formData:{},
//
@ -151,7 +87,30 @@ export default {
},
onLoad() {
},
onShow(){
this.init()
},
methods: {
//
async init(){
await this.getList()
},
//
async getList(){
let res = await memberApi.jlSktj({})
if (res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.sktjlist = res.data//
},
//
clickCourse(e){
console.log(e)
@ -203,7 +162,14 @@ export default {
align-items: center;
background: #29d3b4;
.title{
padding: 20rpx 0;
padding: 40rpx 0rpx;
/* 小程序端样式 */
// #ifdef MP-WEIXIN
padding: 80rpx 0rpx;
// #endif
font-size: 30rpx;
color: #315d55;
}

331
pages/coach/student/info.vue

@ -9,63 +9,63 @@
<!--学员信息-->
<view class="user_section">
<view class="box">
<vie class="left">
<image class="pic" src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<view class="btn_box">
<view class="left">
<image class="pic" :src="$util.img(studentsInfo.header)"></image>
<view class="btn_box" v-if="checkExpireTime(studentsInfo.expire_time)">
<view class="btn">即将到期</view>
</view>
</vie>
<vie class="right">
<veiw class="item">
<view class="name">黄明明</view>
</view>
<view class="right">
<view class="item">
<view class="name">{{studentsInfo.name}}</view>
<view class="age">
13
{{studentsInfo.age}}
</view>
</veiw>
<view class="item">
<view class="title">家长姓名黄大呢</view>
</view>
<!-- <view class="item">-->
<!-- <view class="title">家长姓名黄大呢</view>-->
<!-- </view>-->
<view class="item">
<view class="title">家长电话18888888888</view>
<view class="title">电话{{studentsInfo.phone}}</view>
</view>
</vie>
</view>
</view>
</view>
<!--课程信息-->
<view class="course_section">
<view class="main">
<view class="course_box">
<view class="item">
<view class="title">篮球少儿课程</view>
</view>
<view class="item">
<image class="pic" src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<view class="name">包子皮</view>
</view>
<view class="item">
<view class="content">截止时间2020.05:25</view>
</view>
<view class="item">
<view class="content">已上课时24</view>
<view class="content">剩余课时24</view>
</view>
<view class="tag">
出勤高
</view>
<view class="btn">
延课一周
</view>
</view>
</view>
<view class="bg_box bg_top"></view>
<view class="bg_box bg_bottom"></view>
</view>
<!-- <view class="course_section">-->
<!-- <view class="main">-->
<!-- <view class="course_box">-->
<!-- <view class="item">-->
<!-- <view class="title">篮球少儿课程</view>-->
<!-- </view>-->
<!-- <view class="item">-->
<!-- <image class="pic" src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>-->
<!-- <view class="name">{{studentsInfo.name}}</view>-->
<!-- </view>-->
<!-- <view class="item">-->
<!-- <view class="content">截止时间{{studentsInfo.expire_time}}</view>-->
<!-- </view>-->
<!-- <view class="item">-->
<!-- <view class="content">已上课时{{studentsInfo.have_study_time}}</view>-->
<!-- <view class="content">剩余课时{{studentsInfo.end_study_time}}</view>-->
<!-- </view>-->
<!-- <view class="tag">-->
<!-- 出勤高-->
<!-- </view>-->
<!-- <view class="btn">-->
<!-- 延课一周-->
<!-- </view>-->
<!-- </view>-->
<!-- </view>-->
<!-- <view class="bg_box bg_top"></view>-->
<!-- <view class="bg_box bg_bottom"></view>-->
<!-- </view>-->
<view class="main_section">
@ -75,91 +75,48 @@
<view :class="['item', tabType=='2' ? 'select':'']" @click="tabChange(2)">体侧报告</view>
</view>
<!--作业列表-->
<view v-if="tabType=='1'" class="section_1">
<view class="ul">
<view class="li" @click="opebViewWorkDetails({id :1})">
<view class="left">
<view class="title">篮球少儿课</view>
<view class="date">上课时间2020.05.30 15:30 - 17:30</view>
</view>
<view class="right">
<view v-if="Atype==1" class="btn" style="background-color: #29D3B4;">作业完成</view>
<view v-else class="btn" style="background-color: #E2E2E2;">作业未提交</view>
</view>
</view>
<view class="li" @click="opebViewWorkDetails({id :1})">
<view class="left">
<view class="title">篮球少儿课</view>
<view class="date">上课时间2020.05.30 15:30 - 17:30</view>
</view>
<view class="right">
<view v-if="Atype==1" class="btn" style="background-color: #29D3B4;">作业完成</view>
<view v-else class="btn" style="background-color: #E2E2E2;">作业未提交</view>
</view>
</view>
<view class="li" @click="opebViewWorkDetails({id :1})">
<view class="left">
<view class="title">篮球少儿课</view>
<view class="date">上课时间2020.05.30 15:30 - 17:30</view>
</view>
<view class="right">
<view v-if="Atype==2" class="btn" style="background-color: #29D3B4;">作业完成</view>
<view v-else class="btn" style="background-color: #E2E2E2;">作业未提交</view>
</view>
</view>
<view class="li" @click="opebViewWorkDetails({id :1})">
<view class="li"
v-for="(v,k) in assignmentsList"
:key="k"
@click="opebViewWorkDetails(v)">
<view class="left">
<view class="title">篮球少儿课</view>
<view class="date">上课时间2020.05.30 15:30 - 17:30</view>
<view class="title">{{v.courses_name}}</view>
<view class="date">上课时间{{v.submit_time}}</view>
</view>
<view class="right">
<view v-if="Atype==1" class="btn" style="background-color: #29D3B4;">作业完成</view>
<view v-else class="btn" style="background-color: #E2E2E2;">作业未提交</view>
<view v-if="v.status==1" class="btn" style="background-color: #e2e2e2;">作业未提交</view>
<view v-else-if="v.status==2" class="btn" style="background-color: #a4adb3;">待批改</view>
<view v-else-if="v.status==3" class="btn" style="background-color: #29d3b4;">作业已完成</view>
</view>
</view>
</view>
</view>
<!--评测报告-->
<view v-if="tabType=='2'" class="section_2">
<view class="ul">
<view class="li" @click="openViewPhysicalExamination({id:1})">
<view class="top">
<view class="title">综合评分:96</view>
<view class="hint">打败了99%学员</view>
</view>
<view class="bottom">测试时间2020.05.30</view>
</view>
<view class="li" @click="openViewPhysicalExamination({id:1})">
<view class="top">
<view class="title">综合评分:96</view>
<view class="hint">打败了99%学员</view>
</view>
<view class="bottom">测试时间2020.05.30</view>
</view>
<view class="li" @click="openViewPhysicalExamination({id:1})">
<view class="top">
<view class="title">综合评分:96</view>
<view class="hint">打败了99%学员</view>
</view>
<view class="bottom">测试时间2020.05.30</view>
</view>
<view class="li" @click="openViewPhysicalExamination({id:1})">
<view class="top">
<view class="title">综合评分:96</view>
<view class="hint">打败了99%学员</view>
</view>
<view class="bottom">测试时间2020.05.30</view>
</view>
<view class="li" @click="openViewPhysicalExamination({id:1})">
<scroll-view
class="ul"
scroll-y="true"
:lower-threshold="lowerThreshold"
@scrolltolower="loadMoreData"
style="height: 65vh;"
>
<view
class="li"
v-for="(v,k) in surveyList"
:key="k" @click="openViewPhysicalExamination(v)"
>
<view class="top">
<view class="title">综合评分:96</view>
<view class="hint">打败了99%学员</view>
<view class="title">综合评分:{{v.score}}</view>
<!-- <view class="hint">打败了99%学员</view>-->
</view>
<view class="bottom">测试时间2020.05.30</view>
<view class="bottom">测试时间{{v.create_time}}</view>
</view>
</view>
</scroll-view>
</view>
@ -174,7 +131,7 @@
</template>
<script>
// import user from '@/api/user.js';
import memberApi from '@/api/member.js';
import AQTabber from "@/components/AQ/AQTabber.vue"
@ -184,14 +141,137 @@ export default {
},
data() {
return {
formData:{},
tabType:'1',//1=,2=
Atype:1,//1=,2=
students_id:'',//id
studentsInfo:{},//
assignmentsList:[],//
loading:false,//
lowerThreshold: 100,//
isReachedBottom: false,//|true=|false=
//
filteredData:{
page:1,//
limit:10,//
total:10,//
students_id: '',//id
},
surveyList:[],//
}
},
onLoad() {
onLoad(options) {
this.students_id = options.students_id//id
this.filteredData.students_id = options.students_id//id
},
onShow(){
this.init()//
},
methods: {
//
async init(){
//
await this.getStudentsInfo()
this.getSurveyList()
},
//
async getStudentsInfo(){
let data = {
students_id:this.students_id
}
let res = await memberApi.jlStudentsInfo(data)
if (res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.studentsInfo = res.data//
this.assignmentsList = res.data.assignments_list//
},
// expire_time 5
checkExpireTime(expireTime = '') {
if (!expireTime) {
return false
}
const expireDate = new Date(expireTime);
const currentDate = new Date();
//
const timeDifference = expireDate - currentDate;
const daysDifference = timeDifference / (1000 * 60 * 60 * 24);
if (daysDifference >= 5) {
return true
} else {
return false
}
},
//()
loadMoreData() {
//
if (!this.isReachedBottom) {
this.isReachedBottom = true;//
this.getSurveyList();
}
},
//
async resetFilteredData() {
this.isReachedBottom = false; // 便
this.filteredData.page = 1//
this.filteredData.limit = 10//
this.filteredData.total = 10//
},
//
async getSurveyList(){
this.loading = true
let data = {...this.filteredData}
//
if(this.filteredData.page * this.filteredData.limit > this.filteredData.total){
this.loading = false
uni.showToast({
title: '暂无更多',
icon: 'none'
})
return
}
if(data.page == 1){
this.surveyList = []
}
//-
let res = await memberApi.surveyList(data)
this.loading = false
this.isReachedBottom = false;
if (res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.surveyList = this.surveyList.concat(res.data.list.data); // 使 concat
console.log('列表',this.surveyList)
this.filteredData.total = res.data.list.total
this.filteredData.page++
},
//tab
tabChange(tabType) {
this.tabType = tabType
@ -212,8 +292,9 @@ export default {
//
openViewPhysicalExamination(item){
let survey_id = item.id
uni.navigateTo({
url: '/pages/coach/student/physical_examination'
url: `/pages/coach/student/physical_examination?survey_id=${survey_id}`
})
},
@ -241,7 +322,13 @@ export default {
align-items: center;
background: #292929;
.title{
padding: 20rpx 0;
padding: 40rpx 0rpx;
/* 小程序端样式 */
// #ifdef MP-WEIXIN
padding: 80rpx 0rpx;
// #endif
font-size: 30rpx;
color: #fff;
}
@ -476,8 +563,8 @@ export default {
.ul{
display: flex;
flex-direction: column;
gap: 12rpx;
.li{
margin-bottom: 12rpx;
padding: 30rpx 20rpx;
border: 1px solid #29D3B4;
border-radius: 18rpx;

41
pages/coach/student/physical_examination.vue

@ -1,47 +1,76 @@
<!--体测数据-->
<template>
<view class="overall">
<view class="date">2021年03月12日</view>
<view class="date">{{$util.formatToDateTime(surveyInfo.create_time,'Y-m-d')}}</view>
<view class="content">
<view class="circle-container">
<view class="card-con-txt1-left">
<image src="@/static/images/index/score.png" class="overlay-image"></image>
</view>
<view class="card-con-txt1-left-txt">90</view>
<view class="card-con-txt1-left-txt">{{surveyInfo.score}}</view>
<view class="card-con-txt1-left-txt top1">综合评分</view>
</view>
<view style="height: 170rpx;"></view>
<view style="display: flex;justify-content: space-around;">
<view style="text-align: center;">
<view style="color: #AAAAAA;font-size: 30rpx;padding: 15rpx 0;">身高 (CM)</view>
<view style="font-size: 55rpx;color: #29d3b4;">123</view>
<view style="font-size: 55rpx;color: #29d3b4;">{{surveyInfo.height}}</view>
</view>
<view style="text-align: center;">
<view style="color: #AAAAAA;font-size: 30rpx;padding: 15rpx 0;">体重 (KG)</view>
<view style="font-size: 55rpx;color: #29d3b4;">45</view>
<view style="font-size: 55rpx;color: #29d3b4;">{{surveyInfo.weight}}</view>
</view>
</view>
<view class="coach-message">
<view>
<image src="@/static/images/index/lv.png" class="drop-image"></image>
</view>
<view style="padding: 15rpx 0 0 5rpx;line-height: 1.6;font-size: 30rpx;color: #7F7F7F;">教练寄语教练寄语教练寄语教练寄语教练寄语教练寄语教练寄教练寄语教练寄语教练寄语教练寄语教练寄语教练教练寄语教练寄语教练寄语教练寄语练教练语教练寄教练寄语教练寄语教练寄语教练寄语教练寄语教练</view>
<view style="padding: 15rpx 0 0 5rpx;line-height: 1.6;font-size: 30rpx;color: #7F7F7F;">{{surveyInfo.content}}</view>
</view>
<view style="font-size: 45rpx;text-align: center;margin-top: 30%;">详细数据信息</view>
<!-- <view style="font-size: 45rpx;text-align: center;margin-top: 30%;">详细数据信息</view>-->
</view>
</view>
</template>
<script>
import memberApi from '@/api/member.js';
export default {
data() {
return {
survey_id:'',//id
surveyInfo:{},//
}
},
onLoad(options) {
this.survey_id = options.survey_id//id
},
onShow(){
this.init()
},
methods: {
//
async init(){
this.getInfo()
},
//
async getInfo(){
let data = {
survey_id:this.survey_id
}
let res = await memberApi.jlSurveyInfo(data)
if(res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.surveyInfo = res.data
},
}
}
</script>

152
pages/coach/student/work_details.vue

@ -1,68 +1,104 @@
<!--作业任务-->
<!--作业详情-->
<template>
<view>
<view class="top-style">
<image src="@/static/images/index/work_details.png" class="top-style-img">
</view>
<view>
<!-- 作业展示-->
<view class="top-style" v-if="infoData.student_file">
<video v-if="infoData.student_file_type == 2" class="pic" style="width: 100%;border-radius: 15rpx;" :src="$util.img(infoData.student_file)"></video>
<image v-else style="width: 100%;border-radius: 15rpx;" :src="$util.img(infoData.student_file)" mode="aspectFit"></image>
</view>
<view class="below-style">
<view class="head-img">
<fui-avatar width="80" src="https://img1.baidu.com/it/u=3598104138,3632108415&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=800"></fui-avatar>
<view class="head-text">智卓燕</view>
</view>
<view class="multi-line-ellipsis">
作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述</view>
</view>
</view>
<!-- 简练信息+作业描述-->
<view class="below-style">
<view class="head-img">
<!--教练头像-->
<fui-avatar width="80" :src="$util.img(infoData.coach_pic)"></fui-avatar>
<view class="head-text">{{infoData .coach_name}}</view>
</view>
<view class="multi-line-ellipsis" v-html="infoData.content_text"></view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
import memberApi from '@/api/member.js';
}
},
methods: {
}
}
export default {
data() {
return {
//
filteredData: {
id: '',//id
},
infoData:{},
}
},
onLoad(options) {
this.filteredData.id = options.id
},
onShow(){
this.init()//
},
methods: {
//
async init(){
this.getAssignmentsInfo()
},
//
async getAssignmentsInfo() {
let params = {...this.filteredData}
let res = await memberApi.assignmentsInfo(params)
if (res.code != 1) {
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.infoData = res.data
},
}
}
</script>
<style lang="less" scoped>
.top-style{
width: 92%;
height: 700rpx;
margin: auto;
display: flex;
align-items: center;
justify-content: center;
}
.top-style-img{
width: 120rpx;
height: 120rpx;
}
.below-style{
width: 92%;
margin: auto;
}
.head-img {
display: flex;
align-items: center;
padding: 10rpx 20rpx;
}
.head-text {
color: #333333;
font-size: 35rpx;
padding-left: 20rpx;
}
.multi-line-ellipsis {
color: #333333;
font-size: 29rpx;
padding: 5rpx 10rpx;
// display: -webkit-box;
// -webkit-box-orient: vertical;
// -webkit-line-clamp: 2;
// overflow: hidden;
// text-overflow: ellipsis;
}
.top-style{
width: 92%;
height: 700rpx;
margin: auto;
margin-top: 45rpx;
display: flex;
align-items: center;
justify-content: center;
}
.top-style-img{
width: 120rpx;
height: 120rpx;
}
.below-style{
width: 92%;
margin: auto;
}
.head-img {
display: flex;
align-items: center;
padding: 10rpx 20rpx;
}
.head-text {
color: #333333;
font-size: 35rpx;
padding-left: 20rpx;
}
.multi-line-ellipsis {
color: #333333;
font-size: 29rpx;
padding: 5rpx 10rpx;
// display: -webkit-box;
// -webkit-box-orient: vertical;
// -webkit-line-clamp: 2;
// overflow: hidden;
// text-overflow: ellipsis;
}
</style>

129
pages/common/article_info.vue

@ -0,0 +1,129 @@
<!--文章-详情-->
<template>
<view class="main_box">
<view class="main_section">
<view class="section_1">
<view class="titile">{{infoData.title}}</view>
<view class="content" v-html="infoData.content"></view>
</view>
</view>
</view>
</template>
<script>
import commonApi from '@/api/common.js';
export default {
components: {
},
data() {
return {
//
filteredData:{
id: '1',
},
infoData: {
title: '文章标题xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx111111',//
content: `
<p>aspectFit保持纵横比缩放图片使图片的长边能完全显示出来</p>
<p><img src="https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/cat-2.png" alt="uniapp" loading="lazy"></p>
`,//文章内容
},//
}
},
onLoad(options) {
this.filteredData.id = options.id//id
},
onShow(){
this.init()
},
//
async onPullDownRefresh() {
await this.getInfo()
},
methods: {
//
async init(){
await this.getInfo();
},
//
//
async getInfo(){
let res = await memberApi.courseInfo({
id: this.filteredData.id,
})
if(res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.infoData = res.data
},
}
}
</script>
<style lang="less" scoped>
.main_box {
background: #fff;
word-wrap: break-word; /* 允许长单词或 URL 换行 */
word-break: break-all; /* 强制所有字符换行 */
}
//
.navbar_section {
display: flex;
justify-content: center;
align-items: center;
background: #29d3b4;
.title {
padding: 20rpx 0;
font-size: 30rpx;
color: #315d55;
}
}
.main_section {
min-height: 100vh;
background: #fff;
padding: 0 0rpx;
padding-top: 32rpx;
padding-bottom: 150rpx;
font-size: 28rpx;
display: flex;
flex-direction: column;
gap: 20rpx;
.section {
background-color: #434544;
padding: 40rpx 40rpx;
}
.section_1{
padding: 0 24rpx;
display: flex;
flex-direction: column;
gap: 30rpx;
.titile{
font-size: 40rpx;
}
}
}
.describe {
color: #999999;
padding-left: 30rpx;
}
</style>

262
pages/common/contract_list.vue

@ -0,0 +1,262 @@
<!--合同列表-列表-->
<template>
<view class="main_box">
<view class="main_section">
<scroll-view
class="section_1"
scroll-y="true"
:lower-threshold="lowerThreshold"
@scrolltolower="loadMoreData"
style="height: 90vh;"
>
<view
class="item"
v-for="(v,k) in tableList"
:key="k"
>
<view class="top">
<view class="">企业合同</view>
<view class="btn" @click="downloadFile($util.img(v.file_data))">下载合同 <fui-icon name="arrowright" color="#A4ADB3" size="35"></fui-icon></view>
</view>
<view class="bottom">
<view class="box">
<view class="title">合同名称</view>
<view class="content">{{v.title}}</view>
</view>
<view class="box">
<view class="title">签署方</view>
<view class="content">{{v.signatory_a}}</view>
</view>
<view class="box">
<view class="title">签署方</view>
<view class="content">{{v.signatory_b}}</view>
</view>
</view>
</view>
</scroll-view>
</view>
</view>
</template>
<script>
import marketApi from '@/api/market.js';
import commonApi from '@/api/common.js';
export default {
components: {
},
data() {
return {
loading:false,//
lowerThreshold: 100,//
isReachedBottom: false,//|true=|false=
//
filteredData:{
page:1,//
limit:10,//
total:10,//
},
tableList:[],//
}
},
onLoad(options) {},
onShow(){
this.init()
},
//
async onPullDownRefresh() {
//
await this.resetFilteredData()
await this.getList()
},
methods: {
//
async init(){
await this.getList();
},
//()
loadMoreData() {
//
if (!this.isReachedBottom) {
this.isReachedBottom = true;//
this.getList();
}
},
//
async resetFilteredData() {
this.isReachedBottom = false; // 便
this.filteredData.page = 1//
this.filteredData.limit = 10//
this.filteredData.total = 10//
},
//
async getList(){
this.loading = true
let data = {...this.filteredData}
//
if(this.filteredData.page * this.filteredData.limit > this.filteredData.total){
this.loading = false
uni.showToast({
title: '暂无更多',
icon: 'none'
})
return
}
if(data.page == 1){
this.tableList = []
}
let res = await marketApi.contractsList(data)//
this.loading = false
this.isReachedBottom = false;
if (res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.tableList = this.tableList.concat(res.data.data); // 使 concat
// this.tableList.unshift(...res.data.data); //
console.log('列表',this.tableList)
this.filteredData.total = res.data.total
this.filteredData.page++
},
//
openViewArticleInfo(item) {
let id = item.id
let redirect = item.redirect//
uni.navigateTo({
url: `/pages/common/article_info?id=${id}`
})
},
//
async downloadFile(fileUrl) {
if (!fileUrl) {
this.$util.showToast({
title: '暂无电子发票'
});
return false;
}
uni.downloadFile({
url: fileUrl,
success: function (res) {
console.log('下载成功');
// uni.openDocument({
// filePath: res.tempFilePath,
// fileType: 'pdf',
// success: function (res) {
// console.log('');
// }
// });
}
});
}
}
}
</script>
<style lang="less" scoped>
.main_box {
background: #292929;
}
//
.navbar_section {
display: flex;
justify-content: center;
align-items: center;
background: #29d3b4;
.title {
padding: 20rpx 0;
font-size: 30rpx;
color: #315d55;
}
}
.main_section {
min-height: 100vh;
background: #292929 100%;
padding: 0 0rpx;
padding-top: 32rpx;
padding-bottom: 150rpx;
font-size: 28rpx;
display: flex;
flex-direction: column;
gap: 20rpx;
.section {
background-color: #434544;
padding: 40rpx 40rpx;
}
.section_1{
padding: 0 24rpx;
display: flex;
flex-direction: column;
.item{
margin-bottom: 38rpx;
display: flex;
flex-direction: column;
padding: 32rpx 24rpx;
border-radius: 14rpx;
background-color: #434544;
color: #fff;
.top{
font-size: 28rpx;
display: flex;
justify-content: space-between;
.btn{
display: flex;
align-items: center;
color: #29D3B4;
}
}
.bottom{
font-size: 26rpx;
margin-top: 25rpx;
display: flex;
flex-direction: column;
gap: 15rpx;
.box{
display: flex;
justify-content: space-between;
.title{
width: 180rpx;
}
.content{
width: 100%;
}
}
}
}
}
}
.describe {
color: #999999;
padding-left: 30rpx;
}
</style>

329
pages/common/im_chat_info.vue

@ -0,0 +1,329 @@
<!--聊天记录-列表-->
<template>
<view class="main_box">
<view class="main_section">
<scroll-view
class="section_1"
scroll-y="true"
:lower-threshold="lowerThreshold"
@scrolltolower="loadMoreData"
style="height: 80vh;"
>
<view class="ul">
<view class="item_box" v-for="(v,k) in tableList" :key="k">
<view class="time_section" v-if="v.create_time">{{v.create_time}}</view>
<view class="li" v-if="v.direction == `left`">
<view class="item left_item">
<view class="text_box">{{v.content}}</view>
</view>
<view class="item"></view>
</view>
<view class="li" v-if="v.direction == `right`">
<view class="item"></view>
<view class="item right_item">
<view class="text_box">{{v.content}}</view>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
<view class="input_section">
<view class="left_box">
<input class="input" v-model="formData.content" type="text" placeholder="请输入">
</view>
<view class="right_box">
<image @click="submitForm()" class="send_img" src="@/static/images/common/fa_song.png"></image>
</view>
</view>
</view>
</template>
<script>
import memberApi from '@/api/member.js';
import commonApi from '@/api/common.js';
import AQUplodeImgMulti from '@/components/AQ/AQUplodeImgMulti';
import AQTabber from "@/components/AQ/AQTabber"
export default {
components: {
AQTabber,
AQUplodeImgMulti,
},
data() {
return {
loading:false,//
lowerThreshold: 100,//
isReachedBottom: false,//|true=|false=
//
filteredData:{
page:1,//
limit:10,//
total:10,//
hair_staff_id: '',//id
},
tableList:[],//
formData: {
content: '',
},
}
},
onLoad(options) {
this.filteredData.hair_staff_id = options.hair_staff_id//id
},
onShow(){
this.init()
},
//
async onPullDownRefresh() {
//()
await this.loadMoreData()
},
methods: {
//
async init(){
await this.getList();
},
//()
loadMoreData() {
//
if (!this.isReachedBottom) {
this.isReachedBottom = true;//
this.getList();
}
},
//
async resetFilteredData() {
this.isReachedBottom = false; // 便
this.filteredData.page = 1//
this.filteredData.limit = 10//
this.filteredData.total = 10//
},
//
async getList(){
this.loading = true
let data = {...this.filteredData}
//
if(this.filteredData.page * this.filteredData.limit > this.filteredData.total){
this.loading = false
uni.showToast({
title: '暂无更多',
icon: 'none'
})
return
}
if(data.page == 1){
this.tableList = []
}
let res = await commonApi.getContactMessage(data)//
this.loading = false
this.isReachedBottom = false;
if (res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
// this.tableList = this.tableList.concat(res.data.data); // 使 concat
this.tableList.unshift(...res.data.data); //
console.log('列表',this.tableList)
this.filteredData.total = res.data.total
this.filteredData.page++
},
//######AQ######
//
AQUploadSuccess(res) {
console.log('接收AQ上传回调xxx1', res)
// 使 split
let _inputValue = []
if (res.filePathArr.length) {
_inputValue = res.filePathArr
}
this.formData[res.inputName] = _inputValue
// console.log('AQxxx1',res)
// console.log('AQxxx2',this.formData.member_store_certification_arr)
},
//
async submitForm() {
let data = {
hair_staff_id: this.filteredData.hair_staff_id,
content: this.formData.content,
}
if (!data.content) {
//
uni.showToast({
title: '请输入内容',
icon: 'none'
})
return
}
let res = await commonApi.sendMessage(data)
if (res.code != 1) {
uni.showToast({
title: res.msg,
icon: 'none'
})
} else {
let content = this.formData.content
this.formData.content = ''//
let msgData = {
"id": '',
"hair_staff_id": this.filteredData.hair_staff_id,
"closed_staff_id": '',
"content": content,
"status": 1,
"type": 2,
"create_time": "",
"redirect": null,
"title": null,
"direction": "right",
"show_time": ""
}
//
this.tableList = this.tableList.concat(msgData);
}
},
}
}
</script>
<style lang="less" scoped>
.main_box {
background: #292929;
}
//
.navbar_section {
display: flex;
justify-content: center;
align-items: center;
background: #29d3b4;
.title {
padding: 20rpx 0;
font-size: 30rpx;
color: #315d55;
}
}
.main_section {
min-height: 100vh;
background: #292929 100%;
padding: 0 0rpx;
padding-top: 32rpx;
padding-bottom: 150rpx;
font-size: 28rpx;
display: flex;
flex-direction: column;
gap: 20rpx;
.section {
background-color: #434544;
padding: 40rpx 40rpx;
}
.section_1{
color: #FFFFFF;
font-size: 28rpx;
padding: 0 24rpx;
display: flex;
flex-direction: column;
gap: 40rpx;
.ul{
.time_section{
text-align: center;
font-size: 28rpx;
color: #989898;
}
.li{
margin: 40rpx 0;
display: flex;
justify-content: space-between;
.item{
max-width: 70%;
padding: 32rpx;
border-radius: 32rpx;
word-wrap: break-word; /* 允许长单词或 URL 换行 */
word-break: break-all; /* 强制所有字符换行 */
.text_box{}
}
.left_item{
background-color: #f4f6f9;
color: #343434;
}
.right_item{
background-color: #1684fc;
color: #fff;
}
}
}
}
}
//
.input_section{
width: 100%;
position: fixed;
bottom: 0;
padding: 50rpx 50rpx;
display: flex;
justify-content:space-between;
align-items: center;
.left_box{
width: 70%;
.input{
background-color: #f4f6f9;
height: 88rpx;
padding: 28rpx;
font-size: 28rpx;
border-radius: 32rpx;
width: 532rpx;
color: #292929;
font-size: 28rpx;
}
}
.right_box{
border-radius: 50%;
background-color: #a2cefe;
width: 88rpx;
height: 88rpx;
display: flex;
justify-content: center;
align-items: center;
.send_img{
width: 36rpx;
height: 36rpx;
}
}
}
.describe {
color: #999999;
padding-left: 30rpx;
}
</style>

498
pages/common/my_attendance.vue

@ -0,0 +1,498 @@
<!--我的考勤-详情-->
<template>
<view class="main_box">
<fui-segmented-control
:values="optionTable"
:current="(Number(filteredData.status))"
type="text"
activeColor="#29d3b4"
color="#fff"
@click="segmented">
</fui-segmented-control>
<view class="main_section">
<!-- 教练端-->
<view v-if="userType == 1">
<!--全部-->
<scroll-view
class="section_1"
v-if="filteredData.status == '0'"
scroll-y="true"
:lower-threshold="lowerThreshold"
@scrolltolower="loadMoreData"
style="height: 80vh;"
>
<view class="ul">
<view class="li"
v-for="(v,k) in tableList"
:key="k"
>
<view class="left">
<image :src="$util.img(v.courses.thumbnail)" model="aspectFill"></image>
</view>
<view class="right">
<view class="content">{{v.courses.name}}</view>
<view class="content">
{{v.status == 1 ? '考勤正常':'请假'}}
</view>
<view class="content">{{v.add_time}} - {{v.end_time}}</view>
</view>
</view>
</view>
</scroll-view>
<!--考勤-->
<scroll-view
class="section_1"
v-if="filteredData.status == '1'"
scroll-y="true"
:lower-threshold="lowerThreshold"
@scrolltolower="loadMoreData"
style="height: 80vh;"
>
<view class="ul">
<view class="li"
v-for="(v,k) in tableList"
:key="k"
>
<view class="left">
<image :src="$util.img(v.courses.thumbnail)" model="aspectFill"></image>
</view>
<view class="right">
<view class="content">{{v.courses.name}}</view>
<view class="content">
{{v.status == 1 ? '考勤正常':'请假'}}
</view>
<view class="content">{{v.add_time}} - {{v.end_time}}</view>
</view>
</view>
</view>
</scroll-view>
<!--请假-->
<scroll-view
class="section_1"
v-if="filteredData.status == '2'"
scroll-y="true"
:lower-threshold="lowerThreshold"
@scrolltolower="loadMoreData"
style="height: 80vh;"
>
<view class="ul">
<view class="li"
v-for="(v,k) in tableList"
:key="k"
>
<view class="left">
<image :src="$util.img(v.courses.thumbnail)" model="aspectFill"></image>
</view>
<view class="right">
<view class="content">{{v.courses.name}}</view>
<view class="content">
{{v.status == 1 ? '考勤正常':'请假'}}
</view>
<view class="content">{{v.add_time}} - {{v.end_time}}</view>
</view>
</view>
</view>
</scroll-view>
</view>
<!-- 销售端-->
<view v-else>
<!--全部-->
<scroll-view
class="section_1"
v-if="filteredData.status == '0'"
scroll-y="true"
:lower-threshold="lowerThreshold"
@scrolltolower="loadMoreData"
style="height: 80vh;"
>
<view class="ul">
<view class="li"
v-for="(v,k) in tableList"
:key="k"
>
<view class="left">
<!-- <image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image>-->
</view>
<view class="right">
<view class="content">普通考勤</view>
<view class="content">
{{v.status == 1 ? '考勤正常':'请假'}}
</view>
<view class="content">{{v.add_time}} - {{v.end_time}}</view>
</view>
</view>
</view>
</scroll-view>
<!--考勤-->
<scroll-view
class="section_1"
v-if="filteredData.status == '1'"
scroll-y="true"
:lower-threshold="lowerThreshold"
@scrolltolower="loadMoreData"
style="height: 80vh;"
>
<view class="ul">
<view class="li"
v-for="(v,k) in tableList"
:key="k"
>
<view class="left">
<!-- <image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image>-->
</view>
<view class="right">
<view class="content">普通考勤</view>
<view class="content">
{{v.status == 1 ? '考勤正常':'请假'}}
</view>
<view class="content">{{v.add_time}} - {{v.end_time}}</view>
</view>
</view>
</view>
</scroll-view>
<!--请假-->
<scroll-view
class="section_1"
v-if="filteredData.status == '2'"
scroll-y="true"
:lower-threshold="lowerThreshold"
@scrolltolower="loadMoreData"
style="height: 80vh;"
>
<view class="ul">
<view class="li"
v-for="(v,k) in tableList"
:key="k"
>
<view class="left">
<!-- <image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image>-->
</view>
<view class="right">
<view class="content">普通考勤</view>
<view class="content">
{{v.status == 1 ? '考勤正常':'请假'}}
</view>
<view class="content">{{v.add_time}} - {{v.end_time}}</view>
</view>
</view>
</view>
</scroll-view>
</view>
<!--请假按钮-->
<view class="section_btn">
<view class="btn" @click="openShow()">请假</view>
</view>
</view>
<!-- 请假提示框-->
<fui-dialog :show="show" :content="content" maskClosable @click="onClick" @close="closeShow"></fui-dialog>
</view>
</template>
<script>
import commonApi from '@/api/common.js';
import marketApi from '@/api/market.js';
import AQTabber from "@/components/AQ/AQTabber.vue"
export default {
components: {
AQTabber,
},
data() {
return {
userType: '', //|1=,2=
//tab
optionTable: [
{
id: 0,
name: '全部'
},
{
id: 1,
name: '考勤'
},
{
id: 2,
name: '请假'
}
],
loading:false,//
lowerThreshold: 100,//
isReachedBottom: false,//|true=|false=
//
filteredData:{
page:1,//
limit:10,//
total:10,//
status:'0'//0 1 2
},
tableList:[],//
//
formData:{
date:'',//
},
//
show:false,//
content:'',//
}
},
onLoad(options) {},
onShow(){
this.init()//
},
methods: {
//
async init(){
this.userType = uni.getStorageSync('userType')
// this.userType = 2
this.getCurrentDate()//
await this.getList();
},
//
getCurrentDate() {
let now = new Date();
let year = now.getFullYear();
let month = String(now.getMonth() + 1).padStart(2, '0'); // 0 1
let day = String(now.getDate()).padStart(2, '0');
let res = `${year}-${month}-${day}`
this.content = `${res} 是否确认请假?`
this.formData.date = res
},
//tag
async segmented(e) {
console.log(e)
//
await this.resetFilteredData()
//e.id|0 1 2
let status = e.id
this.filteredData.status = String(status)
await this.getList()
},
//()
loadMoreData() {
//
if (!this.isReachedBottom) {
this.isReachedBottom = true;//
this.getList();
}
},
//
async resetFilteredData() {
this.isReachedBottom = false; // 便
this.filteredData.page = 1//
this.filteredData.limit = 10//
this.filteredData.total = 10//
},
//
async getList(){
this.loading = true
let data = {...this.filteredData}
//
if(this.filteredData.page * this.filteredData.limit > this.filteredData.total){
this.loading = false
uni.showToast({
title: '暂无更多',
icon: 'none'
})
return
}
if(data.page == 1){
this.tableList = []
}
let res = await commonApi.clockingList(data)
this.loading = false
this.isReachedBottom = false;
if (res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.tableList = this.tableList.concat(res.data.data); // 使 concat
console.log('列表',this.tableList)
this.filteredData.total = res.data.total
this.filteredData.page++
},
//
openShow(){
this.show = true
},
//
closeShow(){
this.show = false
},
//
onClick(e){
console.log('xxx',e)
if(e.index == 0){
//
this.closeShow()
}else{
//
this.submitRest()
}
},
//
async submitRest() {
this.closeShow()
let param = {...this.formData}
let res = await commonApi.clockingRest(param)
if (res.code != 1) {
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
uni.showToast({
title: '操作成功',
icon: 'success'
})
//1s
setTimeout(() => {
this.segmented({id:0})//
}, 1500)
}
}
}
</script>
<style lang="less" scoped>
.main_box{
background: #292929 ;
}
//
.navbar_section{
display: flex;
justify-content: center;
align-items: center;
background: #29d3b4;
.title{
padding: 40rpx 0rpx;
/* 小程序端样式 */
// #ifdef MP-WEIXIN
padding: 80rpx 0rpx;
// #endif
font-size: 30rpx;
color: #315d55;
}
}
.main_section{
min-height: 100vh;
background: #292929 100%;
padding: 0 24rpx;
padding-top: 32rpx;
padding-bottom: 150rpx;
font-size: 28rpx;
.section_1{
color: #fff;
font-size: 28rpx;
.ul{
margin-top: 23rpx;
display: flex;
flex-direction: column;
gap: 24rpx;
.li{
display: flex;
align-items: center;
gap: 43rpx;
.left{
image{
width: 174rpx;
height: 174rpx;
border-radius: 24rpx;
background-color: #333333;
}
}
.right{
display: flex;
flex-direction: column;
gap: 18rpx;
.content{
font-size: 24rpx;
}
.content:nth-child(1){
font-size: 28rpx;
}
}
}
}
.title_box{
margin-top: 46rpx;
font-size: 28rpx;
}
.subhead_box{
margin-top: 22rpx;
font-size: 24rpx;
}
}
.section_btn{
display: flex;
justify-content: center;
.btn{
width: 722rpx;
height: 64rpx;
line-height: 64rpx;
border-radius: 8rpx;
background-color: rgba(32,202,175,1);
color: rgba(255,255,255,1);
font-size: 28rpx;
text-align: center;
}
}
}
</style>

262
pages/common/my_message.vue

@ -0,0 +1,262 @@
<!--我的消息-列表-->
<template>
<view class="main_box">
<view class="main_section">
<view class="section_1">
<!-- <view class="item" @click="openViewSysMsgList()">-->
<!-- <view class="left">-->
<!-- <image class="pic" src="@/static/images/common/xi_tong_xiao_xi.png"></image>-->
<!-- <view>系统消息</view>-->
<!-- </view>-->
<!-- <view class="right">-->
<!-- <view>99</view>-->
<!-- <fui-icon name="arrowright" :size="60"></fui-icon>-->
<!-- </view>-->
<!-- </view>-->
<view
v-for="(v,k) in contactList"
:key="k"
class="item"
@click="openViewImChatInfo(v)"
>
<view class="left">
<image
v-if="v.type==2"
class="pic"
:src="(v.header ? $util.img(v.header) : `@/static/images/common/yong_hu.png`)"
model="aspectFit"
></image>
<image v-else class="pic" src="@/static/images/common/xi_tong_xiao_xi.png"></image>
<view>{{v.name}}</view>
</view>
<view class="right">
<view>{{v.count >= 99 ? '99':v.count}}</view>
<fui-icon name="arrowright" :size="60"></fui-icon>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import memberApi from '@/api/member.js';
import commonApi from '@/api/common.js';
import AQUplodeImgMulti from '@/components/AQ/AQUplodeImgMulti';
import AQTabber from "@/components/AQ/AQTabber"
export default {
components: {
AQTabber,
AQUplodeImgMulti,
},
data() {
return {
formData: {
images_arr: [],
images: '',
content: '',
mailbox: '',
},
//
contactList:[],
}
},
onLoad() {
},
onShow() {
this.init();
},
methods: {
//
async init(){
this.getContactList()
},
//
async getContactList(){
let res = await commonApi.getContactList()
console.log('获取联系人列表', res)
if (res.code != 1) {
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.contactList = res.data
},
//######AQ######
//
AQUploadSuccess(res) {
console.log('接收AQ上传回调xxx1', res)
// 使 split
let _inputValue = []
if (res.filePathArr.length) {
_inputValue = res.filePathArr
}
this.formData[res.inputName] = _inputValue
// console.log('AQxxx1',res)
// console.log('AQxxx2',this.formData.member_store_certification_arr)
},
async submitForm() {
let data = {...this.formData}
data.images = data.images_arr.join(',')
if (!data.content) {
//
uni.showToast({
title: '反馈内容为必填项',
icon: 'none'
})
return
}
let res = await memberApi.setFeedback(data)
if (res.code != 1) {
uni.showToast({
title: res.msg,
icon: 'none'
})
} else {
uni.showToast({
title: '提交成功',
icon: 'none'
})
//1s
setTimeout(() => {
this.$util.openHomeView();
}, 1000);
}
},
//-
openViewSysMsgList(e){
let hair_staff_id = e.hair_staff_id//id
uni.navigateTo({
url: `/pages/common/sys_msg_list?hair_staff_id=${hair_staff_id}`
})
},
//-
openViewImChatInfo(e){
if(e.type == 1){
//
this.openViewSysMsgList(e)
}else{
//
let hair_staff_id = e.hair_staff_id//id
uni.navigateTo({
url: `/pages/common/im_chat_info?hair_staff_id=${hair_staff_id}`
})
}
},
}
}
</script>
<style lang="less" scoped>
.main_box {
background: #292929;
}
//
.navbar_section {
display: flex;
justify-content: center;
align-items: center;
background: #29d3b4;
.title {
padding: 20rpx 0;
font-size: 30rpx;
color: #315d55;
}
}
.main_section {
min-height: 100vh;
background: #292929 100%;
padding: 0 0rpx;
padding-top: 32rpx;
padding-bottom: 150rpx;
font-size: 28rpx;
display: flex;
flex-direction: column;
gap: 20rpx;
.section {
background-color: #434544;
padding: 40rpx 40rpx;
}
.section_1{
padding: 0 24rpx;
display: flex;
flex-direction: column;
gap: 38rpx;
.item{
display: flex;
justify-content: space-between;
align-items: center;
padding: 40rpx 18rpx 36rpx;
border-radius: 14rpx;
background-color: rgba(255,255,255,1);
border: 2rpx solid rgba(187,187,187,1);
.left{
display: flex;
align-items: center;
gap: 16rpx;
.pic{
width: 68rpx;
height: 68rpx;
border-radius: 50%;
}
view{
color: #D9001B;
font-size: 32rpx;
}
}
.right{
display: flex;
align-items: center;
view{
display: flex;
justify-content: center;
align-items: center;
width: 50rpx;
height: 50rpx;
padding: 5rpx;
border: 1px solid #BBBBBB;
border-radius: 50%;
color: #D9001B;
}
}
}
}
}
.describe {
color: #999999;
padding-left: 30rpx;
}
</style>

225
pages/common/sys_msg_list.vue

@ -0,0 +1,225 @@
<!--系统消息-列表-->
<template>
<view class="main_box">
<view class="main_section">
<scroll-view
class="section_1"
scroll-y="true"
:lower-threshold="lowerThreshold"
@scrolltolower="loadMoreData"
style="height: 90vh;"
>
<view
class="item"
v-for="(v,k) in tableList"
:key="k"
@click="openViewArticleInfo(v)"
>
<view class="title">{{v.title}}</view>
<!-- <image-->
<!-- class="img_box"-->
<!-- :src="$util.img('/upload/attachment/image/202504/02/1743562333d1bb6666f969da1b7170381d0845153e_local.png')"-->
<!-- model="aspectFit"-->
<!-- ></image>-->
<view class="content" v-html="v.content"></view>
<view class="time">{{v.show_time}}</view>
</view>
</scroll-view>
</view>
</view>
</template>
<script>
import commonApi from '@/api/common.js';
export default {
components: {
},
data() {
return {
loading:false,//
lowerThreshold: 100,//
isReachedBottom: false,//|true=|false=
//
filteredData:{
page:1,//
limit:10,//
total:10,//
hair_staff_id: '',//id
},
tableList:[],//
}
},
onLoad(options) {
this.filteredData.hair_staff_id = options.hair_staff_id//id
},
onShow(){
this.init()
},
//
async onPullDownRefresh() {
//
await this.resetFilteredData()
await this.getList()
},
methods: {
//
async init(){
await this.getList();
},
//()
loadMoreData() {
//
if (!this.isReachedBottom) {
this.isReachedBottom = true;//
this.getList();
}
},
//
async resetFilteredData() {
this.isReachedBottom = false; // 便
this.filteredData.page = 1//
this.filteredData.limit = 10//
this.filteredData.total = 10//
},
//
async getList(){
this.loading = true
let data = {...this.filteredData}
//
if(this.filteredData.page * this.filteredData.limit > this.filteredData.total){
this.loading = false
uni.showToast({
title: '暂无更多',
icon: 'none'
})
return
}
if(data.page == 1){
this.tableList = []
}
let res = await commonApi.getContactMessage(data)//
this.loading = false
this.isReachedBottom = false;
if (res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.tableList = this.tableList.concat(res.data.data); // 使 concat
// this.tableList.unshift(...res.data.data); //
console.log('列表',this.tableList)
this.filteredData.total = res.data.total
this.filteredData.page++
},
//
openViewArticleInfo(item) {
let id = item.id
let redirect = item.redirect//
uni.navigateTo({
url: `/pages/common/article_info?id=${id}`
})
},
}
}
</script>
<style lang="less" scoped>
.main_box {
background: #292929;
}
//
.navbar_section {
display: flex;
justify-content: center;
align-items: center;
background: #29d3b4;
.title {
padding: 20rpx 0;
font-size: 30rpx;
color: #315d55;
}
}
.main_section {
min-height: 100vh;
background: #292929 100%;
padding: 0 0rpx;
padding-top: 32rpx;
padding-bottom: 150rpx;
font-size: 28rpx;
display: flex;
flex-direction: column;
gap: 20rpx;
.section {
background-color: #434544;
padding: 40rpx 40rpx;
}
.section_1{
padding: 0 24rpx;
display: flex;
flex-direction: column;
.item{
margin-bottom: 38rpx;
display: flex;
flex-direction: column;
padding: 32rpx 24rpx;
border-radius: 14rpx;
background-color: rgba(255,255,255,1);
border: 2rpx solid rgba(187,187,187,1);
color: #4F4F4F;
font-size: 32rpx;
.title{
}
.img_box{
margin-top: 30rpx;
width: 100%;
}
.content{
margin-top: 30rpx;
}
.time{
display: flex;
justify-content: flex-end;
margin-top: 36rpx;
}
}
}
}
.describe {
color: #999999;
padding-left: 30rpx;
}
</style>

1645
pages/market/clue/add_clues.vue

File diff suppressed because it is too large

713
pages/market/clue/clue_info.vue

@ -1,338 +1,407 @@
<!--我的-首页-->
<!--客户详情-->
<template>
<view class="assemble">
<view class="main_box">
<view style="height: 20rpx;background: #29D3B4;"></view>
<view class="count_section">
<view class="main">
<view class="course_box">
<view class="course_box_top">
<view class="course_box_top_top">
<image class="pic" src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<view class="name">包子皮</view>
</view>
<view class="course_box_top_below">
<view class="course_box_top_below-left">
<view>08-30 14:25  跟进</view>
<view style="display: flex;align-items: center;" v-if="false">
<view style="padding-left: 30rpx;">
<image src="@/static/images/index/intention1.png" class="drop-image-x"></image>
</view>
<view class="title-x">意向</view>
</view>
<view style="display: flex;align-items: center;" v-if="true">
<view style="padding-left: 30rpx;">
<image src="@/static/images/index/intention3.png" class="drop-image-x"></image>
</view>
<view class="title-x">意向</view>
</view>
<view style="display: flex;align-items: center;" v-if="false">
<view style="padding-left: 30rpx;">
<image src="@/static/images/index/intention2.png" class="drop-image-x"></image>
</view>
<view class="title-x">意向</view>
</view>
</view>
<view class="course_box_top_below-right">
<view>
<image src="@/static/images/index/star.png" class="drop-image-star"></image>
</view>
<view class="title-x">重点关注</view>
</view>
</view>
</view>
<view class="course_box_centre"></view>
<view class="course_box_below">
<view :class="{'selected-text': switch_tags_type === 1, 'text': switch_tags_type !== 1}" @click="switch_tags(1)">基本资料</view>
<view :class="{'selected-text': switch_tags_type === 2, 'text': switch_tags_type !== 2}" @click="switch_tags(2)">跟进记录</view>
<view :class="{'selected-text': switch_tags_type === 3, 'text': switch_tags_type !== 3}" @click="switch_tags(3)">通话记录</view>
<view :class="{'selected-text': switch_tags_type === 4, 'text': switch_tags_type !== 4}" @click="switch_tags(4)">在籍客户</view>
</view>
</view>
</view>
<view class="bg_box bg_top"></view>
<view class="bg_box bg_bottom"></view>
</view>
<view class="basic-information" v-if="switch_tags_type == 1">
<view class="basic-message">基本信息</view>
<view class="basic-message-div">
<view class="basic-message-div-txt">
<view>客户编号</view>
<view>1254545</view>
</view>
<view class="basic-message-div-txt">
<view>年龄</view>
<view>12</view>
</view>
<view class="basic-message-div-txt">
<view>学校</view>
<view>幸福小学</view>
</view>
<view class="basic-message-div-txt">
<view>年级</view>
<view>小学 五年级</view>
</view>
<view class="basic-message-div-txt">
<view>班级</view>
<view>3</view>
</view>
<view class="basic-message-div-txt">
<view>小区</view>
<view>幸福小区</view>
</view>
<view class="basic-message-div-txt">
<view>客户来源</view>
<view>地推</view>
</view>
<view class="basic-message-div-txt">
<view>客户归属</view>
<view>赵小刚 (已锁定到期时间10/30)</view>
</view>
</view>
<view class="basic-message">
<view>联系人信息<span style="padding-left: 10rpx;color: #7F7F7F;">选中为客户首联系人</span></view>
<view style="color: #45C59F;font-size: 24rpx;">添加</view>
</view>
<view class="basic-message-div">
<view class="basic-message-div-txt">
<view>包念念</view>
<view>1888888888</view>
</view>
<view class="basic-message-div-txt">
<view>张铭行</view>
<view>1888888888</view>
</view>
</view>
<view class="basic-message">附加信息</view>
<view class="basic-message-div">
<view class="basic-message-div-txt">
<view>已成交次数</view>
<view>3</view>
</view>
<view class="basic-message-div-txt">
<view>体验课程</view>
<view>1</view>
</view>
<view class="basic-message-div-txt">
<view>客户标签</view>
<view>XXXX,XXXX,XXXX</view>
</view>
</view>
<view style="height: 200rpx;"></view>
</view>
<view class="follow-records" v-if="switch_tags_type == 2">
<view>
<view class="basic-message">08-23</view>
<view class="follow-records-list">
<view style="display: flex;justify-content: space-between;padding: 16rpx 16rpx 16rpx 60rpx;">
<view>赵小刚</view>
<view>跟进(电话)</view>
</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;">客户对产品意向很高但是希望价格能有优惠</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;">2019-08-23 22:31</view>
</view>
</view>
<view>
<view class="basic-message">08-23</view>
<view class="follow-records-list">
<view style="display: flex;justify-content: space-between;padding: 16rpx 16rpx 16rpx 60rpx;">
<view>赵小刚</view>
<view>跟进(电话)</view>
</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;">客户对产品意向很高但是希望价格能有优惠</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;">2019-08-23 22:31</view>
</view>
</view>
<view>
<view class="basic-message">08-23</view>
<view class="follow-records-list">
<view style="display: flex;justify-content: space-between;padding: 16rpx 16rpx 16rpx 60rpx;">
<view>赵小刚</view>
<view>跟进(电话)</view>
</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;">客户对产品意向很高但是希望价格能有优惠</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;">2019-08-23 22:31</view>
</view>
</view>
<view style="height: 200rpx;"></view>
</view>
<view class="call-log" v-if="switch_tags_type == 3">
<view>
<view class="basic-message">08-23</view>
<view class="follow-records-list">
<view style="display: flex;justify-content: space-between;padding: 16rpx 16rpx 16rpx 60rpx;">
<view>赵小刚</view>
<view>2019-08-23 22:31</view>
</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;">呼叫类型主叫</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;">呼叫号码18888888888</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;">呼叫对象包念念</view>
</view>
</view>
<view>
<view class="basic-message">08-23</view>
<view class="follow-records-list">
<view style="display: flex;justify-content: space-between;padding: 16rpx 16rpx 16rpx 60rpx;">
<view>赵小刚</view>
<view>2019-08-23 22:31</view>
</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;">呼叫类型主叫</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;">呼叫号码18888888888</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;">呼叫对象包念念</view>
</view>
</view>
<view>
<view class="basic-message">08-23</view>
<view class="follow-records-list">
<view style="display: flex;justify-content: space-between;padding: 16rpx 16rpx 16rpx 60rpx;">
<view>赵小刚</view>
<view>2019-08-23 22:31</view>
</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;">呼叫类型主叫</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;">呼叫号码18888888888</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;">呼叫对象包念念</view>
</view>
</view>
<view style="height: 200rpx;"></view>
</view>
<view class="registered-clients" v-if="switch_tags_type == 4">
<view class="search">
<view :class="{'selected': select_type === 1, 'not-selected': select_type !== 1}" @click="getSelect(1)">全部(320)</view>
<view :class="{'selected': select_type === 2, 'not-selected': select_type !== 2}" @click="getSelect(2)">同校(8)</view>
<view :class="{'selected': select_type === 3, 'not-selected': select_type !== 3}" @click="getSelect(3)">同班(15)</view>
<view :class="{'selected': select_type === 4, 'not-selected': select_type !== 4}" @click="getSelect(4)">同小区(12)</view>
</view>
<view style="margin: 16rpx;">
<view class="follow-records-list">
<view class="same-community" v-if="true">
同小区
</view>
<view class="coeducation" v-if="false">
同校
</view>
<view class="coeducation" v-if="false">
同班
</view>
<view style="display: flex;justify-content: space-between;padding: 16rpx 16rpx 16rpx 60rpx;">
<view>包子皮</view>
</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;display: flex;justify-content: space-between;">
<view>合同联系人包念念<span style="font-size: 20rpx;color: #a47332;padding-left: 12rpx;">妈妈</span></view>
<view>课程课程名称1</view>
</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;">2020-08-30 签单</view>
</view>
</view>
<view style="margin: 16rpx;">
<view class="follow-records-list">
<view class="same-community" v-if="false">
同小区
</view>
<view class="coeducation" v-if="true">
同校
</view>
<view class="coeducation" v-if="false">
同班
</view>
<view style="display: flex;justify-content: space-between;padding: 16rpx 16rpx 16rpx 60rpx;">
<view>包子皮</view>
</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;display: flex;justify-content: space-between;">
<view>合同联系人包念念<span style="font-size: 20rpx;color: #a47332;padding-left: 12rpx;">妈妈</span></view>
<view>课程课程名称1</view>
</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;">2020-08-30 签单</view>
</view>
</view>
<view style="margin: 16rpx;">
<view class="follow-records-list">
<view class="same-community" v-if="false">
同小区
</view>
<view class="coeducation" v-if="false">
同校
</view>
<view class="coeducation" v-if="true">
同班
</view>
<view style="display: flex;justify-content: space-between;padding: 16rpx 16rpx 16rpx 60rpx;">
<view>包子皮</view>
</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;display: flex;justify-content: space-between;">
<view>合同联系人包念念<span style="font-size: 20rpx;color: #a47332;padding-left: 12rpx;">妈妈</span></view>
<view>课程课程名称1</view>
</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;">2020-08-30 签单</view>
</view>
</view>
<view style="margin: 16rpx;">
<view class="follow-records-list">
<view class="same-community" v-if="true">
同小区
</view>
<view class="coeducation" v-if="false">
同校
</view>
<view class="coeducation" v-if="false">
同班
</view>
<view style="display: flex;justify-content: space-between;padding: 16rpx 16rpx 16rpx 60rpx;">
<view>包子皮</view>
</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;display: flex;justify-content: space-between;">
<view>合同联系人包念念<span style="font-size: 20rpx;color: #a47332;padding-left: 12rpx;">妈妈</span></view>
<view>课程课程名称1</view>
</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;">2020-08-30 签单</view>
</view>
</view>
<view style="margin: 16rpx;">
<view class="follow-records-list">
<view class="same-community" v-if="true">
同小区
</view>
<view class="coeducation" v-if="false">
同校
</view>
<view class="coeducation" v-if="false">
同班
</view>
<view style="display: flex;justify-content: space-between;padding: 16rpx 16rpx 16rpx 60rpx;">
<view>包子皮</view>
</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;display: flex;justify-content: space-between;">
<view>合同联系人包念念<span style="font-size: 20rpx;color: #a47332;padding-left: 12rpx;">妈妈</span></view>
<view>课程课程名称1</view>
</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;">2020-08-30 签单</view>
</view>
</view>
<view style="height: 200rpx;"></view>
</view>
<view class="bottom-label">
<view>写作跟进</view>
<view>新建任务</view>
<view>拨打电话</view>
<view>更多操作</view>
</view>
</view>
</view>
<view class="assemble">
<view class="main_box">
<view style="height: 20rpx;background: #29D3B4;"></view>
<view class="count_section">
<view class="main">
<view class="course_box">
<view class="course_box_top">
<view class="course_box_top_top">
<!-- <image class="pic" src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>-->
<view class="name">{{ clientInfo.student_name }}</view>
</view>
<view class="course_box_top_below">
<view class="course_box_top_below-left">
<view>{{ clientInfo.follow.follow_up_time}} 跟进</view>
<view style="display: flex;align-items: center;">
<view style="padding-left: 30rpx;">
<image v-if="clientInfo.follow.initial_customer_intent == 'A'"
src="@/static/images/index/lvs.png" class="drop-image-x"></image>
<image v-else-if="clientInfo.follow.initial_customer_intent == 'B'"
src="@/static/images/index/intention2.png" class="drop-image-x"></image>
<image v-else="clientInfo.follow.initial_customer_intent == 'C'"
src="@/static/images/index/intention1.png" class="drop-image-x"></image>
</view>
<view class="title-x">意向{{ clientInfo.follow.initial_customer_intent }}</view>
</view>
</view>
<view class="course_box_top_below-right">
<view v-if="clientInfo.is_zdgz == 1">
<image src="@/static/images/index/star.png" class="drop-image-star"></image>
</view>
<view class="title-x">重点关注</view>
</view>
</view>
</view>
<view class="course_box_centre"></view>
<view class="course_box_below">
<view :class="{'selected-text': switch_tags_type === 1, 'text': switch_tags_type !== 1}"
@click="switch_tags(1)">基本资料
</view>
<view :class="{'selected-text': switch_tags_type === 2, 'text': switch_tags_type !== 2}"
@click="switch_tags(2)">跟进记录
</view>
<view :class="{'selected-text': switch_tags_type === 3, 'text': switch_tags_type !== 3}"
@click="switch_tags(3)">通话记录
</view>
</view>
</view>
</view>
<view class="bg_box bg_top"></view>
<view class="bg_box bg_bottom"></view>
</view>
<!-- 基本资料-->
<view class="basic-information" v-if="switch_tags_type == 1">
<view class="basic-message">基本信息</view>
<view class="basic-message-div">
<view class="basic-message-div-txt">
<view>来源渠道</view>
<view>{{clientInfo.source_channel}}</view>
</view>
<view class="basic-message-div-txt">
<view>来源</view>
<view>{{clientInfo.customer_source}}</view>
</view>
<view class="basic-message-div-txt">
<view>顾问</view>
<view>{{clientInfo.gw}}</view>
</view>
<view class="basic-message-div-txt">
<view>学生姓名</view>
<view>{{clientInfo.student_name}}</view>
</view>
<view class="basic-message-div-txt">
<view>性别</view>
<view>{{clientInfo.sex == 1 ? '男':'女'}}</view>
</view>
</view>
<view class="basic-message">附加信息</view>
<view class="basic-message-div">
<view class="basic-message-div-txt">
<view>已成交次数</view>
<view>{{clientInfo.cj_count}}</view>
</view>
<view class="basic-message-div-txt">
<view>体验课程</view>
<view>{{clientInfo.ty_count}}</view>
</view>
</view>
<view style="height: 200rpx;"></view>
</view>
<!-- 跟进记录-->
<view class="follow-records" v-if="switch_tags_type == 2">
<view v-for="(v,k) in followList" :key="k">
<view class="basic-message">{{$util.formatToDateTime(v.follow_up_time,'m-d')}}</view>
<view class="follow-records-list">
<view style="display: flex;justify-content: space-between;padding: 16rpx 16rpx 16rpx 60rpx;">
<view>{{v.student_name}}</view>
<view>跟进({{v.student_phone}})</view>
</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;">{{v.follow_up_content}}</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;">{{v.follow_up_time}}</view>
</view>
</view>
<view style="height: 200rpx;"></view>
</view>
<!-- 通话记录-->
<view class="call-log" v-if="switch_tags_type == 3">
<view style="margin-top: 20rpx" v-for="(v,k) in listCallUp" :key="k">
<!-- <view class="basic-message">08-23</view>-->
<view class="follow-records-list">
<view style="display: flex;justify-content: space-between;padding: 16rpx 16rpx 16rpx 60rpx;">
<view>{{v.name}}</view>
<view>{{v.create_time}}</view>
</view>
<view style="display: flex;justify-content: space-between;padding: 16rpx 16rpx 16rpx 60rpx;">
<view>呼叫对象{{v.student_name}}</view>
<view>呼叫号码{{v.student_phone}}</view>
</view>
</view>
</view>
<view style="height: 200rpx;"></view>
</view>
<!-- 在籍客户-->
<view class="registered-clients" v-if="switch_tags_type == 4">
<view class="search">
<view :class="{'selected': select_type === 1, 'not-selected': select_type !== 1}" @click="getSelect(1)">
全部(320)
</view>
<view :class="{'selected': select_type === 2, 'not-selected': select_type !== 2}" @click="getSelect(2)">
同校(8)
</view>
<view :class="{'selected': select_type === 3, 'not-selected': select_type !== 3}" @click="getSelect(3)">
同班(15)
</view>
<view :class="{'selected': select_type === 4, 'not-selected': select_type !== 4}" @click="getSelect(4)">
同小区(12)
</view>
</view>
<view style="margin: 16rpx;">
<view class="follow-records-list">
<view class="same-community" v-if="true">
同小区
</view>
<view class="coeducation" v-if="false">
同校
</view>
<view class="coeducation" v-if="false">
同班
</view>
<view style="display: flex;justify-content: space-between;padding: 16rpx 16rpx 16rpx 60rpx;">
<view>包子皮</view>
</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;display: flex;justify-content: space-between;">
<view>合同联系人包念念<span style="font-size: 20rpx;color: #a47332;padding-left: 12rpx;">妈妈</span></view>
<view>课程课程名称1</view>
</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;">2020-08-30 签单</view>
</view>
</view>
<view style="margin: 16rpx;">
<view class="follow-records-list">
<view class="same-community" v-if="false">
同小区
</view>
<view class="coeducation" v-if="true">
同校
</view>
<view class="coeducation" v-if="false">
同班
</view>
<view style="display: flex;justify-content: space-between;padding: 16rpx 16rpx 16rpx 60rpx;">
<view>包子皮</view>
</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;display: flex;justify-content: space-between;">
<view>合同联系人包念念<span style="font-size: 20rpx;color: #a47332;padding-left: 12rpx;">妈妈</span></view>
<view>课程课程名称1</view>
</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;">2020-08-30 签单</view>
</view>
</view>
<view style="margin: 16rpx;">
<view class="follow-records-list">
<view class="same-community" v-if="false">
同小区
</view>
<view class="coeducation" v-if="false">
同校
</view>
<view class="coeducation" v-if="true">
同班
</view>
<view style="display: flex;justify-content: space-between;padding: 16rpx 16rpx 16rpx 60rpx;">
<view>包子皮</view>
</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;display: flex;justify-content: space-between;">
<view>合同联系人包念念<span style="font-size: 20rpx;color: #a47332;padding-left: 12rpx;">妈妈</span></view>
<view>课程课程名称1</view>
</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;">2020-08-30 签单</view>
</view>
</view>
<view style="margin: 16rpx;">
<view class="follow-records-list">
<view class="same-community" v-if="true">
同小区
</view>
<view class="coeducation" v-if="false">
同校
</view>
<view class="coeducation" v-if="false">
同班
</view>
<view style="display: flex;justify-content: space-between;padding: 16rpx 16rpx 16rpx 60rpx;">
<view>包子皮</view>
</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;display: flex;justify-content: space-between;">
<view>合同联系人包念念<span style="font-size: 20rpx;color: #a47332;padding-left: 12rpx;">妈妈</span></view>
<view>课程课程名称1</view>
</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;">2020-08-30 签单</view>
</view>
</view>
<view style="margin: 16rpx;">
<view class="follow-records-list">
<view class="same-community" v-if="true">
同小区
</view>
<view class="coeducation" v-if="false">
同校
</view>
<view class="coeducation" v-if="false">
同班
</view>
<view style="display: flex;justify-content: space-between;padding: 16rpx 16rpx 16rpx 60rpx;">
<view>包子皮</view>
</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;display: flex;justify-content: space-between;">
<view>合同联系人包念念<span style="font-size: 20rpx;color: #a47332;padding-left: 12rpx;">妈妈</span></view>
<view>课程课程名称1</view>
</view>
<view style="padding: 16rpx 16rpx 16rpx 60rpx;">2020-08-30 签单</view>
</view>
</view>
<view style="height: 200rpx;"></view>
</view>
<!-- 底部按钮组-->
<view class="bottom-label">
<view @click="openViewWritingFollowUp()">添加跟进记录</view>
<view @click="callTel(clientInfo.student_phone)">拨打电话</view>
<view @click="openViewNewTask()">转交跟进任务</view>
</view>
</view>
</view>
</template>
<script>
// import user from '@/api/user.js';
import marketApi from '@/api/market.js';
export default {
data() {
return {
formData: {},
switch_tags_type: 4,
switch_tags_type: 1,
select_type: 1,
id:'',//线id
clientInfo:{
follow:{
follow_up_time:'',
initial_customer_intent:'',
}
},//
//
followList:[],
//
listCallUp:[],
}
},
onLoad() {},
onLoad(options) {
this.id = options.id
},
onShow(){
this.init()
},
methods: {
async init(){
await this.getInfo()
this.getFollowList()
this.getListCallUp()
},
//
async getInfo(){
let data = {
id:this.id//线id
}
let res = await marketApi.clientInfo(data)
if(res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.clientInfo = res.data
},
//
async getFollowList(){
let data = {
sales_id:this.id//
}
let res = await marketApi.followList(data)
if(res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.followList = res.data
},
//
async getListCallUp(){
let data = {
sales_id:this.id//
}
let res = await marketApi.listCallUp(data)
if(res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.listCallUp = res.data
},
//-
openViewWritingFollowUp() {
uni.navigateTo({
url: `/pages/market/clue/writing_followUp`
})
},
//-
openViewNewTask() {
uni.navigateTo({
url: `/pages/market/clue/new_task`
})
},
//
async callTel(tel) {
if (!tel) {
uni.showToast({
title: '电话号码为空',
icon: 'none'
});
return;
}
let param = {
sales_id:this.id//线id
}
let res = await marketApi.setCallUp(param)//
if(res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
uni.makePhoneCall({
phoneNumber: tel,
success: function () {
// console.log('');
},
fail: function (err) {
console.log('拨打电话失败', err);
uni.showToast({
title: '拨打电话失败',
icon: 'none'
});
return;
}
});
},
//
switch_tags(type){
this.switch_tags_type = type

760
pages/market/clue/index.vue

@ -1,373 +1,394 @@
<template>
<view class="assemble">
<fui-segmented-control :values="values" type="text" activeColor="#29d3b4" color="#fff" @click="segmented"></fui-segmented-control>
<view class="search">
<view :class="{'selected': select_type === 1, 'not-selected': select_type !== 1}" @click="getSelect(1)">全部(320)</view>
<view :class="{'selected': select_type === 2, 'not-selected': select_type !== 2}" @click="getSelect(2)">待跟进(8)</view>
<view :class="{'selected': select_type === 3, 'not-selected': select_type !== 3}" @click="getSelect(3)">7天未跟进(15)</view>
<view :class="{'selected': select_type === 4, 'not-selected': select_type !== 4}" @click="getSelect(4)">30天未成交(12)</view>
</view>
<view v-if="segmented_type == 1">
<view class="card">
<view style="width: 70%;" @click="clue_info">
<view style="display: flex;align-items: center;padding: 20rpx;">
<view><image src="@/static/images/index/myk.png" class="card-image"></image></view>
<view class="card-text">包子皮</view>
<view class="card-label">试听</view>
</view>
<view class="card-con">
首联系人包念念 <span class="card-con-span">妈妈</span>
</view>
<view class="card-date">
<view class="card-con">08-30 14:25  跟进</view>
<view style="margin-left: 30rpx;">
<view style="display: flex;align-items: center;">
<view style="padding: 12rpx;">
<image src="@/static/images/index/intention1.png" class="drop-image-x"></image>
</view>
<view class="title-x">意向</view>
</view>
</view>
</view>
</view>
<view style="width: 15%;">
<image src="@/static/images/index/message.png" class="image"></image>
</view>
<view style="width: 15%;">
<image src="@/static/images/index/phone.png" class="image"></image>
</view>
</view>
<view class="card">
<view style="width: 70%;" @click="clue_info">
<view style="display: flex;align-items: center;padding: 20rpx;">
<view><image src="@/static/images/index/myk.png" class="card-image"></image></view>
<view class="card-text">包子皮</view>
<view class="card-label">试听</view>
</view>
<view class="card-con">
首联系人包念念 <span class="card-con-span">妈妈</span>
</view>
<view class="card-date">
<view class="card-con">08-30 14:25  跟进</view>
<view style="margin-left: 30rpx;">
<view style="display: flex;align-items: center;">
<view style="padding: 12rpx;">
<image src="@/static/images/index/intention3.png" class="drop-image-x"></image>
</view>
<view class="title-x">意向</view>
</view>
</view>
</view>
</view>
<view style="width: 15%;">
<image src="@/static/images/index/message.png" class="image"></image>
</view>
<view style="width: 15%;">
<image src="@/static/images/index/phone.png" class="image"></image>
</view>
</view>
<view class="card">
<view style="width: 70%;" @click="clue_info">
<view style="display: flex;align-items: center;padding: 20rpx;">
<view><image src="@/static/images/index/myk.png" class="card-image"></image></view>
<view class="card-text">包子皮</view>
<view class="card-label">试听</view>
</view>
<view class="card-con">
首联系人包念念 <span class="card-con-span">妈妈</span>
</view>
<view class="card-date">
<view class="card-con">08-30 14:25  跟进</view>
<view style="margin-left: 30rpx;">
<view style="display: flex;align-items: center;">
<view style="padding: 12rpx;">
<image src="@/static/images/index/intention2.png" class="drop-image-x"></image>
</view>
<view class="title-x">意向</view>
</view>
</view>
</view>
</view>
<view style="width: 15%;">
<image src="@/static/images/index/message.png" class="image"></image>
</view>
<view style="width: 15%;">
<image src="@/static/images/index/phone.png" class="image"></image>
</view>
</view>
<view class="card">
<view style="width: 70%;" @click="clue_info">
<view style="display: flex;align-items: center;padding: 20rpx;">
<view><image src="@/static/images/index/myk.png" class="card-image"></image></view>
<view class="card-text">包子皮</view>
<view class="card-label">试听</view>
</view>
<view class="card-con">
首联系人包念念 <span class="card-con-span">妈妈</span>
</view>
<view class="card-date">
<view class="card-con">待跟进</view>
<view style="margin-left: 30rpx;">
<view style="display: flex;align-items: center;">
<view style="padding: 12rpx;">
<image src="@/static/images/index/intention1.png" class="drop-image-x"></image>
</view>
<view class="title-x">意向</view>
</view>
</view>
</view>
</view>
<view style="width: 15%;">
<image src="@/static/images/index/message.png" class="image"></image>
</view>
<view style="width: 15%;">
<image src="@/static/images/index/phone.png" class="image"></image>
</view>
</view>
<view class="card">
<view style="width: 70%;" @click="clue_info">
<view style="display: flex;align-items: center;padding: 20rpx;">
<view><image src="@/static/images/index/myk.png" class="card-image"></image></view>
<view class="card-text">包子皮</view>
<view class="card-label">试听</view>
</view>
<view class="card-con">
首联系人包念念 <span class="card-con-span">妈妈</span>
</view>
<view class="card-date">
<view class="card-con">08-30 14:25  跟进</view>
<view style="margin-left: 30rpx;">
<view style="display: flex;align-items: center;">
<view style="padding: 12rpx;">
<image src="@/static/images/index/intention1.png" class="drop-image-x"></image>
</view>
<view class="title-x">意向</view>
</view>
</view>
</view>
</view>
<view style="width: 15%;">
<image src="@/static/images/index/message.png" class="image"></image>
</view>
<view style="width: 15%;">
<image src="@/static/images/index/phone.png" class="image"></image>
</view>
</view>
</view>
<view v-if="segmented_type == 2">
<view style="color: #999999;padding: 20rpx 30rpx;">
今日待领15/30
</view>
<view class="card">
<view style="width: 70%;" @click="clue_info">
<view style="display: flex;align-items: center;padding: 20rpx;">
<view><image src="@/static/images/index/myk.png" class="card-image"></image></view>
<view class="card-text">包子皮</view>
<view class="card-label">试听</view>
</view>
<view class="card-con">
首联系人包念念 <span class="card-con-span">妈妈</span>
</view>
<view class="card-date">
<view class="card-con">08-30 14:25  跟进</view>
<view style="margin-left: 30rpx;">
<view style="display: flex;align-items: center;">
<view style="padding: 12rpx;">
<image src="@/static/images/index/intention1.png" class="drop-image-x"></image>
</view>
<view class="title-x">意向</view>
</view>
</view>
</view>
</view>
<view style="width: 30%;display: flex;justify-content: center;">
<view class="neck">
</view>
</view>
</view>
<view class="card">
<view style="width: 70%;" @click="clue_info">
<view style="display: flex;align-items: center;padding: 20rpx;">
<view><image src="@/static/images/index/myk.png" class="card-image"></image></view>
<view class="card-text">包子皮</view>
<view class="card-label">试听</view>
</view>
<view class="card-con">
首联系人包念念 <span class="card-con-span">妈妈</span>
</view>
<view class="card-date">
<view class="card-con">08-30 14:25  跟进</view>
<view style="margin-left: 30rpx;">
<view style="display: flex;align-items: center;">
<view style="padding: 12rpx;">
<image src="@/static/images/index/intention1.png" class="drop-image-x"></image>
</view>
<view class="title-x">意向</view>
</view>
</view>
</view>
</view>
<view style="width: 30%;display: flex;justify-content: center;">
<view class="neck">
</view>
</view>
</view>
<view class="card">
<view style="width: 70%;" @click="clue_info">
<view style="display: flex;align-items: center;padding: 20rpx;">
<view><image src="@/static/images/index/myk.png" class="card-image"></image></view>
<view class="card-text">包子皮</view>
<view class="card-label">试听</view>
</view>
<view class="card-con">
首联系人包念念 <span class="card-con-span">妈妈</span>
</view>
<view class="card-date">
<view class="card-con">08-30 14:25  跟进</view>
<view style="margin-left: 30rpx;">
<view style="display: flex;align-items: center;">
<view style="padding: 12rpx;">
<image src="@/static/images/index/intention1.png" class="drop-image-x"></image>
</view>
<view class="title-x">意向</view>
</view>
</view>
</view>
</view>
<view style="width: 30%;display: flex;justify-content: center;">
<view class="neck">
</view>
</view>
</view>
<view class="card">
<view style="width: 70%;" @click="clue_info">
<view style="display: flex;align-items: center;padding: 20rpx;">
<view><image src="@/static/images/index/myk.png" class="card-image"></image></view>
<view class="card-text">包子皮</view>
<view class="card-label">试听</view>
</view>
<view class="card-con">
首联系人包念念 <span class="card-con-span">妈妈</span>
</view>
<view class="card-date">
<view class="card-con">08-30 14:25  跟进</view>
<view style="margin-left: 30rpx;">
<view style="display: flex;align-items: center;">
<view style="padding: 12rpx;">
<image src="@/static/images/index/intention1.png" class="drop-image-x"></image>
</view>
<view class="title-x">意向</view>
</view>
</view>
</view>
</view>
<view style="width: 30%;display: flex;justify-content: center;">
<view class="neck">
</view>
</view>
</view>
<view class="card">
<view style="width: 70%;" @click="clue_info">
<view style="display: flex;align-items: center;padding: 20rpx;">
<view><image src="@/static/images/index/myk.png" class="card-image"></image></view>
<view class="card-text">包子皮</view>
<view class="card-label">试听</view>
</view>
<view class="card-con">
首联系人包念念 <span class="card-con-span">妈妈</span>
</view>
<view class="card-date">
<view class="card-con">08-30 14:25  跟进</view>
<view style="margin-left: 30rpx;">
<view style="display: flex;align-items: center;">
<view style="padding: 12rpx;">
<image src="@/static/images/index/intention1.png" class="drop-image-x"></image>
</view>
<view class="title-x">意向</view>
</view>
</view>
</view>
</view>
<view style="width: 30%;display: flex;justify-content: center;">
<view class="neck">
</view>
</view>
</view>
<view class="card">
<view style="width: 70%;" @click="clue_info">
<view style="display: flex;align-items: center;padding: 20rpx;">
<view><image src="@/static/images/index/myk.png" class="card-image"></image></view>
<view class="card-text">包子皮</view>
<view class="card-label">试听</view>
</view>
<view class="card-con">
首联系人包念念 <span class="card-con-span">妈妈</span>
</view>
<view class="card-date">
<view class="card-con">08-30 14:25  跟进</view>
<view style="margin-left: 30rpx;">
<view style="display: flex;align-items: center;">
<view style="padding: 12rpx;">
<image src="@/static/images/index/intention1.png" class="drop-image-x"></image>
</view>
<view class="title-x">意向</view>
</view>
</view>
</view>
</view>
<view style="width: 30%;display: flex;justify-content: center;">
<view class="neck">
</view>
</view>
</view>
</view>
<view style="height: 170rpx;"></view>
<AQTabber />
</view>
<view class="assemble">
<fui-segmented-control :values="values" type="text" activeColor="#29d3b4" color="#fff"
@click="segmented"></fui-segmented-control>
<view class="search">
<view :class="{'selected': select_type == 1, 'not-selected': select_type != 1}" @click="setSelect(1)">全部({{countArr.type_0}})
</view>
<view :class="{'selected': select_type == 2, 'not-selected': select_type != 2}" @click="setSelect(2)">待跟进({{countArr.type_1}})
</view>
<view :class="{'selected': select_type == 3, 'not-selected': select_type != 3}" @click="setSelect(3)">
7天未跟进({{countArr.type_2}})
</view>
<view :class="{'selected': select_type == 4, 'not-selected': select_type != 4}" @click="setSelect(4)">
30天未成交({{countArr.type_3}})
</view>
</view>
<!--我的客户-->
<scroll-view
v-if="segmented_type == 1"
scroll-y="true"
:lower-threshold="lowerThreshold"
@scrolltolower="loadMoreData"
style="height: 100vh;"
>
<view class="card" v-for="(v,k) in tableList" :key="k">
<view style="width: 70%;" @click="clue_info(v)">
<view style="display: flex;align-items: center;padding: 20rpx;">
<view>
<image src="@/static/images/index/myk.png" class="card-image"></image>
</view>
<view class="card-text">{{ v.student_name }}</view>
<view class="card-label">{{ v.is_status == 1 ? '试听' : '成交' }}</view>
</view>
<view class="card-con">
首联系人{{ v.contact_name }} <span class="card-con-span">{{ v.decision_maker }}</span>
</view>
<view class="card-date">
<view class="card-con">{{ $util.formatToDateTime((v.follow && v.follow.follow_up_time || ''), 'm-d H:i') }}
跟进
</view>
<view style="margin-left: 30rpx;">
<view style="display: flex;align-items: center;">
<view style="padding: 12rpx;">
<image
v-if="['A+','A','A-'].includes(v.follow && v.follow.initial_customer_intent || '')"
src="@/static/images/index/intention3.png"
class="drop-image-x"
></image>
<image
v-else-if="['B+','B','B-'].includes(v.follow && v.follow.initial_customer_intent || '')"
src="@/static/images/index/intention2.png"
class="drop-image-x"
></image>
<image
v-else
src="@/static/images/index/intention1.png"
class="drop-image-x"
></image>
</view>
<view class="title-x">意向{{ v.follow && v.follow.initial_customer_intent || '' }}</view>
</view>
</view>
</view>
</view>
<view style="width: 15%;">
<image src="@/static/images/index/message.png" class="image" @click="openViewMyMessage(v)"></image>
</view>
<view style="width: 15%;">
<image v-if="v.student_phone" src="@/static/images/index/phone.png" class="image" @click="dialTel(v)"></image>
</view>
</view>
</scroll-view>
<!--区域公海-->
<scroll-view
v-if="segmented_type == 2"
scroll-y="true"
:lower-threshold="lowerThreshold"
@scrolltolower="loadMoreData"
style="height: 100vh;"
>
<view style="color: #999999;padding: 20rpx 30rpx;">
今日待领{{countArr.lq_count}}/{{countArr.max_count}}
</view>
<view class="card" v-for="(v,k) in tableList" :key="k">
<view style="width: 70%;">
<view style="display: flex;align-items: center;padding: 20rpx;">
<view>
<image src="@/static/images/index/myk.png" class="card-image"></image>
</view>
<view class="card-text">{{v.student_name}}</view>
<view class="card-label">{{v.is_status == 1 ? '试听' : '成交'}}</view>
</view>
<view class="card-con">
首联系人{{v.contact_name}} <span class="card-con-span">{{v.decision_maker}}</span>
</view>
<view class="card-date">
<view class="card-con">{{ $util.formatToDateTime((v.follow && v.follow.follow_up_time || ''),'m-d H:i') }} 跟进</view>
<view style="margin-left: 30rpx;">
<view style="display: flex;align-items: center;">
<view style="padding: 12rpx;">
<image
v-if="['A+','A','A-'].includes(v.follow && v.follow.initial_customer_intent || '')"
src="@/static/images/index/intention3.png"
class="drop-image-x"
></image>
<image
v-else-if="['B+','B','B-'].includes(v.follow && v.follow.initial_customer_intent || '')"
src="@/static/images/index/intention2.png"
class="drop-image-x"
></image>
<image
v-else
src="@/static/images/index/intention1.png"
class="drop-image-x"
></image>
</view>
<view class="title-x">意向{{ v.follow && v.follow.initial_customer_intent || '' }}</view>
</view>
</view>
</view>
</view>
<view style="width: 15%;">
<!-- <image src="@/static/images/index/message.png" class="image"></image>-->
</view>
<view style="width: 15%;" @click="getSales(v)">
<view class="ling"></view>
</view>
</view>
</scroll-view>
<view style="height: 170rpx;"></view>
<AQTabber/>
</view>
</template>
<script>
import AQTabber from "@/components/AQ/AQTabber.vue"
export default {
components: {
AQTabber,
},
data() {
return {
values: [{
id: 1,
name: '我的客户'
}, {
id: 2,
name: '区域公海'
}],
select_type: 1,
segmented_type: 1,
}
},
methods: {
getSelect(type){
this.select_type = type
},
segmented(index){
this.segmented_type = index.id
},
clue_info(){
uni.navigateTo({
url: '/pages/market/clue/clue_info'
})
},
}
}
import AQTabber from "@/components/AQ/AQTabber.vue"
import marketApi from '@/api/market.js';
export default {
components: {
AQTabber,
},
data() {
return {
loading:false,//
lowerThreshold: 100,//
isReachedBottom: false,//|true=|false=
//
filteredData:{
page:1,//
limit:10,//
total:10,//
type: '0',//0=,1=,2=7,3=30
is_gh: '2',//1=,2=
},
countArr:{
type_0:0,
type_1:0,
type_2:0,
type_3:0,
max_count:0,
lq_count:0,
},//
tableList:[],//
values: [{
id: 1,
name: '我的客户'
}, {
id: 2,
name: '区域公海'
}],
select_type: 1,//|1,2,3,4
segmented_type: 1,//1=,2=
}
},
onLoad(options) {},
onShow(){
this.init()//
},
//
async onPullDownRefresh() {
//
await this.resetFilteredData()
await this.getList()
},
methods: {
//
async init(){
await this.getList();
},
//()
loadMoreData() {
//
if (!this.isReachedBottom) {
this.isReachedBottom = true;//
this.getList();
}
},
//
async resetFilteredData() {
this.isReachedBottom = false; // 便
this.filteredData.page = 1//
this.filteredData.limit = 10//
this.filteredData.total = 10//
},
//
async getList(){
this.loading = true
let data = {...this.filteredData}
//
if(this.filteredData.page * this.filteredData.limit > this.filteredData.total){
this.loading = false
uni.showToast({
title: '暂无更多',
icon: 'none'
})
return
}
if(data.page == 1){
this.tableList = []
}
let res = await marketApi.myClient(data)
this.loading = false
this.isReachedBottom = false;
if (res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.tableList = this.tableList.concat(res.data.list.data); // 使 concat
console.log('列表',this.tableList)
this.filteredData.total = res.data.list.total
this.filteredData.page++
this.countArr = {
type_0:res.data.count[0],
type_1:res.data.count[1],
type_2:res.data.count[2],
type_3:res.data.count[3],
max_count:res.data.gh.max_count,
lq_count:res.data.gh.lq_count,
}
},
//
async setSelect(type) {
this.select_type = type
//
await this.resetFilteredData()
if(this.segmented_type == 1){
this.filteredData.is_gh = '2'//2=
}else{
this.filteredData.is_gh = '1'//1=
}
switch (type) {
//
case 1:
this.filteredData.type = '0'
break
//
case 2:
this.filteredData.type = '1'
break
//7
case 3:
this.filteredData.type = '2'
break
//30
case 4:
this.filteredData.type = '3'
break
}
await this.getList()
},
//tag
async segmented(index) {
this.select_type = 1
this.segmented_type = index.id//1=,2=
//
await this.resetFilteredData()
if(this.segmented_type == 1){
this.filteredData.is_gh = '2'//2=
}else{
this.filteredData.is_gh = '1'//1=
}
this.filteredData.type = '0'
await this.getList()
},
//-
openViewMyMessage(item) {
let hair_staff_id = item.hair_staff_id
uni.navigateTo({
url: `/pages/common/im_chat_info?hair_staff_id=${hair_staff_id}`
})
},
//
async dialTel(item) {
let tel = item.student_phone
if (!tel) {
uni.showToast({
title: '电话号码为空',
icon: 'none'
});
return;
}
let param = {
sales_id: item.id//线id
}
let res = await marketApi.setCallUp(param)//
if (res.code != 1) {
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
uni.makePhoneCall({
phoneNumber: tel
})
},
//
clue_info(item) {
let id = item.id
uni.navigateTo({
url: `/pages/market/clue/clue_info?id=${id}`
})
},
//-
async getSales(item){
let param = {
sales_id:item.id
}
let res = await marketApi.getSales(param)
if(res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
uni.showToast({
title: res.msg,
icon: 'success'
})
//1s
setTimeout(() => {
let param = {
index:{
id:2//2=
}
}
this.segmented(param)
}, 1000)
},
}
}
</script>
<style>
<style lang="less" scoped>
.assemble{
width: 100%;
height: 100vh;
@ -459,4 +480,15 @@
line-height: 60rpx;
text-align: center;
}
//
.ling{
display: flex;
justify-content: center;
align-items: center;
border-radius:50%;
color: #fff;
width: 50rpx;
height: 50rpx;
background-color: #F59A23;
}
</style>

491
pages/market/clue/new_task.vue

@ -3,60 +3,102 @@
<view class="title">跟进任务</view>
<view class="form-style">
<fui-form class="input-style" ref="form" top="0" :model="formData" :show="false">
<fui-form-item label="跟进客户" labelSize='26' prop="name" background='#434544' labelColor='#fff'
:bottomBorder='false'>
<view class="input-title" style="margin-right:14rpx;" v-if="result_name == ''"
@click="selectCon(2)">点击选择</view>
<view class="input-title" style="margin-right:14rpx;" v-else @click="selectCon(2)">{{ result_name }}
</view>
</fui-form-item>
<fui-form-item label="跟进时间" labelSize='26' asterisk asteriskPosition="right" prop="mobile"
background='#434544' labelColor='#fff' :bottomBorder='false'>
<view class="input-title" style="margin-right:14rpx;" @click="selectCon(1)"
v-if="result_date == ''">点击选择</view>
<view class="input-title" style="margin-right:14rpx;" @click="selectCon(1)" v-else>{{ result_date }}
</view>
</fui-form-item>
<fui-form-item label="跟进内容" labelSize='26' prop="mobile" background='#434544' labelColor='#fff'
:bottomBorder='false'>
<fui-input :borderBottom="false" :padding="[0]" placeholder="点击填写" v-model="formData.mobile"
backgroundColor="#434544" size="26" color="#fff"></fui-input>
</fui-form-item>
<fui-form-item label="跟进人员" labelSize='26' asterisk asteriskPosition="right" prop="mobile"
background='#434544' labelColor='#fff' :bottomBorder='false'>
<fui-input :borderBottom="false" :padding="[0]" placeholder="点击填写" v-model="formData.mobile"
backgroundColor="#434544" size="26" color="#fff"></fui-input>
</fui-form-item>
<fui-form-item label="任务提醒" labelSize='26' prop="mobile" background='#434544' labelColor='#fff'
:bottomBorder='false'>
<view class="input-title" style="margin-right:14rpx;" @click="selectCon(3)"
v-if="result_renwu == ''">点击选择</view>
<view class="input-title" style="margin-right:14rpx;" @click="selectCon(3)" v-else>{{ result_renwu }}
</view>
</fui-form-item>
<fui-form-item label="提醒方式" labelSize='26' prop="mobile" background='#434544' labelColor='#fff'
:bottomBorder='false'>
<view class="input-title" style="margin-right:14rpx;" @click="selectCon(4)"
v-if="result_fangshi == ''">点击选择</view>
<view class="input-title" style="margin-right:14rpx;" @click="selectCon(4)" v-else>{{ result_fangshi }}
</view>
</fui-form-item>
<!--基础表单-->
<!--下拉-->
<fui-form-item
asterisk
label="跟进类型"
asteriskPosition="right"
labelSize='26'
prop=""
background='#434544'
labelColor='#fff'
:bottomBorder='false'
>
<view class="input-title" style="margin-right:14rpx;">
<view v-if="!formData.entry_type" class="input-title" style="margin-right:14rpx;" @click="selectCon(`entry_type`)">点击选择
</view>
<view v-else class="input-title" style="margin-right:14rpx;" @click="selectCon(`entry_type`)">
{{ str_entry_type }}
</view>
</view>
</fui-form-item>
<!--下拉-->
<fui-form-item
asterisk
label="跟进人员"
asteriskPosition="right"
labelSize='26'
prop=""
background='#434544'
labelColor='#fff'
:bottomBorder='false'
>
<view class="input-title" style="margin-right:14rpx;">
<view v-if="!formData.follow_staff_id" class="input-title" style="margin-right:14rpx;" @click="selectCon(`follow_staff_id`)">点击选择
</view>
<view v-else class="input-title" style="margin-right:14rpx;" @click="selectCon(`follow_staff_id`)">
{{ str_follow_staff_id }}
</view>
</view>
</fui-form-item>
<!--下拉-->
<fui-form-item
asterisk
label="跟进时间"
asteriskPosition="right"
labelSize='26'
prop=""
background='#434544'
labelColor='#fff'
:bottomBorder='false'
>
<view class="input-title" style="margin-right:14rpx;">
<view v-if="!formData.reminder_time" class="input-title" style="margin-right:14rpx;" @click="selectCon(`reminder_time`)">点击选择
</view>
<view v-else class="input-title" style="margin-right:14rpx;" @click="selectCon(`reminder_time`)">
{{ formData.reminder_time }}
</view>
</view>
</fui-form-item>
<!--手写-->
<fui-form-item
label="备注"
asteriskPosition="right"
labelSize='26'
prop=""
background='#434544'
labelColor='#fff'
:bottomBorder='false'
>
<view class="input-title" style="margin-right:14rpx;">
<fui-input :borderBottom="false" :padding="[0]" placeholder="点击填写" v-model="formData.follow_content"
backgroundColor="#434544" size="26" color="#fff"></fui-input>
</view>
</fui-form-item>
</fui-form>
</view>
<view class="fui-btn__box">
<fui-button background="#434544" color="#24BA9F" borderColor="#24BA9F" @click="submit">保存</fui-button>
</view>
<!-- 年月日-选择时间 -->
<fui-date-picker :show="show_date" type="3" @change="change_date" @cancel="cancel_date"></fui-date-picker>
<!-- 年月日-选择时间 -->
<fui-date-picker :show="show_date" type="5" @change="change_date" @cancel="cancel_date"></fui-date-picker>
<!-- 选择器 -->
<fui-picker :linkage='linkage' :options="options" :layer="1" :show="show" @change="change" @cancel="cancel"></fui-picker>
<!-- 下拉选择器 -->
<fui-picker :linkage='linkage' :options="options" :layer="1" :show="show" @change="changeOptions"
@cancel="cancel"></fui-picker>
</view>
</template>
<script>
import marketApi from '@/api/market.js';
import memberApi from '@/api/member.js';
const rules = [{
name: "mobile",
rule: ["required", "isMobile"],
@ -66,107 +108,276 @@
data() {
return {
rules,
formData: {},
show_date: false,
result_date: '',
result_name: '',
result_renwu: '',
result_fangshi: '',
show: false,
options: [],
linkage: true,
options_type : undefined,
options_kehu: [{
'value': 1,
'text': '张三'
}, {
'value': 2,
'text': '李四'
}, {
'value': 3,
'text': '王五'
}],
options_renwu: [{
'value': 1,
'text': '是'
}, {
'value': 2,
'text': '否'
}],
options_fangshi: [{
'value': 1,
'text': '短信'
}, {
'value': 2,
'text': '微信'
}]
is_submit: true,//()|true=,false=
//
formData:{
//##### #####
entry_type:'',//(1=,2=)
follow_staff_id:'',//
reminder_time:'',//
follow_content:'',//
},
//
options_type: undefined,//
show: false,//
linkage: true,//
options: [
// {
// 'value': 1,
// 'text': '1'
// }
],//
//
show_date: false,//|true=,false=
//-
//-
options_entry_type:[
{
value: 1,
text: '市场人员'
},
{
value: 2,
text: '销售人员'
},
],
//-
str_entry_type:'',
//-
//-
options_follow_staff_id_sc:[],//(-)
options_follow_staff_id_xs:[],//(-)
//-
str_follow_staff_id:'',
}
},
onShow() {
this.init()
},
methods: {
submit() {
console.log(this.formData)
this.$refs.form.validator(null, null, true).then(res => {
console.log(res)
if (res.isPassed) {
console.log('校验通过!')
} else {
console.log('向上滑动页面查看错误提示!')
}
}).catch(err => {
console.log(err)
})
},
//
selectCon(type) {
if (type == 1) {
//
this.show_date = true
} else if (type == 2) {
//
this.options_type = 2
this.options = this.options_kehu
this.show = true
this.linkage = true
} else if (type == 3) {
//
this.options_type = 3
this.options = this.options_renwu
this.show = true
this.linkage = true
} else if (type == 4) {
//
this.options_type = 4
this.options = this.options_fangshi
this.show = true
this.linkage = true
}
},
//
change_date(e) {
this.show_date = false
this.result_date = e.result ?? ''
console.log(this.result_date, '选择')
},
//
cancel_date() {
this.show_date = false
},
//
change(e) {
this.show = false
console.log(e)
if(this.options_type == 2){
this.result_name = e.result
}else if(this.options_type == 3){
this.result_renwu = e.result
}else if(this.options_type == 4){
this.result_fangshi = e.result
}
},
//
cancel() {
this.show = false
}
//
async init() {
this.getUserInfo()
//-()
this.getDic_staff_id('5')
//-()
this.getDic_staff_id('6')
},
//
async getUserInfo(){
let res = await marketApi.member({})
if (res.code != 1) {
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
console.log(111,res.data)
this.formData.staff_id = res.data.staff_id//->
this.str_staff_id = res.data.name//->
},
//-()
// role_id|5=,6=
async getDic_staff_id(role_id){
let res = await memberApi.staffList({
type: 2,
role_id:role_id
})
if (res.code != 1) {
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
let arr = []
res.data.forEach((v,k)=>{
arr.push({
text: v.name,
value: v.id,
})
})
if(role_id == 5){
this.options_follow_staff_id_sc = arr
console.log('市场',arr)
}else if(role_id == 6){
this.options_follow_staff_id_xs = arr
console.log('销售',arr)
}else{
//
this.options_staff_id = arr
console.log('全部',arr)
}
},
//
async validatorForm(data) {
//
if(!data.entry_type){
uni.showToast({
title: '跟进类型必填',
icon: 'none'
})
return false
}
//
if(!data.follow_staff_id){
uni.showToast({
title: '跟进人员必填',
icon: 'none'
})
return false
}
//
if(!data.reminder_time){
uni.showToast({
title: '跟进时间必填',
icon: 'none'
})
return false
}
return true
},
//
async submit() {
console.log('提交',this.formData)
let data = {...this.formData}
//
let validatorForm = await this.validatorForm(data)
console.log('验证结果',validatorForm)
if(!validatorForm){
return
}
//
if (!this.is_submit) {
return
}
this.is_submit = false
let res = await marketApi.createTask(data)//
this.is_submit = true
if(res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
uni.showToast({
title: res.msg,
icon: 'success'
})
//1s
setTimeout(() => {
//-线
uni.navigateTo({
url: `/pages/market/clue/index`
})
}, 1000)
},
//
selectCon(type) {
this.options_type = type
switch (type) {
//
case 'entry_type':
this.options = this.options_entry_type
this.show = true
this.linkage = true
//->
this.formData.follow_staff_id = ''
break;
//->
case 'follow_staff_id':
if(!this.formData.entry_type){
uni.showToast({
title: '请先选择跟进类型',
icon: 'none'
})
return
}
if(this.formData.entry_type == 1){
//
this.options = this.options_follow_staff_id_sc
}else{
//
this.options = this.options_follow_staff_id_xs
}
this.show = true
this.linkage = true
break;
//
case 'reminder_time':
this.show_date = true
break;
}
},
//-
changeOptions(e) {
console.log('选择器选中',e)
this.show = false
let type = this.options_type
switch (type) {
//
case 'entry_type':
this.str_entry_type = e.text//text
this.formData.entry_type = e.value//value
break;
//
case 'follow_staff_id':
this.str_follow_staff_id = e.text//text
this.formData.follow_staff_id = e.value//value
break;
}
},
//
cancel() {
this.show = false
},
//-
change_date(e) {
this.show_date = false
//
let type = this.options_type
console.log('时间选择器',type,e)
let val = (e.result ?? '')
if(val){
val = val + ':00'
}
switch (type) {
//->
case 'reminder_time':
this.formData.reminder_time = val
break;
}
},
//
cancel_date() {
this.show_date = false
},
}
}
</script>

1279
pages/market/clue/writing_followUp.vue

File diff suppressed because it is too large

149
pages/market/data/index.vue

@ -21,11 +21,11 @@
<view class="right">
<view class="title">目标金额</view>
<view class="content">
<text class="strong">100000</text>
<text class="strong">{{infoData.goal}}</text>
</view>
<view class="title">完成金额</view>
<view class="content">
<text class="strong">100000</text>
<text class="strong">{{infoData.wx_performance}}</text>
<text>较上月</text>
</view>
@ -77,28 +77,28 @@
<view class="right">
<view class="item">
<view class="title" style="color: #12E7E8;">
成交率<text>(93.77%)</text>
成交率<text>({{infoData.cj_lv}}%)</text>
</view>
<view class="title" style="color: #12E7E8;">
11239<text></text>
{{infoData.cj_count}}<text></text>
</view>
</view>
<view class="item">
<view class="title" style="color: #4DA3FF;">
试听率<text>(93.77%)</text>
试听率<text>({{infoData.st_lv}}%)</text>
</view>
<view class="title" style="color: #4DA3FF;">
11239<text></text>
{{infoData.st_count}}<text></text>
</view>
</view>
<view class="item">
<view class="title" style="color: #FFCB31;">
跟进率<text>(93.77%)</text>
跟进率<text>({{infoData.gj_count}}%)</text>
</view>
<view class="title" style="color: #FFCB31;">
11239<text></text>
{{infoData.gj_count}}<text></text>
</view>
</view>
</view>
@ -106,33 +106,11 @@
<!-- 销售排名-->
<view class="section_box_2" v-else>
<view class="itme">
<view class="title">01 李小刚</view>
<view class="money">100000</view>
<view class="itme" v-for="(v,k) in infoData.staff_list" :key="k">
<view class="title">{{k+1}} {{v.name}}</view>
<view class="money">{{v.goal}}</view>
<view class="plan">
<fui-progress :percent="80" height="15" radius="15" background="#e4e4e4" activeColor="#4bced0"></fui-progress>
</view>
</view>
<view class="itme">
<view class="title">02 张刚</view>
<view class="money">100000</view>
<view class="plan">
<fui-progress :percent="80" height="15" radius="15" background="#e4e4e4" activeColor="#4bced0"></fui-progress>
</view>
</view>
<view class="itme">
<view class="title">03 李华</view>
<view class="money">100000</view>
<view class="plan">
<fui-progress :percent="80" height="15" radius="15" background="#e4e4e4" activeColor="#4bced0"></fui-progress>
</view>
</view>
<view class="itme">
<view class="title">04 王明</view>
<view class="money">100000</view>
<view class="plan">
<fui-progress :percent="80" height="15" radius="15" background="#e4e4e4" activeColor="#4bced0"></fui-progress>
<fui-progress :percent="getPercent(v.wx_yj,v.goal)" height="15" radius="100" background="#e4e4e4" activeColor="#4bced0"></fui-progress>
</view>
</view>
</view>
@ -146,7 +124,7 @@
<script>
// import user from '@/api/user.js';
import marketApi from '@/api/market.js';
import AQTabber from "@/components/AQ/AQTabber.vue"
@ -157,6 +135,10 @@ export default {
data() {
return {
infoData:{
staff_list:[],//
},//
//
chartData: {},
opts: {
@ -181,7 +163,7 @@ export default {
color: "#666666" //
},
subtitle: {
name: "40%", //
name: "0%", //
fontSize: 18, //
color: "#7cb5ec" //
},
@ -243,36 +225,77 @@ export default {
}
}
},
onLoad() {
onLoad() {},
onShow() {
this.init()
},
methods: {
async init(){
this.getPerformance()
},
//
async getPerformance(){
let res= await marketApi.performance({})
if (res.code != 1) {
uni.showToast({
title: res.msg,
icon: 'none'
});
return
}
// console.log('xx',res)
this.infoData = res.data
//
let mb = this.infoData.wx_performance//
let xp =this.infoData.new_performance//
let xf =this.infoData.renew_performance//
// 000
let xp_percent = mb != 0 ? parseInt((xp / mb) * 100) : 0;
let xf_percent = mb != 0 ? parseInt((xf / mb) * 100) : 0;
let wwc_percent = 100 - xp_percent - xf_percent >= 0 ? '0' : 100 - xp_percent - xf_percent//
wwc_percent = parseInt(wwc_percent)
let w_c_d = ((xp + xf) - mb) * -1 * 100 //
w_c_d = w_c_d <= 0 ? 0 : w_c_d
w_c_d = 100 - w_c_d
let w_c_d_rounded = Math.round(w_c_d * 10) / 10;
// console.log('zzz',[xp_percent,xf_percent,wwc_percent,w_c_d_rounded])
//
let chartData_1 = {
series: [
{
data: [
{
"name": "新签",
"value": 50,
"name": "未完成",
"value": wwc_percent,
"labelShow": false
},
{
"name": "续费",
"value": 30,
"value": xf_percent,
"labelShow": false
},
{
"name": "未完成",
"value": 20,
"name": "新签",
"value": xp_percent,
"labelShow": false
}
},
]
}
]
};
this.chartData = JSON.parse(JSON.stringify(chartData_1));
this.opts.subtitle = {
name: `${w_c_d_rounded}%`, //
fontSize: 18, //
color: "#7cb5ec" //
}
//
let chartDataB = {
@ -281,24 +304,24 @@ export default {
data: [
{
"name": "跟进中", //
"centerText": "70", //
"value": 70, // 50
"centerText": this.infoData.gj_count, //
"value": this.infoData.gj_lv, // 50
// "labelText":''
"labelShow":false,
"color": "#FFCB31", //
},
{
"name": "试听",
"centerText": "30",
"value": 30,
"centerText": this.infoData.st_count,
"value": this.infoData.st_lv,
// "labelText":""
"labelShow":false,
"color": "#4DA3FF", //
},
{
"name": "已成交",
"centerText": "10",
"value": 10,
"centerText": this.infoData.cj_count,
"value": this.infoData.cj_lv,
// "labelText":""
"labelShow":false,
"color": "#12E7E8", //
@ -308,8 +331,28 @@ export default {
]
};
this.chartData_2 = JSON.parse(JSON.stringify(chartDataB));
},
//
getPercent(num1,total){
//
if(!total){
return 0
}
let num_percent = (num1 / total) * 100;
if(num_percent <= 0){
num_percent = 0
}else{
num_percent = Math.ceil((num1 / total) * 100);
}
// console.log('qqq',[num_percent,num1,total])
return num_percent
},
//tag
changeTag(type){
this.tagType = type
@ -384,7 +427,13 @@ export default {
align-items: center;
background: #292929;
.title{
padding: 20rpx 0;
padding: 40rpx 0rpx;
/* 小程序端样式 */
// #ifdef MP-WEIXIN
padding: 80rpx 0rpx;
// #endif
font-size: 30rpx;
color: #fff;
}

226
pages/market/index/index.vue

@ -3,7 +3,7 @@
<!--自定义导航栏-->
<view class="navbar_section">
<view class="title">我的</view>
<view class="title">首页</view>
</view>
<view style="height: 20rpx;"></view>
@ -24,7 +24,7 @@
</view>
<view class="title-x">目标</view>
</view>
<view class="title-x1">50.000</view>
<view class="title-x1">{{infoData.goal}}</view>
</view>
<view>
<view style="display: flex;align-items: center;">
@ -33,7 +33,7 @@
</view>
<view class="title-x">预测</view>
</view>
<view class="title-x1">50.000</view>
<view class="title-x1">{{infoData.yc_yj}}</view>
</view>
<view>
<view style="display: flex;align-items: center;">
@ -42,37 +42,48 @@
</view>
<view class="title-x">成交</view>
</view>
<view class="title-x1">50.000</view>
</view>
<view>
<view style="display: flex;align-items: center;">
<view style="padding: 12rpx;">
<image src="@/static/images/index/lan.png" class="drop-image-x"></image>
</view>
<view class="title-x">定金</view>
</view>
<view class="title-x1">50.000</view>
<view class="title-x1">{{infoData.cj_yj}}</view>
</view>
<!-- <view>-->
<!-- <view style="display: flex;align-items: center;">-->
<!-- <view style="padding: 12rpx;">-->
<!-- <image src="@/static/images/index/lan.png" class="drop-image-x"></image>-->
<!-- </view>-->
<!-- <view class="title-x">定金</view>-->
<!-- </view>-->
<!-- <view class="title-x1">50.000</view>-->
<!-- </view>-->
</view>
<!-- 目标-->
<view class="right1">
<view style="text-align: center;">08月01日-08月30日</view>
<view style="width: 100%;height: 80%;padding: 12rpx;">
<view style="padding: 10rpx;">目标 100%</view>
<fui-progress :percent="100" background="#ddd" activeColor="#FFB703" height="20"></fui-progress>
</view>
<view style="width: 100%;height: 80%;padding: 12rpx;">
<view style="padding: 10rpx;">目标 1%</view>
<fui-progress :percent="1" background="#ddd" activeColor="#039f64" height="20"></fui-progress>
</view>
<view style="width: 100%;height: 80%;padding: 12rpx;">
<view style="padding: 10rpx;">目标 20%</view>
<fui-progress :percent="20" background="#ddd" activeColor="#4066f2" height="20"></fui-progress>
</view>
<view style="width: 100%;height: 80%;padding: 12rpx;">
<view style="padding: 10rpx;">目标 8%</view>
<fui-progress :percent="8" background="#ddd" activeColor="#3b8bd1" height="20"></fui-progress>
</view>
<view style="text-align: center;">{{infoData.date}}</view>
<view class="statistics_box">
<!--目标-->
<view class="item">
<view class="box">
<view class="progress-bar" :style="{ height: `${infoData.goal_percent}%`, background: '#f59a23' }"></view>
<view class="ratio" :style="{ color: infoData.goal_percent <= 0 ? '#333333' : '#fff' }">{{ infoData.goal_percent }}%</view>
</view>
<view class="title">目标</view>
</view>
<!--预测-->
<view class="item">
<view class="box">
<view class="progress-bar" :style="{ height: `${infoData.yc_yj_percent}%`, background: '#039f64' }"></view>
<view class="ratio" :style="{ color: infoData.yc_yj_percent <= 0 ? '#333333' : '#fff' }">{{ infoData.yc_yj_percent }}%</view>
</view>
<view class="title">预测</view>
</view>
<!--成交-->
<view class="item">
<view class="box">
<view class="progress-bar" :style="{ height: `${infoData.cj_yj_percent}%`, background: '#4066f2' }"></view>
<view class="ratio" :style="{ color: infoData.cj_yj_percent <= 0 ? '#333333' : '#fff' }">{{ infoData.cj_yj_percent }}%</view>
</view>
<view class="title">成交</view>
</view>
</view>
</view>
</view>
@ -85,6 +96,7 @@
</view>
<view class="title">本月业绩</view>
</view>
<view class="coach-message">
<view class="this_month">
<view style="padding: 20rpx 0;display: flex;justify-content: space-between;">
@ -102,9 +114,9 @@
<view style="padding: 12rpx;">
<image src="@/static/images/index/danlv.png" class="drop-image-x"></image>
</view>
<view class="title-x">联系</view>
<view class="title-x">领取</view>
</view>
<view class="title-x1">50</view>
<view class="title-x1">{{infoData.dlq}}</view>
</view>
</view>
<view style="padding: 20rpx 0;display: flex;justify-content: space-between;">
@ -115,28 +127,31 @@
</view>
<view class="title-x">待释放</view>
</view>
<view class="title-x1">50</view>
</view>
<view style="width: 48%;">
<view style="display: flex;align-items: center;">
<view style="padding: 12rpx;">
<image src="@/static/images/index/danlv.png" class="drop-image-x"></image>
</view>
<view class="title-x">合同审核中</view>
</view>
<view class="title-x1">50</view>
<view class="title-x1">{{infoData.dsf}}</view>
</view>
<!-- <view style="width: 48%;">-->
<!-- <view style="display: flex;align-items: center;">-->
<!-- <view style="padding: 12rpx;">-->
<!-- <image src="@/static/images/index/danlv.png" class="drop-image-x"></image>-->
<!-- </view>-->
<!-- <view class="title-x">合同审核中</view>-->
<!-- </view>-->
<!-- <view class="title-x1">50</view>-->
<!-- </view>-->
<view style="width: 48%;">
<view style="display: flex;align-items: center;">
<view style="padding: 12rpx;">
<image src="@/static/images/index/danlv.png" class="drop-image-x"></image>
</view>
<view class="title-x">待协作</view>
</view>
<view class="title-x1">{{infoData.dxz}}</view>
</view>
</view>
<view style="padding: 20rpx 0;display: flex;justify-content: space-between;">
<view style="width: 48%;">
<view style="display: flex;align-items: center;">
<view style="padding: 12rpx;">
<image src="@/static/images/index/danlv.png" class="drop-image-x"></image>
</view>
<view class="title-x">待协作</view>
</view>
<view class="title-x1">50</view>
</view>
<view style="width: 48%;">
<view style="display: flex;align-items: center;">
<view style="padding: 12rpx;">
@ -144,7 +159,7 @@
</view>
<view class="title-x">消息</view>
</view>
<view class="title-x1">50</view>
<view class="title-x1">{{infoData.xx}}</view>
</view>
</view>
</view>
@ -156,20 +171,42 @@
</template>
<script>
import AQTabber from "@/components/AQ/AQTabber.vue"
export default {
components: {
AQTabber,
},
data() {
return {
import marketApi from '@/api/market.js';
}
},
methods: {
import AQTabber from "@/components/AQ/AQTabber.vue"
}
}
export default {
components: {
AQTabber,
},
data() {
return {
infoData:{},//
}
},
onShow() {
this.init()
},
methods: {
async init() {
this.getXsIndex()
},
//
async getXsIndex() {
let res = await marketApi.xsIndex({})
if (res.code != 1) {
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.infoData = res.data
},
}
}
</script>
<style lang="less" scoped>
@ -183,7 +220,13 @@
align-items: center;
background: #fff;
.title{
padding: 20rpx 0;
padding: 40rpx 0rpx;
/* 小程序端样式 */
// #ifdef MP-WEIXIN
padding: 80rpx 0rpx;
// #endif
font-size: 30rpx;
color: #858585;
}
@ -228,11 +271,52 @@
margin: auto;
}
.right1 {
width: 48%;
height: 95%;
margin: auto;
}
.right1 {
width: 48%;
height: 95%;
margin: auto;
.statistics_box {
margin: auto;
margin-top: 10rpx;
display: flex;
justify-content: space-between;
.item {
width: 90rpx;
display: flex;
flex-direction: column;
align-items: center;
.box {
width: 100%;
height: 328rpx;
border: 1px solid #ddd;
border-radius: 6rpx;
background: #f5f5f5;
position: relative;
.progress-bar {
width: 100%;
height: 0;
transition: height 0.3s ease;
position: absolute;
bottom: 0;
}
.ratio {
width: 100%;
position: absolute;
bottom: -0rpx;
font-size: 26rpx;
text-align: center;
}
}
.title {
margin-top: 5rpx;
padding: 0;
font-size: 26rpx;
color: #999999;;
text-align: center;
}
}
}
}
.this_month {
width: 100%;

49
pages/market/my/firm_info.vue

@ -4,7 +4,7 @@
<view style="height: 30rpx;"></view>
<view class="section_1">
<image class="pic" src="https://res.firstui.cn/static/images/common/img_logo.png" mode="aspectFit"></image>
<image class="pic" :src="$util.img(dataInfo.cover)" mode="aspectFit"></image>
</view>
<view class="title_section">基本信息</view>
@ -12,44 +12,41 @@
<view class="section_2">
<view class="item">
<view class="title">企业名称</view>
<view class="content">荧幕小将</view>
<view class="content">{{dataInfo.enterprise_name}}</view>
</view>
<view class="item">
<view class="title">企业简称</view>
<view class="content">Europa</view>
<view class="content">{{dataInfo.enterprise_abbreviation}}</view>
</view>
<view class="item">
<view class="title">企业电话</view>
<view class="content">0755-88888888</view>
<view class="content">{{dataInfo.phone}}</view>
</view>
<view class="item">
<view class="title">所属行业</view>
<view class="content">教育培训</view>
<view class="content">{{dataInfo.profession}}</view>
</view>
<view class="item">
<view class="title">企业名称</view>
<view class="content">荧幕小将</view>
</view>
<view class="item">
<view class="title">企业网址</view>
<view class="content">http://www.ymxj.com</view>
<view class="content">{{dataInfo.website}}</view>
</view>
<view class="item">
<view class="title">成立时间</view>
<view class="content">201x-08</view>
<view class="content">{{dataInfo.establishment_time}}</view>
</view>
</view>
<view class="title_section">企业介绍</view>
<view class="section_3">
<view class="html" v-html="htmlData"></view>
<view class="html" v-html="dataInfo.
content"></view>
</view>
@ -57,13 +54,39 @@
</template>
<script>
import memberApi from '@/api/member.js';
export default {
data() {
return {
htmlData:`<div data-v-24249f85="" class="con"><p data-v-24249f85="">爱查线索-爱查 ICP是上海凭安网络科技有限公司旗下产品。</p><p data-v-24249f85=""> 爱查线索-爱查 ICP(aichaicp.com)提供最新、最全的网站域名ICP备案信息查询,每天实时同步更新大量 官方数据。致力于为企业销售人员提供各种增值服务和解决各种问题,不再为找不到客户而苦恼! </p><h4 data-v-24249f85="">本站特色</h4><p data-v-24249f85="">【实时更新】采用全新技术算法,提供毫秒级别加载速度,给您带来前所未有的实时更新体验</p><p data-v-24249f85="">【备案监控】多地区ICP备案信息监控</p><p data-v-24249f85="">【深度功能】百度推广开通状态、整年备案信息导出、提醒功能等,满足大部分满足用户需求</p><p data-v-24249f85="">【联系方式】可以查询到ICP备案网站信息联系方式</p></div>`
dataInfo:{},//
}
},
onShow(){
this.init()
},
methods: {
//
async init(){
await this.getEnterpriseInformation()
},
//
async getEnterpriseInformation(){
let data = {}
let res = await memberApi.getEnterpriseInformation(data)
if(res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.dataInfo = res.data
console.log(123,this.dataInfo)
},
privacy_agreement(type){
uni.navigateTo({
url: '/pages/common/privacy_agreement?type='+type

112
pages/market/my/index.vue

@ -1,4 +1,4 @@
<!--我的-首页-->
<!--销售我的-首页-->
<template>
<view class="main_box">
<!--自定义导航栏-->
@ -11,12 +11,12 @@
<view class="user_section">
<view class="box">
<view class="left" @click="openViewMyInfo()">
<image class="pic" src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<view class="name">包子皮</view>
<image class="pic" :src="$util.img(userInfo.headimg)"></image>
<view class="name">{{userInfo.name}}</view>
</view>
<view class="right">
<view class="btn"></view>
<view class="btn">切换身份</view>
<!-- <view class="btn">切换身份</view>-->
<view class="btn"></view>
</view>
</view>
@ -35,11 +35,11 @@
<view class="course_box">
<view class="top">
<view class="item">
<view class="num">1234</view>
<view class="num">{{userInfo.yjds}}</view>
<view class="intro">业绩单数/</view>
</view>
<view class="item">
<view class="num">4</view>
<view class="num">{{userInfo.yqds}}</view>
<view class="intro">已签单数/</view>
</view>
<view class="item">
@ -63,14 +63,24 @@
<view class="main_section">
<view class="section_box">
<view class="item">
<view>已签客户</view>
<view>23</view>
<view @click="openViewSignedClientList()">已签客户</view>
<view>{{signedClientListCount}}</view>
</view>
<view class="item" @click="openViewFirmInfo()">
<view>企业信息</view>
<view></view>
</view>
<view class="item" @click="openViewMyAttendance()">
<view>我的考勤</view>
<view></view>
</view>
<view class="item" @click="openViewMyMessage()">
<view>我的消息</view>
<view></view>
</view>
</view>
<view class="section_box">
@ -92,7 +102,11 @@
</template>
<script>
// import user from '@/api/user.js';
import marketApi from '@/api/market.js';
import apiRoute from '@/api/apiRoute.js';
import {
Api_url
} from "@/common/config.js";
import AQTabber from "@/components/AQ/AQTabber.vue"
@ -103,11 +117,58 @@ export default {
data() {
return {
formData:{},
userInfo:{},//
//APi
uploadUrl: `${Api_url}/file/image`,
signedClientListCount:0,//
}
},
onLoad() {
},
onShow() {
this.init();
},
methods: {
//
async init(){
await this.getUserInfo()//
// await this.getSignedClientListCount()//
},
//
async getSignedClientListCount(){
let data = {
page:1,
limit:1,
}
let res = await marketApi.signClient(data);
if (res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.signedClientListCount = res.data.total
},
//
async getUserInfo(){
let data = {}
let res = await apiRoute.getPersonnelInfo(data);
if (res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.userInfo = res.data
},
//
openViewArrivalStatistics(){
uni.navigateTo({
@ -143,6 +204,22 @@ export default {
})
},
//-
openViewSignedClientList(){
uni.navigateTo({
url: '/pages/market/my/signed_client_list'
})
},
//-
openViewMyAttendance(){
uni.navigateTo({
url: '/pages/common/my_attendance'
})
},
//
openViewFirmInfo(){
uni.navigateTo({
@ -156,7 +233,14 @@ export default {
uni.navigateTo({
url: '/pages/market/my/set_up'
})
}
},
//-
openViewMyMessage(){
uni.navigateTo({
url: '/pages/common/my_message'
})
},
}
}
</script>
@ -176,7 +260,13 @@ export default {
align-items: center;
background: #29D3B4;
.title{
padding: 20rpx 0;
padding: 40rpx 0rpx;
/* 小程序端样式 */
// #ifdef MP-WEIXIN
padding: 80rpx 0rpx;
// #endif
font-size: 30rpx;
color: #fff;
}

245
pages/market/my/info.vue

@ -1,11 +1,16 @@
<!--授课统计-详情-->
<!--销售-个人资料-详情-->
<template>
<view class="main_box">
<view class="main_section">
<view class="section">
<view class="item">
<image @click="changeAvatar()" class="pic" src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<image
@click="changeAvatar()"
class="pic"
:src="$util.img(formData.header)"
></image>
<view class="btn" @click="changeAvatar()">修改头像</view>
</view>
</view>
@ -25,7 +30,7 @@
账号 <text class="required"></text>
</view>
<view class="input">
<input disabled placeholder="暂无" />
<input v-model="formData.username" disabled placeholder="暂无" />
</view>
</view>
@ -43,7 +48,7 @@
等级 <text class="required"></text>
</view>
<view class="input">
<input disabled placeholder="暂无" />
<input v-model="formData.member_level_name" disabled placeholder="暂无" />
</view>
</view>
</view>
@ -54,7 +59,7 @@
性别 <text class="required">*</text>
</view>
<view class="input">
<input placeholder="请选择性别" v-model="sex_name" @click="picker_show_sex=true"/>
<input placeholder="请选择性别" v-model="formData.gender" @click="picker_show_sex=true"/>
<fui-picker
layer="1"
:linkage="true"
@ -97,7 +102,7 @@
手机 <text class="required">*</text>
</view>
<view class="input">
<input v-model="formData.tel" placeholder="请输入手机" />
<input v-model="formData.phone" placeholder="请输入手机" />
</view>
</view>
@ -111,14 +116,16 @@
</view>
</view>
<view class="submet_btn">提交</view>
<view class="submet_btn" @click="submit">提交</view>
</view>
</view>
</template>
<script>
// import user from '@/api/user.js';
import {Api_url} from "@/common/config.js";
import marketApi from '@/api/market.js';
import {
Api_url
} from "@/common/config.js";
import AQTabber from "@/components/AQ/AQTabber"
@ -129,30 +136,43 @@ export default {
data() {
return {
formData:{
images_arr:[],
header:'',//
name:'',//
email:'',//
tel:'',//
wx:'',//
sex:'',//
username:'',//
address:'',//
gender:'',//|,
birthday:'',//
email:'',//
phone:'',//
wx:'',//
},
userInfo: {},
//APi
uploadUrl: `${Api_url}/salesmanapi/common/uploadFile`,
uploadUrl: `${Api_url}/file/image`,
//
picker_show_sex: false,
sex_name:'请选择',
options_sex_arr:[
{ value: 1, text: '男' },
{ value: 2, text: '女' },
options_sex_arr: [
{
value: 1,
text: '男'
},
{
value: 2,
text: '女'
},
],
//
minDate:'',
maxDate:'',
picker_show_birthday:false,
minDate: '',
maxDate: '',
picker_show_birthday: false,
upload_type: 1,
uploadHeadimg: '',
editHeadimg: '',
}
},
onLoad() {
@ -163,7 +183,44 @@ export default {
methods: {
async init(){
this.getBirthday()
// this.getBirthday()
this.setDateYear()
await this.getUserInfo()
},
//
setDateYear() {
let currentYear = new Date().getFullYear();
this.minDate = String(currentYear - 100);
this.maxDate = String(currentYear + 1);
},
//
async getUserInfo(){
let res = await marketApi.member({})
if (res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
//
this.formData = {
header: res.data.headimg,//
name: res.data.name,//
username: res.data.username,//
address: res.data.address,//
gender: res.data.gender,//|,
birthday: res.data.birthday,//
email: res.data.email,//
phone: res.data.phone,//
wx: res.data.wx || '',//
member_level_name: res.data.member_level_name || '',//
}
console.log(123,this.formData);
},
//
@ -179,33 +236,30 @@ export default {
}
})
},
async uploadFilePromise(url) {
console.log('AQ',this.uploadUrl,url)
return new Promise((resolve, reject) => {
let a = uni.uploadFile({
url: this.uploadUrl, //
filePath: url,
name: "file",
formData: {
token: this.$store.state.token,
},
success: (e) => {
console.log('上传成功1',e)
let res = JSON.parse(e.data.replace(/\ufeff/g, "") || "{}")
console.log('上传成功2',res)
if (res.code >= 0){
this.userInfo.pic = res.data.pic_path
this.editPic(res.data.pic_path)
}else{
this.$util.showToast({
title: res.message
});
}
setTimeout(() => {
resolve(res.data.data);
}, 1000);
},
});
uploadFilePromise(url) {
let token = uni.getStorageSync('token') || ''
let a = uni.uploadFile({
url: this.uploadUrl, //
filePath: url,
name: 'file',
header: {
'token': `${token}`, //token
},
success: (e) => {
let res = JSON.parse(e.data.replace(/\ufeff/g, "") || "{}")
console.log('上传成功2', res)
if (res.code == 1) {
this.upload_type = 2
this.formData.header = res.data.path
// this.editHeadimg = res.data.path
// this.uploadHeadimg = res.data.url
} else {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
},
});
},
//Api
@ -223,16 +277,15 @@ export default {
},
//
changePickerSex(e){
console.log('监听选择',e)
this.sex_name = e.text
this.formData.sex = e.value
changePickerSex(e) {
console.log('监听选择', e)
this.formData.gender = e.text
this.picker_show_sex = false
},
//
//+30
getBirthday(){
getBirthday() {
let date = new Date();
let year = date.getFullYear();
let month = date.getMonth() + 1;
@ -265,18 +318,88 @@ export default {
year_30 = year_30 + 1;
}
let minDate = year_30 + "-" + month_30 + "-" + day_30
let maxDate = year + "-" + month + "-" + day
let maxDate = year + "-" + month + "-" + day
this.minDate = minDate
this.maxDate = maxDate
},
//
changePickerBirthday(e){
console.log('监听生日选择',e)
changePickerBirthday(e) {
console.log('监听生日选择', e)
this.formData.birthday = e.result
this.picker_show_birthday = false
},
//
async submit() {
let data = {...this.formData}
if(!data.header){
uni.showToast({
title: '请上传头像',
icon: 'none'
})
return
}
if(!data.name){
uni.showToast({
title: '请填写',
icon: 'none'
})
return
}
if(!data.gender){
uni.showToast({
title: '请选择性别',
icon: 'none'
})
return
}
if(!data.birthday){
uni.showToast({
title: '请选择生日',
icon: 'none'
})
return
}
if(!data.email){
uni.showToast({
title: '请填写邮箱',
icon: 'none'
})
return
}
if(!data.phone){
uni.showToast({
title: '请填写手机',
icon: 'none'
})
return
}
let res = await marketApi.memberEdit(data)
if(res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
uni.showToast({
title: res.msg,
icon: 'success'
})
this.getUserInfo()
},
}
}
</script>
@ -294,7 +417,13 @@ export default {
align-items: center;
background: #29d3b4;
.title{
padding: 20rpx 0;
padding: 40rpx 0rpx;
/* 小程序端样式 */
// #ifdef MP-WEIXIN
padding: 80rpx 0rpx;
// #endif
font-size: 30rpx;
color: #315d55;
}

275
pages/market/my/signed_client_list.vue

@ -0,0 +1,275 @@
<!--已签客户-列表-->
<template>
<view class="main_box">
<!--自定义导航栏-->
<!-- <view class="navbar_section">-->
<!-- <view class="title">班级详情</view>-->
<!-- </view>-->
<view class="main_section">
<!-- 班级成员列表-->
<scroll-view
class="section_4"
scroll-y="true"
:lower-threshold="lowerThreshold"
@scrolltolower="loadMoreData"
style="height: 83vh;"
>
<view class="ul">
<view class="li"
v-for="(v,k) in tableList"
:key="k"
@click="openViewStudentInfo(v)">
<view class="left">
<view class="box_1">
<image class="pic"
v-if="v.header" :src="$util.img(v.header)"></image>
<image v-else class="pic" src="@/static/images/index/myk.png"></image>
<!-- <view class="tag_box">-->
<!-- 即将到期-->
<!-- </view>-->
</view>
<view class="box_2">
<view class="name">{{v.name}}</view>
<view class="date">课程截止时间{{v.end_time}}</view>
</view>
</view>
<view class="right">
<view class="item">
<view>{{v.have_study_time}}</view>
<view>已上课时</view>
</view>
<view class="item">
<view>{{v.end_study_time ? v.end_study_time:0}}</view>
<view>剩余课时</view>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
<!-- 底部导航-->
<!-- <AQTabber/>-->
</view>
</template>
<script>
import marketApi from '@/api/market.js';
import AQTabber from "@/components/AQ/AQTabber.vue"
export default {
components: {
AQTabber,
},
data() {
return {
loading:false,//
lowerThreshold: 100,//
isReachedBottom: false,//|true=|false=
//
filteredData:{
page:1,//
limit:10,//
total:10,//
name: '',//
},
tableList:[],//
}
},
onLoad() {
},
onShow() {
this.init();
},
methods: {
//
async init(){
await this.getList()//
},
//()
loadMoreData() {
//
if (!this.isReachedBottom) {
this.isReachedBottom = true;//
this.getList();
}
},
//
async resetFilteredData() {
this.isReachedBottom = false; // 便
this.filteredData.page = 1//
this.filteredData.limit = 10//
this.filteredData.total = 10//
},
//
async getList(){
this.loading = true
let data = {...this.filteredData}
//
if(this.filteredData.page * this.filteredData.limit > this.filteredData.total){
this.loading = false
uni.showToast({
title: '暂无更多',
icon: 'none'
})
return
}
if(data.page == 1){
this.tableList = []
}
let res = await marketApi.signClient(data)
this.loading = false
this.isReachedBottom = false;
if (res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.tableList = this.tableList.concat(res.data.data); // 使 concat
console.log('列表',this.tableList)
this.filteredData.total = res.data.total
this.filteredData.page++
},
//
openViewStudentInfo(item){
let students_id= item.id
uni.navigateTo({
url: `/pages/coach/student/info?students_id=${students_id}`
})
},
}
}
</script>
<style lang="less" scoped>
.main_box{
background: #292929 ;
}
//
.navbar_section{
display: flex;
justify-content: center;
align-items: center;
background: #292929;
.title{
padding: 40rpx 0rpx;
/* 小程序端样式 */
// #ifdef MP-WEIXIN
padding: 80rpx 0rpx;
// #endif
font-size: 30rpx;
color: #fff;
}
}
.main_section{
min-height: 95vh;
background: #292929 100%;
padding: 0 24rpx;
padding-top: 40rpx;
padding-bottom: 150rpx;
font-size: 24rpx;
color: #FFFFFF;
//
.section_4{
.ul{
display: flex;
flex-direction: column;
gap: 10rpx;
.li{
padding: 20rpx 0;
padding-bottom: 40rpx;
border-bottom: 2px solid #D7D7D7;
display: flex;
justify-content: space-between;
.left{
display: flex;
align-items: center;
gap: 30rpx;
.box_1{
padding-left: 20rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: relative;
.pic{
width: 84rpx;
height: 84rpx;
border-radius: 50%;
}
.tag_box{
position: absolute;
bottom: -30rpx;
width: 120rpx;
height: 38rpx;
background-color: #F59A23;
border-radius: 4rpx;
line-height: 35rpx;
text-align: center;
font-size: 20rpx;
}
}
.box_2{
display: flex;
flex-direction: column;
gap: 20rpx;
.name{
font-size: 28rpx;
}
.date{
font-size: 24rpx;
}
}
}
.right{
display: flex;
align-items: center;
gap: 14rpx;
.item{
border: 1px solid #00E5BB;
border-radius: 10rpx;
width: 102rpx;
display: flex;
flex-direction: column;
view{
text-align: center;
height: 50rpx;
line-height: 50rpx;
}
view:nth-child(1){
font-size: 32rpx;
background-color: #fff;
color: #00e5bb;
}
view:nth-child(2){
font-size: 20rpx;
background-color: #00e5bb;
}
}
}
}
}
}
}
</style>

411
pages/student/index/index.vue

@ -14,39 +14,41 @@
<view class="card-back color-style"></view>
<view class="card-backs color-style"></view>
<view class="card-con">
<view class="card-head">
<view>
<span class="card-head-txt">班级</span>
<span class="card-head-txt1 card-head-back1">篮球少儿班</span>
</view>
<view>
<span class="card-head-txt">已耗课时</span>
<span class="card-head-txt1 card-head-back2">24/</span><span class="card-head-txt">60</span>
</view>
</view>
<view class="card-con-txt">课程到期时间2021.12.25</view>
<!-- <view class="card-head">-->
<!-- <view>-->
<!-- <span class="card-head-txt">班级</span>-->
<!-- <span class="card-head-txt1 card-head-back1">篮球少儿班</span>-->
<!-- </view>-->
<!-- <view>-->
<!-- <span class="card-head-txt">已耗课时</span>-->
<!-- <span class="card-head-txt1 card-head-back2">24/</span><span class="card-head-txt">60</span>-->
<!-- </view>-->
<!-- </view>-->
<!-- <view class="card-con-txt">课程到期时间2021.12.25</view>-->
<view class="card-con-txt1">
<view class="card-con-txt1-left">
<image src="@/static/images/index/score.png" class="overlay-image"></image>
<view class="card-con-txt1-left-txt top">90</view>
<view class="card-con-txt1-left-txt top">{{memberIndexData.tx.score}}</view>
<view class="card-con-txt1-left-txt top1">综合评分</view>
</view>
<view class="card-con-txt1-right">
<view style="color: #AAAAAA;padding: 5rpx;">数据测评时间2020.03.12</view>
<view style="color: #AAAAAA;padding: 5rpx;">数据测评时间{{$util.formatToDateTime(memberIndexData.tx.create_time,'Y-m-d')}}</view>
<view style="display: flex;justify-content: space-around;margin-top: 20rpx;">
<view>
<view style="font-size: 48rpx;color: #29d3b4;">123</view>
<view style="font-size: 48rpx;color: #29d3b4;">{{memberIndexData.tx.height * 100}}</view>
<view style="color: #AAAAAA;font-size: 30rpx;">身高CM</view>
</view>
<view>
<view style="font-size: 48rpx;color: #29d3b4;">45</view>
<view style="font-size: 48rpx;color: #29d3b4;">{{memberIndexData.tx.weight}}</view>
<view style="color: #AAAAAA;font-size: 30rpx;">体重KG</view>
</view>
</view>
</view>
</view>
<view class="more" @click="physical_examination">更多</view>
<view class="more" @click="physical_examination(memberIndexData)">更多</view>
</view>
<view class="upcomin-classes">
<view class="upcomin-classes-div">
<view class="upcomin-classes-div-con">
@ -54,21 +56,23 @@
<view class="upcomin-classes-div-con-centre"
style="width: 2rpx;height: 60rpx;background-color: #fff;margin-left: 25rpx;"></view>
<view style="margin-left: 25rpx;">
<view>5/28 周五 15:30 - 17:30</view>
<view>301 篮球少儿课程</view>
<view>{{$util.formatToDateTime(memberIndexData.kcyg.date_time,'m-d')}} {{memberIndexData.kcyg.weekday}} {{memberIndexData.kcyg.time_slot[0]}}-{{memberIndexData.kcyg.time_slot[1]}}</view>
<view>{{memberIndexData.kcyg.address}} {{memberIndexData.kcyg.courses_name}}</view>
</view>
<view class="upcomin-classes-div-con-right" @click="details">
<view class="upcomin-classes-div-con-right" @click="openViewTimetableInfo(memberIndexData.kcyg)">
详情
</view>
</view>
</view>
</view>
<view class="after-class">
<view class="after-class-title">
<view class="after-class-title-left">课后作业</view>
<view class="after-class-title-right" @click="jobList">全部</view>
</view>
<view class="after-class-con">
<view class="after-class-con" v-for="(v,k) in jobAssignmentsInfo" :key="k" @click="openViewWorkDetails(v)">
<view class="after-class-con-txt">
<view style="width: 25%;margin-top: 5%;">
<view style="font-size: 55rpx;color: #fff;"><span style="color: #29d3b4;">12</span>/23
@ -78,31 +82,38 @@
<view style="width: 70%;">
<view style="color: #fff;display: flex;justify-content: space-between;align-items: center;">
<view style="display: flex;align-items: center;">
<image src="@/static/images/index/dian.png" style="width: 50rpx;height: 50rpx;">
<image :src="$util.img(v.coach_pic)" style="width: 50rpx;height: 50rpx;">
</image>
<span style="padding-left: 10rpx;font-size: 35rpx;">包子皮</span>
<span style="padding-left: 10rpx;font-size: 35rpx;">{{v.coach_name}}</span>
</view>
<view>
<fui-button background="#404045" color="#F59A23" borderColor="#F59A23"
btnSize="mini">上传</fui-button>
btnSize="mini" @click="submitJob(v)">上传</fui-button>
</view>
</view>
<view style="color: #fff;padding: 10rpx;">时间2020.05:25 15:30 - 17:30</view>
<view class="multi-line-ellipsis">
作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述</view>
<view style="color: #fff;padding: 10rpx;">时间{{v.create_time}}</view>
<view class="multi-line-ellipsis" v-html="v.content_text">
</view>
</view>
</view>
</view>
<view class="multi-line-ellipsis text-style">
作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述</view>
<view style="width: 92%;margin: auto;border-radius: 15rpx;">
<video style="width: 100%;border-radius: 15rpx;"></video>
</view>
<view class="multi-line-ellipsis text-style">
作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述</view>
<view style="width: 92%;margin: auto;border-radius: 15rpx;">
<video style="width: 100%;border-radius: 15rpx;"></video>
</view>
<view class="item" v-for="(v,k) in assignmentsList" :key="k" @click="openViewWorkDetails(v)">
<view class="multi-line-ellipsis text-style" v-html="v.content_text"></view>
<view style="width: 92%;margin: auto;border-radius: 15rpx;" v-if="v.student_file">
<video v-if="v.student_file_type == 2" style="width: 100%;border-radius: 15rpx;" :src="$util.img(v.student_file)"></video>
<image v-else style="width: 100%;border-radius: 15rpx;" :src="$util.img(v.student_file)" mode="aspectFit"></image>
</view>
</view>
<!-- <view class="multi-line-ellipsis text-style">-->
<!-- 作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述</view>-->
<!-- <view style="width: 92%;margin: auto;border-radius: 15rpx;">-->
<!-- <video style="width: 100%;border-radius: 15rpx;"></video>-->
<!-- </view>-->
</view>
<view style="height: 180rpx;width: 100%;"></view>
</view>
@ -111,7 +122,8 @@
</template>
<script>
import member from '@/api/member.js';
import {Api_url} from "@/common/config";
import memberApi from '@/api/member.js';
import AQTabber from "@/components/AQ/AQTabber.vue"
export default {
components: {
@ -119,16 +131,146 @@
},
data() {
return {
//
uploadApiUrl: ``,
uploadImageApiUrl: `${Api_url}/file/image`,
uploadVideoApiUrl: `${Api_url}/file/video`,
member_info: [],
assignmentsList: [],//
jobAssignmentsInfo: [],//
memberIndexData:{
tx:{//
height: '', //
weight: '', //
score: '', //
create_time: '' //
},
kcyg: { //
id: '', // ID
date_time: "", //
time_slot: "", //
address: "", //
courses_name: "", //
date_md: "", // /
weekday: "" //
}
},//
path_arr:{
'1':'/pages/coach/home/index',//
'2':'/pages/market/index/index',//
'3':'/pages/student/index/index',//
},
thisPath:'',//('')
openPath:'',//('')
}
},
onLoad() {
this.member_init()
},
onShow(){
this.openViewHome()//-
},
methods: {
//
async init(){
this.member_init()
this.getMemberIndex()
this.getList()
this.getJobAssignmentsInfo()
},
//-
async openViewHome(){
//
let pages = getCurrentPages();
//
this.thisPath = '/' + pages[0].route
//
let userType = String(uni.getStorageSync('userType'))
this.openPath = this.path_arr[userType]
if(this.thisPath != this.openPath){
//tabBar-
uni.setStorageSync('tabBerIndex', 0)
uni.navigateTo({
url: this.openPath
})
}else{
//
this.init()
}
console.log(123123123123,this.thisPath,userType,this.path_arr[userType])
},
async getMemberIndex(){
let res = await memberApi.memberIndex({})
if(res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
// console.log('',res)
if(res.data.kcyg.time_slot){
res.data.kcyg.time_slot = res.data.kcyg.time_slot.split(',');
}
this.memberIndexData = res.data
},
//
async getList(){
let data = {
page: 1,
limit: 10,
status: '2',//1=,2=,3=
}
let res = await memberApi.assignmentsList(data)
if(res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.assignmentsList = res.data.data
// console.log('',this.assignmentsList)
},
//
async getJobAssignmentsInfo(){
let data = {
page: 1,
limit: 1,
status: '1',//1=,2=,3=
}
let res = await memberApi.assignmentsList(data)
if(res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.jobAssignmentsInfo = res.data.data
// console.log('',this.jobAssignmentsInfo)
},
//
member_init() {
member.member().then(res => {
memberApi.member().then(res => {
if(res.code == 1){
this.member_info = res.data
}else{
@ -141,17 +283,183 @@
url: '/pages/student/index/work_details'
})
},
physical_examination(){
//
physical_examination(e){
let students_id = e.students_id
uni.navigateTo({
url: '/pages/student/index/physical_examination'
url: `/pages/student/index/physical_examination?students_id=${students_id}`
})
},
//
jobList(){
uni.navigateTo({
url: '/pages/student/index/job_list'
})
}
}
},
//
async submitJob(item) {
let type = item.content_type // 12
try {
//
let uploadRes = await this.uploadFile(type)
// console.log('', uploadRes)
//
if (!uploadRes.data.path) {
return
}
//
let data = {
id: item.id, // id
student_file: uploadRes.data.path, //
student_file_type: type, // 12
student_content: '', //
}
//
await this.assignmentsSubmit(data)
} catch (error) {
console.error('上传或提交作业失败:', error)
alert('上传或提交作业失败')
}
},
// (/) type=12
async uploadFile(type) {
return new Promise((resolve, reject) => {
if (type == 1) {
this.uploadApiUrl = this.uploadImageApiUrl
uni.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success: async (res) => {
const tempFilePath = res.tempFilePaths[0]
//
try {
let data = await this.uploadFilePromise(tempFilePath)
resolve(data)
} catch (error) {
reject(error)
}
},
fail: (error) => {
reject(error)
}
})
} else {
this.uploadApiUrl = this.uploadVideoApiUrl
uni.chooseVideo({
count: 1,
// sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success: async (res) => {
// console.log(':', res); // res tempFilePaths
const tempFilePath = res.tempFilePath; //
// console.log('',tempFilePath)
//
try {
let data = await this.uploadFilePromise(tempFilePath)
resolve(data)
} catch (error) {
reject(error)
}
},
fail: (error) => {
reject(error)
}
})
}
})
},
//
uploadFilePromise(url) {
return new Promise((resolve, reject) => {
let token = uni.getStorageSync('token') || ''
uni.uploadFile({
url: this.uploadApiUrl, //
filePath: url,
name: 'file',
header: {
'token': `${token}`, // token
},
success: (e) => {
let res = JSON.parse(e.data.replace(/\ufeff/g, "") || "{}")
// console.log('2', res)
if (res.code == 1) {
resolve({
code: 1,
data: res.data,
msg: '上传成功'
})
} else {
uni.showToast({
title: res.msg,
icon: 'none'
})
reject({
code: 0,
data: {},
msg: '上传失败'
})
}
},
fail: (error) => {
reject(error)
}
})
})
},
//
async assignmentsSubmit(item) {
let data = {
id: item.id, // id
student_file: item.student_file, //
student_file_type: item.student_file_type, // 12
student_content: item.student_content, //
}
let res = await memberApi.assignmentsSubmit(data)
if (res.code != 1) {
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
uni.showToast({
title: res.msg,
icon: 'success'
})
// 1s
setTimeout(() => {
this.init()
}, 1000)
},
//-
openViewWorkDetails(item) {
let id = item.id
uni.navigateTo({
url: `/pages/student/index/work_details?id=${id}`
})
},
//-
openViewTimetableInfo(item) {
let id = item.id
uni.navigateTo({
url: `/pages/student/timetable/info?id=${id}`
})
},
}
}
</script>
@ -164,8 +472,15 @@
align-items: center;
background: #29d3b4;
.title{
padding: 110rpx 0 20rpx;
font-size: 30rpx;
padding: 40rpx 0rpx;
/* 小程序端样式 */
// #ifdef MP-WEIXIN
padding: 80rpx 0rpx;
// #endif
font-size: 30rpx;
color: #fff;
}
}
@ -176,7 +491,7 @@
.overlay-image {
width: 95%;
height: 100%;
height: 90%;
}
.multi-line-ellipsis {
@ -238,7 +553,7 @@
.card-con {
width: 92%;
height: 92%;
//height: 92%;
background-color: #fff;
border-radius: 20rpx;
position: absolute;
@ -278,7 +593,7 @@
.card-con-txt1 {
display: flex;
justify-content: space-between;
padding: 10rpx 20rpx 0;
padding: 20rpx 20rpx 0;
height: 220rpx;
}

220
pages/student/index/job_list.vue

@ -3,64 +3,164 @@
<view class="after-class-title">
<view class="after-class-title-left">课后作业</view>
</view>
<view>
<view class="con-list">
<view class="con-list-img">
<image class="pic" src="@/static/images/index/img.jpg"></image>
</view>
<view class="con" style="margin-top: 20rpx;">
时间2020.05:25 15:30
</view>
<view class="con" style="margin-bottom: 20rpx;">
作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述
</view>
<view class="mark" v-if="true">
<image class="check_mark" src="@/static/images/index/check_mark.png"></image>
</view>
<view class="assignment">
班级作业
</view>
</view>
<view class="con-list">
<view class="con-list-img">
<video class="pic" style="width: 100%;border-radius: 15rpx;"></video>
</view>
<view class="con" style="margin-top: 20rpx;">
时间2020.05:25 15:30
</view>
<view class="con" style="margin-bottom: 20rpx;">
作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述
</view>
<view class="mark" v-if="false">
<image class="check_mark" src="@/static/images/index/check_mark.png"></image>
</view>
<view class="assignment">
个人作业
</view>
</view>
</view>
<scroll-view
class="table_list"
scroll-y="true"
:lower-threshold="lowerThreshold"
@scrolltolower="loadMoreData"
style="height: 100vh;"
>
<view class="con-list" v-for="(v,k) in tableList" :key="k" @click="openViewWorkDetails(v)">
<view class="con-list-img" v-if="v.student_file">
<video v-if="v.student_file_type == 2" class="pic" style="width: 100%;border-radius: 15rpx;" :src="$util.img(v.student_file)"></video>
<image v-else style="width: 100%;border-radius: 15rpx;" :src="$util.img(v.student_file)" mode="aspectFit"></image>
</view>
<view class="date_box">
<view class="describe" style="margin-top: 20rpx;">
时间{{v.create_time}}
</view>
<!--是否已经完成作业-->
<view class="mark" v-if="v.status == 2">
<image class="check_mark" src="@/static/images/index/check_mark.png"></image>
</view>
</view>
<!--作业描述-->
<view class="con" style="margin-bottom: 20rpx; color:#fff;" v-html="v.content_text"></view>
<view class="assignment">
<view>{{v.type == 1 ? '班级作业' : '个人作业'}}</view>
</view>
</view>
</scroll-view>
</view>
</template>
<script>
import memberApi from '@/api/member.js';
export default {
data() {
return {
loading:false,//
lowerThreshold: 100,//
isReachedBottom: false,//|true=|false=
//
filteredData:{
page:1,//
limit:10,//
total:10,//
status: '',//1=,2=,3=
},
tableList:[],//
}
},
onShow(){
this.init()//
},
//
async onPullDownRefresh() {
//
await this.resetFilteredData()
await this.getList()
},
methods: {
//
async init(){
await this.getList();
},
//()
loadMoreData() {
//
if (!this.isReachedBottom) {
this.isReachedBottom = true;//
this.getList();
}
},
//
async resetFilteredData() {
this.isReachedBottom = false; // 便
this.filteredData.page = 1//
this.filteredData.limit = 10//
this.filteredData.total = 10//
},
//
async getList(){
this.loading = true
}
let data = {...this.filteredData}
//
if(this.filteredData.page * this.filteredData.limit > this.filteredData.total){
this.loading = false
uni.showToast({
title: '暂无更多',
icon: 'none'
})
return
}
if(data.page == 1){
this.tableList = []
}
let res = await memberApi.assignmentsList(data)
this.loading = false
this.isReachedBottom = false;
if (res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.tableList = this.tableList.concat(res.data.data); // 使 concat
console.log('列表',this.tableList)
this.filteredData.total = res.data.total
this.filteredData.page++
},
//-
openViewWorkDetails(item) {
let id = item.id
uni.navigateTo({
url: `/pages/student/index/work_details?id=${id}`
})
},
},
}
</script>
<style>
<style lang="less" scoped>
.main_box{
width: 100%;
height: 100vh;
background: #292929;
overflow: auto;
.table_list{
padding-bottom: 150rpx;
}
}
.after-class-title {
width: 92%;
@ -79,7 +179,16 @@
padding: 30rpx;
margin-top: 20rpx;
border-bottom: 2rpx #fff solid;
position: relative;
.date_box{
padding-top: 30rpx;
display: flex;
justify-content: space-between;
align-items: center;
.describe{
width: 75%;
color: #fff;
}
}
}
.con-list-img{
width: 100%;
@ -87,6 +196,16 @@
display: flex;
align-items: center;
justify-content: center;
video{
width: 100%;
height: 280rpx;
}
image{
width: 100%;
height: 280rpx;
}
}
.pic{
width: 85%;
@ -98,9 +217,6 @@
padding-top: 30rpx;
}
.mark{
position: absolute;
right: 8%;
bottom: 23%;
width: 70rpx;
height: 70rpx;
border-radius: 100%;
@ -114,14 +230,16 @@
height: 80%;
}
.assignment{
position: absolute;
right: 3%;
bottom: 10%;
width: 150rpx;
text-align: center;
border-radius: 10rpx;
padding: 6rpx 12rpx;
color: #6b9d53;
border: 2rpx #6b9d53 solid;
display: flex;
justify-content: flex-end;
align-items: center;
view{
padding: 6rpx 12rpx;
color: #6b9d53;
border: 2rpx #6b9d53 solid;
border-radius: 10rpx;
width: 150rpx;
text-align: center;
}
}
</style>

159
pages/student/index/physical_examination.vue

@ -1,46 +1,138 @@
<!--体测数据-详情-->
<template>
<view class="overall">
<view class="date">2021年03月12日</view>
<view class="content">
<view class="circle-container">
<view class="card-con-txt1-left">
<image src="@/static/images/index/score.png" class="overlay-image"></image>
</view>
<view class="card-con-txt1-left-txt">90</view>
<view class="card-con-txt1-left-txt top1">综合评分</view>
</view>
<view style="height: 170rpx;"></view>
<view style="display: flex;justify-content: space-around;">
<view style="text-align: center;">
<view style="color: #AAAAAA;font-size: 30rpx;padding: 15rpx 0;">身高 (CM)</view>
<view style="font-size: 55rpx;color: #29d3b4;">123</view>
</view>
<view style="text-align: center;">
<view style="color: #AAAAAA;font-size: 30rpx;padding: 15rpx 0;">体重 (KG)</view>
<view style="font-size: 55rpx;color: #29d3b4;">45</view>
</view>
</view>
<view class="coach-message">
<view>
<image src="@/static/images/index/lv.png" class="drop-image"></image>
</view>
<view style="padding: 15rpx 0 0 5rpx;line-height: 1.6;font-size: 30rpx;color: #7F7F7F;">教练寄语教练寄语教练寄语教练寄语教练寄语教练寄语教练寄教练寄语教练寄语教练寄语教练寄语教练寄语教练教练寄语教练寄语教练寄语教练寄语练教练语教练寄教练寄语教练寄语教练寄语教练寄语教练寄语教练</view>
</view>
<view style="font-size: 45rpx;text-align: center;margin-top: 30%;">详细数据信息</view>
</view>
<scroll-view
class="table_list"
scroll-y="true"
:lower-threshold="lowerThreshold"
@scrolltolower="loadMoreData"
style="height: 100vh;"
>
<view class="item" v-for="(v,k) in tableList" :key="k">
<view class="date">{{$util.formatToDateTime(v.create_time, 'Y-m-d')}}</view>
<view class="content">
<view class="circle-container">
<view class="card-con-txt1-left">
<image src="@/static/images/index/score.png" class="overlay-image"></image>
</view>
<view class="card-con-txt1-left-txt">{{v.score}}</view>
<view class="card-con-txt1-left-txt top1">综合评分</view>
</view>
<view style="height: 170rpx;"></view>
<view style="display: flex;justify-content: space-around;">
<view style="text-align: center;">
<view style="color: #AAAAAA;font-size: 30rpx;padding: 15rpx 0;">身高 (CM)</view>
<view style="font-size: 55rpx;color: #29d3b4;">{{(v.height * 100)}}</view>
</view>
<view style="text-align: center;">
<view style="color: #AAAAAA;font-size: 30rpx;padding: 15rpx 0;">体重 (KG)</view>
<view style="font-size: 55rpx;color: #29d3b4;">{{v.weight}}</view>
</view>
</view>
<view class="coach-message">
<view>
<image src="@/static/images/index/lv.png" class="drop-image"></image>
</view>
<view style="padding: 15rpx 0 0 5rpx;line-height: 1.6;font-size: 30rpx;color: #7F7F7F;">{{v.content}}</view>
</view>
<view style="font-size: 45rpx;text-align: center;margin-top: 30%;">详细数据信息</view>
</view>
</view>
</scroll-view>
</view>
</template>
<script>
import memberApi from '@/api/member.js';
export default {
data() {
return {
loading:false,//
lowerThreshold: 100,//
isReachedBottom: false,//|true=|false=
//
filteredData:{
page:1,//
limit:10,//
total:10,//
students_id: '',//id
},
tableList:[],//
}
},
onLoad(options) {
this.filteredData.students_id = options.students_id//id
},
onShow(){
this.init()
},
methods: {
//
async init(){
this.getList()
},
//()
loadMoreData() {
//
if (!this.isReachedBottom) {
this.isReachedBottom = true;//
this.getList();
}
},
//
async resetFilteredData() {
this.isReachedBottom = false; // 便
this.filteredData.page = 1//
this.filteredData.limit = 10//
this.filteredData.total = 10//
},
//--
async getList(){
this.loading = true
let data = {...this.filteredData}
//
if(this.filteredData.page * this.filteredData.limit > this.filteredData.total){
this.loading = false
uni.showToast({
title: '暂无更多',
icon: 'none'
})
return
}
if(data.page == 1){
this.tableList = []
}
//-
let res = await memberApi.surveyList(data)
this.loading = false
this.isReachedBottom = false;
if (res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.tableList = this.tableList.concat(res.data.list.data); // 使 concat
// console.log('',this.tableList)
this.filteredData.total = res.data.list.total
this.filteredData.page++
},
}
}
</script>
@ -52,6 +144,15 @@
background-color: #29d3b4;
}
.table_list{
padding-bottom: 40rpx;
display: flex;
flex-direction: column;
.item{
margin-bottom: 40rpx;
}
}
.date {
color: #fff;
width: 92%;

65
pages/student/index/work_details.vue

@ -1,30 +1,66 @@
<!--作业详情-->
<template>
<view>
<view class="top-style">
<image src="@/static/images/index/work_details.png" class="top-style-img">
<!-- 作业展示-->
<view class="top-style" v-if="infoData.student_file">
<video v-if="infoData.student_file_type == 2" class="pic" style="width: 100%;border-radius: 15rpx;" :src="$util.img(infoData.student_file)"></video>
<image v-else style="width: 100%;border-radius: 15rpx;" :src="$util.img(infoData.student_file)" mode="aspectFit"></image>
</view>
<!-- 简练信息+作业描述-->
<view class="below-style">
<view class="head-img">
<fui-avatar width="80" src="https://img1.baidu.com/it/u=3598104138,3632108415&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=800"></fui-avatar>
<view class="head-text">智卓燕</view>
<!--教练头像-->
<fui-avatar width="80" :src="$util.img(infoData.coach_pic)"></fui-avatar>
<view class="head-text">{{infoData .coach_name}}</view>
</view>
<view class="multi-line-ellipsis">
作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述作业描述</view>
<view class="multi-line-ellipsis" v-html="infoData.content_text"></view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
import memberApi from '@/api/member.js';
}
},
methods: {
}
}
export default {
data() {
return {
//
filteredData: {
id: '',//id
},
infoData:{},
}
},
onLoad(options) {
this.filteredData.id = options.id
},
onShow(){
this.init()//
},
methods: {
//
async init(){
this.getAssignmentsInfo()
},
//
async getAssignmentsInfo() {
let params = {...this.filteredData}
let res = await memberApi.assignmentsInfo(params)
if (res.code != 1) {
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.infoData = res.data
},
}
}
</script>
<style lang="less" scoped>
@ -32,6 +68,7 @@
width: 92%;
height: 700rpx;
margin: auto;
margin-top: 45rpx;
display: flex;
align-items: center;
justify-content: center;

2
pages/student/login/forgot.vue

@ -66,7 +66,7 @@
}
</script>
<style>
<style lang="less" scoped>
page {
font-weight: normal;
}

324
pages/student/login/login.vue

@ -1,174 +1,188 @@
<template>
<view>
<view style="height: 500rpx;background-color:#fff;">
<view style="height: 150rpx;"></view>
<view class="image-container;">
<image src="@/static/images/login/login1.png" class="base-image"></image>
<image src="@/static/images/login/login2.png" class="overlay-image"></image>
</view>
<view style="width: 100%;font-size: 60rpx;color: #ccc;text-align: center;margin-top: 60rpx;">
运动课堂
</view>
</view>
<view :style="{'background-color':'#fff','width':'100%','height':'100vh' }">
<view style="width: 95%;height: 30rpx;"></view>
<view style="width: 95%;margin:30rpx auto;">
<fui-input borderTop placeholder="登录账号" v-model="user" @input="input"
backgroundColor="#f2f2f2"></fui-input>
</view>
<view style="width: 95%;margin: auto;">
<fui-input borderTop :padding="['20rpx','32rpx']" v-model="password1" placeholder="登录密码"
:password="password" @input="input" backgroundColor="#f2f2f2">
<fui-icon :name="password?'invisible':'visible'" color="#B2B2B2" :size="50"
@click="change"></fui-icon>
</fui-input>
</view>
<view style="width: 95%;margin:60rpx auto;">
<fui-button background="#00be8c" radius="5rpx" @click="login">登录</fui-button>
</view>
<view>
<view style="height: 500rpx;background-color:#fff;">
<view style="height: 150rpx;"></view>
<view class="image-container;">
<image src="@/static/images/login/login1.png" class="base-image"></image>
<image src="@/static/images/login/login2.png" class="overlay-image"></image>
</view>
<view style="width: 100%;font-size: 60rpx;color: #ccc;text-align: center;margin-top: 60rpx;">
运动课堂
</view>
</view>
<view :style="{'background-color':'#fff','width':'100%','height':'100vh' }">
<view style="width: 95%;height: 30rpx;"></view>
<view style="width: 95%;margin:30rpx auto;">
<fui-input borderTop placeholder="登录账号" v-model="user" @input="input"
backgroundColor="#f2f2f2"></fui-input>
</view>
<view style="width: 95%;margin: auto;">
<fui-input borderTop :padding="['20rpx','32rpx']" v-model="password1" placeholder="登录密码"
:password="password" @input="input" backgroundColor="#f2f2f2">
<fui-icon :name="password?'invisible':'visible'" color="#B2B2B2" :size="50"
@click="change"></fui-icon>
</fui-input>
</view>
<view style="width: 95%;margin:60rpx auto;">
<fui-button background="#00be8c" radius="5rpx" @click="login">登录</fui-button>
</view>
<view style="width: 95%;margin:60rpx auto;">
<fui-button background="#fff" radius="5rpx" @click="forgot" color="#00be8c">忘记登录密码</fui-button>
</view>
<view style="width: 95%;margin:60rpx auto;">
<fui-button background="#fff" radius="5rpx" @click="forgot" color="#00be8c">忘记登录密码</fui-button>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import memberApi from '@/api/member.js';
import apiRoute from '@/api/apiRoute.js';
export default {
data() {
return {
password: true,
user: '18888888888', //
password1: '123456' //
}
},
onLoad() {
// uni.hideHomeButton()
// console.log(uni.getStorageSync('um_id'))
},
methods: {
input(e) {
console.log(e)
},
change() {
this.password = !this.password
},
forgot() {
uni.navigateTo({
url: '/pages/student/login/forgot'
})
},
//
login() {
let item = {};
item['username'] = this.user
item['password'] = this.password1
//
memberApi.login(item).then(res => {
if (res.code == 1) {
uni.setStorageSync('token', res.data.token);
let userType = res.data.userType
export default {
data() {
return {
password: true,
user: '15148228108', //
password1: '123123', //
loginType:'',//|1=,2=,3=
}
},
onLoad(options) {
this.loginType = options.loginType ?? '2'//|1=,2=,3=
// uni.hideHomeButton()
// console.log(uni.getStorageSync('um_id'))
},
methods: {
input(e) {
console.log(e)
},
change() {
this.password = !this.password
},
forgot() {
uni.navigateTo({
url: '/pages/student/login/forgot'
})
},
//
async login() {
let item = {};
item['username'] = this.user
item['password'] = this.password1
// userType = 2//
let res
//|1=,2=,3=
if(this.loginType == 1){
}else if(this.loginType == 2){
//
let params = {
'phone': this.user,
'password': this.password1,
'login_type': 2,
}
res = await apiRoute.personnelLogin(params)
console.log(123123,res)
uni.setStorageSync('userType', userType);
uni.setStorageSync('tabBerIndex', 0);
}else if (this.loginType == 3){
}
let url_path = ''
switch (String(userType)) {
case '1': //
url_path = '/pages/coach/home/index'
break;
case '2': //
url_path = '/pages/market/index/index'
break;
case '3': //
url_path = '/pages/student/index/index'
break;
default:
uni.showToast({
title: '用户类型错误',
icon: 'none'
})
return;
}
if(!res.code){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
uni.setStorageSync('expires_time', res.data.expires_time);//token
uni.setStorageSync('token', res.data.token);
let userType = res.data.user_type
console.log('用户类型', userType)
uni.setStorageSync('userType', userType);
uni.setStorageSync('tabBerIndex', 0);
uni.navigateTo({
url: url_path
})
} else {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
});
},
loginWx() {
uni.login({
provider: 'weixin',
success: (res) => {
console.log(res)
medication.wechatminilogin({
code: res.code
}).then(res1 => {
if (res1.status == 200) {
uni.setStorageSync('um_id', res1.data.um_id);
uni.setStorageSync('user', res1.data);
uni.switchTab({
url: '/pages/my/my'
})
} else {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
})
}
});
},
}
}
let url_path = ''
switch (String(userType)) {
case '1': //
url_path = '/pages/coach/home/index'
break;
case '2': //
url_path = '/pages/market/index/index'
break;
case '3': //
url_path = '/pages/student/index/index'
break;
default:
uni.showToast({
title: '用户类型错误',
icon: 'none'
})
return;
}
uni.navigateTo({
url: url_path
})
},
loginWx() {
uni.login({
provider: 'weixin',
success: (res) => {
console.log(res)
medication.wechatminilogin({
code: res.code
}).then(res1 => {
if (res1.status == 200) {
uni.setStorageSync('um_id', res1.data.um_id);
uni.setStorageSync('user', res1.data);
uni.switchTab({
url: '/pages/my/my'
})
} else {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
})
}
});
},
}
}
</script>
<style>
page {
font-weight: normal;
}
<style lang="less" scoped>
page {
font-weight: normal;
}
.fui-section__title {
margin-left: 32rpx;
}
.fui-section__title {
margin-left: 32rpx;
}
.fui-left__icon {
padding-right: 24rpx;
}
.fui-left__icon {
padding-right: 24rpx;
}
.image-container {
margin: auto;
position: relative;
width: 150rpx;
/* 设置与第一张图片相同的宽度 */
height: 150rpx;
/* 设置与第一张图片相同的高度 */
}
.image-container {
margin: auto;
position: relative;
width: 150rpx;
/* 设置与第一张图片相同的宽度 */
height: 150rpx;
/* 设置与第一张图片相同的高度 */
}
.base-image {
width: 100%;
height: 100%;
}
.base-image {
width: 100%;
height: 100%;
}
.overlay-image {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 100rpx;
height: 100rpx;
}
.overlay-image {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 100rpx;
height: 100rpx;
}
</style>

190
pages/student/my/lesson_consumption.vue

@ -1,95 +1,29 @@
<!--课时消耗列表-->
<template>
<view class="assemble">
<view style="height: 50rpx;"></view>
<view class="ul">
<view class="li">
<view class="li" v-for="(v,k) in tableList" :key="k">
<view class="left">
<view class="title">篮球少儿课</view>
<view class="date">上课时间2020.05.30 15:30 - 17:30</view>
<view class="title">{{v.name}}</view>
<view class="date">上课时间{{v.create_time}}</view>
</view>
<view class="right">
<view class="btn" style="background-color: #29d3b4;">1课时</view>
</view>
</view>
<view class="li">
<view class="left">
<view class="title">篮球少儿课</view>
<view class="date">上课时间2020.05.30 15:30 - 17:30</view>
</view>
<view class="right">
<view class="btn" style="background-color: #29d3b4;">1课时</view>
</view>
</view>
<view class="li">
<view class="left">
<view class="title">篮球少儿课</view>
<view class="date">上课时间2020.05.30 15:30 - 17:30</view>
</view>
<view class="right">
<view class="btn" style="background-color: #29d3b4;">1课时</view>
</view>
</view>
<view class="li">
<view class="left">
<view class="title">篮球少儿课</view>
<view class="date">上课时间2020.05.30 15:30 - 17:30</view>
</view>
<view class="right">
<view class="btn" style="background-color: #29d3b4;">1课时</view>
</view>
</view>
<view class="li">
<view class="left">
<view class="title">篮球少儿课</view>
<view class="date">上课时间2020.05.30 15:30 - 17:30</view>
</view>
<view class="right">
<view class="btn" style="background-color: #29d3b4;">1课时</view>
</view>
</view>
<view class="li">
<view class="left">
<view class="title">篮球少儿课</view>
<view class="date">上课时间2020.05.30 15:30 - 17:30</view>
</view>
<view class="right">
<view class="btn" style="background-color: #29d3b4;">1课时</view>
</view>
</view>
<view class="li">
<view class="left">
<view class="title">篮球少儿课</view>
<view class="date">上课时间2020.05.30 15:30 - 17:30</view>
</view>
<view class="right">
<view class="btn" style="background-color: #29d3b4;">1课时</view>
</view>
</view>
<view class="li">
<view class="left">
<view class="title">篮球少儿课</view>
<view class="date">上课时间2020.05.30 15:30 - 17:30</view>
</view>
<view class="right">
<view class="btn" style="background-color: #29d3b4;">1课时</view>
</view>
</view>
<view class="li">
<view class="left">
<view class="title">篮球少儿课</view>
<view class="date">上课时间2020.05.30 15:30 - 17:30</view>
</view>
<view class="right">
<view class="btn" style="background-color: #29d3b4;">1课时</view>
</view>
</view>
<view class="li">
<view class="left">
<view class="title">篮球少儿课</view>
<view class="date">上课时间2020.05.30 15:30 - 17:30</view>
</view>
<view class="right">
<view class="btn" style="background-color: #29d3b4;">1课时</view>
<view
v-if="v.status == 1"
class="btn"
style="background-color: #29d3b4;"
>
{{v.hour}}课时
</view>
<view
v-if="v.status == 2"
class="btn"
style="background-color: #FAD04D;"
>
请假
</view>
</view>
</view>
</view>
@ -97,15 +31,99 @@
</template>
<script>
import memberApi from '@/api/member.js';
export default {
data() {
return {
loading:false,//
lowerThreshold: 100,//
isReachedBottom: false,//|true=|false=
//
filteredData:{
page:1,//
limit:10,//
total:10,//
},
tableList:[],//
}
},
onLoad(options) {
},
onShow(){
this.init()//
},
//
async onPullDownRefresh() {
//
await this.resetFilteredData()
await this.getList()
},
methods: {
//
async init(){
await this.getList()//
},
//()
loadMoreData() {
//
if (!this.isReachedBottom) {
this.isReachedBottom = true;//
this.getList();
}
},
//
async resetFilteredData() {
this.isReachedBottom = false; // 便
this.filteredData.page = 1//
this.filteredData.limit = 10//
this.filteredData.total = 10//
},
//
async getList(){
this.loading = true
let data = {...this.filteredData}
//
if(this.filteredData.page * this.filteredData.limit > this.filteredData.total){
this.loading = false
uni.showToast({
title: '暂无更多',
icon: 'none'
})
return
}
if(data.page == 1){
this.tableList = []
}
let res = await memberApi.studentsSignList(data)
this.loading = false
this.isReachedBottom = false;
if (res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.tableList = this.tableList.concat(res.data.data); // 使 concat
console.log('列表',this.tableList)
this.filteredData.total = res.data.total
this.filteredData.page++
},
}
}
}
</script>

49
pages/student/my/my.vue

@ -51,12 +51,12 @@
<view>课时消耗</view>
</view>
<view class="item" @click="my_members">
<view>我的成员</view>
<view></view>
</view>
<!-- <view class="item" @click="my_members">-->
<!-- <view>我的成员</view>-->
<!-- <view></view>-->
<!-- </view>-->
<view class="item">
<view class="item" @click="openViewContractList()">
<view>我的合同</view>
<view></view>
</view>
@ -67,14 +67,18 @@
<view>我的教练</view>
<view></view>
</view>
<view class="item">
<view>负责人</view>
<view></view>
</view>
<!-- <view class="item">-->
<!-- <view>负责人</view>-->
<!-- <view></view>-->
<!-- </view>-->
<view class="item" @click="feedback">
<view>意见反馈</view>
<view></view>
</view>
<view class="item" @click="openViewMyMessage({user_id:1})">
<view>我的消息</view>
<view></view>
</view>
</view>
</view>
@ -138,7 +142,21 @@
uni.navigateTo({
url: '/pages/student/my/personal_data'
})
}
},
//-
openViewContractList(item) {
uni.navigateTo({
url: `/pages/common/contract_list`
})
},
//-
openViewMyMessage(item) {
uni.navigateTo({
url: `/pages/common/my_message`
})
},
}
}
</script>
@ -158,8 +176,15 @@
background: #29D3B4;
.title {
padding: 110rpx 0 20rpx;
font-size: 30rpx;
padding: 40rpx 20rpx;
/* 小程序端样式 */
// #ifdef MP-WEIXIN
padding: 80rpx 0 20rpx;
// #endif
font-size: 30rpx;
color: #fff;
}
}

275
pages/student/timetable/index.vue

@ -10,13 +10,16 @@
<view class="section_1">
<view class="ul">
<view class="li" v-for="(v,k) in dateList" :key="k" @click="selectDate(v.date)">
<text>{{v.name}}</text>
<text>{{v.week}}</text>
<text :class="[filteredData.schedule_date == v.date ? 'today':'']">{{today == v.date ? '今':v.today}}</text>
<text :class="[today == v.date ?'select_plan':'']"></text>
<text :class="[v.status == 2 ?'select_plan':'']"></text>
</view>
</view>
<view class="btn" @click="show_calendar=true">
查看更多 <fui-icon name="arrowdown" color="#A4ADB3" size="45"></fui-icon>
</view>
</view>
<view class="section_2">
@ -37,18 +40,17 @@
style="height: 100vh;"
>
<view class="ul">
<view v-for="(v,k) in tableList" :key="k" class="li" @click="openViewCourseInfo({id:v.id})">
<view v-for="(v,k) in tableList" :key="k" class="li" @click="openViewCourseInfo(v)">
<view class="top_box">
<view class="center_box">
<view>班级{{v.name}}</view>
<view>时间{{v.start_date}} - {{$util.formatToDateTime(v.end_date,'H:i')}}</view>
<view>课室{{v.address}}
</view>
<view>课程{{v.courses_name}}
</view>
<view>班级{{v.classes_name}}</view>
<view>时间{{v.date}}</view>
<view>课室{{v.address}}</view>
<view>课程{{v.courses_name}}</view>
</view>
<view class="right_box">
<view class="tag" :style="{background: v.status === 1 ? '#1cd188' : v.status === 2 ? '#fad24e' : '#ff4d4f'}">
<!-- v.status|1=未开始,2=进行中,3=已结束-->
<view class="tag" :style="{background: v.status == 1 ? '#1cd188' : v.status == 2 ? '#fad24e' : '#ff4d4f'}">
{{ v.status === 1 ? '未开始' : v.status === 2 ? '上课中' : '已结束' }}
</view>
<!-- <view class="tag" style="background:#1cd188;">待上课</view>-->
@ -56,15 +58,15 @@
</view>
<view class="bottom_box">
<view class="hint">
已签到学生 ({{v.has_sign_count }}/{{v.max_students }})
已签到学生 ({{v.sign_list.length }}/{{v.max_students.split(',').length }})
</view>
<view class="list_box">
<view class="list">
<view class="itme" v-for="index in parseInt(v.has_sign_count) || 0" :key="index">
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png"></image>
<view class="itme" v-for="(item,index) in v.sign_list || 0" :key="index">
<image :src="$util.img(item.header)"></image>
</view>
</view>
<view class="btn" @click="openViewTimetableInfo(v)">
<view class="btn">
详情
</view>
</view>
@ -77,6 +79,20 @@
</view>
<!-- 日历选择-->
<fui-bottom-popup :show="show_calendar" @close="show_calendar=false">
<view class="fui-custom__wrap">
<uni-calendar
:insert="true"
:lunar="false"
:selected="calendarSelected"
:startDate="startDate"
:endDate="endDate"
@change="changeCalendar"
/>
</view>
</fui-bottom-popup>
<!-- 底部导航-->
<AQTabber/>
</view>
@ -84,6 +100,7 @@
<script>
import memberApi from '@/api/member.js';
import commonApi from '@/api/common.js';
import AQTabber from "@/components/AQ/AQTabber.vue"
@ -93,28 +110,37 @@ export default {
},
data() {
return {
loading:false,//
loading: false,//
lowerThreshold: 100,//
isReachedBottom: false,//|true=|false=
//
filteredData:{
page:1,//
limit:10,//
total:10,//
schedule_date:'',//
venue_id:'',//id
filteredData: {
page: 1,//
limit: 10,//
total: 10,//
schedule_date: '',//
venue_id: '',//id
},
tableList:[],//
tableList: [],//
venuesInfo:{},//
venuesInfo: {},//
//
today: '',
dateList:[]//
dateList: [],//
//
show_calendar:false,//
startDate:'',//
endDate:'',//
calendarSelected: [],//
}
},
onLoad() {
onLoad(options) {
if (options.venue_id) {
this.filteredData.venue_id = options.venue_id
}
},
onShow() {
this.init()//
@ -123,7 +149,6 @@ export default {
async onPullDownRefresh() {
//
let schedule_date = this.filteredData.schedule_date
console.log('eee',schedule_date)
await this.loadData()
this.filteredData.schedule_date = schedule_date
await this.getList()
@ -131,15 +156,46 @@ export default {
methods: {
//
async init(){
await this.getDate()
async init() {
await this.getThisDate()
await this.getHeadDate()
await this.getList()
await this.getDateList(); //
console.log(1111,this.dateList)
this.getDateRange()
this.setCalendarSelected()
},
//
async getHeadDate() {
let res = await commonApi.getDate()
if (res.code != 1) {
//
uni.showToast({
title: res.msg,
icon: 'none',
})
return
}
this.dateList = []
res.data.forEach((v, k) => {
let today = v.date.split("-")[2]; // "09"
this.dateList.push({
date: v.date,
status: v.status,//1 2
week: v.week,
today: today,
})
})
console.log('xxx', res)
},
//
async getDate() {
async getThisDate() {
let date = new Date();
let year = date.getFullYear();
let month = String(date.getMonth() + 1).padStart(2, '0'); //
@ -152,39 +208,6 @@ export default {
this.today = res;
this.filteredData.schedule_date = res;
},
//
async getDateList() {
const days = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
const dateList = [];
const today = new Date(); //
// 24
for (let i = -2; i <= 4; i++) {
const date = new Date(today);
date.setDate(today.getDate() + i); //
let dayOfWeek = days[date.getDay()]; //
let formattedDateArr = this.formatDate(date); //
let formattedDate = `${formattedDateArr[0]}-${formattedDateArr[1]}-${formattedDateArr[2]}`; //
dateList.push({
name: dayOfWeek,
date: formattedDate,
today: formattedDateArr[2],//
});
}
this.dateList = dateList
},
// YYYY-MM-DD
formatDate(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return [
year, month, day
]
},
//()
loadMoreData() {
@ -197,22 +220,19 @@ export default {
//
async loadData() {
this.isReachedBottom = false; // 便
this.filteredData = {
page:1,//
limit:10,//
total:10,//
schedule_date:'',//
venue_id:'',//id
}
this.filteredData.page = 1//
this.filteredData.limit = 10//
this.filteredData.total = 10//
},
//
async getList(){
async getList() {
this.loading = true
let data = {...this.filteredData}
//
if(this.filteredData.page * this.filteredData.limit > this.filteredData.total || this.filteredData.limit > this.filteredData.total ){
if (this.filteredData.page * this.filteredData.limit > this.filteredData.total || this.filteredData.limit > this.filteredData.total) {
this.loading = false
uni.showToast({
title: '暂无更多',
@ -224,7 +244,7 @@ export default {
let res = await memberApi.courseList(data)
this.loading = false
this.isReachedBottom = false;
if (res.code != 1){
if (res.code != 1) {
uni.showToast({
title: res.msg,
icon: 'none'
@ -236,31 +256,103 @@ export default {
//
this.venuesInfo = res.data.venues_info
this.total = res.data.list.total
this.page++
this.filteredData.total = res.data.list.total
this.filteredData.page++
},
//
async selectDate(date){
async selectDate(date) {
this.loadData()
this.filteredData.schedule_date = date
this.getList()
},
//
//
getDateRange() {
const today = new Date(); //
const startDate = new Date(today); //
const endDate = new Date(today); //
// startDate 1
startDate.setMonth(today.getMonth() - 1);
// endDate 1
endDate.setMonth(today.getMonth() + 2);
// YYYY-MM-DD
const formatDate = (date) => {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
};
// data startDate endDate
this.startDate = formatDate(startDate);
this.endDate = formatDate(endDate);
console.log([this.startDate,this.endDate])
},
//
async setCalendarSelected(){
//
let month = new Date().getMonth() + 1;
let res = await commonApi.getMonthDate({month:month})
if (res.code != 1){
//
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
})
return
}
this.calendarSelected = []
res.data.forEach((v,k)=>{
this.calendarSelected.push({
date: v.date,
})
})
// this.calendarSelected = [
// {
// date: '2025-04-07',
// },
// {
// date: '2025-04-08',
// },
// {
// date: '2025-04-09',
// }
// ]
},
//
changeCalendar(e){
console.log('日历',e)
this.show_calendar = false
console.log('日历',e)
this.show_calendar = false
this.loadData()
this.filteredData.schedule_date = e.fulldate
this.getList()
},
//
openViewTimetableInfo(item){
openViewCourseInfo(item) {
uni.navigateTo({
url: `/pages/student/timetable/info?id=${item.id}`
})
},
//
more(){
uni.navigateTo({
url: '/pages/student/timetable/list'
})
}
//
more() {
let schedule_date = this.filteredData.schedule_date
let venue_id = this.venuesInfo.id//id
uni.navigateTo({
url: `/pages/student/timetable/list?schedule_date=${schedule_date}&venue_id=${venue_id}`
})
}
}
}
</script>
@ -278,7 +370,13 @@ export default {
align-items: center;
background: #292929;
.title{
padding: 110rpx 0 20rpx;
padding: 40rpx 0rpx;
/* 小程序端样式 */
// #ifdef MP-WEIXIN
padding: 80rpx 0rpx;
// #endif
font-size: 30rpx;
color: #fff;
}
@ -331,6 +429,13 @@ export default {
}
}
}
.btn{
margin-top: 20rpx;
display: flex;
justify-content: center;
align-items: center;
color: #A4ADB3;
}
}
.section_2{

194
pages/student/timetable/info.vue

@ -3,59 +3,78 @@
<view class="main_box">
<view class="main_section">
<view class="section_1">
<view class="title_box">青少儿篮球课</view>
<view class="title_box">{{infoData.courses_name}}</view>
<view class="ul">
<view class="li">
<view class="title">课程名称</view>
<view class="content">青少年篮球课</view>
<view class="content">{{infoData.courses_name}}</view>
</view>
<view class="li">
<view class="title">班级</view>
<view class="content">班级名称</view>
<view class="content">{{infoData.classes_name}}</view>
</view>
<view class="li">
<view class="title">上课时间</view>
<view class="content">2020.03.25 15:30-17:00</view>
<view class="content">{{infoData.date_time}} {{infoData.time_slot.replace(',', '-')}}</view>
</view>
<view class="li">
<view class="title">上课地址</view>
<view class="content">xxxx体育馆302室</view>
<view class="content">{{infoData.address}}</view>
</view>
<view class="li">
<view class="title">课程名称</view>
<view class="content">青少年篮球课</view>
</view>
<view class="li">
<view class="title">教练</view>
<view class="content">包子皮</view>
<view class="content">{{infoData.staff_name}}</view>
</view>
<view class="li">
<view class="title">教练号码</view>
<view class="content">18888888888</view>
<view class="content">{{infoData.staff_phone}}</view>
</view>
<view class="li">
<view class="title">扣除课时</view>
<view class="content">2个课时</view>
<view class="content">{{infoData.hour}}个课时</view>
</view>
<view class="state_box">
<!--1未上课 2已上课-->
<view class="state_box" v-if="infoData.status == 2">
<view>已上</view>
</view>
<view class="state_box_btn" v-if="infoData.status != 2">
<!--sign_status字段| 0未签到 1已签到 2请假-->
<view v-if="!['1','2'].includes(String(infoData.sign_status))" @click="askForLeave(1)">请假</view>
<view v-else @click="askForLeave(2)">取消请假</view>
</view>
</view>
</view>
</view>
<!-- 请假模态框-->
<fui-modal class="leave_section" :buttons="[{text: '取消',plain: true}, {text: '保存'}]" width="600" :show="leaveShow" @cancel="closeLeaveModal" @click="closeLeaveModal">
<text class="fui-title" style="font-size: 30rpx;padding: 15rpx">请假申请</text>
<view class="form_box" style="width: 100%;padding: 20rpx">
<view class="input_box" style="border: 1px solid #888888;font-size: 28rpx;">
<fui-input style="font-size: 28rpx;height: 60rpx;line-height: 60rpx;padding-left: 15rpx" :borderBottom="false" placeholder="请输入请假原因" v-model="leaveFormData.reason"></fui-input>
</view>
</view>
</fui-modal>
<!--取消请假-->
<fui-dialog :show="cancelLeaveShow" content="确定取消吗?" maskClosable @click="submitCancelLeave" @close="cancelLeaveShow=false"></fui-dialog>
</view>
</template>
<script>
// import user from '@/api/user.js';
import memberApi from '@/api/member.js';
import AQTabber from "@/components/AQ/AQTabber.vue"
@ -65,15 +84,30 @@ export default {
},
data() {
return {
formData:{},
infoData:{},//
//
filteredData: {
id: '',//id
},
leaveShow:false,//
//
leaveFormData:{
schedules_id: '',// id
courses_id: '',//id
reason: '',//
file_url: '',//
},
//
cancelLeaveShow:false,//
}
},
onLoad(options) {
this.filteredData.id = options.id//id
this.leaveFormData.courses_id = options.id//id
this.leaveFormData.schedules_id = options.id//id
},
onShow(){
this.init()
@ -81,7 +115,22 @@ export default {
methods: {
//
async init(){
await this.getInfo()
},
//
async getInfo(){
let res = await memberApi.courseInfo({
id: this.filteredData.id,
})
if(res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
this.infoData = res.data
},
@ -91,6 +140,88 @@ export default {
url: '/pages/coach/course/info'
})
},
/// type|1=,2=
askForLeave(type){
if(type == 1){
//
this.leaveShow = true
}else{
//
this.cancelLeaveShow = true
}
},
//
openLeaveModal(){
this.leaveShow = true
},
//
closeLeaveModal(e){
if(e.index == 0){
//
this.leaveFormData.reason = ''
}else{
//
if (!this.leaveFormData.reason){
uni.showToast({
title: '请输入请假原因',
icon: 'none'
})
return
}
this.submitLeave()//
}
this.leaveShow = false
},
//
async submitLeave(){
let data = {...this.leaveFormData}
let res = await memberApi.askForLeave(data)
if(res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
uni.showToast({
title: res.msg,
icon: 'success'
})
//1s
setTimeout(() => {
this.init()
}, 1000)
},
//
async submitCancelLeave(e){
if(e.index == 0){
//
return
}
//
this.leaveFormData.reason = ''//
let data = {...this.leaveFormData}
let res = await memberApi.delAskForLeave(data)
this.cancelLeaveShow = false
if(res.code != 1){
uni.showToast({
title: res.msg,
icon: 'none'
})
return
}
uni.showToast({
title: res.msg,
icon: 'success'
})
//1s
setTimeout(() => {
this.init()
}, 1000)
},
}
}
</script>
@ -108,7 +239,13 @@ export default {
align-items: center;
background: #292929;
.title{
padding: 20rpx 0;
padding: 40rpx 0rpx;
/* 小程序端样式 */
// #ifdef MP-WEIXIN
padding: 80rpx 0rpx;
// #endif
font-size: 30rpx;
color: #fff;
}
@ -126,7 +263,8 @@ export default {
.section_1{
border-radius: 22rpx;
padding: 20rpx 40rpx;
background: #333333 100%;
background: #fff;
color: #333333;
width: 100%;
.title_box{
padding: 10rpx;
@ -169,8 +307,30 @@ export default {
transform: rotate(-35deg); /* 旋转 */
}
}
.state_box_btn{
position: absolute;
bottom: 50rpx;
right: 10rpx;
view{
width: 160rpx;
height: 60rpx;
line-height: 60rpx;
background-color: #00BE8C;
border-radius: 8rpx;
color: #fff;
font-size: 28rpx;
text-align: center;
}
}
}
}
//
.leave_section {
}
}

230
pages/student/timetable/list.vue

@ -4,122 +4,18 @@
<scroll-view scroll-y="true" :lower-threshold="lowerThreshold"
@scrolltolower="loadMoreData" style="height: 100vh;">
<view class="main_section">
<view class="title">XXX体育馆</view>
<view class="con">南山区科苑路15号科兴科学园</view>
<view class="con">距您1km</view>
<view class="current-venue" v-if="true">
<view class="main_section" v-for="(v,k) in tableList" :key="k" @click="opebViewTimetable(v)">
<view class="title">{{v.name}}</view>
<view class="con">{{v.address}}</view>
<view class="con" v-if="v.distance === null ">无法获取定位</view>
<view class="con" v-else-if="v.distance">距您{{v.distance}}km</view>
<view class="current-venue" v-if="venue_id == v.id">
当前场馆
</view>
</view>
<view class="main_section">
<view class="title">XXX体育馆</view>
<view class="con">南山区科苑路15号科兴科学园</view>
<view class="con">距您1km</view>
<view class="current-venue" v-if="true">
当前场馆
</view>
</view>
<view class="main_section">
<view class="title">XXX体育馆</view>
<view class="con">南山区科苑路15号科兴科学园</view>
<view class="con">距您1km</view>
<view class="current-venue" v-if="true">
当前场馆
</view>
</view>
<view class="main_section">
<view class="title">XXX体育馆</view>
<view class="con">南山区科苑路15号科兴科学园</view>
<view class="con">距您1km</view>
<view class="current-venue" v-if="true">
当前场馆
</view>
</view>
<view class="main_section">
<view class="title">XXX体育馆</view>
<view class="con">南山区科苑路15号科兴科学园</view>
<view class="con">距您1km</view>
<view class="current-venue" v-if="true">
当前场馆
</view>
</view>
<view class="main_section">
<view class="title">XXX体育馆</view>
<view class="con">南山区科苑路15号科兴科学园</view>
<view class="con">距您1km</view>
<view class="current-venue" v-if="true">
当前场馆
</view>
</view>
<view class="main_section">
<view class="title">XXX体育馆</view>
<view class="con">南山区科苑路15号科兴科学园</view>
<view class="con">距您1km</view>
<view class="current-venue" v-if="true">
当前场馆
</view>
</view>
<view class="main_section">
<view class="title">XXX体育馆</view>
<view class="con">南山区科苑路15号科兴科学园</view>
<view class="con">距您1km</view>
<view class="current-venue" v-if="true">
当前场馆
</view>
</view>
</scroll-view>
<!-- 加载状态-->
<fui-loading :isFixed="true" srcCol="/static/icon-img/loading_white.png" text="正在加载..." v-if="loading"></fui-loading>
<!-- <view class="main_section">-->
<!-- <view class="title">XXX体育馆</view>-->
<!-- <view class="con">南山区科苑路15号科兴科学园</view>-->
<!-- <view class="con">距您1km</view>-->
<!-- </view>-->
<!-- <view class="main_section">-->
<!-- <view class="title">XXX体育馆</view>-->
<!-- <view class="con">南山区科苑路15号科兴科学园</view>-->
<!-- <view class="con">距您1km</view>-->
<!-- </view>-->
<!-- <view class="main_section">-->
<!-- <view class="title">XXX体育馆</view>-->
<!-- <view class="con">南山区科苑路15号科兴科学园</view>-->
<!-- <view class="con">距您1km</view>-->
<!-- </view>-->
<!-- <view class="main_section">-->
<!-- <view class="title">XXX体育馆</view>-->
<!-- <view class="con">南山区科苑路15号科兴科学园</view>-->
<!-- <view class="con">距您1km</view>-->
<!-- </view>-->
<!-- <view class="main_section">-->
<!-- <view class="title">XXX体育馆</view>-->
<!-- <view class="con">南山区科苑路15号科兴科学园</view> -->
<!-- <view class="con">距您1km</view>-->
<!-- </view>-->
<!-- <view class="main_section">-->
<!-- <view class="title">XXX体育馆</view>-->
<!-- <view class="con">南山区科苑路15号科兴科学园</view>-->
<!-- <view class="con">距您1km</view>-->
<!-- </view>-->
<!-- <view class="main_section">-->
<!-- <view class="title">XXX体育馆</view>-->
<!-- <view class="con">南山区科苑路15号科兴科学园</view>-->
<!-- <view class="con">距您1km</view>-->
<!-- </view>-->
<!-- <view class="main_section">-->
<!-- <view class="title">XXX体育馆</view>-->
<!-- <view class="con">南山区科苑路15号科兴科学园</view>-->
<!-- <view class="con">距您1km</view>-->
<!-- </view>-->
<!-- <view class="main_section">-->
<!-- <view class="title">XXX体育馆</view>-->
<!-- <view class="con">南山区科苑路15号科兴科学园</view>-->
<!-- <view class="con">距您1km</view>-->
<!-- </view>-->
<!-- <fui-loading :isFixed="true" srcCol="/static/icon-img/loading_white.png" text="正在加载..." v-if="loading"></fui-loading>-->
</view>
</template>
@ -140,29 +36,92 @@
//
filteredData:{
page:1,//
limit:10,//
total:10,//
// page:1,//
// limit:10,//
// total:10,//
schedule_date:'',//
},
tableList:[],//
longitude:'',//
latitude:'',//
venue_id:'',//id
}
},
onLoad() {},
onLoad(options) {
this.filteredData.schedule_date = options.schedule_date//
//id
this.venue_id = options.venue_id || ''
},
onShow() {
this.init()//
},
methods: {
//
async init() {
await this.getList()
await this.getUserLocation();
await this.getList();
},
//
async getUserLocation() {
try {
const location = await this.getLocation();
this.longitude = location.longitude;
this.latitude = location.latitude;
} catch (error) {
console.log(error);
uni.showToast({
title: '获取位置失败',
icon: 'none'
});
// throw error; // 便 init
}
},
// uni.getLocation Promise
getLocation() {
return new Promise((resolve, reject) => {
uni.getLocation({
type: 'wgs84',
success: (res) => {
console.log('当前位置的经度:' + res.longitude);
console.log('当前位置的纬度:' + res.latitude);
resolve(res);
},
fail: (err) => {
console.log(err);
reject(err);
}
});
});
},
//
getDistance(lat1, lng1, lat2, lng2) {
const R = 6371; //
const dLat = this.deg2rad(lat2 - lat1);
const dLon = this.deg2rad(lng2 - lng1);
const a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(this.deg2rad(lat1)) * Math.cos(this.deg2rad(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
const distance = R * c; //
return distance.toFixed(2); //
},
//
deg2rad(deg) {
return deg * (Math.PI / 180);
},
//()
//()
loadMoreData() {
return //
//
if (!this.isReachedBottom) {
this.isReachedBottom = true;//
@ -176,7 +135,7 @@
}, 1000);
},
//
//
async getList(){
this.loading = true
@ -192,7 +151,7 @@
return
}
let res = await memberApi.courseList(data)
let res = await memberApi.venuesList(data)
this.loading = false
this.isReachedBottom = false;
if (res.code != 1){
@ -203,11 +162,34 @@
return
}
this.tableList = res.data.data
this.tableList = res.data
this.tableList.forEach((v,k)=>{
if(this.longitude && this.latitude && v.longitude && v.latitude){
v.distance = this.getDistance(this.latitude, this.longitude, v.latitude, v.longitude)
}else{
v.distance = null
}
})
console.log('列表',this.tableList)
this.total = res.data.total
this.page++
},
//-
opebViewTimetable(item) {
let venue_id = item.id
uni.navigateTo({
url: `/pages/student/timetable/index?venue_id=${venue_id}`
})
},
}
}
</script>

BIN
static/images/common/fa_song.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 B

BIN
static/images/common/xi_tong_xiao_xi.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 729 B

BIN
static/images/common/yong_hu.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 625 B

BIN
static/images/index/zan_wu.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 872 B

BIN
static/images/tabbar/banji.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 543 B

BIN
static/images/tabbar/banjis.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 560 B

30
uni_modules/uni-calendar/changelog.md

@ -0,0 +1,30 @@
## 1.4.12(2024-09-21)
- 修复 calendar在选择日期范围后重新选择日期需要点两次的Bug
## 1.4.11(2024-01-10)
- 修复 回到今天时,月份显示不一致问题
## 1.4.10(2023-04-10)
- 修复 某些情况 monthSwitch 未触发的Bug
## 1.4.9(2023-02-02)
- 修复 某些情况切换月份错误的Bug
## 1.4.8(2023-01-30)
- 修复 某些情况切换月份错误的Bug [详情](https://ask.dcloud.net.cn/question/161964)
## 1.4.7(2022-09-16)
- 优化 支持使用 uni-scss 控制主题色
## 1.4.6(2022-09-08)
- 修复 表头年月切换,导致改变当前日期为选择月1号,且未触发change事件的Bug
## 1.4.5(2022-02-25)
- 修复 条件编译 nvue 不支持的 css 样式的Bug
## 1.4.4(2022-02-25)
- 修复 条件编译 nvue 不支持的 css 样式的Bug
## 1.4.3(2021-09-22)
- 修复 startDate、 endDate 属性失效的Bug
## 1.4.2(2021-08-24)
- 新增 支持国际化
## 1.4.1(2021-08-05)
- 修复 弹出层被 tabbar 遮盖的Bug
## 1.4.0(2021-07-30)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.3.16(2021-05-12)
- 新增 组件示例地址
## 1.3.15(2021-02-04)
- 调整为uni_modules目录规范

544
uni_modules/uni-calendar/components/uni-calendar/calendar.js

@ -0,0 +1,544 @@
/**
* @1900-2100区间内的公历农历互转
* @charset UTF-8
* @github https://github.com/jjonline/calendar.js
* @Author Jea杨(JJonline@JJonline.Cn)
* @Time 2014-7-21
* @Time 2016-8-13 Fixed 2033hexAttribution Annals
* @Time 2016-9-25 Fixed lunar LeapMonth Param Bug
* @Time 2017-7-24 Fixed use getTerm Func Param Error.use solar year,NOT lunar year
* @Version 1.0.3
* @公历转农历calendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0]
* @农历转公历calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0]
*/
/* eslint-disable */
var calendar = {
/**
* 农历1900-2100的润大小信息表
* @Array Of Property
* @return Hex
*/
lunarInfo: [0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, // 1900-1909
0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, // 1910-1919
0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, // 1920-1929
0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, // 1930-1939
0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, // 1940-1949
0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, // 1950-1959
0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, // 1960-1969
0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, // 1970-1979
0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, // 1980-1989
0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0, // 1990-1999
0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, // 2000-2009
0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, // 2010-2019
0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, // 2020-2029
0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, // 2030-2039
0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, // 2040-2049
/** Add By JJonline@JJonline.Cn**/
0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, // 2050-2059
0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, // 2060-2069
0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, // 2070-2079
0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, // 2080-2089
0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, // 2090-2099
0x0d520], // 2100
/**
* 公历每个月份的天数普通表
* @Array Of Property
* @return Number
*/
solarMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
/**
* 天干地支之天干速查表
* @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"]
* @return Cn string
*/
Gan: ['\u7532', '\u4e59', '\u4e19', '\u4e01', '\u620a', '\u5df1', '\u5e9a', '\u8f9b', '\u58ec', '\u7678'],
/**
* 天干地支之地支速查表
* @Array Of Property
* @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"]
* @return Cn string
*/
Zhi: ['\u5b50', '\u4e11', '\u5bc5', '\u536f', '\u8fb0', '\u5df3', '\u5348', '\u672a', '\u7533', '\u9149', '\u620c', '\u4ea5'],
/**
* 天干地支之地支速查表<=>生肖
* @Array Of Property
* @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"]
* @return Cn string
*/
Animals: ['\u9f20', '\u725b', '\u864e', '\u5154', '\u9f99', '\u86c7', '\u9a6c', '\u7f8a', '\u7334', '\u9e21', '\u72d7', '\u732a'],
/**
* 24节气速查表
* @Array Of Property
* @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"]
* @return Cn string
*/
solarTerm: ['\u5c0f\u5bd2', '\u5927\u5bd2', '\u7acb\u6625', '\u96e8\u6c34', '\u60ca\u86f0', '\u6625\u5206', '\u6e05\u660e', '\u8c37\u96e8', '\u7acb\u590f', '\u5c0f\u6ee1', '\u8292\u79cd', '\u590f\u81f3', '\u5c0f\u6691', '\u5927\u6691', '\u7acb\u79cb', '\u5904\u6691', '\u767d\u9732', '\u79cb\u5206', '\u5bd2\u9732', '\u971c\u964d', '\u7acb\u51ac', '\u5c0f\u96ea', '\u5927\u96ea', '\u51ac\u81f3'],
/**
* 1900-2100各年的24节气日期速查表
* @Array Of Property
* @return 0x string For splice
*/
sTermInfo: ['9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f',
'97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
'97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f',
'b027097bd097c36b0b6fc9274c91aa', '9778397bd19801ec9210c965cc920e', '97b6b97bd19801ec95f8c965cc920f',
'97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd197c36c9210c9274c91aa',
'97b6b97bd19801ec95f8c965cc920e', '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2',
'9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec95f8c965cc920e', '97bcf97c3598082c95f8e1cfcc920f',
'97bd097bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e',
'97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722',
'9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f',
'97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
'97bcf97c359801ec95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd097bd07f595b0b6fc920fb0722',
'9778397bd097c36b0b6fc9210c8dc2', '9778397bd19801ec9210c9274c920e', '97b6b97bd19801ec95f8c965cc920f',
'97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e',
'97b6b97bd19801ec95f8c965cc920f', '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2',
'9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bd07f1487f595b0b0bc920fb0722',
'7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
'97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
'9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f531b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
'97bcf7f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
'9778397bd097c36b0b6fc9210c91aa', '97b6b97bd197c36c9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e',
'97b6b7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2',
'9778397bd097c36b0b70c9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
'9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b7f0e47f531b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
'9778397bd097c36b0b6fc9210c91aa', '97b6b7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '977837f0e37f149b0723b0787b0721',
'7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c35b0b6fc9210c8dc2',
'977837f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc9210c8dc2', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '977837f0e37f14998082b0787b06bd',
'7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
'977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd',
'7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
'977837f0e37f14998082b0723b06bd', '7f07e7f0e37f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721',
'7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f595b0b0bb0b6fb0722', '7f0e37f0e37f14898082b0723b02d5',
'7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f531b0b0bb0b6fb0722',
'7f0e37f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
'7f0e37f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd',
'7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35',
'7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
'7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f149b0723b0787b0721',
'7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0723b06bd',
'7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e37f0e366aa89801eb072297c35',
'7ec967f0e37f14998082b0723b06bd', '7f07e7f0e37f14998083b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
'7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14898082b0723b02d5', '7f07e7f0e37f14998082b0787b0721',
'7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66aa89801e9808297c35', '665f67f0e37f14898082b0723b02d5',
'7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66a449801e9808297c35',
'665f67f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
'7f0e36665b66a449801e9808297c35', '665f67f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd',
'7f07e7f0e47f531b0723b0b6fb0721', '7f0e26665b66a449801e9808297c35', '665f67f0e37f1489801eb072297c35',
'7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722'],
/**
* 数字转中文速查表
* @Array Of Property
* @trans ['日','一','二','三','四','五','六','七','八','九','十']
* @return Cn string
*/
nStr1: ['\u65e5', '\u4e00', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341'],
/**
* 日期转农历称呼速查表
* @Array Of Property
* @trans ['初','十','廿','卅']
* @return Cn string
*/
nStr2: ['\u521d', '\u5341', '\u5eff', '\u5345'],
/**
* 月份转农历称呼速查表
* @Array Of Property
* @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊']
* @return Cn string
*/
nStr3: ['\u6b63', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341', '\u51ac', '\u814a'],
/**
* 返回农历y年一整年的总天数
* @param lunar Year
* @return Number
* @eg:var count = calendar.lYearDays(1987) ;//count=387
*/
lYearDays: function (y) {
var i; var sum = 348
for (i = 0x8000; i > 0x8; i >>= 1) { sum += (this.lunarInfo[y - 1900] & i) ? 1 : 0 }
return (sum + this.leapDays(y))
},
/**
* 返回农历y年闰月是哪个月若y年没有闰月 则返回0
* @param lunar Year
* @return Number (0-12)
* @eg:var leapMonth = calendar.leapMonth(1987) ;//leapMonth=6
*/
leapMonth: function (y) { // 闰字编码 \u95f0
return (this.lunarInfo[y - 1900] & 0xf)
},
/**
* 返回农历y年闰月的天数 若该年没有闰月则返回0
* @param lunar Year
* @return Number (02930)
* @eg:var leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29
*/
leapDays: function (y) {
if (this.leapMonth(y)) {
return ((this.lunarInfo[y - 1900] & 0x10000) ? 30 : 29)
}
return (0)
},
/**
* 返回农历y年m月非闰月的总天数计算m为闰月时的天数请使用leapDays方法
* @param lunar Year
* @return Number (-12930)
* @eg:var MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29
*/
monthDays: function (y, m) {
if (m > 12 || m < 1) { return -1 }// 月份参数从1至12,参数错误返回-1
return ((this.lunarInfo[y - 1900] & (0x10000 >> m)) ? 30 : 29)
},
/**
* 返回公历(!)y年m月的天数
* @param solar Year
* @return Number (-128293031)
* @eg:var solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30
*/
solarDays: function (y, m) {
if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1
var ms = m - 1
if (ms == 1) { // 2月份的闰平规律测算后确认返回28或29
return (((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0)) ? 29 : 28)
} else {
return (this.solarMonth[ms])
}
},
/**
* 农历年份转换为干支纪年
* @param lYear 农历年的年份数
* @return Cn string
*/
toGanZhiYear: function (lYear) {
var ganKey = (lYear - 3) % 10
var zhiKey = (lYear - 3) % 12
if (ganKey == 0) ganKey = 10// 如果余数为0则为最后一个天干
if (zhiKey == 0) zhiKey = 12// 如果余数为0则为最后一个地支
return this.Gan[ganKey - 1] + this.Zhi[zhiKey - 1]
},
/**
* 公历月日判断所属星座
* @param cMonth [description]
* @param cDay [description]
* @return Cn string
*/
toAstro: function (cMonth, cDay) {
var s = '\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf'
var arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22]
return s.substr(cMonth * 2 - (cDay < arr[cMonth - 1] ? 2 : 0), 2) + '\u5ea7'// 座
},
/**
* 传入offset偏移量返回干支
* @param offset 相对甲子的偏移量
* @return Cn string
*/
toGanZhi: function (offset) {
return this.Gan[offset % 10] + this.Zhi[offset % 12]
},
/**
* 传入公历(!)y年获得该年第n个节气的公历日期
* @param y公历年(1900-2100)n二十四节气中的第几个节气(1~24)从n=1(小寒)算起
* @return day Number
* @eg:var _24 = calendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春
*/
getTerm: function (y, n) {
if (y < 1900 || y > 2100) { return -1 }
if (n < 1 || n > 24) { return -1 }
var _table = this.sTermInfo[y - 1900]
var _info = [
parseInt('0x' + _table.substr(0, 5)).toString(),
parseInt('0x' + _table.substr(5, 5)).toString(),
parseInt('0x' + _table.substr(10, 5)).toString(),
parseInt('0x' + _table.substr(15, 5)).toString(),
parseInt('0x' + _table.substr(20, 5)).toString(),
parseInt('0x' + _table.substr(25, 5)).toString()
]
var _calday = [
_info[0].substr(0, 1),
_info[0].substr(1, 2),
_info[0].substr(3, 1),
_info[0].substr(4, 2),
_info[1].substr(0, 1),
_info[1].substr(1, 2),
_info[1].substr(3, 1),
_info[1].substr(4, 2),
_info[2].substr(0, 1),
_info[2].substr(1, 2),
_info[2].substr(3, 1),
_info[2].substr(4, 2),
_info[3].substr(0, 1),
_info[3].substr(1, 2),
_info[3].substr(3, 1),
_info[3].substr(4, 2),
_info[4].substr(0, 1),
_info[4].substr(1, 2),
_info[4].substr(3, 1),
_info[4].substr(4, 2),
_info[5].substr(0, 1),
_info[5].substr(1, 2),
_info[5].substr(3, 1),
_info[5].substr(4, 2)
]
return parseInt(_calday[n - 1])
},
/**
* 传入农历数字月份返回汉语通俗表示法
* @param lunar month
* @return Cn string
* @eg:var cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月'
*/
toChinaMonth: function (m) { // 月 => \u6708
if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1
var s = this.nStr3[m - 1]
s += '\u6708'// 加上月字
return s
},
/**
* 传入农历日期数字返回汉字表示法
* @param lunar day
* @return Cn string
* @eg:var cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一'
*/
toChinaDay: function (d) { // 日 => \u65e5
var s
switch (d) {
case 10:
s = '\u521d\u5341'; break
case 20:
s = '\u4e8c\u5341'; break
case 30:
s = '\u4e09\u5341'; break
default :
s = this.nStr2[Math.floor(d / 10)]
s += this.nStr1[d % 10]
}
return (s)
},
/**
* 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是立春
* @param y year
* @return Cn string
* @eg:var animal = calendar.getAnimal(1987) ;//animal='兔'
*/
getAnimal: function (y) {
return this.Animals[(y - 4) % 12]
},
/**
* 传入阳历年月日获得详细的公历农历object信息 <=>JSON
* @param y solar year
* @param m solar month
* @param d solar day
* @return JSON object
* @eg:console.log(calendar.solar2lunar(1987,11,01));
*/
solar2lunar: function (y, m, d) { // 参数区间1900.1.31~2100.12.31
// 年份限定、上限
if (y < 1900 || y > 2100) {
return -1// undefined转换为数字变为NaN
}
// 公历传参最下限
if (y == 1900 && m == 1 && d < 31) {
return -1
}
// 未传参 获得当天
if (!y) {
var objDate = new Date()
} else {
var objDate = new Date(y, parseInt(m) - 1, d)
}
var i; var leap = 0; var temp = 0
// 修正ymd参数
var y = objDate.getFullYear()
var m = objDate.getMonth() + 1
var d = objDate.getDate()
var offset = (Date.UTC(objDate.getFullYear(), objDate.getMonth(), objDate.getDate()) - Date.UTC(1900, 0, 31)) / 86400000
for (i = 1900; i < 2101 && offset > 0; i++) {
temp = this.lYearDays(i)
offset -= temp
}
if (offset < 0) {
offset += temp; i--
}
// 是否今天
var isTodayObj = new Date()
var isToday = false
if (isTodayObj.getFullYear() == y && isTodayObj.getMonth() + 1 == m && isTodayObj.getDate() == d) {
isToday = true
}
// 星期几
var nWeek = objDate.getDay()
var cWeek = this.nStr1[nWeek]
// 数字表示周几顺应天朝周一开始的惯例
if (nWeek == 0) {
nWeek = 7
}
// 农历年
var year = i
var leap = this.leapMonth(i) // 闰哪个月
var isLeap = false
// 效验闰月
for (i = 1; i < 13 && offset > 0; i++) {
// 闰月
if (leap > 0 && i == (leap + 1) && isLeap == false) {
--i
isLeap = true; temp = this.leapDays(year) // 计算农历闰月天数
} else {
temp = this.monthDays(year, i)// 计算农历普通月天数
}
// 解除闰月
if (isLeap == true && i == (leap + 1)) { isLeap = false }
offset -= temp
}
// 闰月导致数组下标重叠取反
if (offset == 0 && leap > 0 && i == leap + 1) {
if (isLeap) {
isLeap = false
} else {
isLeap = true; --i
}
}
if (offset < 0) {
offset += temp; --i
}
// 农历月
var month = i
// 农历日
var day = offset + 1
// 天干地支处理
var sm = m - 1
var gzY = this.toGanZhiYear(year)
// 当月的两个节气
// bugfix-2017-7-24 11:03:38 use lunar Year Param `y` Not `year`
var firstNode = this.getTerm(y, (m * 2 - 1))// 返回当月「节」为几日开始
var secondNode = this.getTerm(y, (m * 2))// 返回当月「节」为几日开始
// 依据12节气修正干支月
var gzM = this.toGanZhi((y - 1900) * 12 + m + 11)
if (d >= firstNode) {
gzM = this.toGanZhi((y - 1900) * 12 + m + 12)
}
// 传入的日期的节气与否
var isTerm = false
var Term = null
if (firstNode == d) {
isTerm = true
Term = this.solarTerm[m * 2 - 2]
}
if (secondNode == d) {
isTerm = true
Term = this.solarTerm[m * 2 - 1]
}
// 日柱 当月一日与 1900/1/1 相差天数
var dayCyclical = Date.UTC(y, sm, 1, 0, 0, 0, 0) / 86400000 + 25567 + 10
var gzD = this.toGanZhi(dayCyclical + d - 1)
// 该日期所属的星座
var astro = this.toAstro(m, d)
return { 'lYear': year, 'lMonth': month, 'lDay': day, 'Animal': this.getAnimal(year), 'IMonthCn': (isLeap ? '\u95f0' : '') + this.toChinaMonth(month), 'IDayCn': this.toChinaDay(day), 'cYear': y, 'cMonth': m, 'cDay': d, 'gzYear': gzY, 'gzMonth': gzM, 'gzDay': gzD, 'isToday': isToday, 'isLeap': isLeap, 'nWeek': nWeek, 'ncWeek': '\u661f\u671f' + cWeek, 'isTerm': isTerm, 'Term': Term, 'astro': astro }
},
/**
* 传入农历年月日以及传入的月份是否闰月获得详细的公历农历object信息 <=>JSON
* @param y lunar year
* @param m lunar month
* @param d lunar day
* @param isLeapMonth lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可]
* @return JSON object
* @eg:console.log(calendar.lunar2solar(1987,9,10));
*/
lunar2solar: function (y, m, d, isLeapMonth) { // 参数区间1900.1.31~2100.12.1
var isLeapMonth = !!isLeapMonth
var leapOffset = 0
var leapMonth = this.leapMonth(y)
var leapDay = this.leapDays(y)
if (isLeapMonth && (leapMonth != m)) { return -1 }// 传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同
if (y == 2100 && m == 12 && d > 1 || y == 1900 && m == 1 && d < 31) { return -1 }// 超出了最大极限值
var day = this.monthDays(y, m)
var _day = day
// bugFix 2016-9-25
// if month is leap, _day use leapDays method
if (isLeapMonth) {
_day = this.leapDays(y, m)
}
if (y < 1900 || y > 2100 || d > _day) { return -1 }// 参数合法性效验
// 计算农历的时间差
var offset = 0
for (var i = 1900; i < y; i++) {
offset += this.lYearDays(i)
}
var leap = 0; var isAdd = false
for (var i = 1; i < m; i++) {
leap = this.leapMonth(y)
if (!isAdd) { // 处理闰月
if (leap <= i && leap > 0) {
offset += this.leapDays(y); isAdd = true
}
}
offset += this.monthDays(y, i)
}
// 转换闰月农历 需补充该年闰月的前一个月的时差
if (isLeapMonth) { offset += day }
// 1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点)
var stmap = Date.UTC(1900, 1, 30, 0, 0, 0)
var calObj = new Date((offset + d - 31) * 86400000 + stmap)
var cY = calObj.getUTCFullYear()
var cM = calObj.getUTCMonth() + 1
var cD = calObj.getUTCDate()
return this.solar2lunar(cY, cM, cD)
}
}
export default calendar

12
uni_modules/uni-calendar/components/uni-calendar/i18n/en.json

@ -0,0 +1,12 @@
{
"uni-calender.ok": "ok",
"uni-calender.cancel": "cancel",
"uni-calender.today": "today",
"uni-calender.MON": "MON",
"uni-calender.TUE": "TUE",
"uni-calender.WED": "WED",
"uni-calender.THU": "THU",
"uni-calender.FRI": "FRI",
"uni-calender.SAT": "SAT",
"uni-calender.SUN": "SUN"
}

8
uni_modules/uni-calendar/components/uni-calendar/i18n/index.js

@ -0,0 +1,8 @@
import en from './en.json'
import zhHans from './zh-Hans.json'
import zhHant from './zh-Hant.json'
export default {
en,
'zh-Hans': zhHans,
'zh-Hant': zhHant
}

12
uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hans.json

@ -0,0 +1,12 @@
{
"uni-calender.ok": "确定",
"uni-calender.cancel": "取消",
"uni-calender.today": "今日",
"uni-calender.SUN": "日",
"uni-calender.MON": "一",
"uni-calender.TUE": "二",
"uni-calender.WED": "三",
"uni-calender.THU": "四",
"uni-calender.FRI": "五",
"uni-calender.SAT": "六"
}

12
uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hant.json

@ -0,0 +1,12 @@
{
"uni-calender.ok": "確定",
"uni-calender.cancel": "取消",
"uni-calender.today": "今日",
"uni-calender.SUN": "日",
"uni-calender.MON": "一",
"uni-calender.TUE": "二",
"uni-calender.WED": "三",
"uni-calender.THU": "四",
"uni-calender.FRI": "五",
"uni-calender.SAT": "六"
}

187
uni_modules/uni-calendar/components/uni-calendar/uni-calendar-item.vue

@ -0,0 +1,187 @@
<template>
<view class="uni-calendar-item__weeks-box" :class="{
'uni-calendar-item--disable':weeks.disable,
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
'uni-calendar-item--checked':(calendar.fullDate === weeks.fullDate && !weeks.isDay) ,
'uni-calendar-item--before-checked':weeks.beforeMultiple,
'uni-calendar-item--multiple': weeks.multiple,
'uni-calendar-item--after-checked':weeks.afterMultiple,
}"
@click="choiceDate(weeks)">
<view class="uni-calendar-item__weeks-box-item">
<text v-if="selected&&weeks.extraInfo" class="uni-calendar-item__weeks-box-circle"></text>
<text class="uni-calendar-item__weeks-box-text" :class="{
'uni-calendar-item--isDay-text': weeks.isDay,
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
'uni-calendar-item--before-checked':weeks.beforeMultiple,
'uni-calendar-item--multiple': weeks.multiple,
'uni-calendar-item--after-checked':weeks.afterMultiple,
'uni-calendar-item--disable':weeks.disable,
}">{{weeks.date}}</text>
<text v-if="!lunar&&!weeks.extraInfo && weeks.isDay" class="uni-calendar-item__weeks-lunar-text" :class="{
'uni-calendar-item--isDay-text':weeks.isDay,
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
'uni-calendar-item--before-checked':weeks.beforeMultiple,
'uni-calendar-item--multiple': weeks.multiple,
'uni-calendar-item--after-checked':weeks.afterMultiple,
}">{{todayText}}</text>
<text v-if="lunar&&!weeks.extraInfo" class="uni-calendar-item__weeks-lunar-text" :class="{
'uni-calendar-item--isDay-text':weeks.isDay,
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
'uni-calendar-item--before-checked':weeks.beforeMultiple,
'uni-calendar-item--multiple': weeks.multiple,
'uni-calendar-item--after-checked':weeks.afterMultiple,
'uni-calendar-item--disable':weeks.disable,
}">{{weeks.isDay ? todayText : (weeks.lunar.IDayCn === '初一'?weeks.lunar.IMonthCn:weeks.lunar.IDayCn)}}</text>
<text v-if="weeks.extraInfo&&weeks.extraInfo.info" class="uni-calendar-item__weeks-lunar-text" :class="{
'uni-calendar-item--extra':weeks.extraInfo.info,
'uni-calendar-item--isDay-text':weeks.isDay,
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
'uni-calendar-item--before-checked':weeks.beforeMultiple,
'uni-calendar-item--multiple': weeks.multiple,
'uni-calendar-item--after-checked':weeks.afterMultiple,
'uni-calendar-item--disable':weeks.disable,
}">{{weeks.extraInfo.info}}</text>
</view>
</view>
</template>
<script>
import { initVueI18n } from '@dcloudio/uni-i18n'
import i18nMessages from './i18n/index.js'
const { t } = initVueI18n(i18nMessages)
export default {
emits:['change'],
props: {
weeks: {
type: Object,
default () {
return {}
}
},
calendar: {
type: Object,
default: () => {
return {}
}
},
selected: {
type: Array,
default: () => {
return []
}
},
lunar: {
type: Boolean,
default: false
}
},
computed: {
todayText() {
return t("uni-calender.today")
},
},
methods: {
choiceDate(weeks) {
this.$emit('change', weeks)
}
}
}
</script>
<style lang="scss" scoped>
$uni-font-size-base:14px;
$uni-text-color:#333;
$uni-font-size-sm:12px;
$uni-color-error: #e43d33;
$uni-opacity-disabled: 0.3;
$uni-text-color-disable:#c0c0c0;
$uni-primary: #2979ff !default;
.uni-calendar-item__weeks-box {
flex: 1;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
align-items: center;
}
.uni-calendar-item__weeks-box-text {
font-size: $uni-font-size-base;
color: $uni-text-color;
}
.uni-calendar-item__weeks-lunar-text {
font-size: $uni-font-size-sm;
color: $uni-text-color;
}
.uni-calendar-item__weeks-box-item {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
align-items: center;
width: 100rpx;
height: 100rpx;
}
.uni-calendar-item__weeks-box-circle {
position: absolute;
top: 5px;
right: 5px;
width: 8px;
height: 8px;
border-radius: 8px;
background-color: $uni-color-error;
}
.uni-calendar-item--disable {
background-color: rgba(249, 249, 249, $uni-opacity-disabled);
color: $uni-text-color-disable;
}
.uni-calendar-item--isDay-text {
color: $uni-primary;
}
.uni-calendar-item--isDay {
background-color: $uni-primary;
opacity: 0.8;
color: #fff;
}
.uni-calendar-item--extra {
color: $uni-color-error;
opacity: 0.8;
}
.uni-calendar-item--checked {
background-color: $uni-primary;
color: #fff;
opacity: 0.8;
}
.uni-calendar-item--multiple {
background-color: $uni-primary;
color: #fff;
opacity: 0.8;
}
.uni-calendar-item--before-checked {
background-color: #ff5a5f;
color: #fff;
}
.uni-calendar-item--after-checked {
background-color: #ff5a5f;
color: #fff;
}
</style>

567
uni_modules/uni-calendar/components/uni-calendar/uni-calendar.vue

@ -0,0 +1,567 @@
<template>
<view class="uni-calendar">
<view v-if="!insert&&show" class="uni-calendar__mask" :class="{'uni-calendar--mask-show':aniMaskShow}" @click="clean"></view>
<view v-if="insert || show" class="uni-calendar__content" :class="{'uni-calendar--fixed':!insert,'uni-calendar--ani-show':aniMaskShow}">
<view v-if="!insert" class="uni-calendar__header uni-calendar--fixed-top">
<view class="uni-calendar__header-btn-box" @click="close">
<text class="uni-calendar__header-text uni-calendar--fixed-width">{{cancelText}}</text>
</view>
<view class="uni-calendar__header-btn-box" @click="confirm">
<text class="uni-calendar__header-text uni-calendar--fixed-width">{{okText}}</text>
</view>
</view>
<view class="uni-calendar__header">
<view class="uni-calendar__header-btn-box" @click.stop="pre">
<view class="uni-calendar__header-btn uni-calendar--left"></view>
</view>
<picker mode="date" :value="date" fields="month" @change="bindDateChange">
<text class="uni-calendar__header-text">{{ (nowDate.year||'') +' / '+( nowDate.month||'')}}</text>
</picker>
<view class="uni-calendar__header-btn-box" @click.stop="next">
<view class="uni-calendar__header-btn uni-calendar--right"></view>
</view>
<text class="uni-calendar__backtoday" @click="backToday">{{todayText}}</text>
</view>
<view class="uni-calendar__box">
<view v-if="showMonth" class="uni-calendar__box-bg">
<text class="uni-calendar__box-bg-text">{{nowDate.month}}</text>
</view>
<view class="uni-calendar__weeks">
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text">{{SUNText}}</text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text">{{monText}}</text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text">{{TUEText}}</text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text">{{WEDText}}</text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text">{{THUText}}</text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text">{{FRIText}}</text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text">{{SATText}}</text>
</view>
</view>
<view class="uni-calendar__weeks" v-for="(item,weekIndex) in weeks" :key="weekIndex">
<view class="uni-calendar__weeks-item" v-for="(weeks,weeksIndex) in item" :key="weeksIndex">
<calendar-item class="uni-calendar-item--hook" :weeks="weeks" :calendar="calendar" :selected="selected" :lunar="lunar" @change="choiceDate"></calendar-item>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import Calendar from './util.js';
import CalendarItem from './uni-calendar-item.vue'
import { initVueI18n } from '@dcloudio/uni-i18n'
import i18nMessages from './i18n/index.js'
const { t } = initVueI18n(i18nMessages)
/**
* Calendar 日历
* @description 日历组件可以查看日期选择任意范围内的日期打点操作常用场景如酒店日期预订火车机票选择购买日期上下班打卡等
* @tutorial https://ext.dcloud.net.cn/plugin?id=56
* @property {String} date 自定义当前时间默认为今天
* @property {Boolean} lunar 显示农历
* @property {String} startDate 日期选择范围-开始日期
* @property {String} endDate 日期选择范围-结束日期
* @property {Boolean} range 范围选择
* @property {Boolean} insert = [true|false] 插入模式,默认为false
* @value true 弹窗模式
* @value false 插入模式
* @property {Boolean} clearDate = [true|false] 弹窗模式是否清空上次选择内容
* @property {Array} selected 打点期待格式[{date: '2019-06-27', info: '签到', data: { custom: '自定义信息', name: '自定义消息头',xxx:xxx... }}]
* @property {Boolean} showMonth 是否选择月份为背景
* @event {Function} change 日期改变`insert :ture` 时生效
* @event {Function} confirm 确认选择`insert :false` 时生效
* @event {Function} monthSwitch 切换月份时触发
* @example <uni-calendar :insert="true":lunar="true" :start-date="'2019-3-2'":end-date="'2019-5-20'"@change="change" />
*/
export default {
components: {
CalendarItem
},
emits:['close','confirm','change','monthSwitch'],
props: {
date: {
type: String,
default: ''
},
selected: {
type: Array,
default () {
return []
}
},
lunar: {
type: Boolean,
default: false
},
startDate: {
type: String,
default: ''
},
endDate: {
type: String,
default: ''
},
range: {
type: Boolean,
default: false
},
insert: {
type: Boolean,
default: true
},
showMonth: {
type: Boolean,
default: true
},
clearDate: {
type: Boolean,
default: true
}
},
data() {
return {
show: false,
weeks: [],
calendar: {},
nowDate: '',
aniMaskShow: false
}
},
computed:{
/**
* for i18n
*/
okText() {
return t("uni-calender.ok")
},
cancelText() {
return t("uni-calender.cancel")
},
todayText() {
return t("uni-calender.today")
},
monText() {
return t("uni-calender.MON")
},
TUEText() {
return t("uni-calender.TUE")
},
WEDText() {
return t("uni-calender.WED")
},
THUText() {
return t("uni-calender.THU")
},
FRIText() {
return t("uni-calender.FRI")
},
SATText() {
return t("uni-calender.SAT")
},
SUNText() {
return t("uni-calender.SUN")
},
},
watch: {
date(newVal) {
// this.cale.setDate(newVal)
this.init(newVal)
},
startDate(val){
this.cale.resetSatrtDate(val)
this.cale.setDate(this.nowDate.fullDate)
this.weeks = this.cale.weeks
},
endDate(val){
this.cale.resetEndDate(val)
this.cale.setDate(this.nowDate.fullDate)
this.weeks = this.cale.weeks
},
selected(newVal) {
this.cale.setSelectInfo(this.nowDate.fullDate, newVal)
this.weeks = this.cale.weeks
}
},
created() {
this.cale = new Calendar({
selected: this.selected,
startDate: this.startDate,
endDate: this.endDate,
range: this.range,
})
this.init(this.date)
},
methods: {
// 穿
clean() {},
bindDateChange(e) {
const value = e.detail.value + '-1'
this.setDate(value)
const { year,month } = this.cale.getDate(value)
this.$emit('monthSwitch', {
year,
month
})
},
/**
* 初始化日期显示
* @param {Object} date
*/
init(date) {
this.cale.setDate(date)
this.weeks = this.cale.weeks
this.nowDate = this.calendar = this.cale.getInfo(date)
},
/**
* 打开日历弹窗
*/
open() {
//
if (this.clearDate && !this.insert) {
this.cale.cleanMultipleStatus()
// this.cale.setDate(this.date)
this.init(this.date)
}
this.show = true
this.$nextTick(() => {
setTimeout(() => {
this.aniMaskShow = true
}, 50)
})
},
/**
* 关闭日历弹窗
*/
close() {
this.aniMaskShow = false
this.$nextTick(() => {
setTimeout(() => {
this.show = false
this.$emit('close')
}, 300)
})
},
/**
* 确认按钮
*/
confirm() {
this.setEmit('confirm')
this.close()
},
/**
* 变化触发
*/
change() {
if (!this.insert) return
this.setEmit('change')
},
/**
* 选择月份触发
*/
monthSwitch() {
let {
year,
month
} = this.nowDate
this.$emit('monthSwitch', {
year,
month: Number(month)
})
},
/**
* 派发事件
* @param {Object} name
*/
setEmit(name) {
let {
year,
month,
date,
fullDate,
lunar,
extraInfo
} = this.calendar
this.$emit(name, {
range: this.cale.multipleStatus,
year,
month,
date,
fulldate: fullDate,
lunar,
extraInfo: extraInfo || {}
})
},
/**
* 选择天触发
* @param {Object} weeks
*/
choiceDate(weeks) {
if (weeks.disable) return
this.calendar = weeks
//
this.cale.setMultiple(this.calendar.fullDate)
this.weeks = this.cale.weeks
this.change()
},
/**
* 回到今天
*/
backToday() {
const nowYearMonth = `${this.nowDate.year}-${this.nowDate.month}`
const date = this.cale.getDate(new Date())
const todayYearMonth = `${date.year}-${date.month}`
this.init(date.fullDate)
if(nowYearMonth !== todayYearMonth) {
this.monthSwitch()
}
this.change()
},
/**
* 上个月
*/
pre() {
const preDate = this.cale.getDate(this.nowDate.fullDate, -1, 'month').fullDate
this.setDate(preDate)
this.monthSwitch()
},
/**
* 下个月
*/
next() {
const nextDate = this.cale.getDate(this.nowDate.fullDate, +1, 'month').fullDate
this.setDate(nextDate)
this.monthSwitch()
},
/**
* 设置日期
* @param {Object} date
*/
setDate(date) {
this.cale.setDate(date)
this.weeks = this.cale.weeks
this.nowDate = this.cale.getInfo(date)
}
}
}
</script>
<style lang="scss" scoped>
$uni-bg-color-mask: rgba($color: #000000, $alpha: 0.4);
$uni-border-color: #EDEDED;
$uni-text-color: #333;
$uni-bg-color-hover:#f1f1f1;
$uni-font-size-base:14px;
$uni-text-color-placeholder: #808080;
$uni-color-subtitle: #555555;
$uni-text-color-grey:#999;
.uni-calendar {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
}
.uni-calendar__mask {
position: fixed;
bottom: 0;
top: 0;
left: 0;
right: 0;
background-color: $uni-bg-color-mask;
transition-property: opacity;
transition-duration: 0.3s;
opacity: 0;
/* #ifndef APP-NVUE */
z-index: 99;
/* #endif */
}
.uni-calendar--mask-show {
opacity: 1
}
.uni-calendar--fixed {
position: fixed;
/* #ifdef APP-NVUE */
bottom: 0;
/* #endif */
left: 0;
right: 0;
transition-property: transform;
transition-duration: 0.3s;
transform: translateY(460px);
/* #ifndef APP-NVUE */
bottom: calc(var(--window-bottom));
z-index: 99;
/* #endif */
}
.uni-calendar--ani-show {
transform: translateY(0);
}
.uni-calendar__content {
background-color: #fff;
}
.uni-calendar__header {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: center;
align-items: center;
height: 50px;
border-bottom-color: $uni-border-color;
border-bottom-style: solid;
border-bottom-width: 1px;
}
.uni-calendar--fixed-top {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: space-between;
border-top-color: $uni-border-color;
border-top-style: solid;
border-top-width: 1px;
}
.uni-calendar--fixed-width {
width: 50px;
}
.uni-calendar__backtoday {
position: absolute;
right: 0;
top: 25rpx;
padding: 0 5px;
padding-left: 10px;
height: 25px;
line-height: 25px;
font-size: 12px;
border-top-left-radius: 25px;
border-bottom-left-radius: 25px;
color: $uni-text-color;
background-color: $uni-bg-color-hover;
}
.uni-calendar__header-text {
text-align: center;
width: 100px;
font-size: $uni-font-size-base;
color: $uni-text-color;
}
.uni-calendar__header-btn-box {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
justify-content: center;
width: 50px;
height: 50px;
}
.uni-calendar__header-btn {
width: 10px;
height: 10px;
border-left-color: $uni-text-color-placeholder;
border-left-style: solid;
border-left-width: 2px;
border-top-color: $uni-color-subtitle;
border-top-style: solid;
border-top-width: 2px;
}
.uni-calendar--left {
transform: rotate(-45deg);
}
.uni-calendar--right {
transform: rotate(135deg);
}
.uni-calendar__weeks {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
}
.uni-calendar__weeks-item {
flex: 1;
}
.uni-calendar__weeks-day {
flex: 1;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
align-items: center;
height: 45px;
border-bottom-color: #F5F5F5;
border-bottom-style: solid;
border-bottom-width: 1px;
}
.uni-calendar__weeks-day-text {
font-size: 14px;
}
.uni-calendar__box {
position: relative;
}
.uni-calendar__box-bg {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
justify-content: center;
align-items: center;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.uni-calendar__box-bg-text {
font-size: 200px;
font-weight: bold;
color: $uni-text-color-grey;
opacity: 0.1;
text-align: center;
/* #ifndef APP-NVUE */
line-height: 1;
/* #endif */
}
</style>

360
uni_modules/uni-calendar/components/uni-calendar/util.js

@ -0,0 +1,360 @@
import CALENDAR from './calendar.js'
class Calendar {
constructor({
date,
selected,
startDate,
endDate,
range
} = {}) {
// 当前日期
this.date = this.getDate(new Date()) // 当前初入日期
// 打点信息
this.selected = selected || [];
// 范围开始
this.startDate = startDate
// 范围结束
this.endDate = endDate
this.range = range
// 多选状态
this.cleanMultipleStatus()
// 每周日期
this.weeks = {}
// this._getWeek(this.date.fullDate)
}
/**
* 设置日期
* @param {Object} date
*/
setDate(date) {
this.selectDate = this.getDate(date)
this._getWeek(this.selectDate.fullDate)
}
/**
* 清理多选状态
*/
cleanMultipleStatus() {
this.multipleStatus = {
before: '',
after: '',
data: []
}
}
/**
* 重置开始日期
*/
resetSatrtDate(startDate) {
// 范围开始
this.startDate = startDate
}
/**
* 重置结束日期
*/
resetEndDate(endDate) {
// 范围结束
this.endDate = endDate
}
/**
* 获取任意时间
*/
getDate(date, AddDayCount = 0, str = 'day') {
if (!date) {
date = new Date()
}
if (typeof date !== 'object') {
date = date.replace(/-/g, '/')
}
const dd = new Date(date)
switch (str) {
case 'day':
dd.setDate(dd.getDate() + AddDayCount) // 获取AddDayCount天后的日期
break
case 'month':
if (dd.getDate() === 31 && AddDayCount>0) {
dd.setDate(dd.getDate() + AddDayCount)
} else {
const preMonth = dd.getMonth()
dd.setMonth(preMonth + AddDayCount) // 获取AddDayCount天后的日期
const nextMonth = dd.getMonth()
// 处理 pre 切换月份目标月份为2月没有当前日(30 31) 切换错误问题
if(AddDayCount<0 && preMonth!==0 && nextMonth-preMonth>AddDayCount){
dd.setMonth(nextMonth+(nextMonth-preMonth+AddDayCount))
}
// 处理 next 切换月份目标月份为2月没有当前日(30 31) 切换错误问题
if(AddDayCount>0 && nextMonth-preMonth>AddDayCount){
dd.setMonth(nextMonth-(nextMonth-preMonth-AddDayCount))
}
}
break
case 'year':
dd.setFullYear(dd.getFullYear() + AddDayCount) // 获取AddDayCount天后的日期
break
}
const y = dd.getFullYear()
const m = dd.getMonth() + 1 < 10 ? '0' + (dd.getMonth() + 1) : dd.getMonth() + 1 // 获取当前月份的日期,不足10补0
const d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate() // 获取当前几号,不足10补0
return {
fullDate: y + '-' + m + '-' + d,
year: y,
month: m,
date: d,
day: dd.getDay()
}
}
/**
* 获取上月剩余天数
*/
_getLastMonthDays(firstDay, full) {
let dateArr = []
for (let i = firstDay; i > 0; i--) {
const beforeDate = new Date(full.year, full.month - 1, -i + 1).getDate()
dateArr.push({
date: beforeDate,
month: full.month - 1,
lunar: this.getlunar(full.year, full.month - 1, beforeDate),
disable: true
})
}
return dateArr
}
/**
* 获取本月天数
*/
_currentMonthDys(dateData, full) {
let dateArr = []
let fullDate = this.date.fullDate
for (let i = 1; i <= dateData; i++) {
let nowDate = full.year + '-' + (full.month < 10 ?
full.month : full.month) + '-' + (i < 10 ?
'0' + i : i)
// 是否今天
let isDay = fullDate === nowDate
// 获取打点信息
let info = this.selected && this.selected.find((item) => {
if (this.dateEqual(nowDate, item.date)) {
return item
}
})
// 日期禁用
let disableBefore = true
let disableAfter = true
if (this.startDate) {
// let dateCompBefore = this.dateCompare(this.startDate, fullDate)
// disableBefore = this.dateCompare(dateCompBefore ? this.startDate : fullDate, nowDate)
disableBefore = this.dateCompare(this.startDate, nowDate)
}
if (this.endDate) {
// let dateCompAfter = this.dateCompare(fullDate, this.endDate)
// disableAfter = this.dateCompare(nowDate, dateCompAfter ? this.endDate : fullDate)
disableAfter = this.dateCompare(nowDate, this.endDate)
}
let multiples = this.multipleStatus.data
let checked = false
let multiplesStatus = -1
if (this.range) {
if (multiples) {
multiplesStatus = multiples.findIndex((item) => {
return this.dateEqual(item, nowDate)
})
}
if (multiplesStatus !== -1) {
checked = true
}
}
let data = {
fullDate: nowDate,
year: full.year,
date: i,
multiple: this.range ? checked : false,
beforeMultiple: this.dateEqual(this.multipleStatus.before, nowDate),
afterMultiple: this.dateEqual(this.multipleStatus.after, nowDate),
month: full.month,
lunar: this.getlunar(full.year, full.month, i),
disable: !(disableBefore && disableAfter),
isDay
}
if (info) {
data.extraInfo = info
}
dateArr.push(data)
}
return dateArr
}
/**
* 获取下月天数
*/
_getNextMonthDays(surplus, full) {
let dateArr = []
for (let i = 1; i < surplus + 1; i++) {
dateArr.push({
date: i,
month: Number(full.month) + 1,
lunar: this.getlunar(full.year, Number(full.month) + 1, i),
disable: true
})
}
return dateArr
}
/**
* 获取当前日期详情
* @param {Object} date
*/
getInfo(date) {
if (!date) {
date = new Date()
}
const dateInfo = this.canlender.find(item => item.fullDate === this.getDate(date).fullDate)
return dateInfo
}
/**
* 比较时间大小
*/
dateCompare(startDate, endDate) {
// 计算截止时间
startDate = new Date(startDate.replace('-', '/').replace('-', '/'))
// 计算详细项的截止时间
endDate = new Date(endDate.replace('-', '/').replace('-', '/'))
if (startDate <= endDate) {
return true
} else {
return false
}
}
/**
* 比较时间是否相等
*/
dateEqual(before, after) {
// 计算截止时间
before = new Date(before.replace('-', '/').replace('-', '/'))
// 计算详细项的截止时间
after = new Date(after.replace('-', '/').replace('-', '/'))
if (before.getTime() - after.getTime() === 0) {
return true
} else {
return false
}
}
/**
* 获取日期范围内所有日期
* @param {Object} begin
* @param {Object} end
*/
geDateAll(begin, end) {
var arr = []
var ab = begin.split('-')
var ae = end.split('-')
var db = new Date()
db.setFullYear(ab[0], ab[1] - 1, ab[2])
var de = new Date()
de.setFullYear(ae[0], ae[1] - 1, ae[2])
var unixDb = db.getTime() - 24 * 60 * 60 * 1000
var unixDe = de.getTime() - 24 * 60 * 60 * 1000
for (var k = unixDb; k <= unixDe;) {
k = k + 24 * 60 * 60 * 1000
arr.push(this.getDate(new Date(parseInt(k))).fullDate)
}
return arr
}
/**
* 计算阴历日期显示
*/
getlunar(year, month, date) {
return CALENDAR.solar2lunar(year, month, date)
}
/**
* 设置打点
*/
setSelectInfo(data, value) {
this.selected = value
this._getWeek(data)
}
/**
* 获取多选状态
*/
setMultiple(fullDate) {
let {
before,
after
} = this.multipleStatus
if (!this.range) return
if (before && after) {
this.multipleStatus.before = fullDate
this.multipleStatus.after = ''
this.multipleStatus.data = []
} else {
if (!before) {
this.multipleStatus.before = fullDate
} else {
this.multipleStatus.after = fullDate
if (this.dateCompare(this.multipleStatus.before, this.multipleStatus.after)) {
this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus.after);
} else {
this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus.before);
}
}
}
this._getWeek(fullDate)
}
/**
* 获取每周数据
* @param {Object} dateData
*/
_getWeek(dateData) {
const {
year,
month
} = this.getDate(dateData)
let firstDay = new Date(year, month - 1, 1).getDay()
let currentDay = new Date(year, month, 0).getDate()
let dates = {
lastMonthDays: this._getLastMonthDays(firstDay, this.getDate(dateData)), // 上个月末尾几天
currentMonthDys: this._currentMonthDys(currentDay, this.getDate(dateData)), // 本月天数
nextMonthDays: [], // 下个月开始几天
weeks: []
}
let canlender = []
const surplus = 42 - (dates.lastMonthDays.length + dates.currentMonthDys.length)
dates.nextMonthDays = this._getNextMonthDays(surplus, this.getDate(dateData))
canlender = canlender.concat(dates.lastMonthDays, dates.currentMonthDys, dates.nextMonthDays)
let weeks = {}
// 拼接数组 上个月开始几天 + 本月天数+ 下个月开始几天
for (let i = 0; i < canlender.length; i++) {
if (i % 7 === 0) {
weeks[parseInt(i / 7)] = new Array(7)
}
weeks[parseInt(i / 7)][i % 7] = canlender[i]
}
this.canlender = canlender
this.weeks = weeks
}
//静态方法
// static init(date) {
// if (!this.instance) {
// this.instance = new Calendar(date);
// }
// return this.instance;
// }
}
export default Calendar

86
uni_modules/uni-calendar/package.json

@ -0,0 +1,86 @@
{
"id": "uni-calendar",
"displayName": "uni-calendar 日历",
"version": "1.4.12",
"description": "日历组件",
"keywords": [
"uni-ui",
"uniui",
"日历",
"",
"打卡",
"日历选择"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
"type": "component-vue"
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y",
"alipay": "n"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}

103
uni_modules/uni-calendar/readme.md

@ -0,0 +1,103 @@
## Calendar 日历
> **组件名:uni-calendar**
> 代码块: `uCalendar`
日历组件
> **注意事项**
> 为了避免错误使用,给大家带来不好的开发体验,请在使用组件前仔细阅读下面的注意事项,可以帮你避免一些错误。
> - 本组件农历转换使用的js是 [@1900-2100区间内的公历、农历互转](https://github.com/jjonline/calendar.js)
> - 仅支持自定义组件模式
> - `date`属性传入的应该是一个 String ,如: 2019-06-27 ,而不是 new Date()
> - 通过 `insert` 属性来确定当前的事件是 @change 还是 @confirm 。理应合并为一个事件,但是为了区分模式,现使用两个事件,这里需要注意
> - 弹窗模式下无法阻止后面的元素滚动,如有需要阻止,请在弹窗弹出后,手动设置滚动元素为不可滚动
### 安装方式
本组件符合[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)规范,`HBuilderX 2.5.5`起,只需将本组件导入项目,在页面`template`中即可直接使用,无需在页面中`import`和注册`components`。
如需通过`npm`方式使用`uni-ui`组件,另见文档:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55)
### 基本用法
在 ``template`` 中使用组件
```html
<view>
<uni-calendar
:insert="true"
:lunar="true"
:start-date="'2019-3-2'"
:end-date="'2019-5-20'"
@change="change"
/>
</view>
```
### 通过方法打开日历
需要设置 `insert``false`
```html
<view>
<uni-calendar
ref="calendar"
:insert="false"
@confirm="confirm"
/>
<button @click="open">打开日历</button>
</view>
```
```javascript
export default {
data() {
return {};
},
methods: {
open(){
this.$refs.calendar.open();
},
confirm(e) {
console.log(e);
}
}
};
```
## API
### Calendar Props
| 属性名 | 类型 | 默认值| 说明 |
| - | - | - | - |
| date | String |- | 自定义当前时间,默认为今天 |
| lunar | Boolean | false | 显示农历 |
| startDate | String |- | 日期选择范围-开始日期 |
| endDate | String |- | 日期选择范围-结束日期 |
| range | Boolean | false | 范围选择 |
| insert | Boolean | false | 插入模式,可选值,ture:插入模式;false:弹窗模式;默认为插入模式 |
|clearDate |Boolean |true |弹窗模式是否清空上次选择内容 |
| selected | Array |- | 打点,期待格式[{date: '2019-06-27', info: '签到', data: { custom: '自定义信息', name: '自定义消息头',xxx:xxx... }}] |
|showMonth | Boolean | true | 是否显示月份为背景 |
### Calendar Events
| 事件名 | 说明 |返回值|
| - | - | - |
| open | 弹出日历组件,`insert :false` 时生效|- |
## 组件示例
点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/calendar/calendar](https://hellouniapp.dcloud.net.cn/pages/extUI/calendar/calendar)

42
uni_modules/uni-icons/changelog.md

@ -0,0 +1,42 @@
## 2.0.10(2024-06-07)
- 优化 uni-app x 中,size 属性的类型
## 2.0.9(2024-01-12)
fix: 修复图标大小默认值错误的问题
## 2.0.8(2023-12-14)
- 修复 项目未使用 ts 情况下,打包报错的bug
## 2.0.7(2023-12-14)
- 修复 size 属性为 string 时,不加单位导致尺寸异常的bug
## 2.0.6(2023-12-11)
- 优化 兼容老版本icon类型,如 top ,bottom 等
## 2.0.5(2023-12-11)
- 优化 兼容老版本icon类型,如 top ,bottom 等
## 2.0.4(2023-12-06)
- 优化 uni-app x 下示例项目图标排序
## 2.0.3(2023-12-06)
- 修复 nvue下引入组件报错的bug
## 2.0.2(2023-12-05)
-优化 size 属性支持单位
## 2.0.1(2023-12-05)
- 新增 uni-app x 支持定义图标
## 1.3.5(2022-01-24)
- 优化 size 属性可以传入不带单位的字符串数值
## 1.3.4(2022-01-24)
- 优化 size 支持其他单位
## 1.3.3(2022-01-17)
- 修复 nvue 有些图标不显示的bug,兼容老版本图标
## 1.3.2(2021-12-01)
- 优化 示例可复制图标名称
## 1.3.1(2021-11-23)
- 优化 兼容旧组件 type 值
## 1.3.0(2021-11-19)
- 新增 更多图标
- 优化 自定义图标使用方式
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-icons](https://uniapp.dcloud.io/component/uniui/uni-icons)
## 1.1.7(2021-11-08)
## 1.2.0(2021-07-30)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.1.5(2021-05-12)
- 新增 组件示例地址
## 1.1.4(2021-02-05)
- 调整为uni_modules目录规范

91
uni_modules/uni-icons/components/uni-icons/uni-icons.uvue

@ -0,0 +1,91 @@
<template>
<text class="uni-icons" :style="styleObj">
<slot>{{unicode}}</slot>
</text>
</template>
<script>
import { fontData, IconsDataItem } from './uniicons_file'
/**
* Icons 图标
* @description 用于展示 icon 图标
* @tutorial https://ext.dcloud.net.cn/plugin?id=28
* @property {Number,String} size 图标大小
* @property {String} type 图标图案,参考示例
* @property {String} color 图标颜色
* @property {String} customPrefix 自定义图标
* @event {Function} click 点击 Icon 触发事件
*/
export default {
name: "uni-icons",
props: {
type: {
type: String,
default: ''
},
color: {
type: String,
default: '#333333'
},
size: {
type: [Number, String],
default: 16
},
fontFamily: {
type: String,
default: ''
}
},
data() {
return {};
},
computed: {
unicode() : string {
let codes = fontData.find((item : IconsDataItem) : boolean => { return item.font_class == this.type })
if (codes !== null) {
return codes.unicode
}
return ''
},
iconSize() : string {
const size = this.size
if (typeof size == 'string') {
const reg = /^[0-9]*$/g
return reg.test(size as string) ? '' + size + 'px' : '' + size;
// return '' + this.size
}
return this.getFontSize(size as number)
},
styleObj() : UTSJSONObject {
if (this.fontFamily !== '') {
return { color: this.color, fontSize: this.iconSize, fontFamily: this.fontFamily }
}
return { color: this.color, fontSize: this.iconSize }
}
},
created() { },
methods: {
/**
* 字体大小
*/
getFontSize(size : number) : string {
return size + 'px';
},
},
}
</script>
<style scoped>
@font-face {
font-family: UniIconsFontFamily;
src: url('./uniicons.ttf');
}
.uni-icons {
font-family: UniIconsFontFamily;
font-size: 18px;
font-style: normal;
color: #333;
}
</style>

110
uni_modules/uni-icons/components/uni-icons/uni-icons.vue

@ -0,0 +1,110 @@
<template>
<!-- #ifdef APP-NVUE -->
<text :style="styleObj" class="uni-icons" @click="_onClick">{{unicode}}</text>
<!-- #endif -->
<!-- #ifndef APP-NVUE -->
<text :style="styleObj" class="uni-icons" :class="['uniui-'+type,customPrefix,customPrefix?type:'']" @click="_onClick">
<slot></slot>
</text>
<!-- #endif -->
</template>
<script>
import { fontData } from './uniicons_file_vue.js';
const getVal = (val) => {
const reg = /^[0-9]*$/g
return (typeof val === 'number' || reg.test(val)) ? val + 'px' : val;
}
// #ifdef APP-NVUE
var domModule = weex.requireModule('dom');
import iconUrl from './uniicons.ttf'
domModule.addRule('fontFace', {
'fontFamily': "uniicons",
'src': "url('" + iconUrl + "')"
});
// #endif
/**
* Icons 图标
* @description 用于展示 icons 图标
* @tutorial https://ext.dcloud.net.cn/plugin?id=28
* @property {Number} size 图标大小
* @property {String} type 图标图案参考示例
* @property {String} color 图标颜色
* @property {String} customPrefix 自定义图标
* @event {Function} click 点击 Icon 触发事件
*/
export default {
name: 'UniIcons',
emits: ['click'],
props: {
type: {
type: String,
default: ''
},
color: {
type: String,
default: '#333333'
},
size: {
type: [Number, String],
default: 16
},
customPrefix: {
type: String,
default: ''
},
fontFamily: {
type: String,
default: ''
}
},
data() {
return {
icons: fontData
}
},
computed: {
unicode() {
let code = this.icons.find(v => v.font_class === this.type)
if (code) {
return code.unicode
}
return ''
},
iconSize() {
return getVal(this.size)
},
styleObj() {
if (this.fontFamily !== '') {
return `color: ${this.color}; font-size: ${this.iconSize}; font-family: ${this.fontFamily};`
}
return `color: ${this.color}; font-size: ${this.iconSize};`
}
},
methods: {
_onClick() {
this.$emit('click')
}
}
}
</script>
<style lang="scss">
/* #ifndef APP-NVUE */
@import './uniicons.css';
@font-face {
font-family: uniicons;
src: url('./uniicons.ttf');
}
/* #endif */
.uni-icons {
font-family: uniicons;
text-decoration: none;
text-align: center;
}
</style>

664
uni_modules/uni-icons/components/uni-icons/uniicons.css

@ -0,0 +1,664 @@
.uniui-cart-filled:before {
content: "\e6d0";
}
.uniui-gift-filled:before {
content: "\e6c4";
}
.uniui-color:before {
content: "\e6cf";
}
.uniui-wallet:before {
content: "\e6b1";
}
.uniui-settings-filled:before {
content: "\e6ce";
}
.uniui-auth-filled:before {
content: "\e6cc";
}
.uniui-shop-filled:before {
content: "\e6cd";
}
.uniui-staff-filled:before {
content: "\e6cb";
}
.uniui-vip-filled:before {
content: "\e6c6";
}
.uniui-plus-filled:before {
content: "\e6c7";
}
.uniui-folder-add-filled:before {
content: "\e6c8";
}
.uniui-color-filled:before {
content: "\e6c9";
}
.uniui-tune-filled:before {
content: "\e6ca";
}
.uniui-calendar-filled:before {
content: "\e6c0";
}
.uniui-notification-filled:before {
content: "\e6c1";
}
.uniui-wallet-filled:before {
content: "\e6c2";
}
.uniui-medal-filled:before {
content: "\e6c3";
}
.uniui-fire-filled:before {
content: "\e6c5";
}
.uniui-refreshempty:before {
content: "\e6bf";
}
.uniui-location-filled:before {
content: "\e6af";
}
.uniui-person-filled:before {
content: "\e69d";
}
.uniui-personadd-filled:before {
content: "\e698";
}
.uniui-arrowthinleft:before {
content: "\e6d2";
}
.uniui-arrowthinup:before {
content: "\e6d3";
}
.uniui-arrowthindown:before {
content: "\e6d4";
}
.uniui-back:before {
content: "\e6b9";
}
.uniui-forward:before {
content: "\e6ba";
}
.uniui-arrow-right:before {
content: "\e6bb";
}
.uniui-arrow-left:before {
content: "\e6bc";
}
.uniui-arrow-up:before {
content: "\e6bd";
}
.uniui-arrow-down:before {
content: "\e6be";
}
.uniui-arrowthinright:before {
content: "\e6d1";
}
.uniui-down:before {
content: "\e6b8";
}
.uniui-bottom:before {
content: "\e6b8";
}
.uniui-arrowright:before {
content: "\e6d5";
}
.uniui-right:before {
content: "\e6b5";
}
.uniui-up:before {
content: "\e6b6";
}
.uniui-top:before {
content: "\e6b6";
}
.uniui-left:before {
content: "\e6b7";
}
.uniui-arrowup:before {
content: "\e6d6";
}
.uniui-eye:before {
content: "\e651";
}
.uniui-eye-filled:before {
content: "\e66a";
}
.uniui-eye-slash:before {
content: "\e6b3";
}
.uniui-eye-slash-filled:before {
content: "\e6b4";
}
.uniui-info-filled:before {
content: "\e649";
}
.uniui-reload:before {
content: "\e6b2";
}
.uniui-micoff-filled:before {
content: "\e6b0";
}
.uniui-map-pin-ellipse:before {
content: "\e6ac";
}
.uniui-map-pin:before {
content: "\e6ad";
}
.uniui-location:before {
content: "\e6ae";
}
.uniui-starhalf:before {
content: "\e683";
}
.uniui-star:before {
content: "\e688";
}
.uniui-star-filled:before {
content: "\e68f";
}
.uniui-calendar:before {
content: "\e6a0";
}
.uniui-fire:before {
content: "\e6a1";
}
.uniui-medal:before {
content: "\e6a2";
}
.uniui-font:before {
content: "\e6a3";
}
.uniui-gift:before {
content: "\e6a4";
}
.uniui-link:before {
content: "\e6a5";
}
.uniui-notification:before {
content: "\e6a6";
}
.uniui-staff:before {
content: "\e6a7";
}
.uniui-vip:before {
content: "\e6a8";
}
.uniui-folder-add:before {
content: "\e6a9";
}
.uniui-tune:before {
content: "\e6aa";
}
.uniui-auth:before {
content: "\e6ab";
}
.uniui-person:before {
content: "\e699";
}
.uniui-email-filled:before {
content: "\e69a";
}
.uniui-phone-filled:before {
content: "\e69b";
}
.uniui-phone:before {
content: "\e69c";
}
.uniui-email:before {
content: "\e69e";
}
.uniui-personadd:before {
content: "\e69f";
}
.uniui-chatboxes-filled:before {
content: "\e692";
}
.uniui-contact:before {
content: "\e693";
}
.uniui-chatbubble-filled:before {
content: "\e694";
}
.uniui-contact-filled:before {
content: "\e695";
}
.uniui-chatboxes:before {
content: "\e696";
}
.uniui-chatbubble:before {
content: "\e697";
}
.uniui-upload-filled:before {
content: "\e68e";
}
.uniui-upload:before {
content: "\e690";
}
.uniui-weixin:before {
content: "\e691";
}
.uniui-compose:before {
content: "\e67f";
}
.uniui-qq:before {
content: "\e680";
}
.uniui-download-filled:before {
content: "\e681";
}
.uniui-pyq:before {
content: "\e682";
}
.uniui-sound:before {
content: "\e684";
}
.uniui-trash-filled:before {
content: "\e685";
}
.uniui-sound-filled:before {
content: "\e686";
}
.uniui-trash:before {
content: "\e687";
}
.uniui-videocam-filled:before {
content: "\e689";
}
.uniui-spinner-cycle:before {
content: "\e68a";
}
.uniui-weibo:before {
content: "\e68b";
}
.uniui-videocam:before {
content: "\e68c";
}
.uniui-download:before {
content: "\e68d";
}
.uniui-help:before {
content: "\e679";
}
.uniui-navigate-filled:before {
content: "\e67a";
}
.uniui-plusempty:before {
content: "\e67b";
}
.uniui-smallcircle:before {
content: "\e67c";
}
.uniui-minus-filled:before {
content: "\e67d";
}
.uniui-micoff:before {
content: "\e67e";
}
.uniui-closeempty:before {
content: "\e66c";
}
.uniui-clear:before {
content: "\e66d";
}
.uniui-navigate:before {
content: "\e66e";
}
.uniui-minus:before {
content: "\e66f";
}
.uniui-image:before {
content: "\e670";
}
.uniui-mic:before {
content: "\e671";
}
.uniui-paperplane:before {
content: "\e672";
}
.uniui-close:before {
content: "\e673";
}
.uniui-help-filled:before {
content: "\e674";
}
.uniui-paperplane-filled:before {
content: "\e675";
}
.uniui-plus:before {
content: "\e676";
}
.uniui-mic-filled:before {
content: "\e677";
}
.uniui-image-filled:before {
content: "\e678";
}
.uniui-locked-filled:before {
content: "\e668";
}
.uniui-info:before {
content: "\e669";
}
.uniui-locked:before {
content: "\e66b";
}
.uniui-camera-filled:before {
content: "\e658";
}
.uniui-chat-filled:before {
content: "\e659";
}
.uniui-camera:before {
content: "\e65a";
}
.uniui-circle:before {
content: "\e65b";
}
.uniui-checkmarkempty:before {
content: "\e65c";
}
.uniui-chat:before {
content: "\e65d";
}
.uniui-circle-filled:before {
content: "\e65e";
}
.uniui-flag:before {
content: "\e65f";
}
.uniui-flag-filled:before {
content: "\e660";
}
.uniui-gear-filled:before {
content: "\e661";
}
.uniui-home:before {
content: "\e662";
}
.uniui-home-filled:before {
content: "\e663";
}
.uniui-gear:before {
content: "\e664";
}
.uniui-smallcircle-filled:before {
content: "\e665";
}
.uniui-map-filled:before {
content: "\e666";
}
.uniui-map:before {
content: "\e667";
}
.uniui-refresh-filled:before {
content: "\e656";
}
.uniui-refresh:before {
content: "\e657";
}
.uniui-cloud-upload:before {
content: "\e645";
}
.uniui-cloud-download-filled:before {
content: "\e646";
}
.uniui-cloud-download:before {
content: "\e647";
}
.uniui-cloud-upload-filled:before {
content: "\e648";
}
.uniui-redo:before {
content: "\e64a";
}
.uniui-images-filled:before {
content: "\e64b";
}
.uniui-undo-filled:before {
content: "\e64c";
}
.uniui-more:before {
content: "\e64d";
}
.uniui-more-filled:before {
content: "\e64e";
}
.uniui-undo:before {
content: "\e64f";
}
.uniui-images:before {
content: "\e650";
}
.uniui-paperclip:before {
content: "\e652";
}
.uniui-settings:before {
content: "\e653";
}
.uniui-search:before {
content: "\e654";
}
.uniui-redo-filled:before {
content: "\e655";
}
.uniui-list:before {
content: "\e644";
}
.uniui-mail-open-filled:before {
content: "\e63a";
}
.uniui-hand-down-filled:before {
content: "\e63c";
}
.uniui-hand-down:before {
content: "\e63d";
}
.uniui-hand-up-filled:before {
content: "\e63e";
}
.uniui-hand-up:before {
content: "\e63f";
}
.uniui-heart-filled:before {
content: "\e641";
}
.uniui-mail-open:before {
content: "\e643";
}
.uniui-heart:before {
content: "\e639";
}
.uniui-loop:before {
content: "\e633";
}
.uniui-pulldown:before {
content: "\e632";
}
.uniui-scan:before {
content: "\e62a";
}
.uniui-bars:before {
content: "\e627";
}
.uniui-checkbox:before {
content: "\e62b";
}
.uniui-checkbox-filled:before {
content: "\e62c";
}
.uniui-shop:before {
content: "\e62f";
}
.uniui-headphones:before {
content: "\e630";
}
.uniui-cart:before {
content: "\e631";
}

BIN
uni_modules/uni-icons/components/uni-icons/uniicons.ttf

Binary file not shown.

664
uni_modules/uni-icons/components/uni-icons/uniicons_file.ts

@ -0,0 +1,664 @@
export type IconsData = {
id : string
name : string
font_family : string
css_prefix_text : string
description : string
glyphs : Array<IconsDataItem>
}
export type IconsDataItem = {
font_class : string
unicode : string
}
export const fontData = [
{
"font_class": "arrow-down",
"unicode": "\ue6be"
},
{
"font_class": "arrow-left",
"unicode": "\ue6bc"
},
{
"font_class": "arrow-right",
"unicode": "\ue6bb"
},
{
"font_class": "arrow-up",
"unicode": "\ue6bd"
},
{
"font_class": "auth",
"unicode": "\ue6ab"
},
{
"font_class": "auth-filled",
"unicode": "\ue6cc"
},
{
"font_class": "back",
"unicode": "\ue6b9"
},
{
"font_class": "bars",
"unicode": "\ue627"
},
{
"font_class": "calendar",
"unicode": "\ue6a0"
},
{
"font_class": "calendar-filled",
"unicode": "\ue6c0"
},
{
"font_class": "camera",
"unicode": "\ue65a"
},
{
"font_class": "camera-filled",
"unicode": "\ue658"
},
{
"font_class": "cart",
"unicode": "\ue631"
},
{
"font_class": "cart-filled",
"unicode": "\ue6d0"
},
{
"font_class": "chat",
"unicode": "\ue65d"
},
{
"font_class": "chat-filled",
"unicode": "\ue659"
},
{
"font_class": "chatboxes",
"unicode": "\ue696"
},
{
"font_class": "chatboxes-filled",
"unicode": "\ue692"
},
{
"font_class": "chatbubble",
"unicode": "\ue697"
},
{
"font_class": "chatbubble-filled",
"unicode": "\ue694"
},
{
"font_class": "checkbox",
"unicode": "\ue62b"
},
{
"font_class": "checkbox-filled",
"unicode": "\ue62c"
},
{
"font_class": "checkmarkempty",
"unicode": "\ue65c"
},
{
"font_class": "circle",
"unicode": "\ue65b"
},
{
"font_class": "circle-filled",
"unicode": "\ue65e"
},
{
"font_class": "clear",
"unicode": "\ue66d"
},
{
"font_class": "close",
"unicode": "\ue673"
},
{
"font_class": "closeempty",
"unicode": "\ue66c"
},
{
"font_class": "cloud-download",
"unicode": "\ue647"
},
{
"font_class": "cloud-download-filled",
"unicode": "\ue646"
},
{
"font_class": "cloud-upload",
"unicode": "\ue645"
},
{
"font_class": "cloud-upload-filled",
"unicode": "\ue648"
},
{
"font_class": "color",
"unicode": "\ue6cf"
},
{
"font_class": "color-filled",
"unicode": "\ue6c9"
},
{
"font_class": "compose",
"unicode": "\ue67f"
},
{
"font_class": "contact",
"unicode": "\ue693"
},
{
"font_class": "contact-filled",
"unicode": "\ue695"
},
{
"font_class": "down",
"unicode": "\ue6b8"
},
{
"font_class": "bottom",
"unicode": "\ue6b8"
},
{
"font_class": "download",
"unicode": "\ue68d"
},
{
"font_class": "download-filled",
"unicode": "\ue681"
},
{
"font_class": "email",
"unicode": "\ue69e"
},
{
"font_class": "email-filled",
"unicode": "\ue69a"
},
{
"font_class": "eye",
"unicode": "\ue651"
},
{
"font_class": "eye-filled",
"unicode": "\ue66a"
},
{
"font_class": "eye-slash",
"unicode": "\ue6b3"
},
{
"font_class": "eye-slash-filled",
"unicode": "\ue6b4"
},
{
"font_class": "fire",
"unicode": "\ue6a1"
},
{
"font_class": "fire-filled",
"unicode": "\ue6c5"
},
{
"font_class": "flag",
"unicode": "\ue65f"
},
{
"font_class": "flag-filled",
"unicode": "\ue660"
},
{
"font_class": "folder-add",
"unicode": "\ue6a9"
},
{
"font_class": "folder-add-filled",
"unicode": "\ue6c8"
},
{
"font_class": "font",
"unicode": "\ue6a3"
},
{
"font_class": "forward",
"unicode": "\ue6ba"
},
{
"font_class": "gear",
"unicode": "\ue664"
},
{
"font_class": "gear-filled",
"unicode": "\ue661"
},
{
"font_class": "gift",
"unicode": "\ue6a4"
},
{
"font_class": "gift-filled",
"unicode": "\ue6c4"
},
{
"font_class": "hand-down",
"unicode": "\ue63d"
},
{
"font_class": "hand-down-filled",
"unicode": "\ue63c"
},
{
"font_class": "hand-up",
"unicode": "\ue63f"
},
{
"font_class": "hand-up-filled",
"unicode": "\ue63e"
},
{
"font_class": "headphones",
"unicode": "\ue630"
},
{
"font_class": "heart",
"unicode": "\ue639"
},
{
"font_class": "heart-filled",
"unicode": "\ue641"
},
{
"font_class": "help",
"unicode": "\ue679"
},
{
"font_class": "help-filled",
"unicode": "\ue674"
},
{
"font_class": "home",
"unicode": "\ue662"
},
{
"font_class": "home-filled",
"unicode": "\ue663"
},
{
"font_class": "image",
"unicode": "\ue670"
},
{
"font_class": "image-filled",
"unicode": "\ue678"
},
{
"font_class": "images",
"unicode": "\ue650"
},
{
"font_class": "images-filled",
"unicode": "\ue64b"
},
{
"font_class": "info",
"unicode": "\ue669"
},
{
"font_class": "info-filled",
"unicode": "\ue649"
},
{
"font_class": "left",
"unicode": "\ue6b7"
},
{
"font_class": "link",
"unicode": "\ue6a5"
},
{
"font_class": "list",
"unicode": "\ue644"
},
{
"font_class": "location",
"unicode": "\ue6ae"
},
{
"font_class": "location-filled",
"unicode": "\ue6af"
},
{
"font_class": "locked",
"unicode": "\ue66b"
},
{
"font_class": "locked-filled",
"unicode": "\ue668"
},
{
"font_class": "loop",
"unicode": "\ue633"
},
{
"font_class": "mail-open",
"unicode": "\ue643"
},
{
"font_class": "mail-open-filled",
"unicode": "\ue63a"
},
{
"font_class": "map",
"unicode": "\ue667"
},
{
"font_class": "map-filled",
"unicode": "\ue666"
},
{
"font_class": "map-pin",
"unicode": "\ue6ad"
},
{
"font_class": "map-pin-ellipse",
"unicode": "\ue6ac"
},
{
"font_class": "medal",
"unicode": "\ue6a2"
},
{
"font_class": "medal-filled",
"unicode": "\ue6c3"
},
{
"font_class": "mic",
"unicode": "\ue671"
},
{
"font_class": "mic-filled",
"unicode": "\ue677"
},
{
"font_class": "micoff",
"unicode": "\ue67e"
},
{
"font_class": "micoff-filled",
"unicode": "\ue6b0"
},
{
"font_class": "minus",
"unicode": "\ue66f"
},
{
"font_class": "minus-filled",
"unicode": "\ue67d"
},
{
"font_class": "more",
"unicode": "\ue64d"
},
{
"font_class": "more-filled",
"unicode": "\ue64e"
},
{
"font_class": "navigate",
"unicode": "\ue66e"
},
{
"font_class": "navigate-filled",
"unicode": "\ue67a"
},
{
"font_class": "notification",
"unicode": "\ue6a6"
},
{
"font_class": "notification-filled",
"unicode": "\ue6c1"
},
{
"font_class": "paperclip",
"unicode": "\ue652"
},
{
"font_class": "paperplane",
"unicode": "\ue672"
},
{
"font_class": "paperplane-filled",
"unicode": "\ue675"
},
{
"font_class": "person",
"unicode": "\ue699"
},
{
"font_class": "person-filled",
"unicode": "\ue69d"
},
{
"font_class": "personadd",
"unicode": "\ue69f"
},
{
"font_class": "personadd-filled",
"unicode": "\ue698"
},
{
"font_class": "personadd-filled-copy",
"unicode": "\ue6d1"
},
{
"font_class": "phone",
"unicode": "\ue69c"
},
{
"font_class": "phone-filled",
"unicode": "\ue69b"
},
{
"font_class": "plus",
"unicode": "\ue676"
},
{
"font_class": "plus-filled",
"unicode": "\ue6c7"
},
{
"font_class": "plusempty",
"unicode": "\ue67b"
},
{
"font_class": "pulldown",
"unicode": "\ue632"
},
{
"font_class": "pyq",
"unicode": "\ue682"
},
{
"font_class": "qq",
"unicode": "\ue680"
},
{
"font_class": "redo",
"unicode": "\ue64a"
},
{
"font_class": "redo-filled",
"unicode": "\ue655"
},
{
"font_class": "refresh",
"unicode": "\ue657"
},
{
"font_class": "refresh-filled",
"unicode": "\ue656"
},
{
"font_class": "refreshempty",
"unicode": "\ue6bf"
},
{
"font_class": "reload",
"unicode": "\ue6b2"
},
{
"font_class": "right",
"unicode": "\ue6b5"
},
{
"font_class": "scan",
"unicode": "\ue62a"
},
{
"font_class": "search",
"unicode": "\ue654"
},
{
"font_class": "settings",
"unicode": "\ue653"
},
{
"font_class": "settings-filled",
"unicode": "\ue6ce"
},
{
"font_class": "shop",
"unicode": "\ue62f"
},
{
"font_class": "shop-filled",
"unicode": "\ue6cd"
},
{
"font_class": "smallcircle",
"unicode": "\ue67c"
},
{
"font_class": "smallcircle-filled",
"unicode": "\ue665"
},
{
"font_class": "sound",
"unicode": "\ue684"
},
{
"font_class": "sound-filled",
"unicode": "\ue686"
},
{
"font_class": "spinner-cycle",
"unicode": "\ue68a"
},
{
"font_class": "staff",
"unicode": "\ue6a7"
},
{
"font_class": "staff-filled",
"unicode": "\ue6cb"
},
{
"font_class": "star",
"unicode": "\ue688"
},
{
"font_class": "star-filled",
"unicode": "\ue68f"
},
{
"font_class": "starhalf",
"unicode": "\ue683"
},
{
"font_class": "trash",
"unicode": "\ue687"
},
{
"font_class": "trash-filled",
"unicode": "\ue685"
},
{
"font_class": "tune",
"unicode": "\ue6aa"
},
{
"font_class": "tune-filled",
"unicode": "\ue6ca"
},
{
"font_class": "undo",
"unicode": "\ue64f"
},
{
"font_class": "undo-filled",
"unicode": "\ue64c"
},
{
"font_class": "up",
"unicode": "\ue6b6"
},
{
"font_class": "top",
"unicode": "\ue6b6"
},
{
"font_class": "upload",
"unicode": "\ue690"
},
{
"font_class": "upload-filled",
"unicode": "\ue68e"
},
{
"font_class": "videocam",
"unicode": "\ue68c"
},
{
"font_class": "videocam-filled",
"unicode": "\ue689"
},
{
"font_class": "vip",
"unicode": "\ue6a8"
},
{
"font_class": "vip-filled",
"unicode": "\ue6c6"
},
{
"font_class": "wallet",
"unicode": "\ue6b1"
},
{
"font_class": "wallet-filled",
"unicode": "\ue6c2"
},
{
"font_class": "weibo",
"unicode": "\ue68b"
},
{
"font_class": "weixin",
"unicode": "\ue691"
}
] as IconsDataItem[]
// export const fontData = JSON.parse<IconsDataItem>(fontDataJson)

649
uni_modules/uni-icons/components/uni-icons/uniicons_file_vue.js

@ -0,0 +1,649 @@
export const fontData = [
{
"font_class": "arrow-down",
"unicode": "\ue6be"
},
{
"font_class": "arrow-left",
"unicode": "\ue6bc"
},
{
"font_class": "arrow-right",
"unicode": "\ue6bb"
},
{
"font_class": "arrow-up",
"unicode": "\ue6bd"
},
{
"font_class": "auth",
"unicode": "\ue6ab"
},
{
"font_class": "auth-filled",
"unicode": "\ue6cc"
},
{
"font_class": "back",
"unicode": "\ue6b9"
},
{
"font_class": "bars",
"unicode": "\ue627"
},
{
"font_class": "calendar",
"unicode": "\ue6a0"
},
{
"font_class": "calendar-filled",
"unicode": "\ue6c0"
},
{
"font_class": "camera",
"unicode": "\ue65a"
},
{
"font_class": "camera-filled",
"unicode": "\ue658"
},
{
"font_class": "cart",
"unicode": "\ue631"
},
{
"font_class": "cart-filled",
"unicode": "\ue6d0"
},
{
"font_class": "chat",
"unicode": "\ue65d"
},
{
"font_class": "chat-filled",
"unicode": "\ue659"
},
{
"font_class": "chatboxes",
"unicode": "\ue696"
},
{
"font_class": "chatboxes-filled",
"unicode": "\ue692"
},
{
"font_class": "chatbubble",
"unicode": "\ue697"
},
{
"font_class": "chatbubble-filled",
"unicode": "\ue694"
},
{
"font_class": "checkbox",
"unicode": "\ue62b"
},
{
"font_class": "checkbox-filled",
"unicode": "\ue62c"
},
{
"font_class": "checkmarkempty",
"unicode": "\ue65c"
},
{
"font_class": "circle",
"unicode": "\ue65b"
},
{
"font_class": "circle-filled",
"unicode": "\ue65e"
},
{
"font_class": "clear",
"unicode": "\ue66d"
},
{
"font_class": "close",
"unicode": "\ue673"
},
{
"font_class": "closeempty",
"unicode": "\ue66c"
},
{
"font_class": "cloud-download",
"unicode": "\ue647"
},
{
"font_class": "cloud-download-filled",
"unicode": "\ue646"
},
{
"font_class": "cloud-upload",
"unicode": "\ue645"
},
{
"font_class": "cloud-upload-filled",
"unicode": "\ue648"
},
{
"font_class": "color",
"unicode": "\ue6cf"
},
{
"font_class": "color-filled",
"unicode": "\ue6c9"
},
{
"font_class": "compose",
"unicode": "\ue67f"
},
{
"font_class": "contact",
"unicode": "\ue693"
},
{
"font_class": "contact-filled",
"unicode": "\ue695"
},
{
"font_class": "down",
"unicode": "\ue6b8"
},
{
"font_class": "bottom",
"unicode": "\ue6b8"
},
{
"font_class": "download",
"unicode": "\ue68d"
},
{
"font_class": "download-filled",
"unicode": "\ue681"
},
{
"font_class": "email",
"unicode": "\ue69e"
},
{
"font_class": "email-filled",
"unicode": "\ue69a"
},
{
"font_class": "eye",
"unicode": "\ue651"
},
{
"font_class": "eye-filled",
"unicode": "\ue66a"
},
{
"font_class": "eye-slash",
"unicode": "\ue6b3"
},
{
"font_class": "eye-slash-filled",
"unicode": "\ue6b4"
},
{
"font_class": "fire",
"unicode": "\ue6a1"
},
{
"font_class": "fire-filled",
"unicode": "\ue6c5"
},
{
"font_class": "flag",
"unicode": "\ue65f"
},
{
"font_class": "flag-filled",
"unicode": "\ue660"
},
{
"font_class": "folder-add",
"unicode": "\ue6a9"
},
{
"font_class": "folder-add-filled",
"unicode": "\ue6c8"
},
{
"font_class": "font",
"unicode": "\ue6a3"
},
{
"font_class": "forward",
"unicode": "\ue6ba"
},
{
"font_class": "gear",
"unicode": "\ue664"
},
{
"font_class": "gear-filled",
"unicode": "\ue661"
},
{
"font_class": "gift",
"unicode": "\ue6a4"
},
{
"font_class": "gift-filled",
"unicode": "\ue6c4"
},
{
"font_class": "hand-down",
"unicode": "\ue63d"
},
{
"font_class": "hand-down-filled",
"unicode": "\ue63c"
},
{
"font_class": "hand-up",
"unicode": "\ue63f"
},
{
"font_class": "hand-up-filled",
"unicode": "\ue63e"
},
{
"font_class": "headphones",
"unicode": "\ue630"
},
{
"font_class": "heart",
"unicode": "\ue639"
},
{
"font_class": "heart-filled",
"unicode": "\ue641"
},
{
"font_class": "help",
"unicode": "\ue679"
},
{
"font_class": "help-filled",
"unicode": "\ue674"
},
{
"font_class": "home",
"unicode": "\ue662"
},
{
"font_class": "home-filled",
"unicode": "\ue663"
},
{
"font_class": "image",
"unicode": "\ue670"
},
{
"font_class": "image-filled",
"unicode": "\ue678"
},
{
"font_class": "images",
"unicode": "\ue650"
},
{
"font_class": "images-filled",
"unicode": "\ue64b"
},
{
"font_class": "info",
"unicode": "\ue669"
},
{
"font_class": "info-filled",
"unicode": "\ue649"
},
{
"font_class": "left",
"unicode": "\ue6b7"
},
{
"font_class": "link",
"unicode": "\ue6a5"
},
{
"font_class": "list",
"unicode": "\ue644"
},
{
"font_class": "location",
"unicode": "\ue6ae"
},
{
"font_class": "location-filled",
"unicode": "\ue6af"
},
{
"font_class": "locked",
"unicode": "\ue66b"
},
{
"font_class": "locked-filled",
"unicode": "\ue668"
},
{
"font_class": "loop",
"unicode": "\ue633"
},
{
"font_class": "mail-open",
"unicode": "\ue643"
},
{
"font_class": "mail-open-filled",
"unicode": "\ue63a"
},
{
"font_class": "map",
"unicode": "\ue667"
},
{
"font_class": "map-filled",
"unicode": "\ue666"
},
{
"font_class": "map-pin",
"unicode": "\ue6ad"
},
{
"font_class": "map-pin-ellipse",
"unicode": "\ue6ac"
},
{
"font_class": "medal",
"unicode": "\ue6a2"
},
{
"font_class": "medal-filled",
"unicode": "\ue6c3"
},
{
"font_class": "mic",
"unicode": "\ue671"
},
{
"font_class": "mic-filled",
"unicode": "\ue677"
},
{
"font_class": "micoff",
"unicode": "\ue67e"
},
{
"font_class": "micoff-filled",
"unicode": "\ue6b0"
},
{
"font_class": "minus",
"unicode": "\ue66f"
},
{
"font_class": "minus-filled",
"unicode": "\ue67d"
},
{
"font_class": "more",
"unicode": "\ue64d"
},
{
"font_class": "more-filled",
"unicode": "\ue64e"
},
{
"font_class": "navigate",
"unicode": "\ue66e"
},
{
"font_class": "navigate-filled",
"unicode": "\ue67a"
},
{
"font_class": "notification",
"unicode": "\ue6a6"
},
{
"font_class": "notification-filled",
"unicode": "\ue6c1"
},
{
"font_class": "paperclip",
"unicode": "\ue652"
},
{
"font_class": "paperplane",
"unicode": "\ue672"
},
{
"font_class": "paperplane-filled",
"unicode": "\ue675"
},
{
"font_class": "person",
"unicode": "\ue699"
},
{
"font_class": "person-filled",
"unicode": "\ue69d"
},
{
"font_class": "personadd",
"unicode": "\ue69f"
},
{
"font_class": "personadd-filled",
"unicode": "\ue698"
},
{
"font_class": "personadd-filled-copy",
"unicode": "\ue6d1"
},
{
"font_class": "phone",
"unicode": "\ue69c"
},
{
"font_class": "phone-filled",
"unicode": "\ue69b"
},
{
"font_class": "plus",
"unicode": "\ue676"
},
{
"font_class": "plus-filled",
"unicode": "\ue6c7"
},
{
"font_class": "plusempty",
"unicode": "\ue67b"
},
{
"font_class": "pulldown",
"unicode": "\ue632"
},
{
"font_class": "pyq",
"unicode": "\ue682"
},
{
"font_class": "qq",
"unicode": "\ue680"
},
{
"font_class": "redo",
"unicode": "\ue64a"
},
{
"font_class": "redo-filled",
"unicode": "\ue655"
},
{
"font_class": "refresh",
"unicode": "\ue657"
},
{
"font_class": "refresh-filled",
"unicode": "\ue656"
},
{
"font_class": "refreshempty",
"unicode": "\ue6bf"
},
{
"font_class": "reload",
"unicode": "\ue6b2"
},
{
"font_class": "right",
"unicode": "\ue6b5"
},
{
"font_class": "scan",
"unicode": "\ue62a"
},
{
"font_class": "search",
"unicode": "\ue654"
},
{
"font_class": "settings",
"unicode": "\ue653"
},
{
"font_class": "settings-filled",
"unicode": "\ue6ce"
},
{
"font_class": "shop",
"unicode": "\ue62f"
},
{
"font_class": "shop-filled",
"unicode": "\ue6cd"
},
{
"font_class": "smallcircle",
"unicode": "\ue67c"
},
{
"font_class": "smallcircle-filled",
"unicode": "\ue665"
},
{
"font_class": "sound",
"unicode": "\ue684"
},
{
"font_class": "sound-filled",
"unicode": "\ue686"
},
{
"font_class": "spinner-cycle",
"unicode": "\ue68a"
},
{
"font_class": "staff",
"unicode": "\ue6a7"
},
{
"font_class": "staff-filled",
"unicode": "\ue6cb"
},
{
"font_class": "star",
"unicode": "\ue688"
},
{
"font_class": "star-filled",
"unicode": "\ue68f"
},
{
"font_class": "starhalf",
"unicode": "\ue683"
},
{
"font_class": "trash",
"unicode": "\ue687"
},
{
"font_class": "trash-filled",
"unicode": "\ue685"
},
{
"font_class": "tune",
"unicode": "\ue6aa"
},
{
"font_class": "tune-filled",
"unicode": "\ue6ca"
},
{
"font_class": "undo",
"unicode": "\ue64f"
},
{
"font_class": "undo-filled",
"unicode": "\ue64c"
},
{
"font_class": "up",
"unicode": "\ue6b6"
},
{
"font_class": "top",
"unicode": "\ue6b6"
},
{
"font_class": "upload",
"unicode": "\ue690"
},
{
"font_class": "upload-filled",
"unicode": "\ue68e"
},
{
"font_class": "videocam",
"unicode": "\ue68c"
},
{
"font_class": "videocam-filled",
"unicode": "\ue689"
},
{
"font_class": "vip",
"unicode": "\ue6a8"
},
{
"font_class": "vip-filled",
"unicode": "\ue6c6"
},
{
"font_class": "wallet",
"unicode": "\ue6b1"
},
{
"font_class": "wallet-filled",
"unicode": "\ue6c2"
},
{
"font_class": "weibo",
"unicode": "\ue68b"
},
{
"font_class": "weixin",
"unicode": "\ue691"
}
]
// export const fontData = JSON.parse<IconsDataItem>(fontDataJson)

89
uni_modules/uni-icons/package.json

@ -0,0 +1,89 @@
{
"id": "uni-icons",
"displayName": "uni-icons 图标",
"version": "2.0.10",
"description": "图标组件,用于展示移动端常见的图标,可自定义颜色、大小。",
"keywords": [
"uni-ui",
"uniui",
"icon",
"图标"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": "^3.2.14"
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
"type": "component-vue"
},
"uni_modules": {
"dependencies": ["uni-scss"],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y",
"alipay": "n"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y",
"app-uvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y",
"钉钉": "y",
"快手": "y",
"飞书": "y",
"京东": "y"
},
"快应用": {
"华为": "y",
"联盟": "y"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}

8
uni_modules/uni-icons/readme.md

@ -0,0 +1,8 @@
## Icons 图标
> **组件名:uni-icons**
> 代码块: `uIcons`
用于展示 icons 图标 。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-icons)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
Loading…
Cancel
Save