提交 8a1bd9c62f297819bb40deb1422fd1df18739b11

作者 genglw
2 个父辈 a7c26e7a 1b85bcf9

Merge branch 'developer/yxly-teacher-genglw-20220713' into develop

正在显示 94 个修改的文件 包含 12028 行增加529 行删除
... ... @@ -66,10 +66,10 @@ export default {
66 66 this.page++;
67 67
68 68 await this._getList();
69   -
70   -
  69 +
  70 + console.log(this.total, this.list.length)
71 71 // 判断是否全部加载完成
72   - if (this.total == 0) {
  72 + if (this.total == this.list.length) {
73 73 this.finished = true;
74 74 this.loading = 'nomore';
75 75 } else {
... ...
1 1 <template>
2 2 <view class="u-button">
3   - <u-button :text="text" color="#0CB17A" :plain="false" :hairline="false" :disabled="disabled" :throttleTime="1500"
4   - type="info" shape="circle" :open-type="openType" @getphonenumber="getPhoneNumber"
  3 + <u-button :text="text" :color="reversedColor" :plain="false" :hairline="false" :disabled="disabled"
  4 + :throttleTime="1500" type="default" :open-type="openType" @getphonenumber="getPhoneNumber"
5 5 :custom-style="getCustomStyle" @click="click">
6 6 </u-button>
7 7 </view>
... ... @@ -38,51 +38,70 @@
38 38 default: ''
39 39 },
40 40
  41 +
41 42 },
42 43 data() {
43 44 return {}
44 45 },
45 46
46   - watch: {
47   - buttonType: function(newVal, oldVal) {
  47 + computed: {
  48 + getCustomStyle() {
  49 +
  50 + const {
  51 + type = ''
  52 + } = this;
  53 +
  54 + let style = {};
  55 +
  56 + switch (type) {
  57 + case 'confirm':
  58 + return Object.assign({}, {
  59 + border: 'none',
  60 + color: '#FFFFFF',
  61 + }, this.customStyle);
  62 + break;
  63 +
  64 + case 'cancel':
  65 + return Object.assign({}, {
  66 + border: 'none',
  67 + color: 'rgba(0, 0, 0, 0.4500)',
  68 + }, this.customStyle);
  69 + break;
  70 + }
  71 + },
  72 +
  73 + reversedColor() {
  74 +
  75 + let color = '#0CB17A';
  76 +
48 77 switch (this.type) {
49 78 case 'confirm':
50   - this.color = "#0CB17A";
  79 + color = "#0CB17A";
  80 + break;
  81 +
  82 + case 'cancel':
  83 + color = "rgba(0, 0, 0, 0.0600)";
51 84 break;
52 85 }
  86 +
  87 + return color;
53 88 }
54 89 },
55 90
56   - computed: {
57   - // getCustomStyle() {
58   -
59   - // const {
60   - // type = ''
61   - // } = this;
62   -
63   - // let style = {};
64   -
65   - // switch (type) {
66   - // case 'confirm':
67   - // return Object.assign({}, {
68   - // backgroundColor: '#FF001A',
69   - // borderRadius: '8rpx',
70   - // }, this.customStyle);
71   - // break;
72   -
73   - // case 'cancel':
74   - // return Object.assign({}, {
75   - // backgroundColor: "rgba(0,0,0,0.15)",
76   - // borderRadius: '8rpx',
77   - // }, this.customStyle);
78   - // break;
79   -
80   - // case 'custom':
81   - // return Object.assign({}, this.customStyle);
82   - // break;
83   - // }
84   - // }
85   - },
  91 + // watch: {
  92 + // buttonType: function(newVal, oldVal) {
  93 + // switch (this.type) {
  94 + // case 'confirm':
  95 + // this.color = "#0CB17A";
  96 + // break;
  97 +
  98 + // case 'cancel':
  99 + // this.color = "#0CB17A";
  100 + // break;
  101 + // }
  102 + // }
  103 + // },
  104 +
86 105 methods: {
87 106 // 按钮点击
88 107 click(e) {
... ... @@ -97,5 +116,8 @@
97 116 </script>
98 117
99 118 <style lang="scss">
100   -
  119 + .u-button /deep/ .u-button {
  120 + border: nones;
  121 + border-radius: 8rpx;
  122 + }
101 123 </style>
... ...
1 1 <template>
2 2 <view class="m-loading">
3   - <u-loadmore :status="loading" :icon="icon" :loadText="loadText" bgColor="#F7F7F7" marginTop='12rpx' marginBottom='12rpx'></u-loadmore>
  3 + <u-loadmore :status="loading" :line="true" bgColor="#F7F7F7" fontSize="28rpx" iconSize="34rpx"></u-loadmore>
4 4 </view>
5 5 </template>
6 6
... ... @@ -10,21 +10,7 @@
10 10 loading: {
11 11 type: String,
12 12 default: 'loadmore'
13   - },
14   - icon: {
15   - type: Boolean,
16   - default: true
17   - },
18   - loadText: {
19   - type: Object,
20   - default () {
21   - return {
22   - loadmore: '点击或上拉加载更多',
23   - loading: '正在加载',
24   - nomore: '没有更多了'
25   - }
26   - }
27   - }
  13 + },
28 14 },
29 15 data() {
30 16 return {};
... ...
1 1 <template>
2   - <view class="c-no-data" :style="[wrapStyle]" >
  2 + <view class="c-no-data" :style="[wrapStyle]">
3 3 <view class="image">
4   - <u-image :src="vuex_baseImgUrl+'/nodata.png'" width="260rpx" height="200rpx"></u-image>
  4 + <u-image :src="vuex_baseImgUrl+'/no_data.png'" width="480rpx" height="480rpx"></u-image>
5 5 </view>
6   - <view class="title">{{ title }}</view>
  6 + <view class="title" :style="[topStyle]">{{ title }}</view>
7 7 </view>
8 8 </template>
9 9
... ... @@ -19,10 +19,10 @@
19 19 title: {
20 20 type: String,
21 21 default: '暂无数据'
22   - },
23   - paddingTop: {
24   - type: String,
25   - default: "180rpx"
  22 + },
  23 + paddingTop: {
  24 + type: String,
  25 + default: "180"
26 26 },
27 27 },
28 28 data() {
... ... @@ -34,14 +34,21 @@
34 34
35 35 },
36 36 computed: {
37   - wrapStyle() {
38   - let style = {};
39   - style.paddingTop = this.paddingTop
40   - return style;
  37 + wrapStyle() {
  38 + let style = {};
  39 + style.paddingTop = this.paddingTop + 'rpx';
  40 + return style;
  41 + },
  42 +
  43 + topStyle() {
  44 + let style = {};
  45 + style.top = (Number(this.paddingTop) + 360) + 'rpx';
  46 + return style;
41 47 },
  48 +
42 49 },
43 50 methods: {
44   -
  51 +
45 52
46 53 }
47 54 };
... ... @@ -50,18 +57,22 @@
50 57 <style scoped lang="scss">
51 58 .c-no-data {
52 59 width: 100%;
  60 + position: relative;
53 61
54 62 .image {
55   - width: 260rpx;
  63 + width: 480rpx;
56 64 margin: 0 auto;
57 65 }
58 66
59 67 .title {
60   - margin: 48rpx 0 0 0;
  68 + width: 100%;
  69 + position: absolute;
  70 + top: 560rpx;
  71 + left: 0rpx;
61 72 text-align: center;
62   - font-size: 28rpx;
63   - line-height: 40rpx;
64   - color: #000000;
  73 + font-size: 24rpx;
  74 + line-height: 52rpx;
  75 + color: #909097;
65 76 }
66 77 }
67 78 </style>
... ...
1 1 const http = uni.$u.http
2 2
  3 +// 获取oss对应的图片地址
  4 +export const getImgUrlApi = (params) => http.get('/basic/v1/oss/sign_url', {
  5 + params: params
  6 +})
  7 +
  8 +// OssInit初始化
  9 +export const getOssInitApi = (params) => http.get('/basic/v1/oss/policy', {
  10 + params: params
  11 +})
  12 +
3 13 // 获取token
4   -export const postTokenApi = (params, config = {}) => http.post('/auth/v1/login', params, config)
  14 +export const postTokenApi = (params, config = {}) => http.post('/auth/v1/login', params, config).then(res => {
  15 + console.log(res)
  16 +
  17 + return res;
  18 +})
5 19
6 20 // 获取用户信息
7   -export const getUserInfoApi = (data) => http.get('/user/v1/detail', {
8   - params: data
  21 +export const getUserInfoApi = (params) => http.get('/user/v1/detail', {
  22 + params: params
9 23 })
10 24
11 25 // 获取短信验证码
12   -export const getSmsCodeApi = (data) => http.get('/basic/v1/sms_code/get', {
13   - params: data
  26 +export const getSmsCodeApi = (params) => http.get('/basic/v1/sms_code/get', {
  27 + params: params
  28 +})
  29 +
  30 +// 更新用户信息
  31 +export const updateUserInfoApi = (params) => http.put('/user/v1/update', params);
  32 +
  33 +//注销账户
  34 +export const delAccountApi = (params) => http.delete('/user/v1/annuluser', params);
  35 +
  36 +//撤销注销账户
  37 +export const cancelDelAccountApi = (params) => http.put('/user/v1/annulusercancel', params);
  38 +
  39 +// 更新老师头像
  40 +export const updateAvatarUrlApi = (params) => http.put('/user/v1/teacher/update_avatar_url', params);
  41 +
  42 +// 学校列表
  43 +export const getSchoolListApi = (params) => http.get('/user/v1/schoolList', {
  44 + params: params
  45 +})
  46 +
  47 +// 切换老师身份
  48 +export const putTeacherRolesApi = (id, params) => http.put(`/user/v1/teacher/${id}/change_role`, params);
  49 +
  50 +// 待办事项统计
  51 +export const getTodoListStatisticsApi = (params) => http.get('/internship/v1/index/applet/waitHandleList', {
  52 + params: params
  53 +})
  54 +
  55 +// 实习项目列表
  56 +export const getProjectListApi = (params) => http.get('/internship/v1/project/simpleList', {
  57 + params: params
  58 +})
  59 +
  60 +// 报名审核列表
  61 +export const getRegistrationReviewApi = (params) => http.get('/internship/v1/entry/list', {
  62 + params: params
  63 +})
  64 +
  65 +//报名审核详情
  66 +export const getRegistrationDetailApi = (id, params) => http.get(`/internship/v1/entry/detail/${id}`, {
  67 + params: params
  68 +})
  69 +
  70 +// 报名审核
  71 +export const putRegistrationReviewApi = (params) => http.put(`/internship/v1/entry/audit`, params);
  72 +
  73 +// 学生签到列表
  74 +export const getStudentSignInListApi = (params) => http.get('/internship/v1/attendance/applet/list', {
  75 + params: params
  76 +})
  77 +
  78 +// 日志批阅列表
  79 +export const getLogReviewListApi = (params) => http.get('/internship/v1/form_log/school/list', {
  80 + params: params
  81 +})
  82 +
  83 +// 实习日志详情
  84 +export const getLogDetailApi = (id, params) => http.get(`/internship/v1/form_log/detail/${id}`, {
  85 + params: params
  86 +})
  87 +
  88 +// 日志批阅
  89 +export const putLogReviewApi = (params) => http.put(`/internship/v1/form_log/approve`, params);
  90 +
  91 +// 日志回复列表
  92 +export const getLogReplyListApi = (params) => http.get('/internship/v1/form_log_review/list', {
  93 + params: params
  94 +})
  95 +
  96 +// 创建日志回复
  97 +export const postLogReplyApi = (params) => http.post(`/internship/v1/form_log_review/save`, params);
  98 +
  99 +// 报告批阅列表
  100 +export const getReportReviewListApi = (params) => http.get('/internship/v1/report/list', {
  101 + params: params
  102 +})
  103 +
  104 +// 实习报告详情
  105 +export const getReportDetailApi = (id, params) => http.get(`/internship/v1/report/detail_by_student/${id}`, {
  106 + params: params
  107 +})
  108 +
  109 +//报告批阅
  110 +export const putReportReviewApi = (id, params) => http.put(`/internship/v1/report/examine/${id}`, params);
  111 +
  112 +//审批记录
  113 +export const getReportApprovalListApi = (formId, params) => http.get(`/internship/v1/report/examine_list/${formId}`, {
  114 + params: params
  115 +})
  116 +
  117 +// 成绩鉴定列表
  118 +export const getAchievementAppraisalListApi = (params) => http.get('/internship/v1/form/achievementAppraisalList', {
  119 + params: params
  120 +})
  121 +
  122 +// 成绩鉴定详情
  123 +export const getAchievementDetailApi = (id, params) => http.get(
  124 + `/internship/v1/form/achievementAppraisalDetail/${id}`, {
  125 + params: params
  126 + })
  127 +
  128 +//成绩鉴定
  129 +export const putAchievementAppraisalApi = (params) => http.post(`/internship/v1/form/evaluate`, params);
  130 +
  131 +// 班级列表
  132 +export const getClassListApi = (params) => http.get('/internship/v1/form/listByTeacherApplet', {
  133 + params: params
  134 +})
  135 +
  136 +// 学生列表
  137 +export const getStudentListApi = (params) => http.get('/internship/v1/form/traineeList', {
  138 + params: params
  139 +})
  140 +
  141 +//实习过程详情
  142 +export const getInternshipProcessDetailApi = (params) => http.get(`/internship/v1/form/internshipProcess`, {
  143 + params: params
  144 +})
  145 +
  146 +// 三方协议列表
  147 +export const getAgreementListApi = (params) => http.get('/internship/v1/treaty/list_by_school', {
  148 + params: params
  149 +})
  150 +
  151 +//三方协议详情
  152 +export const getAgreementDetailApi = (id, params) => http.get(`/internship/v1/treaty/detail/${id}`, {
  153 + params: params
  154 +})
  155 +
  156 +//签到列表
  157 +export const getsignInListApi = (params) => http.get('/internship/v1/attendance/applet/monthAttendanceList', {
  158 + params: params
  159 +})
  160 +
  161 +// 实习岗位列表
  162 +export const getInternshipJobListApi = (params) => http.get('/internship/v1/form/internshipJob', {
  163 + params: params
  164 +})
  165 +
  166 +// 实践课程列表
  167 +export const getPracticalCoursesListApi = (params) => http.get('/internship/v1/form/internshipCourse', {
  168 + params: params
  169 +})
  170 +
  171 +//实习单详情
  172 +export const getInternshipDetailApi = (id, params) => http.get(`/internship/v1/form/detail/${id}`, {
  173 + params: params
14 174 })
  175 +
  176 +
  177 +
... ...
... ... @@ -5,9 +5,11 @@ module.exports = (vm) => {
5 5 /* config 为默认全局配置*/
6 6
7 7 // 测试环境
8   - config.baseURL = "http://39.104.52.206:8000";
  8 + config.baseURL = "http://47.110.250.177:8000";
  9 +
9 10 // 预生产环境
10   - // config.baseURL = "https://api-isxpre.workai.com.cn";
  11 + // config.baseURL = "https://api-isxpre.workai.com.cn";
  12 +
11 13 // 线上环境
12 14 // config.baseURL = "https://api-isx.workai.com.cn";
13 15
... ... @@ -68,15 +70,17 @@ module.exports = (vm) => {
68 70
69 71 // 响应拦截
70 72 uni.$u.http.interceptors.response.use((response) => {
  73 +
71 74 /* 对响应成功做点什么 可使用async await 做异步操作*/
72 75 const data = response.data
73 76
74 77 // 自定义参数
75 78 const custom = response.config?.custom
76 79 if (data.code !== 200) {
  80 +
77 81 // 如果没有显式定义custom的toast参数为false的话,默认对报错进行toast弹出提示
78 82 if (custom.toast !== false) {
79   - uni.$u.toast(data.message)
  83 + uni.$u.toast(data.msg)
80 84 }
81 85
82 86 // 如果需要catch返回,则进行reject
... ... @@ -88,8 +92,26 @@ module.exports = (vm) => {
88 92 }
89 93 }
90 94 return data.data === undefined ? {} : data.data
  95 +
91 96 }, (response) => {
92 97 // 对响应错误做点什么 (statusCode !== 200)
  98 + console.log(response)
  99 +
  100 + if (response.statusCode == 401) {
  101 + // 假设401为token失效,这里跳转登录
  102 + vm.$u.toast('登录失效,请重新登录!');
  103 + setTimeout(() => {
  104 + // 此为uView的方法,详见路由相关文档
  105 + // vm.$u.route('/pages/main/my/login/login');
  106 +
  107 + vm.$u.vuex('hasLogin', false);
  108 + vm.$u.vuex('vuex_token', '');
  109 +
  110 + }, 1500)
  111 + return false;
  112 +
  113 + }
  114 +
93 115 return Promise.reject(response)
94 116 })
95 117 }
... ...
1 1 {
2   - "name" : "job-sharing",
  2 + "name" : "yxly-teacher",
3 3 "appid" : "__UNI__C6035C1",
4 4 "description" : "多平台快速开发的UI框架",
5 5 "versionName" : "1.8.5",
... ... @@ -102,7 +102,7 @@
102 102 },
103 103 "quickapp" : {},
104 104 "mp-weixin" : {
105   - "appid" : "wx84b71301436652ce",
  105 + "appid" : "wx6cd2152282abd34c",
106 106 "setting" : {
107 107 "urlCheck" : false,
108 108 "es6" : true,
... ...
... ... @@ -7,23 +7,23 @@
7 7 "current": 0, //当前激活的模式(list 的索引项)
8 8 "list": [{
9 9 "name": "defult", //模式名称
10   - "path": "pages/main/my/mobileLogin/mobileLogin",
11   - "query": ""
  10 + "path": "pages/main/internship/signInList/signInList",
  11 + "query": "studentId=1555434161240838146"
12 12 }]
13 13 },
14 14 "pages": [{
15 15 "path": "pages/tabBar/home/home",
16   - "style": {
17   - "navigationBarTitleText": "人人推",
18   - "navigationBarTextStyle": "black",
19   - "enablePullDownRefresh": false
  16 + "style": {
  17 + "navigationStyle": "custom",
  18 + "navigationBarTitleText": ""
20 19 }
21 20 },
22 21 {
23 22 "path": "pages/tabBar/internship/internship",
24 23 "style": {
25   - "navigationStyle": "custom",
26   - "navigationBarTitleText": ""
  24 + "navigationBarTitleText": "我的实习生",
  25 + "navigationBarTextStyle": "black",
  26 + "enablePullDownRefresh": false
27 27 }
28 28 },
29 29 {
... ... @@ -34,26 +34,268 @@
34 34 }
35 35 }
36 36 ],
  37 +
37 38 "subPackages": [{
38   - "root": "pages/main/my",
39   - "pages": [{
40   - "path": "login/login",
  39 + "root": "pages/main/home",
  40 + "pages": [
  41 +
  42 + {
  43 + "path": "registrationReview/registrationReview",
  44 + "style": {
  45 + "navigationBarTitleText": "报名审核",
  46 + "enablePullDownRefresh": false
  47 + }
  48 +
  49 + }, {
  50 + "path": "registrationDetail/registrationDetail",
  51 + "style": {
  52 + "navigationBarTitleText": "报名详情",
  53 + "enablePullDownRefresh": false
  54 + }
  55 +
  56 + }, {
  57 + "path": "studentSignIn/studentSignIn",
  58 + "style": {
  59 + "navigationBarTitleText": "学生签到",
  60 + "enablePullDownRefresh": false
  61 + }
  62 +
  63 + }, {
  64 + "path": "logReview/logReview",
  65 + "style": {
  66 + "navigationBarTitleText": "日志批阅",
  67 + "enablePullDownRefresh": false
  68 + }
  69 +
  70 + }, {
  71 + "path": "logDetail/logDetail",
  72 + "style": {
  73 + "navigationBarTitleText": "日志详情",
  74 + "enablePullDownRefresh": false
  75 + }
  76 +
  77 + }, {
  78 + "path": "reportReview/reportReview",
  79 + "style": {
  80 + "navigationBarTitleText": "报告批阅",
  81 + "enablePullDownRefresh": false
  82 + }
  83 +
  84 + }, {
  85 + "path": "reportDetail/reportDetail",
  86 + "style": {
  87 + "navigationBarTitleText": "报告详情",
  88 + "enablePullDownRefresh": false
  89 + }
  90 +
  91 + }, {
  92 + "path": "approvalRecord/approvalRecord",
  93 + "style": {
  94 + "navigationBarTitleText": "审批记录",
  95 + "enablePullDownRefresh": false
  96 + }
  97 +
  98 + }, {
  99 + "path": "achievementAppraisal/achievementAppraisal",
  100 + "style": {
  101 + "navigationBarTitleText": "成绩鉴定",
  102 + "enablePullDownRefresh": false
  103 + }
  104 +
  105 + }, {
  106 + "path": "achievementDetail/achievementDetail",
  107 + "style": {
  108 + "navigationBarTitleText": "鉴定详情",
  109 + "enablePullDownRefresh": false
  110 + }
  111 +
  112 + }
  113 + ]
  114 + },
  115 + {
  116 + "root": "pages/main/internship",
  117 + "pages": [{
  118 + "path": "studentList/studentList",
41 119 "style": {
42   - "navigationBarTitleText": "登录",
  120 + "navigationBarTitleText": "实习生列表",
43 121 "enablePullDownRefresh": false
44 122 }
45 123
46   - },
47   - {
48   - "path": "mobileLogin/mobileLogin",
  124 + }, {
  125 + "path": "traineeDetail/traineeDetail",
49 126 "style": {
50   - "navigationBarTitleText": "手机登录",
  127 + "navigationBarTitleText": "学生信息",
51 128 "enablePullDownRefresh": false
52 129 }
53 130
54   - }
55   - ]
56   - }],
  131 + } ,{
  132 + "path" : "agreementList/agreementList",
  133 + "style" :
  134 + {
  135 + "navigationBarTitleText": "三方协议",
  136 + "enablePullDownRefresh": false
  137 + }
  138 +
  139 + }
  140 + ,{
  141 + "path" : "agreementDetail/agreementDetail",
  142 + "style" :
  143 + {
  144 + "navigationBarTitleText": "协议详情",
  145 + "enablePullDownRefresh": false
  146 + }
  147 +
  148 + }
  149 + ,{
  150 + "path" : "signInList/signInList",
  151 + "style" :
  152 + {
  153 + "navigationBarTitleText": "签到",
  154 + "enablePullDownRefresh": false
  155 + }
  156 +
  157 + }
  158 + ,{
  159 + "path" : "intershipInfo/intershipInfo",
  160 + "style" :
  161 + {
  162 + "navigationBarTitleText": "实习单详情",
  163 + "enablePullDownRefresh": false
  164 + }
  165 +
  166 + }
  167 + ,{
  168 + "path" : "achievementDetail/achievementDetail",
  169 + "style" :
  170 + {
  171 + "navigationBarTitleText": "成绩详情",
  172 + "enablePullDownRefresh": false
  173 + }
  174 +
  175 + }
  176 + ,{
  177 + "path" : "studentLogReview/studentLogReview",
  178 + "style" :
  179 + {
  180 + "navigationBarTitleText": "",
  181 + "enablePullDownRefresh": false
  182 + }
  183 +
  184 + }
  185 + ]
  186 + },
  187 + {
  188 + "root": "pages/main/my",
  189 + "pages": [{
  190 + "path": "login/login",
  191 + "style": {
  192 + "navigationBarTitleText": "登录",
  193 + "enablePullDownRefresh": false
  194 + }
  195 +
  196 + },
  197 + {
  198 + "path": "mobileLogin/mobileLogin",
  199 + "style": {
  200 + "navigationBarTitleText": "手机登录",
  201 + "enablePullDownRefresh": false
  202 + }
  203 +
  204 + }, {
  205 + "path": "accountSafe/accountSafe",
  206 + "style": {
  207 + "navigationBarTitleText": "账号与安全",
  208 + "enablePullDownRefresh": false
  209 + }
  210 +
  211 + }, {
  212 + "path": "editAccount/editAccount",
  213 + "style": {
  214 + "navigationBarTitleText": "修改账号",
  215 + "enablePullDownRefresh": false
  216 + }
  217 +
  218 + }, {
  219 + "path": "editMobile/editMobile",
  220 + "style": {
  221 + "navigationBarTitleText": "修改手机号",
  222 + "enablePullDownRefresh": false
  223 + }
  224 +
  225 + }, {
  226 + "path": "editPassword/editPassword",
  227 + "style": {
  228 + "navigationBarTitleText": "修改密码",
  229 + "enablePullDownRefresh": false
  230 + }
  231 +
  232 + }, {
  233 + "path": "removeAccount/removeAccount",
  234 + "style": {
  235 + "navigationBarTitleText": "注销账户",
  236 + "enablePullDownRefresh": false
  237 + }
  238 +
  239 + }, {
  240 + "path": "againRemove/againRemove",
  241 + "style": {
  242 + "navigationBarTitleText": "注销账户",
  243 + "enablePullDownRefresh": false
  244 + }
  245 +
  246 + }, {
  247 + "path": "freezing/freezing",
  248 + "style": {
  249 + "navigationBarTitleText": "",
  250 + "enablePullDownRefresh": false
  251 + }
  252 +
  253 + }, {
  254 + "path": "writtenOff/writtenOff",
  255 + "style": {
  256 + "navigationBarTitleText": "",
  257 + "enablePullDownRefresh": false
  258 + }
  259 +
  260 + }, {
  261 + "path": "policiesAgreement/policiesAgreement",
  262 + "style": {
  263 + "navigationBarTitleText": "政策与协议",
  264 + "enablePullDownRefresh": false
  265 + }
  266 +
  267 + }, {
  268 + "path": "agreement/agreement",
  269 + "style": {
  270 + "navigationBarTitleText": "隐私协议",
  271 + "enablePullDownRefresh": false
  272 + }
  273 +
  274 + }, {
  275 + "path": "userPolicy/userPolicy",
  276 + "style": {
  277 + "navigationBarTitleText": "用户政策",
  278 + "enablePullDownRefresh": false
  279 + }
  280 +
  281 + }, {
  282 + "path": "versionInfo/versionInfo",
  283 + "style": {
  284 + "navigationBarTitleText": "版本信息",
  285 + "enablePullDownRefresh": false
  286 + }
  287 +
  288 + }, {
  289 + "path": "personInfo/personInfo",
  290 + "style": {
  291 + "navigationBarTitleText": "个人信息",
  292 + "enablePullDownRefresh": false
  293 + }
  294 +
  295 + }
  296 + ]
  297 + }
  298 + ],
57 299
58 300 "preloadRule": {
59 301
... ... @@ -69,7 +311,7 @@
69 311
70 312 "tabBar": {
71 313 "color": "#000000",
72   - "selectedColor": "#F64114",
  314 + "selectedColor": "#06B079",
73 315 "backgroundColor": "#FFFFFF",
74 316 "borderStyle": "black",
75 317 "height": "100rpx",
... ... @@ -82,8 +324,8 @@
82 324 },
83 325 {
84 326 "pagePath": "pages/tabBar/internship/internship",
85   - "iconPath": "/static/img/icon/position.png",
86   - "selectedIconPath": "/static/img/icon/positionHL.png",
  327 + "iconPath": "/static/img/icon/internship.png",
  328 + "selectedIconPath": "/static/img/icon/internshipHL.png",
87 329 "text": "实习"
88 330 },
89 331 {
... ...
  1 +<template>
  2 + <view class="registration_review">
  3 + <view class="search_box">
  4 + <view class="top">
  5 + <view class="check">
  6 + <u-checkbox-group v-model="checkboxValue" placement="column" @change="checkboxChange">
  7 + <u-checkbox :customStyle="{marginBottom: '8px'}" shape="circle"
  8 + v-for="(item, index) in checkboxList" :key="index" :label="item.name" :name="item.name"
  9 + activeColor="#06B079" size="28rpx" labelSize="28rpx" labelColor="#202131">
  10 + </u-checkbox>
  11 + </u-checkbox-group>
  12 + </view>
  13 +
  14 + <view class="search">
  15 + <u-search placeholder="请输入学生姓名/学号/手机号" placeholderColor="#C1C1C9" searchIconSize="36" height="64rpx"
  16 + bgColor="#F4F4F4" :showAction="false" shape="square" v-model="keyword" @search="handelSearch">
  17 + </u-search>
  18 + </view>
  19 +
  20 + <u-icon slot="icon" size="40" :name="'/static/img/home/selectIcon.png'" @click="show = true"></u-icon>
  21 + </view>
  22 + </view>
  23 +
  24 + <view class="list_box" v-if="list.length > 0">
  25 + <view class="item" v-for="(item, i) in list" :key="i" @click="handelDetail(item)">
  26 +
  27 + <view class="bg_image" v-if="item.appraisalStatus == 'no_appraisal'">
  28 + <u-image src="/static/img/home/labelBgGreen.png" width="142rpx" height="48rpx"></u-image>
  29 + <text>待鉴定</text>
  30 + </view>
  31 +
  32 + <view class="bg_image" v-else>
  33 + <u-image src="/static/img/home/labelBgGrey.png" width="142rpx" height="48rpx"></u-image>
  34 + <text>已鉴定</text>
  35 + </view>
  36 +
  37 + <view class="info">
  38 + <view class="avatar">{{getNameLastTwo(item.studentName)}}</view>
  39 + <view class="name">{{overflowHide(item.studentName, 6)}}</view>
  40 + <view class="number">NO.{{item.studentNumber}}</view>
  41 + </view>
  42 + <view class="company">
  43 + <text>实习单号</text>
  44 + <text>{{item.number || '--'}}</text>
  45 + </view>
  46 + <view class="company position">
  47 + <text>实习项目</text>
  48 + <text>{{item.projectName|| '--'}}</text>
  49 + </view>
  50 +
  51 + <view class="statistics">
  52 + <view>
  53 + <text>{{item.uploadCount|| 0}}</text>
  54 + <text>三方协议</text>
  55 + </view>
  56 + <view class="line"></view>
  57 + <view>
  58 + <text>{{item.weekLogCount|| 0}}</text>
  59 + <text>周日志</text>
  60 + </view>
  61 + <view class="line"></view>
  62 + <view>
  63 + <text>{{item.internshipReportCount|| 0}}</text>
  64 + <text>实习报告</text>
  65 + </view>
  66 + <view class="line"></view>
  67 + <view>
  68 + <text>{{item.attendanceCount|| 0}}</text>
  69 + <text>签到</text>
  70 + </view>
  71 + </view>
  72 +
  73 + </view>
  74 + <c-loading :loading="loading"></c-loading>
  75 + </view>
  76 + <view v-else class="no_data">
  77 + <c-no-data></c-no-data>
  78 + </view>
  79 +
  80 + <u-popup :show="show" mode="right" @close="close" @open="open" :closeOnClickOverlay="false">
  81 + <view class="popup_search">
  82 + <view class="content">
  83 + <view class="title">按项目筛选</view>
  84 + <scroll-view class="scroll" scroll-y="true">
  85 + <view class="item" v-for="(item, i) in projectList" :key="i" @click="handelClick(item)">
  86 + <view class="selectItem" v-if="item.id == projectId">
  87 + <text>{{item.name}}</text>
  88 + </view>
  89 + <view v-else>
  90 + <text>{{item.name}}</text>
  91 + </view>
  92 + </view>
  93 + </scroll-view>
  94 + <view class="switch">
  95 + <text>待鉴定</text>
  96 + <u-switch v-model="switchValue" size="48" activeColor="#06B079" @change="handelChange">
  97 + </u-switch>
  98 + </view>
  99 + </view>
  100 +
  101 + <view class="footer">
  102 + <view class="left_btn">
  103 + <c-button type="cancel" text="重置" @click="handelCancel">
  104 + </c-button>
  105 + </view>
  106 + <view class="right_btn">
  107 + <c-button type="confirm" text="确定" @click="hancelSubmit">
  108 + </c-button>
  109 + </view>
  110 + </view>
  111 +
  112 + </view>
  113 + </u-popup>
  114 +
  115 + </view>
  116 +</template>
  117 +
  118 +<script>
  119 + import {
  120 + mapGetters,
  121 + mapState,
  122 + mapActions
  123 + } from 'vuex'
  124 + import listMixin from "@/common/mixins/list-mixin.js";
  125 +
  126 + import {
  127 + getAchievementAppraisalListApi,
  128 + getProjectListApi,
  129 + } from '@/config/api.js';
  130 +
  131 + export default {
  132 + mixins: [listMixin],
  133 + data() {
  134 +
  135 + const d = new Date();
  136 + const year = d.getFullYear();
  137 + let month = d.getMonth() + 1;
  138 + month = month < 10 ? `0${month}` : month;
  139 + const date = d.getDate();
  140 +
  141 + return {
  142 + checkboxValue: [],
  143 + // 基本案列数据
  144 + checkboxList: [{
  145 + name: '待鉴定',
  146 + disabled: false
  147 + }],
  148 + keyword: '',
  149 + show: false,
  150 + search: {
  151 + //搜索对象必须为key search的对象
  152 + keySearch: "",
  153 + appraisalStatus: '',
  154 +
  155 + },
  156 + showTime: false,
  157 + timeValue: `${year}-${month}-${date}`,
  158 + defaultDateMultiple: [`${year}-${month}-${date}`],
  159 + list: [], //列表必须为key list的数组
  160 + projectId: '',
  161 + switchValue: false,
  162 +
  163 + }
  164 + },
  165 +
  166 + onLoad(option) {
  167 + this.$store.dispatch(`home/getProjectList`, {
  168 + pageSize: -1,
  169 + })
  170 +
  171 + this.search.keySearch = '';
  172 +
  173 + if (option && option.appraisalStatus) {
  174 + this.search.appraisalStatus = 'no_appraisal';
  175 + this.checkboxValue = ['待鉴定'];
  176 + this.switchValue = true;
  177 + }
  178 +
  179 + this.finished = false;
  180 + this.loading = "loadmore";
  181 + this.page = 0;
  182 + this.list = [];
  183 + },
  184 +
  185 + onShow() {
  186 + this._getList();
  187 + },
  188 +
  189 + computed: {
  190 + ...mapState('home', {
  191 + // 箭头函数可使代码更简练
  192 + projectList: 'projectList',
  193 +
  194 + }),
  195 +
  196 + },
  197 +
  198 + methods: {
  199 +
  200 + getNameLastTwo(value) {
  201 + if (value && value.length > 3) {
  202 + return value.substring(value.length - 3)
  203 + } else {
  204 + return value;
  205 + }
  206 + },
  207 +
  208 + overflowHide(value, num = 4) {
  209 + if (value && value.length > num) {
  210 + return `${value.slice(0, num)}...`
  211 + } else {
  212 + return value;
  213 + }
  214 + },
  215 +
  216 + confirm(e) {
  217 + this.timeValue = e[0];
  218 + this.showTime = false;
  219 + },
  220 +
  221 + handelDetail(record) {
  222 + this.$u.route({
  223 + url: `pages/main/home/achievementDetail/achievementDetail?&id=${record.id}`
  224 + })
  225 + },
  226 +
  227 + timeFormat(timestamp, format = 'yyyy-mm-dd') {
  228 + return timestamp > 0 ? uni.$u.timeFormat(timestamp, format) : '--'
  229 + },
  230 +
  231 + checkboxChange(n) {
  232 + console.log('change', n);
  233 +
  234 + this.search.appraisalStatus = n.length > 0 ? 'no_appraisal' : '';
  235 +
  236 + this.switchValue = n.length > 0 ? true : false;
  237 +
  238 + this.finished = false;
  239 + this.loading = "loadmore";
  240 + this.page = 0;
  241 + this.list = [];
  242 + this._getList();
  243 + },
  244 +
  245 + handelSearch(value) {
  246 + this.finished = false;
  247 + this.loading = "loadmore";
  248 + this.page = 0;
  249 + this.list = [];
  250 + this._getList();
  251 + },
  252 +
  253 + open() {
  254 + // console.log('open');
  255 + },
  256 + close() {
  257 + this.show = false
  258 + // console.log('close');
  259 + },
  260 + // scroll-view到底部加载更多
  261 + onreachBottom() {},
  262 + // 搜索
  263 + searchSubmit() {
  264 + // 调用混合搜索
  265 + this._searchData();
  266 + },
  267 + // 模拟后端分页
  268 + async getData(requestParams) {
  269 + const {
  270 + search = {}
  271 + } = requestParams;
  272 +
  273 + let params = {};
  274 + params.pageNumber = requestParams.page + 1;
  275 + params.pageSize = 5;
  276 +
  277 + if (search.appraisalStatus) {
  278 + params.appraisalStatus = search.appraisalStatus;
  279 + }
  280 +
  281 + if (this.keyword) {
  282 + params.keySearch = this.keyword
  283 + }
  284 +
  285 + if (this.projectId) {
  286 + params.projectId = this.projectId
  287 + }
  288 +
  289 + return await getAchievementAppraisalListApi(params);
  290 + },
  291 + // 数据请求(没错就是这么少的代码)
  292 + async _getList() {
  293 + if (this.page == 0) {
  294 + this.list = [];
  295 + }
  296 +
  297 + // 根据实际情况修改自己修改key
  298 + let result = await this.getData({
  299 + page: this.page, // 传入页码
  300 + size: this.size, // 传入每页条数
  301 + search: this.search, // 传入搜索的对象
  302 + });
  303 +
  304 + this.total = result.total;
  305 +
  306 + if (this.list.length == 0 && result.records.length == 0) {
  307 + this.shownoData = false
  308 + } else {
  309 + this.shownoData = true
  310 + }
  311 +
  312 + this.list = this.list.concat(result.records)
  313 +
  314 + // 判断是否全部加载完成
  315 + if (this.total == this.list.length) {
  316 + this.finished = true;
  317 + this.loading = 'nomore';
  318 + } else {
  319 + this.loading = 'loadmore';
  320 + }
  321 + },
  322 +
  323 + handelClick(values) {
  324 + console.log(values);
  325 + this.projectId = values.id;
  326 + },
  327 +
  328 + handelChange(e) {
  329 + console.log(e)
  330 + this.checkboxValue = e ? ['待鉴定'] : [];
  331 + this.search.appraisalStatus = e ? 'no_appraisal' : '';
  332 +
  333 + },
  334 +
  335 + handelCancel() {
  336 + this.switchValue = false;
  337 + this.projectId = '';
  338 + },
  339 +
  340 + hancelSubmit() {
  341 + this.finished = false;
  342 + this.loading = "loadmore";
  343 + this.page = 0;
  344 + this.list = [];
  345 + this._getList();
  346 +
  347 + this.show = false;
  348 + },
  349 +
  350 + }
  351 + }
  352 +</script>
  353 +
  354 +<style lang="scss" scoped>
  355 + .registration_review {
  356 + width: 100%;
  357 + min-height: 100%;
  358 + height: auto;
  359 + background-color: #F7F7F7;
  360 +
  361 + .search_box {
  362 + padding: 36rpx 30rpx 0;
  363 + background-color: #FFFFFF;
  364 +
  365 + .top {
  366 + display: flex;
  367 + flex-flow: row nowrap;
  368 + justify-content: space-between;
  369 + padding: 0 0 30rpx 0;
  370 +
  371 + .check {
  372 + padding: 20rpx 0 0 0;
  373 + }
  374 +
  375 + .search {
  376 + width: 468rpx;
  377 + }
  378 + }
  379 +
  380 + .bottom {
  381 + .time {
  382 + padding: 30rpx 0 30rpx 40rpx;
  383 + }
  384 + }
  385 +
  386 +
  387 + }
  388 +
  389 + .list_box {
  390 + padding: 0 0 50rpx 0;
  391 +
  392 + .item {
  393 + position: relative;
  394 + width: 630rpx;
  395 + margin: 30rpx auto;
  396 + padding: 30rpx;
  397 + border-radius: 12rpx;
  398 + background-color: #FFFFFF;
  399 +
  400 + .bg_image {
  401 + position: absolute;
  402 + top: 0;
  403 + right: 0;
  404 +
  405 + text {
  406 + position: absolute;
  407 + top: 12rpx;
  408 + right: 30rpx;
  409 + font-size: 24rpx;
  410 + line-height: 24rpx;
  411 + color: #FFFFFF;
  412 + }
  413 + }
  414 +
  415 + .info {
  416 + display: flex;
  417 + flex-flow: row nowrap;
  418 + align-items: center;
  419 + margin: 0 0 30rpx 0;
  420 +
  421 + .avatar {
  422 + width: 94rpx;
  423 + height: 94rpx;
  424 + padding: 0 8rpx;
  425 + border-radius: 4rpx;
  426 + background-color: #06B079;
  427 + font-size: 24rpx;
  428 + line-height: 94rpx;
  429 + color: #FFFFFF;
  430 + text-align: center;
  431 + }
  432 +
  433 + .name {
  434 + font-size: 32rpx;
  435 + line-height: 44rpx;
  436 + color: #202131;
  437 + font-weight: 500;
  438 + margin: 0 20rpx;
  439 + }
  440 +
  441 + .number {
  442 + font-size: 28rpx;
  443 + line-height: 32rpx;
  444 + color: #909097;
  445 + }
  446 + }
  447 +
  448 + .company {
  449 + display: flex;
  450 + flex-flow: row nowrap;
  451 + margin: 0 0 30rpx 0;
  452 +
  453 + text {
  454 + font-size: 28rpx;
  455 + line-height: 32rpx;
  456 + color: #909097;
  457 + margin: 0 0 0 16rpx;
  458 + }
  459 +
  460 + text:last-child {
  461 + color: #202131;
  462 + margin: 0 0 0 30rpx;
  463 + }
  464 + }
  465 +
  466 + .statistics {
  467 + border-top: 2rpx solid #E2E2E8;
  468 + padding: 28rpx 0 0 0;
  469 + display: flex;
  470 + flex-flow: row nowrap;
  471 + justify-content: space-around;
  472 +
  473 + view {
  474 + text-align: center;
  475 +
  476 + text {
  477 + font-size: 32rpx;
  478 + line-height: 32rpx;
  479 + color: #06B079;
  480 + }
  481 +
  482 + text:last-child {
  483 + display: block;
  484 + font-size: 24rpx;
  485 + color: #909097;
  486 + margin: 16rpx 0 0 0;
  487 + }
  488 + }
  489 +
  490 + .line {
  491 + height: 32rpx;
  492 + border-right: 2rpx solid #E2E2E8;
  493 + position: relative;
  494 + top: 30rpx;
  495 + }
  496 +
  497 +
  498 + }
  499 + }
  500 + }
  501 +
  502 + .popup_search {
  503 + width: 640rpx;
  504 + position: relative;
  505 +
  506 + .content {
  507 + padding: 0 40rpx;
  508 +
  509 + .title {
  510 + padding: 24rpx 0;
  511 + font-size: 28rpx;
  512 + line-height: 36rpx;
  513 + color: #202131;
  514 + }
  515 +
  516 + .scroll {
  517 + max-height: 60vh;
  518 +
  519 + .item {
  520 +
  521 + view {
  522 + display: flex;
  523 + flex-flow: row wrap;
  524 + align-items: center;
  525 + width: 500rpx;
  526 + height: 74rpx;
  527 + border-radius: 4rpx;
  528 + border: 2rpx solid #C1C1C9;
  529 + margin: 0 10rpx 20rpx;
  530 + font-size: 24rpx;
  531 + line-height: 32rpx;
  532 + color: #C0C0C9;
  533 + padding: 16rpx 20rpx;
  534 + }
  535 +
  536 + .selectItem {
  537 + background-color: #06B079;
  538 + color: #FFFFFF;
  539 + border: 2rpx solid #06B079;
  540 + }
  541 + }
  542 + }
  543 +
  544 + .time {
  545 + padding: 40rpx 0 0 0;
  546 + }
  547 +
  548 + .switch {
  549 + display: flex;
  550 + flex-flow: row nowrap;
  551 + justify-content: space-between;
  552 + padding: 40rpx 0 0 0;
  553 +
  554 + text {
  555 + font-size: 28rpx;
  556 + line-height: 36rpx;
  557 + color: #202131;
  558 + }
  559 + }
  560 +
  561 +
  562 + }
  563 +
  564 + .footer {
  565 + width: 560rpx;
  566 + height: 96rpx;
  567 + padding: 28rpx 40rpx;
  568 + background: #FFFFFF;
  569 + position: fixed;
  570 + bottom: 0;
  571 + right: 0;
  572 + z-index: 99;
  573 + border-top: 2rpx solid #E2E2E8;
  574 +
  575 + view {
  576 + display: inline-block;
  577 + }
  578 +
  579 + .left_btn {
  580 + width: 194rpx;
  581 + margin: 0 20rpx 0 0;
  582 + }
  583 +
  584 + .right_btn {
  585 + width: 346rpx;
  586 + }
  587 + }
  588 + }
  589 + }
  590 +</style>
... ...
  1 +<template>
  2 + <view class="report_detail">
  3 + <view class="box form_info">
  4 + <view class="info">
  5 + <view class="avatar">{{getNameLastTwo(detail.studentName)}}</view>
  6 + <view class="name">{{overflowHide(detail.studentName, 6)}}</view>
  7 + <view class="number">NO.{{detail.studentNumber}}</view>
  8 + </view>
  9 + <view class="company">
  10 + <text>实习单号</text>
  11 + <text>{{detail.number || '--'}}</text>
  12 + </view>
  13 + <view class="company">
  14 + <text>实习项目</text>
  15 + <text>{{detail.projectName|| '--'}}</text>
  16 + </view>
  17 + </view>
  18 +
  19 + <view class="box attendance">
  20 + <view class="title">考勤</view>
  21 + <view class="item_icon">
  22 + <text>考勤天数</text>
  23 + <view @click="handelRecord('signin')">
  24 + <text>{{detail.attendanceCount || 0}}天</text>
  25 + <u-icon :style="{margin:'0 0 0 8rpx'}" name="arrow-right" color="#909097" size="28"></u-icon>
  26 + </view>
  27 + </view>
  28 + </view>
  29 +
  30 + <view class="box attendance">
  31 + <view class="title">提交材料</view>
  32 + <view class="item_icon">
  33 + <text>三方协议</text>
  34 + <view @click="handelRecord('aggrent')">
  35 + <text>查看</text>
  36 + <u-icon :style="{margin:'0 0 0 8rpx'}" name="arrow-right" color="#909097" size="28"></u-icon>
  37 + </view>
  38 + </view>
  39 + <view class="item_icon">
  40 + <text>日志</text>
  41 + <view @click="handelRecord('daily')">
  42 + <text>{{detail.dailyLogCount || 0}}篇</text>
  43 + <u-icon :style="{margin:'0 0 0 8rpx'}" name="arrow-right" color="#909097" size="28"></u-icon>
  44 + </view>
  45 + </view>
  46 + <view class="item_icon">
  47 + <text>周志</text>
  48 + <view @click="handelRecord('weekly')">
  49 + <text>{{detail.weekLogCount || 0}}篇</text>
  50 + <u-icon :style="{margin:'0 0 0 8rpx'}" name="arrow-right" color="#909097" size="28"></u-icon>
  51 + </view>
  52 + </view>
  53 + <view class="item_icon">
  54 + <text>月志</text>
  55 + <view @click="handelRecord('monthly')">
  56 + <text>{{detail.monthlyLogCount || 0}}篇</text>
  57 + <u-icon :style="{margin:'0 0 0 8rpx'}" name="arrow-right" color="#909097" size="28"></u-icon>
  58 + </view>
  59 + </view>
  60 + <view class="item_icon">
  61 + <text>实习报告</text>
  62 + <view @click="handelRecord('report')">
  63 + <text>{{detail.internshipReportCount || 0}}次</text>
  64 + <u-icon :style="{margin:'0 0 0 8rpx'}" name="arrow-right" color="#909097" size="28"></u-icon>
  65 + </view>
  66 + </view>
  67 + </view>
  68 +
  69 + <view class="footer" v-if="detail.appraisalStatus == 'no_appraisal'">
  70 + <view class="right_btn">
  71 + <c-button type="confirm" text="成绩鉴定" @click="showModal = true">
  72 + </c-button>
  73 + </view>
  74 + </view>
  75 +
  76 + <u-overlay :show="showModal">
  77 + <view class="modal" v-show="showModal">
  78 + <view class="title">成绩鉴定</view>
  79 + <u-form labelPosition="top" :model="form" :rules="rules" :errorType="errorType" ref="uForm">
  80 +
  81 + <u-form-item label="成绩" labelWidth="100rpx" borderBottom prop="score"
  82 + v-if="detail.markWay == 'centesimal'">
  83 + <u-input v-model="form.score" border="none" type="number" :placeholderStyle="{color: 'C1C1C9'}"
  84 + placeholder="请输入" />
  85 + </u-form-item>
  86 +
  87 + <u-form-item label="成绩" @click="showSex = true" labelWidth="100rpx" borderBottom prop="level"
  88 + v-else>
  89 + <u-radio-group v-model="form.level" placement="row">
  90 + <u-radio :customStyle="{marginRight: '24rpx'}" size="28rpx" labelSize="28rpx"
  91 + v-for="(item, index) in radiolist" :key="index" :label="item.name" :name="item.name"
  92 + activeColor="#06B079">
  93 + </u-radio>
  94 + </u-radio-group>
  95 +
  96 +
  97 + </u-form-item>
  98 +
  99 + <u-form-item label="学分" labelWidth="100rpx" borderBottom prop="credit">
  100 + <u-input v-model="form.credit" type="number" border="none" :placeholderStyle="{color: 'C1C1C9'}"
  101 + placeholder="请输入" />
  102 + </u-form-item>
  103 +
  104 + <u-form-item label="评价" labelWidth="100rpx" borderBottom prop="teacherView">
  105 + <u-textarea v-model="form.teacherView" count border="none" :placeholderStyle="{color: 'C1C1C9'}"
  106 + placeholder="请输入评价"></u-textarea>
  107 + </u-form-item>
  108 +
  109 + </u-form>
  110 +
  111 + <view class="moda_footer">
  112 + <view class="left_btn">
  113 + <c-button type="cancel" text="取消" @click="handelCancel">
  114 + </c-button>
  115 + </view>
  116 + <view class="right_btn">
  117 + <c-button type="confirm" text="确定" @click="hancelSubmit">
  118 + </c-button>
  119 + </view>
  120 + </view>
  121 +
  122 +
  123 + </view>
  124 + </u-overlay>
  125 +
  126 + </view>
  127 +</template>
  128 +
  129 +<script>
  130 + import {
  131 + mapGetters,
  132 + mapState,
  133 + mapActions
  134 + } from 'vuex'
  135 + import listMixin from "@/common/mixins/list-mixin.js";
  136 +
  137 + import {
  138 + getAchievementDetailApi,
  139 + putAchievementAppraisalApi,
  140 + } from '@/config/api.js';
  141 +
  142 + export default {
  143 + data() {
  144 + return {
  145 + id: '',
  146 + detail: {},
  147 + showModal: false,
  148 + errorType: 'toast',
  149 + radiolist: [{
  150 + name: '优秀',
  151 + disabled: false
  152 + },
  153 + {
  154 + name: '良好',
  155 + disabled: false
  156 + },
  157 + {
  158 + name: '及格',
  159 + disabled: false
  160 + }, {
  161 + name: '不及格',
  162 + disabled: false
  163 + }
  164 + ],
  165 + form: {
  166 + score: '',
  167 + level: '',
  168 + credit: '',
  169 + teacherView: '',
  170 +
  171 + },
  172 + rules: {
  173 + score: [{
  174 + required: true,
  175 + message: '请输入成绩',
  176 + trigger: ['blur', 'change'],
  177 + }, {
  178 + validator: (rule, value, callback) => {
  179 + return this.$u.test.range(value, [0, 100]);
  180 + },
  181 + message: '手机号码不正确',
  182 + trigger: ['change', 'blur'],
  183 + }],
  184 + level: [{
  185 + required: true,
  186 + message: '请选择成绩',
  187 + trigger: ['blur', 'change'],
  188 + }, ],
  189 + credit: [{
  190 + required: true,
  191 + message: '请输入学分',
  192 + trigger: ['blur', 'change'],
  193 + }],
  194 + teacherView: [],
  195 + },
  196 + }
  197 + },
  198 +
  199 + onLoad(option) {
  200 + this.id = option.id;
  201 + getAchievementDetailApi(option.id).then(data => {
  202 + if (data) {
  203 + this.detail = data;
  204 + this.form.credit = String(data.courseFaceDTO.credit);
  205 + }
  206 + })
  207 + },
  208 +
  209 + onReady() {
  210 + this.$refs.uForm.setRules(this.rules);
  211 + },
  212 +
  213 + methods: {
  214 +
  215 + getNameLastTwo(value) {
  216 + if (value && value.length > 3) {
  217 + return value.substring(value.length - 3)
  218 + } else {
  219 + return value;
  220 + }
  221 + },
  222 +
  223 + overflowHide(value, num = 4) {
  224 + if (value && value.length > num) {
  225 + return `${value.slice(0, num)}...`
  226 + } else {
  227 + return value;
  228 + }
  229 + },
  230 +
  231 + handelRecord(type) {
  232 +
  233 + switch (type) {
  234 +
  235 + case 'signin':
  236 + this.$u.route({
  237 + url: `pages/main/internship/signInList/signInList?studentId=${this.detail.studentId}&projectId=${this.detail.projectId}`
  238 + })
  239 + break;
  240 +
  241 + case 'aggrent':
  242 + this.$u.route({
  243 + url: `pages/main/internship/agreementDetail/agreementDetail?&id=${this.detail.treatyId ? this.detail.treatyId : ''}`
  244 + })
  245 + break;
  246 +
  247 + case 'daily':
  248 + this.$u.route({
  249 + url: `pages/main/internship/studentLogReview/studentLogReview?category=daily&formId=${this.detail.id}`
  250 + })
  251 + break;
  252 +
  253 + case 'weekly':
  254 + this.$u.route({
  255 + url: `pages/main/internship/studentLogReview/studentLogReview?category=weekly&formId=${this.detail.id}`
  256 + })
  257 + break;
  258 +
  259 + case 'monthly':
  260 + this.$u.route({
  261 + url: `pages/main/internship/studentLogReview/studentLogReview?category=monthly&formId=${this.detail.id}`
  262 + })
  263 + break;
  264 +
  265 + case 'report':
  266 + this.$u.route({
  267 + url: `pages/main/home/reportDetail/reportDetail?id=${this.detail.reportId ? this.detail.reportId : ''}`
  268 + })
  269 + break;
  270 + }
  271 +
  272 + },
  273 +
  274 + handelCancel() {
  275 + this.showModal = false;
  276 + },
  277 +
  278 + hancelSubmit() {
  279 + let {
  280 + credit = ''
  281 + } = this.form;
  282 +
  283 + console.log(this.form)
  284 +
  285 + if (String(credit) && credit > this.detail.courseFaceDTO.credit) {
  286 + this.$u.toast('学分不正确');
  287 + return;
  288 + }
  289 +
  290 + this.$refs.uForm.validate().then(res => {
  291 + uni.$u.toast('校验通过');
  292 +
  293 + putAchievementAppraisalApi({
  294 + items: [{
  295 + id: this.detail.id,
  296 + ...this.form
  297 + }]
  298 + }).then(data => {
  299 + if (data) {
  300 + this.showModal = false;
  301 +
  302 + uni.navigateBack({
  303 + delta: 1
  304 + });
  305 + }
  306 + })
  307 +
  308 +
  309 + }).catch(errors => {
  310 + console.log(errors)
  311 + })
  312 +
  313 + },
  314 + }
  315 + }
  316 +</script>
  317 +
  318 +<style lang="scss" scoped>
  319 + .report_detail {
  320 + width: 100%;
  321 + min-height: 100%;
  322 + height: auto;
  323 + background-color: #F7F7F7;
  324 + padding: 20rpx 0 0 0;
  325 +
  326 + .box {
  327 + width: 630rpx;
  328 + margin: 20rpx auto;
  329 + padding: 30rpx 30rpx 12rpx 30rpx;
  330 + border-radius: 12rpx;
  331 + background-color: #FFFFFF;
  332 +
  333 + .title {
  334 + font-size: 32rpx;
  335 + line-height: 32rpx;
  336 + color: #202131;
  337 + margin: 0 0 30rpx 0;
  338 + }
  339 +
  340 + .title::before {
  341 + content: "";
  342 + display: inline-block;
  343 + width: 6rpx;
  344 + height: 32rpx;
  345 + background-color: #06B079;
  346 + margin: 0 12rpx 0 0;
  347 + position: relative;
  348 + top: 4rpx;
  349 + border-radius: 8rpx;
  350 + }
  351 +
  352 + .item {
  353 + margin: 0 0 24rpx 0;
  354 +
  355 + text:first-child {
  356 + display: inline-block;
  357 + width: 112rpx;
  358 + text-align: justify;
  359 + text-align-last: justify;
  360 + font-size: 28rpx;
  361 + line-height: 48rpx;
  362 + color: #909097;
  363 + vertical-align: top;
  364 + }
  365 +
  366 + text:last-child {
  367 + display: inline-block;
  368 + width: 440rpx;
  369 + font-size: 28rpx;
  370 + line-height: 48rpx;
  371 + color: #202131;
  372 + margin: 0 0 0 78rpx;
  373 + }
  374 + }
  375 +
  376 + .item_icon {
  377 + margin: 0 0 24rpx 0;
  378 + display: flex;
  379 + flex-flow: row nowrap;
  380 + justify-content: space-between;
  381 +
  382 + text {
  383 + display: inline-block;
  384 + width: 112rpx;
  385 + text-align: justify;
  386 + text-align-last: justify;
  387 + font-size: 28rpx;
  388 + line-height: 48rpx;
  389 + color: #909097;
  390 + vertical-align: top;
  391 + }
  392 +
  393 + view {
  394 + display: flex;
  395 + flex-flow: row nowrap;
  396 +
  397 + text {
  398 + display: inline-block;
  399 + width: auto;
  400 + font-size: 28rpx;
  401 + line-height: 48rpx;
  402 + color: #202131;
  403 + margin: 0 0 0 78rpx;
  404 + }
  405 + }
  406 + }
  407 + }
  408 +
  409 + .form_info {
  410 + .info {
  411 + display: flex;
  412 + flex-flow: row nowrap;
  413 + align-items: center;
  414 + margin: 0 0 30rpx 0;
  415 +
  416 + .avatar {
  417 + width: 94rpx;
  418 + height: 94rpx;
  419 + padding: 0 8rpx;
  420 + border-radius: 4rpx;
  421 + background-color: #06B079;
  422 + font-size: 24rpx;
  423 + line-height: 94rpx;
  424 + color: #FFFFFF;
  425 + text-align: center;
  426 + }
  427 +
  428 + .name {
  429 + font-size: 32rpx;
  430 + line-height: 44rpx;
  431 + color: #202131;
  432 + font-weight: 500;
  433 + margin: 0 20rpx;
  434 + }
  435 +
  436 + .number {
  437 + font-size: 28rpx;
  438 + line-height: 32rpx;
  439 + color: #909097;
  440 + }
  441 + }
  442 +
  443 + .company {
  444 + display: flex;
  445 + flex-flow: row nowrap;
  446 + margin: 0 0 30rpx 0;
  447 +
  448 + text {
  449 + font-size: 28rpx;
  450 + line-height: 32rpx;
  451 + color: #909097;
  452 + margin: 0 0 0 16rpx;
  453 + }
  454 +
  455 + text:last-child {
  456 + color: #202131;
  457 + margin: 0 0 0 30rpx;
  458 + }
  459 + }
  460 + }
  461 +
  462 + .footer {
  463 + width: 100%;
  464 + height: 96rpx;
  465 + padding: 28rpx 30rpx;
  466 + background: #FFFFFF;
  467 + position: fixed;
  468 + bottom: 0;
  469 + left: 0;
  470 + z-index: 99;
  471 + border-top: 2rpx solid #E2E2E8;
  472 +
  473 + view {
  474 + display: inline-block;
  475 + }
  476 +
  477 + .right_btn {
  478 + width: 690rpx;
  479 + }
  480 + }
  481 +
  482 + .modal {
  483 + width: 570rpx;
  484 + position: relative;
  485 + display: flex;
  486 + flex-direction: column;
  487 + margin: 200rpx auto;
  488 + padding: 40rpx;
  489 + border-radius: 20rpx;
  490 + background-color: #fff;
  491 +
  492 + .title {
  493 + text-align: center;
  494 + font-size: 36rpx;
  495 + line-height: 48rpx;
  496 + color: #202131;
  497 + margin: 0 0 66rpx 0;
  498 + }
  499 +
  500 + .moda_footer {
  501 + width: 590rpx;
  502 + height: 96rpx;
  503 + padding: 40rpx 0 0 0;
  504 +
  505 + view {
  506 + display: inline-block;
  507 + width: 260rpx;
  508 + }
  509 +
  510 + .left_btn {
  511 + margin: 0 48rpx 0 0;
  512 + }
  513 +
  514 + .right_btn {}
  515 + }
  516 +
  517 +
  518 + }
  519 + }
  520 +</style>
... ...
  1 +<template>
  2 + <view class="report_detail">
  3 + <view class="list_box" v-if="list.length > 0">
  4 + <view class="item" v-for="(item, i) in list" :key="i" @click="handelDetail(item)">
  5 +
  6 + <view class="bg_image" v-if="item.status == 'stay_examine'">
  7 + <u-image src="/static/img/home/labelBgGreen.png" width="142rpx" height="48rpx"></u-image>
  8 + <text>待审核</text>
  9 + </view>
  10 +
  11 + <view class="bg_image" v-else-if="item.status == 'adopt'">
  12 + <u-image src="/static/img/home/labelBgGrey.png" width="142rpx" height="48rpx"></u-image>
  13 + <text>已通过</text>
  14 + </view>
  15 +
  16 + <view class="bg_image" v-else>
  17 + <u-image src="/static/img/home/labelBgGrey.png" width="142rpx" height="48rpx"></u-image>
  18 + <text>已退回</text>
  19 + </view>
  20 +
  21 + <view class="info">
  22 + <u-image src="/static/img/home/approvalRecordBg.png" width="94rpx" height="94rpx" />
  23 + <view class="title_name">
  24 + <view class="title">
  25 + {{item.title}}
  26 + </view>
  27 + <view class="time">
  28 +
  29 + <text>创建时间</text>
  30 + <text>
  31 + {{timeFormat(item.createdTime, 'yyyy-mm-dd hh:MM')}}
  32 + </text>
  33 + </view>
  34 + </view>
  35 + </view>
  36 +
  37 + </view>
  38 + <c-loading :loading="loading"></c-loading>
  39 + </view>
  40 + <view v-else class="no_data">
  41 + <c-no-data></c-no-data>
  42 + </view>
  43 +
  44 + <view class="report_info">
  45 +
  46 +
  47 + </view>
  48 + </view>
  49 +</template>
  50 +
  51 +<script>
  52 + import {
  53 + mapGetters,
  54 + mapState,
  55 + mapActions
  56 + } from 'vuex'
  57 + import listMixin from "@/common/mixins/list-mixin.js";
  58 +
  59 + import {
  60 + getReportApprovalListApi,
  61 + } from '@/config/api.js';
  62 +
  63 + export default {
  64 + data() {
  65 + return {
  66 + formId: '',
  67 + list: [],
  68 + }
  69 + },
  70 +
  71 + onLoad(option) {
  72 + this.formId = option.formId;
  73 + getReportApprovalListApi(option.formId).then(data => {
  74 + if (data) {
  75 + this.list = data
  76 + }
  77 + })
  78 + },
  79 +
  80 + methods: {
  81 +
  82 + timeFormat(timestamp, format = 'yyyy-mm-dd') {
  83 + return timestamp > 0 ? uni.$u.timeFormat(timestamp, format) : '--'
  84 + },
  85 +
  86 + handelDetail(record) {
  87 + this.$u.route({
  88 + url: `pages/main/home/reportDetail/reportDetail?id=${record.id}&formId=${record.formId}`
  89 + })
  90 + },
  91 + }
  92 + }
  93 +</script>
  94 +
  95 +<style lang="scss" scoped>
  96 + .report_detail {
  97 + width: 100%;
  98 + min-height: 100%;
  99 + height: auto;
  100 + background-color: #F7F7F7;
  101 + padding: 20rpx 0 0 0;
  102 +
  103 + .list_box {
  104 + padding: 0 0 50rpx 0;
  105 +
  106 + .item {
  107 + position: relative;
  108 + width: 630rpx;
  109 + margin: 30rpx auto;
  110 + padding: 30rpx;
  111 + border-radius: 12rpx;
  112 + background-color: #FFFFFF;
  113 +
  114 + .bg_image {
  115 + position: absolute;
  116 + top: 0;
  117 + right: 0;
  118 +
  119 + text {
  120 + position: absolute;
  121 + top: 12rpx;
  122 + right: 30rpx;
  123 + font-size: 24rpx;
  124 + line-height: 24rpx;
  125 + color: #FFFFFF;
  126 + }
  127 + }
  128 +
  129 + .info {
  130 + display: flex;
  131 + flex-flow: row nowrap;
  132 + align-items: center;
  133 + margin: 0 0 30rpx 0;
  134 +
  135 + .title_name {
  136 + .title {
  137 + font-size: 32rpx;
  138 + line-height: 44rpx;
  139 + color: #202131;
  140 + font-weight: 500;
  141 + margin: 0 20rpx;
  142 + }
  143 +
  144 + .time {
  145 + padding: 8rpx 0 0 20rpx;
  146 + font-size: 28rpx;
  147 + line-height: 32rpx;
  148 + color: #909097;
  149 +
  150 + text:last-child {
  151 + padding: 0 0 0 30rpx;
  152 + }
  153 + }
  154 + }
  155 + }
  156 + }
  157 + }
  158 + }
  159 +</style>
... ...
  1 +<template>
  2 + <view class="log_detail">
  3 +
  4 + <scroll-view scroll-y="true" style="height: 100vh;" :scroll-with-animation="true">
  5 + <view class="header_box">
  6 + <view class="header">
  7 + <view class="avatar">{{getNameLastTwo(detail.studentName)}}</view>
  8 + <view class="form_name">
  9 + <view class="name">{{overflowHide(detail.studentName, 4)}}</view>
  10 + <view class="week">
  11 + <!-- <text>{{timeFormat(detail.logTime, 'yyyy年')}}</text> -->
  12 + <!-- <text>{{getWeek(detail.logTime)}}</text> -->
  13 + <text>{{getCreatedTime(detail)}}</text>
  14 + </view>
  15 + </view>
  16 + <view class="status" :style="{color:'#909097', backgroundColor:'#EAEAEC'}"
  17 + v-if="detail.status == 'read'">
  18 + <text>已阅</text>
  19 + </view>
  20 +
  21 + <view class="status" v-else @click="putLog">
  22 + <text>未阅</text>
  23 + </view>
  24 + </view>
  25 + </view>
  26 +
  27 + <view class="content">
  28 + <view class="name_time">
  29 + <view class="title">{{detail.title}}</view>
  30 + <view class="time">创建时间:{{timeFormat(detail.createdTime)}}</view>
  31 + </view>
  32 +
  33 + <view class="u-parse">
  34 + <u-parse :content="detail.content"></u-parse>
  35 + </view>
  36 +
  37 + <view v-if="commentList.length>0" class="reply">
  38 + <view class="title">评论</view>
  39 + <view v-for="(item,index) in commentList" :key="index">
  40 + <view v-if="index!=0" class="divide_line_padding"></view>
  41 + <view class="list">
  42 + <view style="margin-top: 8rpx;" class="userInfo">
  43 + <text> {{item.name?item.name:"佚名"}}</text>
  44 + <text>({{userType[item.userType]}})</text>
  45 + </view>
  46 + <view class="replyTime" style="margin-top: 8rpx;">{{timeFormat(item.createdTime)}}</view>
  47 + <view class="describe" style="margin-top: 8rpx;">{{item.content}}</view>
  48 + <view v-if="false" class="" v-for="(item1,index) in item.replies">
  49 + <view class="reply_bg">
  50 + {{item1}}
  51 + </view>
  52 + </view>
  53 + </view>
  54 + </view>
  55 + </view>
  56 + </view>
  57 + </scroll-view>
  58 +
  59 +
  60 +
  61 + <view class="nextPage">
  62 + <u-icon name="arrow-down" size="36"></u-icon>
  63 + </view>
  64 +
  65 + <view class="footer">
  66 + <view class="divide_line"></view>
  67 + <input class="uni-input" placeholder="这么精彩,不说点什么吗?" :value="reply" confirm-type="send" @confirm="goReply" />
  68 + </view>
  69 + </view>
  70 +</template>
  71 +
  72 +<script>
  73 + import {
  74 + mapGetters,
  75 + mapState,
  76 + mapActions
  77 + } from 'vuex'
  78 +
  79 + import {
  80 + getLogDetailApi,
  81 + putLogReviewApi,
  82 + getLogReplyListApi,
  83 + postLogReplyApi,
  84 + } from '@/config/api.js';
  85 + export default {
  86 + data() {
  87 + return {
  88 + id: "",
  89 + formLogId: "",
  90 + show: false,
  91 + reply: '',
  92 + content: "",
  93 + style: {
  94 + // 字符串的形式
  95 + p: 'color: red;font-size:32rpx',
  96 + span: 'font-size: 30rpx'
  97 + },
  98 + detail: {},
  99 + userType: {
  100 + "student": "学生",
  101 + "teacher": "学校",
  102 + "company": "企业"
  103 + },
  104 + commentList: [],
  105 + }
  106 + },
  107 +
  108 + onLoad(option) {
  109 +
  110 + this.id = option.id;
  111 + getLogDetailApi(option.id).then(data => {
  112 + if (data) {
  113 + this.detail = data
  114 + }
  115 + })
  116 +
  117 + this.getCommentList()
  118 +
  119 + },
  120 +
  121 + methods: {
  122 + getCreatedTime(e) {
  123 + console.log(e)
  124 + let time = this.$u.timeFormat(e.logTime / 1000, 'yyyy/mm/dd');
  125 + if (e.category == "weekly") {
  126 + time = new Date(e.logTime).getFullYear() + "年第" + (this.getWeek(e.logTime) + 1) + "周";
  127 + } else if (e.category == "monthly") {
  128 + time = this.$u.timeFormat(e.logTime / 1000, 'yyyy年mm月');
  129 + }
  130 + return time
  131 + },
  132 +
  133 + getWeek(dt) {
  134 + if (dt > 0) {
  135 + let d1 = new Date(dt);
  136 + let d2 = new Date(dt);
  137 + d2.setMonth(0);
  138 + d2.setDate(1);
  139 + let rq = d1 - d2;
  140 + let days = Math.ceil(rq / (24 * 60 * 60 * 1000));
  141 + let num = Math.ceil(days / 7);
  142 + return num;
  143 + } else {
  144 + return '';
  145 + }
  146 + },
  147 +
  148 + getNameLastTwo(value) {
  149 +
  150 + if (value && value.length > 3) {
  151 + return value.substring(value.length - 3)
  152 + } else {
  153 + return value;
  154 + }
  155 + },
  156 +
  157 + overflowHide(value, num = 4) {
  158 + if (value && value.length > num) {
  159 + return `${value.slice(0, num)}...`
  160 + } else {
  161 + return value;
  162 + }
  163 + },
  164 +
  165 + timeFormat(timestamp, format = 'yyyy-mm-dd') {
  166 + return timestamp > 0 ? uni.$u.timeFormat(timestamp, format) : '--'
  167 + },
  168 +
  169 + putLog() {
  170 + putLogReviewApi({
  171 + ids: [this.id]
  172 + }).then(data => {
  173 + if (data) {
  174 + getLogDetailApi(this.id).then(result => {
  175 + if (result) {
  176 + this.detail = result
  177 + }
  178 + })
  179 + }
  180 + })
  181 + },
  182 +
  183 + getCommentList() {
  184 + getLogReplyListApi({
  185 + formLogId: this.id
  186 + }).then(data => {
  187 + if (data) {
  188 + this.commentList = data.records;
  189 + }
  190 + })
  191 + },
  192 +
  193 + goReply(e) { //回复评论
  194 + console.log(e)
  195 + this.reply = e.target.value
  196 + postLogReplyApi({
  197 + formLogId: this.id,
  198 + content: e.target.value
  199 + }).then(data => {
  200 + this.reply = ''
  201 + this.getCommentList()
  202 + })
  203 + }
  204 + }
  205 + }
  206 +</script>
  207 +
  208 +<style lang="scss" scoped>
  209 + .log_detail {
  210 + width: 100%;
  211 + min-height: 100%;
  212 + height: auto;
  213 + background-color: #F7F7F7;
  214 +
  215 + .nextPage {
  216 + position: fixed;
  217 + bottom: 20vh;
  218 + right: 30rpx;
  219 + background-color: #FFFFFF;
  220 + padding: 12rpx;
  221 + border-radius: 8rpx;
  222 + }
  223 +
  224 + .header_box {
  225 + background-color: #FFFFFF;
  226 +
  227 + .header {
  228 + display: flex;
  229 + flex-flow: row nowrap;
  230 + align-items: center;
  231 + padding: 52rpx 0;
  232 + margin: 0 30rpx;
  233 + position: relative;
  234 + border-bottom: 2rpx solid #E2E2E8;
  235 + background-color: #FFFFFF;
  236 +
  237 + .avatar {
  238 + width: 94rpx;
  239 + height: 94rpx;
  240 + border-radius: 4rpx;
  241 + background-color: #06B079;
  242 + font-size: 24rpx;
  243 + line-height: 94rpx;
  244 + color: #FFFFFF;
  245 + text-align: center;
  246 + }
  247 +
  248 + .form_name {
  249 + .name {
  250 + font-size: 32rpx;
  251 + line-height: 44rpx;
  252 + color: #202131;
  253 + font-weight: 500;
  254 + margin: 0 20rpx;
  255 + }
  256 +
  257 + .week {
  258 + padding: 8rpx 0 0 0;
  259 + font-size: 24rpx;
  260 + line-height: 32rpx;
  261 + color: #909097;
  262 +
  263 + text {
  264 + padding: 8rpx 0 0 20rpx;
  265 + }
  266 + }
  267 + }
  268 +
  269 + .status {
  270 + font-size: 24rpx;
  271 + line-height: 34rpx;
  272 + color: #FFFFFF;
  273 + width: 112rpx;
  274 + height: 48rpx;
  275 + line-height: 48rpx;
  276 + text-align: center;
  277 + border-radius: 200rpx;
  278 + background-color: #06B079;
  279 + position: absolute;
  280 + top: 74rpx;
  281 + right: 0;
  282 + }
  283 + }
  284 + }
  285 +
  286 + .content {
  287 +
  288 + padding: 16rpx 0 150rpx;
  289 +
  290 + .name_time {
  291 + background-color: #FFFFFF;
  292 + padding: 26rpx 30rpx;
  293 +
  294 + .title {
  295 + font-size: 36rpx;
  296 + line-height: 50rpx;
  297 + color: #06B079;
  298 + }
  299 +
  300 + .time {
  301 + padding: 6rpx 0 0 0;
  302 + font-size: 24rpx;
  303 + line-height: 32rpx;
  304 + color: #909097;
  305 + padding: 0 0 26rpx 0;
  306 + }
  307 + }
  308 +
  309 + .u-parse {
  310 + background-color: #FFFFFF;
  311 + padding: 0 30rpx 50rpx;
  312 + font-size: 28rpx;
  313 + line-height: 36rpx;
  314 + color: #4A4A53;
  315 + }
  316 +
  317 + .reply {
  318 + background-color: #fff;
  319 + padding: 50rpx 30rpx 150rpx;
  320 + margin: 16rpx 0 0 0;
  321 +
  322 + .title {
  323 + font-size: 34rpx;
  324 + line-height: 48rpx;
  325 + color: #202131;
  326 + }
  327 +
  328 + .list {
  329 + padding: 32rpx;
  330 + border-bottom: 2rpx solid #E2E2E8;
  331 +
  332 + .userInfo {
  333 + color: rgba(0, 0, 0, 0.4500);
  334 + font-size: 28rpx;
  335 + line-height: 40rpx;
  336 + }
  337 +
  338 + .replyTime {
  339 + color: rgba(0, 0, 0, 0.4500);
  340 + font-size: 26rpx;
  341 + line-height: 36rpx;
  342 + }
  343 +
  344 +
  345 + }
  346 +
  347 + .reply_bg {
  348 + background: rgba(0, 0, 0, 0.03);
  349 + border-radius: 8rpx;
  350 + padding: 20rpx 32rpx;
  351 + margin-top: 16rpx;
  352 + }
  353 + }
  354 + }
  355 +
  356 + }
  357 +
  358 + .footer {
  359 + width: 100%;
  360 + height: 130rpx;
  361 + background: #fff;
  362 + position: fixed;
  363 + bottom: 0;
  364 + left: 0;
  365 + z-index: 99;
  366 +
  367 + .uni-input {
  368 + height: 96rpx;
  369 + background: rgba(0, 0, 0, 0.04);
  370 + border-radius: 8rpx;
  371 + margin: 10rpx 32rpx 32rpx 32rpx;
  372 + padding: 0 20rpx;
  373 + }
  374 + }
  375 +</style>
... ...
  1 +<template>
  2 + <view class="registration_review">
  3 + <view class="search_box">
  4 + <view class="check">
  5 + <u-checkbox-group v-model="checkboxValue" placement="column" @change="checkboxChange">
  6 + <u-checkbox :customStyle="{marginBottom: '8px'}" shape="circle"
  7 + v-for="(item, index) in checkboxList" :key="index" :label="item.name" :name="item.name"
  8 + activeColor="#06B079" size="28rpx" labelSize="28rpx" labelColor="#202131">
  9 + </u-checkbox>
  10 + </u-checkbox-group>
  11 + </view>
  12 +
  13 + <view class="search">
  14 + <u-search placeholder="请输入学生姓名/学号/手机号" placeholderColor="#C1C1C9" searchIconSize="36" height="64rpx"
  15 + bgColor="#F4F4F4" :showAction="false" shape="square" v-model="keyword" @search="handelSearch">
  16 + </u-search>
  17 + </view>
  18 +
  19 + <u-icon slot="icon" size="40" :name="'/static/img/home/selectIcon.png'" @click="show = true"></u-icon>
  20 + </view>
  21 +
  22 + <u-sticky bgColor="#fff">
  23 + <u-tabs :list="tabs" :scrollable="false" lineWidth="30rpx" lineHeight="4rpx" lineColor="#06B079"
  24 + :inactiveStyle="{fontSize:'28rpx', color:'#4A4A53'}" :activeStyle="{fontSize:'36rpx', color:'#06B079'}"
  25 + @change="handelTab" :current="current">
  26 + </u-tabs>
  27 + </u-sticky>
  28 +
  29 + <view class="list_box" v-if="list.length > 0">
  30 + <view class="item" v-for="(item, i) in list" :key="i" @click="handelDetail(item)">
  31 +
  32 + <view class="bg_image" v-if="item.status == 'unread'">
  33 + <u-image src="/static/img/home/labelBgGreen.png" width="142rpx" height="48rpx"></u-image>
  34 + <text>未阅</text>
  35 + </view>
  36 +
  37 + <view class="bg_image" v-else>
  38 + <u-image src="/static/img/home/labelBgGrey.png" width="142rpx" height="48rpx"></u-image>
  39 + <text>已阅</text>
  40 + </view>
  41 +
  42 + <view class="info">
  43 + <view class="avatar">{{getNameLastTwo(item.studentName)}}</view>
  44 + <view class="form_name">
  45 + <view class="name">{{overflowHide(item.title, 10)}}</view>
  46 + <view class="week">
  47 + <!-- <text>{{timeFormat(item.logTime, 'yyyy年')}}</text> -->
  48 + <!-- <text>{{getWeek(item.logTime)}}</text> -->
  49 + <text>{{getCreatedTime(item)}}</text>
  50 +
  51 + </view>
  52 + </view>
  53 + </view>
  54 + <view class="u-content">
  55 + <u-parse :content="item.content"></u-parse>
  56 + </view>
  57 + <view class="name_time">
  58 + <view class="name">
  59 + <text>学生姓名</text>
  60 + <text>{{item.studentName}}</text>
  61 + </view>
  62 + <view class="time">{{timeFormat(item.createdTime)}}</view>
  63 + </view>
  64 +
  65 + </view>
  66 + <c-loading :loading="loading"></c-loading>
  67 + </view>
  68 + <view v-else class="no_data">
  69 + <c-no-data></c-no-data>
  70 + </view>
  71 +
  72 + <u-popup :show="show" mode="right" @close="close" @open="open" :closeOnClickOverlay="false">
  73 + <view class="popup_search">
  74 + <view class="content">
  75 + <view class="title">按项目筛选</view>
  76 + <scroll-view class="scroll" scroll-y="true">
  77 + <view class="item" v-for="(item, i) in projectList" :key="i" @click="handelClick(item)">
  78 + <view class="selectItem" v-if="item.id == projectId">
  79 + <text>{{item.name}}</text>
  80 + </view>
  81 + <view v-else>
  82 + <text>{{item.name}}</text>
  83 + </view>
  84 + </view>
  85 + </scroll-view>
  86 + <view class="switch">
  87 + <text>未阅</text>
  88 + <u-switch v-model="switchValue" size="48" activeColor="#06B079" @change="handelChange">
  89 + </u-switch>
  90 + </view>
  91 + </view>
  92 +
  93 + <view class="footer">
  94 + <view class="left_btn">
  95 + <c-button type="cancel" text="重置" @click="handelCancel">
  96 + </c-button>
  97 + </view>
  98 + <view class="right_btn">
  99 + <c-button type="confirm" text="确定" @click="hancelSubmit">
  100 + </c-button>
  101 + </view>
  102 + </view>
  103 + </view>
  104 + </u-popup>
  105 + </view>
  106 +</template>
  107 +
  108 +<script>
  109 + import {
  110 + mapGetters,
  111 + mapState,
  112 + mapActions
  113 + } from 'vuex'
  114 + import listMixin from "@/common/mixins/list-mixin.js";
  115 +
  116 + import {
  117 + getLogReviewListApi,
  118 + getProjectListApi,
  119 + } from '@/config/api.js';
  120 +
  121 + export default {
  122 + mixins: [listMixin],
  123 + data() {
  124 + return {
  125 + studentId: '',
  126 + checkboxValue: [],
  127 + checkboxList: [{
  128 + name: '未阅',
  129 + disabled: false
  130 + }],
  131 + keyword: '',
  132 + search: {
  133 + //搜索对象必须为key search的对象
  134 + keySearch: "",
  135 + status: '',
  136 + category: 'daily',
  137 +
  138 + },
  139 + show: false, //筛选
  140 + current: 0,
  141 + tabs: [{
  142 + name: '日志',
  143 + }, {
  144 + name: '周志',
  145 + }, {
  146 + name: '月志'
  147 + }],
  148 +
  149 + list: [], //列表必须为key list的数组
  150 +
  151 + projectId: '',
  152 + showTime: false,
  153 + timeValue: '',
  154 + switchValue: false,
  155 +
  156 + }
  157 + },
  158 +
  159 + onLoad(option) {
  160 + console.log(option)
  161 + this.studentId = option.studentId;
  162 + this.projectId = option.projectId;
  163 +
  164 + this.$store.dispatch(`home/getProjectList`, {
  165 + pageSize: -1,
  166 + })
  167 +
  168 + this.search.keySearch = '';
  169 +
  170 + if (option && option.category) {
  171 + this.search.category = option.category;
  172 + this.current =
  173 + option.category == 'daily' ? 0 :
  174 + option.category == 'weekly' ? 1 :
  175 + option.category == 'monthly' ? 2 :
  176 + '';
  177 + }
  178 +
  179 + if (option && option.status) {
  180 + this.search.status = 'unread';
  181 + this.checkboxValue = ['未阅'];
  182 + this.switchValue = true;
  183 + }
  184 +
  185 + this.finished = false;
  186 + this.loading = "loadmore";
  187 + this.page = 0;
  188 + this.list = [];
  189 + },
  190 +
  191 + onShow() {
  192 + this._getList();
  193 + },
  194 +
  195 + computed: {
  196 + ...mapState('home', {
  197 + // 箭头函数可使代码更简练
  198 + projectList: 'projectList',
  199 + }),
  200 + },
  201 +
  202 + methods: {
  203 +
  204 + getCreatedTime(e) {
  205 + let time = this.$u.timeFormat(e.logTime / 1000, 'yyyy/mm/dd');
  206 + if (e.category == "weekly") {
  207 + time = new Date(e.logTime).getFullYear() + "年第" + (this.getWeek(e.logTime) + 1) + "周";
  208 + } else if (e.category == "monthly") {
  209 + time = this.$u.timeFormat(e.logTime / 1000, 'yyyy年mm月');
  210 + }
  211 + return time
  212 + },
  213 +
  214 + getWeek(dt) {
  215 + if (dt > 0) {
  216 + let d1 = new Date(dt);
  217 + let d2 = new Date(dt);
  218 + d2.setMonth(0);
  219 + d2.setDate(1);
  220 + let rq = d1 - d2;
  221 + let days = Math.ceil(rq / (24 * 60 * 60 * 1000));
  222 + let num = Math.ceil(days / 7);
  223 + return num;
  224 + } else {
  225 + return '';
  226 + }
  227 + },
  228 +
  229 + getNameLastTwo(value) {
  230 + if (value && value.length > 3) {
  231 + return value.substring(value.length - 3)
  232 + } else {
  233 + return value;
  234 + }
  235 + },
  236 +
  237 + overflowHide(value, num = 4) {
  238 + if (value && value.length > num) {
  239 + return `${value.slice(0, num)}...`
  240 + } else {
  241 + return value;
  242 + }
  243 + },
  244 +
  245 + handelTab(item) {
  246 + let category = item.index === 0 ? 'daily' : item.index === 1 ? 'weekly' : item.index === 2 ? 'monthly' :
  247 + '';
  248 +
  249 + this.search.category = category;
  250 +
  251 + this.finished = false;
  252 + this.loading = "loadmore";
  253 + this.page = 0;
  254 + this.list = [];
  255 + this._getList();
  256 +
  257 + },
  258 +
  259 + handelDetail(record) {
  260 + this.$u.route({
  261 + url: `pages/main/home/logDetail/logDetail?id=${record.id}&formId=${record.formId}`
  262 + })
  263 + },
  264 +
  265 + timeFormat(timestamp, format = 'yyyy-mm-dd') {
  266 + return timestamp > 0 ? uni.$u.timeFormat(timestamp, format) : '--'
  267 + },
  268 +
  269 + checkboxChange(n) {
  270 + console.log('change', n);
  271 +
  272 + this.search.status = n.length > 0 ? 'unread' : '';
  273 +
  274 + this.switchValue = n.length > 0 ? true : false;
  275 +
  276 + this.finished = false;
  277 + this.loading = "loadmore";
  278 + this.page = 0;
  279 + this.list = [];
  280 + this._getList();
  281 + },
  282 +
  283 + handelSearch(value) {
  284 + this.finished = false;
  285 + this.loading = "loadmore";
  286 + this.page = 0;
  287 + this.list = [];
  288 + this._getList();
  289 + },
  290 +
  291 + open() {
  292 +
  293 + },
  294 +
  295 + close() {
  296 + this.show = false
  297 + },
  298 +
  299 + // scroll-view到底部加载更多
  300 + onreachBottom() {},
  301 + // 搜索
  302 + searchSubmit() {
  303 + // 调用混合搜索
  304 + this._searchData();
  305 + },
  306 + // 模拟后端分页
  307 + async getData(requestParams) {
  308 + const {
  309 + search = {}
  310 + } = requestParams;
  311 +
  312 + let params = {};
  313 + params.pageNumber = requestParams.page + 1;
  314 + params.pageSize = 5;
  315 +
  316 + if (search.status) {
  317 + params.status = search.status;
  318 + }
  319 +
  320 + if (search.category) {
  321 + params.category = search.category;
  322 + }
  323 +
  324 + if (this.keyword) {
  325 + params.keySearch = this.keyword
  326 + }
  327 +
  328 + if (this.studentId) {
  329 + params.studentId = this.studentId
  330 + }
  331 +
  332 + if (this.projectId) {
  333 + params.projectId = this.projectId
  334 + }
  335 +
  336 + return await getLogReviewListApi(params);
  337 + },
  338 + // 数据请求(没错就是这么少的代码)
  339 + async _getList() {
  340 + if (this.page == 0) {
  341 + this.list = [];
  342 + }
  343 +
  344 + // 根据实际情况修改自己修改key
  345 + let result = await this.getData({
  346 + page: this.page, // 传入页码
  347 + size: this.size, // 传入每页条数
  348 + search: this.search, // 传入搜索的对象
  349 + });
  350 +
  351 + this.total = result.total;
  352 +
  353 + if (this.list.length == 0 && result.records.length == 0) {
  354 + this.shownoData = false
  355 + } else {
  356 + this.shownoData = true
  357 + }
  358 +
  359 + this.list = this.list.concat(result.records)
  360 +
  361 + // 判断是否全部加载完成
  362 + if (this.total == this.list.length) {
  363 + this.finished = true;
  364 + this.loading = 'nomore';
  365 + } else {
  366 + this.loading = 'loadmore';
  367 + }
  368 + },
  369 +
  370 + handelClick(values) {
  371 + this.projectId = values.id;
  372 + },
  373 +
  374 + handelChange(e) {
  375 + this.checkboxValue = e ? ['未阅'] : [];
  376 + this.search.status = e ? 'unread' : '';
  377 +
  378 + },
  379 +
  380 + handelCancel() {
  381 + this.switchValue = false;
  382 + this.projectId = '';
  383 + },
  384 +
  385 + hancelSubmit() {
  386 + this.finished = false;
  387 + this.loading = "loadmore";
  388 + this.page = 0;
  389 + this.list = [];
  390 + this._getList();
  391 +
  392 + this.show = false;
  393 + },
  394 +
  395 + }
  396 + }
  397 +</script>
  398 +
  399 +<style lang="scss" scoped>
  400 + .registration_review {
  401 + width: 100%;
  402 + min-height: 100%;
  403 + height: auto;
  404 + background-color: #F7F7F7;
  405 +
  406 + .search_box {
  407 + padding: 36rpx 30rpx 12rpx;
  408 + background-color: #FFFFFF;
  409 + display: flex;
  410 + flex-flow: row nowrap;
  411 + justify-content: space-between;
  412 +
  413 + .check {
  414 + padding: 20rpx 0 0 0;
  415 + }
  416 +
  417 + .search {
  418 + width: 468rpx;
  419 + }
  420 + }
  421 +
  422 + .list_box {
  423 + padding: 0 0 50rpx 0;
  424 +
  425 + .item {
  426 + position: relative;
  427 + width: 630rpx;
  428 + margin: 30rpx auto;
  429 + padding: 30rpx;
  430 + border-radius: 12rpx;
  431 + background-color: #FFFFFF;
  432 +
  433 + .bg_image {
  434 + position: absolute;
  435 + top: 0;
  436 + right: 0;
  437 +
  438 + text {
  439 + position: absolute;
  440 + top: 12rpx;
  441 + right: 30rpx;
  442 + font-size: 24rpx;
  443 + line-height: 24rpx;
  444 + color: #FFFFFF;
  445 + }
  446 + }
  447 +
  448 + .info {
  449 + display: flex;
  450 + flex-flow: row nowrap;
  451 + align-items: center;
  452 + margin: 0 0 30rpx 0;
  453 +
  454 + .avatar {
  455 + width: 94rpx;
  456 + height: 94rpx;
  457 + border-radius: 4rpx;
  458 + background-color: #06B079;
  459 + font-size: 24rpx;
  460 + line-height: 94rpx;
  461 + color: #FFFFFF;
  462 + text-align: center;
  463 + }
  464 +
  465 + .form_name {
  466 + .name {
  467 + font-size: 32rpx;
  468 + line-height: 44rpx;
  469 + color: #202131;
  470 + font-weight: 500;
  471 + margin: 0 20rpx;
  472 + }
  473 +
  474 + .week {
  475 + padding: 8rpx 0 0 0;
  476 + font-size: 20rpx;
  477 + line-height: 32rpx;
  478 + color: #909097;
  479 +
  480 + // padding: 0 0 0 20rpx;
  481 + text {
  482 + padding: 8rpx 0 0 20rpx;
  483 + }
  484 + }
  485 + }
  486 + }
  487 +
  488 + .u-content {
  489 + font-size: 24rpx;
  490 + line-height: 32rpx;
  491 + color: #909097;
  492 + margin: 32rpx 0 30rpx 0;
  493 + max-height: 100rpx;
  494 + overflow: hidden;
  495 + }
  496 +
  497 + .name_time {
  498 + border-top: 2rpx solid #E2E2E8;
  499 + padding: 28rpx 0 0 0;
  500 + display: flex;
  501 + flex-flow: row nowrap;
  502 + justify-content: space-between;
  503 +
  504 +
  505 + .name {
  506 + text {
  507 + font-size: 28rpx;
  508 + line-height: 32rpx;
  509 + color: #909097;
  510 + }
  511 +
  512 + text:last-child {
  513 + color: #202131;
  514 + margin: 0 0 0 30rpx;
  515 + }
  516 + }
  517 +
  518 + .time {
  519 + font-size: 28rpx;
  520 + line-height: 32rpx;
  521 + color: #909097;
  522 + }
  523 + }
  524 + }
  525 + }
  526 +
  527 + .popup_search {
  528 + width: 640rpx;
  529 + position: relative;
  530 +
  531 + .content {
  532 + padding: 0 40rpx;
  533 +
  534 + .title {
  535 + padding: 24rpx 0;
  536 + font-size: 28rpx;
  537 + line-height: 36rpx;
  538 + color: #202131;
  539 + }
  540 +
  541 + .scroll {
  542 + max-height: 60vh;
  543 +
  544 + .item {
  545 +
  546 + view {
  547 + display: flex;
  548 + flex-flow: row wrap;
  549 + align-items: center;
  550 + width: 500rpx;
  551 + height: 74rpx;
  552 + border-radius: 4rpx;
  553 + border: 2rpx solid #C1C1C9;
  554 + margin: 0 10rpx 20rpx;
  555 + font-size: 24rpx;
  556 + line-height: 32rpx;
  557 + color: #C0C0C9;
  558 + padding: 16rpx 20rpx;
  559 + }
  560 +
  561 + .selectItem {
  562 + background-color: #06B079;
  563 + color: #FFFFFF;
  564 + border: 2rpx solid #06B079;
  565 + }
  566 + }
  567 + }
  568 +
  569 + .time {
  570 + padding: 40rpx 0 0 0;
  571 + }
  572 +
  573 + .switch {
  574 + display: flex;
  575 + flex-flow: row nowrap;
  576 + justify-content: space-between;
  577 + padding: 40rpx 0 0 0;
  578 +
  579 + text {
  580 + font-size: 28rpx;
  581 + line-height: 36rpx;
  582 + color: #202131;
  583 + }
  584 + }
  585 +
  586 +
  587 + }
  588 +
  589 + .footer {
  590 + width: 560rpx;
  591 + height: 96rpx;
  592 + padding: 28rpx 40rpx;
  593 + background: #FFFFFF;
  594 + position: fixed;
  595 + bottom: 0;
  596 + right: 0;
  597 + z-index: 99;
  598 + border-top: 2rpx solid #E2E2E8;
  599 +
  600 + view {
  601 + display: inline-block;
  602 + }
  603 +
  604 + .left_btn {
  605 + width: 194rpx;
  606 + margin: 0 20rpx 0 0;
  607 + }
  608 +
  609 + .right_btn {
  610 + width: 346rpx;
  611 + }
  612 + }
  613 + }
  614 + }
  615 +</style>
... ...
  1 +<template>
  2 + <view class="registration_detail">
  3 +
  4 + <view class="box student_info">
  5 + <view class="title">学生信息</view>
  6 + <view class="item">
  7 + <text>学生姓名</text>
  8 + <text>{{registrationDetail.studentName}}</text>
  9 + </view>
  10 + <view class="item">
  11 + <text>手机号</text>
  12 + <text>{{registrationDetail.studentPhone}}</text>
  13 + </view>
  14 + <view class="item">
  15 + <text>学号</text>
  16 + <text>{{registrationDetail.studentNumber}}</text>
  17 + </view>
  18 + <view class="item">
  19 + <text>班级</text>
  20 + <text>{{registrationDetail.classInfo}}</text>
  21 + </view>
  22 +
  23 + <view class="icon_item">
  24 + <u-icon size="32rpx" label="实习项目" labelSize="28rpx" labelColor="#909097"
  25 + name="/static/img/home/internshipProgramIcon.png"></u-icon>
  26 + <text>{{registrationDetail.projectName}}</text>
  27 + </view>
  28 +
  29 + <view class="border_top item">
  30 + <text>申请时间</text>
  31 + <text>{{timeFormat(registrationDetail.applyTime, 'yyyy-mm-dd hh:MM')}}</text>
  32 + </view>
  33 + </view>
  34 +
  35 + <view class="box company_info">
  36 + <view class="title">单位信息</view>
  37 + <view class="icon_item">
  38 + <u-icon size="32rpx" label="实习单位" labelSize="28rpx" labelColor="#909097"
  39 + name="/static/img/home/internshipUnitIcon.png"></u-icon>
  40 + <text>{{registrationDetail.companyName}}</text>
  41 + </view>
  42 + <view class="icon_item">
  43 + <u-icon size="32rpx" label="实习岗位" labelSize="28rpx" labelColor="#909097"
  44 + name="/static/img/home/internshipJobIcon.png"></u-icon>
  45 + <text>{{registrationDetail.jobName}}</text>
  46 + </view>
  47 + <view class="border_top item">
  48 + <text>联系人</text>
  49 + <text>{{jobDetail.contactName}}</text>
  50 + </view>
  51 + <view class="item">
  52 + <text>联系电话</text>
  53 + <text>{{jobDetail.contactPhone}}</text>
  54 + </view>
  55 + <view class="item">
  56 + <text>所在地区</text>
  57 + <text>{{address}}</text>
  58 + </view>
  59 + <view class="item">
  60 + <text>详细地址</text>
  61 + <text>{{jobDetail.workSite}}</text>
  62 + </view>
  63 + </view>
  64 +
  65 + <view class="box status">
  66 + <view class="title">状态</view>
  67 + <view class="item">
  68 + <text>审核状态</text>
  69 + <text>{{reviewStatus}}</text>
  70 + </view>
  71 + <view class="item">
  72 + <text>审核人</text>
  73 + <text>{{registrationDetail.auditTeacherName}}</text>
  74 + </view>
  75 + <view class="item">
  76 + <text>接受状态</text>
  77 + <text>{{receiveStatus}}</text>
  78 + </view>
  79 + </view>
  80 +
  81 + <view class="footer" v-if="registrationDetail.status == 'wait'">
  82 + <view class="left_btn">
  83 + <c-button type="cancel" text="审核拒绝" @click="handelCancel">
  84 + </c-button>
  85 + </view>
  86 + <view class="right_btn">
  87 + <c-button type="confirm" text="审核通过" @click="hancelSubmit">
  88 + </c-button>
  89 + </view>
  90 + </view>
  91 + </view>
  92 +</template>
  93 +
  94 +<script>
  95 + import {
  96 + getRegistrationDetailApi,
  97 + putRegistrationReviewApi,
  98 + } from '@/config/api.js';
  99 +
  100 + export default {
  101 + data() {
  102 + return {
  103 + registrationDetail: {},
  104 + }
  105 + },
  106 +
  107 + onLoad(option) {
  108 + getRegistrationDetailApi(option.id).then(data => {
  109 + if (data) {
  110 + console.log(data)
  111 + this.registrationDetail = data
  112 + }
  113 + })
  114 +
  115 + },
  116 +
  117 + onShow(options) {
  118 +
  119 + },
  120 +
  121 + computed: {
  122 + jobDetail: function() {
  123 + let {
  124 + jobDetail = {}
  125 + } = this.registrationDetail
  126 + return jobDetail;
  127 + },
  128 +
  129 + address: function() {
  130 + return this.jobDetail && this.jobDetail.province ?
  131 + `${this.jobDetail.province}/${this.jobDetail.city}/${this.jobDetail.district}` : '';
  132 +
  133 + },
  134 +
  135 + reviewStatus: function() {
  136 + return this.registrationDetail.status == 'apply' ? '待报名' :
  137 + this.registrationDetail.status == 'wait' ? '待审核' :
  138 + this.registrationDetail.status == 'pass' ? '已审核' :
  139 + this.registrationDetail.status == 'reject' ? '已拒绝' : '';
  140 + },
  141 +
  142 + receiveStatus: function() {
  143 + return this.registrationDetail.receiveStatus == 'received' ? '已接收' :
  144 + this.registrationDetail.receiveStatus == 'wait' ? '待处理' :
  145 + this.registrationDetail.receiveStatus == 'reject' ? '已拒绝' :
  146 + '';
  147 + },
  148 + },
  149 +
  150 + methods: {
  151 + timeFormat(timestamp, format = 'yyyy-mm-dd') {
  152 + return timestamp > 0 ? uni.$u.timeFormat(timestamp, format) : '--'
  153 + },
  154 +
  155 + handelCancel() {
  156 + putRegistrationReviewApi({
  157 + formIds: [this.registrationDetail.id],
  158 + status: 'reject',
  159 + }).then(data => {
  160 + if (data) {
  161 + uni.navigateBack({
  162 + delta: 1
  163 + });
  164 + }
  165 + })
  166 + },
  167 +
  168 + hancelSubmit() {
  169 + putRegistrationReviewApi({
  170 + formIds: [this.registrationDetail.id],
  171 + status: 'pass',
  172 + }).then(data => {
  173 + if (data) {
  174 + uni.navigateBack({
  175 + delta: 1
  176 + });
  177 + }
  178 + })
  179 + },
  180 + }
  181 + }
  182 +</script>
  183 +
  184 +<style lang="scss" scoped>
  185 + .registration_detail {
  186 + width: 100%;
  187 + min-height: 100%;
  188 + height: auto;
  189 + padding: 20rpx 0 194rpx 0;
  190 + background-color: #F7F7F7;
  191 +
  192 + .box {
  193 + width: 630rpx;
  194 + margin: 0 auto 20rpx;
  195 + padding: 30rpx 30rpx 12rpx 30rpx;
  196 + border-radius: 12rpx;
  197 + background-color: #FFFFFF;
  198 +
  199 + .title {
  200 + font-size: 32rpx;
  201 + line-height: 32rpx;
  202 + color: #202131;
  203 + margin: 0 0 30rpx 0;
  204 + }
  205 +
  206 + .title::before {
  207 + content: "";
  208 + display: inline-block;
  209 + width: 6rpx;
  210 + height: 32rpx;
  211 + background-color: #06B079;
  212 + margin: 0 12rpx 0 0;
  213 + position: relative;
  214 + top: 4rpx;
  215 + border-radius: 8rpx;
  216 + }
  217 +
  218 + .icon_item {
  219 + display: flex;
  220 + flex-flow: row nowrap;
  221 + margin: 0 0 24rpx 0;
  222 +
  223 + text {
  224 + display: inline-block;
  225 + width: 460rpx;
  226 + font-size: 28rpx;
  227 + line-height: 48rpx;
  228 + color: #202131;
  229 + margin: 0 0 0 40rpx;
  230 + }
  231 + }
  232 +
  233 + .item {
  234 + margin: 0 0 24rpx 0;
  235 +
  236 + text:first-child {
  237 + display: inline-block;
  238 + width: 112rpx;
  239 + text-align: justify;
  240 + text-align-last: justify;
  241 + font-size: 28rpx;
  242 + line-height: 48rpx;
  243 + color: #909097;
  244 + vertical-align: top;
  245 + }
  246 +
  247 + text:last-child {
  248 + display: inline-block;
  249 + width: 440rpx;
  250 + font-size: 28rpx;
  251 + line-height: 48rpx;
  252 + color: #202131;
  253 + margin: 0 0 0 78rpx;
  254 + }
  255 + }
  256 +
  257 + .border_top {
  258 + border-top: 2rpx solid #E2E2E8;
  259 + padding: 28rpx 0 0 0;
  260 + }
  261 + }
  262 +
  263 + .footer {
  264 + width: 100%;
  265 + height: 96rpx;
  266 + padding: 28rpx 30rpx;
  267 + background: #FFFFFF;
  268 + position: fixed;
  269 + bottom: 0;
  270 + left: 0;
  271 + z-index: 99;
  272 + border-top: 2rpx solid #E2E2E8;
  273 +
  274 + view {
  275 + display: inline-block;
  276 + }
  277 +
  278 + .left_btn {
  279 + width: 330rpx;
  280 + margin: 0 30rpx 0 0;
  281 + }
  282 +
  283 + .right_btn {
  284 + width: 330rpx;
  285 + }
  286 + }
  287 +
  288 + }
  289 +</style>
... ...
  1 +<template>
  2 + <view class="registration_review">
  3 + <view class="search_box">
  4 + <view class="check">
  5 + <u-checkbox-group v-model="checkboxValue" placement="column" @change="checkboxChange">
  6 + <u-checkbox :customStyle="{marginBottom: '8px'}" shape="circle"
  7 + v-for="(item, index) in checkboxList" :key="index" :label="item.name" :name="item.name"
  8 + activeColor="#06B079" size="28rpx" labelSize="28rpx" labelColor="#202131">
  9 + </u-checkbox>
  10 + </u-checkbox-group>
  11 + </view>
  12 +
  13 + <view class="search">
  14 + <u-search placeholder="请输入学生姓名/学号/手机号" placeholderColor="#C1C1C9" searchIconSize="36" height="64rpx"
  15 + bgColor="#F4F4F4" :showAction="false" shape="square" v-model="keyword" @search="handelSearch">
  16 + </u-search>
  17 + </view>
  18 +
  19 + <u-icon slot="icon" size="40" :name="'/static/img/home/selectIcon.png'" @click="show = true"></u-icon>
  20 + </view>
  21 +
  22 + <view class="list_box" v-if="list.length > 0">
  23 + <view class="item" v-for="(item, i) in list" :key="i" @click="handelDetail(item)">
  24 +
  25 + <view class="bg_image" v-if="item.status == 'wait'">
  26 + <u-image src="/static/img/home/labelBgGreen.png" width="142rpx" height="48rpx"></u-image>
  27 + <text>待审核</text>
  28 + </view>
  29 +
  30 + <view class="bg_image" v-if="item.status == 'pass'">
  31 + <u-image src="/static/img/home/labelBgGrey.png" width="142rpx" height="48rpx"></u-image>
  32 + <text>已通过</text>
  33 + </view>
  34 +
  35 + <view class="bg_image" v-if="item.status == 'reject'">
  36 + <u-image src="/static/img/home/labelBgGrey.png" width="142rpx" height="48rpx"></u-image>
  37 + <text>已拒绝</text>
  38 + </view>
  39 +
  40 + <view class="name">{{item.studentName}}</view>
  41 + <view class="company">
  42 + <u-icon size="32rpx" name="/static/img/home/internshipUnitIcon.png"></u-icon>
  43 + <text>实习单位</text>
  44 + <text>{{item.companyName || '--'}}</text>
  45 + </view>
  46 + <view class="company position">
  47 + <u-icon size="32rpx" name="/static/img/home/internshipJobIcon.png"></u-icon>
  48 + <text>实习岗位</text>
  49 + <text>{{item.jobName|| '--'}}</text>
  50 + </view>
  51 +
  52 + <view class="time">
  53 + <text>申请时间</text>
  54 + <text>{{timeFormat(item.applyTime, 'yyyy-mm-dd hh:MM')}}</text>
  55 + </view>
  56 +
  57 + </view>
  58 + <c-loading :loading="loading"></c-loading>
  59 + </view>
  60 + <view v-else class="no_data">
  61 + <c-no-data></c-no-data>
  62 + </view>
  63 +
  64 + <u-popup :show="show" mode="right" @close="close" @open="open" :closeOnClickOverlay="false">
  65 + <view class="popup_search">
  66 + <view class="content">
  67 + <view class="title">按项目筛选</view>
  68 + <scroll-view class="scroll" scroll-y="true">
  69 + <view class="item" v-for="(item, i) in projectList" :key="i" @click="handelClick(item)">
  70 + <view class="selectItem" v-if="item.id == projectId">
  71 + <text>{{item.name}}</text>
  72 + </view>
  73 + <view v-else>
  74 + <text>{{item.name}}</text>
  75 + </view>
  76 + </view>
  77 + </scroll-view>
  78 + <view class="switch">
  79 + <text>待审核</text>
  80 + <u-switch v-model="switchValue" size="48" activeColor="#06B079" @change="handelChange">
  81 + </u-switch>
  82 + </view>
  83 + </view>
  84 +
  85 + <view class="footer">
  86 + <view class="left_btn">
  87 + <c-button type="cancel" text="重置" @click="handelCancel">
  88 + </c-button>
  89 + </view>
  90 + <view class="right_btn">
  91 + <c-button type="confirm" text="确定" @click="hancelSubmit">
  92 + </c-button>
  93 + </view>
  94 + </view>
  95 +
  96 + </view>
  97 + </u-popup>
  98 +
  99 + </view>
  100 +</template>
  101 +
  102 +<script>
  103 + import {
  104 + mapGetters,
  105 + mapState,
  106 + mapActions
  107 + } from 'vuex'
  108 + import listMixin from "@/common/mixins/list-mixin.js";
  109 +
  110 + import {
  111 + getRegistrationReviewApi,
  112 + getProjectListApi,
  113 + } from '@/config/api.js';
  114 +
  115 + export default {
  116 + mixins: [listMixin],
  117 + data() {
  118 + return {
  119 + checkboxValue: [],
  120 + // 基本案列数据
  121 + checkboxList: [{
  122 + name: '待审核',
  123 + disabled: false
  124 + }],
  125 + keyword: '',
  126 + show: false,
  127 + list: [], //列表必须为key list的数组
  128 + search: {
  129 + //搜索对象必须为key search的对象
  130 + keySearch: "",
  131 + status: 'wait,pass,reject',
  132 +
  133 + },
  134 + projectId: '',
  135 + switchValue: false,
  136 + }
  137 + },
  138 +
  139 + onLoad(option) {
  140 + console.log(option)
  141 + this.$store.dispatch(`home/getProjectList`, {
  142 + pageSize: -1,
  143 + })
  144 +
  145 + this.search.keySearch = '';
  146 +
  147 + if (option && option.status) {
  148 + this.search.status = 'wait';
  149 + this.checkboxValue = ['待审核'];
  150 + this.switchValue = true;
  151 + }
  152 +
  153 + this.finished = false;
  154 + this.loading = "loadmore";
  155 + this.page = 0;
  156 + this.list = [];
  157 +
  158 + },
  159 +
  160 + onShow() {
  161 + this._getList();
  162 + },
  163 +
  164 + computed: {
  165 + ...mapState('home', {
  166 + // 箭头函数可使代码更简练
  167 + projectList: 'projectList',
  168 +
  169 + }),
  170 +
  171 + },
  172 +
  173 + methods: {
  174 +
  175 + handelDetail(record) {
  176 + this.$u.route({
  177 + url: `pages/main/home/registrationDetail/registrationDetail?&id=${record.id}`
  178 + })
  179 + },
  180 +
  181 + timeFormat(timestamp, format = 'yyyy-mm-dd') {
  182 + return timestamp > 0 ? uni.$u.timeFormat(timestamp, format) : '--'
  183 + },
  184 +
  185 + checkboxChange(n) {
  186 + console.log('change', n);
  187 +
  188 + this.search.status = n.length > 0 ? 'wait' : 'wait,pass,reject';
  189 +
  190 + this.switchValue = n.length > 0 ? true : false;
  191 +
  192 + this.finished = false;
  193 + this.loading = "loadmore";
  194 + this.page = 0;
  195 + this.list = [];
  196 + this._getList();
  197 + },
  198 +
  199 + handelSearch(value) {
  200 + this.finished = false;
  201 + this.loading = "loadmore";
  202 + this.page = 0;
  203 + this.list = [];
  204 + this._getList();
  205 + },
  206 +
  207 + open() {
  208 + // console.log('open');
  209 + },
  210 + close() {
  211 + this.show = false
  212 + // console.log('close');
  213 + },
  214 + // scroll-view到底部加载更多
  215 + onreachBottom() {},
  216 + // 搜索
  217 + searchSubmit() {
  218 + // 调用混合搜索
  219 + this._searchData();
  220 + },
  221 + // 模拟后端分页
  222 + async getData(requestParams) {
  223 + const {
  224 + search = {}
  225 + } = requestParams;
  226 +
  227 + let params = {};
  228 + params.pageNumber = requestParams.page + 1;
  229 + params.pageSize = 5;
  230 +
  231 + if (search.status) {
  232 + params.status = search.status;
  233 + }
  234 +
  235 + if (this.keyword) {
  236 + params.keySearch = this.keyword
  237 + }
  238 +
  239 + if (this.projectId) {
  240 + params.projectId = this.projectId
  241 + }
  242 +
  243 + return await getRegistrationReviewApi(params);
  244 + },
  245 + // 数据请求(没错就是这么少的代码)
  246 + async _getList() {
  247 + if (this.page == 0) {
  248 + this.list = [];
  249 + }
  250 +
  251 + // 根据实际情况修改自己修改key
  252 + let result = await this.getData({
  253 + page: this.page, // 传入页码
  254 + size: this.size, // 传入每页条数
  255 + search: this.search, // 传入搜索的对象
  256 + });
  257 +
  258 + this.total = result.total;
  259 +
  260 + if (this.list.length == 0 && result.records.length == 0) {
  261 + this.shownoData = false
  262 + } else {
  263 + this.shownoData = true
  264 + }
  265 +
  266 + this.list = this.list.concat(result.records)
  267 +
  268 + // 判断是否全部加载完成
  269 + if (this.total == this.list.length) {
  270 + this.finished = true;
  271 + this.loading = 'nomore';
  272 + } else {
  273 + this.loading = 'loadmore';
  274 + }
  275 + },
  276 +
  277 + handelClick(values) {
  278 + console.log(values);
  279 + this.projectId = values.id;
  280 + },
  281 +
  282 + handelChange(e) {
  283 + console.log(e)
  284 + this.checkboxValue = e ? ['待审核'] : [];
  285 + this.search.status = e ? 'wait' : 'wait,pass,reject';
  286 +
  287 + },
  288 +
  289 + handelCancel() {
  290 + this.switchValue = false;
  291 + this.projectId = '';
  292 + },
  293 +
  294 + hancelSubmit() {
  295 + this.finished = false;
  296 + this.loading = "loadmore";
  297 + this.page = 0;
  298 + this.list = [];
  299 + this._getList();
  300 +
  301 + this.show = false;
  302 + },
  303 +
  304 + }
  305 + }
  306 +</script>
  307 +
  308 +<style lang="scss" scoped>
  309 + .registration_review {
  310 + width: 100%;
  311 + min-height: 100%;
  312 + height: auto;
  313 + background-color: #F7F7F7;
  314 +
  315 + .search_box {
  316 + padding: 36rpx 30rpx 12rpx;
  317 + background-color: #FFFFFF;
  318 + display: flex;
  319 + flex-flow: row nowrap;
  320 + justify-content: space-between;
  321 +
  322 + .check {
  323 + padding: 20rpx 0 0 0;
  324 + }
  325 +
  326 + .search {
  327 + width: 468rpx;
  328 + }
  329 + }
  330 +
  331 + .list_box {
  332 + padding: 0 0 50rpx 0;
  333 +
  334 + .item {
  335 + position: relative;
  336 + width: 630rpx;
  337 + margin: 30rpx auto;
  338 + padding: 30rpx;
  339 + border-radius: 12rpx;
  340 + background-color: #FFFFFF;
  341 +
  342 + .bg_image {
  343 + position: absolute;
  344 + top: 0;
  345 + right: 0;
  346 +
  347 + text {
  348 + position: absolute;
  349 + top: 12rpx;
  350 + right: 30rpx;
  351 + font-size: 24rpx;
  352 + line-height: 24rpx;
  353 + color: #FFFFFF;
  354 + }
  355 + }
  356 +
  357 + .name {
  358 + font-size: 32rpx;
  359 + line-height: 44rpx;
  360 + color: #202131;
  361 + font-weight: 500;
  362 + margin: 0 0 30rpx 0;
  363 + }
  364 +
  365 + .company {
  366 + display: flex;
  367 + flex-flow: row nowrap;
  368 + margin: 0 0 30rpx 0;
  369 +
  370 + text {
  371 + font-size: 28rpx;
  372 + line-height: 32rpx;
  373 + color: #909097;
  374 + margin: 0 0 0 16rpx;
  375 + }
  376 +
  377 + text:last-child {
  378 + color: #202131;
  379 + margin: 0 0 0 30rpx;
  380 + }
  381 + }
  382 +
  383 + .time {
  384 + border-top: 2rpx solid #E2E2E8;
  385 + padding: 28rpx 0 0 0;
  386 +
  387 + text {
  388 + font-size: 28rpx;
  389 + line-height: 32rpx;
  390 + color: #909097;
  391 + }
  392 +
  393 + text:last-child {
  394 + color: #202131;
  395 + margin: 0 0 0 78rpx;
  396 + }
  397 + }
  398 + }
  399 + }
  400 +
  401 + .popup_search {
  402 + width: 640rpx;
  403 + position: relative;
  404 +
  405 + .content {
  406 + padding: 0 40rpx;
  407 +
  408 + .title {
  409 + padding: 24rpx 0;
  410 + font-size: 28rpx;
  411 + line-height: 36rpx;
  412 + color: #202131;
  413 + }
  414 +
  415 + .scroll {
  416 + max-height: 60vh;
  417 +
  418 + .item {
  419 +
  420 + view {
  421 + display: flex;
  422 + flex-flow: row wrap;
  423 + align-items: center;
  424 + width: 500rpx;
  425 + height: 74rpx;
  426 + border-radius: 4rpx;
  427 + border: 2rpx solid #C1C1C9;
  428 + margin: 0 10rpx 20rpx;
  429 + font-size: 24rpx;
  430 + line-height: 32rpx;
  431 + color: #C0C0C9;
  432 + padding: 16rpx 20rpx;
  433 + }
  434 +
  435 + .selectItem {
  436 + background-color: #06B079;
  437 + color: #FFFFFF;
  438 + border: 2rpx solid #06B079;
  439 + }
  440 + }
  441 + }
  442 +
  443 + .switch {
  444 + display: flex;
  445 + flex-flow: row nowrap;
  446 + justify-content: space-between;
  447 + padding: 40rpx 0 0 0;
  448 +
  449 + text {
  450 + font-size: 28rpx;
  451 + line-height: 36rpx;
  452 + color: #202131;
  453 + }
  454 + }
  455 +
  456 +
  457 + }
  458 +
  459 + .footer {
  460 + width: 560rpx;
  461 + height: 96rpx;
  462 + padding: 28rpx 40rpx;
  463 + background: #FFFFFF;
  464 + position: fixed;
  465 + bottom: 0;
  466 + right: 0;
  467 + z-index: 99;
  468 + border-top: 2rpx solid #E2E2E8;
  469 +
  470 + view {
  471 + display: inline-block;
  472 + }
  473 +
  474 + .left_btn {
  475 + width: 194rpx;
  476 + margin: 0 20rpx 0 0;
  477 + }
  478 +
  479 + .right_btn {
  480 + width: 346rpx;
  481 + }
  482 + }
  483 + }
  484 + }
  485 +</style>
... ...
  1 +<template>
  2 + <view class="report_detail">
  3 + <view v-if="id">
  4 + <view class="report_info">
  5 +
  6 + <view class="bg_image" v-if="detail.status == 'stay_examine'">
  7 + <u-image src="/static/img/home/labelBgGreen.png" width="142rpx" height="48rpx"></u-image>
  8 + <text>待审核</text>
  9 + </view>
  10 +
  11 + <view class="bg_image" v-else-if="detail.status == 'adopt'">
  12 + <u-image src="/static/img/home/labelBgGrey.png" width="142rpx" height="48rpx"></u-image>
  13 + <text>已通过</text>
  14 + </view>
  15 +
  16 + <view class="bg_image" v-else>
  17 + <u-image src="/static/img/home/labelBgGrey.png" width="142rpx" height="48rpx"></u-image>
  18 + <text>已退回</text>
  19 + </view>
  20 +
  21 + <view class="info">
  22 + <view class="avatar">{{getNameLastTwo(detail.studentName)}}</view>
  23 + <view class="title_name">
  24 + <view class="title">{{detail.title}}</view>
  25 + <view class="name">
  26 + <text>学生姓名</text>
  27 + <text>{{detail.studentName}}</text>
  28 + </view>
  29 + </view>
  30 + </view>
  31 +
  32 + <view class="time_record">
  33 + <text>
  34 + {{timeFormat(detail.createdTime, 'yyyy-mm-dd hh:MM')}}
  35 + </text>
  36 + <view class="record" @click="handelRecord">
  37 + <text>审批记录</text>
  38 + <u-icon :style="{margin:'0 0 0 8rpx'}" name="arrow-right" color="#06B079" size="28"></u-icon>
  39 + </view>
  40 + </view>
  41 + </view>
  42 +
  43 + <view class="box">
  44 + <view class="title">附件</view>
  45 + <view class="item" v-for="(item,index) in reportAttachments">
  46 + <text>报告附件</text>
  47 + <text :style="{color:'#06B079'}" @click="openLink(item)">{{item.filename}}</text>
  48 + </view>
  49 + </view>
  50 +
  51 + <view>
  52 + <view class="box file" v-if="detail.status == 'stay_examine'">
  53 + <view class="title">反馈附件</view>
  54 + <view class="icon_item" v-for="(item,index) in attachments">
  55 + <text @click="openLink(item)">{{item.filename}}</text>
  56 + <u-icon name="close" @click="deletePic(index)" width="28rpx" color="red" size="28"></u-icon>
  57 + </view>
  58 + <view class="icon_box" @click="handelFile">
  59 + <u-icon name="plus" width="28rpx" label="添加" labelPos="bottom" labelColor="#06B079" color="#06B079"
  60 + size="28"></u-icon>
  61 + </view>
  62 + </view>
  63 +
  64 + <view class="box file" v-else>
  65 + <view class="title">反馈附件</view>
  66 + <view class="icon_item" v-for="(item,index) in reviewAttachments">
  67 + <text @click="openLink(item)">{{item.filename}}</text>
  68 + </view>
  69 + </view>
  70 + </view>
  71 +
  72 + <view>
  73 + <view class="box" :style="{padding:'30rpx'}" v-if="detail.status == 'stay_examine'">
  74 + <view class="title">反馈信息</view>
  75 + <u-textarea v-model="textarea" placeholder="请输入内容" count></u-textarea>
  76 + </view>
  77 + <view class="box" :style="{padding:'30rpx'}" v-else>
  78 + <view class="title">反馈信息</view>
  79 + <u-textarea v-model="textarea" :disabled="true" placeholder="请输入内容" count></u-textarea>
  80 + </view>
  81 + </view>
  82 +
  83 + <view class="footer" v-if="detail.status == 'stay_examine'">
  84 + <view class="left_btn">
  85 + <c-button type="cancel" text="退回" @click="handelCancel">
  86 + </c-button>
  87 + </view>
  88 + <view class="right_btn">
  89 + <c-button type="confirm" text="通过" @click="hancelSubmit">
  90 + </c-button>
  91 + </view>
  92 + </view>
  93 + </view>
  94 +
  95 + <view v-else class="no_data">
  96 + <c-no-data></c-no-data>
  97 + </view>
  98 +
  99 + </view>
  100 +</template>
  101 +
  102 +<script>
  103 + import {
  104 + mapGetters,
  105 + mapState,
  106 + mapActions
  107 + } from 'vuex'
  108 + import listMixin from "@/common/mixins/list-mixin.js";
  109 +
  110 + import {
  111 + getOssInitApi,
  112 + getImgUrlApi,
  113 + getReportDetailApi,
  114 + putReportReviewApi,
  115 + } from '@/config/api.js';
  116 +
  117 + export default {
  118 + data() {
  119 + return {
  120 + id: '',
  121 + formId: '',
  122 + detail: {},
  123 + reportAttachments: [],
  124 + reviewAttachments: [],
  125 + ossInit: {},
  126 + mFileDir: "yxly",
  127 + mFileType: ".doc",
  128 + fileList: [],
  129 + attachments: [],
  130 + show: false,
  131 + selector: ["上传微信文件", "上传电脑文件"],
  132 + maxCount: 9,
  133 + textarea: '',
  134 + }
  135 + },
  136 +
  137 + onLoad(option) {
  138 + this.id = option.id;
  139 + this.formId = option.formId;
  140 +
  141 + if(!option.id) {
  142 + return;
  143 + }
  144 +
  145 + getOssInitApi({
  146 + "uploadFileType": "report"
  147 + }).then(res => {
  148 + this.ossInit = res
  149 + })
  150 +
  151 + getReportDetailApi(option.id).then(data => {
  152 + if (data) {
  153 + this.detail = data;
  154 + if (data.reportAttachments) {
  155 + this.reportAttachments = data.reportAttachments ? JSON.parse(data.reportAttachments) : [];
  156 + this.reviewAttachments = data.reviewAttachments ? JSON.parse(data.reviewAttachments) : [];
  157 + this.textarea = data.review;
  158 + }
  159 + }
  160 + })
  161 + },
  162 +
  163 + methods: {
  164 + getNameLastTwo(value) {
  165 + if (value && value.length > 3) {
  166 + return value.substring(value.length - 3)
  167 + } else {
  168 + return value;
  169 + }
  170 + },
  171 +
  172 + overflowHide(value) {
  173 + if (value && value.length > 4) {
  174 + return `${value.slice(0, 4)}...`
  175 + } else {
  176 + return value;
  177 + }
  178 + },
  179 +
  180 + timeFormat(timestamp, format = 'yyyy-mm-dd') {
  181 + return timestamp > 0 ? uni.$u.timeFormat(timestamp, format) : '--'
  182 + },
  183 +
  184 + handelRecord() {
  185 + this.$u.route({
  186 + url: `pages/main/home/approvalRecord/approvalRecord?formId=${this.detail.formId}`
  187 + })
  188 + },
  189 +
  190 + openLink(e) {
  191 + var _this = this
  192 + this.mFileDir = e.filename.substring(0, e.filename.lastIndexOf('.'))
  193 + this.mFileType = e.filename.substring(e.filename.lastIndexOf('.'), e.filename.length)
  194 + getImgUrlApi({
  195 + bucket: e.bucket,
  196 + filePath: e.object
  197 + }).then(data => {
  198 + console.log("data...", data)
  199 + if (e.mime_type.indexOf("image") != -1) {
  200 + _this.openImage(data.url)
  201 + } else {
  202 + uni.downloadFile({
  203 + url: data.url,
  204 + filePath: wx.env.USER_DATA_PATH + '/' + _this.mFileDir + this.mFileType,
  205 + success: (res) => {
  206 + if (res.statusCode === 200) {
  207 + uni.showLoading();
  208 + console.log('download succ', res)
  209 + let fileMgr = wx.getFileSystemManager();
  210 + let filePath = res.filePath
  211 + uni.saveFile({
  212 + tempFilePath: filePath,
  213 + success: function(res) {
  214 + var savedFilePath = res.savedFilePath;
  215 + /* 删除缓存 */
  216 + fileMgr.unlink({
  217 + filePath: wx.env.USER_DATA_PATH +
  218 + '/' +
  219 + _this.mFileDir + _this
  220 + .mFileType,
  221 + success: function(res) {
  222 + console.log(
  223 + 'unlink success:',
  224 + res);
  225 + }
  226 + })
  227 + _this.openDoc()
  228 + },
  229 + fail: function(res) {
  230 + console.log('save fail', res);
  231 + _this.createFile()
  232 + }
  233 + })
  234 + }
  235 + }
  236 + });
  237 + }
  238 + })
  239 + },
  240 +
  241 + createFile() {
  242 + let fileMgr = wx.getFileSystemManager();
  243 + var _this = this
  244 + //利用access方法判断文件是否可用
  245 + fileMgr.access({
  246 + path: wx.env.USER_DATA_PATH + '/' + _this.mFileDir,
  247 + success: (res) => {
  248 + console.log('check success:', res);
  249 + _this.openDoc()
  250 + },
  251 + fail: (res) => {
  252 + console.log('check fail.', res);
  253 + fileMgr.mkdir({
  254 + dirPath: wx.env.USER_DATA_PATH + '/' + _this.mFileDir,
  255 + success: (res) => {
  256 + console.log('mk dir success:', res);
  257 + _this.openDoc()
  258 + },
  259 + fail: (res) => {
  260 + console.log('mk dir fail:', res);
  261 + uni.hideLoading();
  262 + }
  263 + });
  264 + }
  265 + });
  266 + },
  267 +
  268 + openDoc() {
  269 + uni.openDocument({
  270 + filePath: wx.env.USER_DATA_PATH + '/' + this.mFileDir + this.mFileType,
  271 + showMenu: true,
  272 + success: function(res) {
  273 + uni.hideLoading();
  274 + console.log('openDoc succ');
  275 + }
  276 + });
  277 + },
  278 +
  279 + openImage(imgPath) {
  280 + let array = new Array(1).fill(imgPath);
  281 + uni.previewImage({
  282 + urls: array,
  283 + success(res) {
  284 + console.log('openImage success');
  285 + },
  286 + fail(res) {
  287 + console.log('openImage fail:', res);
  288 + }
  289 + });
  290 + },
  291 +
  292 + deletePic(index) {
  293 + this.attachments.splice(index, 1)
  294 + },
  295 +
  296 + handelFile() {
  297 + let _this = this;
  298 +
  299 + wx.chooseMessageFile({
  300 + count: 9,
  301 + extension: ['.doc', '.pdf', '.docx', '.png', 'jpg', 'xlsx', 'xls', '.pptx'],
  302 + success(res) {
  303 + console.log(res.tempFiles);
  304 +
  305 + let files = res.tempFiles;
  306 +
  307 + for (var i = 0; i < files.length; i++) {
  308 + uni.uploadFile({
  309 + url: _this.vuex_ossUrl,
  310 + filePath: files[i].path,
  311 + name: "file",
  312 + formData: {
  313 + 'key': `${_this.ossInit.dir}${new Date().getTime()}/` + files[i].name,
  314 + 'action': `${_this.ossInit.host}`,
  315 + 'OSSAccessKeyId': _this.ossInit.accessId,
  316 + 'policy': _this.ossInit.policy,
  317 + 'signature': _this.ossInit.signature,
  318 + 'callback': _this.ossInit.callback,
  319 + },
  320 + success: (uploadFileRes) => {
  321 + console.log('uploadFileRes...', uploadFileRes)
  322 + _this.attachments.push(JSON.parse(uploadFileRes.data))
  323 +
  324 + },
  325 + complete: (res) => {
  326 + console.log('res...', res)
  327 + }
  328 + });
  329 + }
  330 +
  331 +
  332 + }
  333 + });
  334 + },
  335 +
  336 + handelCancel() {
  337 + putReportReviewApi(this.id, {
  338 + status: 'return',
  339 + reviewAttachments: JSON.stringify(this.attachments),
  340 + review: this.textarea,
  341 + }).then(data => {
  342 + if (data) {
  343 + uni.navigateBack({
  344 + delta: 1
  345 + });
  346 + }
  347 + })
  348 + },
  349 +
  350 + hancelSubmit() {
  351 + putReportReviewApi(this.id, {
  352 + status: 'adopt',
  353 + reviewAttachments: JSON.stringify(this.attachments),
  354 + review: this.textarea,
  355 + }).then(data => {
  356 + if (data) {
  357 + uni.navigateBack({
  358 + delta: 1
  359 + });
  360 + }
  361 + })
  362 + },
  363 + }
  364 + }
  365 +</script>
  366 +
  367 +<style lang="scss" scoped>
  368 + .report_detail {
  369 + width: 100%;
  370 + min-height: 100%;
  371 + height: auto;
  372 + background-color: #F7F7F7;
  373 + padding: 20rpx 0 150rpx 0;
  374 +
  375 + .report_info {
  376 + position: relative;
  377 + width: 630rpx;
  378 + margin: 0 auto;
  379 + padding: 30rpx;
  380 + border-radius: 12rpx;
  381 + background-color: #FFFFFF;
  382 +
  383 + .bg_image {
  384 + position: absolute;
  385 + top: 0;
  386 + right: 0;
  387 +
  388 + text {
  389 + position: absolute;
  390 + top: 12rpx;
  391 + right: 30rpx;
  392 + font-size: 24rpx;
  393 + line-height: 24rpx;
  394 + color: #FFFFFF;
  395 + }
  396 + }
  397 +
  398 + .info {
  399 + display: flex;
  400 + flex-flow: row nowrap;
  401 + align-items: center;
  402 + margin: 0 0 30rpx 0;
  403 +
  404 + .avatar {
  405 + width: 78rpx;
  406 + height: 94rpx;
  407 + padding: 0 8rpx;
  408 + border-radius: 4rpx;
  409 + background-color: #06B079;
  410 + font-size: 24rpx;
  411 + line-height: 94rpx;
  412 + color: #FFFFFF;
  413 + text-align: center;
  414 + }
  415 +
  416 + .title_name {
  417 + .title {
  418 + font-size: 32rpx;
  419 + line-height: 44rpx;
  420 + color: #202131;
  421 + font-weight: 500;
  422 + margin: 0 20rpx;
  423 + }
  424 +
  425 + .name {
  426 + padding: 8rpx 0 0 20rpx;
  427 + font-size: 28rpx;
  428 + line-height: 32rpx;
  429 + color: #909097;
  430 +
  431 + text:last-child {
  432 + padding: 0 0 0 30rpx;
  433 + color: #202131;
  434 + }
  435 + }
  436 + }
  437 +
  438 + }
  439 +
  440 + .time_record {
  441 + border-top: 2rpx solid #E2E2E8;
  442 + padding: 28rpx 0 0 0;
  443 + display: flex;
  444 + flex-flow: row nowrap;
  445 + justify-content: space-between;
  446 +
  447 + text {
  448 + font-size: 28rpx;
  449 + line-height: 32rpx;
  450 + color: #909097;
  451 + }
  452 +
  453 + .record {
  454 + display: flex;
  455 + flex-flow: row nowrap;
  456 +
  457 + text {
  458 + font-size: 24rpx;
  459 + line-height: 32rpx;
  460 + color: #06B079;
  461 + }
  462 + }
  463 + }
  464 + }
  465 +
  466 + .box {
  467 + width: 630rpx;
  468 + margin: 20rpx auto;
  469 + padding: 30rpx 30rpx 12rpx 30rpx;
  470 + border-radius: 12rpx;
  471 + background-color: #FFFFFF;
  472 +
  473 + .title {
  474 + font-size: 32rpx;
  475 + line-height: 32rpx;
  476 + color: #202131;
  477 + margin: 0 0 30rpx 0;
  478 + }
  479 +
  480 + .title::before {
  481 + content: "";
  482 + display: inline-block;
  483 + width: 6rpx;
  484 + height: 32rpx;
  485 + background-color: #06B079;
  486 + margin: 0 12rpx 0 0;
  487 + position: relative;
  488 + top: 4rpx;
  489 + border-radius: 8rpx;
  490 + }
  491 +
  492 +
  493 +
  494 + .item {
  495 + margin: 0 0 24rpx 0;
  496 +
  497 + text:first-child {
  498 + display: inline-block;
  499 + width: 112rpx;
  500 + text-align: justify;
  501 + text-align-last: justify;
  502 + font-size: 28rpx;
  503 + line-height: 48rpx;
  504 + color: #909097;
  505 + vertical-align: top;
  506 + }
  507 +
  508 + text:last-child {
  509 + display: inline-block;
  510 + width: 440rpx;
  511 + word-break: break-word;
  512 + font-size: 28rpx;
  513 + line-height: 48rpx;
  514 + color: #202131;
  515 + margin: 0 0 0 78rpx;
  516 + }
  517 + }
  518 +
  519 + .border_top {
  520 + border-top: 2rpx solid #E2E2E8;
  521 + padding: 28rpx 0 0 0;
  522 + }
  523 + }
  524 +
  525 + .file {
  526 +
  527 + .icon_item {
  528 + display: flex;
  529 + flex-flow: row wrap;
  530 + margin: 0 0 12rpx 0;
  531 +
  532 + text {
  533 + display: inline-block;
  534 + font-size: 28rpx;
  535 + line-height: 36rpx;
  536 + margin: 0 8rpx 12rpx 0;
  537 + color: #06B079;
  538 + }
  539 +
  540 + }
  541 +
  542 + .icon_box {
  543 + width: 70rpx;
  544 + border: 2rpx solid #06B079;
  545 + text-align: center;
  546 + margin: 0 auto 20rpx;
  547 + padding: 20rpx;
  548 +
  549 + text {
  550 + font-size: 34rpx;
  551 +
  552 + }
  553 + }
  554 + }
  555 +
  556 + .footer {
  557 + width: 100%;
  558 + height: 96rpx;
  559 + padding: 28rpx 30rpx;
  560 + background: #FFFFFF;
  561 + position: fixed;
  562 + bottom: 0;
  563 + left: 0;
  564 + z-index: 99;
  565 + border-top: 2rpx solid #E2E2E8;
  566 +
  567 + view {
  568 + display: inline-block;
  569 + }
  570 +
  571 + .left_btn {
  572 + width: 330rpx;
  573 + margin: 0 30rpx 0 0;
  574 + }
  575 +
  576 + .right_btn {
  577 + width: 330rpx;
  578 + }
  579 + }
  580 + }
  581 +</style>
... ...
  1 +<template>
  2 + <view class="registration_review">
  3 + <view class="search_box" v-if="!studentId">
  4 + <view class="top">
  5 + <view class="check">
  6 + <u-checkbox-group v-model="checkboxValue" placement="column" @change="checkboxChange">
  7 + <u-checkbox :customStyle="{marginBottom: '8px'}" shape="circle"
  8 + v-for="(item, index) in checkboxList" :key="index" :label="item.name" :name="item.name"
  9 + activeColor="#06B079" size="28rpx" labelSize="28rpx" labelColor="#202131">
  10 + </u-checkbox>
  11 + </u-checkbox-group>
  12 + </view>
  13 +
  14 + <view class="search">
  15 + <u-search placeholder="请输入学生姓名/学号/手机号" placeholderColor="#C1C1C9" searchIconSize="36" height="64rpx"
  16 + bgColor="#F4F4F4" :showAction="false" shape="square" v-model="keyword" @search="handelSearch">
  17 + </u-search>
  18 + </view>
  19 +
  20 + <u-icon slot="icon" size="40" :name="'/static/img/home/selectIcon.png'" @click="show = true"></u-icon>
  21 + </view>
  22 + </view>
  23 +
  24 + <view class="list_box" v-if="list.length > 0">
  25 + <view class="item" v-for="(item, i) in list" :key="i" @click="handelDetail(item)">
  26 +
  27 + <view class="bg_image" v-if="item.status == 'stay_examine'">
  28 + <u-image src="/static/img/home/labelBgGreen.png" width="142rpx" height="48rpx"></u-image>
  29 + <text>待审核</text>
  30 + </view>
  31 +
  32 + <view class="bg_image" v-else-if="item.status == 'adopt'">
  33 + <u-image src="/static/img/home/labelBgGrey.png" width="142rpx" height="48rpx"></u-image>
  34 + <text>已通过</text>
  35 + </view>
  36 +
  37 + <view class="bg_image" v-else>
  38 + <u-image src="/static/img/home/labelBgGrey.png" width="142rpx" height="48rpx"></u-image>
  39 + <text>已退回</text>
  40 + </view>
  41 +
  42 + <view class="info">
  43 + <view class="avatar">{{getNameLastTwo(item.form.studentName)}}</view>
  44 + <view class="title_name">
  45 + <view class="title">{{item.title}}</view>
  46 + <view class="name">
  47 + <text>学生姓名</text>
  48 + <text>{{item.form.studentName}}</text>
  49 + </view>
  50 + </view>
  51 + </view>
  52 +
  53 + <view class="time">
  54 + <text>{{timeFormat(item.createdTime, 'yyyy-mm-dd hh:MM')}}</text>
  55 + </view>
  56 +
  57 + </view>
  58 + <c-loading :loading="loading"></c-loading>
  59 + </view>
  60 + <view v-else class="no_data">
  61 + <c-no-data></c-no-data>
  62 + </view>
  63 +
  64 + <u-popup :show="show" mode="right" @close="close" @open="open" :closeOnClickOverlay="false">
  65 + <view class="popup_search">
  66 + <view class="content">
  67 + <view class="title">按项目筛选</view>
  68 + <scroll-view class="scroll" scroll-y="true">
  69 + <view class="item" v-for="(item, i) in projectList" :key="i" @click="handelClick(item)">
  70 + <view class="selectItem" v-if="item.id == projectId">
  71 + <text>{{item.name}}</text>
  72 + </view>
  73 + <view v-else>
  74 + <text>{{item.name}}</text>
  75 + </view>
  76 + </view>
  77 + </scroll-view>
  78 + <view class="switch">
  79 + <text>待批阅</text>
  80 + <u-switch v-model="switchValue" size="48" activeColor="#06B079" @change="handelChange">
  81 + </u-switch>
  82 + </view>
  83 + </view>
  84 +
  85 + <view class="footer">
  86 + <view class="left_btn">
  87 + <c-button type="cancel" text="重置" @click="handelCancel">
  88 + </c-button>
  89 + </view>
  90 + <view class="right_btn">
  91 + <c-button type="confirm" text="确定" @click="hancelSubmit">
  92 + </c-button>
  93 + </view>
  94 + </view>
  95 +
  96 + </view>
  97 + </u-popup>
  98 +
  99 + </view>
  100 +</template>
  101 +
  102 +<script>
  103 + import {
  104 + mapGetters,
  105 + mapState,
  106 + mapActions
  107 + } from 'vuex'
  108 + import listMixin from "@/common/mixins/list-mixin.js";
  109 +
  110 + import {
  111 + getReportReviewListApi,
  112 + getProjectListApi,
  113 + } from '@/config/api.js';
  114 +
  115 + export default {
  116 + mixins: [listMixin],
  117 + data() {
  118 +
  119 + const d = new Date();
  120 + const year = d.getFullYear();
  121 + let month = d.getMonth() + 1;
  122 + month = month < 10 ? `0${month}` : month;
  123 + const date = d.getDate();
  124 +
  125 + return {
  126 + studentId: '',
  127 + checkboxValue: [],
  128 + // 基本案列数据
  129 + checkboxList: [{
  130 + name: '待批阅',
  131 + disabled: false
  132 + }],
  133 + keyword: '',
  134 + show: false,
  135 + search: {
  136 + //搜索对象必须为key search的对象
  137 + keySearch: "",
  138 + status: '',
  139 +
  140 + },
  141 + showTime: false,
  142 + timeValue: `${year}-${month}-${date}`,
  143 + defaultDateMultiple: [`${year}-${month}-${date}`],
  144 + list: [], //列表必须为key list的数组
  145 + projectId: '',
  146 + switchValue: false,
  147 +
  148 + }
  149 + },
  150 +
  151 + onLoad(option) {
  152 + console.log(option)
  153 + this.studentId = option.studentId;
  154 + this.projectId = option.projectId;
  155 +
  156 + this.$store.dispatch(`home/getProjectList`, {
  157 + pageSize: -1,
  158 + })
  159 +
  160 + this.search.keySearch = '';
  161 +
  162 + if (option && option.status) {
  163 + this.search.status = 'stay_examine';
  164 + this.checkboxValue = ['待批阅'];
  165 + this.switchValue = true;
  166 + }
  167 +
  168 + this.finished = false;
  169 + this.loading = "loadmore";
  170 + this.page = 0;
  171 + this.list = [];
  172 + },
  173 +
  174 + onShow() {
  175 + this._getList();
  176 + },
  177 +
  178 + computed: {
  179 + ...mapState('home', {
  180 + // 箭头函数可使代码更简练
  181 + projectList: 'projectList',
  182 +
  183 + }),
  184 +
  185 + },
  186 +
  187 + methods: {
  188 + getNameLastTwo(value) {
  189 + if (value && value.length > 3) {
  190 + return value.substring(value.length - 3)
  191 + } else {
  192 + return value;
  193 + }
  194 + },
  195 +
  196 + overflowHide(value) {
  197 + if (value && value.length > 4) {
  198 + return `${value.slice(0, 4)}...`
  199 + } else {
  200 + return value;
  201 + }
  202 + },
  203 +
  204 + confirm(e) {
  205 + this.timeValue = e[0];
  206 + this.showTime = false;
  207 + },
  208 +
  209 + handelDetail(record) {
  210 + this.$u.route({
  211 + url: `pages/main/home/reportDetail/reportDetail?id=${record.id}&formId=${record.formId}`
  212 + })
  213 + },
  214 +
  215 + timeFormat(timestamp, format = 'yyyy-mm-dd') {
  216 + return timestamp > 0 ? uni.$u.timeFormat(timestamp, format) : '--'
  217 + },
  218 +
  219 + checkboxChange(n) {
  220 + console.log('change', n);
  221 +
  222 + this.search.status = n.length > 0 ? 'stay_examine' : '';
  223 +
  224 + this.switchValue = n.length > 0 ? true : false;
  225 +
  226 + this.finished = false;
  227 + this.loading = "loadmore";
  228 + this.page = 0;
  229 + this.list = [];
  230 + this._getList();
  231 + },
  232 +
  233 + handelSearch(value) {
  234 + this.finished = false;
  235 + this.loading = "loadmore";
  236 + this.page = 0;
  237 + this.list = [];
  238 + this._getList();
  239 + },
  240 +
  241 + open() {
  242 + // console.log('open');
  243 + },
  244 + close() {
  245 + this.show = false
  246 + // console.log('close');
  247 + },
  248 + // scroll-view到底部加载更多
  249 + onreachBottom() {},
  250 + // 搜索
  251 + searchSubmit() {
  252 + // 调用混合搜索
  253 + this._searchData();
  254 + },
  255 + // 模拟后端分页
  256 + async getData(requestParams) {
  257 + const {
  258 + search = {}
  259 + } = requestParams;
  260 +
  261 + let params = {};
  262 + params.pageNumber = requestParams.page + 1;
  263 + params.pageSize = 5;
  264 +
  265 + if (search.status) {
  266 + params.status = search.status;
  267 + }
  268 +
  269 + if (this.keyword) {
  270 + params.keySearch = this.keyword
  271 + }
  272 +
  273 + if (this.studentId) {
  274 + params.studentId = this.studentId
  275 + }
  276 +
  277 + if (this.projectId) {
  278 + params.projectId = this.projectId
  279 + }
  280 +
  281 + return await getReportReviewListApi(params);
  282 + },
  283 + // 数据请求(没错就是这么少的代码)
  284 + async _getList() {
  285 + if (this.page == 0) {
  286 + this.list = [];
  287 + }
  288 +
  289 + // 根据实际情况修改自己修改key
  290 + let result = await this.getData({
  291 + page: this.page, // 传入页码
  292 + size: this.size, // 传入每页条数
  293 + search: this.search, // 传入搜索的对象
  294 + });
  295 +
  296 + this.total = result.total;
  297 +
  298 + if (this.list.length == 0 && result.records.length == 0) {
  299 + this.shownoData = false
  300 + } else {
  301 + this.shownoData = true
  302 + }
  303 +
  304 + this.list = this.list.concat(result.records)
  305 +
  306 + // 判断是否全部加载完成
  307 + if (this.total == this.list.length) {
  308 + this.finished = true;
  309 + this.loading = 'nomore';
  310 + } else {
  311 + this.loading = 'loadmore';
  312 + }
  313 + },
  314 +
  315 + handelClick(values) {
  316 + console.log(values);
  317 + this.projectId = values.id;
  318 + },
  319 +
  320 + handelChange(e) {
  321 + console.log(e)
  322 + this.checkboxValue = e ? ['待批阅'] : [];
  323 + this.search.status = e ? 'stay_examine' : '';
  324 +
  325 + },
  326 +
  327 + handelCancel() {
  328 + this.switchValue = false;
  329 + this.projectId = '';
  330 + },
  331 +
  332 + hancelSubmit() {
  333 + this.finished = false;
  334 + this.loading = "loadmore";
  335 + this.page = 0;
  336 + this.list = [];
  337 + this._getList();
  338 +
  339 + this.show = false;
  340 + },
  341 +
  342 + }
  343 + }
  344 +</script>
  345 +
  346 +<style lang="scss" scoped>
  347 + .registration_review {
  348 + width: 100%;
  349 + min-height: 100%;
  350 + height: auto;
  351 + background-color: #F7F7F7;
  352 +
  353 + .search_box {
  354 + padding: 36rpx 30rpx 0;
  355 + background-color: #FFFFFF;
  356 +
  357 + .top {
  358 + display: flex;
  359 + flex-flow: row nowrap;
  360 + justify-content: space-between;
  361 + padding: 0 0 30rpx 0;
  362 +
  363 + .check {
  364 + padding: 20rpx 0 0 0;
  365 + }
  366 +
  367 + .search {
  368 + width: 468rpx;
  369 + }
  370 + }
  371 +
  372 + .bottom {
  373 + .time {
  374 + padding: 30rpx 0 30rpx 40rpx;
  375 + }
  376 + }
  377 +
  378 +
  379 + }
  380 +
  381 + .list_box {
  382 + padding: 30rpx 0 50rpx 0;
  383 +
  384 + .item {
  385 + position: relative;
  386 + width: 630rpx;
  387 + margin: 0 auto 30rpx;
  388 + padding: 30rpx;
  389 + border-radius: 12rpx;
  390 + background-color: #FFFFFF;
  391 +
  392 + .bg_image {
  393 + position: absolute;
  394 + top: 0;
  395 + right: 0;
  396 +
  397 + text {
  398 + position: absolute;
  399 + top: 12rpx;
  400 + right: 30rpx;
  401 + font-size: 24rpx;
  402 + line-height: 24rpx;
  403 + color: #FFFFFF;
  404 + }
  405 + }
  406 +
  407 + .info {
  408 + display: flex;
  409 + flex-flow: row nowrap;
  410 + align-items: center;
  411 + margin: 0 0 30rpx 0;
  412 +
  413 + .avatar {
  414 + width: 78rpx;
  415 + height: 94rpx;
  416 + padding: 0 8rpx;
  417 + border-radius: 4rpx;
  418 + background-color: #06B079;
  419 + font-size: 24rpx;
  420 + line-height: 94rpx;
  421 + color: #FFFFFF;
  422 + text-align: center;
  423 + }
  424 +
  425 + .title_name {
  426 + .title {
  427 + font-size: 32rpx;
  428 + line-height: 44rpx;
  429 + color: #202131;
  430 + font-weight: 500;
  431 + margin: 0 20rpx;
  432 + }
  433 +
  434 + .name {
  435 + padding: 8rpx 0 0 20rpx;
  436 + font-size: 28rpx;
  437 + line-height: 32rpx;
  438 + color: #909097;
  439 +
  440 + text:last-child {
  441 + padding: 0 0 0 30rpx;
  442 + color: #202131;
  443 + }
  444 + }
  445 + }
  446 +
  447 + }
  448 +
  449 + .time {
  450 + border-top: 2rpx solid #E2E2E8;
  451 + padding: 28rpx 0 0 0;
  452 +
  453 + text {
  454 + font-size: 28rpx;
  455 + line-height: 32rpx;
  456 + color: #909097;
  457 + }
  458 + }
  459 + }
  460 + }
  461 +
  462 + .popup_search {
  463 + width: 640rpx;
  464 + position: relative;
  465 +
  466 + .content {
  467 + padding: 0 40rpx;
  468 +
  469 + .title {
  470 + padding: 24rpx 0;
  471 + font-size: 28rpx;
  472 + line-height: 36rpx;
  473 + color: #202131;
  474 + }
  475 +
  476 + .scroll {
  477 + max-height: 60vh;
  478 +
  479 + .item {
  480 +
  481 + view {
  482 + display: flex;
  483 + flex-flow: row wrap;
  484 + align-items: center;
  485 + width: 500rpx;
  486 + height: 74rpx;
  487 + border-radius: 4rpx;
  488 + border: 2rpx solid #C1C1C9;
  489 + margin: 0 10rpx 20rpx;
  490 + font-size: 24rpx;
  491 + line-height: 32rpx;
  492 + color: #C0C0C9;
  493 + padding: 16rpx 20rpx;
  494 + }
  495 +
  496 + .selectItem {
  497 + background-color: #06B079;
  498 + color: #FFFFFF;
  499 + border: 2rpx solid #06B079;
  500 + }
  501 + }
  502 + }
  503 +
  504 + .time {
  505 + padding: 40rpx 0 0 0;
  506 + }
  507 +
  508 + .switch {
  509 + display: flex;
  510 + flex-flow: row nowrap;
  511 + justify-content: space-between;
  512 + padding: 40rpx 0 0 0;
  513 +
  514 + text {
  515 + font-size: 28rpx;
  516 + line-height: 36rpx;
  517 + color: #202131;
  518 + }
  519 + }
  520 +
  521 +
  522 + }
  523 +
  524 + .footer {
  525 + width: 560rpx;
  526 + height: 96rpx;
  527 + padding: 28rpx 40rpx;
  528 + background: #FFFFFF;
  529 + position: fixed;
  530 + bottom: 0;
  531 + right: 0;
  532 + z-index: 99;
  533 + border-top: 2rpx solid #E2E2E8;
  534 +
  535 + view {
  536 + display: inline-block;
  537 + }
  538 +
  539 + .left_btn {
  540 + width: 194rpx;
  541 + margin: 0 20rpx 0 0;
  542 + }
  543 +
  544 + .right_btn {
  545 + width: 346rpx;
  546 + }
  547 + }
  548 + }
  549 + }
  550 +</style>
... ...
  1 +<template>
  2 + <view class="registration_review">
  3 + <view class="search_box">
  4 + <view class="top">
  5 + <view class="check">
  6 + <u-checkbox-group v-model="checkboxValue" placement="column" @change="checkboxChange">
  7 + <u-checkbox :customStyle="{marginBottom: '8px'}" shape="circle"
  8 + v-for="(item, index) in checkboxList" :key="index" :label="item.name" :name="item.name"
  9 + activeColor="#06B079" size="28rpx" labelSize="28rpx" labelColor="#202131">
  10 + </u-checkbox>
  11 + </u-checkbox-group>
  12 + </view>
  13 +
  14 + <view class="search">
  15 + <u-search placeholder="请输入学生姓名/学号/手机号" placeholderColor="#C1C1C9" searchIconSize="36" height="64rpx"
  16 + bgColor="#F4F4F4" :showAction="false" shape="square" v-model="keyword" @search="handelSearch">
  17 + </u-search>
  18 + </view>
  19 +
  20 + <view class="icon">
  21 + <view :style="{position:'relative', top:'14rpx', right:'18rpx'}">
  22 + <u-icon slot="icon" size="40" :name="'/static/img/home/dateIcon.png'" @click="showTime = true">
  23 + </u-icon>
  24 + </view>
  25 + <u-icon slot="icon" size="40" :name="'/static/img/home/selectIcon.png'" @click="show = true">
  26 + </u-icon>
  27 + </view>
  28 +
  29 +
  30 + </view>
  31 + <view class="bottom" :style="{padding:'0 0 20rpx 0'}">
  32 + <u-calendar :minDate="minDate" :maxDate="maxDate" :monthNum="25" :show="showTime"
  33 + :defaultDate="defaultDateMultiple" @close="showTime = false" :showSubtitle="false" color="#06B079"
  34 + @confirm="confirm">
  35 + </u-calendar>
  36 + <!-- <view class="time">{{timeValue}}</view> -->
  37 + </view>
  38 + </view>
  39 +
  40 + <view class="list_box" v-if="list.length > 0">
  41 + <view class="item" v-for="(item, i) in list" :key="i">
  42 +
  43 + <view class="bg_image" v-if="item.waitAttendance == 'not_attendance'">
  44 + <u-image src="/static/img/home/labelBgGreen.png" width="142rpx" height="48rpx"></u-image>
  45 + <text>未签到</text>
  46 + </view>
  47 +
  48 + <view class="bg_image" v-else>
  49 + <u-image src="/static/img/home/labelBgGrey.png" width="142rpx" height="48rpx"></u-image>
  50 + <text>已签到</text>
  51 + </view>
  52 +
  53 + <view class="info">
  54 + <view class="avatar">{{getNameLastTwo(item.studentName)}}</view>
  55 + <view class="name">{{overflowHide(item.studentName)}}</view>
  56 + <view class="number">{{item.studentNumber}}</view>
  57 + </view>
  58 + <view class="company">
  59 + <text>实习项目</text>
  60 + <text>{{item.projectName || '--'}}</text>
  61 + </view>
  62 + <view class="company">
  63 + <text>班级</text>
  64 + <text>{{item.className || '--'}}</text>
  65 + </view>
  66 + <view class="company position">
  67 + <text>手机号</text>
  68 + <text>{{item.studentPhone|| '--'}}</text>
  69 + </view>
  70 +
  71 + <view class="time">
  72 + <text>签到时间</text>
  73 + <text>{{timeFormat(item.signIn, 'yyyy-mm-dd hh:MM')}}</text>
  74 + </view>
  75 +
  76 + </view>
  77 + <c-loading :loading="loading"></c-loading>
  78 + </view>
  79 + <view v-else class="no_data">
  80 + <c-no-data></c-no-data>
  81 + </view>
  82 +
  83 + <u-popup :show="show" mode="right" @close="close" @open="open" :closeOnClickOverlay="false">
  84 + <view class="popup_search">
  85 + <view class="content">
  86 + <view class="title">按项目筛选</view>
  87 + <scroll-view class="scroll" scroll-y="true">
  88 + <view class="item" v-for="(item, i) in projectList" :key="i" @click="handelClick(item)">
  89 + <view class="selectItem" v-if="item.id == projectId">
  90 + <text>{{item.name}}</text>
  91 + </view>
  92 + <view v-else>
  93 + <text>{{item.name}}</text>
  94 + </view>
  95 + </view>
  96 + </scroll-view>
  97 + <view class="switch">
  98 + <text>未签到</text>
  99 + <u-switch v-model="switchValue" size="48" activeColor="#06B079" @change="handelChange">
  100 + </u-switch>
  101 + </view>
  102 + </view>
  103 +
  104 + <view class="footer">
  105 + <view class="left_btn">
  106 + <c-button type="cancel" text="重置" @click="handelCancel">
  107 + </c-button>
  108 + </view>
  109 + <view class="right_btn">
  110 + <c-button type="confirm" text="确定" @click="hancelSubmit">
  111 + </c-button>
  112 + </view>
  113 + </view>
  114 +
  115 + </view>
  116 + </u-popup>
  117 +
  118 + </view>
  119 +</template>
  120 +
  121 +<script>
  122 + import {
  123 + mapGetters,
  124 + mapState,
  125 + mapActions
  126 + } from 'vuex'
  127 + import listMixin from "@/common/mixins/list-mixin.js";
  128 + import miment from 'miment'
  129 +
  130 + import {
  131 + getStudentSignInListApi,
  132 + getProjectListApi,
  133 + } from '@/config/api.js';
  134 +
  135 + export default {
  136 + mixins: [listMixin],
  137 + data() {
  138 +
  139 + const d = new Date();
  140 + const year = d.getFullYear();
  141 + let month = d.getMonth() + 1;
  142 + month = month < 10 ? `0${month}` : month;
  143 + const date = d.getDate();
  144 +
  145 + return {
  146 + checkboxValue: [],
  147 + // 基本案列数据
  148 + checkboxList: [{
  149 + name: '未签到',
  150 + disabled: false
  151 + }],
  152 + keyword: '',
  153 + show: false,
  154 + search: {
  155 + //搜索对象必须为key search的对象
  156 + keySearch: "",
  157 + waitAttendance: '',
  158 + time: '',
  159 +
  160 + },
  161 + showTime: false,
  162 + minDate: `${year-2}-${month}-${date+1}`,
  163 + maxDate: `${year}-${month}-${date+1}`,
  164 + timeValue: `${year}-${month}-${date}`,
  165 + defaultDateMultiple: [`${year}-${month}-${date}`],
  166 + list: [], //列表必须为key list的数组
  167 + projectId: '',
  168 + switchValue: false,
  169 +
  170 + }
  171 + },
  172 +
  173 + onLoad(option) {
  174 + this.$store.dispatch(`home/getProjectList`, {
  175 + pageSize: -1,
  176 + })
  177 +
  178 + this.search.keySearch = '';
  179 +
  180 + this.finished = false;
  181 + this.loading = "loadmore";
  182 + this.page = 0;
  183 + this.list = [];
  184 +
  185 +
  186 +
  187 + },
  188 +
  189 + onShow() {
  190 + this._getList();
  191 + },
  192 +
  193 + computed: {
  194 + ...mapState('home', {
  195 + // 箭头函数可使代码更简练
  196 + projectList: 'projectList',
  197 +
  198 + }),
  199 +
  200 + },
  201 +
  202 + methods: {
  203 +
  204 + getNameLastTwo(value) {
  205 + if (value && value.length > 3) {
  206 + return value.substring(value.length - 3)
  207 + } else {
  208 + return value;
  209 + }
  210 + },
  211 +
  212 + overflowHide(value, num = 4) {
  213 + if (value && value.length > num) {
  214 + return `${value.slice(0, num)}...`
  215 + } else {
  216 + return value;
  217 + }
  218 + },
  219 +
  220 + confirm(e) {
  221 + this.timeValue = e[0];
  222 + this.time = miment(e[0]).valueOf();
  223 +
  224 + this.finished = false;
  225 + this.loading = "loadmore";
  226 + this.page = 0;
  227 + this.list = [];
  228 + this._getList();
  229 +
  230 + this.showTime = false;
  231 + },
  232 +
  233 + handelDetail(record) {
  234 + this.$u.route({
  235 + url: `pages/main/home/registrationDetail/registrationDetail?&id=${record.id}`
  236 + })
  237 + },
  238 +
  239 + timeFormat(timestamp, format = 'yyyy-mm-dd') {
  240 + return timestamp > 0 ? uni.$u.timeFormat(timestamp, format) : '--'
  241 + },
  242 +
  243 + checkboxChange(n) {
  244 + console.log('change', n);
  245 +
  246 + this.search.waitAttendance = n.length > 0 ? 'not_attendance' : '';
  247 +
  248 + this.switchValue = n.length > 0 ? true : false;
  249 +
  250 + this.finished = false;
  251 + this.loading = "loadmore";
  252 + this.page = 0;
  253 + this.list = [];
  254 + this._getList();
  255 + },
  256 +
  257 + handelSearch(value) {
  258 + this.finished = false;
  259 + this.loading = "loadmore";
  260 + this.page = 0;
  261 + this.list = [];
  262 + this._getList();
  263 + },
  264 +
  265 + open() {
  266 + // console.log('open');
  267 + },
  268 + close() {
  269 + this.show = false
  270 + // console.log('close');
  271 + },
  272 + // scroll-view到底部加载更多
  273 + onreachBottom() {},
  274 + // 搜索
  275 + searchSubmit() {
  276 + // 调用混合搜索
  277 + this._searchData();
  278 + },
  279 + // 模拟后端分页
  280 + async getData(requestParams) {
  281 + const {
  282 + search = {}
  283 + } = requestParams;
  284 +
  285 + let params = {};
  286 + params.pageNumber = requestParams.page + 1;
  287 + params.pageSize = 5;
  288 +
  289 + if (search.waitAttendance) {
  290 + params.waitAttendance = search.waitAttendance;
  291 + }
  292 +
  293 + if (this.keyword) {
  294 + params.keySearch = this.keyword
  295 + }
  296 +
  297 + if (this.projectId) {
  298 + params.projectId = this.projectId
  299 + }
  300 +
  301 + if (this.time) {
  302 + params.time = this.time
  303 + }
  304 +
  305 + return await getStudentSignInListApi(params);
  306 + },
  307 + // 数据请求(没错就是这么少的代码)
  308 + async _getList() {
  309 + if (this.page == 0) {
  310 + this.list = [];
  311 + }
  312 +
  313 + // 根据实际情况修改自己修改key
  314 + let result = await this.getData({
  315 + page: this.page, // 传入页码
  316 + size: this.size, // 传入每页条数
  317 + search: this.search, // 传入搜索的对象
  318 + });
  319 +
  320 + this.total = result.total;
  321 +
  322 + if (this.list.length == 0 && result.records.length == 0) {
  323 + this.shownoData = false
  324 + } else {
  325 + this.shownoData = true
  326 + }
  327 +
  328 + this.list = this.list.concat(result.records)
  329 +
  330 + // 判断是否全部加载完成
  331 + if (this.total == this.list.length) {
  332 + this.finished = true;
  333 + this.loading = 'nomore';
  334 + } else {
  335 + this.loading = 'loadmore';
  336 + }
  337 + },
  338 +
  339 + handelClick(values) {
  340 + console.log(values);
  341 + this.projectId = values.id;
  342 + },
  343 +
  344 + handelChange(e) {
  345 + console.log(e)
  346 + this.checkboxValue = e ? ['未签到'] : [];
  347 + this.search.waitAttendance = e ? 'not_attendance' : '';
  348 + },
  349 +
  350 + handelCancel() {
  351 + this.switchValue = false;
  352 + this.projectId = '';
  353 + },
  354 +
  355 + hancelSubmit() {
  356 + this.finished = false;
  357 + this.loading = "loadmore";
  358 + this.page = 0;
  359 + this.list = [];
  360 + this._getList();
  361 +
  362 + this.show = false;
  363 + },
  364 +
  365 + }
  366 + }
  367 +</script>
  368 +
  369 +<style lang="scss" scoped>
  370 + .registration_review {
  371 + width: 100%;
  372 + min-height: 100%;
  373 + height: auto;
  374 + background-color: #F7F7F7;
  375 +
  376 + .search_box {
  377 + padding: 36rpx 30rpx 0;
  378 + background-color: #FFFFFF;
  379 +
  380 + .top {
  381 + display: flex;
  382 + flex-flow: row nowrap;
  383 + justify-content: space-between;
  384 +
  385 + .check {
  386 + padding: 20rpx 0 0 0;
  387 + }
  388 +
  389 + .search {
  390 + width: 410rpx;
  391 + }
  392 +
  393 + .icon {
  394 + display: flex;
  395 + flex-flow: row nowrap;
  396 + }
  397 + }
  398 +
  399 + .bottom {
  400 + .time {
  401 + padding: 30rpx 0 30rpx 40rpx;
  402 + }
  403 + }
  404 +
  405 +
  406 + }
  407 +
  408 + .list_box {
  409 + padding: 0 0 50rpx 0;
  410 +
  411 + .item {
  412 + position: relative;
  413 + width: 630rpx;
  414 + margin: 30rpx auto;
  415 + padding: 30rpx;
  416 + border-radius: 12rpx;
  417 + background-color: #FFFFFF;
  418 +
  419 + .bg_image {
  420 + position: absolute;
  421 + top: 0;
  422 + right: 0;
  423 +
  424 + text {
  425 + position: absolute;
  426 + top: 12rpx;
  427 + right: 30rpx;
  428 + font-size: 24rpx;
  429 + line-height: 24rpx;
  430 + color: #FFFFFF;
  431 + }
  432 + }
  433 +
  434 + .info {
  435 + display: flex;
  436 + flex-flow: row nowrap;
  437 + align-items: center;
  438 + margin: 0 0 30rpx 0;
  439 +
  440 + .avatar {
  441 + width: 78rpx;
  442 + height: 94rpx;
  443 + padding: 0 8rpx;
  444 + border-radius: 4rpx;
  445 + background-color: #06B079;
  446 + font-size: 24rpx;
  447 + line-height: 94rpx;
  448 + color: #FFFFFF;
  449 + text-align: center;
  450 + }
  451 +
  452 + .name {
  453 + font-size: 32rpx;
  454 + line-height: 44rpx;
  455 + color: #202131;
  456 + font-weight: 500;
  457 + margin: 0 20rpx;
  458 + }
  459 +
  460 + .number {
  461 + font-size: 28rpx;
  462 + line-height: 32rpx;
  463 + color: #909097;
  464 + }
  465 + }
  466 +
  467 + .company {
  468 + display: flex;
  469 + flex-flow: row nowrap;
  470 + margin: 0 0 30rpx 0;
  471 +
  472 + text {
  473 + width: 130rpx;
  474 + font-size: 28rpx;
  475 + line-height: 32rpx;
  476 + color: #909097;
  477 + margin: 0 0 0 16rpx;
  478 + }
  479 +
  480 + text:first-child {
  481 + text-align: justify;
  482 + text-align-last: justify;
  483 + }
  484 +
  485 + text:last-child {
  486 + width: 400rpx;
  487 + color: #202131;
  488 + margin: 0 0 0 30rpx;
  489 + }
  490 + }
  491 +
  492 + .time {
  493 + border-top: 2rpx solid #E2E2E8;
  494 + padding: 28rpx 0 0 0;
  495 +
  496 + text {
  497 + font-size: 28rpx;
  498 + line-height: 32rpx;
  499 + color: #909097;
  500 + }
  501 +
  502 + text:last-child {
  503 + color: #202131;
  504 + margin: 0 0 0 78rpx;
  505 + }
  506 + }
  507 + }
  508 + }
  509 +
  510 + .popup_search {
  511 + width: 640rpx;
  512 + position: relative;
  513 +
  514 + .content {
  515 + padding: 0 40rpx;
  516 +
  517 + .title {
  518 + padding: 24rpx 0;
  519 + font-size: 28rpx;
  520 + line-height: 36rpx;
  521 + color: #202131;
  522 + }
  523 +
  524 + .scroll {
  525 + max-height: 60vh;
  526 +
  527 + .item {
  528 +
  529 + view {
  530 + display: flex;
  531 + flex-flow: row wrap;
  532 + align-items: center;
  533 + width: 500rpx;
  534 + height: 74rpx;
  535 + border-radius: 4rpx;
  536 + border: 2rpx solid #C1C1C9;
  537 + margin: 0 10rpx 20rpx;
  538 + font-size: 24rpx;
  539 + line-height: 32rpx;
  540 + color: #C0C0C9;
  541 + padding: 16rpx 20rpx;
  542 + }
  543 +
  544 + .selectItem {
  545 + background-color: #06B079;
  546 + color: #FFFFFF;
  547 + border: 2rpx solid #06B079;
  548 + }
  549 + }
  550 + }
  551 +
  552 + .time {
  553 + padding: 40rpx 0 0 0;
  554 + }
  555 +
  556 + .switch {
  557 + display: flex;
  558 + flex-flow: row nowrap;
  559 + justify-content: space-between;
  560 + padding: 40rpx 0 0 0;
  561 +
  562 + text {
  563 + font-size: 28rpx;
  564 + line-height: 36rpx;
  565 + color: #202131;
  566 + }
  567 + }
  568 +
  569 +
  570 + }
  571 +
  572 + .footer {
  573 + width: 560rpx;
  574 + height: 96rpx;
  575 + padding: 28rpx 40rpx;
  576 + background: #FFFFFF;
  577 + position: fixed;
  578 + bottom: 0;
  579 + right: 0;
  580 + z-index: 99;
  581 + border-top: 2rpx solid #E2E2E8;
  582 +
  583 + view {
  584 + display: inline-block;
  585 + }
  586 +
  587 + .left_btn {
  588 + width: 194rpx;
  589 + margin: 0 20rpx 0 0;
  590 + }
  591 +
  592 + .right_btn {
  593 + width: 346rpx;
  594 + }
  595 + }
  596 + }
  597 + }
  598 +</style>
... ...
  1 +<template>
  2 + <view class="info">
  3 + <view style="display: flex;">
  4 + <image class="header_bg" :src="vuex_baseImgUrl+'/intership_header_bg.png'"></image>
  5 + <view style="position: absolute;display: flex;">
  6 + <image class="header_img" src="/static/img/internship/intership_header.png" mode=""></image>
  7 + <text class="text_white">成绩详情</text>
  8 + </view>
  9 + </view>
  10 + <view class="content">
  11 + <view class="content_box">
  12 + <view>
  13 + <text>成绩</text>
  14 + <text class="value_type">{{interDetail.level ? interDetail.level : interDetail.score}}</text>
  15 + </view>
  16 + <view style="margin-top: 32rpx;">
  17 + <text>学分</text>
  18 + <text class="value_type">{{interDetail.credit}}</text>
  19 + </view>
  20 + <view style="margin-top: 32rpx;">
  21 + <text>考评人</text>
  22 + <text class="value_type">{{interDetail.assessorName ? interDetail.assessorName : '--'}}</text>
  23 + </view>
  24 +
  25 + <view style="margin-top: 32rpx;">
  26 + <text>评价</text>
  27 + <text class="value_type">{{interDetail.teacherView ? interDetail.teacherView : '--'}}</text>
  28 + </view>
  29 +
  30 + </view>
  31 + </view>
  32 + </view>
  33 +</template>
  34 +
  35 +<script>
  36 + import {
  37 + getInternshipDetailApi,
  38 + } from '@/config/api.js';
  39 +
  40 + export default {
  41 + data() {
  42 + return {
  43 + id: '',
  44 + interDetail: {},
  45 + projectDetail: {},
  46 + jobDetail: {},
  47 + levels: {
  48 + 'excellence': '优秀',
  49 + 'good': '良好',
  50 + 'pass': '及格',
  51 + 'fail': '不及格'
  52 + },
  53 + grades: '',
  54 + }
  55 + },
  56 + onLoad(e) {
  57 + this.id = e.id;
  58 +
  59 + getInternshipDetailApi(this.id).then(res => {
  60 + this.interDetail = res;
  61 + this.projectDetail = res.projectDetail;
  62 + this.jobDetail = res.jobDetail;
  63 + this.grades = (res.markWay == "hierarchy" ? (res.level ? this.levels[res.level] : "--") : res
  64 + .score + 0 + "/100")
  65 + })
  66 + },
  67 + methods: {
  68 +
  69 + timeFormat(timestamp, format = 'yyyy-mm-dd') {
  70 + return timestamp > 0 ? uni.$u.timeFormat(timestamp, format) : '--'
  71 + },
  72 + }
  73 + }
  74 +</script>
  75 +
  76 +<style lang="scss" scoped>
  77 + .info {
  78 + width: 690rpx;
  79 + background-color: #F7F7F7;
  80 + display: flex;
  81 + flex-direction: column;
  82 + padding: 30rpx;
  83 + height: 100%;
  84 + }
  85 +
  86 + .header_bg {
  87 + width: 100%;
  88 + height: 100rpx;
  89 + }
  90 +
  91 + .header_img {
  92 + width: 36rpx;
  93 + height: 36rpx;
  94 + margin-left: 32rpx;
  95 + margin-right: 10rpx;
  96 + margin-top: 26rpx;
  97 + }
  98 +
  99 + .text_white {
  100 + font-size: 32rpx;
  101 + font-family: PingFangSC-Medium, PingFang SC;
  102 + font-weight: 500;
  103 + color: #FFFFFF;
  104 + line-height: 84rpx;
  105 + }
  106 +
  107 + .content {
  108 + width: 100%;
  109 + background-color: #fff;
  110 + border-bottom-left-radius: 12rpx;
  111 + border-bottom-right-radius: 12rpx;
  112 +
  113 + .text_title {
  114 + font-size: 32rpx;
  115 + font-family: PingFangSC-Medium, PingFang SC;
  116 + font-weight: 500;
  117 + color: #000000;
  118 + margin: 32rpx;
  119 + }
  120 +
  121 + .divide_line {
  122 + height: 1px;
  123 + border: 1px solid rgba(0, 0, 0, 0.06);
  124 + margin-top: 30rpx;
  125 + }
  126 +
  127 + .content_box {
  128 + padding: 32rpx;
  129 + margin-bottom: 48rpx;
  130 + }
  131 +
  132 + .value_type {
  133 + font-size: 28rpx;
  134 + font-family: PingFangSC-Regular, PingFang SC;
  135 + font-weight: 400;
  136 + float: right;
  137 + color: #000000;
  138 + text-align: right;
  139 + width: 400rpx;
  140 + }
  141 + }
  142 +</style>
... ...
  1 +<template>
  2 + <view class="agreemen_detail">
  3 +
  4 + <view v-if="id">
  5 + <view class="box">
  6 + <view class="title">{{detail.title}}</view>
  7 + <view class="item">
  8 + <text>创建时间</text>
  9 + <text>{{timeFormat(detail.createdTime)}}</text>
  10 + </view>
  11 + </view>
  12 +
  13 + <view class="list_box">
  14 + <view class="item">
  15 + <view class="company">
  16 + <text>实习单号</text>
  17 + <text @click="handelDetail" :style="{color:'#06B079'}">{{detail.formNumber || '--'}}</text>
  18 + </view>
  19 + <view class="company">
  20 + <text>学生姓名</text>
  21 + <text>{{detail.studentName|| '--'}}</text>
  22 + </view>
  23 + <view class="company">
  24 + <text>课程名称</text>
  25 + <text>{{detail.courseName|| '--'}}</text>
  26 + </view>
  27 + <view class="company">
  28 + <text>项目名称</text>
  29 + <text>{{detail.projectName|| '--'}}</text>
  30 + </view>
  31 + <view class="company">
  32 + <text>三方协议</text>
  33 + <view class="item_box">
  34 + <text :style="{color:'#06B079'}" v-for="(item,index) in attachments" :key="index"
  35 + @click="openLink(item)">{{item.filename}}</text>
  36 + </view>
  37 +
  38 + </view>
  39 +
  40 + </view>
  41 + </view>
  42 + </view>
  43 +
  44 + <view v-else class="no_data">
  45 + <c-no-data></c-no-data>
  46 + </view>
  47 +
  48 + </view>
  49 +</template>
  50 +
  51 +<script>
  52 + import {
  53 + mapGetters,
  54 + mapState,
  55 + mapActions
  56 + } from 'vuex'
  57 + import listMixin from "@/common/mixins/list-mixin.js";
  58 +
  59 + import {
  60 + getImgUrlApi,
  61 + getAgreementDetailApi,
  62 + } from '@/config/api.js';
  63 +
  64 + export default {
  65 + data() {
  66 + return {
  67 + id: '',
  68 + detail: {},
  69 + attachments: [],
  70 + }
  71 + },
  72 +
  73 + onLoad(option) {
  74 +
  75 + this.id = option.id;
  76 +
  77 + if(!option.id) {
  78 + return;
  79 + }
  80 +
  81 + getAgreementDetailApi(option.id).then(data => {
  82 + if (data) {
  83 + this.detail = data;
  84 + this.attachments = data.attachments ? JSON.parse(data.attachments) : [];
  85 + }
  86 + })
  87 + },
  88 +
  89 + methods: {
  90 + timeFormat(timestamp, format = 'yyyy-mm-dd') {
  91 + return timestamp > 0 ? uni.$u.timeFormat(timestamp, format) : '--'
  92 + },
  93 +
  94 + handelDetail(record) {
  95 + this.$u.route({
  96 + url: `pages/main/internship/intershipInfo/intershipInfo?id=${this.detail.formId}`
  97 + })
  98 + },
  99 +
  100 + openLink(e) {
  101 + var _this = this
  102 + this.mFileDir = e.filename.substring(0, e.filename.lastIndexOf('.'))
  103 + this.mFileType = e.filename.substring(e.filename.lastIndexOf('.'), e.filename.length)
  104 + getImgUrlApi({
  105 + bucket: e.bucket,
  106 + filePath: e.object
  107 + }).then(data => {
  108 + console.log("data...", data)
  109 + if (e.mime_type.indexOf("image") != -1) {
  110 + _this.openImage(data.url)
  111 + } else {
  112 + uni.downloadFile({
  113 + url: data.url,
  114 + filePath: wx.env.USER_DATA_PATH + '/' + _this.mFileDir + this.mFileType,
  115 + success: (res) => {
  116 + if (res.statusCode === 200) {
  117 + uni.showLoading();
  118 + console.log('download succ', res)
  119 + let fileMgr = wx.getFileSystemManager();
  120 + let filePath = res.filePath
  121 + uni.saveFile({
  122 + tempFilePath: filePath,
  123 + success: function(res) {
  124 + var savedFilePath = res.savedFilePath;
  125 + /* 删除缓存 */
  126 + fileMgr.unlink({
  127 + filePath: wx.env.USER_DATA_PATH +
  128 + '/' +
  129 + _this.mFileDir + _this
  130 + .mFileType,
  131 + success: function(res) {
  132 + console.log(
  133 + 'unlink success:',
  134 + res);
  135 + }
  136 + })
  137 + _this.openDoc()
  138 + },
  139 + fail: function(res) {
  140 + console.log('save fail', res);
  141 + _this.createFile()
  142 + }
  143 + })
  144 + }
  145 + }
  146 + });
  147 + }
  148 + })
  149 + },
  150 +
  151 + createFile() {
  152 + let fileMgr = wx.getFileSystemManager();
  153 + var _this = this
  154 + //利用access方法判断文件是否可用
  155 + fileMgr.access({
  156 + path: wx.env.USER_DATA_PATH + '/' + _this.mFileDir,
  157 + success: (res) => {
  158 + console.log('check success:', res);
  159 + _this.openDoc()
  160 + },
  161 + fail: (res) => {
  162 + console.log('check fail.', res);
  163 + fileMgr.mkdir({
  164 + dirPath: wx.env.USER_DATA_PATH + '/' + _this.mFileDir,
  165 + success: (res) => {
  166 + console.log('mk dir success:', res);
  167 + _this.openDoc()
  168 + },
  169 + fail: (res) => {
  170 + console.log('mk dir fail:', res);
  171 + uni.hideLoading();
  172 + }
  173 + });
  174 + }
  175 + });
  176 + },
  177 +
  178 + openDoc() {
  179 + uni.openDocument({
  180 + filePath: wx.env.USER_DATA_PATH + '/' + this.mFileDir + this.mFileType,
  181 + showMenu: true,
  182 + success: function(res) {
  183 + uni.hideLoading();
  184 + console.log('openDoc succ');
  185 + }
  186 + });
  187 + },
  188 +
  189 + openImage(imgPath) {
  190 + let array = new Array(1).fill(imgPath);
  191 + uni.previewImage({
  192 + urls: array,
  193 + success(res) {
  194 + console.log('openImage success');
  195 + },
  196 + fail(res) {
  197 + console.log('openImage fail:', res);
  198 + }
  199 + });
  200 + },
  201 +
  202 + }
  203 + }
  204 +</script>
  205 +
  206 +<style lang="scss" scoped>
  207 + .agreemen_detail {
  208 + width: 100%;
  209 + min-height: 100%;
  210 + height: auto;
  211 + background-color: #F7F7F7;
  212 + padding: 20rpx 0 0 0;
  213 +
  214 + .box {
  215 + width: 630rpx;
  216 + margin: 0 auto 20rpx;
  217 + padding: 30rpx 30rpx 12rpx 30rpx;
  218 + border-radius: 12rpx;
  219 + background-color: #FFFFFF;
  220 +
  221 + .title {
  222 + font-size: 32rpx;
  223 + line-height: 32rpx;
  224 + color: #202131;
  225 + margin: 0 0 30rpx 0;
  226 + }
  227 +
  228 + .title::before {
  229 + content: "";
  230 + display: inline-block;
  231 + width: 6rpx;
  232 + height: 32rpx;
  233 + background-color: #06B079;
  234 + margin: 0 12rpx 0 0;
  235 + position: relative;
  236 + top: 4rpx;
  237 + border-radius: 8rpx;
  238 + }
  239 +
  240 +
  241 +
  242 + .item {
  243 + margin: 0 0 24rpx 0;
  244 +
  245 + text:first-child {
  246 + display: inline-block;
  247 + width: 112rpx;
  248 + text-align: justify;
  249 + text-align-last: justify;
  250 + font-size: 28rpx;
  251 + line-height: 48rpx;
  252 + color: #909097;
  253 + vertical-align: top;
  254 + }
  255 +
  256 + text:last-child {
  257 + display: inline-block;
  258 + width: 440rpx;
  259 + word-break: break-word;
  260 + font-size: 28rpx;
  261 + line-height: 48rpx;
  262 + color: #202131;
  263 + margin: 0 0 0 30rpx;
  264 + }
  265 + }
  266 + }
  267 +
  268 + .list_box {
  269 + padding: 0 0 50rpx 0;
  270 +
  271 + .item {
  272 + position: relative;
  273 + width: 630rpx;
  274 + margin: 30rpx auto;
  275 + padding: 30rpx;
  276 + border-radius: 12rpx;
  277 + background-color: #FFFFFF;
  278 +
  279 + .company {
  280 + display: flex;
  281 + flex-flow: row nowrap;
  282 + margin: 0 0 30rpx 0;
  283 +
  284 + text {
  285 + width: 120rpx;
  286 + font-size: 28rpx;
  287 + line-height: 32rpx;
  288 + color: #909097;
  289 + margin: 0 0 0 16rpx;
  290 + }
  291 +
  292 + text:last-child {
  293 + width: 450rpx;
  294 + color: #202131;
  295 + margin: 0 0 0 30rpx;
  296 + }
  297 +
  298 + .item_box {
  299 + width: 450rpx;
  300 + margin: 0 0 0 30rpx;
  301 + text {
  302 + display: inline-block;
  303 + width: 450rpx;
  304 + overflow: hidden;
  305 + white-space: nowrap;
  306 + text-overflow: ellipsis;
  307 + margin: 0;
  308 +
  309 + }
  310 + }
  311 + }
  312 +
  313 + }
  314 + }
  315 + }
  316 +</style>
... ...
  1 +<template>
  2 + <view class="registration_review">
  3 +
  4 + <view class="list_box" v-if="list.length > 0">
  5 + <view class="item" v-for="(item, i) in list" :key="i" @click="handelDetail(item)">
  6 +
  7 + <view class="company">
  8 + <text>实践课程</text>
  9 + <text>{{item.courseName || '--'}}</text>
  10 + </view>
  11 + <view class="company">
  12 + <text>实习计划</text>
  13 + <text>{{item.planName|| '--'}}</text>
  14 + </view>
  15 + <view class="company">
  16 + <text>实习项目</text>
  17 + <text>{{item.projectName|| '--'}}</text>
  18 + </view>
  19 + <view class="company">
  20 + <text>学生名称</text>
  21 + <text>{{item.studentName|| '--'}}</text>
  22 + </view>
  23 +
  24 + <view class="time">
  25 + <text>上传时间</text>
  26 + <text>{{timeFormat(item.createdTime, 'yyyy-mm-dd hh:MM')}}</text>
  27 + </view>
  28 +
  29 + </view>
  30 + <c-loading :loading="loading"></c-loading>
  31 + </view>
  32 + <view v-else class="no_data">
  33 + <c-no-data></c-no-data>
  34 + </view>
  35 +
  36 + </view>
  37 +</template>
  38 +
  39 +<script>
  40 + import {
  41 + mapGetters,
  42 + mapState,
  43 + mapActions
  44 + } from 'vuex'
  45 + import listMixin from "@/common/mixins/list-mixin.js";
  46 +
  47 + import {
  48 + getAgreementListApi,
  49 + } from '@/config/api.js';
  50 +
  51 + export default {
  52 + mixins: [listMixin],
  53 + data() {
  54 + return {
  55 +
  56 + list: [], //列表必须为key list的数组
  57 + search: {
  58 + //搜索对象必须为key search的对象
  59 + status: 'wait,pass,reject',
  60 +
  61 + },
  62 + }
  63 + },
  64 +
  65 + onLoad(option) {
  66 + this.studentId = option.studentId;
  67 + this.projectId = option.projectId;
  68 +
  69 + this.finished = false;
  70 + this.loading = "loadmore";
  71 + this.page = 0;
  72 + this.list = [];
  73 + this._getList();
  74 + },
  75 +
  76 + onShow() {
  77 +
  78 + },
  79 +
  80 + computed: {
  81 +
  82 +
  83 + },
  84 +
  85 + methods: {
  86 +
  87 + handelDetail(record) {
  88 + this.$u.route({
  89 + url: `pages/main/internship/agreementDetail/agreementDetail?&id=${record.id}`
  90 + })
  91 + },
  92 +
  93 + timeFormat(timestamp, format = 'yyyy-mm-dd') {
  94 + return timestamp > 0 ? uni.$u.timeFormat(timestamp, format) : '--'
  95 + },
  96 +
  97 + // scroll-view到底部加载更多
  98 + onreachBottom() {},
  99 + // 搜索
  100 + searchSubmit() {
  101 + // 调用混合搜索
  102 + this._searchData();
  103 + },
  104 + // 模拟后端分页
  105 + async getData(requestParams) {
  106 + const {
  107 + search = {}
  108 + } = requestParams;
  109 +
  110 + let params = {};
  111 + params.pageNumber = requestParams.page + 1;
  112 + params.pageSize = 5;
  113 +
  114 + if (this.studentId) {
  115 + params.studentId = this.studentId
  116 + }
  117 +
  118 + if (this.projectId) {
  119 + params.projectId = this.projectId
  120 + }
  121 +
  122 + return await getAgreementListApi(params);
  123 + },
  124 + // 数据请求(没错就是这么少的代码)
  125 + async _getList() {
  126 + if (this.page == 0) {
  127 + this.list = [];
  128 + }
  129 +
  130 + // 根据实际情况修改自己修改key
  131 + let result = await this.getData({
  132 + page: this.page, // 传入页码
  133 + size: this.size, // 传入每页条数
  134 + search: this.search, // 传入搜索的对象
  135 + });
  136 +
  137 + this.total = result.total;
  138 +
  139 + if (this.list.length == 0 && result.records.length == 0) {
  140 + this.shownoData = false
  141 + } else {
  142 + this.shownoData = true
  143 + }
  144 +
  145 + this.list = this.list.concat(result.records)
  146 +
  147 + // 判断是否全部加载完成
  148 + if (this.total == this.list.length) {
  149 + this.finished = true;
  150 + this.loading = 'nomore';
  151 + } else {
  152 + this.loading = 'loadmore';
  153 + }
  154 + },
  155 +
  156 + }
  157 + }
  158 +</script>
  159 +
  160 +<style lang="scss" scoped>
  161 + .registration_review {
  162 + width: 100%;
  163 + min-height: 100%;
  164 + height: auto;
  165 + background-color: #F7F7F7;
  166 +
  167 + .list_box {
  168 + padding: 30rpx 0 50rpx 0;
  169 +
  170 + .item {
  171 + position: relative;
  172 + width: 630rpx;
  173 + margin: 0 auto 30rpx ;
  174 + padding: 30rpx;
  175 + border-radius: 12rpx;
  176 + background-color: #FFFFFF;
  177 +
  178 + .company {
  179 + display: flex;
  180 + flex-flow: row nowrap;
  181 + margin: 0 0 30rpx 0;
  182 +
  183 + text {
  184 + width: 120rpx;
  185 + font-size: 28rpx;
  186 + line-height: 32rpx;
  187 + color: #909097;
  188 + margin: 0 0 0 16rpx;
  189 + }
  190 +
  191 + text:last-child {
  192 + width: 450rpx;
  193 + color: #202131;
  194 + margin: 0 0 0 30rpx;
  195 + }
  196 + }
  197 +
  198 + .time {
  199 + border-top: 2rpx solid #E2E2E8;
  200 + padding: 28rpx 0 0 0;
  201 +
  202 + text {
  203 + width: 120rpx;
  204 + font-size: 28rpx;
  205 + line-height: 32rpx;
  206 + color: #909097;
  207 + }
  208 +
  209 + text:last-child {
  210 + width: 450rpx;
  211 + color: #202131;
  212 + margin: 0 0 0 78rpx;
  213 + }
  214 + }
  215 + }
  216 + }
  217 +
  218 + }
  219 +</style>
... ...
  1 +<template>
  2 + <view class="info">
  3 + <view style="display: flex;">
  4 + <image class="header_bg" :src="vuex_baseImgUrl+'/intership_header_bg.png'"></image>
  5 + <view style="position: absolute;display: flex;">
  6 + <image class="header_img" src="/static/img/internship/intership_header.png" mode=""></image>
  7 + <text class="text_white">实习单详情</text>
  8 + </view>
  9 + </view>
  10 + <view class="content">
  11 + <!-- 基本信息 -->
  12 + <text class="text_title">基本信息</text>
  13 + <view class="divide_line"></view>
  14 + <view class="content_box">
  15 + <view>
  16 + <text>实习单号</text>
  17 + <text class="value_type">{{interDetail.number}}</text>
  18 + </view>
  19 + <view style="margin-top: 32rpx;">
  20 + <text>状态</text>
  21 + <text v-if="interDetail.status == 'wait'" class="value_type">未开始</text>
  22 + <text v-else-if="interDetail.status == 'running'" class="value_type">进行中</text>
  23 + <text v-else-if="interDetail.status == 'done'" class="value_type">已结束</text>
  24 + </view>
  25 + <view style="margin-top: 32rpx;">
  26 + <text>学生姓名</text>
  27 + <text class="value_type">{{interDetail.studentName}}</text>
  28 + </view>
  29 + <view style="margin-top: 32rpx;">
  30 + <text>是否到岗</text>
  31 + <text v-if="interDetail.dutyStatus == 'wait'" class="value_type">未到岗</text>
  32 + <text v-else-if="interDetail.dutyStatus == 'online'" class="value_type">已到岗</text>
  33 + <text v-else-if="interDetail.dutyStatus == 'offline'" class="value_type">已离岗</text>
  34 + </view>
  35 + <view style="margin-top: 32rpx;">
  36 + <text>学号</text>
  37 + <text class="value_type">{{interDetail.studentNumber}}</text>
  38 + </view>
  39 + <view style="margin-top: 32rpx;">
  40 + <text>学生手机号</text>
  41 + <text class="value_type">{{interDetail.studentPhone}}</text>
  42 + </view>
  43 + <view class="item">
  44 + <text>班级</text>
  45 + <text class="value_type">{{interDetail.classInfo}}</text>
  46 + </view>
  47 + <view class="item">
  48 + <text>实践课程</text>
  49 + <text class="value_type">{{interDetail.courseName}}</text>
  50 + </view>
  51 + <view style="margin-top: 32rpx;">
  52 + <text>实习成绩</text>
  53 + <text v-if="grades" class="value_type">{{grades}}</text>
  54 + <text v-else class="value_type">--</text>
  55 + </view>
  56 + <view class="item">
  57 + <text>实习评价</text>
  58 + <text v-if="interDetail.teacherView" class="value_type">{{interDetail.teacherView}}</text>
  59 + <text v-else class="value_type">--</text>
  60 + </view>
  61 + </view>
  62 + <!-- 项目信息 -->
  63 + <text class="text_title">项目信息</text>
  64 + <view class="divide_line"></view>
  65 + <view class="content_box">
  66 + <view class="item" :style="{margin:'0rpx'}">
  67 + <text>开设院系</text>
  68 + <text class="value_type">{{interDetail.departmentName}}</text>
  69 + </view>
  70 + <view class="item">
  71 + <text>开设学期</text>
  72 + <text class="value_type">{{interDetail.schoolTerm}}</text>
  73 + </view>
  74 + <view class="item">
  75 + <text>实习计划</text>
  76 + <text class="value_type"><text class="value_type">{{interDetail.planName}}</text></text>
  77 + </view>
  78 + <view class="item">
  79 + <text>实习项目</text>
  80 + <text class="value_type">{{interDetail.projectName}}</text></text>
  81 + </view>
  82 + <view style="margin-top: 32rpx;">
  83 + <text>实习形式</text>
  84 + <text v-if="projectDetail.practiceForm == 'oneself'" class="value_type">自主</text>
  85 + <text v-else-if="projectDetail.practiceForm == 'centralize'" class="value_type">集中</text>
  86 + </view>
  87 + <view style="margin-top: 32rpx;">
  88 + <text>实习开始时间</text>
  89 + <text class="value_type">{{timeFormat(projectDetail.startTime)}}</text>
  90 + </view>
  91 + <view style="margin-top: 32rpx;">
  92 + <text>实习结束时间</text>
  93 + <text class="value_type">{{timeFormat(projectDetail.endTime)}}</text>
  94 + </view>
  95 + <view style="margin-top: 32rpx;">
  96 + <text>实习指导老师</text>
  97 + <text v-if="interDetail.teacherName" class="value_type">{{interDetail.teacherName}}</text>
  98 + <text v-else class="value_type">--</text>
  99 + </view>
  100 + <view style="margin-top: 32rpx;">
  101 + <text>老师手机号</text>
  102 + <text v-if="interDetail.teacherPhone" class="value_type">{{interDetail.teacherPhone}}</text>
  103 + <text v-else class="value_type">--</text>
  104 + </view>
  105 + </view>
  106 +
  107 + <!-- 单位信息 -->
  108 + <text class="text_title">单位信息</text>
  109 + <view class="divide_line"></view>
  110 + <view class="content_box">
  111 + <view class="item" :style="{margin:'0rpx'}">
  112 + <text>实习企业</text>
  113 + <text v-if="jobDetail.company" class="value_type">{{jobDetail.company}}</text>
  114 + <text v-else class="value_type">--</text>
  115 + </view>
  116 + <view class="item">
  117 + <text>实习岗位</text>
  118 + <text class="value_type">{{jobDetail.name}}</text>
  119 + </view>
  120 + <view style="margin-top: 32rpx;">
  121 + <text>联系人</text>
  122 + <text v-if="jobDetail.contactName" class="value_type">{{jobDetail.contactName}}</text>
  123 + <text v-else class="value_type">--</text>
  124 + </view>
  125 + <view style="margin-top: 32rpx;">
  126 + <text>联系电话</text>
  127 + <text v-if="jobDetail.contactPhone" class="value_type">{{jobDetail.contactPhone}}</text>
  128 + <text v-else class="value_type">--</text>
  129 + </view>
  130 + <view class="item">
  131 + <text>实习地址</text>
  132 + <text v-if="jobDetail.workSite" class="value_type">{{jobDetail.workSite}}</text>
  133 + <text v-else class="value_type">--</text>
  134 + </view>
  135 + </view>
  136 + </view>
  137 + </view>
  138 +</template>
  139 +
  140 +<script>
  141 + import {
  142 + getInternshipDetailApi,
  143 + } from '@/config/api.js';
  144 +
  145 + export default {
  146 + data() {
  147 + return {
  148 + id: '',
  149 + interDetail: {},
  150 + projectDetail: {},
  151 + jobDetail: {},
  152 + levels: {
  153 + 'excellence': '优秀',
  154 + 'good': '良好',
  155 + 'pass': '及格',
  156 + 'fail': '不及格'
  157 + },
  158 + grades: '',
  159 + }
  160 + },
  161 + onLoad(e) {
  162 + this.id = e.id;
  163 +
  164 + getInternshipDetailApi(this.id).then(res => {
  165 + this.interDetail = res;
  166 + this.projectDetail = res.projectDetail;
  167 + this.jobDetail = res.jobDetail;
  168 + this.grades = (res.markWay == "hierarchy" ? (res.level ? res.level : "--") : res
  169 + .score + 0 + "/100")
  170 + })
  171 + },
  172 + methods: {
  173 +
  174 + timeFormat(timestamp, format = 'yyyy-mm-dd') {
  175 + return timestamp > 0 ? uni.$u.timeFormat(timestamp, format) : '--'
  176 + },
  177 + }
  178 + }
  179 +</script>
  180 +
  181 +<style lang="scss" scoped>
  182 + .info {
  183 + width: 690rpx;
  184 + background-color: #F7F7F7;
  185 + display: flex;
  186 + flex-direction: column;
  187 + padding: 30rpx;
  188 + }
  189 +
  190 + .header_bg {
  191 + width: 100%;
  192 + height: 100rpx;
  193 + }
  194 +
  195 + .header_img {
  196 + width: 36rpx;
  197 + height: 36rpx;
  198 + margin-left: 32rpx;
  199 + margin-right: 10rpx;
  200 + margin-top: 26rpx;
  201 + }
  202 +
  203 + .text_white {
  204 + font-size: 32rpx;
  205 + font-family: PingFangSC-Medium, PingFang SC;
  206 + font-weight: 500;
  207 + color: #FFFFFF;
  208 + line-height: 84rpx;
  209 + }
  210 +
  211 + .content {
  212 + width: 100%;
  213 + background-color: #fff;
  214 +
  215 + .item {
  216 + display: flex;
  217 + flex-flow: row nowrap;
  218 + justify-content: space-between;
  219 + margin: 32rpx 0 0 0;
  220 +
  221 + text {
  222 + display: block;
  223 + }
  224 + }
  225 +
  226 + .text_title {
  227 + font-size: 32rpx;
  228 + font-family: PingFangSC-Medium, PingFang SC;
  229 + font-weight: 500;
  230 + color: #000000;
  231 + margin: 32rpx;
  232 + }
  233 +
  234 + .divide_line {
  235 + height: 1px;
  236 + border: 1px solid rgba(0, 0, 0, 0.06);
  237 + margin-top: 30rpx;
  238 + }
  239 +
  240 + .content_box {
  241 + padding: 32rpx;
  242 + margin-bottom: 48rpx;
  243 + }
  244 +
  245 + .value_type {
  246 + font-size: 28rpx;
  247 + font-family: PingFangSC-Regular, PingFang SC;
  248 + font-weight: 400;
  249 + float: right;
  250 + color: #000000;
  251 + text-align: right;
  252 + width: 400rpx;
  253 + }
  254 + }
  255 +</style>
... ...
  1 +<template>
  2 + <view class="signin_list">
  3 + <mi-calendar :suspensionDateList="suspensionDateList" @change="change" @changeMonth="changeMonth"></mi-calendar>
  4 +
  5 + <view class="steps">
  6 + <u-steps current="1" direction="column" v-if="signList.length> 0">
  7 +
  8 + <view v-for="(item, i) in signList" :key="i">
  9 + <u-steps-item :title="timeFormat(item.createdTime, 'yyyy-mm-dd hh:MM')" :desc="item.location"
  10 + v-if="i == 0">
  11 + <u-icon slot="icon" size="38rpx" name="/static/img/internship/currentTime.png"></u-icon>
  12 + </u-steps-item>
  13 + <u-steps-item :title="timeFormat(item.createdTime, 'yyyy-mm-dd hh:MM')" :desc="item.location"
  14 + v-else>
  15 + <u-icon slot="icon" size="16rpx" name="/static/img/internship/beforeTime.png"></u-icon>
  16 + </u-steps-item>
  17 + </view>
  18 + </u-steps>
  19 +
  20 + <view v-else class="no_data">
  21 + <c-no-data paddingTop="30"></c-no-data>
  22 + </view>
  23 +
  24 + </view>
  25 + </view>
  26 +</template>
  27 +
  28 +<script>
  29 + import {
  30 + mapGetters,
  31 + mapState,
  32 + mapActions
  33 + } from 'vuex'
  34 + import listMixin from "@/common/mixins/list-mixin.js";
  35 +
  36 + import {
  37 + getsignInListApi,
  38 + } from '@/config/api.js';
  39 +
  40 +
  41 + export default {
  42 + data() {
  43 +
  44 + const d = new Date();
  45 + const year = d.getFullYear();
  46 + let month = d.getMonth() + 1;
  47 + month = month < 10 ? `0${month}` : month;
  48 + const date = d.getDate();
  49 +
  50 + return {
  51 + initList: [],
  52 + nowTime: `${year}-${month}-${date}`,
  53 + suspensionDateList: [],
  54 + signList: [],
  55 + }
  56 + },
  57 +
  58 + onLoad(option) {
  59 + this.studentId = option.studentId;
  60 + this.projectId = option.projectId;
  61 +
  62 + getsignInListApi({
  63 + studentId: option.studentId,
  64 + projectId: option.projectId,
  65 + }).then(data => {
  66 + this.initList = data;
  67 + if (data && data.length > 0) {
  68 +
  69 + let suspensionDateList = [];
  70 + data.map((item, index) => {
  71 + let suspensionDate = this.timeFormat(item.signIn)
  72 + console.log(suspensionDate, this.nowTime)
  73 + suspensionDateList.push(suspensionDate);
  74 + })
  75 + this.suspensionDateList = suspensionDateList;
  76 +
  77 + this.filterData(data, this.nowTime);
  78 +
  79 +
  80 + }
  81 + })
  82 +
  83 + },
  84 +
  85 + methods: {
  86 + timeFormat(timestamp, format = 'yyyy-mm-dd') {
  87 + return timestamp > 0 ? uni.$u.timeFormat(timestamp, format) : '--'
  88 + },
  89 +
  90 + filterData(data, time) {
  91 + let signListArr = data.filter(item => this.timeFormat(item.signIn) == time);
  92 + this.signList = signListArr.length > 0 ? signListArr[0].attendanceList : [];
  93 + },
  94 +
  95 + change(date) {
  96 + console.log(date); // 日期 eg:'2022-01-01'
  97 + this.filterData(this.initList, date);
  98 + },
  99 +
  100 + changeMonth(year, month) {
  101 + console.log(year, month); // 日期 eg:2022, 6
  102 +
  103 + let monthTime = new Date(year, month - 1);
  104 + console.log(monthTime.getTime())
  105 +
  106 + getsignInListApi({
  107 + studentId: this.studentId,
  108 + time: monthTime.getTime(),
  109 + }).then(data => {
  110 + this.initList = data;
  111 + if (data && data.length > 0) {
  112 +
  113 + let suspensionDateList = [];
  114 + data.map((item, index) => {
  115 + let suspensionDate = this.timeFormat(item.signIn)
  116 + console.log(suspensionDate, this.nowTime)
  117 + suspensionDateList.push(suspensionDate);
  118 + })
  119 + this.suspensionDateList = suspensionDateList;
  120 +
  121 + // let monthFormat = month < 10 ? `${year}-0${month}` : `${year}-${month}`;
  122 + // if (this.nowTime.indexOf(monthFormat) != -1) {
  123 + // this.filterData(data, this.nowTime);
  124 +
  125 + // }
  126 +
  127 + }
  128 + })
  129 + },
  130 + }
  131 + }
  132 +</script>
  133 +
  134 +<style lang="scss" scoped>
  135 + .signin_list {
  136 + width: 100%;
  137 + min-height: 100%;
  138 + height: auto;
  139 + background-color: #F7F7F7;
  140 + padding: 5rpx 0 20rpx 0;
  141 +
  142 + .steps {
  143 + width: 630rpx;
  144 + min-height: 550rpx;
  145 + padding: 30rpx;
  146 + margin: 20rpx auto 0;
  147 + background-color: #fff;
  148 + border-radius: 12rpx;
  149 + box-shadow: 0 3rpx 32rpx 0rpx rgba(0, 0, 0, 0.1);
  150 + }
  151 +
  152 + .steps /deep/ .u-steps-item {
  153 + padding-bottom: 40rpx;
  154 +
  155 + .u-steps-item__content {
  156 + .u-text {
  157 +
  158 + .u-text__value {
  159 + font-size: 28rpx !important;
  160 + }
  161 +
  162 + .u-text__value--content {
  163 +
  164 + color: #202131 !important;
  165 + }
  166 +
  167 + .u-text__value--tips {
  168 + color: #909097 !important;
  169 + }
  170 + }
  171 + }
  172 + }
  173 +
  174 + }
  175 +</style>
... ...
  1 +<template>
  2 + <view class="internship_box">
  3 + <view class="internship" v-if="hasLogin">
  4 +
  5 + <view class="search_box">
  6 + <view class="search">
  7 + <u-search placeholder="请输入学生姓名/学号/手机号" placeholderColor="#C1C1C9" searchIconSize="36" height="64rpx"
  8 + bgColor="#F4F4F4" :showAction="false" shape="square" v-model="keyword" @search="handelSearch">
  9 + </u-search>
  10 + </view>
  11 + </view>
  12 +
  13 + <view class="list_box" v-if="list.length > 0">
  14 + <view class="item" v-for="(item, i) in list" :key="i" @click="handelDetail(item)">
  15 +
  16 + <view class="info">
  17 + <view class="avatar">{{getNameLastTwo(item.studentName)}}</view>
  18 + <view class="student_info">
  19 + <view class="name">
  20 + <text>{{overflowHide(item.studentName, 4)}}</text>
  21 + <text>({{item.studentNumber}})</text>
  22 + </view>
  23 + <view class="mobile">
  24 + <text>{{item.studentPhone}}</text>
  25 + </view>
  26 + </view>
  27 + </view>
  28 +
  29 + </view>
  30 + <c-loading :loading="loading"></c-loading>
  31 + </view>
  32 + <view v-else class="no_data">
  33 + <c-no-data></c-no-data>
  34 + </view>
  35 +
  36 + </view>
  37 + <view class="no_login" v-else>
  38 + <view class="image">
  39 + <u-image :style="{margin:'0 auto'}" :src="vuex_baseImgUrl+'/internship_bg.png'" width="480rpx"
  40 + height="480rpx"></u-image>
  41 + </view>
  42 + <view class="btn">
  43 + <text>登录后可查看待办事项</text>
  44 + <u-button type="primary" text="登录" color="#06B079" :customStyle="{width:'340rpx'}" @click="handelLOgin">
  45 + </u-button>
  46 + </view>
  47 + </view>
  48 + </view>
  49 +</template>
  50 +
  51 +<script>
  52 + import {
  53 + mapGetters,
  54 + mapState,
  55 + mapActions
  56 + } from 'vuex'
  57 +
  58 + import listMixin from "@/common/mixins/list-mixin.js";
  59 +
  60 + import {
  61 + getStudentListApi,
  62 + } from '@/config/api.js';
  63 +
  64 + export default {
  65 + mixins: [listMixin],
  66 + data() {
  67 + return {
  68 + classInfoId: '',
  69 + keyword: '',
  70 + list: [],
  71 + search: {
  72 + keySearch: "",
  73 + },
  74 + }
  75 + },
  76 +
  77 + onLoad(option) {
  78 + this.classInfoId = option.classInfoId
  79 +
  80 + this.search.keySearch = '';
  81 +
  82 + this.finished = false;
  83 + this.loading = "loadmore";
  84 + this.page = 0;
  85 + this.list = [];
  86 + this._getList();
  87 + },
  88 +
  89 + onShow() {
  90 +
  91 + },
  92 +
  93 + computed: {
  94 + ...mapState({
  95 + hasLogin: 'hasLogin',
  96 + vuex_user: 'vuex_user',
  97 + teacher: (state) => state.vuex_user.teacher,
  98 + }),
  99 +
  100 +
  101 + },
  102 +
  103 + methods: {
  104 + getNameLastTwo(value) {
  105 + if (value && value.length > 3) {
  106 + return value.substring(value.length - 3)
  107 + } else {
  108 + return value;
  109 + }
  110 + },
  111 +
  112 + overflowHide(value, num = 4) {
  113 + if (value && value.length > num) {
  114 + return `${value.slice(0, num)}...`
  115 + } else {
  116 + return value;
  117 + }
  118 + },
  119 +
  120 + timeFormat(timestamp, format = 'yyyy-mm-dd') {
  121 + return timestamp > 0 ? uni.$u.timeFormat(timestamp, format) : '--'
  122 + },
  123 +
  124 + handelSearch(value) {
  125 + this.finished = false;
  126 + this.loading = "loadmore";
  127 + this.page = 0;
  128 + this.list = [];
  129 + this._getList();
  130 + },
  131 +
  132 + // scroll-view到底部加载更多
  133 + onreachBottom() {},
  134 + // 搜索
  135 + searchSubmit() {
  136 + // 调用混合搜索
  137 + this._searchData();
  138 + },
  139 + // 模拟后端分页
  140 + async getData(requestParams) {
  141 + const {
  142 + search = {}
  143 + } = requestParams;
  144 +
  145 + let params = {};
  146 + params.pageNumber = requestParams.page + 1;
  147 + params.pageSize = 5;
  148 +
  149 + if (this.classInfoId) {
  150 + params.classInfoId = this.classInfoId
  151 + }
  152 +
  153 + if (this.keyword) {
  154 + params.keySearch = this.keyword
  155 + }
  156 +
  157 + return await getStudentListApi(params);
  158 + },
  159 + // 数据请求(没错就是这么少的代码)
  160 + async _getList() {
  161 + if (this.page == 0) {
  162 + this.list = [];
  163 + }
  164 +
  165 + // 根据实际情况修改自己修改key
  166 + let result = await this.getData({
  167 + page: this.page, // 传入页码
  168 + size: this.size, // 传入每页条数
  169 + search: this.search, // 传入搜索的对象
  170 + });
  171 +
  172 + this.total = result.total;
  173 + this.list = this.list.concat(result.records)
  174 +
  175 + // 判断是否全部加载完成
  176 + if (this.total == this.list.length) {
  177 + this.finished = true;
  178 + this.loading = 'nomore';
  179 + } else {
  180 + this.loading = 'loadmore';
  181 + }
  182 + },
  183 +
  184 + handelDetail(record) {
  185 + this.$u.route({
  186 + url: `pages/main/internship/traineeDetail/traineeDetail?studentId=${record.studentId}`
  187 + })
  188 + },
  189 +
  190 + }
  191 + }
  192 +</script>
  193 +
  194 +<style lang="scss" scoped>
  195 + .internship_box {
  196 + background-color: #F7F7F7;
  197 + min-height: 100%;
  198 + height: auto;
  199 +
  200 + .internship {
  201 + width: 100%;
  202 + margin: 0 auto;
  203 +
  204 + .search_box {
  205 + padding: 36rpx 0;
  206 + background-color: #FFFFFF;
  207 +
  208 + .search {
  209 + width: 690rpx;
  210 + margin: 0 auto;
  211 + }
  212 +
  213 + }
  214 +
  215 + .list_box {
  216 + padding: 0 0 50rpx 0;
  217 +
  218 + .item {
  219 + position: relative;
  220 + width: 630rpx;
  221 + margin: 30rpx auto;
  222 + padding: 30rpx;
  223 + border-radius: 12rpx;
  224 + background-color: #FFFFFF;
  225 +
  226 + .info {
  227 + display: flex;
  228 + flex-flow: row nowrap;
  229 + align-items: center;
  230 + margin: 0 0 30rpx 0;
  231 +
  232 + .avatar {
  233 + width: 94rpx;
  234 + height: 94rpx;
  235 + border-radius: 4rpx;
  236 + background-color: #06B079;
  237 + font-size: 24rpx;
  238 + line-height: 94rpx;
  239 + color: #FFFFFF;
  240 + text-align: center;
  241 + }
  242 +
  243 + .student_info {
  244 + .name {
  245 + font-size: 32rpx;
  246 + line-height: 32rpx;
  247 + color: #121212;
  248 + font-weight: 500;
  249 + margin: 0 20rpx;
  250 +
  251 + text:last-child {
  252 + font-size: 26rpx;
  253 + color: #26292F;
  254 + padding: 0 0 0 20rpx;
  255 + }
  256 + }
  257 +
  258 + .mobile {
  259 + padding: 20rpx 0 0 20rpx;
  260 + font-size: 26rpx;
  261 + line-height: 36rpx;
  262 + color: #26292F;
  263 + }
  264 + }
  265 + }
  266 + }
  267 + }
  268 + }
  269 +
  270 + .no_login {
  271 + padding: 180rpx 0 0 0;
  272 + text-align: center;
  273 +
  274 + .image {
  275 + width: 480rpx;
  276 + margin: 0 auto;
  277 + }
  278 +
  279 + .btn {
  280 + position: relative;
  281 + top: -80rpx;
  282 +
  283 + text {
  284 + font-size: 24rpx;
  285 + line-height: 52rpx;
  286 + color: #909097;
  287 +
  288 + }
  289 + }
  290 + }
  291 +
  292 + }
  293 +</style>
... ...
  1 +<template>
  2 + <view class="registration_review">
  3 +
  4 + <u-sticky bgColor="#fff">
  5 + <u-tabs :list="tabs" :scrollable="false" lineWidth="30rpx" lineHeight="4rpx" lineColor="#06B079"
  6 + :inactiveStyle="{fontSize:'28rpx', color:'#4A4A53'}" :activeStyle="{fontSize:'36rpx', color:'#06B079'}"
  7 + @change="handelTab" :current="current">
  8 + </u-tabs>
  9 + </u-sticky>
  10 +
  11 + <view class="list_box" v-if="list.length > 0">
  12 + <view class="item" v-for="(item, i) in list" :key="i" @click="handelDetail(item)">
  13 +
  14 + <view class="bg_image" v-if="item.status == 'unread'">
  15 + <u-image src="/static/img/home/labelBgGreen.png" width="142rpx" height="48rpx"></u-image>
  16 + <text>未阅</text>
  17 + </view>
  18 +
  19 + <view class="bg_image" v-else>
  20 + <u-image src="/static/img/home/labelBgGrey.png" width="142rpx" height="48rpx"></u-image>
  21 + <text>已阅</text>
  22 + </view>
  23 +
  24 + <view class="info">
  25 + <view class="avatar">{{getNameLastTwo(item.studentName)}}</view>
  26 + <view class="form_name">
  27 + <view class="name">{{overflowHide(item.title, 10)}}</view>
  28 + <view class="week">
  29 + <!-- <text>{{timeFormat(item.logTime, 'yyyy年')}}</text> -->
  30 + <!-- <text>{{getWeek(item.logTime)}}</text> -->
  31 + <text>{{getCreatedTime(item)}}</text>
  32 +
  33 + </view>
  34 + </view>
  35 + </view>
  36 + <view class="u-content">
  37 + <u-parse :content="item.content"></u-parse>
  38 + </view>
  39 + <view class="name_time">
  40 + <view class="name">
  41 + <text>学生姓名</text>
  42 + <text>{{item.studentName}}</text>
  43 + </view>
  44 + <view class="time">{{timeFormat(item.createdTime)}}</view>
  45 + </view>
  46 +
  47 + </view>
  48 + <c-loading :loading="loading"></c-loading>
  49 + </view>
  50 + <view v-else class="no_data">
  51 + <c-no-data></c-no-data>
  52 + </view>
  53 +
  54 + <u-popup :show="show" mode="right" @close="close" @open="open" :closeOnClickOverlay="false">
  55 + <view class="popup_search">
  56 + <view class="content">
  57 + <view class="title">按项目筛选</view>
  58 + <scroll-view class="scroll" scroll-y="true">
  59 + <view class="item" v-for="(item, i) in projectList" :key="i" @click="handelClick(item)">
  60 + <view class="selectItem" v-if="item.id == projectId">
  61 + <text>{{item.name}}</text>
  62 + </view>
  63 + <view v-else>
  64 + <text>{{item.name}}</text>
  65 + </view>
  66 + </view>
  67 + </scroll-view>
  68 + <view class="switch">
  69 + <text>未阅</text>
  70 + <u-switch v-model="switchValue" size="48" activeColor="#06B079" @change="handelChange">
  71 + </u-switch>
  72 + </view>
  73 + </view>
  74 +
  75 + <view class="footer">
  76 + <view class="left_btn">
  77 + <c-button type="cancel" text="重置" @click="handelCancel">
  78 + </c-button>
  79 + </view>
  80 + <view class="right_btn">
  81 + <c-button type="confirm" text="确定" @click="hancelSubmit">
  82 + </c-button>
  83 + </view>
  84 + </view>
  85 + </view>
  86 + </u-popup>
  87 + </view>
  88 +</template>
  89 +
  90 +<script>
  91 + import {
  92 + mapGetters,
  93 + mapState,
  94 + mapActions
  95 + } from 'vuex'
  96 + import listMixin from "@/common/mixins/list-mixin.js";
  97 +
  98 + import {
  99 + getLogReviewListApi,
  100 + getProjectListApi,
  101 + } from '@/config/api.js';
  102 +
  103 + export default {
  104 + mixins: [listMixin],
  105 + data() {
  106 + return {
  107 + studentId: '',
  108 + formId: '',
  109 + checkboxValue: [],
  110 + checkboxList: [{
  111 + name: '未阅',
  112 + disabled: false
  113 + }],
  114 + keyword: '',
  115 + search: {
  116 + //搜索对象必须为key search的对象
  117 + keySearch: "",
  118 + status: '',
  119 + category: 'daily',
  120 +
  121 + },
  122 + show: false, //筛选
  123 + current: 0,
  124 + tabs: [{
  125 + name: '日志',
  126 + }, {
  127 + name: '周志',
  128 + }, {
  129 + name: '月志'
  130 + }],
  131 +
  132 + list: [], //列表必须为key list的数组
  133 +
  134 + projectId: '',
  135 + showTime: false,
  136 + timeValue: '',
  137 + switchValue: false,
  138 +
  139 + }
  140 + },
  141 +
  142 + onLoad(option) {
  143 + console.log(option)
  144 + this.studentId = option.studentId;
  145 + this.projectId = option.projectId;
  146 + this.formId = option.formId;
  147 +
  148 + this.$store.dispatch(`home/getProjectList`, {
  149 + pageSize: -1,
  150 + })
  151 +
  152 + this.search.keySearch = '';
  153 +
  154 + if (option && option.category) {
  155 + this.search.category = option.category;
  156 + this.current =
  157 + option.category == 'daily' ? 0 :
  158 + option.category == 'weekly' ? 1 :
  159 + option.category == 'monthly' ? 2 :
  160 + '';
  161 + }
  162 +
  163 + if (option && option.status) {
  164 + this.search.status = 'unread';
  165 + this.checkboxValue = ['未阅'];
  166 + this.switchValue = true;
  167 + }
  168 +
  169 + this.finished = false;
  170 + this.loading = "loadmore";
  171 + this.page = 0;
  172 + this.list = [];
  173 + this._getList();
  174 + },
  175 +
  176 + onShow() {
  177 +
  178 + },
  179 +
  180 + computed: {
  181 + ...mapState('home', {
  182 + // 箭头函数可使代码更简练
  183 + projectList: 'projectList',
  184 + }),
  185 + },
  186 +
  187 + methods: {
  188 +
  189 + getCreatedTime(e) {
  190 + let time = this.$u.timeFormat(e.logTime / 1000, 'yyyy/mm/dd');
  191 + if (e.category == "weekly") {
  192 + time = new Date(e.logTime).getFullYear() + "年第" + (this.getWeek(e.logTime) + 1) + "周";
  193 + } else if (e.category == "monthly") {
  194 + time = this.$u.timeFormat(e.logTime / 1000, 'yyyy年mm月');
  195 + }
  196 + return time
  197 + },
  198 +
  199 + getWeek(dt) {
  200 + if (dt > 0) {
  201 + let d1 = new Date(dt);
  202 + let d2 = new Date(dt);
  203 + d2.setMonth(0);
  204 + d2.setDate(1);
  205 + let rq = d1 - d2;
  206 + let days = Math.ceil(rq / (24 * 60 * 60 * 1000));
  207 + let num = Math.ceil(days / 7);
  208 + return num;
  209 + } else {
  210 + return '';
  211 + }
  212 + },
  213 +
  214 + getNameLastTwo(value) {
  215 + if (value && value.length > 3) {
  216 + return value.substring(value.length - 3)
  217 + } else {
  218 + return value;
  219 + }
  220 + },
  221 +
  222 + overflowHide(value, num = 4) {
  223 + if (value && value.length > num) {
  224 + return `${value.slice(0, num)}...`
  225 + } else {
  226 + return value;
  227 + }
  228 + },
  229 +
  230 + handelTab(item) {
  231 + let category = item.index === 0 ? 'daily' : item.index === 1 ? 'weekly' : item.index === 2 ? 'monthly' :
  232 + '';
  233 +
  234 + this.search.category = category;
  235 +
  236 + this.finished = false;
  237 + this.loading = "loadmore";
  238 + this.page = 0;
  239 + this.list = [];
  240 + this._getList();
  241 +
  242 + },
  243 +
  244 + handelDetail(record) {
  245 + this.$u.route({
  246 + url: `pages/main/home/logDetail/logDetail?id=${record.id}&formId=${record.formId}`
  247 + })
  248 + },
  249 +
  250 + timeFormat(timestamp, format = 'yyyy-mm-dd') {
  251 + return timestamp > 0 ? uni.$u.timeFormat(timestamp, format) : '--'
  252 + },
  253 +
  254 + checkboxChange(n) {
  255 + console.log('change', n);
  256 +
  257 + this.search.status = n.length > 0 ? 'unread' : '';
  258 +
  259 + this.switchValue = n.length > 0 ? true : false;
  260 +
  261 + this.finished = false;
  262 + this.loading = "loadmore";
  263 + this.page = 0;
  264 + this.list = [];
  265 + this._getList();
  266 + },
  267 +
  268 + handelSearch(value) {
  269 + this.finished = false;
  270 + this.loading = "loadmore";
  271 + this.page = 0;
  272 + this.list = [];
  273 + this._getList();
  274 + },
  275 +
  276 + open() {
  277 +
  278 + },
  279 +
  280 + close() {
  281 + this.show = false
  282 + },
  283 +
  284 + // scroll-view到底部加载更多
  285 + onreachBottom() {},
  286 + // 搜索
  287 + searchSubmit() {
  288 + // 调用混合搜索
  289 + this._searchData();
  290 + },
  291 + // 模拟后端分页
  292 + async getData(requestParams) {
  293 + const {
  294 + search = {}
  295 + } = requestParams;
  296 +
  297 + let params = {};
  298 + params.pageNumber = requestParams.page + 1;
  299 + params.pageSize = 5;
  300 +
  301 + if (search.status) {
  302 + params.status = search.status;
  303 + }
  304 +
  305 + if (search.category) {
  306 + params.category = search.category;
  307 + }
  308 +
  309 + if (this.keyword) {
  310 + params.keySearch = this.keyword
  311 + }
  312 +
  313 + if (this.studentId) {
  314 + params.studentId = this.studentId
  315 + }
  316 +
  317 + if (this.projectId) {
  318 + params.projectId = this.projectId
  319 + }
  320 +
  321 + if (this.formId) {
  322 + params.formId = this.formId
  323 + }
  324 +
  325 + return await getLogReviewListApi(params);
  326 + },
  327 + // 数据请求(没错就是这么少的代码)
  328 + async _getList() {
  329 + if (this.page == 0) {
  330 + this.list = [];
  331 + }
  332 +
  333 + // 根据实际情况修改自己修改key
  334 + let result = await this.getData({
  335 + page: this.page, // 传入页码
  336 + size: this.size, // 传入每页条数
  337 + search: this.search, // 传入搜索的对象
  338 + });
  339 +
  340 + this.total = result.total;
  341 +
  342 + if (this.list.length == 0 && result.records.length == 0) {
  343 + this.shownoData = false
  344 + } else {
  345 + this.shownoData = true
  346 + }
  347 +
  348 + this.list = this.list.concat(result.records)
  349 +
  350 + // 判断是否全部加载完成
  351 + if (this.total == this.list.length) {
  352 + this.finished = true;
  353 + this.loading = 'nomore';
  354 + } else {
  355 + this.loading = 'loadmore';
  356 + }
  357 + },
  358 +
  359 + handelClick(values) {
  360 + this.projectId = values.id;
  361 + },
  362 +
  363 + handelChange(e) {
  364 + this.checkboxValue = e ? ['未阅'] : [];
  365 + this.search.status = e ? 'unread' : '';
  366 +
  367 + },
  368 +
  369 + handelCancel() {
  370 + this.switchValue = false;
  371 + this.projectId = '';
  372 + },
  373 +
  374 + hancelSubmit() {
  375 + this.finished = false;
  376 + this.loading = "loadmore";
  377 + this.page = 0;
  378 + this.list = [];
  379 + this._getList();
  380 +
  381 + this.show = false;
  382 + },
  383 +
  384 + }
  385 + }
  386 +</script>
  387 +
  388 +<style lang="scss" scoped>
  389 + .registration_review {
  390 + width: 100%;
  391 + min-height: 100%;
  392 + height: auto;
  393 + background-color: #F7F7F7;
  394 +
  395 + .search_box {
  396 + padding: 36rpx 30rpx 12rpx;
  397 + background-color: #FFFFFF;
  398 + display: flex;
  399 + flex-flow: row nowrap;
  400 + justify-content: space-between;
  401 +
  402 + .check {
  403 + padding: 20rpx 0 0 0;
  404 + }
  405 +
  406 + .search {
  407 + width: 468rpx;
  408 + }
  409 + }
  410 +
  411 + .list_box {
  412 + padding: 0 0 50rpx 0;
  413 +
  414 + .item {
  415 + position: relative;
  416 + width: 630rpx;
  417 + margin: 30rpx auto;
  418 + padding: 30rpx;
  419 + border-radius: 12rpx;
  420 + background-color: #FFFFFF;
  421 +
  422 + .bg_image {
  423 + position: absolute;
  424 + top: 0;
  425 + right: 0;
  426 +
  427 + text {
  428 + position: absolute;
  429 + top: 12rpx;
  430 + right: 30rpx;
  431 + font-size: 24rpx;
  432 + line-height: 24rpx;
  433 + color: #FFFFFF;
  434 + }
  435 + }
  436 +
  437 + .info {
  438 + display: flex;
  439 + flex-flow: row nowrap;
  440 + align-items: center;
  441 + margin: 0 0 30rpx 0;
  442 +
  443 + .avatar {
  444 + width: 94rpx;
  445 + height: 94rpx;
  446 + border-radius: 4rpx;
  447 + background-color: #06B079;
  448 + font-size: 24rpx;
  449 + line-height: 94rpx;
  450 + color: #FFFFFF;
  451 + text-align: center;
  452 + }
  453 +
  454 + .form_name {
  455 + .name {
  456 + font-size: 32rpx;
  457 + line-height: 44rpx;
  458 + color: #202131;
  459 + font-weight: 500;
  460 + margin: 0 20rpx;
  461 + }
  462 +
  463 + .week {
  464 + padding: 8rpx 0 0 0;
  465 + font-size: 20rpx;
  466 + line-height: 32rpx;
  467 + color: #909097;
  468 +
  469 + // padding: 0 0 0 20rpx;
  470 + text {
  471 + padding: 8rpx 0 0 20rpx;
  472 + }
  473 + }
  474 + }
  475 + }
  476 +
  477 + .u-content {
  478 + font-size: 24rpx;
  479 + line-height: 32rpx;
  480 + color: #909097;
  481 + margin: 32rpx 0 30rpx 0;
  482 + }
  483 +
  484 + .name_time {
  485 + border-top: 2rpx solid #E2E2E8;
  486 + padding: 28rpx 0 0 0;
  487 + display: flex;
  488 + flex-flow: row nowrap;
  489 + justify-content: space-between;
  490 +
  491 +
  492 + .name {
  493 + text {
  494 + font-size: 28rpx;
  495 + line-height: 32rpx;
  496 + color: #909097;
  497 + }
  498 +
  499 + text:last-child {
  500 + color: #202131;
  501 + margin: 0 0 0 30rpx;
  502 + }
  503 + }
  504 +
  505 + .time {
  506 + font-size: 28rpx;
  507 + line-height: 32rpx;
  508 + color: #909097;
  509 + }
  510 + }
  511 + }
  512 + }
  513 +
  514 + .popup_search {
  515 + width: 640rpx;
  516 + position: relative;
  517 +
  518 + .content {
  519 + padding: 0 40rpx;
  520 +
  521 + .title {
  522 + padding: 24rpx 0;
  523 + font-size: 28rpx;
  524 + line-height: 36rpx;
  525 + color: #202131;
  526 + }
  527 +
  528 + .scroll {
  529 + max-height: 60vh;
  530 +
  531 + .item {
  532 +
  533 + view {
  534 + display: flex;
  535 + flex-flow: row wrap;
  536 + align-items: center;
  537 + width: 500rpx;
  538 + height: 74rpx;
  539 + border-radius: 4rpx;
  540 + border: 2rpx solid #C1C1C9;
  541 + margin: 0 10rpx 20rpx;
  542 + font-size: 24rpx;
  543 + line-height: 32rpx;
  544 + color: #C0C0C9;
  545 + padding: 16rpx 20rpx;
  546 + }
  547 +
  548 + .selectItem {
  549 + background-color: #06B079;
  550 + color: #FFFFFF;
  551 + border: 2rpx solid #06B079;
  552 + }
  553 + }
  554 + }
  555 +
  556 + .time {
  557 + padding: 40rpx 0 0 0;
  558 + }
  559 +
  560 + .switch {
  561 + display: flex;
  562 + flex-flow: row nowrap;
  563 + justify-content: space-between;
  564 + padding: 40rpx 0 0 0;
  565 +
  566 + text {
  567 + font-size: 28rpx;
  568 + line-height: 36rpx;
  569 + color: #202131;
  570 + }
  571 + }
  572 +
  573 +
  574 + }
  575 +
  576 + .footer {
  577 + width: 560rpx;
  578 + height: 96rpx;
  579 + padding: 28rpx 40rpx;
  580 + background: #FFFFFF;
  581 + position: fixed;
  582 + bottom: 0;
  583 + right: 0;
  584 + z-index: 99;
  585 + border-top: 2rpx solid #E2E2E8;
  586 +
  587 + view {
  588 + display: inline-block;
  589 + }
  590 +
  591 + .left_btn {
  592 + width: 194rpx;
  593 + margin: 0 20rpx 0 0;
  594 + }
  595 +
  596 + .right_btn {
  597 + width: 346rpx;
  598 + }
  599 + }
  600 + }
  601 + }
  602 +</style>
... ...
  1 +<template>
  2 + <view class="report_detail">
  3 + <view class="box form_info">
  4 + <view class="info">
  5 + <view class="avatar">{{getNameLastTwo(detail.studentName)}}</view>
  6 + <view class="name">{{overflowHide(detail.studentName, 6)}}</view>
  7 + <view class="number">NO.{{detail.studentNumber}}</view>
  8 + </view>
  9 + <view class="company">
  10 + <text>联系电话</text>
  11 + <text>{{detail.studentPhone || '--'}}</text>
  12 + </view>
  13 + <view class="company">
  14 + <text>班级信息</text>
  15 + <text>{{detail.departmentName}} {{detail.classInfo}}</text>
  16 + </view>
  17 + </view>
  18 +
  19 + <view class="tab_box">
  20 + <view class="tab">
  21 + <u-tabs :list="tabs" :scrollable="false" lineWidth="30rpx" lineHeight="4rpx" lineColor="#06B079"
  22 + :inactiveStyle="{fontSize:'28rpx', color:'#4A4A53'}"
  23 + :activeStyle="{fontSize:'36rpx', color:'#06B079'}" @change="handelTab" :current="current">
  24 + </u-tabs>
  25 + </view>
  26 + <view class="u-icon" v-if="current == 0">
  27 + <u-icon slot="icon" size="40" :name="'/static/img/home/selectIcon.png'" @click="show = true"></u-icon>
  28 + </view>
  29 + </view>
  30 +
  31 + <view v-if="current == 0">
  32 + <view class="box attendance">
  33 + <view class="title">考勤</view>
  34 + <view class="item_icon">
  35 + <text>考勤天数</text>
  36 + <view @click="handelRecord('signin')">
  37 + <text>{{detail.attendanceCount || 0}}天</text>
  38 + <u-icon :style="{margin:'0 0 0 8rpx'}" name="arrow-right" color="#909097" size="28"></u-icon>
  39 + </view>
  40 + </view>
  41 + </view>
  42 +
  43 + <view class="box attendance">
  44 + <view class="title">提交材料</view>
  45 + <view class="item_icon">
  46 + <text>三方协议</text>
  47 + <view @click="handelRecord('aggrent')">
  48 + <text>查看</text>
  49 + <u-icon :style="{margin:'0 0 0 8rpx'}" name="arrow-right" color="#909097" size="28"></u-icon>
  50 + </view>
  51 + </view>
  52 + <view class="item_icon">
  53 + <text>日志</text>
  54 + <view @click="handelRecord('daily')">
  55 + <text>{{detail.dailyLogCount || 0}}篇</text>
  56 + <u-icon :style="{margin:'0 0 0 8rpx'}" name="arrow-right" color="#909097" size="28"></u-icon>
  57 + </view>
  58 + </view>
  59 + <view class="item_icon">
  60 + <text>周志</text>
  61 + <view @click="handelRecord('weekly')">
  62 + <text>{{detail.weekLogCount || 0}}篇</text>
  63 + <u-icon :style="{margin:'0 0 0 8rpx'}" name="arrow-right" color="#909097" size="28"></u-icon>
  64 + </view>
  65 + </view>
  66 + <view class="item_icon">
  67 + <text>月志</text>
  68 + <view @click="handelRecord('monthly')">
  69 + <text>{{detail.monthlyLogCount || 0}}篇</text>
  70 + <u-icon :style="{margin:'0 0 0 8rpx'}" name="arrow-right" color="#909097" size="28"></u-icon>
  71 + </view>
  72 + </view>
  73 + <view class="item_icon">
  74 + <text>实习报告</text>
  75 + <view @click="handelRecord('report')">
  76 + <text>{{detail.internshipReportCount || 0}}次</text>
  77 + <u-icon :style="{margin:'0 0 0 8rpx'}" name="arrow-right" color="#909097" size="28"></u-icon>
  78 + </view>
  79 + </view>
  80 + </view>
  81 + </view>
  82 +
  83 + <view class="practical_courses" v-if="current == 1">
  84 + <view class="list_box" v-if="list.length > 0">
  85 + <view class="item" v-for="(item, i) in list" :key="i">
  86 +
  87 + <view class="company_box">
  88 + <view class="company">
  89 + <u-icon size="32rpx" name="/static/img/home/internshipUnitIcon.png"></u-icon>
  90 + <text>{{item.companyName}}</text>
  91 + </view>
  92 + <view class="address">
  93 + <u-icon size="32rpx" name="/static/img/internship/addressIcon.png"></u-icon>
  94 + <text>{{item.province}}/{{item.city}}/{{item.district}}</text>
  95 + </view>
  96 + </view>
  97 +
  98 + <view class="projiect_item" v-for="(ele, index) in item.jobResultList" :key="index">
  99 +
  100 + <view class="projiect">
  101 + <text>实习岗位</text>
  102 + <text>{{ele.jobName || '--'}}</text>
  103 + </view>
  104 + <view class="projiect">
  105 + <text>实习时间</text>
  106 + <text>{{ ele.startTime>0 ? `${timeFormat(ele.startTime)}至${timeFormat(ele.endTime)}` : '--'}}</text>
  107 + </view>
  108 + <view class="projiect">
  109 + <text>联系人</text>
  110 + <text>{{ele.contactName|| '--'}}</text>
  111 + </view>
  112 + <view class="projiect">
  113 + <text>联系电话</text>
  114 + <text>{{ele.contactPhone|| ''}}</text>
  115 + </view>
  116 + </view>
  117 + </view>
  118 + <c-loading :loading="loading"></c-loading>
  119 + </view>
  120 +
  121 + </view>
  122 +
  123 + <view class="practical_courses" v-if="current == 2">
  124 + <view class="list_box" v-if="list.length > 0">
  125 + <view class="item" v-for="(item, i) in list" :key="i">
  126 +
  127 + <view class="title_box">
  128 + <view class="title">{{item.courseName}}</view>
  129 + <text class="credit">学分:{{item.credit}}分</text>
  130 + </view>
  131 +
  132 + <view class="projiect_item" v-for="(ele, index) in item.achievementDataList" :key="index">
  133 +
  134 + <view class="projiect">
  135 + <text>项目名称</text>
  136 + <text>{{ele.projectName || '--'}}</text>
  137 + </view>
  138 + <view class="projiect">
  139 + <text>实习时间</text>
  140 + <text>{{ ele.internshipStartTime>0 ? `${timeFormat(ele.internshipStartTime)}至${timeFormat(ele.internshipEndTime)}` : '--'}}</text>
  141 + </view>
  142 + <view class="projiect">
  143 + <text>实习单号</text>
  144 + <text @click="handelDetail(ele, 'internship')"
  145 + :style="{color:'#06B079',textDecoration:'underline'}">{{ele.formNumber|| '--'}}</text>
  146 + </view>
  147 + <view class="projiect">
  148 + <text>成绩</text>
  149 + <text>{{ele.level|| '--'}}</text>
  150 + </view>
  151 +
  152 + <view class="projiect" v-if="ele.credit">
  153 + <text>学分</text>
  154 + <text @click="handelDetail(ele, 'credit')"
  155 + :style="{color:'#06B079'}">{{ele.credit}}</text>
  156 + </view>
  157 +
  158 + <view class="projiect" v-else>
  159 + <text>学分</text>
  160 + <text>{{'--'}}</text>
  161 + </view>
  162 + </view>
  163 + </view>
  164 + <c-loading :loading="loading"></c-loading>
  165 + </view>
  166 +
  167 + </view>
  168 +
  169 + <u-popup :show="show" mode="right" @close="close" @open="open" :closeOnClickOverlay="false">
  170 + <view class="popup_search">
  171 + <view class="content">
  172 + <view class="title">按项目筛选</view>
  173 + <scroll-view class="scroll" scroll-y="true">
  174 + <view class="item" v-for="(item, i) in projectList" :key="i" @click="handelClick(item)">
  175 + <view class="selectItem" v-if="item.id == projectId">
  176 + <text>{{item.name}}</text>
  177 + </view>
  178 + <view v-else>
  179 + <text>{{item.name}}</text>
  180 + </view>
  181 + </view>
  182 + </scroll-view>
  183 + </view>
  184 +
  185 + <view class="footer">
  186 + <view class="left_btn">
  187 + <c-button type="cancel" text="重置" @click="handelCancel">
  188 + </c-button>
  189 + </view>
  190 + <view class="right_btn">
  191 + <c-button type="confirm" text="确定" @click="hancelSubmit">
  192 + </c-button>
  193 + </view>
  194 + </view>
  195 + </view>
  196 + </u-popup>
  197 + </view>
  198 +</template>
  199 +
  200 +<script>
  201 + import {
  202 + mapGetters,
  203 + mapState,
  204 + mapActions
  205 + } from 'vuex'
  206 + import listMixin from "@/common/mixins/list-mixin.js";
  207 +
  208 + import {
  209 + getInternshipProcessDetailApi,
  210 + getInternshipJobListApi,
  211 + getPracticalCoursesListApi,
  212 + } from '@/config/api.js';
  213 +
  214 + export default {
  215 + data() {
  216 + return {
  217 + studentId: '',
  218 + detail: {},
  219 + current: 0,
  220 + tabs: [{
  221 + name: '实习过程',
  222 + }, {
  223 + name: '实习岗位',
  224 + }, {
  225 + name: '实践课程'
  226 + }],
  227 + show: false,
  228 + projectId: '',
  229 + list: [],
  230 + search: {
  231 + //搜索对象必须为key search的对象
  232 + status: 'wait,pass,reject',
  233 +
  234 + },
  235 + }
  236 + },
  237 +
  238 + onLoad(option) {
  239 + this.$store.dispatch(`home/getProjectList`, {
  240 + pageSize: -1,
  241 + })
  242 +
  243 + this.studentId = option.studentId;
  244 + getInternshipProcessDetailApi({
  245 + studentId: option.studentId,
  246 + }).then(data => {
  247 + if (data) {
  248 + this.detail = data
  249 + }
  250 + })
  251 + },
  252 +
  253 + computed: {
  254 + ...mapState('home', {
  255 + // 箭头函数可使代码更简练
  256 + projectList: 'projectList',
  257 + }),
  258 + },
  259 +
  260 + methods: {
  261 +
  262 + getNameLastTwo(value) {
  263 + if (value && value.length > 3) {
  264 + return value.substring(value.length - 3)
  265 + } else {
  266 + return value;
  267 + }
  268 + },
  269 +
  270 + overflowHide(value, num = 4) {
  271 + if (value && value.length > num) {
  272 + return `${value.slice(0, num)}...`
  273 + } else {
  274 + return value;
  275 + }
  276 + },
  277 +
  278 + timeFormat(timestamp, format = 'yyyy-mm-dd') {
  279 + return timestamp > 0 ? uni.$u.timeFormat(timestamp, format) : '--'
  280 + },
  281 +
  282 + handelTab(item) {
  283 + this.current = item.index;
  284 +
  285 + switch (item.index) {
  286 +
  287 + case 1:
  288 + this.finished = false;
  289 + this.loading = "loadmore";
  290 + this.page = 0;
  291 + this.list = [];
  292 + this._getList();
  293 + break;
  294 +
  295 + case 2:
  296 + this.finished = false;
  297 + this.loading = "loadmore";
  298 + this.page = 0;
  299 + this.list = [];
  300 + this._getList();
  301 + break;
  302 + }
  303 + },
  304 +
  305 + handelRecord(type) {
  306 +
  307 + switch (type) {
  308 +
  309 + case 'signin':
  310 + if(!this.projectId) {
  311 + this.$u.toast('请先选择实习项目');
  312 + return;
  313 + }
  314 + this.$u.route({
  315 + url: `pages/main/internship/signInList/signInList?studentId=${this.detail.studentId}&projectId=${this.projectId}`
  316 + })
  317 + break;
  318 +
  319 + case 'aggrent':
  320 + this.$u.route({
  321 + url: `pages/main/internship/agreementList/agreementList?studentId=${this.detail.studentId}&projectId=${this.projectId}`
  322 + })
  323 + break;
  324 +
  325 + case 'daily':
  326 + this.$u.route({
  327 + url: `pages/main/internship/studentLogReview/studentLogReview?category=daily&studentId=${this.detail.studentId}&projectId=${this.projectId}`
  328 + })
  329 + break;
  330 +
  331 + case 'weekly':
  332 + this.$u.route({
  333 + url: `pages/main/internship/studentLogReview/studentLogReview?category=weekly&studentId=${this.detail.studentId}&projectId=${this.projectId}`
  334 + })
  335 + break;
  336 +
  337 + case 'monthly':
  338 + this.$u.route({
  339 + url: `pages/main/internship/studentLogReview/studentLogReview?category=monthly&studentId=${this.detail.studentId}&projectId=${this.projectId}`
  340 + })
  341 + break;
  342 +
  343 + case 'report':
  344 + this.$u.route({
  345 + url: `pages/main/home/reportReview/reportReview?studentId=${this.detail.studentId}&projectId=${this.projectId}`
  346 + })
  347 + break;
  348 + }
  349 +
  350 + },
  351 +
  352 + open() {
  353 +
  354 + },
  355 +
  356 + close() {
  357 + this.show = false
  358 + },
  359 +
  360 + handelClick(values) {
  361 + this.projectId = values.id;
  362 + },
  363 +
  364 + handelCancel() {
  365 + this.switchValue = false;
  366 + this.projectId = '';
  367 + },
  368 +
  369 + hancelSubmit() {
  370 + this.finished = false;
  371 +
  372 + getInternshipProcessDetailApi({
  373 + studentId: this.studentId,
  374 + projectId: this.projectId,
  375 + }).then(data => {
  376 + if (data) {
  377 + this.detail = data;
  378 + this.show = false
  379 + }
  380 + })
  381 + },
  382 +
  383 + // scroll-view到底部加载更多
  384 + onreachBottom() {},
  385 + // 搜索
  386 + searchSubmit() {
  387 + // 调用混合搜索
  388 + this._searchData();
  389 + },
  390 + // 模拟后端分页
  391 + async getData(requestParams) {
  392 + const {
  393 + search = {}
  394 + } = requestParams;
  395 +
  396 + let params = {};
  397 + params.pageNumber = requestParams.page + 1;
  398 + params.pageSize = 5;
  399 +
  400 + if (this.studentId) {
  401 + params.studentId = this.studentId
  402 + }
  403 +
  404 + if (this.current == 1) {
  405 + return await getInternshipJobListApi(params);
  406 + } else {
  407 + return await getPracticalCoursesListApi(params);
  408 + }
  409 +
  410 +
  411 + },
  412 + // 数据请求(没错就是这么少的代码)
  413 + async _getList() {
  414 + if (this.page == 0) {
  415 + this.list = [];
  416 + }
  417 +
  418 + // 根据实际情况修改自己修改key
  419 + let result = await this.getData({
  420 + page: this.page, // 传入页码
  421 + size: this.size, // 传入每页条数
  422 + search: this.search, // 传入搜索的对象
  423 + });
  424 +
  425 + console.log(this.list, result)
  426 +
  427 + this.total = result.total;
  428 +
  429 + if (this.list.length == 0 && result.length == 0) {
  430 + this.shownoData = false
  431 + } else {
  432 + this.shownoData = true
  433 + }
  434 +
  435 + this.list = this.list.concat(result)
  436 +
  437 + // 判断是否全部加载完成
  438 + if (this.total == this.list.length) {
  439 + this.finished = true;
  440 + this.loading = 'nomore';
  441 + } else {
  442 + this.loading = 'loadmore';
  443 + }
  444 + },
  445 +
  446 + handelDetail(record, type) {
  447 + switch (type) {
  448 + case 'internship':
  449 + this.$u.route({
  450 + url: `pages/main/internship/intershipInfo/intershipInfo?id=${record.formId}`
  451 + })
  452 + break;
  453 +
  454 + case 'credit':
  455 + this.$u.route({
  456 + url: `pages/main/internship/achievementDetail/achievementDetail?id=${record.formId}`
  457 + })
  458 + break;
  459 + }
  460 + }
  461 +
  462 + }
  463 + }
  464 +</script>
  465 +
  466 +<style lang="scss" scoped>
  467 + .report_detail {
  468 + width: 100%;
  469 + min-height: 100%;
  470 + height: auto;
  471 + background-color: #F7F7F7;
  472 + padding: 20rpx 0 0 0;
  473 +
  474 + .box {
  475 + width: 630rpx;
  476 + margin: 20rpx auto;
  477 + padding: 30rpx 30rpx 12rpx 30rpx;
  478 + border-radius: 12rpx;
  479 + background-color: #FFFFFF;
  480 +
  481 + .title {
  482 + font-size: 32rpx;
  483 + line-height: 32rpx;
  484 + color: #202131;
  485 + margin: 0 0 30rpx 0;
  486 + }
  487 +
  488 + .title::before {
  489 + content: "";
  490 + display: inline-block;
  491 + width: 6rpx;
  492 + height: 32rpx;
  493 + background-color: #06B079;
  494 + margin: 0 12rpx 0 0;
  495 + position: relative;
  496 + top: 4rpx;
  497 + border-radius: 8rpx;
  498 + }
  499 +
  500 + .item {
  501 + margin: 0 0 24rpx 0;
  502 +
  503 + text:first-child {
  504 + display: inline-block;
  505 + width: 112rpx;
  506 + text-align: justify;
  507 + text-align-last: justify;
  508 + font-size: 28rpx;
  509 + line-height: 48rpx;
  510 + color: #909097;
  511 + vertical-align: top;
  512 + }
  513 +
  514 + text:last-child {
  515 + display: inline-block;
  516 + width: 440rpx;
  517 + font-size: 28rpx;
  518 + line-height: 48rpx;
  519 + color: #202131;
  520 + margin: 0 0 0 78rpx;
  521 + }
  522 + }
  523 +
  524 + .item_icon {
  525 + margin: 0 0 24rpx 0;
  526 + display: flex;
  527 + flex-flow: row nowrap;
  528 + justify-content: space-between;
  529 + margin: 0 0 50rpx 0;
  530 +
  531 + text {
  532 + display: inline-block;
  533 + width: 112rpx;
  534 + text-align: justify;
  535 + text-align-last: justify;
  536 + font-size: 28rpx;
  537 + line-height: 32rpx;
  538 + color: #909097;
  539 + vertical-align: top;
  540 + }
  541 +
  542 + view {
  543 + display: flex;
  544 + flex-flow: row nowrap;
  545 +
  546 + text {
  547 + display: inline-block;
  548 + width: auto;
  549 + font-size: 28rpx;
  550 + line-height: 32rpx;
  551 + color: #202131;
  552 + margin: 0 0 0 78rpx;
  553 + }
  554 + }
  555 + }
  556 + }
  557 +
  558 + .form_info {
  559 + .info {
  560 + display: flex;
  561 + flex-flow: row nowrap;
  562 + align-items: center;
  563 + margin: 0 0 30rpx 0;
  564 +
  565 + .avatar {
  566 + width: 94rpx;
  567 + height: 94rpx;
  568 + padding: 0 8rpx;
  569 + border-radius: 4rpx;
  570 + background-color: #06B079;
  571 + font-size: 24rpx;
  572 + line-height: 94rpx;
  573 + color: #FFFFFF;
  574 + text-align: center;
  575 + }
  576 +
  577 + .name {
  578 + font-size: 32rpx;
  579 + line-height: 44rpx;
  580 + color: #202131;
  581 + font-weight: 500;
  582 + margin: 0 20rpx;
  583 + }
  584 +
  585 + .number {
  586 + font-size: 28rpx;
  587 + line-height: 32rpx;
  588 + color: #909097;
  589 + }
  590 + }
  591 +
  592 + .company {
  593 + display: flex;
  594 + flex-flow: row nowrap;
  595 + margin: 0 0 30rpx 0;
  596 +
  597 + text {
  598 + width: 120rpx;
  599 + font-size: 28rpx;
  600 + line-height: 32rpx;
  601 + color: #909097;
  602 + }
  603 +
  604 + text:last-child {
  605 + width: 470rpx;
  606 + color: #202131;
  607 + margin: 0 0 0 30rpx;
  608 + }
  609 + }
  610 + }
  611 +
  612 + .tab_box {
  613 + position: relative;
  614 +
  615 + .tab {
  616 + width: 600rpx;
  617 + }
  618 +
  619 + .u-icon {
  620 + width: 32rpx;
  621 + position: absolute;
  622 + top: 30rpx;
  623 + right: 30rpx;
  624 + }
  625 + }
  626 +
  627 + .practical_courses {
  628 +
  629 + .list_box {
  630 + padding: 30rpx 0 50rpx 0;
  631 +
  632 + .item {
  633 + position: relative;
  634 + width: 630rpx;
  635 + margin: 0 auto 30rpx;
  636 + padding: 30rpx;
  637 + border-radius: 12rpx;
  638 + background-color: #FFFFFF;
  639 +
  640 + .title_box {
  641 + display: flex;
  642 + flex-flow: row nowrap;
  643 +
  644 + .title {
  645 + font-size: 32rpx;
  646 + line-height: 44rpx;
  647 + color: #202131;
  648 + margin: 0 0 30rpx 0;
  649 + font-weight: 500;
  650 + }
  651 +
  652 + .title::before {
  653 + content: "";
  654 + display: inline-block;
  655 + width: 6rpx;
  656 + height: 32rpx;
  657 + background-color: #06B079;
  658 + margin: 0 12rpx 0 0;
  659 + position: relative;
  660 + top: 4rpx;
  661 + border-radius: 8rpx;
  662 + }
  663 +
  664 + .credit {
  665 + font-size: 28rpx;
  666 + line-height: 44rpx;
  667 + color: #909097;
  668 + margin: 0 0 0 32rpx;
  669 + }
  670 + }
  671 +
  672 + .company_box {
  673 + .company {
  674 + display: flex;
  675 + flex-flow: row nowrap;
  676 + font-size: 32rpx;
  677 + line-height: 44rpx;
  678 + color: #202131;
  679 + margin: 0 0 20rpx 0;
  680 + font-weight: 500;
  681 +
  682 + text {
  683 + margin: 0 0 0 8rpx;
  684 + }
  685 + }
  686 +
  687 + .address {
  688 + display: flex;
  689 + flex-flow: row nowrap;
  690 + font-size: 28rpx;
  691 + line-height: 32rpx;
  692 + color: #909097;
  693 + margin: 0 0 20rpx 0;
  694 +
  695 + text {
  696 + margin: 0 0 0 8rpx;
  697 + }
  698 + }
  699 + }
  700 +
  701 + .projiect_item {
  702 + width: 570rpx;
  703 + border-radius: 12rpx;
  704 + background-color: #F8F8FB;
  705 + margin: 0 0 20rpx 0;
  706 + padding: 30rpx;
  707 +
  708 + .projiect {
  709 + display: flex;
  710 + flex-flow: row nowrap;
  711 + margin: 0 0 30rpx 0;
  712 +
  713 + text {
  714 + width: 120rpx;
  715 + font-size: 28rpx;
  716 + line-height: 32rpx;
  717 + color: #909097;
  718 + text-align: justify;
  719 + text-align-last: justify;
  720 + }
  721 +
  722 + text:last-child {
  723 + width: 420rpx;
  724 + color: #202131;
  725 + margin: 0 0 0 30rpx;
  726 + text-align: start;
  727 + text-align-last: start;
  728 + }
  729 + }
  730 + }
  731 +
  732 +
  733 +
  734 + }
  735 + }
  736 + }
  737 +
  738 + .popup_search {
  739 + width: 640rpx;
  740 + position: relative;
  741 +
  742 + .content {
  743 + padding: 0 40rpx;
  744 +
  745 + .title {
  746 + padding: 24rpx 0;
  747 + font-size: 28rpx;
  748 + line-height: 36rpx;
  749 + color: #202131;
  750 + }
  751 +
  752 + .scroll {
  753 + max-height: 60vh;
  754 +
  755 + .item {
  756 +
  757 + view {
  758 + display: flex;
  759 + flex-flow: row wrap;
  760 + align-items: center;
  761 + width: 500rpx;
  762 + height: 74rpx;
  763 + border-radius: 4rpx;
  764 + border: 2rpx solid #C1C1C9;
  765 + margin: 0 10rpx 20rpx;
  766 + font-size: 24rpx;
  767 + line-height: 32rpx;
  768 + color: #C0C0C9;
  769 + padding: 16rpx 20rpx;
  770 + }
  771 +
  772 + .selectItem {
  773 + background-color: #06B079;
  774 + color: #FFFFFF;
  775 + border: 2rpx solid #06B079;
  776 + }
  777 + }
  778 + }
  779 +
  780 + .time {
  781 + padding: 40rpx 0 0 0;
  782 + }
  783 +
  784 + .switch {
  785 + display: flex;
  786 + flex-flow: row nowrap;
  787 + justify-content: space-between;
  788 + padding: 40rpx 0 0 0;
  789 +
  790 + text {
  791 + font-size: 28rpx;
  792 + line-height: 36rpx;
  793 + color: #202131;
  794 + }
  795 + }
  796 +
  797 +
  798 + }
  799 +
  800 + .footer {
  801 + width: 560rpx;
  802 + height: 96rpx;
  803 + padding: 28rpx 40rpx;
  804 + background: #FFFFFF;
  805 + position: fixed;
  806 + bottom: 0;
  807 + right: 0;
  808 + z-index: 99;
  809 + border-top: 2rpx solid #E2E2E8;
  810 +
  811 + view {
  812 + display: inline-block;
  813 + }
  814 +
  815 + .left_btn {
  816 + width: 194rpx;
  817 + margin: 0 20rpx 0 0;
  818 + }
  819 +
  820 + .right_btn {
  821 + width: 346rpx;
  822 + }
  823 + }
  824 + }
  825 + }
  826 +</style>
... ...
  1 +<template>
  2 + <view class="account_safe">
  3 + <view class="cell top">
  4 + <u-cell-group>
  5 + <u-cell title="登录账号" :isLink="true" url="/pages/main/my/editAccount/editAccount" arrow-direction="right"
  6 + :rightIconStyle="{fontSize:'26rpx'}" :title-style="{color:'#909097', fontSize:'28rpx'}">
  7 + <text slot="value" class="u-slot-value">{{accountName}}</text>
  8 + </u-cell>
  9 + <u-cell title="修改登录密码" :isLink="true" url="/pages/main/my/editPassword/editPassword"
  10 + arrow-direction="right" :rightIconStyle="{fontSize:'26rpx'}"
  11 + :title-style="{color:'#909097', fontSize:'28rpx'}">
  12 + <text slot="value" class="u-slot-value">******</text>
  13 + </u-cell>
  14 + </u-cell-group>
  15 + </view>
  16 +
  17 + <view class="cell bottom">
  18 + <u-cell-group :border="false">
  19 + <u-cell title="手机号" :isLink="true" url="/pages/main/my/editMobile/editMobile" arrow-direction="right"
  20 + :rightIconStyle="{fontSize:'26rpx'}" :title-style="{color:'#909097', fontSize:'28rpx'}">
  21 + <text slot="value" class="u-slot-value">{{getPhone}}</text>
  22 + </u-cell>
  23 + <u-cell title="注销账户" :isLink="true" url="/pages/main/my/removeAccount/removeAccount" arrow-direction="right"
  24 + :rightIconStyle="{fontSize:'26rpx'}" :title-style="{color:'#909097', fontSize:'28rpx'}">
  25 + </u-cell>
  26 + </u-cell-group>
  27 + </view>
  28 +
  29 + </view>
  30 +</template>
  31 +
  32 +<script>
  33 + import {
  34 + mapState,
  35 + mapActions
  36 + } from 'vuex'
  37 + import {
  38 + replaceTextToStar
  39 + } from '@/common/commonUtil.js'
  40 +
  41 + export default {
  42 + data() {
  43 + return {
  44 +
  45 + }
  46 + },
  47 +
  48 + computed: {
  49 + ...mapState({
  50 + accountName: (state) => state.vuex_user.username ? state.vuex_user.username : '',
  51 +
  52 + getPhone(state) {
  53 + let phone = state.vuex_user.phone;
  54 + return phone ? replaceTextToStar(phone) : '';
  55 + },
  56 +
  57 + }),
  58 + },
  59 +
  60 + methods: {
  61 + link(type) {
  62 +
  63 + switch (type) {
  64 + case 'account':
  65 + this.$u.route('/pages/student/my/edit-account/edit-account');
  66 + break;
  67 +
  68 + case 'password':
  69 + this.$u.route('/pages/student/my/edit-password/edit-password');
  70 + break;
  71 + }
  72 +
  73 + },
  74 + }
  75 + }
  76 +</script>
  77 +
  78 +<style lang="scss" scoped>
  79 + .account_safe {
  80 + width: 100%;
  81 + height: 100%;
  82 + background-color: #F7F7F7;
  83 + padding: 20rpx 0 0 0;
  84 +
  85 + .top {
  86 + margin: 0 0 20rpx 0;
  87 + }
  88 +
  89 + .cell {
  90 + background-color: #FFFFFF;
  91 +
  92 + .u-slot-value {
  93 + font-size: 28rpx;
  94 + line-height: 40rpx;
  95 + color: #202131;
  96 + }
  97 + }
  98 +
  99 + .cell /deep/ .u-cell {
  100 + padding: 12rpx 0;
  101 +
  102 + .u-cell__value {
  103 + font-size: 34rpx;
  104 + color: rgba(0, 0, 0, 0.5);
  105 + }
  106 + }
  107 + }
  108 +</style>
... ...
  1 +<template>
  2 + <view>
  3 + <view style="width: 100%;height: 100%;">
  4 + <view class="title" style="margin: 32rpx;">账户注销协议</view>
  5 + <view class="content">
  6 + <text class="text" :user-select="true">
  7 + 【特别说明】亲爱的用户,在您正式开始下一步账号注销流程前,我们先为您做出如下特别说明:注销账号后,您将无法再以此账号登录和使用一起教育科技(以下简称“我们”或者“一起教育科技”)的产品与服务以及产品及服务中与第三方合作的服务内容(以下简称为“产品与服务”),这同时也可能会给您的售后维权带来不便。且账号一旦注销完成,将无法恢复。请您在注销前慎重考虑。
  8 +
  9 +
  10 +
  11 + 若您经过慎重考虑后仍执意决定注销账号的,请您务必先行仔细阅读和充分理解本《账号注销协议》,在同意全部内容、且在账号符合全部注销条件后,按照我们的注销操作指引点击进行下一步操作,您勾选本注销协议并点击下一步操作的,即视为您已经同意并签署和遵守本协议全部内容。如您在注销后需要再次使用我们的服务的,欢迎您使用手机号码或我们允许的其他方式重新注册。
  12 +
  13 +
  14 +
  15 + (如您执意决定注销账号的,请继续向下阅读)
  16 +
  17 +
  18 +
  19 + 一、您知悉并同意:您的账号注销后,将(可能)产生包括但不限于如下结果需要您自行承担。
  20 + </text>
  21 + </view>
  22 + <view style="position: fixed;bottom: 0;width: 100%;">
  23 + <view class="divide_line"></view>
  24 + <view class="bottom">
  25 + <view class="bd1">
  26 + <text class="text1" @click="giveUp">放弃注销</text>
  27 + </view>
  28 + <view class="bd2">
  29 + <text class="text2" @click="getCode">同意注销</text>
  30 + </view>
  31 + </view>
  32 + </view>
  33 + </view>
  34 +
  35 + <u-overlay :show="showModal">
  36 + <view class="modal" v-show="showModal">
  37 + <image src="/static/img/my/delete.png" class="close" @click="closeModal"></image>
  38 + <view class="text0" style="margin-top:64rpx">请输入验证码</view>
  39 + <view class="text1" style="margin: 32rpx;">已发送至手机号:{{getPhone}}</view>
  40 + <view style="margin: 32rpx auto;width:'200rpx'">
  41 + <u-code-input :maxlength="4" v-model="currentCode" size="48" :focus="false" :dot="true" :width="76"
  42 + @change="change" @finish="goNext"></u-code-input>
  43 + </view>
  44 + <view style="margin-top: 32rpx;">
  45 + <u-code ref="uCode" @change="codeChange">
  46 + </u-code>
  47 + <view class="text2" @click="getCode">{{tips}}</view>
  48 + </view>
  49 + </view>
  50 + </u-overlay>
  51 +
  52 + </view>
  53 +</template>
  54 +
  55 +<script>
  56 + import {
  57 + replaceTextToStar
  58 + } from '@/common/commonUtil.js'
  59 + import {
  60 + mapState,
  61 + mapActions
  62 + } from 'vuex'
  63 +
  64 + import {
  65 + getSmsCodeApi,
  66 + delAccountApi,
  67 + } from '@/config/api.js';
  68 +
  69 + export default {
  70 + data() {
  71 + return {
  72 + showModal: false,
  73 + title_style: {
  74 + "font-size": "34rpx",
  75 + "font-family": "PingFangSC-Medium, PingFang SC",
  76 + "font-weight": 500,
  77 + "color": "#000000"
  78 + },
  79 + tips: '',
  80 + currentCode: ""
  81 + }
  82 + },
  83 +
  84 + computed: {
  85 + ...mapState({
  86 + // phone: (state) => state.vuex_user.phone,
  87 + getPhone(state) {
  88 + let phone = state.vuex_user.phone;
  89 + return replaceTextToStar(phone);
  90 + },
  91 + }),
  92 + },
  93 +
  94 + methods: {
  95 + giveUp() {
  96 + uni.navigateBack({
  97 + delta: 2
  98 + });
  99 + },
  100 +
  101 + getCode() { //获取验证码
  102 + this.showModal = true;
  103 + if (this.$refs.uCode.canGetCode) {
  104 + // 模拟向后端请求验证码
  105 + uni.showLoading({
  106 + title: '正在获取验证码'
  107 + })
  108 +
  109 + getSmsCodeApi({
  110 + phone: this.vuex_phone
  111 + }).then(data => {
  112 + console.log(data)
  113 +
  114 + uni.hideLoading();
  115 + // 这里此提示会被this.start()方法中的提示覆盖
  116 + this.$u.toast('验证码已发送');
  117 + // 通知验证码组件内部开始倒计时
  118 + this.$refs.uCode.start();
  119 +
  120 + })
  121 + } else {
  122 + this.$u.toast('倒计时结束后再发送');
  123 + }
  124 + },
  125 +
  126 + closeModal() {
  127 + if (this.showModal) {
  128 + this.showModal = false;
  129 + this.$refs.uCode.reset();
  130 + this.currentCode = "";
  131 + }
  132 + },
  133 +
  134 + change(e) {
  135 + this.currentCode = e;
  136 + },
  137 +
  138 + codeChange(text) {
  139 + this.tips = text;
  140 + },
  141 +
  142 + goNext(e) {
  143 + console.log('输入结束,当前值为:' + e);
  144 +
  145 + delAccountApi({
  146 + phone: this.vuex_phone,
  147 + code: e,
  148 + }).then(async data => {
  149 + if (data && data.code == 200) {
  150 + uni.showToast({
  151 + title: '注销成功'
  152 + });
  153 + this.closeModal();
  154 +
  155 + await uni.$u.vuex('vuex_user', {});
  156 + await uni.$u.vuex('vuex_token', {});
  157 + await uni.setStorageSync('lifeData', {})
  158 +
  159 + this.$u.route({
  160 + url: '/pages/main/my/freezing/freezing',
  161 + type: 'reLaunch',
  162 + });
  163 + }
  164 + })
  165 + }
  166 + }
  167 + }
  168 +</script>
  169 +
  170 +<style lang="scss" scoped>
  171 + .title {
  172 + font-size: 48rpx;
  173 + font-family: PingFangSC-Medium, PingFang SC;
  174 + font-weight: 500;
  175 + color: #26292F;
  176 + margin-top: 66rpx;
  177 + }
  178 +
  179 + .content {
  180 + width: 690rpx;
  181 + padding: 12rpx 30rpx;
  182 + margin-bottom: 180rpx;
  183 +
  184 + .text {
  185 + font-size: 28rpx;
  186 + font-family: PingFangSC-Regular, PingFang SC;
  187 + font-weight: 400;
  188 + color: #26292F;
  189 + line-height: 40rpx;
  190 + }
  191 + }
  192 +
  193 + .divide_line {
  194 + width: 100%;
  195 + height: 2rpx;
  196 + border: 2rpx solid #F0F0F1;
  197 + }
  198 +
  199 + .bottom {
  200 + height: 144rpx;
  201 + background-color: #fff;
  202 + display: flex;
  203 + flex-direction: row;
  204 +
  205 + .bd1 {
  206 + height: 96rpx;
  207 + border-radius: 8rpx;
  208 + background-color: rgba(0, 0, 0, 0.03);
  209 + margin: auto 30rpx;
  210 + width: 30%;
  211 + display: flex;
  212 + }
  213 +
  214 + .bd2 {
  215 + height: 96rpx;
  216 + border-radius: 8rpx;
  217 + background-color: rgba(12, 177, 122, 1);
  218 + margin: auto 30rpx;
  219 + width: 60%;
  220 + display: flex;
  221 + }
  222 +
  223 + .text1 {
  224 + color: rgba(0, 0, 0, 0.45);
  225 + font-size: 34rpx;
  226 + font-family: PingFangSC-Medium;
  227 + line-height: 48rpx;
  228 + margin: auto;
  229 + }
  230 +
  231 + .text2 {
  232 + color: #ffff;
  233 + font-size: 34rpx;
  234 + line-height: 48rpx;
  235 + margin: auto;
  236 + }
  237 + }
  238 +
  239 + .modal {
  240 + width: 88%;
  241 + position: relative;
  242 + display: flex;
  243 + flex-direction: column;
  244 + margin: 200rpx auto;
  245 + padding-bottom: 64rpx;
  246 + border-radius: 12rpx;
  247 + background-color: #fff;
  248 +
  249 + .close {
  250 + width: 48rpx;
  251 + height: 48rpx;
  252 + padding: 12rpx;
  253 + position: fixed;
  254 + right: 40rpx;
  255 + }
  256 +
  257 + .text0 {
  258 + font-size: 34rpx;
  259 + font-family: PingFangSC-Medium, PingFang SC;
  260 + font-weight: 500;
  261 + color: #000000;
  262 + text-align: center;
  263 + }
  264 +
  265 + .text1 {
  266 + font-size: 34rpx;
  267 + font-family: PingFangSC-Regular, PingFang SC;
  268 + font-weight: 400;
  269 + color: rgba(0, 0, 0, 0.45);
  270 + text-align: center;
  271 + }
  272 +
  273 + .text2 {
  274 + font-size: 30rpx;
  275 + font-family: PingFangSC-Regular, PingFang SC;
  276 + font-weight: 400;
  277 + color: rgba(0, 0, 0, 0.5);
  278 + line-height: 48rpx;
  279 + text-align: center;
  280 + }
  281 + }
  282 +</style>
... ...
  1 +<template>
  2 + <view class="app">
  3 + <view class="content">
  4 + <view class="title">{{title}}</view>
  5 + <!-- <view class="desc">{{desc}}</view> -->
  6 + <text class="paragraph1">
  7 + 隐私政策
  8 + \n
  9 + 本应用尊重并保护所有使用服务用户的个人隐私权。为了给您提供更准确、更有个性化的服务,本应用会按照本隐私权政策的规定使用和披露您的个人信息。但本应用将以高度的勤勉、审慎义务对待这些信息。除本隐私权政策另有规定外,在未征得您事先许可的情况下,本应用不会将这些信息对外披露或向第三方提供。本应用会不时更新本隐私权政策。&nbsp;您在同意本应用服务使用协议之时,即视为您已经同意本隐私权政策全部内容。本隐私权政策属于本应用服务使用协议不可分割的一部分。
  10 + \n
  11 + 1.&nbsp;适用范围
  12 + \n
  13 + a)&nbsp;在您注册本应用帐号时,您根据本应用要求提供的个人注册信息;
  14 + \n
  15 + b)&nbsp;在您使用本应用网络服务,或访问本应用平台网页时,本应用自动接收并记录的您的浏览器和计算机上的信息,包括但不限于您的IP地址、浏览器的类型、使用的语言、访问日期和时间、软硬件特征信息及您需求的网页记录等数据;
  16 + \n
  17 + c)&nbsp;本应用通过合法途径从商业伙伴处取得的用户个人数据。
  18 + \n
  19 + 您了解并同意,以下信息不适用本隐私权政策:
  20 + \n
  21 + a)&nbsp;您在使用本应用平台提供的搜索服务时输入的关键字信息;
  22 + \n
  23 + b)&nbsp;本应用收集到的您在本应用发布的有关信息数据,包括但不限于参与活动、成交信息及评价详情;
  24 + \n
  25 + c)&nbsp;违反法律规定或违反本应用规则行为及本应用已对您采取的措施。
  26 + </text>
  27 + </view>
  28 + </view>
  29 +</template>
  30 +
  31 +<script>
  32 + export default {
  33 + data() {
  34 + return {
  35 + type: '0',
  36 + title: '',
  37 + desc: ''
  38 + }
  39 + },
  40 + onReady() {
  41 + if (this.type == '0') {
  42 + this.title = '隐私协议';
  43 + this.desc = '隐私政策本应用尊重并保护所有使用服务用户的个人隐私权。为了给您提供更准确、更有个性化的服务,本应用会按照本隐私权政策的规定使用和披露您的个人信息。但本应用将以高度的勤勉、审慎义务对待这些信息。除本隐私权政策另有规定外,在未征得您事先许可的情况下,本应用不会将这些信息对外披露或向第三方提供。本应用会不时更新本隐私权政策。 您在同意本应用服务使用协议之时,即视为您已经同意本隐私权政策全部内容。本隐私权政策属于本应用服务使用协议不可分割的一部分。';
  44 + }else {
  45 + this.title = '用户政策';
  46 + this.desc = '用户政策本应用尊重并保护所有使用服务用户的个人隐私权。为了给您提供更准确、更有个性化的服务,本应用会按照本隐私权政策的规定使用和披露您的个人信息。但本应用将以高度的勤勉、审慎义务对待这些信息。除本隐私权政策另有规定外,在未征得您事先许可的情况下,本应用不会将这些信息对外披露或向第三方提供。本应用会不时更新本隐私权政策。 您在同意本应用服务使用协议之时,即视为您已经同意本隐私权政策全部内容。本隐私权政策属于本应用服务使用协议不可分割的一部分。';
  47 + }
  48 + },
  49 + methods: {
  50 +
  51 + }
  52 + }
  53 +</script>
  54 +
  55 +<style lang="scss" scoped>
  56 + .app {
  57 + .content {
  58 + .title {
  59 + margin: 24px 16px 0;
  60 + font-size: 24px;
  61 + font-weight: 400;
  62 + color: #26292F;
  63 + }
  64 +
  65 + .paragraph1 {
  66 + margin: 24px 16px 0;
  67 + padding: 0 0 150rpx 0;
  68 + display: block;
  69 + overflow-wrap: break-word;
  70 + color: rgba(38, 41, 47, 1);
  71 + font-size: 14px;
  72 + line-height: 20px;
  73 + overflow: hidden;
  74 + text-overflow: ellipsis;
  75 + }
  76 +
  77 + }
  78 + }
  79 +</style>
... ...
  1 +<template>
  2 + <view class="edit-account">
  3 + <view class="account_name">
  4 + <view class="img_bg">
  5 + <u-image src="/static/img/my/LOGO@2x.png" width="200rpx" height="96rpx" />
  6 + </view>
  7 + <view class="name">
  8 + <text>账号名:</text>
  9 + <text>{{oldAccount}}</text>
  10 + </view>
  11 + <view class="describe">账号名是用户唯一凭证</view>
  12 + </view>
  13 + <view class="form input_warp">
  14 +
  15 + <u-form labelPosition="left" :model="form" :rules="rules" :errorType="errorType" ref="uForm">
  16 + <u-form-item label="新账号名" labelWidth="150rpx" prop="username" borderBottom>
  17 + <u-input v-model="form.username" @input="handleInput" border="none" :placeholderStyle="{color: 'C1C1C9'}" placeholder="请输入新的账号名">
  18 + </u-input>
  19 + </u-form-item>
  20 + </u-form>
  21 +
  22 + <view class="tips">*变更成功后需重新登录</view>
  23 + <view class="button_warp">
  24 + <c-button type="confirm" shape="circle" @click="submit" :disabled="disabled" text="确认修改"></c-button>
  25 + </view>
  26 + </view>
  27 +
  28 + </view>
  29 +</template>
  30 +
  31 +<script>
  32 + import {
  33 + mapState,
  34 + mapActions
  35 + } from 'vuex'
  36 +
  37 + import {
  38 + updateUserInfoApi,
  39 + } from '@/config/api.js';
  40 +
  41 + export default {
  42 + data() {
  43 +
  44 + return {
  45 + errorType: 'toast',
  46 + disabled: true,
  47 + form: {
  48 + username: '',
  49 +
  50 + },
  51 + rules: {
  52 + username: [{
  53 + required: true,
  54 + message: '请输入新账号',
  55 + trigger: ['blur', 'change'],
  56 + },
  57 + {
  58 + pattern: /^[a-zA-Z][a-zA-Z0-9_-]{5,19}$/g,
  59 + // 正则检验前先将值转为字符串
  60 + transform(value) {
  61 + return String(value);
  62 + },
  63 + message: '支持6-20个字母、数字、下划线或减号,以字母开头'
  64 + },
  65 + ],
  66 + }
  67 + }
  68 + },
  69 +
  70 + onLoad(option) {
  71 +
  72 + },
  73 +
  74 + onShow() {
  75 +
  76 + },
  77 +
  78 + // 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
  79 + onReady() {
  80 + this.$refs.uForm.setRules(this.rules);
  81 + },
  82 +
  83 + computed: {
  84 + ...mapState({
  85 +
  86 + oldAccount: (state) => state.vuex_user.username ? state.vuex_user.username : '',
  87 + }),
  88 + },
  89 +
  90 + methods: {
  91 +
  92 + handleInput(value) {
  93 + if (value) {
  94 + this.disabled = false;
  95 + } else {
  96 + this.disabled = true;
  97 + }
  98 + },
  99 +
  100 + submit() {
  101 + console.log(this.form)
  102 +
  103 + this.$refs.uForm.validate().then(res => {
  104 + // uni.$u.toast('校验通过');
  105 +
  106 + updateUserInfoApi({
  107 + ...this.form,
  108 + type: 'username',
  109 + }).then(async res => {
  110 + if (res) {
  111 + this.$u.toast('修改密码成功');
  112 + await this.$store.dispatch(`user/loginOut`);
  113 + }
  114 +
  115 + })
  116 +
  117 + }).catch(errors => {
  118 + console.log(errors)
  119 + })
  120 +
  121 + },
  122 + }
  123 + }
  124 +</script>
  125 +
  126 +<style lang="scss" scoped>
  127 + .edit-account /deep/ .u-input__input {
  128 + font-size: 34rpx;
  129 + }
  130 +
  131 + .edit-account {
  132 + padding: 0 28rpx;
  133 +
  134 + .account_name {
  135 + .img_bg {
  136 + width: 200rpx;
  137 + padding: 100rpx 0 0 0;
  138 + margin: 0 auto;
  139 + }
  140 +
  141 + .name {
  142 + text-align: center;
  143 + padding: 64rpx 0 0 0;
  144 +
  145 + text {
  146 + font-size: 28rpx;
  147 + line-height: 40rpx;
  148 + color: #909097;
  149 + }
  150 +
  151 + text:last-child {
  152 + font-size: 48rpx;
  153 + line-height: 68rpx;
  154 + color: #202131;
  155 + font-weight: 500;
  156 + }
  157 + }
  158 +
  159 + .describe {
  160 + text-align: center;
  161 + font-size: 28rpx;
  162 + line-height: 40rpx;
  163 + color: #909097;
  164 + padding: 0 0 170rpx;
  165 + }
  166 + }
  167 +
  168 + .form {
  169 + .tips {
  170 + font-size: 26rpx;
  171 + color: #909097;
  172 + margin: 12rpx 0 78rpx 0;
  173 + }
  174 + }
  175 + }
  176 +</style>
... ...
  1 +<template>
  2 + <view class="edit-mobile">
  3 + <view class="form input_warp">
  4 + <u-form labelPosition="left" :model="form" :rules="rules" :errorType="errorType" ref="uForm">
  5 + <u-form-item label="新手机号" labelWidth="150rpx" borderBottom prop="phone">
  6 + <u-input v-model="form.phone" @input="handleInput" border="none"
  7 + :placeholderStyle="{color: 'C1C1C9'}" placeholder="请输入手机号码" />
  8 + </u-form-item>
  9 + <u-form-item label="验证码" labelWidth="150rpx" borderBottom prop="code">
  10 + <u-input v-model="form.code" @input="handleInput" border="none"
  11 + :placeholderStyle="{color: 'C1C1C9'}" placeholder="请输入验证码" />
  12 + <u-button type="default" size="mini" slot="right" :hair-line="false"
  13 + :custom-style="{color:'#202131', border:'none',fontSize:'32rpx'}" @click="getCode">{{codeText}}
  14 + </u-button>
  15 + <u-code ref="uCode" @change="codeChange"></u-code>
  16 + </u-form-item>
  17 + </u-form>
  18 + <view class="tips">*变更成功后需重新登录</view>
  19 + <view class="button_warp">
  20 + <c-button type="confirm" shape="circle" @click="submit" :disabled="disabled" text="提交"></c-button>
  21 + </view>
  22 + </view>
  23 +
  24 + <view>
  25 + <u-toast ref="uToast" />
  26 + </view>
  27 + </view>
  28 +</template>
  29 +
  30 +<script>
  31 + import {
  32 + getSmsCodeApi,
  33 + updateUserInfoApi,
  34 + } from '@/config/api.js';
  35 +
  36 + export default {
  37 + data() {
  38 + return {
  39 + errorType: 'toast',
  40 + disabled: true,
  41 + codeText: '发送验证码',
  42 + form: {
  43 + phone: '',
  44 + code: '',
  45 +
  46 + },
  47 + rules: {
  48 + phone: [{
  49 + required: true,
  50 + message: '请输入手机号',
  51 + trigger: ['blur', 'change'],
  52 + },
  53 + {
  54 + validator: (rule, value, callback) => {
  55 + return this.$u.test.mobile(value);
  56 + },
  57 + message: '请输入正确的手机号'
  58 + },
  59 + ],
  60 + code: [{
  61 + required: true,
  62 + message: '请输入验证码',
  63 + trigger: ['blur', 'change'],
  64 + }, {
  65 + validator: (rule, value, callback) => {
  66 + return this.$u.test.code(value, '4');
  67 + },
  68 + message: '请输入正确的验证码'
  69 + }, ],
  70 + },
  71 + }
  72 + },
  73 +
  74 + onLoad(option) {
  75 +
  76 + },
  77 +
  78 + onShow() {
  79 +
  80 + },
  81 +
  82 + // 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
  83 + onReady() {
  84 + this.$refs.uForm.setRules(this.rules);
  85 + },
  86 +
  87 + methods: {
  88 +
  89 + handleInput(value) {
  90 + const {
  91 + phone = '', code = ''
  92 + } = this.form;
  93 +
  94 + if (phone && code) {
  95 + this.disabled = false;
  96 + } else {
  97 + this.disabled = true;
  98 + }
  99 + },
  100 +
  101 + codeChange(text) {
  102 + this.codeText = text;
  103 + },
  104 +
  105 + getCode() {
  106 + const {
  107 + phone = ''
  108 + } = this.form;
  109 +
  110 + if (!(phone && /^1[0-9]{10}$/.test(phone))) {
  111 + this.$refs.uToast.show({
  112 + title: '请填写正确手机号',
  113 + type: 'error',
  114 + duration: 1500,
  115 + })
  116 +
  117 + } else {
  118 + if (this.$refs.uCode.canGetCode) {
  119 + // 模拟向后端请求验证码
  120 + uni.showLoading({
  121 + title: '正在获取验证码'
  122 + })
  123 + setTimeout(() => {
  124 + uni.hideLoading();
  125 + // 通知验证码组件内部开始倒计时
  126 + this.$refs.uCode.start();
  127 +
  128 + getSmsCodeApi({
  129 + phone: phone
  130 + })
  131 +
  132 + }, 1000);
  133 + } else {
  134 + this.$u.toast('倒计时结束后再发送');
  135 + }
  136 + }
  137 + },
  138 +
  139 + submit() {
  140 +
  141 + this.$refs.uForm.validate().then(res => {
  142 + uni.$u.toast('校验通过');
  143 +
  144 + updateUserInfoApi({
  145 + ...this.form,
  146 + type: 'phone',
  147 + userType: 'teacher'
  148 + }).then(async res => {
  149 + if (res) {
  150 +
  151 + this.$u.toast('修改手机号码成功');
  152 + await this.$store.dispatch(`user/loginOut`);
  153 + }
  154 + })
  155 +
  156 + }).catch(errors => {
  157 + console.log(errors)
  158 + })
  159 + }
  160 + }
  161 + }
  162 +</script>
  163 +
  164 +<style lang="scss" scoped>
  165 + .edit-mobile /deep/ .u-input__input {
  166 + font-size: 34rpx;
  167 + }
  168 +
  169 + .edit-mobile {
  170 + padding: 0 28rpx;
  171 +
  172 + .form {
  173 + .tips {
  174 + font-size: 24rpx;
  175 + color: #FA6400;
  176 + margin: 36rpx 0 78rpx 0;
  177 + }
  178 + }
  179 + }
  180 +</style>
... ...
  1 +<template>
  2 + <view class="edit-password">
  3 + <view class="form input_warp">
  4 + <u-form labelPosition="left" :model="form" :rules="rules" :errorType="errorType" ref="uForm">
  5 +
  6 + <u-form-item label="密码" labelWidth="150rpx" borderBottom prop="newPwd">
  7 + <u-input v-model="form.newPwd" @input="handleInput" border="none" :placeholderStyle="{color: 'C1C1C9'}"
  8 + placeholder="请输入密码" />
  9 + </u-form-item>
  10 + <u-form-item label="再次确认" labelWidth="150rpx" borderBottom prop="secondPwd">
  11 + <u-input v-model="form.secondPwd" @input="handleInput" border="none" :placeholderStyle="{color: 'C1C1C9'}"
  12 + placeholder="再次确认" />
  13 + </u-form-item>
  14 +
  15 + </u-form>
  16 + <view class="tips">*变更成功后需重新登录</view>
  17 + <view class="button_warp">
  18 + <c-button type="confirm" shape="circle" @click="getCode" :disabled="disabled" text="提交"></c-button>
  19 + </view>
  20 + </view>
  21 +
  22 + <u-overlay :show="showModal">
  23 + <view class="modal" v-show="showModal">
  24 + <image src="/static/img/my/delete.png" class="close" @click="closeModal"></image>
  25 + <view class="text0" style="margin-top:64rpx">请输入验证码</view>
  26 + <view class="text1" style="margin: 32rpx;">已发送至手机号:{{getPhone}}</view>
  27 + <view style="margin: 32rpx auto;width:'200rpx'">
  28 + <u-code-input :maxlength="4" v-model="currentCode" size="48" :focus="false" :dot="true" :width="76"
  29 + @change="change" @finish="goNext"></u-code-input>
  30 + </view>
  31 + <view style="margin-top: 32rpx;">
  32 + <u-code ref="uCode" @change="codeChange">
  33 + </u-code>
  34 + <view class="text2" @click="getCode">{{tips}}</view>
  35 + </view>
  36 + </view>
  37 + </u-overlay>
  38 +
  39 + </view>
  40 +</template>
  41 +
  42 +<script>
  43 + import {
  44 + replaceTextToStar
  45 + } from '@/common/commonUtil.js'
  46 +
  47 + import {
  48 + mapState,
  49 + mapActions
  50 + } from 'vuex'
  51 +
  52 + import {
  53 + getSmsCodeApi,
  54 + updateUserInfoApi,
  55 + } from '@/config/api.js';
  56 +
  57 + import md5 from '@/common/md5';
  58 +
  59 + export default {
  60 + data() {
  61 +
  62 + return {
  63 + errorType: 'toast',
  64 + disabled: true,
  65 + form: {
  66 + newPwd: '',
  67 + secondPwd: '',
  68 +
  69 + },
  70 + rules: {
  71 + newPwd: [{
  72 + required: true,
  73 + message: '请输入密码',
  74 + trigger: ['blur', 'change'],
  75 + },
  76 + {
  77 + min: 6,
  78 + max: 20,
  79 + message: '长度在6-20个字符之间'
  80 + },
  81 + {
  82 + pattern: /^[a-zA-Z0-9_]*$/g,
  83 + transform(value) {
  84 + return String(value);
  85 + },
  86 + message: '只能包含字母或数字或下划线'
  87 + },
  88 + ],
  89 + secondPwd: [{
  90 + required: true,
  91 + message: '请输入密码',
  92 + trigger: ['blur', 'change'],
  93 + },
  94 + {
  95 + min: 6,
  96 + max: 20,
  97 + message: '长度在6-20个字符之间'
  98 + },
  99 + {
  100 + pattern: /^[a-zA-Z0-9_]*$/g,
  101 + transform(value) {
  102 + return String(value);
  103 + },
  104 + message: '只能包含字母或数字或下划线'
  105 + },
  106 + ],
  107 + },
  108 + showModal: false,
  109 + tips: '',
  110 + currentCode: ""
  111 + }
  112 + },
  113 +
  114 + onLoad(option) {
  115 + let title = this.vuex_user.password ? '修改密码' : '设置密码'
  116 + uni.setNavigationBarTitle({
  117 + title: title
  118 + })
  119 + },
  120 +
  121 + onShow() {
  122 +
  123 + },
  124 +
  125 + // 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
  126 + onReady() {
  127 + this.$refs.uForm.setRules(this.rules);
  128 + },
  129 +
  130 + computed: {
  131 + ...mapState({
  132 + phone: (state) => state.vuex_user.phone,
  133 + getPhone(state) {
  134 + let phone = state.vuex_user.phone;
  135 + return replaceTextToStar(phone);
  136 + },
  137 + }),
  138 + },
  139 +
  140 + methods: {
  141 +
  142 + handleInput(value) {
  143 + const {
  144 + newPwd = '', secondPwd = ''
  145 + } = this.form;
  146 +
  147 + if (newPwd && secondPwd) {
  148 + this.disabled = false;
  149 + } else {
  150 + this.disabled = true;
  151 + }
  152 + },
  153 +
  154 + getCode() { //获取验证码
  155 +
  156 + const {
  157 + newPwd = '', secondPwd = ''
  158 + } = this.form;
  159 +
  160 + if (newPwd != secondPwd) {
  161 + this.$u.toast('两次输入密码不一致');
  162 + return;
  163 + }
  164 +
  165 + this.$refs.uForm.validate().then(res => {
  166 + uni.$u.toast('校验通过');
  167 +
  168 + this.showModal = true;
  169 + if (this.$refs.uCode.canGetCode) {
  170 + // 模拟向后端请求验证码
  171 + uni.showLoading({
  172 + title: '正在获取验证码'
  173 + })
  174 +
  175 + getSmsCodeApi({
  176 + phone: this.phone
  177 + }).then(data => {
  178 + console.log(data)
  179 +
  180 + uni.hideLoading();
  181 + // 这里此提示会被this.start()方法中的提示覆盖
  182 + this.$u.toast('验证码已发送');
  183 + // 通知验证码组件内部开始倒计时
  184 + this.$refs.uCode.start();
  185 +
  186 + })
  187 + } else {
  188 + this.$u.toast('倒计时结束后再发送');
  189 + }
  190 +
  191 + }).catch(errors => {
  192 + console.log(errors)
  193 + })
  194 + },
  195 +
  196 + closeModal() {
  197 + if (this.showModal) {
  198 + this.showModal = false;
  199 + this.$refs.uCode.reset();
  200 + this.currentCode = "";
  201 + }
  202 + },
  203 +
  204 + change(e) {
  205 + this.currentCode = e;
  206 + },
  207 +
  208 + codeChange(text) {
  209 + this.tips = text;
  210 + },
  211 +
  212 + goNext(e) {
  213 + console.log('输入结束,当前值为:' + e);
  214 +
  215 + updateUserInfoApi({
  216 + // ...this.form,
  217 + newPwd: md5.hex_md5(this.form.newPwd),
  218 + secondPwd: md5.hex_md5(this.form.secondPwd),
  219 + phone: this.phone,
  220 + type: 'password',
  221 + code: e,
  222 + }).then(async res => {
  223 + if (res) {
  224 + this.$u.toast('修改密码成功');
  225 + await this.$store.dispatch(`user/loginOut`);
  226 + }
  227 + })
  228 + },
  229 +
  230 + }
  231 + }
  232 +</script>
  233 +
  234 +<style lang="scss" scoped>
  235 + .edit-password /deep/ .u-input__input {
  236 + font-size: 34rpx;
  237 + }
  238 +
  239 + .edit-password {
  240 + padding: 0 28rpx;
  241 +
  242 + .form {
  243 + .tips {
  244 + font-size: 24rpx;
  245 + color: #FA6400;
  246 + margin: 36rpx 0 78rpx 0;
  247 + }
  248 + }
  249 +
  250 + .modal {
  251 + width: 88%;
  252 + position: relative;
  253 + display: flex;
  254 + flex-direction: column;
  255 + margin: 200rpx auto;
  256 + padding-bottom: 64rpx;
  257 + border-radius: 12rpx;
  258 + background-color: #fff;
  259 +
  260 + .close {
  261 + width: 48rpx;
  262 + height: 48rpx;
  263 + padding: 12rpx;
  264 + position: fixed;
  265 + right: 40rpx;
  266 + }
  267 +
  268 + .text0 {
  269 + font-size: 34rpx;
  270 + font-family: PingFangSC-Medium, PingFang SC;
  271 + font-weight: 500;
  272 + color: #000000;
  273 + text-align: center;
  274 + }
  275 +
  276 + .text1 {
  277 + font-size: 34rpx;
  278 + font-family: PingFangSC-Regular, PingFang SC;
  279 + font-weight: 400;
  280 + color: rgba(0, 0, 0, 0.45);
  281 + text-align: center;
  282 + }
  283 +
  284 + .text2 {
  285 + font-size: 30rpx;
  286 + font-family: PingFangSC-Regular, PingFang SC;
  287 + font-weight: 400;
  288 + color: rgba(0, 0, 0, 0.5);
  289 + line-height: 48rpx;
  290 + text-align: center;
  291 + }
  292 + }
  293 + }
  294 +</style>
... ...
  1 +<template>
  2 + <view class="freezing">
  3 + <view class="box">
  4 + <view class="icon">
  5 + <icon type="waiting" size="53"></icon>
  6 + </view>
  7 + <view class="text">
  8 + <view class="title">冻结中</view>
  9 + <view class="describe">您已经提交账号注销申请,此账号已被冻结, 工作人员会在15个工作日内处理您的请求</view>
  10 + </view>
  11 + </view>
  12 +
  13 + <view class="btn fixed_bottom_btn">
  14 + <view class="left_btn">
  15 + <c-button type="cancel" text="撤销注销" @click="giveUp">
  16 + </c-button>
  17 + </view>
  18 + <view class="right_btn">
  19 + <c-button type="confirm" text="联系客服" @click="contactCustomer">
  20 + </c-button>
  21 + </view>
  22 + </view>
  23 +
  24 + </view>
  25 +</template>
  26 +
  27 +<script>
  28 + import {
  29 + mapState,
  30 + mapActions
  31 + } from 'vuex'
  32 +
  33 + import {
  34 + cancelDelAccountApi,
  35 + } from '@/config/api.js';
  36 +
  37 + export default {
  38 + data() {
  39 + return {
  40 +
  41 + }
  42 + },
  43 +
  44 + onLoad(option) {
  45 +
  46 + },
  47 +
  48 + computed: {
  49 + ...mapState({
  50 + // vuex_phone: (state) => state.vuex_phone,
  51 + }),
  52 + },
  53 +
  54 + methods: {
  55 + giveUp() {
  56 + cancelDelAccountApi({
  57 + phone: this.vuex_phone,
  58 + }).then(async data => {
  59 + console.log(data)
  60 + uni.showToast({
  61 + title: '撤销成功'
  62 + });
  63 +
  64 + this.$u.route('/pages/main/my/login/login');
  65 + })
  66 + },
  67 +
  68 + contactCustomer() {
  69 + uni.makePhoneCall({
  70 + phoneNumber: "150-7142-1900"
  71 + })
  72 + },
  73 + }
  74 + }
  75 +</script>
  76 +
  77 +<style lang="scss" scoped>
  78 + .freezing {
  79 + width: 100%;
  80 + height: 100%;
  81 + position: relative;
  82 +
  83 + .box {
  84 + .icon {
  85 + padding: 308rpx 0 0 0;
  86 + text-align: center;
  87 + }
  88 +
  89 + .text {
  90 + text-align: center;
  91 +
  92 + .title {
  93 + font-size: 34rpx;
  94 + color: #000000;
  95 + line-height: 48rpx;
  96 + margin: 44rpx 0 32rpx 0;
  97 + }
  98 +
  99 + .describe {
  100 + width: 560rpx;
  101 + margin: 0 auto;
  102 + font-size: 28rpx;
  103 + color: rgba(0, 0, 0, 0.5);
  104 + line-height: 40rpx;
  105 + }
  106 + }
  107 + }
  108 +
  109 + .fixed_bottom_btn {
  110 + width: 100%;
  111 + height: 144rpx;
  112 + padding: 24rpx 32rpx;
  113 + background: #FFFFFF;
  114 + position: fixed;
  115 + bottom: 0;
  116 + left: 0;
  117 + z-index: 99;
  118 + border-top: 1rpx solid #F0F0F1;
  119 +
  120 + view {
  121 + display: inline-block;
  122 + }
  123 +
  124 + .left_btn {
  125 + width: 212rpx;
  126 + margin: 0 40rpx 0 0;
  127 + }
  128 +
  129 + .right_btn {
  130 + width: 434rpx;
  131 + }
  132 + }
  133 + }
  134 +</style>
... ...
... ... @@ -9,10 +9,8 @@
9 9 </view>
10 10
11 11 <view class="btn button_warp">
12   - <c-button type="confirm" shape="circle"
13   - :customStyle="{borderRadius:'48rpx',fontSize:'34rpx',color:'#fff',fontWeight:'400'}" text="微信一键登录"
14   - :disabled="isDisable" openType="getPhoneNumber" @getPhoneNumber="getPhoneNumber"
15   - @click="getUserProfile"></c-button>
  12 + <c-button type="confirm" text="微信一键登录" :disabled="isDisable" openType="getPhoneNumber"
  13 + @getPhoneNumber="getPhoneNumber" @click="getUserProfile"></c-button>
16 14 </view>
17 15
18 16 <view class="changeLogin" @click="handelMobileLogin">
... ... @@ -45,7 +43,7 @@
45 43
46 44 export default {
47 45 data() {
48   - return {
  46 + return {
49 47 isDisable: true,
50 48 checked: [],
51 49 service: "https://yxlypublic.oss-cn-beijing.aliyuncs.com/WeChat/agreement/%E3%80%8A%E4%BC%98%E5%AD%A6%E4%B9%90%E4%B8%9A%E7%94%A8%E6%88%B7%E6%9C%8D%E5%8A%A1%E5%8D%8F%E8%AE%AE%E3%80%8B.htm",
... ... @@ -66,13 +64,13 @@
66 64
67 65 onShow() {
68 66
69   - },
70   -
71   - watch: {
72   - checked: function(newVal, oldVal) {
73   - this.isDisable = newVal.length != 0 ? false : true;
74   -
75   - }
  67 + },
  68 +
  69 + watch: {
  70 + checked: function(newVal, oldVal) {
  71 + this.isDisable = newVal.length != 0 ? false : true;
  72 +
  73 + }
76 74 },
77 75
78 76 computed: {
... ... @@ -98,7 +96,7 @@
98 96 })
99 97 },
100 98
101   - checkboxChange(n) {
  99 + checkboxChange(n) {
102 100 console.log(n)
103 101
104 102 },
... ... @@ -123,11 +121,9 @@
123 121 success: (res) => {
124 122 console.log(res);
125 123
126   - // this.getUserProfile();
127   -
128 124 this.$store.dispatch(`user/login`, {
129 125 way: 'wechat_code',
130   - type: 'student',
  126 + type: 'teacher',
131 127 jsCode: res.code,
132 128 code: e.detail.code,
133 129 })
... ... @@ -135,15 +131,6 @@
135 131 })
136 132 },
137 133
138   - phoneLogin() {
139   - this.$store.dispatch(`user/login`, {
140   - way: 'name',
141   - type: 'student',
142   - username: this.form.mobile,
143   - password: this.form.password,
144   - })
145   - },
146   -
147 134 handelMobileLogin() {
148 135 this.$u.route({
149 136 url: "/pages/main/my/mobileLogin/mobileLogin",
... ... @@ -179,8 +166,9 @@
179 166 text-align: center;
180 167 margin: 48rpx 0 0 0;
181 168 font-size: 15px;
182   - font-weight: 400;
183   - color: rgba(0, 0, 0, 0.65);
  169 + font-weight: 400;
  170 + color: #06B079;
  171 +
184 172 }
185 173
186 174 .agreement {
... ...
... ... @@ -82,7 +82,7 @@
82 82 export default {
83 83 data() {
84 84 return {
85   - errorType: ['toast'],
  85 + errorType: 'toast',
86 86 isDisable: true,
87 87 checked: [],
88 88 service: "https://yxlypublic.oss-cn-beijing.aliyuncs.com/WeChat/agreement/%E3%80%8A%E4%BC%98%E5%AD%A6%E4%B9%90%E4%B8%9A%E7%94%A8%E6%88%B7%E6%9C%8D%E5%8A%A1%E5%8D%8F%E8%AE%AE%E3%80%8B.htm",
... ... @@ -204,11 +204,10 @@
204 204 },
205 205
206 206 phoneLogin() {
207   - // this.getUserProfile();
208 207 if (this.changeLogin == '账号密码登录') {
209 208 this.$store.dispatch(`user/login`, {
210 209 way: 'code',
211   - type: 'student',
  210 + type: 'teacher',
212 211 phone: this.form.mobile,
213 212 code: this.form.password,
214 213 })
... ... @@ -216,7 +215,7 @@
216 215 console.log(md5.hex_md5(this.form.password));
217 216 this.$store.dispatch(`user/login`, {
218 217 way: 'name',
219   - type: 'student',
  218 + type: 'teacher',
220 219 username: this.form.mobile,
221 220 password: md5.hex_md5(this.form.password),
222 221 })
... ...
  1 +<template>
  2 + <view class="account_safe">
  3 +
  4 + <view class="avatar">
  5 + <u-image @click="show = true" width="190rpx" height="190rpx" shape="circle"
  6 + :src="avatarUrl? `${vuex_ossUrlPubilc}/${avatarUrl}`:wxAvatarUrl" />
  7 + </view>
  8 +
  9 + <view class="cell top">
  10 + <u-cell-group>
  11 + <u-cell title="登录账号" :isLink="true" url="/pages/main/my/editAccount/editAccount" arrow-direction="right"
  12 + :rightIconStyle="{fontSize:'26rpx'}" :title-style="{color:'#909097', fontSize:'28rpx'}">
  13 + <text slot="value" class="u-slot-value">{{accountName}}</text>
  14 + </u-cell>
  15 + <u-cell title="姓名" arrow-direction="right" :rightIconStyle="{fontSize:'26rpx'}"
  16 + :title-style="{color:'#909097', fontSize:'28rpx'}">
  17 + <text slot="value" class="u-slot-value">{{teacherName}}</text>
  18 + </u-cell>
  19 + <u-cell title="手机号" :isLink="true" url="/pages/main/my/editMobile/editMobile" arrow-direction="right"
  20 + :rightIconStyle="{fontSize:'26rpx'}" :title-style="{color:'#909097', fontSize:'28rpx'}">
  21 + <text slot="value" class="u-slot-value">{{getPhone}}</text>
  22 + </u-cell>
  23 + <u-cell title="工号" arrow-direction="right" :rightIconStyle="{fontSize:'26rpx'}"
  24 + :title-style="{color:'#909097', fontSize:'28rpx'}">
  25 + <text slot="value" class="u-slot-value">{{jobNumber}}</text>
  26 + </u-cell>
  27 + <u-cell title="院系专业" arrow-direction="right" :rightIconStyle="{fontSize:'26rpx'}"
  28 + :title-style="{color:'#909097', fontSize:'28rpx'}">
  29 + <text slot="value" class="u-slot-value">{{departmentName}}</text>
  30 + </u-cell>
  31 + </u-cell-group>
  32 + </view>
  33 +
  34 + <u-action-sheet :actions="list" @select="chooseImg" :show="show"></u-action-sheet>
  35 + </view>
  36 +</template>
  37 +
  38 +<script>
  39 + import {
  40 + mapState,
  41 + mapActions
  42 + } from 'vuex'
  43 +
  44 + import {
  45 + getOssInitApi,
  46 + updateAvatarUrlApi,
  47 + } from '@/config/api.js';
  48 +
  49 + import {
  50 + replaceTextToStar
  51 + } from '@/common/commonUtil.js'
  52 +
  53 + export default {
  54 + data() {
  55 + return {
  56 + show: false,
  57 + list: [{
  58 + name: '拍照'
  59 + }, {
  60 + name: '从手机相册选择'
  61 + }],
  62 + ossInit: {},
  63 + picList: [],
  64 + }
  65 + },
  66 +
  67 + onLoad() {
  68 + getOssInitApi({
  69 + "uploadFileType": "other"
  70 + }).then(res => {
  71 + this.ossInit = res
  72 + })
  73 + },
  74 +
  75 +
  76 +
  77 + computed: {
  78 + ...mapState({
  79 + wxAvatarUrl: (state) => state.vuex_weixinUserInfo.avatarUrl ? state.vuex_weixinUserInfo.avatarUrl : '',
  80 + avatarUrl: (state) => state.vuex_user.teacher.avatarUrl ? state.vuex_user.teacher.avatarUrl : '',
  81 + accountName: (state) => state.vuex_user.username ? state.vuex_user.username : '',
  82 + teacherName: (state) => state.vuex_user.teacher.name ? state.vuex_user.teacher.name : '',
  83 + jobNumber: (state) => state.vuex_user.teacher.number ? state.vuex_user.teacher.number : '',
  84 + departmentName: (state) => state.vuex_user.teacher.departments && state.vuex_user.teacher.departments
  85 + .length > 0 && state.vuex_user.teacher.departments[0].name ? state.vuex_user.teacher
  86 + .departments[0].name : '',
  87 +
  88 + getPhone(state) {
  89 + let phone = state.vuex_user.phone;
  90 + return phone ? replaceTextToStar(phone) : '';
  91 + },
  92 +
  93 + }),
  94 + },
  95 +
  96 + methods: {
  97 +
  98 + ...mapActions('user', {
  99 + getUserInfo: 'getUserInfo',
  100 + }),
  101 +
  102 + chooseImg(item) {
  103 + var _this = this
  104 + console.log(item)
  105 + if (item.name == '拍照') { //拍照
  106 + uni.chooseImage({
  107 + count: 1,
  108 + sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
  109 + sourceType: ['camera'], //从相机选择
  110 + success: function(res) {
  111 + console.log("chooseImage...", JSON.stringify(res.tempFilePaths));
  112 + _this.picList = res.tempFilePaths
  113 + _this.uploadImages()
  114 + }
  115 + });
  116 + } else if (item.name == '从手机相册选择') { //相册
  117 + uni.chooseImage({
  118 + count: 1,
  119 + sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
  120 + sourceType: ['album'], //从相册选择
  121 + success: function(res) {
  122 + console.log("chooseImage...", JSON.stringify(res.tempFilePaths));
  123 + _this.picList = res.tempFilePaths
  124 + _this.uploadImages()
  125 + }
  126 + });
  127 + }
  128 + },
  129 +
  130 + uploadImages() { //上传图片
  131 + var _this = this
  132 + console.log('begin', this.picList)
  133 + for (var i = 0; i < this.picList.length; i++) {
  134 + uni.uploadFile({
  135 + url: _this.ossInit.host,
  136 + filePath: _this.picList[i],
  137 + name: 'file',
  138 + formData: {
  139 + 'key': `${_this.ossInit.dir}${new Date().getTime()}/` + '${filename}',
  140 + 'action': `${_this.ossInit.host}`,
  141 + 'OSSAccessKeyId': _this.ossInit.accessId,
  142 + 'policy': _this.ossInit.policy,
  143 + 'signature': _this.ossInit.signature,
  144 + 'callback': _this.ossInit.callback,
  145 + },
  146 + success: (uploadFileRes) => {
  147 + console.log("--", uploadFileRes)
  148 +
  149 + let avatarObj = JSON.parse(uploadFileRes.data)
  150 + _this.avatarUrl = avatarObj.object;
  151 +
  152 + updateAvatarUrlApi({
  153 + id: this.vuex_user.teacher.id,
  154 + avatarUrl: avatarObj.object,
  155 + }).then(data => {
  156 + if (data) {
  157 + _this.getUserInfo()
  158 + }
  159 + })
  160 +
  161 + },
  162 + fail: (error) => {
  163 + console.log("-error-", error)
  164 + },
  165 +
  166 + complete: (res) => {
  167 + this.show = false;
  168 + }
  169 +
  170 + });
  171 + }
  172 + },
  173 +
  174 + link(type) {
  175 +
  176 + switch (type) {
  177 + case 'account':
  178 + this.$u.route('/pages/student/my/edit-account/edit-account');
  179 + break;
  180 +
  181 + case 'password':
  182 + this.$u.route('/pages/student/my/edit-password/edit-password');
  183 + break;
  184 + }
  185 +
  186 + },
  187 + }
  188 + }
  189 +</script>
  190 +
  191 +<style lang="scss" scoped>
  192 + .account_safe {
  193 + width: 100%;
  194 + height: 100%;
  195 + background-color: #F7F7F7;
  196 + padding: 20rpx 0 0 0;
  197 +
  198 + .avatar {
  199 + width: 190rpx;
  200 + margin: 0 auto;
  201 + padding: 50rpx 0;
  202 + }
  203 +
  204 + .top {
  205 + margin: 0 0 20rpx 0;
  206 + }
  207 +
  208 + .cell {
  209 + background-color: #FFFFFF;
  210 +
  211 + .u-slot-value {
  212 + font-size: 28rpx;
  213 + line-height: 40rpx;
  214 + color: #202131;
  215 + }
  216 + }
  217 +
  218 + .cell /deep/ .u-cell {
  219 + padding: 12rpx 0;
  220 +
  221 + .u-cell__value {
  222 + font-size: 34rpx;
  223 + color: rgba(0, 0, 0, 0.5);
  224 + }
  225 + }
  226 + }
  227 +</style>
... ...
  1 +<template>
  2 + <view class="account_safe">
  3 + <view class="cell top">
  4 + <u-cell-group>
  5 + <u-cell title="用户政策" :isLink="true" url="/pages/main/my/userPolicy/userPolicy" arrow-direction="right"
  6 + :rightIconStyle="{fontSize:'26rpx'}" :title-style="{color:'#909097', fontSize:'28rpx'}">
  7 + </u-cell>
  8 + <u-cell title="隐私协议" :isLink="true" url="/pages/main/my/agreement/agreement"
  9 + arrow-direction="right" :rightIconStyle="{fontSize:'26rpx'}"
  10 + :title-style="{color:'#909097', fontSize:'28rpx'}">
  11 + </u-cell>
  12 + </u-cell-group>
  13 + </view>
  14 +
  15 + </view>
  16 +</template>
  17 +
  18 +<script>
  19 + import {
  20 + mapState,
  21 + mapActions
  22 + } from 'vuex'
  23 + import {
  24 + replaceTextToStar
  25 + } from '@/common/commonUtil.js'
  26 +
  27 + export default {
  28 + data() {
  29 + return {
  30 +
  31 + }
  32 + },
  33 +
  34 + computed: {
  35 + ...mapState({
  36 + accountName: (state) => state.vuex_user.username ? state.vuex_user.username : '',
  37 +
  38 + getPhone(state) {
  39 + let phone = state.vuex_user.phone;
  40 + return phone ? replaceTextToStar(phone) : '';
  41 + },
  42 +
  43 + }),
  44 + },
  45 +
  46 + methods: {
  47 + link(type) {
  48 +
  49 + switch (type) {
  50 + case 'account':
  51 + this.$u.route('/pages/student/my/edit-account/edit-account');
  52 + break;
  53 +
  54 + case 'password':
  55 + this.$u.route('/pages/student/my/edit-password/edit-password');
  56 + break;
  57 + }
  58 +
  59 + },
  60 + }
  61 + }
  62 +</script>
  63 +
  64 +<style lang="scss" scoped>
  65 + .account_safe {
  66 + width: 100%;
  67 + height: 100%;
  68 + background-color: #F7F7F7;
  69 + padding: 20rpx 0 0 0;
  70 +
  71 + .top {
  72 + margin: 0 0 20rpx 0;
  73 + }
  74 +
  75 + .cell {
  76 + background-color: #FFFFFF;
  77 +
  78 + .u-slot-value {
  79 + font-size: 28rpx;
  80 + line-height: 40rpx;
  81 + color: #202131;
  82 + }
  83 + }
  84 +
  85 + .cell /deep/ .u-cell {
  86 + padding: 12rpx 0;
  87 +
  88 + .u-cell__value {
  89 + font-size: 34rpx;
  90 + color: rgba(0, 0, 0, 0.5);
  91 + }
  92 + }
  93 + }
  94 +</style>
... ...
  1 +<template>
  2 + <view class="remove_account">
  3 + <view class="title">注销账户</view>
  4 + <view class="sub_title" style="margin-top: 20rpx;">账号主体:{{getPhone}}</view>
  5 + <view class="content">
  6 + <text class="text">
  7 + 如您注销优学乐业服务,则当前服务在APP
  8 + 小程序、等留存的信息均将被清空且无法被
  9 + 找回。具体包括一下信息:
  10 +
  11 + · 优学乐业学生注册账号及状态信息
  12 +
  13 + · 优学乐业保存的学生个人信息
  14 +
  15 + · 优学乐业保存的学生学籍信息
  16 +
  17 + · 学生所有实习及相关活动记录
  18 +
  19 + · 学生实习成绩信息
  20 +
  21 + · 订阅消息、短信等通知不再进行推送
  22 + </text>
  23 + </view>
  24 + <view class="footer">
  25 + <view class="left_btn">
  26 + <c-button type="confirm" shape="circle" @click="removeAccount" :disabled="false" text="注销申请"></c-button>
  27 + </view>
  28 + </view>
  29 + </view>
  30 +</template>
  31 +
  32 +<script>
  33 + import {
  34 + replaceTextToStar
  35 + } from '@/common/commonUtil.js'
  36 + import {
  37 + mapState,
  38 + mapActions
  39 + } from 'vuex'
  40 +
  41 + export default {
  42 + data() {
  43 + return {
  44 +
  45 + }
  46 + },
  47 +
  48 + computed: {
  49 + ...mapState({
  50 + getPhone(state) {
  51 + let phone = state.vuex_user.phone;
  52 + return replaceTextToStar(phone);
  53 + },
  54 + }),
  55 + },
  56 +
  57 + methods: {
  58 + removeAccount() {
  59 + this.$u.route('/pages/main/my/againRemove/againRemove');
  60 + }
  61 + }
  62 + }
  63 +</script>
  64 +
  65 +<style lang="scss" scoped>
  66 + .remove_account {
  67 + background-color: #FFFFFF;
  68 + }
  69 +
  70 + .title {
  71 + font-size: 44rpx;
  72 + font-family: PingFangSC-Medium, PingFang SC;
  73 + font-weight: 500;
  74 + color: #000000;
  75 + margin-top: 48rpx;
  76 + text-align: center;
  77 + }
  78 +
  79 + .sub_title {
  80 + font-size: 17px;
  81 + font-family: PingFangSC-Regular, PingFang SC;
  82 + font-weight: 400;
  83 + color: rgba(0, 0, 0, 0.65);
  84 + line-height: 24px;
  85 + text-align: center;
  86 + }
  87 +
  88 + .content {
  89 + width: 594rpx;
  90 + background: rgba(0, 0, 0, 0.03);
  91 + padding: 48rpx;
  92 + margin: 48rpx auto;
  93 +
  94 + .text {
  95 + font-size: 30rpx;
  96 + font-family: PingFangSC-Regular, PingFang SC;
  97 + font-weight: 400;
  98 + color: rgba(0, 0, 0, 0.65);
  99 + line-height: 42rpx;
  100 + }
  101 + }
  102 +
  103 + .footer {
  104 + width: 100%;
  105 + height: 96rpx;
  106 + padding: 28rpx 30rpx;
  107 + background: #FFFFFF;
  108 + position: fixed;
  109 + bottom: 0;
  110 + left: 0;
  111 + z-index: 99;
  112 + border-top: 2rpx solid #E2E2E8;
  113 +
  114 + view {
  115 + display: inline-block;
  116 + }
  117 +
  118 + .left_btn {
  119 + width: 690rpx;
  120 + margin: 0 30rpx 0 0;
  121 + }
  122 + }
  123 +</style>
... ...
  1 +<template>
  2 + <view class="app">
  3 + <view class="content">
  4 + <view class="title">{{title}}</view>
  5 + <!-- <view class="desc">{{desc}}</view> -->
  6 + <text class="paragraph1">
  7 + 用户政策
  8 + \n
  9 + 本应用尊重并保护所有使用服务用户的个人隐私权。为了给您提供更准确、更有个性化的服务,本应用会按照本隐私权政策的规定使用和披露您的个人信息。但本应用将以高度的勤勉、审慎义务对待这些信息。除本隐私权政策另有规定外,在未征得您事先许可的情况下,本应用不会将这些信息对外披露或向第三方提供。本应用会不时更新本隐私权政策。&nbsp;您在同意本应用服务使用协议之时,即视为您已经同意本隐私权政策全部内容。本隐私权政策属于本应用服务使用协议不可分割的一部分。
  10 + \n
  11 + 1.&nbsp;适用范围
  12 + \n
  13 + a)&nbsp;在您注册本应用帐号时,您根据本应用要求提供的个人注册信息;
  14 + \n
  15 + b)&nbsp;在您使用本应用网络服务,或访问本应用平台网页时,本应用自动接收并记录的您的浏览器和计算机上的信息,包括但不限于您的IP地址、浏览器的类型、使用的语言、访问日期和时间、软硬件特征信息及您需求的网页记录等数据;
  16 + \n
  17 + c)&nbsp;本应用通过合法途径从商业伙伴处取得的用户个人数据。
  18 + \n
  19 + 您了解并同意,以下信息不适用本隐私权政策:
  20 + \n
  21 + a)&nbsp;您在使用本应用平台提供的搜索服务时输入的关键字信息;
  22 + \n
  23 + b)&nbsp;本应用收集到的您在本应用发布的有关信息数据,包括但不限于参与活动、成交信息及评价详情;
  24 + \n
  25 + c)&nbsp;违反法律规定或违反本应用规则行为及本应用已对您采取的措施。
  26 + </text>
  27 + </view>
  28 + </view>
  29 +</template>
  30 +
  31 +<script>
  32 + export default {
  33 + data() {
  34 + return {
  35 + title: '',
  36 + desc: ''
  37 + }
  38 + },
  39 + onReady() {
  40 + this.title = '用户政策';
  41 + this.desc = '隐私政策本应用尊重并保护所有使用服务用户的个人隐私权。为了给您提供更准确、更有个性化的服务,本应用会按照本隐私权政策的规定使用和披露您的个人信息。但本应用将以高度的勤勉、审慎义务对待这些信息。除本隐私权政策另有规定外,在未征得您事先许可的情况下,本应用不会将这些信息对外披露或向第三方提供。本应用会不时更新本隐私权政策。 您在同意本应用服务使用协议之时,即视为您已经同意本隐私权政策全部内容。本隐私权政策属于本应用服务使用协议不可分割的一部分。';
  42 + },
  43 + methods: {
  44 +
  45 + }
  46 + }
  47 +</script>
  48 +
  49 +<style lang="scss" scoped>
  50 + .app {
  51 + .content {
  52 + .title {
  53 + margin: 24px 16px 0;
  54 + font-size: 24px;
  55 + font-weight: 400;
  56 + color: #26292F;
  57 + }
  58 +
  59 + .paragraph1 {
  60 + margin: 24px 16px 0;
  61 + padding: 0 0 150rpx 0;
  62 + display: block;
  63 + overflow-wrap: break-word;
  64 + color: rgba(38, 41, 47, 1);
  65 + font-size: 14px;
  66 + line-height: 20px;
  67 + overflow: hidden;
  68 + text-overflow: ellipsis;
  69 + }
  70 +
  71 + }
  72 + }
  73 +</style>
... ...
  1 +<template>
  2 + <view class="edit-account">
  3 + <view class="account_name">
  4 + <view class="img_bg">
  5 + <u-image src="/static/img/my/LOGO@2x.png" width="200rpx" height="96rpx" />
  6 + </view>
  7 + <view class="describe">版本号v1.3.3</view>
  8 + </view>
  9 +
  10 +
  11 + </view>
  12 +</template>
  13 +
  14 +<script>
  15 +
  16 +
  17 + export default {
  18 + data() {
  19 +
  20 + return {
  21 +
  22 + }
  23 + },
  24 +
  25 + onLoad(option) {
  26 +
  27 + },
  28 +
  29 + onShow() {
  30 +
  31 + },
  32 +
  33 +
  34 +
  35 +
  36 + methods: {
  37 +
  38 +
  39 + }
  40 + }
  41 +</script>
  42 +
  43 +<style lang="scss" scoped>
  44 + .edit-account /deep/ .u-input__input {
  45 + font-size: 34rpx;
  46 + }
  47 +
  48 + .edit-account {
  49 + padding: 0 28rpx;
  50 +
  51 + .account_name {
  52 + .img_bg {
  53 + width: 200rpx;
  54 + padding: 100rpx 0 0 0;
  55 + margin: 0 auto;
  56 + }
  57 +
  58 + .describe {
  59 + text-align: center;
  60 + font-size: 24rpx;
  61 + line-height: 48rpx;
  62 + color: #202131;
  63 + padding: 40rpx 0 0 0;
  64 + }
  65 + }
  66 + }
  67 +</style>
... ...
  1 +<template>
  2 + <view class="written-off">
  3 + <view class="box">
  4 + <view class="icon">
  5 + <icon type="warn" size="53"></icon>
  6 + </view>
  7 + <view class="text">
  8 + <view class="title">已注销</view>
  9 + <view class="describe">您的账号已注销,请更换账号登录</view>
  10 + </view>
  11 + </view>
  12 +
  13 + <view class="footer">
  14 + <view class="left_btn">
  15 + <c-button type="confirm" shape="circle" @click="popPhoneNumber" text="联系客服"></c-button>
  16 + </view>
  17 + </view>
  18 + </view>
  19 +</template>
  20 +
  21 +<script>
  22 + export default {
  23 + data() {
  24 + return {
  25 +
  26 + }
  27 + },
  28 + methods: {
  29 + popPhoneNumber(){
  30 + uni.makePhoneCall({
  31 + phoneNumber:"150-7142-1900"
  32 + })
  33 + },
  34 + }
  35 + }
  36 +</script>
  37 +
  38 +<style lang="scss" scoped>
  39 + .written-off {
  40 + width: 100%;
  41 + height: 100%;
  42 + position: relative;
  43 +
  44 + .box {
  45 + .icon {
  46 + padding: 308rpx 0 0 0;
  47 + text-align: center;
  48 + }
  49 +
  50 + .text {
  51 + text-align: center;
  52 +
  53 + .title {
  54 + font-size: 34rpx;
  55 + color: #000000;
  56 + line-height: 48rpx;
  57 + margin: 44rpx 0 32rpx 0;
  58 + }
  59 +
  60 + .describe {
  61 + font-size: 28rpx;
  62 + color: rgba(0, 0, 0, 0.5);
  63 + line-height: 40rpx;
  64 + }
  65 + }
  66 + }
  67 +
  68 + .footer {
  69 + width: 100%;
  70 + height: 96rpx;
  71 + padding: 28rpx 30rpx;
  72 + background: #FFFFFF;
  73 + position: fixed;
  74 + bottom: 0;
  75 + left: 0;
  76 + z-index: 99;
  77 + border-top: 2rpx solid #E2E2E8;
  78 +
  79 + view {
  80 + display: inline-block;
  81 + }
  82 +
  83 + .left_btn {
  84 + width: 690rpx;
  85 + margin: 0 30rpx 0 0;
  86 + }
  87 + }
  88 + }
  89 +</style>
... ...
1 1 <template>
2   - <view style="height: 100%;">
  2 + <view class="home_box">
  3 + <view class="home">
  4 +
  5 + <view class="school_box" v-if="hasLogin">
  6 + <u-image :src="vuex_baseImgUrl+'/schoolBg.png'" width="750rpx" height="496rpx" />
  7 + <view class="school" :style="{top:top}">
  8 + <u-icon size="32rpx" name="/static/img/home/changeSchool.png" @click="show = true"></u-icon>
  9 + <text>{{doneSchoolName}}</text>
  10 + </view>
  11 + </view>
  12 +
  13 + <view class="school_box" v-else>
  14 + <u-image :src="vuex_baseImgUrl+'/schoolBg.png'" width="750rpx" height="496rpx" />
  15 + <view class="school" :style="{top:top}">
  16 + <u-icon size="32rpx" name="/static/img/home/changeSchool.png"></u-icon>
  17 + <text>校职通</text>
  18 + </view>
  19 + </view>
  20 +
  21 + <view class="info" v-if="hasLogin">
  22 + <u-row justify="space-between" customStyle="margin-bottom: 24rpx">
  23 + <u-col span="5">
  24 + <view class="name">
  25 + <text>{{teacher.name}}</text>
  26 + <text>老师您好!</text>
  27 + </view>
  28 + </u-col>
  29 + <u-col span="3" v-if="doneRolesLength > 1">
  30 + <view class="identity" @click="handelChange">
  31 + <u-icon size="36rpx" :label="doneRolesName" labelPos="right" labelSize="24rpx"
  32 + labelColor="#202131" name="/static/img/home/changeAuth.png"></u-icon>
  33 + </view>
  34 + </u-col>
  35 + </u-row>
  36 + </view>
  37 +
  38 + <view class="info" v-else>
  39 + <u-row justify="space-between" customStyle="margin-bottom: 24rpx">
  40 + <u-col span="5">
  41 + <view class="name" @click="handelLOgin">
  42 + <text>未登录</text>
  43 + <text>您还没有登录</text>
  44 + </view>
  45 + </u-col>
  46 + </u-row>
  47 + </view>
  48 +
  49 + <view class="gate">
  50 + <u-row justify="space-between" gutter="16rpx" customStyle="margin-bottom: 10px">
  51 + <u-col span="4">
  52 + <view class="box">
  53 + <view class="item review" data-type="review" @click="handelGate">
  54 + <u-image src="/static/img/home/registrationReviewBg.png" width="220rpx"
  55 + height="256rpx" />
  56 + <view class="copywriting">
  57 + <text>报名审核</text>
  58 + <text>审核学生实习报名</text>
  59 + </view>
  60 + </view>
  61 + </view>
  62 + </u-col>
  63 + <u-col span="4">
  64 + <view class="box">
  65 + <view class="item signIn" :style="{marginBottom:'16rpx'}" data-type="signin"
  66 + @click="handelGate">
  67 + <u-image src="/static/img/home/studentSignInBg.png" width="220rpx" height="120rpx" />
  68 + <view>
  69 + <u-icon size="48rpx" label="学生签到" labelPos="right" labelSize="28rpx"
  70 + labelColor="#1F71DE" name="/static/img/home/iconStudentSignIn.png"></u-icon>
  71 + <text>查看学生签到数据</text>
  72 + </view>
  73 + </view>
  74 + <view class="item report" data-type="report" @click="handelGate">
  75 + <u-image src="/static/img/home/reportReviewBg.png" width="220rpx" height="120rpx" />
  76 + <view>
  77 + <u-icon size="48rpx" label="报告批阅" labelPos="right" labelSize="28rpx"
  78 + labelColor="#FD9A03" name="/static/img/home/iconReportReview.png"></u-icon>
  79 + <text>批阅学生实习报告</text>
  80 + </view>
  81 + </view>
  82 + </view>
  83 + </u-col>
  84 + <u-col span="4">
  85 + <view class="box">
  86 + <view class="item signIn" :style="{marginBottom:'16rpx'}" data-type="log"
  87 + @click="handelGate">
  88 + <u-image src="/static/img/home/logReviewBg.png" width="220rpx" height="120rpx" />
  89 + <view>
  90 + <u-icon size="48rpx" label="日志批阅" labelPos="right" labelSize="28rpx"
  91 + labelColor="#7A7EF9" name="/static/img/home/iconLogReview.png"></u-icon>
  92 + <text>批阅学生周日志</text>
  93 + </view>
  94 + </view>
  95 + <view class="item report" data-type="achievement" @click="handelGate">
  96 + <u-image src="/static/img/home/achievementAppraisalBg.png" width="220rpx"
  97 + height="120rpx" />
  98 + <view>
  99 + <u-icon size="48rpx" label="成绩鉴定" labelPos="right" labelSize="28rpx"
  100 + labelColor="#FF6363" name="/static/img/home/iconAchievementAppraisal.png">
  101 + </u-icon>
  102 + <text>鉴定学生实习成绩</text>
  103 + </view>
  104 + </view>
  105 + </view>
  106 + </u-col>
  107 + </u-row>
  108 +
  109 + </view>
  110 +
  111 + <view class="todoList">
  112 + <view class="title">待办事项</view>
  113 + <view v-if="hasLogin">
  114 + <view
  115 + v-if="statistics && (statistics.internshipApply > 0 || statistics.formLogWaitReview > 0 || statistics.reportWaitReview > 0 || statistics.achievementWaitAppraisal > 0 )">
  116 + <view class="cell">
  117 + <u-cell-group :border="false">
  118 + <u-cell
  119 + v-if="statistics && statistics.internshipApply && statistics.internshipApply > 0"
  120 + :isLink="true"
  121 + url="/pages/main/home/registrationReview/registrationReview?status=wait"
  122 + arrow-direction="right" :rightIconStyle="{fontSize:'24rpx'}" :border="false">
  123 + <view slot="title" class="u-slot-title">
  124 + <view class="u-cell-title">实习申请</view>
  125 + <view class="u-cell-text">
  126 + 您有<text>{{statistics.internshipApply}}</text>条<text>实习申请</text>待处理!</view>
  127 + </view>
  128 + <text slot="value" class="u-slot-value">立即处理</text>
  129 + </u-cell>
  130 +
  131 + <u-cell
  132 + v-if="statistics && statistics.formLogWaitReview && statistics.formLogWaitReview > 0"
  133 + :isLink="true" url="/pages/main/home/logReview/logReview?status=unread"
  134 + arrow-direction="right" :rightIconStyle="{fontSize:'24rpx'}" :border="false">
  135 + <view slot="title" class="u-slot-title">
  136 + <view class="u-cell-title">日志批阅</view>
  137 + <view class="u-cell-text">
  138 + 您有<text>{{statistics.formLogWaitReview}}</text>篇<text>日志</text>待批阅!</view>
  139 + </view>
  140 + <text slot="value" class="u-slot-value">立即批阅</text>
  141 + </u-cell>
  142 +
  143 + <u-cell
  144 + v-if="statistics && statistics.reportWaitReview && statistics.reportWaitReview > 0"
  145 + :isLink="true" url="/pages/main/home/reportReview/reportReview?status=stay_examine"
  146 + arrow-direction="right" :rightIconStyle="{fontSize:'24rpx'}" :border="false">
  147 + <view slot="title" class="u-slot-title">
  148 + <view class="u-cell-title">报告批阅</view>
  149 + <view class="u-cell-text">
  150 + 您有<text>{{statistics.reportWaitReview}}</text>篇<text>实习报告</text>待批阅!</view>
  151 + </view>
  152 + <text slot="value" class="u-slot-value">立即批阅</text>
  153 + </u-cell>
  154 +
  155 + <u-cell
  156 + v-if="statistics && statistics.achievementWaitAppraisal && statistics.achievementWaitAppraisal > 0"
  157 + :isLink="true"
  158 + url="/pages/main/home/achievementAppraisal/achievementAppraisal?appraisalStatus=no_appraisal"
  159 + arrow-direction="right" :rightIconStyle="{fontSize:'24rpx'}" :border="false">
  160 + <view slot="title" class="u-slot-title">
  161 + <view class="u-cell-title">成绩评定</view>
  162 + <view class="u-cell-text">
  163 + 您有<text>{{statistics.achievementWaitAppraisal}}</text>个<text>成绩</text>待评定!
  164 + </view>
  165 + </view>
  166 + <text slot="value" class="u-slot-value">立即评定</text>
  167 + </u-cell>
  168 +
  169 + </u-cell-group>
  170 + </view>
  171 + </view>
  172 + <view v-else>
  173 + <c-no-data paddingTop="30" title="当前无待办事项"></c-no-data>
  174 + </view>
  175 + </view>
  176 + <view class="no_login" v-else>
  177 + <text>登录后可查看待办事项</text>
  178 + <u-button type="primary" text="登录" color="#06B079" :customStyle="{width:'340rpx'}"
  179 + @click="handelLOgin"></u-button>
  180 + </view>
  181 + </view>
  182 + </view>
  183 +
  184 + <u-popup :show="show" mode="left" @close="close" @open="open">
  185 + <view class="popup_search">
  186 + <view class="content">
  187 + <view class="title">
  188 + <text>选择学校</text>
  189 + <text>请选择您想登录管理的学校</text>
  190 + </view>
  191 + <scroll-view class="scroll" scroll-y="true">
  192 + <view class="item" v-for="(item, i) in schoolList" :key="i" @click="handelClick(item)">
  193 + <view v-if="item.id == schoolId">
  194 + <u-image src="/static/img/home/schoolAvatar.png" width="104rpx" height="104rpx" />
  195 + <text class="fullName">{{item.fullName}}</text>
  196 + </view>
  197 + <view v-else>
  198 + <u-image src="/static/img/home/schoolAvatar.png" width="104rpx" height="104rpx" />
  199 + <text class="fullName">{{item.fullName}}</text>
  200 + </view>
  201 + </view>
  202 + </scroll-view>
  203 +
  204 + </view>
  205 +
  206 + </view>
  207 + </u-popup>
3 208
4 209 </view>
5 210 </template>
6 211
7 212 <script>
  213 + import {
  214 + mapGetters,
  215 + mapState,
  216 + mapActions
  217 + } from 'vuex'
  218 +
  219 +
  220 + import {
  221 + putTeacherRolesApi,
  222 + getTodoListStatisticsApi,
  223 + } from '@/config/api.js';
8 224
9 225 export default {
10 226 data() {
11 227 return {
12   -
  228 + top: '0rpx',
  229 + show: false,
  230 + schoolId: '',
  231 + statistics: {}
13 232 }
14 233 },
15 234
16 235 onLoad() {
17   -
  236 +
18 237 },
19 238
20 239 onShow() {
  240 + uni.getSystemInfo({
  241 + success: (res) => {
  242 +
  243 + let menuButtonInfo = uni.getMenuButtonBoundingClientRect();
  244 + let menuTop = menuButtonInfo.top
  245 +
  246 + // 状态栏高度
  247 + let winWidth = res.windowWidth;
  248 + let proportion = 750 / winWidth;
  249 +
  250 + this.top = ((menuTop * proportion) + 16) + 'rpx';
  251 + },
  252 + complete: function(res) {},
  253 + });
  254 +
  255 + if (this.hasLogin) {
  256 + this.$store.dispatch(`home/getSchoolList`, {
  257 + pageSize: -1,
  258 + })
  259 + getTodoListStatisticsApi().then(data => {
  260 + if (data) {
  261 + this.statistics = data;
  262 + }
  263 + })
  264 + }
  265 + },
  266 +
  267 + computed: {
  268 + ...mapGetters([
  269 + 'doneRolesLength',
  270 + 'doneRolesName',
  271 + 'doneSchoolName',
  272 + ]),
  273 +
  274 + ...mapState({
  275 + hasLogin: 'hasLogin',
  276 + vuex_user: 'vuex_user',
  277 + refresh_token: 'refresh_token',
  278 + teacher: (state) => state.vuex_user.teacher,
  279 + }),
  280 + ...mapState('home', {
  281 + // 箭头函数可使代码更简练
  282 + schoolList: 'schoolList',
  283 +
  284 + }),
  285 + ...mapState('user', {
  286 + // 箭头函数可使代码更简练
  287 + loginInfo: 'loginInfo',
  288 +
  289 + }),
  290 +
  291 +
  292 +
21 293
22 294 },
23 295
24 296 methods: {
25 297
  298 + handelClick(values) {
  299 + this.schoolId = values.id;
  300 +
  301 + this.$store.dispatch(`user/login`, {
  302 + way: 'refresh_token',
  303 + refreshToken: this.refresh_token,
  304 + schoolId: values.id,
  305 + }).then(data => {
  306 + console.log(data)
  307 + if (data) {
  308 +
  309 + getTodoListStatisticsApi().then(data => {
  310 + if (data) {
  311 + this.statistics = data;
  312 + }
  313 + })
  314 +
  315 + this.show = false;
  316 + }
  317 + })
  318 + },
  319 +
  320 + open() {
  321 +
  322 + },
  323 +
  324 + close() {
  325 + this.show = false
  326 + },
  327 +
  328 + handelLOgin() {
  329 + this.$u.route('/pages/main/my/login/login');
  330 + },
  331 +
  332 + handelChange() {
  333 + let {
  334 + roles = []
  335 + } = this.teacher;
  336 +
  337 + if (roles.length < 2) {
  338 + this.$u.toast('暂无可切换权限')
  339 + } else {
  340 +
  341 + let selectRoles = roles.filter(item => item.id != this.teacher.roleId);
  342 +
  343 + putTeacherRolesApi(this.teacher.id, {
  344 + roleId: selectRoles[0].id
  345 + }).then(data => {
  346 + if (data) {
  347 + console.log(data)
  348 + this.$store.dispatch(`user/getUserInfo`);
  349 +
  350 + getTodoListStatisticsApi().then(data => {
  351 + if (data) {
  352 + this.statistics = data;
  353 + }
  354 + })
  355 + }
  356 + })
  357 + }
  358 + },
  359 +
  360 +
  361 +
  362 + handelGate(even) {
  363 + if (!this.hasLogin) {
  364 + this.$u.route('/pages/main/my/login/login');
  365 + return;
  366 + }
  367 +
  368 + let {
  369 + type = ''
  370 + } = even.currentTarget.dataset;
  371 +
  372 + switch (type) {
  373 + case 'review':
  374 + this.$u.route('/pages/main/home/registrationReview/registrationReview');
  375 + break;
  376 +
  377 + case 'signin':
  378 + this.$u.route('/pages/main/home/studentSignIn/studentSignIn');
  379 + break;
  380 +
  381 + case 'log':
  382 + this.$u.route('/pages/main/home/logReview/logReview');
  383 + break;
  384 +
  385 + case 'report':
  386 + this.$u.route('/pages/main/home/reportReview/reportReview');
  387 + break;
  388 +
  389 + case 'achievement':
  390 + this.$u.route('/pages/main/home/achievementAppraisal/achievementAppraisal');
  391 + break;
  392 +
  393 +
  394 +
  395 +
  396 +
  397 +
  398 + }
  399 +
  400 + },
  401 +
26 402 }
27 403 }
28 404 </script>
29 405
30 406 <style lang="scss" scoped>
  407 + .cell /deep/ .u-cell {
  408 + background-color: #FFFFFF;
  409 + border-radius: 12rpx;
  410 + margin: 0 0 20rpx 0;
  411 + }
  412 +
  413 + .home_box {
  414 + background-color: #F7F7F7;
  415 + min-height: 100%;
  416 + height: auto;
  417 +
  418 + .home {
  419 + width: 100%;
  420 +
  421 + .school_box {
  422 + width: 100%;
  423 + height: 496rpx;
  424 + margin: 0 0 34rpx 0;
  425 + position: relative;
  426 +
  427 + .school {
  428 + position: absolute;
  429 + top: 0rpx;
  430 + left: 40rpx;
  431 + display: flex;
  432 + flex-flow: row nowrap;
  433 +
  434 + text {
  435 + font-size: 32rpx;
  436 + line-height: 32rpx;
  437 + color: #202131;
  438 + font-weight: 500;
  439 + width: 600rpx;
  440 + text-align: center;
  441 + }
  442 + }
  443 +
  444 + }
  445 +
  446 + .info {
  447 + width: 690rpx;
  448 + margin: 0 auto;
  449 +
  450 + .name {
  451 + text {
  452 + display: inline-block;
  453 + font-size: 24rpx;
  454 + line-height: 36rpx;
  455 + color: #909097;
  456 + margin: 0 0 0 12rpx;
  457 + }
  458 +
  459 + text:first-child {
  460 +
  461 + font-size: 36rpx;
  462 + line-height: 52rpx;
  463 + color: #202131;
  464 + width: 150rpx;
  465 + overflow: hidden;
  466 + text-overflow: ellipsis;
  467 + white-space: nowrap;
  468 + margin: 0;
  469 + }
31 470
  471 + text:last-child {
  472 + vertical-align: super;
  473 + }
  474 + }
  475 +
  476 + .identity {
  477 + margin: 0 0 0 10rpx;
  478 + }
  479 + }
  480 +
  481 + .gate {
  482 + width: 690rpx;
  483 + margin: 0 auto 50rpx;
  484 +
  485 + .box {
  486 + width: 220rpx;
  487 + height: 256rpx;
  488 +
  489 + .item {
  490 + position: relative;
  491 + width: 220rpx;
  492 + height: 120rpx;
  493 +
  494 + view {
  495 + position: absolute;
  496 + top: 20rpx;
  497 + left: 20rpx;
  498 +
  499 + text {
  500 + display: block;
  501 + margin: 8rpx 0 0 6rpx;
  502 + font-size: 20rpx;
  503 + line-height: 20rpx;
  504 + color: #909097;
  505 + }
  506 + }
  507 + }
  508 +
  509 + .review {
  510 +
  511 +
  512 + .copywriting {
  513 + position: absolute;
  514 + top: 56rpx;
  515 + right: 32rpx;
  516 +
  517 + text {
  518 + display: block;
  519 + font-size: 28rpx;
  520 + line-height: 36rpx;
  521 + color: #06B079;
  522 + margin: 0;
  523 + }
  524 +
  525 + text:last-child {
  526 + font-size: 20rpx;
  527 + line-height: 52rpx;
  528 + color: #909097;
  529 + }
  530 +
  531 + }
  532 + }
  533 + }
  534 + }
  535 +
  536 + .todoList {
  537 + width: 690rpx;
  538 + margin: 0 auto;
  539 +
  540 + .no_login {
  541 + padding: 150rpx 0 0 0;
  542 + text-align: center;
  543 +
  544 + text {
  545 + font-size: 24rpx;
  546 + line-height: 52rpx;
  547 + color: #909097;
  548 + }
  549 + }
  550 +
  551 + .title {
  552 + font-size: 32rpx;
  553 + line-height: 32rpx;
  554 + color: #202131;
  555 + }
  556 +
  557 + .title::before {
  558 + content: "";
  559 + display: inline-block;
  560 + width: 6rpx;
  561 + height: 32rpx;
  562 + background-color: #06B079;
  563 + margin: 0 12rpx 0 0;
  564 + position: relative;
  565 + top: 4rpx;
  566 + border-radius: 8rpx;
  567 + }
  568 +
  569 + .cell {
  570 + margin: 20rpx 0 0 0;
  571 +
  572 + .u-slot-title {
  573 + .u-cell-title {
  574 + font-size: 24rpx;
  575 + line-height: 54rpx;
  576 + color: #909097;
  577 + }
  578 +
  579 + .u-cell-text {
  580 + font-size: 28rpx;
  581 + line-height: 60rpx;
  582 + color: #202131;
  583 +
  584 + text {
  585 + color: #06B079;
  586 + }
  587 + }
  588 + }
  589 +
  590 + .u-slot-value {
  591 + font-size: 24rpx;
  592 + line-height: 36rpx;
  593 + color: #909097;
  594 + }
  595 + }
  596 +
  597 + }
  598 + }
  599 +
  600 + .popup_search {
  601 + width: 540rpx;
  602 + height: 100%;
  603 + background-color: #F7F7F7;
  604 + position: relative;
  605 +
  606 + .content {
  607 + padding: 100rpx 40rpx 0;
  608 +
  609 + .title {
  610 + font-size: 48rpx;
  611 + line-height: 60rpx;
  612 + color: #202131;
  613 +
  614 + text:last-child {
  615 + display: block;
  616 + font-size: 24rpx;
  617 + line-height: 32rpx;
  618 + color: #909097;
  619 + margin: 30rpx 0 70rpx 0;
  620 + }
  621 + }
  622 +
  623 + .scroll {
  624 + max-height: 60vh;
  625 +
  626 + .item {
  627 + width: 380rpx;
  628 + height: 100rpx;
  629 + box-shadow: 0rpx 4rpx 48rpx 0rpx rgba(175, 174, 174, 0.1500);
  630 + border-radius: 20rpx;
  631 + margin: 0 0 20rpx 0;
  632 + padding: 40rpx;
  633 + background-color: #FFFFFF;
  634 +
  635 +
  636 + view {
  637 + display: flex;
  638 + flex-flow: row wrap;
  639 + align-items: center;
  640 +
  641 + text {
  642 + width: 240rpx;
  643 + font-size: 40rpx;
  644 + line-height: 48rpx;
  645 + color: #202131;
  646 + margin: 0 0 0 34rpx;
  647 + }
  648 + }
  649 +
  650 + }
  651 + }
  652 + }
  653 +
  654 + }
  655 + }
32 656 </style>
... ...
1 1 <template>
2   - <view class="internship">
3   -
  2 + <view class="internship_box">
  3 + <view class="internship" v-if="hasLogin">
  4 +
  5 + <view class="search_box">
  6 + <view class="search">
  7 + <u-search placeholder="请输入学生姓名/学号/手机号" placeholderColor="#C1C1C9" searchIconSize="36" height="64rpx"
  8 + bgColor="#F4F4F4" :showAction="false" shape="square" v-model="keyword" @search="handelSearch">
  9 + </u-search>
  10 + </view>
  11 + </view>
  12 +
  13 + <view class="list_box" v-if="list.length > 0">
  14 + <view class="item" v-for="(item, i) in list" :key="i" @click="handelDetail(item)">
  15 +
  16 + <view class="info">
  17 + <u-image src="/static/img/internship/classIcon.png" width="88rpx" height="88rpx" />
  18 + <view class="title_name">
  19 + <view class="title">
  20 + {{item.startSchoolYear}}
  21 + </view>
  22 + <view class="time">
  23 + <text>{{item.classInfoName}}</text>
  24 + </view>
  25 + </view>
  26 + <view class="num">
  27 + <text>{{item.internedTotal || 0}}/{{item.classInfoTotal || 0}}</text>
  28 + <u-icon :style="{margin:'0 0 0 8rpx'}" name="arrow-right" color="#909097" size="24">
  29 + </u-icon>
  30 + </view>
  31 + </view>
  32 +
  33 + </view>
  34 + <c-loading :loading="loading"></c-loading>
  35 + </view>
  36 + <view v-else class="no_data">
  37 + <c-no-data></c-no-data>
  38 + </view>
  39 +
  40 + </view>
  41 + <view class="no_login" v-else>
  42 + <view class="image">
  43 + <u-image :style="{margin:'0 auto'}" :src="vuex_baseImgUrl+'/internship_bg.png'" width="480rpx"
  44 + height="480rpx"></u-image>
  45 + </view>
  46 + <view class="btn">
  47 + <text>登录后可查看待办事项</text>
  48 + <u-button type="primary" text="登录" color="#06B079" :customStyle="{width:'340rpx'}" @click="handelLOgin">
  49 + </u-button>
  50 + </view>
  51 + </view>
4 52 </view>
5 53 </template>
6 54
7 55 <script>
  56 + import {
  57 + mapGetters,
  58 + mapState,
  59 + mapActions
  60 + } from 'vuex'
  61 +
  62 + import listMixin from "@/common/mixins/list-mixin.js";
  63 +
  64 + import {
  65 + getClassListApi,
  66 + } from '@/config/api.js';
8 67
9 68 export default {
  69 + mixins: [listMixin],
10 70 data() {
11 71 return {
12   -
13   - };
  72 + keyword: '',
  73 + list: [],
  74 + search: {
  75 + keySearch: "",
  76 + },
  77 + }
14 78 },
15 79
16   - onLoad() {},
  80 + onLoad() {
17 81
18   - async onShow() {
19   -
20 82 },
21 83
22   - methods: {
23   -
  84 + onShow() {
  85 + if (this.hasLogin) {
  86 + this.search.keySearch = '';
  87 +
  88 + this.finished = false;
  89 + this.loading = "loadmore";
  90 + this.page = 0;
  91 + this.list = [];
  92 + this._getList();
  93 + }
  94 + },
  95 +
  96 + computed: {
  97 + ...mapState({
  98 + hasLogin: 'hasLogin',
  99 + vuex_user: 'vuex_user',
  100 + teacher: (state) => state.vuex_user.teacher,
  101 + }),
  102 +
  103 +
24 104 },
25   - };
26   -</script>
  105 +
  106 + methods: {
  107 + timeFormat(timestamp, format = 'yyyy-mm-dd') {
  108 + return timestamp > 0 ? uni.$u.timeFormat(timestamp, format) : '--'
  109 + },
  110 +
  111 + handelLOgin() {
  112 + this.$u.route('/pages/main/my/login/login');
  113 + },
  114 +
  115 + handelSearch(value) {
  116 + this.finished = false;
  117 + this.loading = "loadmore";
  118 + this.page = 0;
  119 + this.list = [];
  120 + this._getList();
  121 + },
  122 +
  123 + handelDetail(record) {
  124 + this.$u.route({
  125 + url: `pages/main/internship/studentList/studentList?classInfoId=${record.classInfoId}`
  126 + })
  127 + },
  128 +
  129 + // scroll-view到底部加载更多
  130 + onreachBottom() {},
  131 + // 搜索
  132 + searchSubmit() {
  133 + // 调用混合搜索
  134 + this._searchData();
  135 + },
  136 + // 模拟后端分页
  137 + async getData(requestParams) {
  138 + const {
  139 + search = {}
  140 + } = requestParams;
  141 +
  142 + let params = {};
  143 + params.pageNumber = requestParams.page + 1;
  144 + params.pageSize = 5;
  145 +
  146 + if (this.keyword) {
  147 + params.keySearch = this.keyword
  148 + }
  149 +
  150 + return await getClassListApi(params);
  151 + },
  152 + // 数据请求(没错就是这么少的代码)
  153 + async _getList() {
  154 + if (this.page == 0) {
  155 + this.list = [];
  156 + }
  157 +
  158 + // 根据实际情况修改自己修改key
  159 + let result = await this.getData({
  160 + page: this.page, // 传入页码
  161 + size: this.size, // 传入每页条数
  162 + search: this.search, // 传入搜索的对象
  163 + });
  164 +
  165 + this.total = result.total;
  166 +
  167 + if (this.list.length == 0 && result.records.length == 0) {
  168 + this.shownoData = false
  169 + } else {
  170 + this.shownoData = true
  171 + }
  172 +
  173 + this.list = this.list.concat(result.records)
  174 +
  175 + // 判断是否全部加载完成
  176 + if (this.total == this.list.length) {
  177 + this.finished = true;
  178 + this.loading = 'nomore';
  179 + } else {
  180 + this.loading = 'loadmore';
  181 + }
  182 + },
  183 +
  184 + }
  185 + }
  186 +</script>
27 187
28 188 <style lang="scss" scoped>
  189 + .internship_box {
  190 + background-color: #F7F7F7;
  191 + min-height: 100%;
  192 + height: auto;
  193 +
  194 + .internship {
  195 + width: 100%;
  196 + margin: 0 auto;
  197 +
  198 + .search_box {
  199 + padding: 36rpx 0;
  200 + background-color: #FFFFFF;
  201 +
  202 + .search {
  203 + width: 690rpx;
  204 + margin: 0 auto;
  205 + }
  206 +
  207 + }
  208 +
  209 + .list_box {
  210 + padding: 0 0 50rpx 0;
  211 +
  212 + .item {
  213 + position: relative;
  214 + width: 630rpx;
  215 + margin: 30rpx auto;
  216 + padding: 30rpx;
  217 + border-radius: 12rpx;
  218 + background-color: #FFFFFF;
  219 +
  220 + .info {
  221 + display: flex;
  222 + flex-flow: row nowrap;
  223 + align-items: center;
  224 + position: relative;
  225 +
  226 + .title_name {
  227 + .title {
  228 + font-size: 24rpx;
  229 + line-height: 36rpx;
  230 + color: #06B079;
  231 + margin: 0 12rpx;
  232 + }
  233 +
  234 + .time {
  235 + padding: 12rpx 0 0 12rpx;
  236 + font-size: 28rpx;
  237 + line-height: 40rpx;
  238 + color: #202131;
  239 + }
  240 + }
  241 +
  242 + .num {
  243 + display: flex;
  244 + flex-flow: row nowrap;
  245 + position: absolute;
  246 + top: 26rpx;
  247 + right: 0rpx;
  248 +
  249 + text {
  250 + font-size: 24rpx;
  251 + line-height: 36rpx;
  252 + color: #909097;
  253 + }
  254 + }
  255 + }
  256 + }
  257 + }
  258 + }
  259 +
  260 + .no_login {
  261 + padding: 180rpx 0 0 0;
  262 + text-align: center;
  263 +
  264 + .image {
  265 + width: 480rpx;
  266 + margin: 0 auto;
  267 + }
  268 +
  269 + .btn {
  270 + position: relative;
  271 + top: -80rpx;
  272 +
  273 + text {
  274 + font-size: 24rpx;
  275 + line-height: 52rpx;
  276 + color: #909097;
  277 +
  278 + }
  279 + }
  280 + }
29 281
30   -
  282 + }
31 283 </style>
... ...
1   -<template>
2   - <view>
3   -
4   - </view>
5   -</template>
6   -
7   -<script>
8   -
9   - export default {
10   - data() {
11   - return {
12   -
  1 +<template>
  2 + <view class="my_box">
  3 + <view class="my" v-if="hasLogin">
  4 + <view class="box-bg">
  5 + <u-image width="100%" height="500rpx" :src="vuex_baseImgUrl+'/myBg.png'" />
  6 + </view>
  7 + <view class="container">
  8 + <view class="avatar">
  9 + <u-image :src="reversedAvatarUrl" shape="circle" width="190rpx" height="190rpx" />
  10 + </view>
  11 + <view class="top">
  12 +
  13 + <view class="title">
  14 + <text class="name">{{reversedName}}</text>
  15 + <view class="info" @click="link('person')">
  16 + <text class="edit-name">{{"个人资料"}}</text>
  17 + <u-icon class="arrowRight" width="20rpx" name="arrow-right" color="#B2B2B2" size="28">
  18 + </u-icon>
  19 + </view>
  20 + </view>
  21 +
  22 + <view class="cell">
  23 + <u-cell-group :border="false">
  24 + <u-cell title="账号与安全" :isLink="true" url="/pages/main/my/accountSafe/accountSafe"
  25 + arrow-direction="right" :rightIconStyle="{fontSize:'28rpx'}" :border="false"
  26 + :title-style="{padding:'0 0 0 14rpx', color:'#333', fontSize:'28rpx'}">
  27 + <u-icon slot="icon" size="48" :name="'/static/img/my/accountSafe.png'"></u-icon>
  28 + </u-cell>
  29 + <u-cell title="政策与协议" :isLink="true"
  30 + url="/pages/main/my/policiesAgreement/policiesAgreement" arrow-direction="right"
  31 + :rightIconStyle="{fontSize:'28rpx'}" :border="false"
  32 + :title-style="{padding:'0 0 0 14rpx', color:'#333', fontSize:'28rpx'}">
  33 + <u-icon slot="icon" size="48" :name="'/static/img/my/policiesAgreement.png'"></u-icon>
  34 + </u-cell>
  35 + </u-cell-group>
  36 + </view>
  37 + </view>
  38 +
  39 + <view class="bottom">
  40 + <view class="cell">
  41 + <u-cell-group :border="false">
  42 + <u-cell title="版本信息" :isLink="true" url="/pages/main/my/versionInfo/versionInfo"
  43 + arrow-direction="right" :rightIconStyle="{fontSize:'28rpx'}" :border="false"
  44 + :title-style="{padding:'0 0 0 14rpx', color:'#333', fontSize:'28rpx'}">
  45 + <u-icon slot="icon" size="48" :name="'/static/img/my/versionInfo.png'"></u-icon>
  46 + </u-cell>
  47 + </u-cell-group>
  48 + </view>
  49 + </view>
  50 +
  51 + <view class="btn loginOut">
  52 + <c-button type="cancel" @click="link('loginOut')" text="退出登录">
  53 + </c-button>
  54 + </view>
  55 + </view>
  56 + </view>
  57 +
  58 + <view class="my" v-else>
  59 + <view class="box-bg">
  60 + <u-image width="100%" height="500rpx" :src="vuex_baseImgUrl+'/myBg.png'" />
  61 + </view>
  62 + <view class="container">
  63 + <view class="avatar">
  64 + <u-image src="/static/img/my/default_avatar.png" shape="circle" width="190rpx" height="190rpx" />
  65 + </view>
  66 + <view class="top">
  67 +
  68 + <view class="title">
  69 + <text class="name" @click="handelLOgin">{{`未登录/注册`}}</text>
  70 + <view class="info" @click="handelLOgin">
  71 + <text class="edit-name">{{"个人资料"}}</text>
  72 + <u-icon class="arrowRight" width="20rpx" name="arrow-right" color="#B2B2B2" size="28">
  73 + </u-icon>
  74 + </view>
  75 + </view>
  76 +
  77 + <view class="cell">
  78 + <u-cell-group :border="false">
  79 + <u-cell icon="/static/img/my/school_authen.png" title="账号与安全" :isLink="true"
  80 + url="/pages/main/my/login/login" arrow-direction="right"
  81 + :rightIconStyle="{fontSize:'36rpx'}" :border="false"
  82 + :title-style="{padding:'0 0 0 14rpx', color:'#333', fontSize:'36rpx'}">
  83 + <u-icon slot="icon" size="64" :name="'/static/img/my/school_authen.png'"></u-icon>
  84 + </u-cell>
  85 + <u-cell icon="/static/img/my/school_authen.png" title="政策与协议" :isLink="true"
  86 + url="/pages/main/my/login/login" arrow-direction="right"
  87 + :rightIconStyle="{fontSize:'36rpx'}" :border="false"
  88 + :title-style="{padding:'0 0 0 14rpx', color:'#333', fontSize:'36rpx'}">
  89 + <u-icon slot="icon" size="64" :name="'/static/img/my/school_authen.png'"></u-icon>
  90 + </u-cell>
  91 + </u-cell-group>
  92 + </view>
  93 + </view>
  94 +
  95 + <view class="cell bottom">
  96 + <u-cell-group :border="false">
  97 + <u-cell icon="/static/img/my/school_authen.png" title="版本信息" :isLink="true"
  98 + url="/pages/main/my/login/login" arrow-direction="right"
  99 + :rightIconStyle="{fontSize:'36rpx'}" :border="false"
  100 + :title-style="{padding:'0 0 0 14rpx', color:'#333', fontSize:'36rpx'}">
  101 + <u-icon slot="icon" size="64" :name="'/static/img/my/school_authen.png'"></u-icon>
  102 + </u-cell>
  103 + </u-cell-group>
  104 + </view>
  105 + </view>
  106 + </view>
  107 +
  108 + </view>
  109 +</template>
  110 +
  111 +<script>
  112 + import {
  113 + mapState,
  114 + mapActions
  115 + } from 'vuex'
  116 +
  117 + export default {
  118 + data() {
  119 + return {
  120 + avatarUrl: '',
  121 + }
  122 + },
  123 +
  124 + onLoad() {
  125 +
  126 + },
  127 +
  128 + onShow() {
  129 + if (this.hasLogin) {
  130 + this.getUserInfo()
  131 + }
  132 + },
  133 +
  134 + computed: {
  135 + ...mapState({
  136 + hasLogin: 'hasLogin',
  137 + vuex_user: 'vuex_user',
  138 + vuex_weixinUserInfo: 'vuex_weixinUserInfo',
  139 + teacher: (state) => state.vuex_user.teacher,
  140 + vuex_weixinUserInfo: (state) => state.vuex_weixinUserInfo,
  141 + }),
  142 +
  143 + //name
  144 + reversedName() {
  145 + return (this.teacher && this.teacher.name) ? this.teacher.name : this.vuex_user.username;
  146 + },
  147 +
  148 + //avatar
  149 + reversedAvatarUrl() {
  150 + if (this.teacher && this.teacher.avatarUrl) {
  151 + return this.vuex_ossUrlPubilc + '/' + this.teacher.avatarUrl
  152 + }
  153 + return (this.vuex_weixinUserInfo && this.vuex_weixinUserInfo.avatarUrl) ? this.vuex_weixinUserInfo
  154 + .avatarUrl : '/static/img/my/default_avatar.png';
  155 + }
  156 + },
  157 +
  158 + methods: {
  159 +
  160 + ...mapActions('user', {
  161 + getUserInfo: 'getUserInfo',
  162 + }),
  163 +
  164 + handelLOgin() {
  165 + this.$u.route('/pages/main/my/login/login');
  166 + },
  167 +
  168 + link(type) {
  169 + const {
  170 + dispatch
  171 + } = this.$store;
  172 +
  173 + switch (type) {
  174 +
  175 + case 'person':
  176 + this.$u.route('/pages/main/my/personInfo/personInfo');
  177 + break;
  178 +
  179 + case 'loginOut':
  180 + dispatch(`user/loginOut`);
  181 + break;
  182 +
  183 +
  184 + }
  185 +
  186 + },
  187 +
  188 + }
  189 +
  190 +
  191 + }
  192 +</script>
  193 +
  194 +<style lang="scss" scoped>
  195 + .my_box {
  196 + width: 100%;
  197 + height: 100%;
  198 + }
  199 +
  200 + .my {
  201 + width: 100%;
  202 + height: 100%;
  203 + position: relative;
  204 + background-color: #F7F7F7;
  205 +
  206 + .box-bg {}
  207 +
  208 + .container {
  209 + width: 100%;
  210 + position: absolute;
  211 + top: 320rpx;
  212 + left: 0;
  213 + background-color: #F7F7F7;
  214 + padding: 0 0 100rpx 0;
  215 +
  216 +
  217 +
  218 + .avatar {
  219 + position: absolute;
  220 + top: -95rpx;
  221 + left: 32rpx;
13 222 }
14   - },
15   -
16   - onShow() {
17 223
18   - },
19   -
20   - methods: {
21   -
22   - }
23   - }
24   -</script>
25   -
26   -<style lang="scss" scoped>
27   -
  224 + .cell /deep/ .u-cell {
  225 + padding: 16rpx 2rpx;
  226 + }
  227 +
  228 + .top {
  229 + background: #FFFFFF;
  230 + box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.03);
  231 + border-top-left-radius: 20px;
  232 + border-top-right-radius: 20px;
  233 +
  234 + .title {
  235 + padding: 32rpx 0 40rpx 234rpx;
  236 + display: flex;
  237 + flex-flow: row nowrap;
  238 + justify-content: space-between;
  239 +
  240 +
  241 + .name {
  242 + display: inline-block;
  243 + width: 300rpx;
  244 + overflow: hidden;
  245 + text-overflow: ellipsis;
  246 + white-space: nowrap;
  247 + font-size: 44rpx;
  248 + line-height: 60rpx;
  249 + font-size: 500;
  250 + }
  251 +
  252 + .info {
  253 + display: flex;
  254 + flex-flow: row nowrap;
  255 + padding: 0 30rpx 0 0;
  256 +
  257 + .edit-name {
  258 + float: right;
  259 + font-size: 26rpx;
  260 + line-height: 36rpx;
  261 + padding: 12rpx 6rpx 0 0;
  262 + color: rgba(0, 0, 0, 0.65);
  263 + }
  264 +
  265 + .arrowRight {
  266 + float: right;
  267 + padding: 18rpx 32rpx 0 130rpx;
  268 + }
  269 + }
  270 + }
  271 +
  272 + }
  273 +
  274 + .bottom {
  275 + margin: 16rpx 0 0 0;
  276 + background-color: #FFFFFF;
  277 + }
  278 +
  279 + .loginOut {
  280 + width: 634rpx;
  281 + margin: 48rpx auto 0;
  282 + }
  283 +
  284 +
  285 +
  286 +
  287 + }
  288 +
  289 + .fixed_bottom_btn {
  290 + width: 100%;
  291 + height: 144rpx;
  292 + padding: 24rpx 32rpx;
  293 + background: #FFFFFF;
  294 + position: fixed;
  295 + bottom: 0;
  296 + left: 0;
  297 + z-index: 99;
  298 + border-top: 1rpx solid #F0F0F1;
  299 +
  300 + view {
  301 + display: inline-block;
  302 + }
  303 +
  304 + .left_btn {
  305 + width: 212rpx;
  306 + margin: 0 40rpx 0 0;
  307 + }
  308 +
  309 + .right_btn {
  310 + width: 434rpx;
  311 + }
  312 + }
  313 + }
28 314 </style>
... ...
1 1 {
2   - "projectname": "job-sharing",
  2 + "projectname": "yxly-teacher",
3 3 "setting": {
4 4 "compileHotReLoad": true
5 5 },
... ...

819 Bytes | 宽: | 高:

1.2 KB | 宽: | 高:

  • 两方对比
  • 交换覆盖
  • 透明覆盖

1.5 KB | 宽: | 高:

1.0 KB | 宽: | 高:

  • 两方对比
  • 交换覆盖
  • 透明覆盖

876 Bytes | 宽: | 高:

1.5 KB | 宽: | 高:

  • 两方对比
  • 交换覆盖
  • 透明覆盖

1.8 KB | 宽: | 高:

1.1 KB | 宽: | 高:

  • 两方对比
  • 交换覆盖
  • 透明覆盖
1 1 import Vue from 'vue'
2 2 import Vuex from 'vuex'
3 3 import user from './modules/user'
4   -import position from './modules/position'
  4 +import home from './modules/home'
5 5 Vue.use(Vuex)
6 6
7 7 let lifeData = {};
... ... @@ -14,7 +14,7 @@ try {
14 14 }
15 15
16 16 // 需要永久存储,且下次APP启动需要取出的,在state中的变量名
17   -let saveStateKeys = ['vuex_user', 'vuex_token', 'vuex_phone', 'vuex_weixinUserInfo' ];
  17 +let saveStateKeys = ['hasLogin', 'vuex_user', 'vuex_token', 'refresh_token', 'vuex_phone', 'vuex_weixinUserInfo'];
18 18
19 19 // 保存变量到本地存储中
20 20 const saveLifeData = function(key, value) {
... ... @@ -31,29 +31,31 @@ const saveLifeData = function(key, value) {
31 31 }
32 32 const store = new Vuex.Store({
33 33 modules: {
34   - user,
35   - position,
  34 + user,
  35 + home,
36 36 },
37 37 state: {
38   - vuex_appId: 'wx84b71301436652ce',
39   - vuex_corpId: 'ww4300c59cb9537f9e',//企业ID
  38 + hasLogin: lifeData.hasLogin ? lifeData.hasLogin : false,
  39 + vuex_appId: 'wx6cd2152282abd34c',
  40 + vuex_corpId: 'ww4300c59cb9537f9e', //企业ID
40 41 // 如果上面从本地获取的lifeData对象下有对应的属性,就赋值给state中对应的变量
41 42 // 加上vuex_前缀,是防止变量名冲突,也让人一目了然
42 43 vuex_user: lifeData.vuex_user ? lifeData.vuex_user : '',
43 44 vuex_weixinUserInfo: lifeData.vuex_weixinUserInfo ? lifeData.vuex_weixinUserInfo : '',
44 45 vuex_token: lifeData.vuex_token ? lifeData.vuex_token : '',
  46 + refresh_token: lifeData.refresh_token ? lifeData.refresh_token : '',
45 47 vuex_phone: lifeData.vuex_phone ? lifeData.vuex_phone : '',
46 48 // 如果vuex_version无需保存到本地永久存储,无需lifeData.vuex_version方式
47 49 vuex_version: '1.0.1',
48 50 vuex_demo: '绛紫',
49 51 vuex_baseImgUrl: "https://yxlypublic.oss-cn-beijing.aliyuncs.com/WeChat/yxly-teacher",
50 52 vuex_ossUrl: "https://yxly.oss-cn-beijing.aliyuncs.com",
51   - vuex_ossUrlPubilc: "https://yxlypublic.oss-cn-beijing.aliyuncs.com",
52   - vuex_customer_chatUrl:"https://work.weixin.qq.com/kfid/kfc04063cd2d1081221",//企业微信客服
53   - vuex_customer_phone:"",
54   - vuex_applyUrl:"",
55   - vuex_homeUrl:"",
56   - vuex_internshipDetailUrl:"",
  53 + vuex_ossUrlPubilc: "https://yxlypublic.oss-cn-beijing.aliyuncs.com",
  54 + vuex_customer_chatUrl: "https://work.weixin.qq.com/kfid/kfc04063cd2d1081221", //企业微信客服
  55 + vuex_customer_phone: "",
  56 + vuex_applyUrl: "",
  57 + vuex_homeUrl: "",
  58 + vuex_internshipDetailUrl: "",
57 59 // vuex_ossUrl: "https://oss.workai.com.cn",
58 60 vuex_OssInit: {},
59 61 vuex_area: {},
... ... @@ -63,6 +65,48 @@ const store = new Vuex.Store({
63 65 ],
64 66
65 67 },
  68 + getters: {
  69 + doneRolesLength: state => {
  70 + if (state && state.vuex_user && state.vuex_user.teacher) {
  71 + let {
  72 + teacher = {}
  73 + } = state.vuex_user;
  74 + if (teacher && teacher.roles && teacher.roles.length > 0) {
  75 +
  76 + return teacher.roles.length
  77 + } else {
  78 + return 0
  79 + }
  80 + } else {
  81 + return 0
  82 + }
  83 + },
  84 +
  85 + doneRolesName: state => {
  86 +
  87 + if (state && state.vuex_user && state.vuex_user.teacher) {
  88 + let {
  89 + teacher = {}
  90 + } = state.vuex_user;
  91 + if (teacher && teacher.roles && teacher.roles.length > 0) {
  92 + let selectRoles = teacher.roles.filter(item => item.id == teacher.roleId);
  93 + return selectRoles[0].name
  94 + } else {
  95 + return ''
  96 + }
  97 + } else {
  98 + return ''
  99 + }
  100 + },
  101 +
  102 + doneSchoolName: state => {
  103 + if (state && state.vuex_user && state.vuex_user.teacher) {
  104 + return state.vuex_user.teacher.schoolName;
  105 + } else {
  106 + return '';
  107 + }
  108 + },
  109 + },
66 110 mutations: {
67 111 $uStore(state, payload) {
68 112 // 判断是否多层级调用,state中为对象存在的情况,诸如user.info.score = 1
... ... @@ -86,7 +130,7 @@ const store = new Vuex.Store({
86 130 },
87 131
88 132 setWenxinUserInfo(state, result) {
89   - state.vuex_weixinUserInfo = result.userInfo;
  133 + state.vuex_weixinUserInfo = result.userInfo;
90 134 uni.$u.vuex('vuex_weixinUserInfo', result.userInfo);
91 135 },
92 136 }
... ...
  1 +import {
  2 + getSchoolListApi,
  3 + getProjectListApi,
  4 +} from '@/config/api.js';
  5 +
  6 +const state = () => ({
  7 + schoolList: [],
  8 + projectList: [],
  9 +})
  10 +
  11 +const getters = {
  12 +
  13 +}
  14 +
  15 +const actions = {
  16 +
  17 +
  18 +
  19 + async getSchoolList({
  20 + commit,
  21 + dispatch,
  22 + state
  23 + }, params) {
  24 + const result = await getSchoolListApi(params);
  25 + if (result && result.records) {
  26 + commit('setSchoolList', result);
  27 + return result;
  28 + }
  29 + },
  30 +
  31 + async getProjectList({
  32 + commit,
  33 + dispatch,
  34 + state
  35 + }, params) {
  36 + const result = await getProjectListApi(params);
  37 + if (result && result.records) {
  38 + commit('setProjectList', result);
  39 + return result;
  40 + }
  41 + },
  42 +
  43 +}
  44 +
  45 +const mutations = {
  46 +
  47 + setSchoolList(state, result) {
  48 + state.schoolList = result.records;
  49 + },
  50 +
  51 + setProjectList(state, result) {
  52 + state.projectList = result.records;
  53 + },
  54 +
  55 +}
  56 +
  57 +export default {
  58 + namespaced: true,
  59 + state,
  60 + getters,
  61 + actions,
  62 + mutations
  63 +}
... ...
1   -const state = () => ({
2   - positionDetail: {},
3   - reason: '',
4   -})
5   -
6   -const getters = {
7   - doneReleaseTime: state => {
8   - let {
9   - publishTime = 0
10   - } = state.positionDetail;
11   -
12   - return publishTime > 0 ? uni.$u.timeFormat(publishTime, 'mm/dd') : '';
13   - },
14   -
15   - doneSalary: state => {
16   - let {
17   - wageType = '', wageLower = '', wageUpper = '',
18   - } = state.positionDetail;
19   -
20   - let wageTypeOption = {
21   - "monthly": "月",
22   - "daily": "日",
23   - "hourly": "时",
24   - "annual": "年"
25   - };
26   -
27   - let salary = '';
28   -
29   - switch (wageType) {
30   -
31   - case 'negotiable':
32   - salary = '薪资面议'
33   - break;
34   -
35   - default:
36   - if (wageLower == wageUpper) {
37   - salary = `${wageLower}/${wageTypeOption[wageType]}`
38   - } else {
39   - salary = `${wageLower}~${wageUpper}/${wageTypeOption[wageType]}`
40   - }
41   - break;
42   - }
43   -
44   - return salary;
45   - },
46   -
47   - doneAddress: state => {
48   - let {
49   - province = '', district = '',
50   - } = state.positionDetail;
51   -
52   - return `${province}/${district}`;
53   - },
54   -
55   - doneWorkHour: state => {
56   - let {
57   - attendanceType = '', attendanceDay = '',
58   - } = state.positionDetail;
59   -
60   - let attendanceTypeOption = {
61   - "week": "周",
62   - "month": "月",
63   - "year": "年"
64   - };
65   -
66   - return attendanceType && attendanceDay ? `${attendanceDay}/${attendanceTypeOption[attendanceType]}` :
67   - "";
68   - },
69   -
70   - doneProperty: state => {
71   - let {
72   - property = '',
73   - } = state.positionDetail;
74   -
75   - let propertyOptions = {
76   - "part_time": "兼职",
77   - "internship": "实习",
78   - "full_time": "全职",
79   - "other": "其他"
80   - }
81   -
82   - return propertyOptions[property];
83   - },
84   -
85   - doneCategory: state => {
86   - let {
87   - category = '',
88   - } = state.positionDetail;
89   -
90   - let categoryOptions = {
91   - "0": "不限",
92   - "manufacture": "智能制造",
93   - "preschool": "学前教育",
94   - "healthy": "智慧康养",
95   - "software": "大数据与软件",
96   - "other": "其他",
97   - }
98   -
99   - return categoryOptions[category];
100   - },
101   -
102   - doneDegree: state => {
103   - let {
104   - degreeRequires = '',
105   - } = state.positionDetail;
106   -
107   - let degreeOptions = {
108   - "0": "不限",
109   - "1": "初中",
110   - "2": "高中",
111   - "3": "中专/技校",
112   - "4": "大专",
113   - "5": "本科",
114   - "6": "硕士",
115   - "7": "博士",
116   - "8": "MBA/EMBA"
117   - }
118   -
119   - return degreeRequires ? degreeOptions[degreeRequires] : "";
120   - },
121   -
122   - doneWorkExp: state => {
123   - let {
124   - workExp = '',
125   - } = state.positionDetail;
126   -
127   - let workExpOptions = {
128   - "0": "不限",
129   - "1": "在校生",
130   - "2": "应届生",
131   - "3": "1年以内",
132   - "4": "1-3年",
133   - "5": "3-5年",
134   - "6": "5-10年",
135   - "7": "10年以上",
136   - }
137   -
138   - return workExpOptions[workExp];
139   - },
140   -
141   - doneFlag: state => {
142   - let {
143   - flag = '',
144   - } = state.positionDetail;
145   -
146   -
147   - if(flag) {
148   - return flag.split(',');
149   - } else {
150   - return [];
151   - }
152   - },
153   -
154   -}
155   -
156   -const actions = {
157   -
158   - async getPositionDetail({
159   - commit,
160   - dispatch,
161   - state
162   - }, params) {
163   - const result = await uni.$u.api.getJobDetailApi(params);
164   - if (result) {
165   - commit('setPositionDetail', result);
166   - return result;
167   - }
168   - },
169   -
170   -}
171   -
172   -const mutations = {
173   -
174   - setPositionDetail(state, result) {
175   - state.positionDetail = result;
176   - },
177   -
178   - setPositionReason(state, result) {
179   - state.reason = result;
180   - },
181   -
182   -}
183   -
184   -export default {
185   - namespaced: true,
186   - state,
187   - getters,
188   - actions,
189   - mutations
190   -}
1 1 import {
2   - postTokenApi,
3   - getUserInfoApi,
4   - } from '@/config/api.js';
5   -
6   - const state = () => ({
7   - openid: '',
8   - isReg: '',
9   - id: '',
10   - name: '',
11   - number: '',
12   - password: '',
13   - phone: '',
14   - status: '',
15   - type: '',
16   - username: '',
17   - userBasicInfo: {},
18   -
19   - })
20   -
21   - const getters = {
22   - // doneOpenid: (state, getters, rootState) => {
23   - // return state.openid
24   - // },
25   - }
26   -
27   - // actions
28   - const actions = {
29   -
30   - async login({
31   - commit,
32   - dispatch,
33   - state
34   - }, params) {
35   - const login_result = await postTokenApi({
36   - ...params
37   - }, {
38   - custom: {
39   - auth: false
40   - }
41   - });
42   -
43   - console.log(login_result)
44   -
45   - if (login_result) {
46   -
47   - let vuex_token = `Bearer ${login_result.access_token}`
48   - await uni.$u.vuex('vuex_token', vuex_token);
49   - await uni.$u.vuex('vuex_phone', login_result.phone);
50   -
51   - switch (login_result.status) {
52   -
53   - case 'not_reg': //未注册
  2 + postTokenApi,
  3 + getUserInfoApi,
  4 +} from '@/config/api.js';
  5 +
  6 +const state = () => ({
  7 + loginInfo: {},
  8 + userInfo: {},
  9 + userBasicInfo: {},
  10 +})
  11 +
  12 +const getters = {
  13 +
  14 +}
  15 +
  16 +// actions
  17 +const actions = {
  18 +
  19 + async login({
  20 + commit,
  21 + dispatch,
  22 + state
  23 + }, params) {
  24 + const login_result = await postTokenApi({
  25 + ...params
  26 + }, {
  27 + custom: {
  28 + auth: false
  29 + }
  30 + });
  31 +
  32 + console.log(login_result)
  33 +
  34 + if (login_result) {
  35 +
  36 + await commit('setLogin', login_result);
  37 +
  38 + switch (login_result.status) {
  39 +
  40 + case 'not_reg': //未注册
  41 + uni.$u.route({
  42 + url: '/pages/student/my/login/login',
  43 + type: 'reLaunch',
  44 + });
  45 + break;
  46 +
  47 + case 'annulled': //已注销
  48 + uni.$u.route({
  49 + url: '/pages/student/my/written-off/written-off',
  50 + type: 'navigateTo',
  51 + });
  52 + break;
  53 +
  54 + case 'annulling': //注销中
  55 + uni.$u.route({
  56 + url: '/pages/student/my/freezing/freezing',
  57 + type: 'navigateTo',
  58 + });
  59 + break;
  60 +
  61 + case 'active': //已注册
  62 + const userInfo = await dispatch(`getUserInfo`);
  63 + if (userInfo?.teacher) {
54 64 uni.$u.route({
55   - url: '/pages/student/my/login/login',
56   - type: 'reLaunch',
57   - });
58   - break;
  65 + url: 'pages/tabBar/home/home',
  66 + type: 'switchTab',
  67 + params: {
59 68
60   - case 'annulled': //已注销
61   - uni.$u.route({
62   - url: '/pages/student/my/written-off/written-off',
63   - type: 'navigateTo',
64   - });
65   - break;
  69 + }
  70 + })
  71 + }
66 72
67   - case 'annulling': //注销中
68   - uni.$u.route({
69   - url: '/pages/student/my/freezing/freezing',
70   - type: 'navigateTo',
71   - });
72   - break;
73   -
74   - case 'active': //已注册
75   - const userInfo = await dispatch(`getUserInfo`);
76   -
77   - // if (userInfo) {
78   - // const {
79   - // student = {}
80   - // } = userInfo;
81   - // if (student && JSON.stringify(student) != '{}' && student.status == 'verified') {
82   - // uni.$u.route({
83   - // url: 'pages/student/tabBar/internship/internship',
84   - // type: 'switchTab',
85   - // params: {
86   -
87   - // }
88   - // })
89   -
90   - // } else {
91   - // uni.$u.route({
92   - // url: `/pages/student/my/student-status-certification/student-status-certification`,
93   - // type: 'reLaunch',
94   - // params: {
95   -
96   - // }
97   - // })
98   - // }
99   - // }
100   -
101   - break;
102   - }
103   -
104   - return login_result;
  73 + break;
105 74 }
106 75
  76 + return login_result;
  77 + }
  78 +
  79 +
  80 +
  81 +
  82 + },
  83 +
  84 + async loginOut({
  85 + commit,
  86 + dispatch,
  87 + state
  88 + }, params) {
  89 +
  90 + await commit('setLoginOut', {});
  91 + uni.$u.route('/pages/main/my/login/login');
  92 + },
  93 +
  94 + async getUserInfo({
  95 + commit,
  96 + dispatch,
  97 + state
  98 + }, params) {
  99 +
  100 + const result = await getUserInfoApi();
  101 +
  102 + commit('setUserInfo', result);
  103 +
  104 + uni.$u.vuex('vuex_user', result);
  105 +
  106 + return result;
  107 + },
  108 +}
  109 +
  110 +// mutations
  111 +const mutations = {
  112 +
  113 + setLogin(state, result) {
  114 + let vuex_token = `Bearer ${result.access_token}`
  115 + uni.$u.vuex('vuex_token', vuex_token);
  116 + uni.$u.vuex('refresh_token', result.refresh_token);
  117 + uni.$u.vuex('vuex_phone', result.phone);
  118 + uni.$u.vuex('hasLogin', true);
  119 + },
  120 +
  121 + setLoginOut(state, result) {
  122 + uni.$u.vuex('vuex_token', '');
  123 + uni.$u.vuex('vuex_phone', '');
  124 + uni.$u.vuex('vuex_user', {});
  125 + uni.$u.vuex('hasLogin', false);
  126 + },
  127 +
  128 + setUserInfo(state, result) {
  129 + state.userInfo = result;
  130 + },
  131 +
  132 +
  133 +
  134 +}
107 135
108   - },
109   -
110   - async loginOut({
111   - commit,
112   - dispatch,
113   - state
114   - }, params) {
115   -
116   - await uni.$u.vuex('vuex_user', {});
117   - await uni.$u.vuex('vuex_token', {});
118   - await uni.setStorageSync('lifeData', {});
119   -
120   - uni.$u.route('/pages/student/my/login/login');
121   - },
122   -
123   - async getUserInfo({
124   - commit,
125   - dispatch,
126   - state
127   - }, params) {
128   -
129   - const userInfo = await getUserInfoApi();
130   -
131   - uni.$u.vuex('vuex_user', userInfo);
132   -
133   - return userInfo;
134   - },
135   - }
136   -
137   - // mutations
138   - const mutations = {
139   -
140   - setUserInfo(state, userInfo) {
141   - state.id = userInfo.id;
142   - state.name = userInfo.name;
143   - state.phone = userInfo.phone;
144   - state.username = userInfo.username;
145   - state.userBasicInfo = userInfo.userBasicInfo;
146   - },
147   - }
148   -
149   - export default {
150   - namespaced: true,
151   - state,
152   - getters,
153   - actions,
154   - mutations
155   - }
  136 +export default {
  137 + namespaced: true,
  138 + state,
  139 + getters,
  140 + actions,
  141 + mutations
  142 +}
... ...
  1 +<template>
  2 + <view>
  3 + <view class="mi_calendar">
  4 + <view class="top-bar">
  5 + <i class="top-change-month" @click="changeMonth('prev')" />
  6 + <view class="top-bar-ym">{{ y }}.{{ m < 10 ? `0${m}` : m }}</view>
  7 + <i v-show="m == new Date().getMonth() + 1" :style="{ opacity: '0.3' }"
  8 + class="top-change-month next-month" />
  9 + <i v-show="m != new Date().getMonth() + 1" class="top-change-month next-month"
  10 + @click="changeMonth('next')" />
  11 + </view>
  12 + <view class="week">
  13 + <view class="week-day" v-for="(item, index) in weekDay" :key="index">{{ item }}</view>
  14 + </view>
  15 + <view :class="{ hide: !monthOpen }" class="content" :style="{ height: height }">
  16 + <view :style="{ top: positionTop + 'rpx' }" class="days">
  17 + <view :class="['item', { nolm: !item.lm }]" v-for="(item, index) in dates" :key="index">
  18 + <view class="day" :key="`${item.year}-${item.month + 1}-${item.date}`"
  19 + @click="selectOne(item, $event)"
  20 + :class="{ choose: choose == `${item.year}-${item.month}-${item.date}` }">
  21 + {{ item.date }}
  22 + </view>
  23 + <view class="flag_icon late" v-if="filterType('LEAVE', item.year, item.month, item.date)">
  24 + </view>
  25 + <view class="flag_icon truancy"
  26 + v-if="filterType('SUSPENSION', item.year, item.month, item.date)"></view>
  27 + <view class="flag_icon normal" v-if="filterType('NORMAL', item.year, item.month, item.date)">
  28 + </view>
  29 + <!-- <view class="today-text" v-if="isToday(item.year, item.month, item.date)">{{ text.today }}</view> -->
  30 + </view>
  31 + </view>
  32 + </view>
  33 + </view>
  34 + <!-- <view class="type-check">
  35 + <view class="label" v-for="(item, index) in statusText" :key="index"><i></i><text>{{ item }}</text></view>
  36 + </view> -->
  37 + </view>
  38 +</template>
  39 +
  40 +<script>
  41 + export default {
  42 + name: 'mi-calendar',
  43 + props: {
  44 + // 第一列星期几
  45 + weekstart: {
  46 + type: Number,
  47 + default: 1
  48 + },
  49 + // 请假日期
  50 + leaveDateList: {
  51 + type: Array,
  52 + default: () => []
  53 + },
  54 + // 停课日期
  55 + suspensionDateList: {
  56 + type: Array,
  57 + default: () => []
  58 + },
  59 + // 正常考勤日期
  60 + normalDateList: {
  61 + type: Array,
  62 + default: () => []
  63 + },
  64 + // 是否展开 暂未实现
  65 + open: {
  66 + type: Boolean,
  67 + default: true
  68 + }
  69 + },
  70 + data() {
  71 + return {
  72 + statusText: ['出勤', '请假', '停课'],
  73 + text: {
  74 + year: '年',
  75 + month: '月',
  76 + week: ['一', '二', '三', '四', '五', '六', '日'],
  77 + today: '今'
  78 + },
  79 + y: new Date().getFullYear(), // 年
  80 + // m: new Date().getMonth() >= 10 ? new Date().getMonth() + 1 : `0${new Date().getMonth() + 1}`, // 月
  81 + m: new Date().getMonth() + 1,
  82 + dates: [], // 当前月日期集合
  83 + positionTop: 0,
  84 + monthOpen: true,
  85 + choose: ''
  86 + };
  87 + },
  88 + created() {
  89 + this.dates = this.monthDay(this.y, this.m);
  90 + // console.log(this.y, this.m);
  91 + // !this.open && this.trgWeek();
  92 + },
  93 + mounted() {
  94 + const date = new Date();
  95 + const y = date.getFullYear();
  96 + const m = date.getMonth() + 1;
  97 + const d = date.getDate();
  98 + this.choose = `${y}-${m}-${d}`;
  99 + },
  100 + computed: {
  101 + // 顶部星期栏目
  102 + weekDay() {
  103 + return this.text.week.slice(this.weekstart - 1).concat(this.text.week.slice(0, this.weekstart - 1));
  104 + },
  105 + height() {
  106 + return (this.dates.length / 7) * 80 + 'rpx';
  107 + }
  108 + },
  109 + methods: {
  110 + // 获取当前月份天数
  111 + monthDay(y, m) {
  112 + let firstDayOfMonth = new Date(y, m - 1, 1).getDay(); // 当月第一天星期几
  113 + let lastDateOfMonth = new Date(y, m, 0).getDate(); // 当月最后一天
  114 + let lastDayOfLastMonth = new Date(y, m - 1, 0).getDate(); // 上一月的最后一天
  115 + let dates = []; // 所有渲染日历
  116 + let weekstart = this.weekstart == 7 ? 0 : this.weekstart; // 方便进行日期计算,默认星期从0开始
  117 + let startDay = (() => {
  118 + // 周初有几天是上个月的
  119 + if (firstDayOfMonth == weekstart) {
  120 + return 0;
  121 + } else if (firstDayOfMonth > weekstart) {
  122 + return firstDayOfMonth - weekstart;
  123 + } else {
  124 + return 7 - weekstart + firstDayOfMonth;
  125 + }
  126 + })();
  127 + let endDay = 7 - ((startDay + lastDateOfMonth) % 7); // 结束还有几天是下个月的
  128 + for (let i = 1; i <= startDay; i++) {
  129 + const date = lastDayOfLastMonth - startDay + i;
  130 + dates.push({
  131 + date,
  132 + day: weekstart + i - 1 || 7,
  133 + month: m - 1 >= 0 ? m - 1 : 12,
  134 + year: m - 1 >= 0 ? y : y - 1
  135 + });
  136 + }
  137 + for (let j = 1; j <= lastDateOfMonth; j++) {
  138 + dates.push({
  139 + date: j,
  140 + day: (j % 7) + firstDayOfMonth - 1 || 7,
  141 + month: m,
  142 + year: y,
  143 + lm: true
  144 + });
  145 + }
  146 + for (let k = 1; k <= endDay; k++) {
  147 + dates.push({
  148 + date: k,
  149 + day: (lastDateOfMonth + startDay + weekstart + k - 1) % 7 || 7,
  150 + month: m + 1 <= 11 ? m + 1 : 0,
  151 + year: m + 1 <= 11 ? y : y + 1
  152 + });
  153 + }
  154 + return dates;
  155 + },
  156 + getFormatString(m) {
  157 + return m >= 10 ? m : `0${m}`;
  158 + },
  159 + filterType(type, y, m, d) {
  160 + const opt = {
  161 + LEAVE: 'leaveDateList', // 请假
  162 + SUSPENSION: 'suspensionDateList', // 停课
  163 + NORMAL: 'normalDateList' // 出勤
  164 + };
  165 + const list = opt[type];
  166 + const dataList = this[list];
  167 + let flag = false;
  168 + for (let i = 0; i < dataList.length; i++) {
  169 + const M = this.getFormatString(m);
  170 + const D = this.getFormatString(d);
  171 + const dy = `${y}-${M}-${D}`;
  172 + if (dataList[i] == dy) {
  173 + flag = true;
  174 + break;
  175 + }
  176 + }
  177 + return flag;
  178 + },
  179 + isToday(y, m, d) {
  180 + let date = new Date();
  181 + return y == date.getFullYear() && m == date.getMonth() + 1 && d == date.getDate();
  182 + },
  183 + // 切换成周模式
  184 + trgWeek() {
  185 + this.monthOpen = !this.monthOpen;
  186 + if (this.monthOpen) {
  187 + this.positionTop = 0;
  188 + } else {
  189 + let index = -1;
  190 + this.dates.forEach((i, x) => {
  191 + this.isToday(i.year, i.month, i.date) && (index = x);
  192 + });
  193 + this.positionTop = -((Math.ceil((index + 1) / 7) || 1) - 1) * 80;
  194 + }
  195 + },
  196 + // 点击回调
  197 + selectOne({
  198 + year,
  199 + month,
  200 + date
  201 + }, event) {
  202 + let date_time = `${year}-${this.getFormatString(month)}-${this.getFormatString(date)}`;
  203 + if (month != this.m) {
  204 + console.log('不在可选范围内');
  205 + return false;
  206 + }
  207 + this.choose = `${year}-${month}-${date}`;
  208 + this.$emit('change', date_time);
  209 + },
  210 + // 月份切换
  211 + changeMonth(action) {
  212 + if (action === 'next') {
  213 + if (this.m == 12) {
  214 + this.m = 1;
  215 + this.y++;
  216 + } else {
  217 + this.m++;
  218 + }
  219 + } else {
  220 + if (this.m == 1) {
  221 + this.m = 12;
  222 + this.y--;
  223 + } else {
  224 + this.m--;
  225 + }
  226 + }
  227 + this.dates = this.monthDay(this.y, this.m);
  228 + this.$emit(`changeMonth`, this.y, this.m);
  229 + }
  230 + }
  231 + };
  232 +</script>
  233 +
  234 +<style lang="scss" scoped>
  235 + $working: #80b2ff;
  236 + $leave: #ffcd3c;
  237 + $suspend: #f46864;
  238 +
  239 + .mi_calendar {
  240 + color: #1a1a1a;
  241 + font-size: 28rpx;
  242 + text-align: center;
  243 + padding: 30rpx 10rpx;
  244 + margin: 20rpx 30rpx;
  245 + background-color: #fff;
  246 + border-radius: 12rpx;
  247 + box-shadow: 0 3rpx 32rpx 0rpx rgba(0, 0, 0, 0.1);
  248 + overflow: hidden;
  249 +
  250 + .top-bar {
  251 + display: flex;
  252 + height: 80rpx;
  253 + align-items: center;
  254 + justify-content: center;
  255 +
  256 + .top-bar-ym {
  257 + font-size: 32rpx;
  258 + height: 80rpx;
  259 + width: 120rpx;
  260 + line-height: 80rpx;
  261 + }
  262 +
  263 + .top-change-month {
  264 + width: 23rpx;
  265 + height: 13rpx;
  266 + background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC4AAAAaCAYAAADIUm6MAAAAAXNSR0IArs4c6QAAA95JREFUWEfN1ktsG0UYB/D/Z+9sQlWgvCVOHDhEtpeGRogDr0OqtLQU75YaRIsgBwpUIEBFaSsVqkKpeBQQiPdLBESLwDTeJS0vNQdAFQIpEGltKwcOnJBKBLRVSeOdtT80Jo2cYI8fcVrmZu1/vu/n2dnZpVQK0XDc2M5M/QDOI+JvOWo85I5N/Yr/wbC7Oy+jYvgSM10P4C8iHjS6wt1kx80nQPzYLCPxb1FEevf7wfiZtN9imV1FlEbAdOksB9MushNiAsCFVYBHiiXqHc4HuTOBd64wE1ziQwAuqdJ/QsH/BrCoBm4CJfS5eTl2OvF2THQjgq8BXFSj7yTZcbEXhPUa2J8g9Lm+HD0deNsSPeAy+vya/Rj7yOnCBWyIEQBLNbCjXMJKLy9/WEh8Miaupgi+BLBE02eMQrmcVGAar/7lMs2E4xHmVUO58PBC4J24cS0THQRwjqb+TxTKvsw4/ijD1bC7sQShUPirNBNPEPFNGT/8pp14xzJuYKYDABZr6v4IQ65wx3BUZWbg6keqB+cGBXGQgGs0BSaZOOn5oXri5z2SlrGcmDzNAQEGDpsdcnV6FMdONZwFL+NjWCxJfA7CdRrVSWJem8mFaj+2PJy4sZKJhgCcpXkQvxMsV6XzOFGZ+Q9cXVzTg0XRKfEZCL0aVcAcWeflCsOtyJPxjjVEpU8BmBr0SLFT3jw8ism5marwGXzBHAJ4hQ5PoNsz2UCtWsPDSZhrGfyRFg36SpwdOOnvcbJa4ZpwFb7xcnSYneZ+Aq/WqEKANrjZ4JNG5HbCvBXgvQCM2nk6UJgK1n3xCwq1Mlr49J43ZcT4GCBbAysC1O9mgw91eDth3gHwIIBo7Ry7ohTels4j0NWqC1eT7+mB+L0g1CqldHgmbPR8+V61jG2JfjDe0aORvrhDbnhrFLLe3WsIXl75FKIyLz6o83nATNjk+fLNysZJS9xLjNfnHr+zcIx9IibvTKdRrIdW1xuGz+DHxbtg3KUpziA86PryFZVx4uJ+JrxcBz0oYvLuRtFNw9WEnUDkZ0u8QYyNWjx4gAjMTM/p0Ex4+0pf3rcTKDWy0qcyTa14RWH1OfwqgE3NNKuSfc3NygcA9XJsbrQKL98t2xIvgPFwcy2n04QXXV9ubgXd0laZi0wmzGcJPNAMnkF7vGywpZk5c7PzWfGZWsmE+SSBtzcCYdBuLxs82khWl2kLvHx6WMYOZnpcCyLe4frhrvmi27JVKhGOZWxjpqeqwZh4m+eHz7QD3Xa4KmgnjEcA2lNxBDLAA242fL5d6AWBl/H/vt6fLjdgbM3k5PvtRKta/wD9BFRsxb0ftAAAAABJRU5ErkJggg==') no-repeat bottom center;
  267 + background-size: 23rpx 13rpx;
  268 + transform: rotate(90deg);
  269 + margin: 0 30rpx;
  270 + }
  271 +
  272 + .next-month {
  273 + transform: rotate(-90deg);
  274 + }
  275 + }
  276 +
  277 + .week {
  278 + display: flex;
  279 + align-items: center;
  280 + height: 80rpx;
  281 + line-height: 80rpx;
  282 +
  283 + view {
  284 + flex: 1;
  285 + }
  286 +
  287 + .week-day {
  288 + font-size: 26rpx;
  289 + color: #1a1a1a;
  290 + }
  291 + }
  292 +
  293 + .content {
  294 + position: relative;
  295 + overflow: hidden;
  296 + transition: height 0.4s ease;
  297 +
  298 + .days {
  299 + transition: top 0.3s;
  300 + display: flex;
  301 + align-items: center;
  302 + flex-wrap: wrap;
  303 + position: relative;
  304 +
  305 + .item {
  306 + position: relative;
  307 + display: block;
  308 + height: 80rpx;
  309 + line-height: 80rpx;
  310 + width: calc(100% / 7);
  311 +
  312 + .day {
  313 + font-style: normal;
  314 + display: inline-block;
  315 + vertical-align: middle;
  316 + width: 60rpx;
  317 + height: 60rpx;
  318 + line-height: 60rpx;
  319 + overflow: hidden;
  320 + border-radius: 50%;
  321 +
  322 + &.choose {
  323 + background: #06B079;
  324 + color: #FFF;
  325 + }
  326 + }
  327 +
  328 + &.nolm {
  329 + color: #999;
  330 + opacity: 0.3;
  331 + }
  332 +
  333 + .flag_icon {
  334 + bottom: 0;
  335 + left: 50%;
  336 + font-style: normal;
  337 + width: 12rpx;
  338 + height: 12rpx;
  339 + border-radius: 6rpx;
  340 + position: absolute;
  341 + margin-left: -6rpx;
  342 + pointer-events: none;
  343 + }
  344 +
  345 + .late {
  346 + background: #ffcd3c;
  347 + }
  348 +
  349 + .truancy {
  350 + background: #06B079;
  351 + }
  352 +
  353 + .normal {
  354 + background: #80b2ff;
  355 + }
  356 +
  357 + .today-text {
  358 + position: absolute;
  359 + font-size: 20rpx;
  360 + font-weight: normal;
  361 + width: 20rpx;
  362 + height: 20rpx;
  363 + line-height: 20rpx;
  364 + right: 0;
  365 + top: 10rpx;
  366 + color: #fff;
  367 + }
  368 + }
  369 + }
  370 + }
  371 +
  372 + .hide {
  373 + height: 80rpx !important;
  374 + }
  375 +
  376 + .weektoggel {
  377 + width: 80rpx;
  378 + height: 40rpx;
  379 + margin: 10rpx auto 0;
  380 +
  381 + &.down {
  382 + transform: rotate(180deg);
  383 + }
  384 + }
  385 + }
  386 +
  387 + .type-check {
  388 + overflow: hidden;
  389 + margin: 0 24rpx;
  390 + text-align: right;
  391 +
  392 + .label {
  393 + display: inline-block;
  394 + margin-right: 24rpx;
  395 +
  396 + i {
  397 + display: inline-block;
  398 + width: 10rpx;
  399 + height: 10rpx;
  400 + border-radius: 50%;
  401 + vertical-align: middle;
  402 + margin-right: 10rpx;
  403 + }
  404 +
  405 + text {
  406 + color: #1a1a1a;
  407 + font-size: 26rpx;
  408 + }
  409 +
  410 + &:nth-child(1) {
  411 + i {
  412 + background-color: $working;
  413 + }
  414 + }
  415 +
  416 + &:nth-child(2) {
  417 + i {
  418 + background-color: $leave;
  419 + }
  420 + }
  421 +
  422 + &:nth-child(3) {
  423 + i {
  424 + background-color: $suspend;
  425 + }
  426 + }
  427 + }
  428 + }
  429 +</style>
... ...
  1 +
  2 +## mi-calendar 使用帮助
  3 +
  4 +### 快速开始
  5 +使用 uni_modules 安装 (目前仅支持 uni_modules)
  6 +
  7 +下载该文件后,放到uni_modules文件下,然后直接页面使用。
  8 +
  9 +<mi-calendar :leaveDateList="[`2022-1-2`,`2022-1-4`]" :suspensionDateList="[`2022-01-05`]" :normalDateList="[`2022-1-3`]"></mi-calendar>
  10 +
  11 +## leaveDateList
  12 +请假日期
  13 +## suspensionDateList
  14 +停课日期
  15 +## normalDateList
  16 +正常考勤日期
  17 +
  18 +## change 切换日期
  19 +`@change="change"`
  20 +```
  21 +change(date){
  22 + console.log(date); // 日期 eg:'2022-01-01'
  23 +}
  24 +```
  25 +
  26 +## changeMonth 切换月份
  27 +`@change="change"`
  28 +```
  29 +changeMonth(year, month){
  30 + console.log(year, month); // 日期 eg:2022, 6
  31 +}
  32 +```
  33 +
  34 +
... ...
  1 +{
  2 + "id": "mi-calendar",
  3 + "displayName": "考勤日历",
  4 + "version": "1.0.0",
  5 + "description": "考勤日历",
  6 + "repository": "https://github.com/quyapeng/mi-calendar",
  7 + "keywords": [
  8 + "考勤",
  9 + "日历",
  10 + "教学"
  11 + ],
  12 + "dcloudext": {
  13 + "category": [
  14 + "前端组件",
  15 + "通用组件"
  16 + ]
  17 + }
  18 +}
... ...
... ... @@ -253,6 +253,8 @@ export default {
253 253 this.monthNum,
254 254 this.getMonths(minDate, maxDate)
255 255 )
  256 +
  257 + console.log('months...',months)
256 258 // 先清空数组
257 259 this.months = []
258 260 for (let i = 0; i < months; i++) {
... ...
... ... @@ -194,7 +194,8 @@
194 194 const formItemProps = this.children.map(
195 195 (item) => item.prop
196 196 );
197   - this.validateField(formItemProps, (errors) => {
  197 + this.validateField(formItemProps, (errors) => {
  198 +
198 199 if(errors.length) {
199 200 // 如果错误提示方式为toast,则进行提示
200 201 this.errorType === 'toast' && uni.$u.toast(errors[0].message)
... ...
... ... @@ -34,7 +34,7 @@
34 34 'background-color': disabled ? 'transparent' : '#fff',
35 35 }"
36 36 v-if="count"
37   - >{{ innerValue.length }}/{{ maxlength }}</text
  37 + >{{ innerValue.length || 0 }}/{{ maxlength }}</text
38 38 >
39 39 </view>
40 40 </template>
... ...
注册登录 后发表评论