提交 9f0dc82d authored 作者: 刘旭's avatar 刘旭

更新ui设计

上级 9ec04e56
<script setup lang="ts">
import { onLaunch, onShow, onHide } from "@dcloudio/uni-app"
import { onLaunch, onShow, onHide } from "@dcloudio/uni-app";
</script>
<style lang="scss">
@import "./static/iconfont/iconfont.css";
@import "./scss/common.scss";
@import "vk-uview-ui/index.scss";
.uni-tabbar {
max-width: 420px;
margin: 0 auto;
border-left: #f6f6f6 solid 1px;
border-right: #f6f6f6 solid 1px;
}
page {
background: #f5f5f5;
background: #fbfcff;
font-family: PingFang SC-Medium, PingFang SC;
}
</style>
import request from "@/utils/request";
/**
* @brief 查询讲师列表
* @param data
* @return
*/
export const getLecturerList = (data: any) =>
request(
"/LQKJ.K3.PeiXunSystem.WebApi.WebApiService.TeacList,LQKJ.K3.PeiXunSystem.WebApi.common.kdsvc",
"POST",
data
);
......@@ -115,6 +115,20 @@
"navigationBarTitleText": "现场教学点",
"onReachBottomDistance": 50
}
},
{
"path": "pages/lecturer/index",
"style": {
"navigationBarTitleText": "讲师列表",
"onReachBottomDistance": 50
}
},
{
"path": "pages/trainingEvaluation/index",
"style": {
"navigationBarTitleText": "培训评价",
"onReachBottomDistance": 50
}
}
],
"globalStyle": {
......
......@@ -2,6 +2,7 @@
<!-- <headers title="班级通讯录" /> -->
<view class="address-book-item-container">
<uni-search-bar
v-show="addressBookList.length"
placeholder="姓名/单位/电话"
bgColor="#ffffff"
clearButton="auto"
......@@ -10,14 +11,12 @@
@clear="clear"
/>
<view v-if="addressBookList.length">
<text style="margin-bottom: 20rpx; display: block"
>为你找到{{ listQuery.total }}个的同学</text
>
<text class="fund">为您找到{{ listQuery.total }}位同学</text>
<block v-for="(item, i) in addressBookList" :key="i">
<addressBookItem
:addressBookItem="item"
buttonTitle="联系TA"
buttonTitle=""
@tapButton="tapButton"
/>
</block>
......@@ -25,19 +24,23 @@
<u-loadmore :status="status" icon-type="flower" />
</view>
</view>
<view v-else class="empty">
<u-empty text="暂无数据" mode="list"></u-empty>
</view>
<u-empty
v-else
text="暂无数据~"
icon-size="506"
:margin-top="220"
src="../../static/img/noData.png"
></u-empty>
</view>
</template>
<script setup lang="ts">
// import headers from "@/components/header/index.vue"
import addressBookItem from "./components/addressBookItem.vue"
import { getClassBook } from "@/api/class"
import { useGlobalStore } from "@/store/useStore"
import addressBookItem from "./components/addressBookItem.vue";
import { getClassBook } from "@/api/class";
import { useGlobalStore } from "@/store/useStore";
const globalStore = useGlobalStore()
const globalStore = useGlobalStore();
const listQuery = reactive({
Phone: globalStore.Phone,
classId: "",
......@@ -46,60 +49,55 @@ const listQuery = reactive({
total: 0,
type: 2,
Name: "",
})
const status = ref("loadmore")
const addressBookList = ref([] as any)
});
const status = ref("loadmore");
const addressBookList = ref([] as any);
onLoad((options: any) => {
listQuery.classId = options.classId
init()
})
listQuery.classId = options.classId;
init();
});
const search = (val: any) => {
listQuery.Name = val.value
init()
}
listQuery.Name = val.value;
init();
};
const clear = () => {
addressBookList.value = []
listQuery.Name = ""
init()
}
addressBookList.value = [];
listQuery.Name = "";
init();
};
const tapButton = (phone: string) => {
location.href = "tel:" + phone
}
location.href = "tel:" + phone;
};
const init = async () => {
status.value = "loading"
const { data: res } = await getClassBook(listQuery)
status.value = "loading";
const { data: res } = await getClassBook(listQuery);
if (res.code == 200) {
if (res.total > 10) status.value = "loadmore"
else status.value = "nomore"
addressBookList.value = [...addressBookList.value, ...res.data]
listQuery.total = res.total
if (res.total > 10) status.value = "loadmore";
else status.value = "nomore";
addressBookList.value = [...addressBookList.value, ...res.data];
listQuery.total = res.total;
}
}
};
// 上拉加载数据
onReachBottom(() => {
// 判断是否还有下一页数据
if (listQuery.pageIndex * listQuery.pageSize >= listQuery.total)
return (status.value = "nomore")
return (status.value = "nomore");
// // 判断是否正在请求其它数据,如果是,则不发起额外的请求
if (status.value === "loading") return
listQuery.pageIndex += 1
init()
})
if (status.value === "loading") return;
listQuery.pageIndex += 1;
init();
});
</script>
<style lang="scss" scoped>
.address-book-item-container {
padding: 0 30rpx;
box-sizing: border-box;
.uni-searchbar {
padding: 0;
margin: 20rpx 0;
}
}
</style>
<template>
<!-- <headers title="我的班级" /> -->
<u-tabs
:list="tabsState.list"
:is-scroll="false"
v-model="tabsState.current"
bg-color="#f5f5f5"
@change="tabsChange"
/>
<uni-search-bar
placeholder="姓名/单位/电话"
bgColor="#ffffff"
clearButton="auto"
cancelButton="none"
@confirm="search"
@clear="clear"
/>
<view v-if="addressBookList.length" class="address-book-item-container">
<text style="margin-bottom: 20rpx; display: block"
>为你找到{{ listQuery.total }}个的同学</text
>
<block v-for="(item, i) in addressBookList" :key="i">
<addressBookItem
:addressBookItem="item"
:buttonTitle="tabsState.current ? '' : '查看评价'"
@tapButton="tapButton"
/>
</block>
<view style="padding: 20rpx">
<u-loadmore :status="status" icon-type="flower" />
<view style="padding: 0 32rpx 168rpx">
<u-tabs
:list="tabsState.list"
:is-scroll="false"
v-model="tabsState.current"
:active-item-style="{ fontSize: '34rpx', color: '#000000' }"
font-size="28"
bar-width="72"
bar-height="6"
bg-color="#fbfcff"
inactive-color="#cecfcf"
active-color="#05a8ff"
@change="tabsChange"
/>
<uni-search-bar
placeholder="姓名/单位/电话"
bgColor="#ffffff"
clearButton="auto"
cancelButton="none"
@confirm="search"
@clear="clear"
/>
<view v-if="addressBookList.length">
<text class="fund">为您找到{{ listQuery.total }}位同学</text>
<block v-for="(item, i) in addressBookList" :key="i">
<addressBookItem
:addressBookItem="item"
:buttonTitle="tabsState.current ? '' : '查看评价'"
@tapButton="tapButton"
/>
</block>
<view style="padding: 20rpx">
<u-loadmore :status="status" icon-type="flower" />
</view>
</view>
</view>
<view v-else class="empty">
<u-empty text="暂无数据" mode="list"></u-empty>
<u-empty
v-else
text="暂无数据~"
icon-size="506"
:margin-top="220"
src="../../static/img/noData.png"
></u-empty>
</view>
</template>
<script setup lang="ts">
// import headers from "@/components/header/index.vue"
import addressBookItem from "./components/addressBookItem.vue"
import { getClassBook } from "@/api/class"
import { useGlobalStore } from "@/store/useStore"
import addressBookItem from "./components/addressBookItem.vue";
import { getClassBook } from "@/api/class";
import { useGlobalStore } from "@/store/useStore";
const globalStore = useGlobalStore()
const globalStore = useGlobalStore();
const listQuery = reactive({
Phone: globalStore.Phone,
classId: "",
courseId: '',
courseId: "",
pageIndex: 1,
pageSize: 10,
total: 0,
type: 0,
Name: "",
})
});
const tabsState = reactive({
list: [
......@@ -64,70 +74,59 @@ const tabsState = reactive({
},
],
current: 0,
})
const status = ref("loadmore")
const addressBookList = ref([] as any)
});
const status = ref("loadmore");
const addressBookList = ref([] as any);
onLoad((options: any) => {
listQuery.classId = options.classId
init()
})
listQuery.classId = options.classId;
init();
});
const search = (val: any) => {
listQuery.Name = val.value
tabsChange(tabsState.current)
}
listQuery.Name = val.value;
tabsChange(tabsState.current);
};
const clear = () => {
listQuery.Name = ""
tabsChange(tabsState.current)
}
listQuery.Name = "";
tabsChange(tabsState.current);
};
const tabsChange = (index: number) => {
addressBookList.value = []
listQuery.pageIndex = 1
listQuery.pageSize = 10
addressBookList.value = [];
listQuery.pageIndex = 1;
listQuery.pageSize = 10;
if (index) {
listQuery.type = 1
} else listQuery.type = 0
init()
}
listQuery.type = 1;
} else listQuery.type = 0;
init();
};
const tapButton = (classId: string, studentId: string) => {
uni.navigateTo({
url: "/pages/class/evaluate?classId=" + classId + "&studentId=" + studentId,
})
}
});
};
const init = async () => {
status.value = "loading"
const { data: res } = await getClassBook(listQuery)
status.value = "loading";
const { data: res } = await getClassBook(listQuery);
if (res.code == 200) {
if (res.total > 10) status.value = "loadmore"
else status.value = "nomore"
addressBookList.value = res.data
listQuery.total = res.total
if (res.total > 10) status.value = "loadmore";
else status.value = "nomore";
addressBookList.value = res.data;
listQuery.total = res.total;
}
}
};
// 上拉加载数据
onReachBottom(() => {
// 判断是否还有下一页数据
if (listQuery.pageIndex * listQuery.pageSize >= listQuery.total)
return (status.value = "nomore")
return (status.value = "nomore");
// // 判断是否正在请求其它数据,如果是,则不发起额外的请求
if (status.value === "loading") return
listQuery.pageIndex += 1
init()
})
if (status.value === "loading") return;
listQuery.pageIndex += 1;
init();
});
</script>
<style lang="scss" scoped>
.address-book-item-container {
padding: 0 30rpx;
.uni-searchbar {
padding: 0;
margin: 20rpx 0;
}
}
</style>
......@@ -5,22 +5,30 @@
<view class="address-book-content">
<view class="left">
<u-image
width="160rpx"
height="160rpx"
width="92rpx"
height="92rpx"
shape="circle"
:src="baseUrl + '/' + addressBookItem.proPhoto"
></u-image>
<view class="content">
<h4>{{ addressBookItem.stuName }}</h4>
<view class="stu-name">{{ addressBookItem.stuName }}</view>
<text class="tel">{{ addressBookItem.Phone }}</text>
<text>单位: {{ addressBookItem.stuUnit }}</text>
<text class="tel">单位:{{ addressBookItem.stuUnit }}</text>
</view>
</view>
<u-image
v-if="!buttonTitle"
width="96rpx"
height="52rpx"
src="../../../static/img/phone2.png"
@tap="tapButton"
></u-image>
<u-button
v-show="buttonTitle"
size="mini"
type="primary"
v-else
hover-class="background-color: #04a7ff; color: #ffffff"
@tap="tapButton"
>{{ buttonTitle }}
>
<view>{{ buttonTitle }}</view>
</u-button>
</view>
</template>
......@@ -29,8 +37,7 @@
</template>
<script setup lang="ts">
import { src } from "@/utils/example"
import { baseUrl } from "@/utils/request"
import { baseUrl } from "@/utils/request";
const props = defineProps({
addressBookItem: {
......@@ -38,26 +45,33 @@ const props = defineProps({
default: () => [],
} as any,
buttonTitle: String,
})
});
const emits = defineEmits(["tapButton"])
const emits = defineEmits(["tapButton"]);
const tapButton = () => {
if (props.buttonTitle === "联系TA")
emits("tapButton", props.addressBookItem.Phone)
else
console.log(props.buttonTitle);
if (props.buttonTitle) {
emits(
"tapButton",
props.addressBookItem.FCLASS,
props.addressBookItem.studentId
)
}
);
} else {
location.href = "tel:" + props.addressBookItem.Phone;
// emits("tapButton", props.addressBookItem.Phone);
}
};
</script>
<style lang="scss" scoped>
.address-book-container {
margin-bottom: 32rpx;
height: 200rpx;
height: 152rpx;
:deep(.u-card__body) {
padding: 16rpx 32rpx !important;
}
.address-book-content {
display: flex;
......@@ -66,21 +80,42 @@ const tapButton = () => {
.left {
display: flex;
align-items: center;
.content {
display: flex;
flex-direction: column;
justify-content: flex-end;
margin-left: 20rpx;
color: #909399;
font-size: 26rpx;
.stu-name {
font-size: 28rpx;
font-weight: 500;
color: #000000;
margin-bottom: 8rpx;
}
.tel {
margin: 20rpx 0;
margin-bottom: 4rpx;
font-size: 24rpx;
font-weight: 400;
color: rgba(34, 34, 34, 0.5);
height: 34rpx;
line-height: 28rpx;
}
}
}
uni-button {
.u-btn {
margin: 0;
width: 160rpx;
height: 72rpx;
background: #05a8ff;
border-radius: 8rpx;
font-size: 28rpx;
color: #ffffff;
}
}
}
......
<template>
<view class="arrange-item-container">
<h3>
<view class="opening-time">
&nbsp;{{ dayjs(arrangeItem.startDate).format("YYYY-MM-DD") }}&nbsp;&nbsp;
{{
dateFormat(arrangeItem.startDate) +
"~" +
dateFormat(arrangeItem.endDate)
}}
</h3>
</view>
<u-card :show-head="false" margin="0">
<template #body>
<view class="arrange-header">
<h3>{{ arrangeItem.courseName }}</h3>
<u-button size="mini" plain :type="arrangeStatus.type">{{
arrangeStatus.detail
}}</u-button>
</view>
<view class="item">
<u-icon name="account" />
<text>&nbsp;{{ arrangeItem.teachName }}</text>
</view>
<view class="item">
<u-icon name="map" />
<text>&nbsp;{{ arrangeItem.classArea }}&nbsp;</text>
</view>
</template>
<template #foot>
<view class="arrange-footer" @tap="openInfo">
<u-icon name="order" />
<text>课件资料</text>
<view class="body">
<view>
<view class="arrange-header">
<h3>{{ arrangeItem.courseName }}</h3>
</view>
<view class="item" style="margin: 32rpx 0 24rpx">
<u-icon size="32" name="account" />
<text v-for="(item, i) in arrangeItem.Teachs" :key="i">
&nbsp;{{ item.teachName }}&nbsp;
</text>
</view>
<view class="item">
<u-icon size="32" name="map" />
<text>&nbsp;{{ arrangeItem.classArea }}&nbsp;</text>
</view>
</view>
<view class="courseware">
<view>
<u-badge
type="error"
size="mini"
:count="6"
:offset="[-4, -4]"
></u-badge>
<u-icon
name="file-text-fill"
color="#05a8ff"
size="40"
class="courseware-icon"
@tap="openInfo"
></u-icon>
</view>
<view class="desc">课程资料{{ arrangeItem.FileCount }}</view>
</view>
<view
:type="arrangeStatus.type"
:class="arrangeStatus.type"
class="body-right"
>
{{ arrangeStatus.detail }}
</view>
</view>
</template>
</u-card>
......@@ -41,87 +63,116 @@
</template>
<script setup lang="ts">
import infoPopup from "@/pages/course/components/infoPopup.vue"
import dayjs from "dayjs"
import infoPopup from "@/pages/course/components/infoPopup.vue";
import dayjs from "dayjs";
const props = defineProps({
arrangeItem: {
type: Array,
default: () => [],
} as any,
})
});
const show = ref(false)
const infoRef = ref()
const arrangeDetail = ["未开始", "上课中", "已下课"]
const show = ref(false);
const infoRef = ref();
const arrangeDetail = ["未开始", "上课中", "已下课"];
const arrangeStatus = computed(() => {
const statusObj = {
type: "",
detail: "",
}
};
switch (props.arrangeItem.courseType) {
case 0:
statusObj.type = "warning"
break
statusObj.type = "warning";
break;
case 1:
statusObj.type = "primary"
break
statusObj.type = "primary";
break;
case 2:
statusObj.type = "info"
break
statusObj.type = "info";
break;
}
statusObj.detail = arrangeDetail[props.arrangeItem.courseType]
return statusObj
})
statusObj.detail = arrangeDetail[props.arrangeItem.courseType];
return statusObj;
});
const dateFormat = (dateStr: string) => {
// 创建一个日期对象,传入特定日期和时间
const date = new Date(dateStr)
const date = new Date(dateStr);
// 获取小时和分钟
const hours = ("0" + date.getHours()).slice(-2)
const minutes = ("0" + date.getMinutes()).slice(-2)
const hours = ("0" + date.getHours()).slice(-2);
const minutes = ("0" + date.getMinutes()).slice(-2);
// 构建时间字符串
const time = hours + ":" + minutes
return time
}
const time = hours + ":" + minutes;
return time;
};
const openInfo = () => {
show.value = true
infoRef.value.init()
}
show.value = true;
infoRef.value.init();
};
</script>
<style lang="scss" scoped>
.arrange-item-container {
h3 {
margin-bottom: 32rpx;
// :deep(.u-card__body) {
// padding: 40rpx 32rpx !important;
// }
.opening-time {
margin-bottom: 24rpx;
font-size: 28rpx;
font-weight: 400;
color: rgba(0, 0, 0, 0.6);
}
.arrange-header {
.body {
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
h3 {
margin: 0;
.arrange-header {
display: flex;
justify-content: space-between;
align-items: center;
h3 {
margin: 0;
font-size: 34rpx;
font-weight: 500;
color: #222222;
}
uni-button {
margin: 0;
}
}
uni-button {
margin: 0;
.body-right {
position: absolute;
bottom: -29rpx;
right: -29rpx;
text-align: center;
font-size: 24rpx;
color: #2979ff;
background: #e4e4e4;
border-radius: 24rpx 0rpx 24rpx 0rpx;
padding: 4rpx 16rpx;
}
.info {
color: #82848a;
background-color: #e4e4e4;
}
.success {
color: #19be6b;
background-color: #deffd9;
}
}
.item {
margin: 20rpx 0;
}
.arrange-footer {
text-align: end;
text {
color: #2979ff;
}
font-size: 28rpx;
font-weight: 400;
color: rgba(34, 34, 34, 0.9);
}
}
</style>
<template>
<view class="class-item-container">
<u-card :show-head="false" margin="0" border-radius="20">
<u-card :show-head="false" margin="0" border-radius="24">
<template #body>
<view class="calss-header">
<h3>{{ classItem.className }}</h3>
<u-button
<!-- <u-button
v-show="current == 2"
size="mini"
type="primary"
@tap="toEvaluate"
>查看评价</u-button
>
> -->
</view>
<view class="item">
<text>课程时间:</text>
......@@ -20,31 +20,55 @@
<text>教室地点:</text>
<text>{{ classItem.classArea }}</text>
</view>
<view> </view>
<view class="progress item">
<view class="class-progress item">
<text>课程进度:</text>
<u-line-progress
active-color="#2979ff"
active-color="#5363ff"
:percent="percent ? percent : 0"
:height="25"
:show-percent="false"
:height="20"
style="margin-top: 10rpx"
/>
<view class="progress">
{{
(props.classItem.coursePro[0]?.SumPro
? props.classItem.coursePro[0]?.SumPro
: "0") +
"/" +
props.classItem.courseSum[0]?.Sum
}}
</view>
</view>
<view class="class-teacher item">
<text>班主任:</text>
<u-tag
v-for="(item, index) in classItem.Management"
:key="index"
:text="item.teachName"
shape="circle"
/>
<view>
<view
v-for="(item, index) in classItem.Management"
:key="index"
class="btn"
@tap="contact(item.teacPhone)"
>
<u-image src="../../../static/img/phone.png" />
<view>{{ item.teachName }}</view>
</view>
</view>
</view>
</template>
<template #foot>
<view class="class-footer">
<u-button size="mini" plain @tap="toAddressBook">班级通讯录</u-button>
<u-button size="mini" plain @tap="classQrCode">班级二维码</u-button>
<u-button type="primary" size="mini" plain @tap="toCourseArrange"
<!-- @tap="toAddressBook" -->
<u-button size="mini" shape="circle" @tap="toEvaluate"
>班级通讯录</u-button
>
<u-button size="mini" shape="circle" @tap="classQrCode"
>班级二维码</u-button
>
<u-button
size="mini"
shape="circle"
hover-class="background-color: #04a7ff; color: #ffffff"
style="background-color: #04a7ff; color: #ffffff"
@tap="toCourseArrange"
>课程安排</u-button
>
</view>
......@@ -61,7 +85,7 @@
</template>
<script setup lang="ts">
import saveQrCode from "./saveQrCode.vue"
import saveQrCode from "./saveQrCode.vue";
const props = defineProps({
classItem: {
......@@ -72,52 +96,61 @@ const props = defineProps({
type: Number,
default: 0,
},
})
});
const emits = defineEmits(["init"])
const emits = defineEmits(["init"]);
const show = ref(false)
const show = ref(false);
const percent = computed(
() =>
(props.classItem.coursePro[0]?.SumPro / props.classItem.courseSum[0].Sum) *
100
)
);
const classQrCode = () => {
show.value = true
}
show.value = true;
};
const toAddressBook = () => {
uni.navigateTo({
url: "/pages/class/addressBook?classId=" + props.classItem.classId,
})
}
});
};
const toCourseArrange = () => {
uni.navigateTo({
url: "/pages/class/courseArrange?classId=" + props.classItem.classId,
})
}
});
};
const toEvaluate = () => {
uni.navigateTo({
url: "/pages/class/classEvaluate?classId=" + props.classItem.classId,
})
}
});
};
const contact = (tel: string) => {
location.href = "tel:" + tel;
};
</script>
<style lang="scss" scoped>
.class-item-container {
margin-bottom: 20rpx;
margin-bottom: 32rpx;
:deep(.u-card__body) {
padding: 40rpx 32rpx 18rpx !important;
}
.calss-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16rpx;
margin-bottom: 32rpx;
h3 {
margin: 0;
font-size: 34rpx;
font-weight: 500;
color: #222222;
}
uni-button {
......@@ -128,11 +161,13 @@ const toEvaluate = () => {
.item {
display: flex;
align-items: flex-start;
margin-bottom: 24rpx;
text {
display: block;
padding: 12rpx 0;
font-size: 28rpx;
font-weight: 400;
color: rgba(34, 34, 34, 0.9);
}
text:first-child {
......@@ -144,10 +179,19 @@ const toEvaluate = () => {
}
}
.progress {
.class-progress {
display: flex;
align-items: center;
.progress {
margin-left: 10px;
margin-top: 8rpx;
}
.u-progress {
margin-left: 20rpx;
}
text {
white-space: nowrap;
}
......@@ -162,8 +206,21 @@ const toEvaluate = () => {
display: flex;
align-items: center;
.u-tag {
margin-right: 20rpx;
.btn {
height: 56rpx;
padding: 14rpx 36rpx 14rpx 14rpx;
background: #04a7ff;
border-radius: 112rpx;
color: #ffffff;
display: flex;
align-items: center;
justify-content: center;
.u-image {
margin-right: 6rpx;
width: 50rpx !important;
height: 46rpx !important;
}
}
}
......@@ -172,9 +229,9 @@ const toEvaluate = () => {
display: flex;
justify-content: flex-end;
uni-button {
margin-left: 30rpx;
margin-right: 0;
.u-btn {
height: 56rpx;
margin: 0 16rpx 0 0;
}
}
}
......
......@@ -3,50 +3,51 @@
v-model="props.show"
mode="center"
closeable
border-radius="15"
width="80%"
border-radius="40"
@close="handleClose"
>
<view class="qrcode">
<view class="title">班级二维码</view>
<view class="image">
<u-image
width="100%"
height="500rpx"
:src="baseUrl + '/' + Url"
ref="canvasRef"
/>
<u-image width="100%" height="100%" :src="baseUrl + '/' + Url" />
<view class="refresh" @tap="updateImage">
<u-icon name="reload" color="#000000" size="32"></u-icon>
</view>
</view>
<view class="detail"
><text
>扫描二维码快速进入班级群或截图保存二维码微信识别进入班级群</text
></view
>
</view>
<view class="footer">
<!-- <view class="footer">
<u-button type="primary" size="medium" @tap="updateImage"
>更新二维码</u-button
>
<!-- <u-button type="success" size="medium" @tap="saveImage"
<u-button type="primary" size="medium" @tap="saveImage"
>保存二维码</u-button
> -->
</view>
>
</view> -->
</u-popup>
</template>
<script setup lang="ts">
import { baseUrl } from "@/utils/request"
import { toast } from "@/utils/util"
import { baseUrl } from "@/utils/request";
import { toast } from "@/utils/util";
const props = defineProps({
show: Boolean,
classId: Number,
Url: String,
})
const emits = defineEmits(["init", "update:modelValue"])
});
const canvasRef = ref()
const emits = defineEmits(["init", "update:modelValue"]);
const updateImage = () => {
uni.chooseImage({
count: 1,
success: (chooseImageRes) => {
const tempFilePaths = chooseImageRes.tempFilePaths
const tempFilePaths = chooseImageRes.tempFilePaths;
uni.uploadFile({
url:
baseUrl +
......@@ -57,64 +58,110 @@ const updateImage = () => {
classId: props.classId,
},
success: ({ data }: any) => {
const res = JSON.parse(data)
const res = JSON.parse(data);
if (res.code == 200) {
emits("init")
emits("update:modelValue", false)
toast("更新成功")
emits("init");
emits("update:modelValue", false);
toast("更新成功");
}
},
})
});
},
})
}
});
};
const saveImage = () => {
downloadImage(baseUrl + "/" + props.Url)
// downloadFile(baseUrl + "/" + props.Url, "image.jpg")
}
downloadImage(baseUrl + "/" + props.Url);
// downloadFile(baseUrl + "/" + props.Url, "image.jpg");
};
function downloadFile(fileURL: string, fileName: string) {
fetch(fileURL)
.then((response) => response.blob())
.then((blob) => {
const downloadUrl = URL.createObjectURL(blob)
const link = document.createElement("a")
link.href = downloadUrl
link.download = fileName
link.click()
URL.revokeObjectURL(downloadUrl)
})
const downloadUrl = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = downloadUrl;
link.download = fileName;
link.click();
URL.revokeObjectURL(downloadUrl);
});
}
function downloadImage(url: string) {
const link = document.createElement("a")
link.href = url
link.download = "image.jpg"
link.style.display = "none"
const link = document.createElement("a");
link.href = url;
link.download = "image.jpg";
link.style.display = "none";
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
const handleClose = () => emits("update:modelValue", false);
</script>
<style lang="scss" scoped>
:deep(.u-mode-center-box) {
background-color: transparent;
}
:deep(.u-iconfont::before) {
margin-top: 50rpx;
}
.qrcode {
padding: 24rpx;
background-image: url("../../../static/img/bg2.png");
background-repeat: no-repeat;
background-size: cover;
padding: 24rpx 32rpx;
background-color: #fff;
border-bottom-right-radius: 15rpx;
border-bottom-left-radius: 15rpx;
.title {
font-size: larger;
font-weight: bolder;
font-size: 34rpx;
font-weight: 500;
color: #000000;
margin-top: 50rpx;
}
.image {
padding: 46rpx;
position: relative;
width: 350rpx;
height: 330rpx;
margin-top: 44rpx;
margin: 44rpx 125rpx;
.refresh {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background-color: #ffffff;
width: 48rpx;
height: 48rpx;
display: flex;
align-items: center;
justify-content: center;
}
:deep(.u-iconfont::before) {
margin-top: 0;
}
}
.detail {
text-align: center;
margin-bottom: 60rpx;
text {
display: block;
width: 520rpx;
height: 68rpx;
margin: 0 40rpx;
font-size: 24rpx;
font-weight: 400;
color: #bcbcbc;
line-height: 28rpx;
}
}
}
.footer {
......
<template>
<!-- <headers title="课程安排" /> -->
<view class="course-arrange-container">
<view class="progress">
<text>课程进</text>
<view class="course-arrange-progress">
<text>课程进</text>
<u-line-progress
active-color="#2979ff"
active-color="#5363ff"
:percent="percent ? percent : 0"
:height="25"
:show-percent="false"
:height="20"
style="margin-top: 10rpx"
/>
<view class="progress">
{{
(totalPercentage ? totalPercentage : "0") + "/" + arrangeList.length
}}
</view>
</view>
<view v-if="arrangeList.length">
<u-time-line>
<u-time-line-item v-for="(item, index) in arrangeList" :key="index">
<template #node>
<view class="u-node">
<view class="u-dot"></view>
</view>
<u-icon name="clock-fill" color="#909399" />
</template>
<template #content>
<arrangeItem :arrangeItem="item" />
......@@ -33,70 +37,77 @@
</template>
<script setup lang="ts">
// import headers from "@/components/header/index.vue"
import arrangeItem from "./components/arrangeItem.vue"
import { getTeachCourse } from "@/api/course"
import arrangeItem from "./components/arrangeItem.vue";
import { getTeachCourse } from "@/api/course";
const arrangeList = ref([] as any)
const percent = ref()
const arrangeList = ref([] as any);
const percent = ref();
const totalPercentage = ref();
const listQuery = reactive({
pageIndex: 1,
pageSize: 10,
pageSize: 999,
total: 0,
classId: "",
Name: "",
})
});
const status = ref("loadmore")
const status = ref("loadmore");
onLoad((options: any) => {
listQuery.classId = options.classId
init()
})
listQuery.classId = options.classId;
init();
});
// 上拉加载数据
onReachBottom(() => {
// 判断是否还有下一页数据
if (listQuery.pageIndex * listQuery.pageSize >= listQuery.total)
return (status.value = "nomore")
return (status.value = "nomore");
// 判断是否正在请求其它数据,如果是,则不发起额外的请求
if (status.value === "loading") return
listQuery.pageIndex += 1
init()
})
if (status.value === "loading") return;
listQuery.pageIndex += 1;
init();
});
const init = async () => {
status.value = "loading"
const { data: res } = await getTeachCourse(listQuery)
status.value = "loading";
const { data: res } = await getTeachCourse(listQuery);
if (res.code == 200) {
if (res.total > 10) status.value = "loadmore"
else status.value = "nomore"
arrangeList.value = [...arrangeList.value, ...res.data]
listQuery.total = res.total
let num: number = res.data.filter(
if (res.total > 10) status.value = "loadmore";
else status.value = "nomore";
arrangeList.value = [...arrangeList.value, ...res.data];
listQuery.total = res.total;
totalPercentage.value = res.data.filter(
(item: any) => item.courseType === 2
).length
percent.value = (num / res.total) * 100
).length;
percent.value = (totalPercentage.value / res.total) * 100;
// console.log(arrangeList.value)
}
}
};
</script>
<style lang="scss" scoped>
.course-arrange-container {
padding: 0 20rpx;
padding-right: 32rpx;
margin-left: 32rpx;
.progress {
.course-arrange-progress {
display: flex;
align-items: center;
justify-content: center;
padding: 26rpx 10rpx 50rpx 30rpx;
padding: 32rpx 0 56rpx;
width: 90%;
.progress {
margin-left: 10px;
margin-top: 8rpx;
}
text {
display: block;
padding: 12rpx 0;
font-size: 32rpx;
white-space: nowrap;
font-size: 28rpx;
font-weight: 400;
color: rgba(34, 34, 34, 0.9);
margin-top: 6rpx;
}
.registered {
......@@ -104,14 +115,6 @@ const init = async () => {
color: #3b99fc;
}
}
.u-dot {
height: 22rpx;
width: 22rpx;
border-radius: 3.125rem;
background: #2979ff;
box-shadow: 0 0 10px rgba(0, 0, 0.6, 0.412);
}
}
:deep(uni-modal) {
z-index: 99999 !important;
......
......@@ -5,7 +5,13 @@
:list="tabsState.list"
:is-scroll="false"
v-model="tabsState.current"
bg-color="#f5f5f5"
:active-item-style="{ fontSize: '34rpx', color: '#000000' }"
font-size="28"
bar-width="72"
bar-height="6"
bg-color="#fbfcff"
inactive-color="#cecfcf"
active-color="#05a8ff"
@change="tabsChange"
/>
<!-- 搜索 -->
......@@ -19,9 +25,7 @@
/>
<!-- 内容 -->
<view v-if="classList.length">
<text style="margin-bottom: 20rpx; display: block"
>为你找到{{ listQuery.total }}个的班级</text
>
<text class="fund">为您找到{{ listQuery.total }}个班级</text>
<block v-for="(item, index) in classList" :key="index">
<classItem
......@@ -34,19 +38,23 @@
<u-loadmore :status="status" icon-type="flower" />
</view>
</view>
<view v-else class="empty">
<u-empty text="暂无数据" mode="list"></u-empty>
</view>
<u-empty
v-else
text="暂无数据~"
icon-size="506"
:margin-top="220"
src="../../static/img/noData.png"
></u-empty>
</view>
</template>
<script setup lang="ts">
// import headers from "@/components/header/index.vue"
import classItem from "./components/classItem.vue"
import { getClassList } from "@/api/class"
import { useGlobalStore } from "@/store/useStore"
import classItem from "./components/classItem.vue";
import { getClassList } from "@/api/class";
import { useGlobalStore } from "@/store/useStore";
const globalStore = useGlobalStore()
const globalStore = useGlobalStore();
const tabsState = reactive({
list: [
......@@ -61,9 +69,9 @@ const tabsState = reactive({
},
],
current: 0,
})
});
const classList = ref([] as any)
const classList = ref([] as any);
const listQuery = reactive({
Phone: globalStore.Phone,
......@@ -72,70 +80,65 @@ const listQuery = reactive({
pageSize: 10,
total: 0,
Name: "",
})
});
const status = ref("loadmore")
const status = ref("loadmore");
const tabsChange = (index: number) => {
classList.value = []
listQuery.pageIndex = 1
listQuery.pageSize = 10
classList.value = [];
listQuery.pageIndex = 1;
listQuery.pageSize = 10;
switch (index) {
case 0:
listQuery.type = 1
break
listQuery.type = 1;
break;
case 1:
listQuery.type = 0
break
listQuery.type = 0;
break;
default:
listQuery.type = 2
break
listQuery.type = 2;
break;
}
init()
}
init();
};
const search = (val: any) => {
listQuery.Name = val.value
tabsChange(tabsState.current)
}
listQuery.Name = val.value;
tabsChange(tabsState.current);
};
const clear = () => {
listQuery.Name = ""
tabsChange(tabsState.current)
}
listQuery.Name = "";
tabsChange(tabsState.current);
};
// 上拉加载数据
onReachBottom(() => {
// 判断是否还有下一页数据
if (listQuery.pageIndex * listQuery.pageSize >= listQuery.total)
return (status.value = "nomore")
return (status.value = "nomore");
// // 判断是否正在请求其它数据,如果是,则不发起额外的请求
if (status.value === "loading") return
listQuery.pageIndex += 1
init()
})
if (status.value === "loading") return;
listQuery.pageIndex += 1;
init();
});
const init = async () => {
status.value = "loading"
const { data: res } = await getClassList(listQuery)
status.value = "loading";
const { data: res } = await getClassList(listQuery);
if (res.code == 200) {
if (res.total > 10) status.value = "loadmore"
else status.value = "nomore"
classList.value = [...classList.value, ...res.data]
listQuery.total = res.total
if (res.total > 10) status.value = "loadmore";
else status.value = "nomore";
classList.value = [...classList.value, ...res.data];
listQuery.total = res.total;
}
}
};
tabsChange(tabsState.current)
tabsChange(tabsState.current);
</script>
<style lang="scss" scoped>
.class-container {
padding: 0 30rpx 30rpx;
.uni-searchbar {
padding: 0;
margin: 20rpx 0;
}
padding: 0 32rpx 168rpx;
}
</style>
......@@ -21,9 +21,7 @@
/>
</view> -->
<view v-if="detailList.length">
<text style="margin-bottom: 20rpx; display: block"
>为你找到{{ listQuery.total }}个的班级</text
>
<text class="fund">为您找到{{ listQuery.total }}位同学</text>
<block v-for="(item, index) in detailList" :key="index">
<detailsItem :detailItem="item" @init="refresh" />
......@@ -39,8 +37,8 @@
</template>
<script setup lang="ts">
import { getStateList } from "@/api/course"
import detailsItem from "./components/detailsItem.vue"
import { getStateList } from "@/api/course";
import detailsItem from "./components/detailsItem.vue";
const tagList = ref([
{ type: "primary", name: "全部" },
......@@ -48,9 +46,9 @@ const tagList = ref([
{ type: "info", name: "缺勤" },
{ type: "info", name: "请假" },
{ type: "info", name: "补签" },
])
]);
const detailList = ref([] as any)
const detailList = ref([] as any);
const listQuery = reactive({
courseId: "",
......@@ -58,58 +56,58 @@ const listQuery = reactive({
pageSize: 10,
total: 0,
Name: "",
})
});
const status = ref("loadmore")
const status = ref("loadmore");
// 上拉加载数据
onReachBottom(() => {
// 判断是否还有下一页数据
if (listQuery.pageIndex * listQuery.pageSize >= listQuery.total)
return (status.value = "nomore")
return (status.value = "nomore");
// // 判断是否正在请求其它数据,如果是,则不发起额外的请求
if (status.value === "loading") return
listQuery.pageIndex += 1
init()
})
if (status.value === "loading") return;
listQuery.pageIndex += 1;
init();
});
const changeTagType = (index: number) => {
tagList.value.map((item: any, i: number) => {
if (index === i) item.type = "primary"
else item.type = "info"
})
}
if (index === i) item.type = "primary";
else item.type = "info";
});
};
const search = (val: any) => {
listQuery.Name = val.value
init()
}
listQuery.Name = val.value;
init();
};
const clear = () => {
listQuery.Name = ""
init()
}
listQuery.Name = "";
init();
};
const init = async () => {
status.value = "loading"
const { data: res } = await getStateList(listQuery)
status.value = "loading";
const { data: res } = await getStateList(listQuery);
if (res.code == 200) {
if (res.total > 10) status.value = "loadmore"
else status.value = "nomore"
detailList.value = [...detailList.value, ...res.data]
listQuery.total = res.total
if (res.total > 10) status.value = "loadmore";
else status.value = "nomore";
detailList.value = [...detailList.value, ...res.data];
listQuery.total = res.total;
}
}
};
const refresh = () => {
detailList.value = []
init()
}
detailList.value = [];
init();
};
onLoad((options: any) => {
listQuery.courseId = options.courseId
init()
})
listQuery.courseId = options.courseId;
init();
});
</script>
<style lang="scss" scoped>
......
......@@ -5,22 +5,30 @@
<view class="address-book-content">
<view class="left">
<u-image
width="160rpx"
height="160rpx"
width="92rpx"
height="92rpx"
shape="circle"
:src="baseUrl + '/' + addressBookItem.proPhoto"
></u-image>
<view class="content">
<h4>{{ addressBookItem.stuName }}</h4>
<view class="stu-name">{{ addressBookItem.stuName }}</view>
<text class="tel">{{ addressBookItem.Phone }}</text>
<text>单位: {{ addressBookItem.stuUnit }}</text>
<text class="tel">单位:{{ addressBookItem.stuUnit }}</text>
</view>
</view>
<u-image
v-if="!buttonTitle"
width="96rpx"
height="52rpx"
src="../../../static/img/phone2.png"
@tap="tapButton"
></u-image>
<u-button
v-show="buttonTitle"
size="mini"
type="primary"
v-else
hover-class="background-color: #04a7ff; color: #ffffff"
@tap="tapButton"
>{{ buttonTitle }}
>
<view>{{ buttonTitle }}</view>
</u-button>
</view>
</template>
......@@ -29,8 +37,7 @@
</template>
<script setup lang="ts">
import { src } from "@/utils/example"
import { baseUrl } from "@/utils/request"
import { baseUrl } from "@/utils/request";
const props = defineProps({
addressBookItem: {
......@@ -38,27 +45,31 @@ const props = defineProps({
default: () => [],
} as any,
buttonTitle: String,
})
});
const emits = defineEmits(["tapButton"])
const emits = defineEmits(["tapButton"]);
const tapButton = () => {
if (props.buttonTitle === "联系TA")
emits("tapButton", props.addressBookItem.Phone)
if (!props.buttonTitle) location.href = "tel:" + props.addressBookItem.Phone;
// emits("tapButton", props.addressBookItem.Phone)
else
emits(
"tapButton",
props.addressBookItem.FCLASS,
props.addressBookItem.studentId,
props.addressBookItem.courseId
)
}
);
};
</script>
<style lang="scss" scoped>
.address-book-container {
margin-bottom: 32rpx;
height: 200rpx;
height: 152rpx;
:deep(.u-card__body) {
padding: 16rpx 32rpx !important;
}
.address-book-content {
display: flex;
......@@ -67,21 +78,42 @@ const tapButton = () => {
.left {
display: flex;
align-items: center;
.content {
display: flex;
flex-direction: column;
justify-content: flex-end;
margin-left: 20rpx;
color: #909399;
font-size: 26rpx;
.stu-name {
font-size: 28rpx;
font-weight: 500;
color: #000000;
margin-bottom: 8rpx;
}
.tel {
margin: 20rpx 0;
margin-bottom: 4rpx;
font-size: 24rpx;
font-weight: 400;
color: rgba(34, 34, 34, 0.5);
height: 34rpx;
line-height: 28rpx;
}
}
}
uni-button {
.u-btn {
margin: 0;
width: 160rpx;
height: 72rpx;
background: #05a8ff;
border-radius: 8rpx;
font-size: 28rpx;
color: #ffffff;
}
}
}
......
......@@ -7,7 +7,12 @@
@close="close"
>
<view class="u_card">
<u-card :title="'学员' + label">
<u-card
:title="'学员' + label"
:show-head="false"
margin="0"
border-radius="20"
>
<template #body>
<view>学员姓名:{{ name }}</view>
<u-form :model="formData" label-position="top">
......@@ -48,37 +53,37 @@
</template>
<script setup lang="ts">
import { toast } from "@/utils/util"
import { toast } from "@/utils/util";
const props = defineProps({
show: Boolean,
name: String,
label: String,
radio: String,
})
});
const emits = defineEmits(["update:modelValue", "submit"])
const emits = defineEmits(["update:modelValue", "submit"]);
const formData = reactive({
radio: "",
reason: "",
})
});
const submit = () => {
if (!formData.reason) return toast("请输入" + props.label)
emits("submit", formData.reason)
}
if (!formData.reason) return toast("请输入" + props.label);
emits("submit", formData.reason);
};
const close = () => {
formData.reason = ""
}
formData.reason = "";
};
const init = (radio: string) => {
formData.radio = radio
}
formData.radio = radio;
};
defineExpose({
init,
})
});
</script>
<style lang="scss" scoped>
......
......@@ -3,40 +3,58 @@
v-model="props.show"
mode="bottom"
closeable
safe-area-inset-bottom
height="40%"
border-radius="30"
@close="handeClose"
>
<view class="info">
<block v-if="infoList.length">
<text class="title">课件资料</text>
<view v-for="(item, i) in infoList" :key="i" class="item">
<view>
<u-icon name="order" size="50"></u-icon>
<text>{{ item.name }}</text>
</view>
<view>
<u-icon
name="eye-fill"
size="50"
style="margin-right: 30rpx"
@tap="pdfView(item)"
></u-icon>
<u-icon name="download" size="50" @tap="downLoadPdf(item)"></u-icon>
<view style="width: 100%">
<view class="title">课程资料</view>
<view v-if="infoList.length">
<view v-for="(item, i) in infoList" :key="i" class="item">
<view>
<!-- <u-icon name="order" size="50"></u-icon> -->
<u-image
src="../../../static/img/PDF.png"
width="35"
height="40"
></u-image>
<view class="pdf-name">{{ item.name }}</view>
</view>
<view>
<u-image
src="../../../static/img/Check.png"
width="35"
height="40"
style="margin-right: 30rpx"
@tap="pdfView(item)"
></u-image>
<u-image
src="../../../static/img/download.png"
width="35"
height="40"
@tap="downLoadPdf(item)"
></u-image>
</view>
</view>
</view>
</block>
<view v-else class="empty">
<u-empty text="暂无资料" mode="list" />
<u-empty
v-else
text="暂无数据~"
icon-size="300"
:margin-top="100"
src="../../static/img/noData.png"
></u-empty>
</view>
</view>
</u-popup>
</template>
<script setup lang="ts">
import { zconfirm } from "@/utils/util"
import { getFileList } from "@/api/course"
import { baseUrl } from "@/utils/request"
import { zconfirm } from "@/utils/util";
import { getFileList } from "@/api/course";
import { baseUrl } from "@/utils/request";
const props = defineProps({
show: {
......@@ -47,9 +65,9 @@ const props = defineProps({
type: String,
default: "",
},
})
});
const emits = defineEmits(["update:show"])
const emits = defineEmits(["update:show"]);
const pdfView = (item: any) => {
uni.navigateTo({
......@@ -58,38 +76,41 @@ const pdfView = (item: any) => {
item.name +
"&url=" +
encodeURIComponent(baseUrl + "/" + item.url),
})
}
success: () => {
handeClose();
},
});
};
const infoList = ref([] as any)
const infoList = ref([] as any);
const downLoadPdf = (item: any) => {
zconfirm("确定下载课资料?", (result: boolean) => {
zconfirm("确定下载课资料?", (result: boolean) => {
if (result) {
const url = baseUrl + "/" + item.url
const a = document.createElement("a")
a.href = url
a.download = item.name
a.click()
const url = baseUrl + "/" + item.url;
const a = document.createElement("a");
a.href = url;
a.download = item.name;
a.click();
}
})
}
});
};
const handeClose = () => {
emits("update:show", false)
}
emits("update:show", false);
};
const init = async () => {
const { data: res } = await getFileList({ courseNumber: props.courseNumber })
const { data: res } = await getFileList({ courseNumber: props.courseNumber });
if (res.code == 200) {
console.log(res)
infoList.value = res.data
// console.log(res)
infoList.value = res.data;
}
}
};
defineExpose({
init,
})
});
</script>
<style lang="scss" scoped>
......@@ -97,19 +118,18 @@ defineExpose({
display: flex;
flex-direction: column;
align-items: center;
padding: 0 30rpx;
padding: 0 32rpx;
.title {
// position: sticky;
// top: 0;
// left: 0;
height: 90rpx;
line-height: 90rpx;
font-size: 32rpx;
font-weight: bolder;
color: $u-main-color;
text-align: center;
width: 100%;
margin-bottom: 48rpx;
margin-top: 30rpx;
height: 48rpx;
font-size: 34rpx;
font-weight: 500;
color: #222222;
line-height: 40rpx;
}
.item {
......@@ -117,30 +137,37 @@ defineExpose({
display: flex;
justify-content: space-between;
align-items: center;
background-color: $u-type-info-light;
width: 100%;
height: 100rpx;
padding: 30rpx;
padding: 20rpx 40rpx;
border-radius: 10rpx;
margin-bottom: 20rpx;
// height: 88rpx;
background: #ffffff;
box-shadow: 0rpx 8rpx 60rpx 0rpx rgba(0, 0, 0, 0.05);
border-radius: 16rpx;
view {
display: flex;
align-items: center;
text {
margin-left: 10rpx;
display: block;
font-size: 32rpx;
color: #000000;
.pdf-name {
margin-left: 22rpx;
font-size: 28rpx;
font-weight: 400;
color: rgba(34, 34, 34, 0.9);
}
}
}
}
</style>
<style>
<style lang="scss" scoped>
:deep(uni-modal) {
z-index: 19999 !important;
}
:deep(.uni-scroll-view-content) {
background-color: #fbfcff;
}
</style>
<template>
<!-- <headers title="我的班级" /> -->
<u-tabs
:list="tabsState.list"
:is-scroll="false"
v-model="tabsState.current"
bg-color="#f5f5f5"
@change="tabsChange"
/>
<uni-search-bar
placeholder="姓名/单位/电话"
bgColor="#ffffff"
clearButton="auto"
cancelButton="none"
@confirm="search"
@clear="clear"
/>
<view v-if="addressBookList.length" class="address-book-item-container">
<text style="margin-bottom: 20rpx; display: block"
>为你找到{{ listQuery.total }}个的同学</text
>
<block v-for="(item, i) in addressBookList" :key="i">
<addressBookItem
:addressBookItem="item"
:buttonTitle="tabsState.current ? '' : '查看评价'"
@tapButton="tapButton"
/>
</block>
<view style="padding: 20rpx">
<u-loadmore :status="status" icon-type="flower" />
<view style="padding: 0 32rpx 168rpx">
<u-tabs
:list="tabsState.list"
:is-scroll="false"
v-model="tabsState.current"
:active-item-style="{ fontSize: '34rpx', color: '#000000' }"
font-size="28"
bar-width="72"
bar-height="6"
bg-color="#fbfcff"
inactive-color="#cecfcf"
active-color="#05a8ff"
@change="tabsChange"
/>
<uni-search-bar
placeholder="姓名/单位/电话"
bgColor="#ffffff"
clearButton="auto"
cancelButton="none"
@confirm="search"
@clear="clear"
/>
<view v-if="addressBookList.length">
<text class="fund">为您找到{{ listQuery.total }}位同学</text>
<block v-for="(item, i) in addressBookList" :key="i">
<addressBookItem
:addressBookItem="item"
:buttonTitle="tabsState.current ? '' : '查看评价'"
@tapButton="tapButton"
/>
</block>
<view style="padding: 20rpx">
<u-loadmore :status="status" icon-type="flower" />
</view>
</view>
</view>
<view v-else class="empty">
<u-empty text="暂无数据" mode="list"></u-empty>
<u-empty
v-else
text="暂无数据~"
icon-size="506"
:margin-top="220"
src="../../static/img/noData.png"
></u-empty>
</view>
</template>
<script setup lang="ts">
// import headers from "@/components/header/index.vue"
import addressBookItem from "./components/addressBookItem.vue"
import { getClassBook } from "@/api/class"
import { useGlobalStore } from "@/store/useStore"
import addressBookItem from "./components/addressBookItem.vue";
import { getClassBook } from "@/api/class";
import { useGlobalStore } from "@/store/useStore";
const globalStore = useGlobalStore()
const globalStore = useGlobalStore();
const listQuery = reactive({
Phone: globalStore.Phone,
......@@ -52,7 +61,7 @@ const listQuery = reactive({
total: 0,
type: 0,
Name: "",
})
});
const tabsState = reactive({
list: [
......@@ -64,35 +73,35 @@ const tabsState = reactive({
},
],
current: 0,
})
const status = ref("loadmore")
const addressBookList = ref([] as any)
});
const status = ref("loadmore");
const addressBookList = ref([] as any);
onLoad((options: any) => {
listQuery.classId = options.classId
listQuery.courseId = options.courseId
init()
})
listQuery.classId = options.classId;
listQuery.courseId = options.courseId;
init();
});
const search = (val: any) => {
listQuery.Name = val.value
tabsChange(tabsState.current)
}
listQuery.Name = val.value;
tabsChange(tabsState.current);
};
const clear = () => {
listQuery.Name = ""
tabsChange(tabsState.current)
}
listQuery.Name = "";
tabsChange(tabsState.current);
};
const tabsChange = (index: number) => {
addressBookList.value = []
listQuery.pageIndex = 1
listQuery.pageSize = 10
addressBookList.value = [];
listQuery.pageIndex = 1;
listQuery.pageSize = 10;
if (index) {
listQuery.type = 1
} else listQuery.type = 0
init()
}
listQuery.type = 1;
} else listQuery.type = 0;
init();
};
const tapButton = (classId: string, studentId: string, courseId: string) => {
uni.navigateTo({
......@@ -103,38 +112,33 @@ const tapButton = (classId: string, studentId: string, courseId: string) => {
courseId +
"&studentId=" +
studentId,
})
}
});
};
const init = async () => {
status.value = "loading"
const { data: res } = await getClassBook(listQuery)
status.value = "loading";
const { data: res } = await getClassBook(listQuery);
if (res.code == 200) {
if (res.total > 10) status.value = "loadmore"
else status.value = "nomore"
addressBookList.value = res.data
listQuery.total = res.total
if (res.total > 10) status.value = "loadmore";
else status.value = "nomore";
addressBookList.value = res.data;
listQuery.total = res.total;
}
}
};
// 上拉加载数据
onReachBottom(() => {
// 判断是否还有下一页数据
if (listQuery.pageIndex * listQuery.pageSize >= listQuery.total)
return (status.value = "nomore")
return (status.value = "nomore");
// // 判断是否正在请求其它数据,如果是,则不发起额外的请求
if (status.value === "loading") return
listQuery.pageIndex += 1
init()
})
if (status.value === "loading") return;
listQuery.pageIndex += 1;
init();
});
</script>
<style lang="scss" scoped>
.address-book-item-container {
padding: 0 30rpx;
.uni-searchbar {
padding: 0;
margin: 20rpx 0;
}
}
</style>
<template>
<!-- <headers title="培训评价" /> -->
<view class="evaluate-container">
<u-card :show-head="false" :show-foot="false" margin="0" border-radius="20">
<u-card :show-head="false" :show-foot="false" margin="0" border-radius="24">
<template #body>
<h4>尊敬的各位学员:</h4>
<h4 style="font-weight: bolder; color: #000000; font-size: 28rpx">
尊敬的各位学员:
</h4>
<text class="detail">
感谢您参加本次培训班!请各位学员对此次授课老师及教学安排进行满意度评价,同时我们也欢迎您提出意见和建议,您的感受及观点对我们非常重要谢谢!
</text>
</template>
</u-card>
<u-card :show-head="false" :show-foot="false" margin="0" border-radius="20">
<view class="courseEvaluation">
<view class="half-circle"></view>
课程评价
</view>
<u-card :show-head="false" :show-foot="false" margin="0" border-radius="24">
<template #body>
<view>
<view class="rateItem">
......@@ -17,56 +22,64 @@
<u-rate
:count="5"
v-model="evaluateData.parmeters.Model.FContent"
size="42"
size="44"
active-color="#F7BA2A"
:disabled="disabled"
/>
<view class="rate">
{{ evaluateStr(evaluateData.parmeters.Model.FContent) }}
</view>
</view>
<view class="rateItem">
<h4>授课讲师</h4>
<u-rate
:count="5"
v-model="evaluateData.parmeters.Model.FLecturer"
size="42"
v-model="evaluateData.parmeters.Model.FClassService"
size="44"
active-color="#F7BA2A"
:disabled="disabled"
/>
<view class="rate">
{{ evaluateStr(evaluateData.parmeters.Model.FClassService) }}
</view>
</view>
</view>
</template>
</u-card>
<u-card :show-head="false" :show-foot="false" margin="0" border-radius="20">
<template #body>
<text style="margin-top: 40rpx"> 您的培训收获与意见建议: </text>
<view class="evaluate-textarea last">
<view class="evaluate-item">
<view class="title">您的培训收获与意见建议:</view>
<u-card
:show-head="false"
:show-foot="false"
margin="0"
border-radius="24"
>
<template #body>
<u-input
v-model="evaluateData.parmeters.Model.FOpinion"
type="textarea"
placeholder-style="background-color: #f5f5f5;font-size: 24rpx;overflow-y: auto;"
height="160"
placeholder-style="font-size: 24rpx;font-weight: 400;color: #BCBCBC;"
maxlength="1400"
:auto-height="false"
placeholder="快来说说您的想法~"
:disabled="disabled"
/>
</view>
</template>
</u-card>
</template>
</u-card>
</view>
<view class="submit" v-show="!disabled">
<u-button type="primary" @tap="submit">确定提交</u-button>
<u-button @tap="submit">确定提交</u-button>
</view>
</view>
</template>
<script setup lang="ts">
// import headers from "@/components/header/index.vue"
import { remarkOn, remarkDetail } from "@/api/class"
import { useGlobalStore } from "@/store/useStore"
import { toast, zconfirm } from "@/utils/util"
import { remarkOn, remarkDetail } from "@/api/class";
import { useGlobalStore } from "@/store/useStore";
import { toast, zconfirm, evaluateStr } from "@/utils/util";
const globalStore = useGlobalStore()
const disabled = ref(false)
const globalStore = useGlobalStore();
const disabled = ref(false);
const evaluateData = reactive({
parmeters: {
NeedReturnFields: ["FID"],
......@@ -95,11 +108,11 @@ const evaluateData = reactive({
FClassService: 0, //班主任服务
},
},
})
});
onLoad(async (options: any) => {
evaluateData.parmeters.Model.FClass.FNUMBER = options.classNumber
evaluateData.parmeters.Model.FTrainingPro.FNUMBER = options.ItemNumber
evaluateData.parmeters.Model.FClass.FNUMBER = options.classNumber;
evaluateData.parmeters.Model.FTrainingPro.FNUMBER = options.ItemNumber;
if (options.iEvaluate != "false") {
let data = {
classId: "",
......@@ -107,37 +120,37 @@ onLoad(async (options: any) => {
studentId: options.studentId,
pageIndex: 1,
pageSize: 10,
}
const { data: res } = await remarkDetail(data)
};
const { data: res } = await remarkDetail(data);
if (res.code == 200) {
evaluateData.parmeters.Model.FClassService = res.data[0].FCLASSSERVICE
evaluateData.parmeters.Model.FContent = res.data[0].FCONTENT
evaluateData.parmeters.Model.FLecturer = res.data[0].LECTURER
evaluateData.parmeters.Model.FPostService = res.data[0].FPOSTSERVICE
evaluateData.parmeters.Model.FHighlights = res.data[0].FHIGHLIGHTS
evaluateData.parmeters.Model.FSupplement = res.data[0].FSUPPLEMENT
evaluateData.parmeters.Model.FOpinion = res.data[0].FOPINION
disabled.value = true
evaluateData.parmeters.Model.FClassService = res.data[0].FCLASSSERVICE;
evaluateData.parmeters.Model.FContent = res.data[0].FCONTENT;
evaluateData.parmeters.Model.FLecturer = res.data[0].LECTURER;
evaluateData.parmeters.Model.FPostService = res.data[0].FPOSTSERVICE;
evaluateData.parmeters.Model.FHighlights = res.data[0].FHIGHLIGHTS;
evaluateData.parmeters.Model.FSupplement = res.data[0].FSUPPLEMENT;
evaluateData.parmeters.Model.FOpinion = res.data[0].FOPINION;
disabled.value = true;
}
}
})
});
const submit = () => {
zconfirm("确定提交评价?", async (result: boolean) => {
if (result) {
const { data: res } = await remarkOn(evaluateData)
const { data: res } = await remarkOn(evaluateData);
if (res.code == 200) {
uni.navigateBack()
toast("评价成功")
uni.navigateBack();
toast("评价成功");
}
}
})
}
});
};
</script>
<style lang="scss" scoped>
.evaluate-container {
padding: 30rpx;
padding: 30rpx 30rpx 110rpx 30rpx;
.u-card {
margin-bottom: 10rpx !important;
......@@ -150,7 +163,9 @@ const submit = () => {
text-indent: 2em;
display: block;
font-size: 28rpx;
margin-top: 10rpx;
margin-top: 20rpx;
font-weight: 400;
color: rgba(34, 34, 34, 0.8);
}
.rateItem {
......@@ -166,23 +181,45 @@ const submit = () => {
h4 {
width: 140rpx;
margin-right: 20rpx;
font-size: 28rpx;
font-weight: 500;
color: rgba(34, 34, 34, 0.9);
}
}
.evaluate-textarea {
background-color: #f5f5f5;
padding: 0 10rpx;
box-sizing: border-box;
margin: 20rpx 0;
}
.evaluate-item {
margin-top: 40rpx;
.title {
font-size: 28rpx;
font-weight: 400;
color: rgba(0, 0, 0, 0.9);
margin-bottom: 24rpx;
}
.last {
margin-bottom: 0;
:deep(.u-card__body) {
padding: 20rpx 24rpx !important;
}
:deep(.uni-textarea-placeholder, .u-input__textarea) {
background-color: #ffffff !important;
}
:deep(.uni-textarea-compute) {
font-size: 24rpx;
font-weight: 400;
color: rgba(0, 0, 0, 0.6);
}
:deep(.uni-textarea-textarea) {
overflow-y: auto !important;
}
}
}
.submit {
margin: 40rpx 40rpx 0;
margin: 64rpx 184rpx 0;
.u-btn {
width: 320rpx;
height: 96rpx;
background: #05a8ff;
border-radius: 12rpx;
color: #ffffff;
}
}
</style>
......@@ -5,7 +5,13 @@
:list="tabsState.list"
:is-scroll="false"
v-model="tabsState.current"
bg-color="#f5f5f5"
:active-item-style="{ fontSize: '34rpx', color: '#000000' }"
font-size="28"
bar-width="72"
bar-height="6"
bg-color="#fbfcff"
inactive-color="#cecfcf"
active-color="#05a8ff"
@change="tabsChange"
/>
<!-- 搜索 -->
......@@ -19,9 +25,7 @@
/>
<!-- 内容 -->
<view v-if="courseList.length">
<text style="margin-bottom: 20rpx; display: block"
>为你找到{{ listQuery.total }}个的班级</text
>
<text class="fund">为您找到{{ listQuery.total }}个课程</text>
<block v-for="(item, index) in courseList" :key="index">
<courseItem :courseItem="item" :current="tabsState.current" />
......@@ -30,19 +34,23 @@
<u-loadmore :status="status" icon-type="flower" />
</view>
</view>
<view v-else class="empty">
<u-empty text="暂无数据" mode="list" />
</view>
<u-empty
v-else
text="暂无数据~"
icon-size="506"
:margin-top="220"
src="../../static/img/noData.png"
></u-empty>
</view>
</template>
<script setup lang="ts">
// import headers from "@/components/header/index.vue"
import courseItem from "./components/courseItem.vue"
import { getCourseList } from "@/api/course"
import { useGlobalStore } from "@/store/useStore"
import courseItem from "./components/courseItem.vue";
import { getCourseList } from "@/api/course";
import { useGlobalStore } from "@/store/useStore";
const globalStore = useGlobalStore()
const globalStore = useGlobalStore();
const tabsState = reactive({
list: [
......@@ -57,9 +65,9 @@ const tabsState = reactive({
},
],
current: 0,
})
});
const courseList = ref([] as any)
const courseList = ref([] as any);
const listQuery = reactive({
Phone: globalStore.Phone,
......@@ -68,61 +76,61 @@ const listQuery = reactive({
total: 0,
type: 0,
Name: "",
})
});
const status = ref("loadmore")
const status = ref("loadmore");
const tabsChange = (index: number) => {
courseList.value = []
listQuery.pageIndex = 1
listQuery.pageSize = 10
courseList.value = [];
listQuery.pageIndex = 1;
listQuery.pageSize = 10;
switch (index) {
case 0:
listQuery.type = 0
break
listQuery.type = 0;
break;
case 1:
listQuery.type = 1
break
listQuery.type = 1;
break;
default:
listQuery.type = 2
break
listQuery.type = 2;
break;
}
init()
}
init();
};
const search = (val: any) => {
listQuery.Name = val.value
tabsChange(tabsState.current)
}
listQuery.Name = val.value;
tabsChange(tabsState.current);
};
const clear = () => {
listQuery.Name = ""
tabsChange(tabsState.current)
}
listQuery.Name = "";
tabsChange(tabsState.current);
};
// 上拉加载数据
onReachBottom(() => {
// 判断是否还有下一页数据
if (listQuery.pageIndex * listQuery.pageSize >= listQuery.total)
return (status.value = "nomore")
return (status.value = "nomore");
// // 判断是否正在请求其它数据,如果是,则不发起额外的请求
if (status.value === "loading") return
listQuery.pageIndex += 1
init()
})
if (status.value === "loading") return;
listQuery.pageIndex += 1;
init();
});
const init = async () => {
status.value = "loading"
const { data: res } = await getCourseList(listQuery)
status.value = "loading";
const { data: res } = await getCourseList(listQuery);
if (res.code == 200) {
if (res.total > 10) status.value = "loadmore"
else status.value = "nomore"
courseList.value = [...courseList.value, ...res.data]
listQuery.total = res.total
if (res.total > 10) status.value = "loadmore";
else status.value = "nomore";
courseList.value = [...courseList.value, ...res.data];
listQuery.total = res.total;
}
}
};
init()
init();
</script>
<style lang="scss" scoped>
......@@ -130,11 +138,6 @@ init()
padding: 0 30rpx 30rpx;
padding-top: 20rpx;
.uni-searchbar {
padding: 0;
margin: 20rpx 0;
}
.tag .u-tag {
margin-right: 20rpx;
}
......
<template>
<!-- <headers :title="pdfState.title" /> -->
<view class="pdf-container">
<web-view class="webview" :src="pdfState.pdfUrl"></web-view>
<view class="down" @tap="downLoadPdf">
<u-image
src="../../static/img/download.png"
width="50"
height="50"
></u-image>
<view style="margin-left: 10rpx">点击下载</view>
</view>
</view>
</template>
<script setup lang="ts">
// import headers from "@/components/header/index.vue"
import { zconfirm } from "@/utils/util";
const pdfState = reactive({
title: "",
pdfUrl: "",
viewerUrl: "/static/pdf/web/viewer.html",
})
url: "",
});
const downLoadPdf = () => {
zconfirm("确定下载课程资料?", (result: boolean) => {
if (result) {
const a = document.createElement("a");
a.href = pdfState.url;
a.download = pdfState.title;
a.click();
}
});
};
onLoad((options: any) => {
pdfState.title = options.name
pdfState.title = options.name;
pdfState.url = options.url;
pdfState.pdfUrl =
pdfState.viewerUrl + "?file=" + encodeURIComponent(options.url)
})
pdfState.viewerUrl + "?file=" + encodeURIComponent(options.url);
});
onReady(() => {
uni.setNavigationBarTitle({
title: pdfState.title,
})
})
});
});
onBackPress(() => {
uni.$emit("refresh", { refresh: true });
});
</script>
<style lang="scss" scoped>
.pdf-container {
width: 100vw;
height: 100vh;
position: relative;
.webview {
height: 90%;
}
.down {
position: absolute;
bottom: 15%;
z-index: 999;
right: 0;
background-color: #ffffff;
padding: 10rpx;
display: flex;
align-items: center;
border-radius: 10rpx 0 0 10rpx;
color: #04a7ff;
}
}
</style>
<template>
<view class="see-more-container">
<block v-for="(item, index) in Teachs">
<view style="position: relative">
<u-image
width="100%"
height="824rpx"
:src="baseUrl + '/' + Teachs[0].Url"
/>
<view class="teach-name">
{{ Teachs[0].teachName }}
</view>
<view class="see-more-container">
<view class="menu-title">
<view class="half-circle"></view>
<view class="title">讲师简介</view>
</view>
<view class="detail">
{{ Teachs[0].teachMsg }}
</view>
</view>
<!-- <block v-for="(item, index) in Teachs">
<u-card :show-head="false" :show-foot="false" margin="0">
<template #body>
<u-section
......@@ -41,51 +58,96 @@
</view>
</template>
</u-card>
</block>
</block> -->
</view>
</template>
<script setup lang="ts">
import { useCourseStore } from "@/store/modules/courseStore"
import { baseUrl } from "@/utils/request"
import { useCourseStore } from "@/store/modules/courseStore";
import { baseUrl } from "@/utils/request";
const courseStore = useCourseStore()
const courseStore = useCourseStore();
const Teachs = computed(() => courseStore.getTeachs)
const Teachs = computed(() => courseStore.getTeachs);
</script>
<style lang="scss" scoped>
.see-more-container {
padding: 20rpx 30rpx;
padding: 52rpx 32rpx 0;
box-sizing: border-box;
position: fixed;
bottom: 0;
width: 100%;
height: 830rpx;
background: #fbfcff;
border-radius: 90rpx 90rpx 0rpx 0rpx;
border-radius: 90rpx;
.u-card {
margin-bottom: 24rpx !important;
.menu-title {
width: 100%;
display: flex;
margin-bottom: 30rpx;
.info {
display: flex;
margin-top: 20rpx;
.info-text {
display: flex;
flex-direction: column;
margin-left: 20rpx;
justify-content: space-around;
text:nth-child(1) {
font-size: 34rpx;
font-weight: bold;
color: #303133;
}
}
.title {
font-size: 34rpx;
font-weight: 600;
color: #222222;
line-height: 40rpx;
}
}
.detail {
text-indent: 1em;
margin-top: 30rpx;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 28rpx;
line-height: 1.25;
}
.detail {
text-indent: 2em;
font-size: 28rpx;
font-weight: 400;
color: rgba(34, 34, 34, 0.8);
height: 630rpx;
overflow-y: auto;
}
// .u-card {
// margin-bottom: 24rpx !important;
// .info {
// display: flex;
// margin-top: 20rpx;
// .info-text {
// display: flex;
// flex-direction: column;
// margin-left: 20rpx;
// justify-content: space-around;
// text:nth-child(1) {
// font-size: 34rpx;
// font-weight: bold;
// color: #303133;
// }
// }
// }
// .detail {
// text-indent: 1em;
// margin-top: 30rpx;
// font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
// font-size: 28rpx;
// line-height: 1.25;
// }
// }
}
.teach-name {
position: absolute;
top: 594rpx;
left: 50%;
transform: translateX(-50%);
width: 184rpx;
height: 68rpx;
background: rgba(4, 167, 255, 0.3);
border-radius: 16rpx;
line-height: 68rpx;
font-size: 34rpx;
font-weight: 600;
color: #ffffff;
text-align: center;
}
</style>
<template>
<!-- <headers title='西部人力培训中心' backIconName="close" /> -->
<view class="bg-header">
<u-image src="../../static/img/background.png" width="100%" height="100%" />
</view>
<view class="home-container">
<!-- 用户信息部分 -->
<view class="user-info">
<u-image
width="260rpx"
height="260rpx"
:src="baseUrl + '/' + globalStore.infoData.Image"
border-radius="30"
width="240rpx"
height="240rpx"
:src="baseUrl + '/' + globalStore.infoData?.Image"
border-radius="24"
/>
<text class="name">{{ globalStore.infoData.Name }}</text>
<text class="name">{{ globalStore.infoData?.Name }}</text>
<view v-if="globalStore.Phone" class="info">
<text>{{
globalStore.infoData.Type == "BZR" ? "班主任" : "讲师"
......@@ -17,12 +19,15 @@
</view>
</view>
<view class="user-menu">
<text class="menu-title">服务功能</text>
<view class="menu-title">
<view class="half-circle"></view>
<view class="title">服务功能</view>
</view>
<!-- <view class="user-menu">
<view class="content">
<u-grid :col="3">
<u-grid-item @tap="toClass">
<!-- <u-badge count="2" :offset="[20, 20]"></u-badge> -->
<u-icon name="man-add-fill" :size="53"></u-icon>
<view class="grid-text">管理班级</view>
</u-grid-item>
......@@ -31,7 +36,6 @@
<view class="grid-text">我的课程</view>
</u-grid-item>
<u-grid-item @tap="toSetPositioning">
<!-- <u-badge count="3" :offset="[20, 20]"></u-badge> -->
<u-icon name="list-dot" :size="53"></u-icon>
<view class="grid-text">设置考勤定位</view>
</u-grid-item>
......@@ -41,54 +45,132 @@
</u-grid-item>
</u-grid>
</view>
</view> -->
<view class="user-menu">
<view
class="menu-item"
v-for="item in menuList"
:key="item.id"
@tap="gridChange(item.id)"
>
<!-- Ribbon2 Ribbon5 -->
<u-image :src="item.src" width="120rpx" height="120rpx" />
<text>{{ item.name }}</text>
</view>
</view>
<view class="bg-footer">
<u-image
src="../../static/img/mask_group.png"
width="100%"
height="100%"
/>
</view>
</view>
</template>
<script setup lang="ts">
// import headers from '@/components/header/index.vue'
import { useGlobalStore } from "@/store/useStore"
import { baseUrl } from "@/utils/request"
import { useGlobalStore } from "@/store/useStore";
import { baseUrl } from "@/utils/request";
const globalStore = useGlobalStore();
const globalStore = useGlobalStore()
const menuList = [
{
id: 0,
src: "../../static/img/Ribbon1.png",
name: "班级管理",
},
{
id: 1,
src: "../../static/img/Ribbon2.png",
name: "我的课程",
},
{
id: 2,
src: "../../static/img/Ribbon3.png",
name: "考勤定位",
},
{
id: 3,
src: "../../static/img/Ribbon4.png",
name: "讲师列表",
},
{
id: 4,
src: "../../static/img/Ribbon5.png",
name: "现场教学",
},
{
id: 5,
src: "../../static/img/Ribbon6.png",
name: "培训评价",
},
];
const toClass = () => {
uni.navigateTo({
url: "/pages/class/index",
})
}
});
};
const toCourse = () => {
uni.navigateTo({
url: "/pages/course/index",
})
}
});
};
const toSetPositioning = () => {
uni.navigateTo({
url: "/pages/setPositioning/index",
})
}
});
};
const toTeachPoints = () => {
uni.navigateTo({
url: "/pages/teachPoints/index",
})
}
});
};
const gridChange = (type: number) => {
switch (type) {
case 0:
toClass();
break;
case 1:
toCourse();
break;
case 2:
toSetPositioning();
break;
case 3:
uni.navigateTo({
url: "/pages/lecturer/index",
});
break;
case 4:
toTeachPoints();
break;
case 5:
uni.navigateTo({
url: "/pages/trainingEvaluation/index",
});
break;
}
};
</script>
<style lang="scss" scoped>
page {
background-image: url("https://img2.baidu.com/it/u=460732253,1892860896&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=888");
background-size: cover;
/* 背景图片自适应屏幕大小 */
/* 其他样式设置 */
background-color: #ffffff;
}
.bg-header {
position: relative;
}
.home-container {
position: absolute;
top: 3%;
width: 100%;
height: calc(100% - 48px);
.user-info {
margin: 40rpx 0 100rpx 0;
margin: 40rpx 0 40rpx 0;
width: 100%;
height: 30%;
display: flex;
......@@ -110,31 +192,48 @@ page {
}
}
.menu-title {
margin: 0 32rpx;
width: 100%;
display: flex;
margin-bottom: 32rpx;
.title {
font-size: 34rpx;
font-weight: 600;
color: #222222;
line-height: 40rpx;
}
}
.user-menu {
// height: 238rpx;
margin: 0 32rpx;
padding: 48rpx;
background: #ffffff;
box-shadow: 0rpx 8rpx 60rpx 0rpx rgba(0, 0, 0, 0.05);
border-radius: 24rpx;
display: flex;
flex-direction: column;
flex-wrap: wrap;
box-sizing: border-box;
margin: 16rpx;
border-radius: 8rpx;
// border: 1px solid #e4e7ed;
background-color: #ffffff;
overflow: hidden;
color: #303133;
transition: 0.3s;
box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.05);
.menu-title {
box-sizing: border-box;
width: 100%;
font-size: 36rpx;
font-weight: bold;
padding: 32rpx 0 32rpx 50rpx;
background: linear-gradient(to right, #f4f8ff, #cce3fe);
.menu-item {
text-align: center;
flex-basis: calc((100% - 96rpx) / 3);
// height: 200rpx;
display: flex;
flex-direction: column;
align-items: center;
margin-right: 48rpx;
margin-bottom: 24rpx;
}
.content {
padding: 30rpx 0 80rpx 0;
& .menu-item:nth-child(3n) {
margin-right: 0;
}
}
}
.bg-footer {
// z-index: -99;
}
</style>
<template>
<view class="lecturer-item">
<u-card :show-head="false" margin="0" border-radius="24">
<template #body>
<view class="body">
<view class="body-left">
<view class="body-left-header">
<u-image
width="112rpx"
height="112rpx"
border-radius="8"
:src="baseUrl + '/' + lecturerItem.FPHOTO"
></u-image>
<view class="body-left-header-right">
<view class="body-left-header-right-top">
<text>{{ lecturerItem.FNAME }}</text>
<text class="line"></text>
<text>{{ lecturerItem.FTITLE }}</text>
</view>
<view class="body-left-header-right-bottom"
>党性学习第一节</view
>
</view>
</view>
<view class="body-left-bottom">
<view class="item"
>可授课程:{{ lecturerItem.FCANCOURSE }}
<view class="item-sub">查看全部可授课程</view>
</view>
<view class="item">课酬参考:{{ lecturerItem.FSALARY }}</view>
<view class="item"
>联系电话:{{
hidePhoneNumber(lecturerItem.FPHONENUMBER)
}}</view
>
</view>
</view>
<view class="body-right">
<view class="body-right-title">职称证明</view>
<u-image
width="182rpx"
height="250rpx"
:src="baseUrl + '/' + lecturerItem.FTITLEPROVE"
></u-image>
<view class="body-right-down" @tap="downTitleImage">点击下载</view>
</view>
</view>
</template>
<template #foot>
<view class="foot">
<text>{{ lecturerItem.FINTRODUCE }}</text>
</view>
</template>
</u-card>
</view>
</template>
<script setup lang="ts">
import { baseUrl } from "@/utils/request";
import { hidePhoneNumber, toast } from "@/utils/util";
const props = defineProps({
lecturerItem: {
type: Object,
} as any,
});
const downTitleImage = () => {
try {
uni.downloadFile({
url: baseUrl + "/" + props.lecturerItem.FTITLEPROVE, // 这里是你接口地址 若要传参 直接 url拼接参数即可
success: (res) => {
console.log(res, "res");
var tempFilePath = res.tempFilePath; // 这里拿到后端返回的图片路径
const url = tempFilePath;
const a = document.createElement("a");
a.href = url;
a.download = props.lecturerItem.FNAME + ".jpg";
a.click();
},
fail: () => {
uni.hideLoading();
},
});
} catch (error) {
toast("下载失败");
}
};
</script>
<style lang="scss" scoped>
.lecturer-item {
margin-bottom: 32rpx;
:deep(.u-card__body) {
padding: 40rpx 32rpx 32rpx !important;
}
:deep(.u-card__foot) {
padding: 32rpx 32rpx 40rpx !important;
}
.body {
display: flex;
height: 348rpx;
justify-content: space-between;
.body-left {
.body-left-header {
display: flex;
margin-bottom: 24rpx;
.body-left-header-right {
margin-left: 16rpx;
height: 112rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
.body-left-header-right-top {
display: flex;
align-items: center;
font-size: 32rpx;
font-weight: 500;
color: #000000;
.line {
width: 0rpx;
height: 24rpx;
border: 2rpx solid rgba(0, 0, 0, 0.1);
margin: 0 8rpx;
}
& text:last-child {
font-size: 24rpx;
font-weight: 500;
color: rgba(0, 0, 0, 0.5);
line-height: 28rpx;
}
}
.body-left-header-right-bottom {
font-size: 28rpx;
font-weight: 400;
color: #666666;
}
}
}
.body-left-bottom {
.item {
font-size: 28rpx;
font-weight: 400;
color: #222222;
margin-bottom: 24rpx;
.item-sub {
font-size: 24rpx;
font-weight: 400;
color: #05a8ff;
margin-top: 4rpx;
}
}
& .item:last-child {
margin-bottom: 8rpx;
}
}
}
.body-right {
display: flex;
flex-direction: column;
align-items: center;
.body-right-title {
margin-bottom: 16rpx;
font-size: 28rpx;
font-weight: 400;
color: #222222;
}
.body-right-down {
font-size: 24rpx;
font-weight: 400;
color: #05a8ff;
margin-top: 8rpx;
}
}
}
.foot {
max-height: 102rpx;
font-size: 24rpx;
font-weight: 400;
color: rgba(34, 34, 34, 0.7);
text {
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
</style>
<template>
<view class="lecturer-container">
<!-- 搜索 -->
<uni-search-bar
placeholder="班级名称"
bgColor="#ffffff"
clearButton="auto"
cancelButton="none"
@confirm="search"
@clear="clear"
/>
<view v-if="lecturerList.length">
<block v-for="(item, index) in lecturerList" :key="index">
<lecturerItem :lecturerItem="item" @init="initLecturerItem" />
</block>
<view style="padding: 20rpx">
<u-loadmore :status="status" icon-type="flower" />
</view>
</view>
<u-empty
v-else
text="暂无数据~"
icon-size="506"
:margin-top="220"
src="../../static/img/noData.png"
></u-empty>
</view>
</template>
<script setup lang="ts">
import { getLecturerList } from "@/api/lecturer";
import lecturerItem from "./components/lecturerItem.vue";
const listQuery = reactive({
PageIndex: 1,
PageSize: 10,
total: 0,
KeyWords: "",
});
const lecturerList = ref([] as any);
const status = ref("loadmore");
const search = (val: any) => {
listQuery.KeyWords = val.value;
};
const clear = () => {
listQuery.KeyWords = "";
};
const initLecturerItem = () => {};
// 上拉加载数据
onReachBottom(() => {
// 判断是否还有下一页数据
if (listQuery.PageIndex * listQuery.PageSize >= listQuery.total)
return (status.value = "nomore");
// // 判断是否正在请求其它数据,如果是,则不发起额外的请求
if (status.value === "loading") return;
listQuery.PageIndex += 1;
init();
});
const init = async () => {
status.value = "loading";
const { data: res } = await getLecturerList(listQuery);
if (res.code == 200) {
if (res.total > 10) status.value = "loadmore";
else status.value = "nomore";
lecturerList.value = [...lecturerList.value, ...res.data];
listQuery.total = res.total;
}
};
init();
</script>
<style lang="scss" scoped>
.lecturer-container {
padding: 0 32rpx 64rpx;
}
</style>
<template>
<view class="login-container">
<u-form :model="data.formData" ref="form" label-width="150">
<u-form-item label="手机号" prop="Phone"
><u-input v-model="data.formData.Phone" placeholder="请出输入手机号"
/></u-form-item>
<u-form-item label="密码" prop="Password"
><u-input
v-model="data.formData.Password"
type="password"
placeholder="请输入密码"
/></u-form-item>
</u-form>
<view class="footer">
<u-button @click="submit" size="medium" type="primary">登录</u-button>
<view style="position: relative">
<view class="bg-header">
<u-image
src="../../static/img/background.png"
width="100%"
height="100%"
/>
</view>
<view class="logo">
<u-image src="../../static/img/logo.png" width="100%" height="240rpx" />
<view class="logo-detail">培训系统</view>
</view>
<view class="container">
<view class="content">
<u-form :model="data.formData" ref="form" label-width="150">
<u-form-item
prop="Phone"
left-icon="../../static/img/icon_user.png"
:left-icon-style="data.leftIconStyle"
>
<u-input v-model="data.formData.Phone" placeholder="请输入手机号"
/></u-form-item>
<u-form-item
prop="Password"
left-icon="../../static/img/icon_yanzhenma.png"
:left-icon-style="data.leftIconStyle"
style="margin-top: 48rpx"
>
<u-input
v-model="data.formData.Password"
type="password"
placeholder="请输入密码"
/></u-form-item>
</u-form>
<view class="footer">
<u-button @click="submit" type="primary">登录</u-button>
</view>
</view>
</view>
<view v-if="hideshow" class="bg-footer">
<u-image
src="../../static/img/mask_group.png"
width="100%"
height="100%"
/>
</view>
</view>
</template>
<script setup lang="ts">
import { useGlobalStore } from "@/store/useStore"
import { Login } from "./interface/index"
import { teachLogin } from "@/api/login"
import { useGlobalStore } from "@/store/useStore";
import { Login } from "./interface/index";
import { teachLogin } from "@/api/login";
import { toast } from "@/utils/util";
const globalStore = useGlobalStore()
const globalStore = useGlobalStore();
const form = ref()
const uniA: any = uni
const form = ref();
const uniA: any = uni;
const showHeight = ref();
const hideshow = ref(true);
const docmHeight = document.documentElement.clientHeight;
const data = reactive({
formData: {
Phone: "",
Password: "",
Phone: "15077060245",
Password: "123456",
} as Login.LoginForm,
rules: {
Phone: [
......@@ -39,15 +73,15 @@ const data = reactive({
message: "请输入手机号",
trigger: ["change", "blur"],
},
// {
// // 自定义验证函数,见上说明
// validator: (rule: any, value: any, callback: any) => {
// return uniA.$u.test.mobile(value)
// },
// message: "手机号码不正确",
// // 触发器可以同时用blur和change
// trigger: ["change", "blur"],
// },
{
// 自定义验证函数,见上说明
validator: (rule: any, value: any, callback: any) => {
return uniA.$u.test.mobile(value);
},
message: "手机号码不正确",
// 触发器可以同时用blur和change
trigger: ["change", "blur"],
},
],
Password: [
{
......@@ -57,49 +91,101 @@ const data = reactive({
},
],
},
})
leftIconStyle: {
width: "40rpx",
height: "40rpx",
display: "flex",
},
});
onReady(() => {
form.value.setRules(data.rules)
})
form.value.setRules(data.rules);
});
onMounted(() => {
window.onresize = () => {
return (() => {
showHeight.value = document.body.clientHeight;
})();
};
});
watch(
() => showHeight.value,
() => {
if (docmHeight > showHeight.value) {
hideshow.value = false;
} else {
hideshow.value = true;
}
}
);
const submit = () => {
form.value.validate(async (valid: boolean) => {
if (valid) {
const { data: res } = await teachLogin(data.formData)
const { data: res } = await teachLogin(data.formData);
if (res.code == 200) {
globalStore.setPhone(data.formData.Phone)
globalStore.setInfoData(res.data[0])
uni.reLaunch({ url: "/pages/home/index" })
toast('登录成功')
globalStore.setPhone(data.formData.Phone);
globalStore.setInfoData(res.data[0]);
uni.reLaunch({ url: "/pages/home/index" });
toast("登录成功");
}
} else {
console.log("验证失败")
console.log("验证失败");
}
})
}
});
};
</script>
<style lang="scss" scoped>
page {
background-image: url("https://img2.baidu.com/it/u=460732253,1892860896&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=888");
background-size: cover;
/* 背景图片自适应屏幕大小 */
/* 其他样式设置 */
}
.login-container {
padding: 30rpx;
.container {
position: absolute;
top: 25%;
left: 5%;
width: 90vw;
background-color: #fff;
border-radius: 15rpx;
top: 500rpx;
left: 12%;
z-index: 99;
width: 568rpx;
.content {
width: 568rpx;
height: 372rpx;
.yanzhenma {
display: flex;
align-items: center;
margin-top: 48rpx;
.u-form-item {
width: 392rpx;
}
}
.footer {
display: flex;
margin-top: 30rpx;
:deep(.u-form-item) {
position: relative;
box-sizing: border-box;
background: #ffffff;
padding: 10rpx 36rpx 10rpx;
box-shadow: 0rpx 8rpx 100rpx 0rpx rgba(0, 0, 0, 0.05);
border-radius: 16rpx;
height: 90rpx;
}
:deep(.u-form-item__message) {
padding-left: 0 !important;
margin-top: 20rpx;
}
.footer {
height: 84rpx;
margin-top: 64rpx;
.u-btn {
width: 100%;
height: 100%;
background-color: #04a7ff;
}
.register {
text-align: center;
font-size: 26rpx;
margin: 20rpx 0;
color: #07a9ff;
}
}
}
}
</style>
<template>
<u-popup
v-model="props.show"
mode="center"
closeable
width="600rpx"
border-radius="24"
@close="handleClose"
>
<view class="position">
<view class="title">请设置定位的应用范围</view>
<u-form :model="data.parmeters" ref="formRef" label-position="top">
<!-- <u-form-item label="考勤地址名称" prop="F_LQKJ_HITAREA"
><u-input v-model="data.parmeters.F_LQKJ_HITAREA" clearable
/></u-form-item> -->
<u-form-item prop="F_LQKJ_SCOPE" :border-bottom="false">
<u-radio-group v-model="num" shape="square">
<u-radio name="0"
>距离范围{{
data.parmeters.F_LQKJ_SCOPE ? data.parmeters.F_LQKJ_SCOPE : 0
}}</u-radio
>
</u-radio-group>
</u-form-item>
<u-form-item
prop="F_LQKJ_SCOPE"
:border-bottom="false"
style="margin-left: 48rpx"
>
<u-radio-group
v-model="data.parmeters.F_LQKJ_SCOPE"
shape="square"
@change="change"
>
<u-radio name="50">50</u-radio>
<u-radio name="100">100</u-radio>
<u-radio name="200">200</u-radio>
</u-radio-group>
</u-form-item>
<u-form-item
prop="type"
:border-bottom="false"
style="margin-bottom: 24rpx"
>
<u-radio-group v-model="data.parmeters.type" shape="square">
<u-radio name="0">仅当前课程考勤定位 </u-radio>
<u-radio name="1">同步班级所有课程的考勤定位 </u-radio>
</u-radio-group>
</u-form-item>
</u-form>
<view class="footer">
<u-button @tap="handleClose" size="medium">拒绝</u-button>
<u-button type="success" size="medium" @tap="submit">确认</u-button>
</view>
</view>
</u-popup>
</template>
<script setup lang="ts">
import { setAddr } from "@/api/position";
import { toast } from "@/utils/util";
import { useMapStore } from "@/store/modules/mapStore";
const mapStore = useMapStore();
const props = defineProps({
show: {
type: Boolean,
default: false,
},
});
const emits = defineEmits(["update:show"]);
const data = reactive({
parmeters: {
F_LQKJ_LONGITUDE: "",
F_LQKJ_SCOPE: "",
FCOURSEID: 0,
type: "0",
F_LQKJ_HITAREA: "",
classId: "",
},
rules: {
F_LQKJ_HITAREA: [
{
required: true,
message: "请输入考勤地址名称",
trigger: ["change", "blur"],
},
],
F_LQKJ_SCOPE: [
{
required: true,
message: "请设置有效范围",
trigger: "blur",
},
],
},
});
const num = ref();
const formRef = ref();
const change = () => {
num.value = "0";
};
const submit = () => {
formRef.value.validate(async (valid: any) => {
if (valid) {
const { data: res } = await setAddr({ parmeters: data.parmeters });
if (res.code == 200) {
uni.navigateBack();
handleClose();
toast("设置成功");
}
} else {
}
});
};
const init = () => {
data.parmeters.F_LQKJ_HITAREA = mapStore.mapData.hitArea;
data.parmeters.F_LQKJ_LONGITUDE = mapStore.mapData.Longitude;
data.parmeters.F_LQKJ_SCOPE = mapStore.mapData.Scope;
data.parmeters.FCOURSEID = mapStore.mapData.courseId;
data.parmeters.type = mapStore.mapData.type;
data.parmeters.classId = mapStore.mapData.classId;
if (data.parmeters.F_LQKJ_SCOPE) num.value = "0";
formRef.value.setRules(data.rules);
};
const handleClose = () => {
formRef.value?.resetFields();
emits("update:show", false);
};
const resetFields = () => {};
defineExpose({
init,
});
</script>
<style lang="scss" scoped>
:deep(.u-iconfont::before) {
margin-top: 24rpx;
}
.u-form-item {
padding: 0;
}
.position {
padding: 40rpx 32rpx;
.title {
font-size: 34rpx;
font-weight: 500;
color: #000000;
margin-bottom: 32rpx;
}
:deep(.u-iconfont::before) {
margin-top: 0;
}
.footer {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 8rpx;
.u-btn {
width: 176rpx;
height: 66rpx;
background: #04a7ff;
border-radius: 12rpx;
}
:deep(.u-hairline-border:after) {
border: 0;
}
& .u-btn:first-child {
color: #04a7ff;
background: rgba(0, 0, 0, 0.1);
}
}
}
</style>
<template>
<div class="position-container">
<view class="position-container">
<u-card :show-head="false" margin="0">
<template #body>
<view class="position-header">
<h3>{{ positionItem.courseName }}</h3>
{{ positionItem.courseName }}
</view>
<view class="item">
<text>上课地点:{{ positionItem.classArea }}</text>
......@@ -30,17 +30,17 @@
<template #foot>
<view class="position-footer">
<text>所属班级:{{ positionItem.className }}</text>
<u-button type="primary" size="mini" @tap="openMap">{{
<u-button type="primary" @tap="openMap">{{
current ? "修改定位" : "设置定位"
}}</u-button>
</view>
</template>
</u-card>
</div>
</view>
</template>
<script setup lang="ts">
import { useMapStore } from "@/store/modules/mapStore"
import { useMapStore } from "@/store/modules/mapStore";
const props = defineProps({
positionItem: {
......@@ -51,35 +51,56 @@ const props = defineProps({
type: Number,
default: 0,
},
})
});
const mapStore = useMapStore()
const mapStore = useMapStore();
const openMap = () => {
mapStore.setMapData(props.positionItem)
mapStore.setMapData(props.positionItem);
uni.navigateTo({
url: "/pages/setPositioning/map",
})
}
});
};
</script>
<style lang="scss" scoped>
.position-container {
margin-bottom: 20rpx;
:deep(.u-card__body) {
padding: 40rpx 32rpx 8rpx !important;
}
.position-header {
margin-bottom: 30rpx;
margin-bottom: 32rpx;
height: 48rpx;
font-size: 34rpx;
font-weight: 500;
color: #222222;
line-height: 40rpx;
}
.item {
margin-bottom: 20rpx;
margin-bottom: 24rpx;
font-size: 28rpx;
font-weight: 400;
color: rgba(34, 34, 34, 0.9);
}
.position-footer {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 24rpx;
font-weight: 400;
color: rgba(34, 34, 34, 0.5);
line-height: 28rpx;
.u-btn {
margin: 0;
height: 58rpx;
background: #04a7ff;
border-radius: 12rpx;
font-size: 24rpx;
}
}
}
......
......@@ -5,7 +5,13 @@
:list="tabsState.list"
:is-scroll="false"
v-model="tabsState.current"
bg-color="#f5f5f5"
:active-item-style="{ fontSize: '34rpx', color: '#000000' }"
font-size="28"
bar-width="72"
bar-height="6"
bg-color="#fbfcff"
inactive-color="#cecfcf"
active-color="#05a8ff"
@change="tabsChange"
/>
<!-- 搜索 -->
......@@ -19,9 +25,7 @@
/>
<!-- 内容 -->
<view v-if="positionList.length">
<text style="margin-bottom: 20rpx; display: block"
>为你找到{{ listQuery.total }} 个的课程</text
>
<text class="fund">为您找到{{ listQuery.total }} 个课程</text>
<block v-for="(item, index) in positionList" :key="index">
<setPositionItem :positionItem="item" :current="tabsState.current" />
......@@ -30,19 +34,23 @@
<u-loadmore :status="status" icon-type="flower" />
</view>
</view>
<view v-else class="empty">
<u-empty text="暂无数据" mode="list" />
</view>
<u-empty
v-else
text="暂无数据~"
icon-size="506"
:margin-top="220"
src="../../static/img/noData.png"
></u-empty>
</div>
</template>
<script setup lang="ts">
// import headers from "@/components/header/index.vue"
import setPositionItem from "./components/setPositionItem.vue"
import { getLocationList } from "@/api/position"
import { useGlobalStore } from "@/store/useStore"
import setPositionItem from "./components/setPositionItem.vue";
import { getLocationList } from "@/api/position";
import { useGlobalStore } from "@/store/useStore";
const globalStore = useGlobalStore()
const globalStore = useGlobalStore();
const tabsState = reactive({
list: [
......@@ -54,9 +62,9 @@ const tabsState = reactive({
},
],
current: 0,
})
});
const positionList: any = ref([] as any)
const positionList: any = ref([] as any);
const listQuery = reactive({
Phone: globalStore.Phone,
pageIndex: 1,
......@@ -64,54 +72,54 @@ const listQuery = reactive({
total: 0,
type: 0,
Name: "",
})
const status = ref("loadmore")
});
const status = ref("loadmore");
const tabsChange = (index: number) => {
positionList.value = []
positionList.value = [];
if (index) {
listQuery.type = 1
listQuery.type = 1;
} else {
listQuery.type = 0
listQuery.type = 0;
}
init()
}
init();
};
const search = (val: any) => {
listQuery.Name = val.value
init()
}
listQuery.Name = val.value;
init();
};
const clear = () => {
listQuery.Name = ""
init()
}
listQuery.Name = "";
init();
};
// 上拉加载数据
onReachBottom(() => {
// 判断是否还有下一页数据
if (listQuery.pageIndex * listQuery.pageSize >= listQuery.total)
return (status.value = "nomore")
return (status.value = "nomore");
// // 判断是否正在请求其它数据,如果是,则不发起额外的请求
if (status.value === "loading") return
listQuery.pageIndex += 1
init()
})
if (status.value === "loading") return;
listQuery.pageIndex += 1;
init();
});
const init = async () => {
status.value = "loading"
const { data: res } = await getLocationList(listQuery)
status.value = "loading";
const { data: res } = await getLocationList(listQuery);
if (res.code == 200) {
if (res.total > 10) status.value = "loadmore"
else status.value = "nomore"
positionList.value = [...positionList.value, ...res.data]
listQuery.total = res.total
if (res.total > 10) status.value = "loadmore";
else status.value = "nomore";
positionList.value = [...positionList.value, ...res.data];
listQuery.total = res.total;
// console.log(positionList.value)
}
}
};
onShow(() => {
tabsChange(tabsState.current)
})
tabsChange(tabsState.current);
});
</script>
<style lang="scss" scoped>
......
<template>
<!-- <headers title="考勤地点设置" :is-button="false" @submit="submit" /> -->
<view v-if="flag" class="map">
<iframe id="mapPage" width="100%" height="100%" frameborder="0" :src="src">
</iframe>
<view class="complete">
<u-button
type="primary"
size="mini"
@tap="submit"
style="margin-right: 30rpx"
>下一步</u-button
<u-button type="primary" @tap="submit" style="margin-right: 30rpx"
>完成</u-button
>
</view>
</view>
<positionPopup ref="positionRef" v-model:show="show" />
</template>
<script setup lang="ts">
import headers from "@/components/header/index.vue"
import { toast, zconfirm } from "@/utils/util"
import { useMapStore } from "@/store/modules/mapStore"
import { toast, zconfirm } from "@/utils/util";
import { useMapStore } from "@/store/modules/mapStore";
import positionPopup from "./components/positionPopup.vue";
const mapStore = useMapStore()
const mapStore = useMapStore();
const state = reactive({
key: "3M5BZ-SFCRJ-AHSF7-XRA5Q-Y6NIJ-DXBH4",
coord: "",
})
});
const src = ref()
const flag = ref(false)
const addrDetail = ref()
window.addEventListener(
"message",
function (event) {
// 接收位置信息,用户选择确认位置点后选点组件会触发该事件,回传用户的位置信息
var loc = event.data
if (loc && loc.module == "locationPicker") {
//防止其他应用也会向该页面post信息,需判断module是否为'locationPicker'
addrDetail.value = loc
}
},
false
)
const src = ref();
const flag = ref(false);
const show = ref(false);
const addrDetail = ref();
const positionRef = ref();
const submit = () => {
if (!addrDetail.value) return toast("请选择地址")
console.log("location", addrDetail.value)
uni.navigateTo({
url: "/pages/setPositioning/setAttendance",
success() {
const Longitude =
addrDetail.value.latlng.lat + "," + addrDetail.value.latlng.lng
mapStore.setMapData({
...mapStore.mapData,
...{ hitArea: addrDetail.value.poiaddress, Longitude },
})
},
})
setTimeout(function () {
console.log(mapStore.mapData, "mapStore.mapData")
}, 10)
}
if (!addrDetail.value) return toast("请选择地址");
const Longitude =
addrDetail.value.latlng.lat + "," + addrDetail.value.latlng.lng;
mapStore.setMapData({
...mapStore.mapData,
...{ hitArea: addrDetail.value.poiaddress, Longitude },
});
show.value = true;
setTimeout(() => {
positionRef.value.init();
// console.log("location", addrDetail.value);
}, 100);
// uni.navigateTo({
// url: "/pages/setPositioning/setAttendance",
// success() {
// const Longitude =
// addrDetail.value.latlng.lat + "," + addrDetail.value.latlng.lng;
// mapStore.setMapData({
// ...mapStore.mapData,
// ...{ hitArea: addrDetail.value.poiaddress, Longitude },
// });
// },
// });
};
const setPosition = (event: any) => {
// 接收位置信息,用户选择确认位置点后选点组件会触发该事件,回传用户的位置信息
var loc = event.data;
if (loc && loc.module == "locationPicker") {
//防止其他应用也会向该页面post信息,需判断module是否为'locationPicker'
addrDetail.value = loc;
}
};
onReady(() => {
// positionRef.value.initRules();
});
onMounted(() => {
if (mapStore.mapData.StateType) {
state.coord = mapStore.mapData.Longitude
console.log(mapStore.mapData, state.coord , 'state.coord ')
src.value = `https://apis.map.qq.com/tools/locpicker?search=1&type=1&key=${state.key}&referer=XBRLPX&coord=${state.coord}&zoom=18`
state.coord = mapStore.mapData.Longitude;
console.log(mapStore.mapData, state.coord, "state.coord ");
src.value = `https://apis.map.qq.com/tools/locpicker?search=1&type=1&key=${state.key}&referer=XBRLPX&coord=${state.coord}&zoom=18`;
setTimeout(() => {
flag.value = true
}, 300)
flag.value = true;
}, 300);
} else {
uni.getLocation({
type: "gcj02",
success(res: any) {
console.log(res)
state.coord = res.latitude + "," + res.longitude
src.value = `https://apis.map.qq.com/tools/locpicker?search=1&type=1&key=${state.key}&referer=XBRLPX&coord=${state.coord}&zoom=18`
// console.log(res);
state.coord = res.latitude + "," + res.longitude;
src.value = `https://apis.map.qq.com/tools/locpicker?search=1&type=1&key=${state.key}&referer=XBRLPX&coord=${state.coord}&zoom=18`;
setTimeout(() => {
flag.value = true
}, 300)
flag.value = true;
}, 300);
},
})
});
}
})
window.addEventListener("message", setPosition, false);
});
onBackPress(() => {
window.removeEventListener("message", setPosition, false);
flag.value = false;
});
</script>
<style lang="scss" scoped>
......@@ -95,8 +106,15 @@ onMounted(() => {
.complete {
position: absolute;
top: 5.5%;
right: -3%;
top: 46%;
right: -2%;
.u-btn {
padding: 12rpx;
height: 58rpx;
background: #04a7ff;
border-radius: 12rpx 12rpx 12rpx 12rpx;
opacity: 1;
}
}
}
</style>
......@@ -35,13 +35,13 @@
<script setup lang="ts">
// import headers from "@/components/header/index.vue"
import { setAddr } from "@/api/position"
import { toast } from "@/utils/util"
import { useMapStore } from "@/store/modules/mapStore"
import { setAddr } from "@/api/position";
import { toast } from "@/utils/util";
import { useMapStore } from "@/store/modules/mapStore";
const mapStore = useMapStore()
const mapStore = useMapStore();
const formRef = ref()
const formRef = ref();
const data = reactive({
parmeters: {
......@@ -103,41 +103,41 @@ const data = reactive({
label: "800米",
},
],
})
});
const back = () => {
uni.navigateBack()
}
uni.navigateBack();
};
const submit = () => {
formRef.value.validate(async (valid: any) => {
if (valid) {
const { data: res } = await setAddr({ parmeters: data.parmeters })
const { data: res } = await setAddr({ parmeters: data.parmeters });
if (res.code == 200) {
uni.navigateBack({ delta: 2 })
toast("设置成功")
uni.navigateBack({ delta: 2 });
toast("设置成功");
}
} else {
}
})
}
});
};
const onConfirm = (item: any) => {
data.parmeters.F_LQKJ_SCOPE = item[0].value
}
data.parmeters.F_LQKJ_SCOPE = item[0].value;
};
onReady(() => {
formRef.value.setRules(data.rules)
formRef.value.setRules(data.rules);
setTimeout(() => {
data.parmeters.F_LQKJ_HITAREA = mapStore.mapData.hitArea
data.parmeters.F_LQKJ_LONGITUDE = mapStore.mapData.Longitude
data.parmeters.F_LQKJ_SCOPE = mapStore.mapData.Scope
data.parmeters.FCOURSEID = mapStore.mapData.courseId
data.parmeters.type = mapStore.mapData.type
data.parmeters.classId = mapStore.mapData.classId
console.log(mapStore.mapData)
}, 100)
})
data.parmeters.F_LQKJ_HITAREA = mapStore.mapData.hitArea;
data.parmeters.F_LQKJ_LONGITUDE = mapStore.mapData.Longitude;
data.parmeters.F_LQKJ_SCOPE = mapStore.mapData.Scope;
data.parmeters.FCOURSEID = mapStore.mapData.courseId;
data.parmeters.type = mapStore.mapData.type;
data.parmeters.classId = mapStore.mapData.classId;
console.log(mapStore.mapData);
}, 100);
});
</script>
<style lang="scss" scoped>
......
......@@ -2,17 +2,56 @@
<div class="teach-points-container">
<u-card :show-head="false" margin="0">
<template #body>
<view class="teach-points-header">
<h3>{{ teachPointsItem.FTERRITORIALITY }}</h3>
<view class="body">
<view>
<!-- <view class="teach-points-header">
<h3>{{ teachPointsItem.FTERRITORIALITY }}</h3>
</view> -->
<view class="item">
<text>现场教学点:{{ teachPointsItem.FTEACHINGPOINTS }}</text>
</view>
<view class="item">
<text>属地:{{ teachPointsItem.FTEACHINGPOINTS }}</text>
</view>
<view class="item">
<text>讲解员:{{ teachPointsItem.FTEACHINGPOINTS }}</text>
</view>
<view class="item">
<text>联系人:{{ teachPointsItem.FCONTACTS }}</text>
<u-icon
name="phone"
size="32"
color="#05A8FF"
style="margin-left: 32rpx"
@tap="tapButton(teachPointsItem.FPHONE)"
></u-icon>
</view>
<view class="item">
<text>票价/门票:{{ teachPointsItem.FTEACHINGPOINTS }}</text>
</view>
<view class="item">
<text>预约方式:{{ teachPointsItem.FTEACHINGPOINTS }}</text>
</view>
<view class="item">
<text>备注:{{ teachPointsItem.FTEACHINGPOINTS }}</text>
</view>
</view>
<u-image
src=""
width="220rpx"
height="296rpx"
border-radius="8"
style="margin-bottom: 24rpx"
/>
</view>
<view class="item">
<text>现场教学点:{{ teachPointsItem.FTEACHINGPOINTS }}</text>
</view>
<view class="item">
<text>联系人:{{ teachPointsItem.FCONTACTS }}</text>
</view>
<view class="item">
<text>联系电话:{{ teachPointsItem.FPHONE }}</text>
</template>
<template #foot>
<view class="foot">
<text
>深圳市南山区西丽街道办公室位于圳地处中国华南地区、广东南部、珠江口东岸,东临大亚湾和大鹏湾,西濒珠江口和伶仃洋;南隔深圳河与香港相连,
北部与东莞、惠州两城市接深圳市南山区西丽街道办公室位于圳地处中国华南地区、广东南部、珠江口东岸,东临大亚湾和大鹏湾,西濒珠江口和伶仃洋;
南隔深圳河与香港相连,北部与东莞、惠州两城市接
</text>
</view>
</template>
</u-card>
......@@ -25,18 +64,53 @@ defineProps({
type: Array,
default: () => [],
} as any,
})
});
const tapButton = (phone: string) => {
location.href = "tel:" + phone;
};
</script>
<style lang="scss" scoped>
.teach-points-container {
margin-bottom: 20rpx;
:deep(.u-card__body) {
padding: 40rpx 32rpx 6rpx !important;
}
:deep(.u-card__foot) {
padding: 32rpx 32rpx 40rpx !important;
}
.teach-points-header {
margin-bottom: 30rpx;
}
.body {
display: flex;
justify-content: space-between;
align-items: flex-end;
.item {
display: flex;
margin-bottom: 24rpx;
font-size: 28rpx;
font-weight: 400;
color: rgba(34, 34, 34, 0.9);
}
}
.foot {
max-height: 102rpx;
font-size: 24rpx;
font-weight: 400;
color: rgba(34, 34, 34, 0.7);
.item {
margin-bottom: 20rpx;
text {
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
</style>
......@@ -2,16 +2,23 @@
<view class="teach-container">
<view v-if="teachPointsList.length">
<!-- 搜索 -->
<uni-search-bar
placeholder="现场教学点"
bgColor="#ffffff"
clearButton="auto"
cancelButton="none"
@confirm="search"
/>
<text style="margin-bottom: 20rpx; display: block"
>为你找到{{ listQuery.total }}个的现场教学点</text
>
<view class="search">
<view class="search-btn">属地</view>
<u-input
v-model="listQuery.territoriality"
placeholder=""
border
border-color="#F8F8F8"
/>
<uni-search-bar
placeholder="关键词"
bgColor="#ffffff"
clearButton="auto"
cancelButton="none"
@confirm="search"
/>
</view>
<!-- <text class="fund">为您找到{{ listQuery.total }}个现场教学点</text> -->
<block v-for="(item, index) in teachPointsList" :key="index">
<teachPointsItem :teachPointsItem="item" />
......@@ -27,53 +34,99 @@
</template>
<script setup lang="ts">
import teachPointsItem from "./components/teachPointsItem.vue"
import { getTeachPointsList } from "@/api/teachPoints"
import teachPointsItem from "./components/teachPointsItem.vue";
import { getTeachPointsList } from "@/api/teachPoints";
const teachPointsList = ref([] as any)
const status = ref("loadmore")
const teachPointsList = ref([] as any);
const status = ref("loadmore");
const listQuery = reactive({
pageIndex: 1,
pageSize: 10,
total: 0,
Area: "",
})
territoriality: "",
});
const search = (val: any) => {
teachPointsList.value = []
listQuery.Area = val.value
init()
}
teachPointsList.value = [];
listQuery.Area = val.value;
init();
};
// 上拉加载数据
onReachBottom(() => {
// 判断是否还有下一页数据
if (listQuery.pageIndex * listQuery.pageSize >= listQuery.total)
return (status.value = "nomore")
return (status.value = "nomore");
// // 判断是否正在请求其它数据,如果是,则不发起额外的请求
if (status.value === "loading") return
listQuery.pageIndex += 1
init()
})
if (status.value === "loading") return;
listQuery.pageIndex += 1;
init();
});
const init = async () => {
status.value = "loading"
const { data: res } = await getTeachPointsList(listQuery)
status.value = "loading";
const { data: res } = await getTeachPointsList(listQuery);
if (res.code == 200) {
if (res.total > 10) status.value = "loadmore"
else status.value = "nomore"
teachPointsList.value = [...teachPointsList.value, ...res.data]
listQuery.total = res.total
console.log(teachPointsList.value)
} else status.value = "nomore"
}
if (res.total > 10) status.value = "loadmore";
else status.value = "nomore";
teachPointsList.value = [...teachPointsList.value, ...res.data];
listQuery.total = res.total;
console.log(teachPointsList.value);
} else status.value = "nomore";
};
init()
init();
</script>
<style lang="scss" scoped>
.teach-container {
padding: 0 30rpx 30rpx;
padding: 0 32rpx 64rpx;
padding-top: 20rpx;
.search {
width: 100%;
display: flex;
align-items: center;
height: 72rpx;
margin: 32rpx 0 48rpx;
.search-btn {
width: 72rpx;
background: #05a8ff;
border-radius: 24rpx 0rpx 0rpx 24rpx;
line-height: 72rpx;
text-align: center;
color: #ffffff;
font-size: 24rpx;
}
.u-input {
flex: 1;
height: 100%;
// margin-right: 1rpx;
background-color: #ffffff;
:deep(.u-input__input) {
background-color: #ffffff;
}
}
.uni-searchbar {
margin: 0;
padding: 0 !important;
width: 446rpx;
height: 100%;
// box-shadow: 0rpx 8rpx 60rpx 0rpx rgba(0, 0, 0, 0.05) !important;
border-radius: 0 24rpx 24rpx 0;
border: 1rpx solid #f8f8f8;
:deep(.uni-searchbar__box) {
border-radius: 0 24rpx 24rpx 0 !important;
padding: 0;
background-color: #ffffff;
}
}
}
}
</style>
<template>
<!-- <headers title="我的班级" /> -->
<view class="class-container">
<u-tabs
:list="tabsState.list"
:is-scroll="false"
v-model="tabsState.current"
:active-item-style="{ fontSize: '34rpx', color: '#000000' }"
font-size="28"
bar-width="72"
bar-height="6"
bg-color="#fbfcff"
inactive-color="#cecfcf"
active-color="#05a8ff"
@change="tabsChange"
/>
<!-- 搜索 -->
<uni-search-bar
placeholder="班级名称"
bgColor="#ffffff"
clearButton="auto"
cancelButton="none"
@confirm="search"
@clear="clear"
/>
<!-- 内容 -->
<view v-if="evaluateList.length">
<text class="fund">为您找到{{ listQuery.total }}个班级</text>
<view v-if="!tabsState.current">
<block v-for="(item, index) in evaluateList" :key="index">
<classItem :classItem="item" :current="2" @init="tabsChange" />
</block>
</view>
<view v-else>
<block v-for="(item, index) in evaluateList" :key="index">
<courseItem :courseItem="item" :current="2" />
</block>
</view>
<view style="padding: 20rpx">
<u-loadmore :status="status" icon-type="flower" />
</view>
</view>
<u-empty
v-else
text="暂无数据~"
icon-size="506"
:margin-top="220"
src="../../static/img/noData.png"
></u-empty>
</view>
</template>
<script setup lang="ts">
// import headers from "@/components/header/index.vue"
import classItem from "@/pages/class/components/classItem.vue";
import courseItem from "@/pages/course/components/courseItem.vue";
import { getClassList } from "@/api/class";
import { getCourseList } from "@/api/course";
import { useGlobalStore } from "@/store/useStore";
const globalStore = useGlobalStore();
const tabsState = reactive({
list: [
{
name: "培训评价",
},
{
name: "课程评价",
},
],
current: 0,
});
const evaluateList = ref([] as any);
const listQuery = reactive({
Phone: globalStore.Phone,
type: 2,
pageIndex: 1,
pageSize: 10,
total: 0,
Name: "",
});
const status = ref("loadmore");
const tabsChange = (index: number) => {
evaluateList.value = [];
listQuery.pageIndex = 1;
listQuery.pageSize = 10;
if (index) initCourse();
else initClass();
};
const search = (val: any) => {
listQuery.Name = val.value;
tabsChange(tabsState.current);
};
const clear = () => {
listQuery.Name = "";
tabsChange(tabsState.current);
};
// 上拉加载数据
onReachBottom(() => {
// 判断是否还有下一页数据
if (listQuery.pageIndex * listQuery.pageSize >= listQuery.total)
return (status.value = "nomore");
// // 判断是否正在请求其它数据,如果是,则不发起额外的请求
if (status.value === "loading") return;
listQuery.pageIndex += 1;
if (tabsState.current) initCourse();
else initClass();
});
const initClass = async () => {
status.value = "loading";
const { data: res } = await getClassList(listQuery);
if (res.code == 200) {
if (res.total > 10) status.value = "loadmore";
else status.value = "nomore";
evaluateList.value = [...evaluateList.value, ...res.data];
listQuery.total = res.total;
}
};
const initCourse = async () => {
status.value = "loading";
const { data: res } = await getCourseList(listQuery);
if (res.code == 200) {
if (res.total > 10) status.value = "loadmore";
else status.value = "nomore";
evaluateList.value = [...evaluateList.value, ...res.data];
listQuery.total = res.total;
}
};
tabsChange(tabsState.current);
</script>
<style lang="scss" scoped>
.class-container {
padding: 0 32rpx 168rpx;
}
</style>
.card {
box-sizing: border-box;
margin: 16rpx;
padding: 16rpx;
border-radius: 8rpx;
border: 1px solid #e4e7ed;
.uni-tabbar {
max-width: 420px;
margin: 0 auto;
border-left: #f6f6f6 solid 1px;
border-right: #f6f6f6 solid 1px;
}
.uni-searchbar {
padding: 0 !important;
margin: 32rpx 0 48rpx;
width: 686rpx;
height: 72rpx;
background: #ffffff;
box-shadow: 0rpx 8rpx 60rpx 0rpx rgba(0, 0, 0, 0.05) !important;
border-radius: 24rpx;
:deep(.uni-searchbar__box) {
border-radius: 30rpx !important;
}
}
.u-card {
border-radius: 20rpx;
background-color: #ffffff;
overflow: hidden;
color: #303133;
transition: 0.3s;
box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.05);
box-shadow: 0rpx 8rpx 60rpx 0rpx rgba(0, 0, 0, 0.05) !important;
border-radius: 24rpx;
}
.card-text {
.logo {
position: absolute;
top: 128rpx;
left: 270rpx;
width: 212rpx;
height: 316rpx;
.logo-detail {
width: 100%;
height: 44rpx;
font-size: 34rpx;
font-family: PingFang SC-Medium, PingFang SC;
font-weight: 500;
color: #222222;
line-height: 44rpx;
margin-top: 32rpx;
text-align: center;
}
}
.half-circle {
width: 20rpx;
height: 40rpx;
border-radius: 0 20rpx 20rpx 0;
background-color: #04a7ff;
line-height: 40rpx;
margin-right: 20rpx;
}
.fund {
margin-bottom: 32rpx;
display: block;
}
.courseEvaluation {
margin: 48rpx 0 32rpx;
font-weight: bolder;
display: flex;
align-items: center;
font-size: 34rpx;
color: #222222;
}
.rate {
margin-left: 30rpx;
color: #c8c9cc;
font-size: 24rpx;
}
.code {
color: #07a9ff;
font-size: 28rpx;
}
.courseware {
display: flex;
flex-direction: column;
align-items: center;
.courseware-icon {
padding: 20rpx;
border-radius: 50%;
background-color: #ddf3ff;
}
.grid-text {
font-size: 28rpx;
margin-top: 4rpx;
color: #303133;
padding: 0 10rpx;
white-space: "nowrap";
text-overflow: "ellipsis";
overflow: "hidden";
.desc {
margin-top: 10rpx;
font-size: 24rpx;
font-weight: 400;
color: rgba(34, 34, 34, 0.5);
}
}
.card {
// height: 730rpx;
background: #ffffff;
box-shadow: 0rpx 8rpx 38rpx 0rpx rgba(0, 0, 0, 0.05);
border-radius: 24rpx;
padding: 18rpx 32rpx 48rpx;
}
.empty {
margin-top: 40rpx;
margin-top: 220rpx;
}
.bg-header {
position: absolute;
top: 0;
width: 100%;
height: 624rpx;
}
.bg-footer {
position: fixed;
bottom: 0;
width: 100%;
height: 29.68%;
z-index: -99;
}
.prompt {
width: 100%;
margin-top: 28rpx;
.prompt-title {
height: 44rpx;
font-size: 32rpx;
font-weight: 400;
color: #222222;
line-height: 38rpx;
margin-bottom: 16rpx;
}
.prompt-detail {
height: 152rpx;
font-size: 28rpx;
font-weight: 400;
color: #999999;
line-height: 48rpx;
}
}
.active {
color: #ffffff !important;
background: #05a8ff !important;
}
.code {
width: 190rpx;
height: 40rpx;
font-size: 28rpx;
font-family: PingFang SC-Regular, PingFang SC;
text-align: right;
font-weight: 400;
color: #05a8ff;
line-height: 33rpx;
}
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论