提交 cbdb5c70 authored 作者: 刘旭's avatar 刘旭

更新修改后代码

上级 9bb0a4ee
{
"vue3snippets.enable-compile-vue-file-on-did-save-code": false
}
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="" type="png/x-icon" />
<link rel="stylesheet" href="./src/static/iconfont/iconfont.css" />
<script>
var coverSupport =
'CSS' in window &&
typeof CSS.supports === 'function' &&
(CSS.supports('top: env(a)') || CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') +
'" />'
)
</script>
</head>
<page>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</page>
<head>
<meta charset="UTF-8" />
<link rel="icon" href="" type="png/x-icon" />
<link rel="stylesheet" href="./src/static/iconfont/iconfont.css" />
<script>
var coverSupport =
"CSS" in window &&
typeof CSS.supports === "function" &&
(CSS.supports("top: env(a)") || CSS.supports("top: constant(a)"))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ", viewport-fit=cover" : "") +
'" />'
)
</script>
</head>
<page>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</page>
</html>
<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.css';
@import './scss/common.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;
max-width: 420px;
margin: 0 auto;
border-left: #f6f6f6 solid 1px;
border-right: #f6f6f6 solid 1px;
}
page {
background: #f5f5f5;
background: #f5f5f5;
}
</style>
<template>
<!-- <headers title='考勤地点设置' />
<view class="map" :style="{ height: mapState.windowHeight * 0.5 + 'px', top: mapState.searchStatus ? '-10%' : 0 }">
<map :longitude="mapState.longitude" :latitude="mapState.latitude" :show-location="true">
<view class="cotrons">
<u-button size="mini" type="primary">完成</u-button>
</view>
</map>
</view>
<view class="addr"
:style="{ height: mapState.windowHeight * 0.7 + 'px', top: mapState.searchStatus ? '50%' : '30%' }">
<uni-search-bar placeholder="课程名称/班级名称" clearButton="auto" @confirm="search" @focus="onFocus"
@cancel="onCancel" />
</view> -->
</template>
<script setup lang='ts'>
// import headers from '@/components/header/index.vue'
// import QQMapWX from '@/utils/qqmap-wx-jssdk'
// import { jsonp } from '@/utils/util';
// new QQMapWX({
// key: '3M5BZ-SFCRJ-AHSF7-XRA5Q-Y6NIJ-DXBH4' // 必填
// });
// const flag = ref(true)
// const mapState = reactive({
// windowWidth: uni.getSystemInfoSync().windowWidth,
// windowHeight: uni.getSystemInfoSync().windowHeight,
// searchStatus: true,
// longitude: '139.7902',
// latitude: '35.6513',
// markers: [
// {
// id: "gyqy",
// latitude: "29.595587852178966",
// longitude: "106.22169495575275",
// title: "企业",
// iconPath: "./images/map/currentPos.png",
// },
// ] as any,
// })
// //触发关键词输入提示事件
// const getsuggest = (e?: any) => {
// uni.getLocation({
// type: 'gcj02',
// success: function (res) {
// console.log('当前位置的经度:' + res.longitude);
// console.log('当前位置的纬度:' + res.latitude);
// }
// });
// // console.log("e", e.detail.value)
// let url = 'https://apis.map.qq.com/ws/place/v1/suggestion/?keyword=';
// jsonp(url, {
// key: '3M5BZ-SFCRJ-AHSF7-XRA5Q-Y6NIJ-DXBH4',
// keyword: '湖南',
// output: 'jsonp'
// }).then((res: any) => {
// console.log("jsonp", res)
// var sug = [];
// // for (var i = 0; i < res.data.length; i++) {
// // sug.push({ // 获取返回结果,放到sug数组中
// // title: res.data[i].title,
// // id: res.data[i].id,
// // addr: res.data[i].address,
// // city: res.data[i].city,
// // district: res.data[i].district,
// // latitude: res.data[i].location.lat,
// // longitude: res.data[i].location.lng
// // });
// // }
// })
// }
// // getsuggest()
// const search = () => {
// }
// const onFocus = () => {
// mapState.searchStatus = false
// }
// const onCancel = () => {
// mapState.searchStatus = true
// }
// const init = () => {
// uni.getLocation({
// type: 'gcj02',
// success: function (res: any) {
// console.log('当前位置的经度:' + res.longitude);
// console.log('当前位置的纬度:' + res.latitude);
// setTimeout(function () {
// mapState.longitude = res.longitude
// mapState.latitude = res.latitude
// }, 2000);
// // console.log(mapState);
// }
// });
// }
// onMounted(() => {
// init()
// })
// </script>
// <style lang="scss" scoped>
// .map {
// width: 100%;
// transition: height .3s;
// map {
// width: 100%;
// height: 100%;
// }
// .cotrons {
// text-align: end;
// padding: 20rpx;
// }
// }
// .addr {
// position: fixed;
// bottom: 0;
// width: 100%;
// background-color: #ffffff;
// // height: 500px;
// padding: 10rpx;
// transition: height .3s;
// border-top-left-radius: 20rpx;
// border-top-right-radius: 20rpx;
// }
//
</style>
\ No newline at end of file
import request from "@/utils/request"
// 查询班级
export const getClassList = (data: any) =>
request(
"/LQKJ.K3.PeiXunSystem.WebApi.WebApiService.TeachMgt,LQKJ.K3.PeiXunSystem.WebApi.common.kdsvc",
"POST",
data
)
/**
* @brief 查询每个班级通讯录信息
* @param CLASSID // 班级内码
* @return
*/
export const getClassBook = (data?: any) =>
request(
"/LQKJ.K3.PeiXunSystem.WebApi.WebApiService.ClassBook,LQKJ.K3.PeiXunSystem.WebApi.common.kdsvc",
"POST",
data
)
/**
* @brief 评价
* @param data
* @return
*/
export const remarkOn = (data?: any) =>
request(
"/LQKJ.K3.PeiXunSystem.WebApi.WebApiEditService.RemarkOn,LQKJ.K3.PeiXunSystem.WebApi.common.kdsvc",
"POST",
data
)
/**
* @brief 查看评价
* @param data
* @return
*/
export const remarkDetail = (data?: any) =>
request(
"/LQKJ.K3.PeiXunSystem.WebApi.WebApiService.RemarkDetail,LQKJ.K3.PeiXunSystem.WebApi.common.kdsvc",
"POST",
data
)
import request from "@/utils/request"
/**
* @brief 查询我的课程
* @param FMOBILE //手机号码
* @param type //0:上课中,1:已结束,2:未开始
* @return
*/
export const getCourse = (data?: any) =>
request(
"/LQKJ.K3.PeiXunSystem.WebApi.WebApiService.CourseDetail,LQKJ.K3.PeiXunSystem.WebApi.common.kdsvc",
"POST",
data
)
/**
* @brief 查询我的课程
* @param FMOBILE //手机号码
* @param type //0:上课中,1:已结束,2:未开始
* @return
*/
export const getCourseList = (data?: any) =>
request(
"/LQKJ.K3.PeiXunSystem.WebApi.WebApiService.TeachAndCourse,LQKJ.K3.PeiXunSystem.WebApi.common.kdsvc",
"POST",
data
)
/**
* @brief 查询讲师介绍和课程介绍
* @param TeachName // 班级名称
* @param CouseId // 课程内码
* @return
*/
export const getTeachDetail = (data?: any) =>
request(
"/LQKJ.K3.PeiXunSystem.WebApi.WebApiService.TeachDetail,LQKJ.K3.PeiXunSystem.WebApi.common.kdsvc",
"POST",
data
)
/**
* @brief 签到签退
* @param data
* @return
*/
export const signInAndOut = (data?: any) =>
request(
"/LQKJ.K3.PeiXunSystem.WebApi.WebApiEditService.ClockId,LQKJ.K3.PeiXunSystem.WebApi.common.kdsvc",
"POST",
data
)
/**
* @brief 查看附件
* @param data
* @return
*/
export const geFileList = (data?: any) =>
request(
"/LQKJ.K3.PeiXunSystem.WebApi.WebApiService.FilePDF,LQKJ.K3.PeiXunSystem.WebApi.common.kdsvc",
"POST",
data
)
import request from '@/utils/request'
import request from "@/utils/request"
// 登录
export const login = (data: any) => request('/lowcodeplatform-system/auth/login/app', 'POST', data)
export const getUserInfo = (code: string) => {
alert(code)
request(
"/LQKJ.K3.PeiXunSystem.WebApi.WebApiService.User,LQKJ.K3.PeiXunSystem.WebApi.common.kdsvc",
"POST",
{ code }
)
}
// 注册
export const register = (data: any) => {
request(
"/LQKJ.K3.PeiXunSystem.WebApi.WebApiEditService.Quit,LQKJ.K3.PeiXunSystem.WebApi.common.kdsvc",
"POST",
data
)
}
// 上传图片
export const uploadImage = (data: any) => {
request(
"/LQKJ.K3.PeiXunSystem.WebApi.WebApiEditService.Image,LQKJ.K3.PeiXunSystem.WebApi.common.kdsvc",
"POST",
data
)
}
import request from "@/utils/request"
/**
* @brief 查询考勤信息
* @param data
* @return
*/
export const getLocationList = (data: any) =>
request(
"/LQKJ.K3.PeiXunSystem.WebApi.WebApiService.Location,LQKJ.K3.PeiXunSystem.WebApi.common.kdsvc",
"POST",
data
)
/**
* @brief 设置考勤地位
* @param data
* @return
*/
export const setAddr= (data: any) =>
request(
"/LQKJ.K3.PeiXunSystem.WebApi.WebApiEditService.Sett,LQKJ.K3.PeiXunSystem.WebApi.common.kdsvc",
"POST",
data
)
......@@ -35,7 +35,7 @@
size="mini"
@tap="submit"
style="margin-right: 30rpx"
>完成</u-button
>下一步</u-button
>
</template>
</u-navbar>
......
{
"easycom": {
"autoscan": true,
"custom": {
"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue",
"^u-(.*)": "vk-uview-ui/components/u-$1/u-$1.vue"
}
},
"pages": [
{
"path": "pages/login/index",
"style": {
"navigationBarTitleText": "登录",
"navigationStyle": "custom"
}
},
{
"path": "pages/home/index",
"style": {
"navigationBarTitleText": "主页",
"navigationStyle": "custom"
}
},
{
"path": "pages/class/index",
"style": {
"navigationBarTitleText": "我的班级",
"navigationStyle": "custom"
}
},
{
"path": "pages/class/addressBook",
"style": {
"navigationBarTitleText": "班级通讯录",
"navigationStyle": "custom"
}
},
{
"path": "pages/class/classEvaluate",
"style": {
"navigationBarTitleText": "我的班级",
"navigationStyle": "custom"
}
},
{
"path": "pages/class/evaluate",
"style": {
"navigationBarTitleText": "培训评价",
"navigationStyle": "custom"
}
},
{
"path": "pages/course/index",
"style": {
"navigationBarTitleText": "我的课程",
"navigationStyle": "custom"
}
},
{
"path": "pages/course/seeMore",
"style": {
"navigationBarTitleText": "查看更多",
"navigationStyle": "custom"
}
},
{
"path": "pages/course/attendanceDetails",
"style": {
"navigationBarTitleText": "考勤详情",
"navigationStyle": "custom"
}
},
{
"path": "pages/setPositioning/index",
"style": {
"navigationBarTitleText": "设置考勤定位",
"navigationStyle": "custom"
}
"easycom": {
"autoscan": true,
"custom": {
"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue",
"^u-(.*)": "vk-uview-ui/components/u-$1/u-$1.vue"
}
},
{
"path": "pages/setPositioning/map",
"style": {
"navigationBarTitleText": "考勤地点设置",
"navigationStyle": "custom"
}
"pages": [
{
"path": "pages/login/index",
"style": {
"navigationBarTitleText": "登录",
"navigationStyle": "custom"
}
},
{
"path": "pages/home/index",
"style": {
"navigationBarTitleText": "主页",
"navigationStyle": "custom"
}
},
{
"path": "pages/class/index",
"style": {
"navigationBarTitleText": "我的班级",
"navigationStyle": "custom",
"onReachBottomDistance": 50
}
},
{
"path": "pages/class/addressBook",
"style": {
"navigationBarTitleText": "班级通讯录",
"navigationStyle": "custom",
"onReachBottomDistance": 50
}
},
{
"path": "pages/class/classEvaluate",
"style": {
"navigationBarTitleText": "我的班级",
"navigationStyle": "custom",
"onReachBottomDistance": 50
}
},
{
"path": "pages/class/evaluate",
"style": {
"navigationBarTitleText": "培训评价",
"navigationStyle": "custom",
"onReachBottomDistance": 50
}
},
{
"path": "pages/course/index",
"style": {
"navigationBarTitleText": "我的课程",
"navigationStyle": "custom",
"onReachBottomDistance": 50
}
},
{
"path": "pages/course/seeMore",
"style": {
"navigationBarTitleText": "查看更多",
"navigationStyle": "custom"
}
},
{
"path": "pages/course/attendanceDetails",
"style": {
"navigationBarTitleText": "考勤详情",
"navigationStyle": "custom"
}
},
{
"path": "pages/setPositioning/index",
"style": {
"navigationBarTitleText": "设置考勤定位",
"navigationStyle": "custom"
}
},
{
"path": "pages/setPositioning/map",
"style": {
"navigationBarTitleText": "考勤地点设置",
"navigationStyle": "custom"
}
},
{
"path": "pages/setPositioning/setAttendance",
"style": {
"navigationBarTitleText": "考勤地点设置",
"navigationStyle": "custom"
}
},
{
"path": "pages/class/courseArrange",
"style": {
"navigationBarTitleText": "课程安排",
"navigationStyle": "custom"
}
},
{
"path": "pages/course/pdfView",
"style": {
"navigationBarTitleText": "预览pdf",
"navigationStyle": "custom"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#fff",
"backgroundColor": "#ccc"
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#fff",
"backgroundColor": "#ccc"
}
}
<template>
<headers title='班级通讯录' />
<div class='address-book-item-container'>
<uni-search-bar placeholder="姓名/单位/电话" bgColor="#ffffff" clearButton="auto" cancelButton="none"
@confirm="search" />
<text style="margin-bottom: 20rpx; display: block;">为你找到10个的同学</text>
<view>
<block v-for="(item, i) in 6" :key="i">
<addressBookItem button-title="联系TA" />
</block>
</view>
</div>
<headers title="班级通讯录" />
<view v-if="addressBookList.length" class="address-book-item-container">
<uni-search-bar
placeholder="姓名/单位/电话"
bgColor="#ffffff"
clearButton="auto"
cancelButton="none"
@confirm="search"
/>
<text style="margin-bottom: 20rpx; display: block">为你找到10个的同学</text>
<block v-for="(item, i) in addressBookList" :key="i">
<addressBookItem
:addressBookItem="item"
buttonTitle="联系TA"
@tapButton="tapButton"
/>
</block>
<view style="padding: 20rpx">
<u-loadmore :status="status" icon-type="flower" />
</view>
</view>
<view v-else class="empty">
<u-empty text="暂无数据" mode="list"></u-empty>
</view>
</template>
<script setup lang='ts'>
import headers from '@/components/header/index.vue'
import addressBookItem from './components/addressBookItem.vue'
<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"
const globalStore = useGlobalStore()
const listQuery = reactive({
Phone: globalStore.Phone,
classId: "",
pageIndex: 1,
pageSize: 10,
total: 0,
})
const status = ref("loadmore")
const addressBookList = ref([] as any)
onLoad((options: any) => {
listQuery.classId = options.classId
init()
})
const search = (val: string) => {
console.log('我的同学' + val);
console.log("我的同学" + val)
}
const tapButton = (phone: string) => {
location.href = "tel:" + phone
}
const init = async () => {
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
console.log(res.data)
}
}
// 上拉加载数据
onReachBottom(() => {
// 判断是否还有下一页数据
if (listQuery.pageIndex * listQuery.pageSize >= listQuery.total)
return (status.value = "nomore")
// // 判断是否正在请求其它数据,如果是,则不发起额外的请求
if (status.value === "loading") return
listQuery.pageIndex += 1
init()
})
</script>
<style lang="scss" scoped>
.address-book-item-container {
padding: 0 30rpx;
padding: 0 30rpx;
.uni-searchbar {
padding: 0;
margin: 20rpx 0;
}
.uni-searchbar {
padding: 0;
margin: 20rpx 0;
}
}
</style>
\ No newline at end of file
</style>
<template>
<headers title='我的班级' />
<view class='eval-container'>
<u-tabs :list="tabsState.list" :is-scroll="false" v-model="tabsState.current" bg-color="#f5f5f5"
@change="tabsChange" />
<headers title="我的班级" />
<view v-if="addressBookList.length" class="address-book-item-container">
<uni-search-bar
placeholder="姓名/单位/电话"
bgColor="#ffffff"
clearButton="auto"
cancelButton="none"
@confirm="search"
/>
<text style="margin-bottom: 20rpx; display: block">为你找到10个的同学</text>
<!-- 内容 -->
<view v-if="true">
<!-- 搜索 -->
<uni-search-bar placeholder="班级名称" bgColor="#ffffff" clearButton="auto" cancelButton="none"
@confirm="search" />
<text style="margin-bottom: 20rpx; display: block;">为你找到10个的班级</text>
<view>
<block v-for="(item, i) in 6" :key="i">
<addressBookItem :button-title="buttonTitle" @tapButton="tapButton" />
</block>
</view>
</view>
<view v-else class="empty">
<u-empty text="暂无数据" mode="list"></u-empty>
</view>
<block v-for="(item, i) in addressBookList" :key="i">
<addressBookItem
:addressBookItem="item"
buttonTitle="查看评价"
@tapButton="tapButton"
/>
</block>
<view style="padding: 20rpx">
<u-loadmore :status="status" icon-type="flower" />
</view>
</view>
<view v-else class="empty">
<u-empty text="暂无数据" mode="list"></u-empty>
</view>
</template>
<script setup lang='ts'>
import headers from '@/components/header/index.vue'
import addressBookItem from './components/addressBookItem.vue'
<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"
const tabsState = reactive({
list: [{
name: '已评价'
}, {
name: '未评价'
}],
current: 0
const globalStore = useGlobalStore()
const listQuery = reactive({
Phone: globalStore.Phone,
classId: "",
pageIndex: 1,
pageSize: 10,
total: 0,
})
const status = ref("loadmore")
const addressBookList = ref([] as any)
const buttonTitle = ref('查看评价')
const tabsChange = (index: number) => {
console.log(index);
if (index) {
buttonTitle.value = ''
} else buttonTitle.value = '查看评价'
onLoad((options: any) => {
listQuery.classId = options.classId
init()
})
const search = (val: string) => {
console.log("我的同学" + val)
}
const search = (val: string) => {
console.log('我的班级' + val);
const tapButton = (classId: string, studentId: string) => {
uni.navigateTo({
url: "/pages/class/evaluate?classId=" + classId + "&studentId=" + studentId,
})
}
const tapButton = () => {
uni.navigateTo({
url: '/pages/class/evaluate'
})
const init = async () => {
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
console.log(res.data)
}
}
// 上拉加载数据
onReachBottom(() => {
// 判断是否还有下一页数据
if (listQuery.pageIndex * listQuery.pageSize >= listQuery.total)
return (status.value = "nomore")
// // 判断是否正在请求其它数据,如果是,则不发起额外的请求
if (status.value === "loading") return
listQuery.pageIndex += 1
init()
})
</script>
<style lang="scss" scoped>
.eval-container {
padding: 0 30rpx 30rpx;
.address-book-item-container {
padding: 0 30rpx;
.uni-searchbar {
padding: 0;
margin: 20rpx 0;
}
.uni-searchbar {
padding: 0;
margin: 20rpx 0;
}
}
</style>
\ No newline at end of file
</style>
<template>
<div class='address-book-container'>
<u-card :show-head="false" :show-foot="false" margin="0" border-radius="20">
<template #body>
<view class="address-book-content">
<view class="left">
<u-image width="160rpx" height="160rpx" :src="src"></u-image>
<view class="content">
<h4>刘芳芳</h4>
<text class="tel">15611111111</text>
<text>单位:南山区南山街道办</text>
</view>
</view>
<div class="address-book-container">
<u-card :show-head="false" :show-foot="false" margin="0" border-radius="20">
<template #body>
<view class="address-book-content">
<view class="left">
<u-image width="160rpx" height="160rpx" :src="src"></u-image>
<view class="content">
<h4>{{ addressBookItem.stuName }}</h4>
<text class="tel">{{ addressBookItem.Phone }}</text>
<text>单位: {{ addressBookItem.stuUnit }}</text>
</view>
</view>
<u-button v-show="buttonTitle" size="mini" type="primary" @tap="tapButton">{{ buttonTitle }}
</u-button>
</view>
</template>
</u-card>
</div>
<u-button
v-show="buttonTitle"
size="mini"
type="primary"
@tap="tapButton"
>{{ buttonTitle }}
</u-button>
</view>
</template>
</u-card>
</div>
</template>
<script setup lang='ts'>
import { src } from '@/utils/example';
<script setup lang="ts">
import { src } from "@/utils/example"
defineProps({
buttonTitle: String
const props = defineProps({
addressBookItem: {
type: Array,
default: () => [],
} as any,
buttonTitle: String,
})
const emits = defineEmits(['tapButton'])
const emits = defineEmits(["tapButton"])
const tapButton = () => {
emits('tapButton')
if (props.buttonTitle === "联系TA")
emits("tapButton", props.addressBookItem.Phone)
else
emits(
"tapButton",
props.addressBookItem.FCLASS,
props.addressBookItem.studentId
)
}
</script>
<style lang="scss" scoped>
.address-book-container {
margin-bottom: 32rpx;
height: 200rpx;
.address-book-content {
margin-bottom: 32rpx;
height: 200rpx;
display: flex;
justify-content: space-between;
align-items: center;
.address-book-content {
display: flex;
justify-content: space-between;
align-items: center;
.left {
display: flex;
.left {
display: flex;
.content {
display: flex;
flex-direction: column;
justify-content: flex-end;
margin-left: 20rpx;
.content {
display: flex;
flex-direction: column;
justify-content: flex-end;
margin-left: 20rpx;
.tel {
margin: 20rpx 0;
}
}
.tel {
margin: 20rpx 0;
}
}
}
uni-button {
margin: 0;
}
uni-button {
margin: 0;
}
}
}
</style>
\ No newline at end of file
</style>
......@@ -28,6 +28,8 @@
</template>
<script setup lang='ts'>
const props = defineProps({
arrangeList: {
type: Array,
......
<template>
<div class='class-item-container'>
<u-card :show-head="false" margin="0" border-radius="20">
<template #body>
<view class="calss-header">
<h3>{{ classList.title }}</h3>
<!-- <u-button v-show="current == 2" size="mini" type="primary" @tap="toEvaluate">去评价</u-button> -->
</view>
<view class="item">
<text>课程时间:</text>
<text>{{ classList.dateStart }}{{ classList.dateEnd }}</text>
</view>
<view class="item">
<text>教室地点:</text>
<text>{{ classList.address }}</text>
</view>
<view>
</view>
<view class="progress item">
<text>课程进度:</text>
<u-line-progress active-color="#2979ff" :percent="percent" :height="25" />
</view>
<view class="class-teacher item">
<text>班主任:</text>
<u-tag v-for="(item, index) in classList.classTeacher" :key="index" :text="item" shape="circle" />
</view>
</template>
<template #foot>
<view class="class-footer">
<u-button size="mini" plain @tap="toAddressBook">班级通讯录</u-button>
<u-button size="mini" plain>班级二维码</u-button>
<u-button type="primary" size="mini" plain @tap="toClassEvaluate">培训评价</u-button>
</view>
</template>
</u-card>
</div>
</template>
<script setup lang='ts'>
<view class="class-item-container">
<u-card :show-head="false" margin="0" border-radius="20">
<template #body>
<view class="calss-header">
<h3>{{ classItem.className }}</h3>
<u-button
v-show="current == 2"
size="mini"
type="primary"
@tap="toEvaluate"
>查看评价</u-button
>
</view>
<view class="item">
<text>课程时间:</text>
<text>{{ classItem.startDate }}{{ classItem.endDate }}</text>
</view>
<view class="item">
<text>教室地点:</text>
<text>{{ classItem.classArea }}</text>
</view>
<view> </view>
<view class="progress item">
<text>课程进度:</text>
<u-line-progress
active-color="#2979ff"
:percent="percent ? percent : 0"
:height="25"
/>
</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>
</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"
>课程安排</u-button
>
</view>
</template>
</u-card>
</view>
<saveQrCode v-model="show" />
</template>
<script setup lang="ts">
import saveQrCode from "./saveQrCode.vue"
const props = defineProps({
classList: {
type: Array,
default: () => []
} as any,
current: {
type: Number,
default: 0
}
classItem: {
type: Array,
default: () => [],
} as any,
current: {
type: Number,
default: 0,
},
})
const percent = computed(() => {
return props.classList.currentProgress / props.classList.overallProgress * 100
})
const show = ref(false)
const percent = computed(
() =>
(props.classItem.coursePro[0]?.SumPro / props.classItem.courseSum[0].Sum) *
100
)
const classQrCode = () => {
show.value = true
}
const toAddressBook = () => {
uni.navigateTo({
url: '/pages/class/addressBook'
})
uni.navigateTo({
url: "/pages/class/addressBook?classId=" + props.classItem.classId,
})
}
const toClassEvaluate = () => {
uni.navigateTo({
url: '/pages/class/classEvaluate'
})
const toCourseArrange = () => {
uni.navigateTo({
url: "/pages/class/courseArrange?classId=" + props.classItem.classId,
})
}
const toEvaluate = () => {
uni.navigateTo({
url: '/pages/class/evaluate'
})
uni.navigateTo({
url: "/pages/class/classEvaluate?classId=" + props.classItem.classId,
})
}
</script>
<style lang="scss" scoped>
.class-item-container {
margin-bottom: 20rpx;
margin-bottom: 20rpx;
.calss-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16rpx;
.calss-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16rpx;
h3 {
margin: 0
}
h3 {
margin: 0;
}
uni-button {
margin: 0;
}
uni-button {
margin: 0;
}
}
.item {
display: flex;
align-items: flex-start;
.item {
display: flex;
align-items: flex-start;
text {
display: block;
padding: 12rpx 0;
font-size: 32rpx;
}
text {
display: block;
padding: 12rpx 0;
font-size: 28rpx;
}
text:first-child {
width: 160rpx;
}
text:first-child {
width: 160rpx;
}
text:last-child {
flex: 1;
}
text:last-child {
flex: 1;
}
}
.progress {
display: flex;
align-items: center;
.progress {
display: flex;
align-items: center;
text {
white-space: nowrap;
}
text {
white-space: nowrap;
}
.registered {
margin-left: 30rpx;
color: #3b99fc;
}
.registered {
margin-left: 30rpx;
color: #3b99fc;
}
}
.class-teacher {
display: flex;
align-items: center;
.class-teacher {
display: flex;
align-items: center;
.u-tag {
margin-right: 20rpx;
}
.u-tag {
margin-right: 20rpx;
}
}
.class-footer {
width: 100%;
display: flex;
justify-content: end;
.class-footer {
width: 100%;
display: flex;
justify-content: flex-end;
uni-button {
margin-left: 30rpx;
margin-right: 0;
}
uni-button {
margin-left: 30rpx;
margin-right: 0;
}
}
}
</style>
\ No newline at end of file
</style>
<template>
<u-popup
v-model="props.show"
mode="center"
closeable
border-radius="15"
width="80%"
>
<view class="qrcode">
<view class="title">班级二维码</view>
<view class="image">
<u-image
width="100%"
height="500rpx"
:src="qrCodeUrl"
ref="canvasRef"
/>
</view>
</view>
<view class="footer">
<u-button type="primary" size="medium" @tap="updateImage"
>更新二维码</u-button
>
<u-button type="success" size="medium" @tap="saveImage(qrCodeUrl)"
>保存二维码</u-button
>
</view>
</u-popup>
</template>
<script setup lang="ts">
import { qrCodeUrl } from "@/utils/example"
import { toast } from "@/utils/util"
import html2canvas from "html2canvas"
const props = defineProps({
show: Boolean,
})
const canvasRef = ref()
const updateImage = () => {
uni.chooseImage({
count: 1,
success: (chooseImageRes) => {
const tempFilePaths = chooseImageRes.tempFilePaths
uni.uploadFile({
url: "https://www.example.com/upload", //仅为示例,非真实的接口地址
filePath: tempFilePaths[0],
name: "file",
formData: {
user: "test",
},
success: (uploadFileRes) => {
console.log(uploadFileRes.data)
},
})
},
})
}
const saveImage = (url: string) => {
// savePic(url)
downloadImage(url)
}
function downloadImage(url: string) {
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)
}
</script>
<style lang="scss" scoped>
:deep(.u-mode-center-box) {
background-color: transparent;
}
.qrcode {
padding: 24rpx;
background-color: #fff;
border-bottom-right-radius: 15rpx;
border-bottom-left-radius: 15rpx;
.title {
font-size: larger;
font-weight: bolder;
}
.image {
padding: 46rpx;
}
}
.footer {
box-sizing: border-box;
margin-top: 50rpx;
background-color: #fff;
border-top-left-radius: 10rpx;
border-top-right-radius: 10rpx;
padding: 20rpx;
display: flex;
.u-btn {
width: 45%;
}
}
</style>
<template>
<headers title="课程安排" />
<view v-if="arrangeList.length" class="course-arrange-container">
<view class="progress">
<text>课程进度:</text>
<u-line-progress
active-color="#2979ff"
:percent="percent ? percent : 0"
:height="25"
/>
</view>
<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>
</template>
<template #content>
<arrangeItem :arrangeItem="item" />
</template>
</u-time-line-item>
</u-time-line>
<view style="padding: 20rpx">
<u-loadmore :status="status" icon-type="flower" />
</view>
</view>
<view v-else class="empty">
<u-empty text="暂无课程安排" mode="list" />
</view>
</template>
<script setup lang="ts">
import headers from "@/components/header/index.vue"
import arrangeItem from "./components/arrangeItem.vue"
import { getCourse } from "@/api/course"
import { useGlobalStore } from "@/store/useStore"
const arrangeList = ref([] as any)
const globalStore = useGlobalStore()
const percent = ref()
const listQuery = reactive({
Phone: globalStore.Phone,
pageIndex: 1,
pageSize: 999,
total: 0,
type: 2,
classId: "",
})
const status = ref("loadmore")
onLoad((options: any) => {
listQuery.classId = options.classId
init()
})
// 上拉加载数据
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 getCourse(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(
(item: any) => item.courseType === 2
).length
percent.value = (num / res.total) * 100
// console.log(arrangeList.value)
}
}
</script>
<style lang="scss" scoped>
.course-arrange-container {
padding: 0 20rpx;
.progress {
display: flex;
align-items: center;
justify-content: center;
padding: 26rpx 10rpx 50rpx 30rpx;
text {
display: block;
padding: 12rpx 0;
font-size: 32rpx;
white-space: nowrap;
}
.registered {
margin-left: 30rpx;
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);
}
}
</style>
<template>
<headers title='我的班级' />
<view class='class-container'>
<u-tabs :list="tabsState.list" :is-scroll="false" v-model="tabsState.current" bg-color="#f5f5f5"
@change="tabsChange" />
<headers title="我的班级" />
<view class="class-container">
<u-tabs
:list="tabsState.list"
:is-scroll="false"
v-model="tabsState.current"
bg-color="#f5f5f5"
@change="tabsChange"
/>
<!-- 内容 -->
<view v-if="classList.length">
<!-- 搜索 -->
<uni-search-bar placeholder="班级名称" bgColor="#ffffff" clearButton="auto" cancelButton="none"
@confirm="search" />
<text style="margin-bottom: 20rpx; display: block;">为你找到10个的班级</text>
<!-- 内容 -->
<view v-if="classList.length">
<!-- 搜索 -->
<uni-search-bar
placeholder="班级名称"
bgColor="#ffffff"
clearButton="auto"
cancelButton="none"
@confirm="search"
/>
<text style="margin-bottom: 20rpx; display: block"
>为你找到10个的班级</text
>
<template v-for="(item, index) in classList" :key="index">
<classItem :classList="item" :current="tabsState.current" />
</template>
</view>
<view v-else class="empty">
<u-empty text="暂无数据" mode="list"></u-empty>
</view>
<block v-for="(item, index) in classList" :key="index">
<classItem :classItem="item" :current="tabsState.current" />
</block>
<view v-if="tabsState.current" style="padding: 20rpx">
<u-loadmore :status="status" icon-type="flower" />
</view>
</view>
<view v-else class="empty">
<u-empty text="暂无数据" mode="list"></u-empty>
</view>
</view>
</template>
<script setup lang='ts'>
import headers from '@/components/header/index.vue'
import classItem from './components/classItem.vue'
<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"
const globalStore = useGlobalStore()
const tabsState = reactive({
list: [{
name: '进行中'
}, {
name: '未开课'
list: [
{
name: "进行中",
},
{
name: "未开课",
},
{
name: '已结课'
}],
current: 0
name: "已结课",
},
],
current: 0,
})
const tabsChange = (index: number) => {
console.log(index);
const classList = ref([] as any)
const listQuery = reactive({
Phone: globalStore.Phone,
type: 0,
studentId: globalStore.studentId,
pageIndex: 1,
pageSize: 10,
total: 0,
})
const status = ref("loadmore")
const tabsChange = (index: number) => {
classList.value = []
switch (index) {
case 0:
listQuery.type = 0
break
case 1:
listQuery.type = 1
break
default:
listQuery.type = 2
break
}
init()
}
const search = (val: string) => {
console.log('我的班级' + val);
console.log("我的班级" + val)
}
const classList = ref([{
title: '党支部书记班',
dateStart: '2022-04-01 09:00', // 课程开始时间
dateEnd: '2022-04-07 09:00', // 课程结束时间
address: '深圳市南山区西丽街道办公室', // 课程地点
overallProgress: 6, // 总进度
currentProgress: 3, // 当前进度
classTeacher: ['郭敬明', '王少龙'] // 班主任
}])
// 上拉加载数据
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 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
console.log(classList.value)
}
}
init()
</script>
<style lang="scss" scoped>
.class-container {
padding: 0 30rpx 30rpx;
padding: 0 30rpx 30rpx;
.uni-searchbar {
padding: 0;
margin: 20rpx 0;
}
.uni-searchbar {
padding: 0;
margin: 20rpx 0;
}
}
</style>
\ No newline at end of file
</style>
<template>
<u-popup v-model="props.show" mode="bottom" closeable height="40%" border-radius="30" @close="handeClose">
<view class="info">
<text class="title">课程资料</text>
<view v-for="(item, i) in 10" class="item">
<view>
<u-icon name="order" size="50"></u-icon>
<text>党性学习第一节课件.pdf</text>
</view>
<view>
<u-icon name="eye-fill" size="50" style="margin-right: 30rpx;"></u-icon>
<u-icon name="download" size="50"></u-icon>
</view>
</view>
<u-popup
v-model="props.show"
mode="bottom"
closeable
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>
</view>
</u-popup>
</block>
<view v-else class="empty">
<u-empty text="暂无资料" mode="list" />
</view>
</view>
</u-popup>
</template>
<script setup lang='ts'>
<script setup lang="ts">
import { zconfirm } from "@/utils/util"
import { geFileList } from "@/api/course"
import { baseUrl } from "@/utils/request"
const props = defineProps({
show: {
type: Boolean,
default: false
}
show: {
type: Boolean,
default: false,
},
courseNumber: {
type: String,
default: "",
},
})
const emits = defineEmits(['update:show'])
const emits = defineEmits(["update:show"])
const pdfView = (item: any) => {
uni.navigateTo({
url:
"/pages/course/pdfView?name=" +
item.name +
"&url=" +
encodeURIComponent(baseUrl + "/" + item.url),
})
}
const infoList = ref([] as any)
const downLoadPdf = (item: any) => {
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 handeClose = () => {
emits('update:show', false)
emits("update:show", false)
}
const init = async () => {
const { data: res } = await geFileList({ courseNumber: props.courseNumber })
if (res.code == 200) {
console.log(res)
infoList.value = res.data
}
}
defineExpose({
init,
})
</script>
<style lang="scss" scoped>
.info {
display: flex;
flex-direction: column;
align-items: center;
padding: 0 30rpx;
.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%;
}
.item {
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
padding: 0 30rpx;
background-color: $u-type-info-light;
width: 100%;
height: 100rpx;
padding: 30rpx;
border-radius: 10rpx;
margin-bottom: 20rpx;
.title {
// position: sticky;
// top: 0;
// left: 0;
height: 90rpx;
line-height: 90rpx;
view {
display: flex;
align-items: center;
text {
margin-left: 10rpx;
display: block;
font-size: 32rpx;
font-weight: bolder;
color: $u-main-color;
text-align: center;
width: 100%;
color: #000000;
}
}
}
}
</style>
.item {
display: flex;
justify-content: space-between;
align-items: center;
background-color: $u-type-info-light;
width: 100%;
height: 100rpx;
padding: 20rpx;
border-radius: 10rpx;
margin-bottom: 20rpx;
view {
display: flex;
align-items: center;
text {
margin-left: 10rpx;
display: block;
font-size: 32rpx;
color: #000000;
}
}
}
<style>
:deep(uni-modal) {
z-index: 19999 !important;
}
</style>
\ No newline at end of file
</style>
<template>
<headers title='我的课程' />
<view class='course-container'>
<u-tabs :list="tabsState.list" :is-scroll="false" v-model="tabsState.current" bg-color="#f5f5f5"
@change="tabsChange" />
<!-- 内容 -->
<view v-if="courseList.length">
<!-- 搜索 -->
<uni-search-bar placeholder="班级名称" bgColor="#ffffff" clearButton="auto" cancelButton="none"
@confirm="search" />
<text style="margin-bottom: 20rpx; display: block;">为你找到10个的班级</text>
<block v-for="(item, index) in courseList" :key="index">
<courseItem :courseList="item" :current="tabsState.current" />
</block>
</view>
<view v-else class="empty">
<u-empty text="暂无数据" mode="list" />
</view>
<headers title="我的课程" />
<view class="course-container">
<u-tabs
:list="tabsState.list"
:is-scroll="false"
v-model="tabsState.current"
bg-color="#f5f5f5"
@change="tabsChange"
/>
<!-- 内容 -->
<view v-if="courseList.length">
<!-- 搜索 -->
<uni-search-bar
placeholder="班级名称"
bgColor="#ffffff"
clearButton="auto"
cancelButton="none"
@confirm="search"
/>
<text style="margin-bottom: 20rpx; display: block"
>为你找到10个的班级</text
>
<block v-for="(item, index) in courseList" :key="index">
<courseItem :courseItem="item" :current="tabsState.current" />
</block>
<view v-if="tabsState.current" style="padding: 20rpx">
<u-loadmore :status="status" icon-type="flower" />
</view>
</view>
<view v-else class="empty">
<u-empty text="暂无数据" mode="list" />
</view>
</view>
</template>
<script setup lang='ts'>
import headers from '@/components/header/index.vue'
import courseItem from './components/courseItem.vue';
import { inClass, notStarted } from './demo'
<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"
const globalStore = useGlobalStore()
const tabsState = reactive({
list: [{
name: '上课中'
}, {
name: '未开始'
}, {
name: '已下课'
}
],
current: 0
list: [
{
name: "上课中",
},
{
name: "未开始",
},
{
name: "已下课",
},
],
current: 0,
})
const courseList: any = ref(inClass)
const courseList = ref([] as any)
const listQuery = reactive({
Phone: globalStore.Phone,
pageIndex: 1,
pageSize: 10,
total: 0,
type: 0,
})
const status = ref("loadmore")
const tabsChange = (index: number) => {
if (index) courseList.value = notStarted
else courseList.value = inClass
courseList.value = []
switch (index) {
case 0:
listQuery.type = 0
break
case 1:
listQuery.type = 1
break
default:
listQuery.type = 2
break
}
init()
}
const search = (val: string) => {
console.log('我的课程' + val);
console.log("我的班级" + val)
}
// 上拉加载数据
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 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
console.log(courseList.value)
}
}
init()
</script>
<style lang="scss" scoped>
.course-container {
padding: 0 30rpx 30rpx;
padding-top: 20rpx;
padding: 0 30rpx 30rpx;
padding-top: 20rpx;
.uni-searchbar {
padding: 0;
margin: 20rpx 0;
}
.uni-searchbar {
padding: 0;
margin: 20rpx 0;
}
.tag .u-tag {
margin-right: 20rpx;
}
.tag .u-tag {
margin-right: 20rpx;
}
}
</style>
\ No newline at end of file
</style>
<template>
<headers :title="pdfState.title" />
<view class="pdf-container">
<web-view class="webview" :src="pdfState.pdfUrl"></web-view>
</view>
</template>
<script setup lang="ts">
import headers from "@/components/header/index.vue"
const pdfState = reactive({
title: "",
pdfUrl: "",
viewerUrl: "/static/pdf/web/viewer.html",
})
onLoad((options: any) => {
pdfState.title = options.name
pdfState.pdfUrl =
pdfState.viewerUrl + "?file=" + encodeURIComponent(options.url)
})
</script>
<style lang="scss" scoped>
.pdf-container {
width: 100vw;
height: 100vh;
.webview {
height: 90%;
}
}
</style>
<template>
<u-form :model="loginForm" ref="loginFormRef" :rules="loginFormRules" style="margin-top: 40rpx;" label-posi>
<u-form-item :leftIconStyle="{ color: '#888', fontSize: '32rpx' }" left-icon="account" label-width="150"
label-position="left" label="用户名" prop="username">
<u-input placeholder="请输入用户名" v-model="loginForm.username" type="text" />
</u-form-item>
<u-form-item label="密码" :leftIconStyle="{ color: '#888', fontSize: '32rpx' }" left-icon="lock"
<u-form
:model="loginForm"
ref="loginFormRef"
:rules="loginFormRules"
style="margin-top: 40rpx"
label-posi
>
<u-form-item
:leftIconStyle="{ color: '#888', fontSize: '32rpx' }"
left-icon="account"
label-width="150"
label-position="left"
label="用户名"
prop="username"
>
<u-input
placeholder="请输入用户名"
v-model="loginForm.username"
type="text"
/>
</u-form-item>
<!-- <u-form-item label="密码" :leftIconStyle="{ color: '#888', fontSize: '32rpx' }" left-icon="lock"
label-width="150rpx" prop="password">
<u-input type="password" v-model="loginForm.password" placeholder="请输入密码" />
</u-form-item>
</u-form>
<button @tap="tapLogin" class="getCaptcha">登录</button>
</u-form-item> -->
</u-form>
<button @tap="tapLogin" class="getCaptcha">登录</button>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { Login } from '../interface';
import { login } from '@/api/login'
import { useGlobalStore } from '@/store/useStore';
import { ref, reactive, onMounted } from "vue"
import { Login } from "../interface"
import { useGlobalStore } from "@/store/useStore"
const globalStore = useGlobalStore()
const loginFormRef = ref()
const loginForm = reactive<Login.LoginForm>({
username: 'admin',
password: '123456'
username: "999666",
password: "123456",
})
const loginFormRules = reactive({
username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
username: [{ required: true, message: "请输入用户名", trigger: "blur" }],
password: [{ required: true, message: "请输入密码", trigger: "blur" }],
})
let tapLogin = () => {
uni.navigateTo({
url: '/pages/home/index'
})
// loginFormRef.value?.validate(async (valid: boolean) => {
// if (valid) {
// const { data: res } = await login(loginForm)
// if (res.code === 200) {
// globalStore.setToken(res.data.token)
// uni.reLaunch({
// url: '/pages/home/index'
// })
// }
// } else {
// console.log('验证失败');
// }
// });
};
globalStore.setPhone(loginForm.username)
uni.navigateTo({
url: "/pages/home/index",
})
}
onMounted(() => loginFormRef.value?.setRules(loginFormRules))
</script>
<style lang="scss" scoped>
.getCaptcha {
width: 500rpx;
background-color: rgb(253, 243, 208);
color: $u-tips-color;
border: none;
font-size: 30rpx;
margin-top: 20rpx;
width: 500rpx;
background-color: rgb(253, 243, 208);
color: $u-tips-color;
border: none;
font-size: 30rpx;
margin-top: 20rpx;
&::after {
border: none;
}
&::after {
border: none;
}
}
:deep(.uicon-eye:before) {
font-size: 40rpx;
font-size: 40rpx;
}
:deep(.uicon-eye-fill:before) {
font-size: 40rpx;
font-size: 40rpx;
}
:deep(.u-input) {
justify-content: center;
align-items: center;
justify-content: center;
align-items: center;
}
</style>
<template>
<headers title='西部人力培训中心' backIconName='close' />
<view style="box-sizing: border-box;">
<view class="login-container">
<text class="login-text">欢迎登陆</text>
<loginForm />
</view>
</view>
<headers title="西部人力培训中心" backIconName="close" />
<view style="box-sizing: border-box">
<view class="login-container">
<text class="login-text">欢迎登陆</text>
<loginForm />
</view>
</view>
<h4>{{ "用户code:" + code + "---" + Msg }}</h4>
</template>
<script setup lang="ts">
import headers from '@/components/header/index.vue'
import loginForm from './components/loginForm.vue';
import headers from "@/components/header/index.vue"
import loginForm from "./components/loginForm.vue"
import { getUrlCode } from "@/utils/util"
import { getUserInfo } from "@/api/login"
const Msg = ref()
const code = ref()
onLoad(async () => {
code.value = getUrlCode().code
const url =
"https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx459ae5e7c5918bf3&redirect_uri=https%3A%2F%2Fweixin3.lingqingkeji.com&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect"
if (code.value) {
const res = await getUserInfo(code.value)
Msg.value = JSON.stringify(res)
alert(JSON.stringify(res))
// if (res.code == 200) {
// alert(JSON.stringify(res.data))
// }
}
// else location.href = url
})
</script>
<style lang="scss" scoped>
:deep(uni-page-wrapper) {
background-color: #fff;
background-color: #fff;
}
:deep(uni-page) {
padding: 0 6rpx;
box-sizing: border-box;
padding: 0 6rpx;
box-sizing: border-box;
}
.login-container {
box-sizing: border-box;
padding-top: 20%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
background-color: #fff;
box-sizing: border-box;
padding-top: 20%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
background-color: #fff;
.login-text {
margin-top: 10%;
font-weight: 700;
font-size: 40rpx;
color: #1d2b5f;
}
.login-text {
margin-top: 10%;
font-weight: 700;
font-size: 40rpx;
color: #1d2b5f;
}
}
</style>
<template>
<div class='position-container'>
<u-card :show-head="false" margin="0">
<template #body>
<view class="position-header">
<h3>上课地点:{{ positionList.title }}</h3>
</view>
<view class="item">
<text>上课地点:{{ positionList.address }}</text>
</view>
<view class="item">
<text>考勤定位:{{ positionList.isSetPosition ? '已设置' : '未设置' }}</text>
</view>
<view class="item">
<text>应用范围:{{ positionList.range }}</text>
</view>
</template>
<template #foot>
<view class="position-footer">
<text>所属班级:{{ positionList.class }}</text>
<u-button type="primary" size="mini" @tap="openMap">{{ current ? '修改定位' : '设置定位' }}</u-button>
</view>
</template>
</u-card>
</div>
<div class="position-container">
<u-card :show-head="false" margin="0">
<template #body>
<view class="position-header">
<h3>{{ positionItem.courseName }}</h3>
</view>
<view class="item">
<text>上课地点:{{ positionItem.classArea }}</text>
</view>
<view class="item">
<text
>考勤定位:{{
positionItem.isSetPosition ? "已设置" : "未设置"
}}</text
>
</view>
<view class="item">
<text
>应用范围:{{
positionItem.range ? positionItem.range + "米" : "未设置"
}}</text
>
</view>
</template>
<template #foot>
<view class="position-footer">
<text>所属班级:{{ positionItem.className }}</text>
<u-button type="primary" size="mini" @tap="openMap">{{
current ? "修改定位" : "设置定位"
}}</u-button>
</view>
</template>
</u-card>
</div>
</template>
<script setup lang='ts'>
<script setup lang="ts">
import { useMapStore } from "@/store/modules/mapStore"
const props = defineProps({
positionList: {
type: Array,
default: () => []
} as any,
current: {
type: Number,
default: 0
}
positionItem: {
type: Array,
default: () => [],
} as any,
current: {
type: Number,
default: 0,
},
})
const mapStore = useMapStore()
const openMap = () => {
uni.navigateTo({
url: '/pages/setPositioning/map'
})
uni.navigateTo({
url: "/pages/setPositioning/map",
success() {
mapStore.setMapData(props.positionItem)
}
})
}
</script>
<style lang="scss" scoped>
.position-container {
.position-header {
margin-bottom: 30rpx;
}
margin-bottom: 20rpx;
.position-header {
margin-bottom: 30rpx;
}
.item {
margin-bottom: 20rpx;
}
.item {
margin-bottom: 20rpx;
}
.position-footer {
display: flex;
justify-content: space-between;
.position-footer {
display: flex;
justify-content: space-between;
.u-btn {
margin: 0;
}
.u-btn {
margin: 0;
}
}
}
</style>
\ No newline at end of file
</style>
<template>
<headers title='设置考勤定位' />
<div class='set-position-container'>
<u-tabs :list="tabsState.list" :is-scroll="false" v-model="tabsState.current" bg-color="#f5f5f5"
@change="tabsChange" />
<!-- 内容 -->
<view v-if="positionList.length">
<!-- 搜索 -->
<uni-search-bar placeholder="课程名称/班级名称" bgColor="#ffffff" clearButton="auto" cancelButton="none"
@confirm="search" />
<headers title="设置考勤定位" />
<div class="set-position-container">
<u-tabs
:list="tabsState.list"
:is-scroll="false"
v-model="tabsState.current"
bg-color="#f5f5f5"
@change="tabsChange"
/>
<!-- 内容 -->
<view v-if="positionList.length">
<!-- 搜索 -->
<uni-search-bar
placeholder="课程名称/班级名称"
bgColor="#ffffff"
clearButton="auto"
cancelButton="none"
@confirm="search"
/>
<text style="margin-bottom: 20rpx; display: block;">为你找到10个的课程</text>
<text style="margin-bottom: 20rpx; display: block"
>为你找到10个的课程</text
>
<block v-for="(item, index) in positionList" :key="index">
<setPositionItem :positionList="item" :current="tabsState.current" />
</block>
</view>
<view v-else class="empty">
<u-empty text="暂无数据" mode="list" />
</view>
</div>
<block v-for="(item, index) in positionList" :key="index">
<setPositionItem :positionItem="item" :current="tabsState.current" />
</block>
<view style="padding: 20rpx">
<u-loadmore :status="status" icon-type="flower" />
</view>
</view>
<view v-else class="empty">
<u-empty text="暂无数据" mode="list" />
</view>
</div>
</template>
<script setup lang='ts'>
import headers from '@/components/header/index.vue'
import setPositionItem from './components/setPositionItem.vue';
<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"
const globalStore = useGlobalStore()
const tabsState = reactive({
list: [{
name: '未设置'
}, {
name: '已设置'
}
],
current: 0
list: [
{
name: "未设置",
},
{
name: "已设置",
},
],
current: 0,
})
const positionList: any = ref([{
title: '第一节党性学习',
address: '深圳市南山区西丽街道办公室', // 上课地点
isSetPosition: false, // 考勤定位
range: '未设置',
class: '党支部培训班'
}])
const positionList: any = ref([] as any)
const listQuery = reactive({
Phone: globalStore.Phone,
pageIndex: 1,
pageSize: 10,
total: 0,
type: 0,
})
const status = ref("loadmore")
const tabsChange = (index: number) => {
positionList.value = []
if (index) {
listQuery.type = 1
} else {
listQuery.type = 0
}
init()
}
const search = (val: string) => {
console.log('我的课程' + val);
console.log("我的课程" + val)
}
// 上拉加载数据
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 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
console.log(positionList.value)
}
}
init()
</script>
<style lang="scss" scoped>
.set-position-container {
padding: 0 30rpx 30rpx;
padding-top: 20rpx;
.tag {
margin-bottom: 30rpx;
padding: 0 30rpx 30rpx;
padding-top: 20rpx;
.u-tag {
margin-right: 20rpx;
.tag {
margin-bottom: 30rpx;
}
.u-tag {
margin-right: 20rpx;
}
}
}
</style>
\ No newline at end of file
</style>
......@@ -8,7 +8,10 @@
<script setup lang="ts">
import headers from "@/components/header/index.vue"
import { zalert, toast } from "@/utils/util"
import { toast, zconfirm } from "@/utils/util"
import { useMapStore } from "@/store/modules/mapStore"
const mapStore = useMapStore()
const state = reactive({
key: "3M5BZ-SFCRJ-AHSF7-XRA5Q-Y6NIJ-DXBH4",
......@@ -35,22 +38,39 @@ window.addEventListener(
const submit = () => {
if (!addrDetail.value) return toast("请选择地址")
console.log("location", addrDetail.value)
zalert("确定设置为该地址?", () => {
uni.navigateBack()
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 },
})
},
})
// zconfirm("确定设置为该地址?", (result: boolean) => {
// if (result) {
// }
// })
}
onMounted(() => {
uni.getLocation({
type: "gcj02",
success(res: any) {
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
}, 100)
},
})
if (mapStore.mapData.StateType) {
} 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`
// mapStore.setMapData({ ...mapStore.mapData, ...{ hitArea: "" } })
setTimeout(() => {
flag.value = true
}, 1000)
},
})
}
})
</script>
......
<template>
<headers title="考勤地点设置" />
<view class="set-attendance-container">
<h3>考勤地点设置</h3>
<u-form :model="data.formData" ref="formRef" label-position="top">
<u-form-item label="考勤地址名称" prop="F_LQKJ_HITAREA"
><u-input v-model="data.formData.F_LQKJ_HITAREA" clearable
/></u-form-item>
<u-form-item label="有效范围" prop="F_LQKJ_SCOPE"
><u-input
type="select"
v-model="data.formData.F_LQKJ_SCOPE"
@tap="data.show = true"
/></u-form-item>
<u-form-item label="请设置定位的应用范围" prop="">
<u-radio-group v-model="data.formData.scope" 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="back" size="medium">上一步</u-button>
<u-button type="success" size="medium" @tap="submit">确认</u-button>
</view>
</view>
<u-select
v-model="data.show"
:list="data.list"
@confirm="onConfirm"
></u-select>
</template>
<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"
const mapStore = useMapStore()
const formRef = ref()
const data = reactive({
formData: {
F_LQKJ_LONGITUDE: "",
F_LQKJ_SCOPE: "",
FCOURSEID: 0,
scope: 0,
F_LQKJ_HITAREA: "",
},
rules: {
F_LQKJ_HITAREA: [
{
required: true,
message: "请输入考勤地址名称",
trigger: ["change", "blur"],
},
],
F_LQKJ_SCOPE: [
{
required: true,
message: "请设置有效范围",
trigger: "blur",
},
],
},
show: false,
list: [
{
value: "100米",
label: "100米",
},
{
value: "200米",
label: "200米",
},
{
value: "300米",
label: "300米",
},
{
value: "400米",
label: "400米",
},
{
value: "500米",
label: "500米",
},
{
value: "600米",
label: "600米",
},
{
value: "700米",
label: "700米",
},
{
value: "800米",
label: "800米",
},
],
})
const back = () => {
uni.navigateBack()
}
const submit = () => {
formRef.value.validate(async (valid: any) => {
if (valid) {
console.log(data.formData)
const { data: res } = await setAddr(data.formData)
if (res.code == 200) {
uni.navigateBack({ delta: 2 })
toast("设置成功")
}
} else {
}
})
}
const onConfirm = (item: any) => {
data.formData.F_LQKJ_SCOPE = item[0].value
}
onReady(() => {
formRef.value.setRules(data.rules)
setTimeout(() => {
data.formData.F_LQKJ_HITAREA = mapStore.mapData.hitArea
data.formData.F_LQKJ_LONGITUDE = mapStore.mapData.Longitude
data.formData.F_LQKJ_SCOPE = mapStore.mapData.Scope
data.formData.FCOURSEID = mapStore.mapData.courseId
console.log(mapStore.mapData)
}, 100)
})
</script>
<style lang="scss" scoped>
body {
background-color: #fff;
}
.set-attendance-container {
padding: 30rpx;
background-color: #fff;
.footer {
position: fixed;
bottom: 10%;
left: 0;
width: 100%;
display: flex;
.u-btn {
width: 30%;
}
}
}
</style>
.card {
box-sizing: border-box;
margin: 16rpx;
padding: 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);
box-sizing: border-box;
margin: 16rpx;
padding: 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);
.card-text {
padding: 20rpx;
}
.card-text {
padding: 20rpx;
}
.grid-text {
font-size: 28rpx;
margin-top: 4rpx;
color: #303133;
padding: 0 10rpx;
white-space: 'nowrap';
text-overflow: 'ellipsis';
overflow: 'hidden';
}
.grid-text {
font-size: 28rpx;
margin-top: 4rpx;
color: #303133;
padding: 0 10rpx;
white-space: "nowrap";
text-overflow: "ellipsis";
overflow: "hidden";
}
}
.empty {
margin-top: 40rpx;
}
@font-face {
font-family: "custom-icon";
/* Project id 3607036 */
src: url('https://at.alicdn.com/t/c/font_3607036_y4hl42aa2g.woff2?t=1686627317404') format('woff2'),
url('https://at.alicdn.com/t/c/font_3607036_y4hl42aa2g.woff?t=1686627317404') format('woff'),
url('https://at.alicdn.com/t/c/font_3607036_y4hl42aa2g.ttf?t=1686627317404') format('truetype');
}
.custom-icon {
font-family: "custom-icon" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.custom-icon-lanya1:before {
content: "\e65f";
}
.custom-icon-lanya:before {
content: "\ec4a";
}
.custom-icon-fujian:before {
content: "\e601";
}
.custom-icon-shangchuandaochu:before {
content: "\e8c6";
}
.custom-icon-shouyefill:before {
content: "\e750";
}
.custom-icon-sandiantu:before {
content: "\e679";
}
.custom-icon-tubiao-zhexiantu:before {
content: "\eb96";
}
.custom-icon-shezhixitongshezhigongnengshezhishuxing:before {
content: "\e795";
}
.custom-icon-caidan1:before {
content: "\e653";
}
.custom-icon-bingtu:before {
content: "\e6bb";
}
.custom-icon-shujudaping:before {
content: "\e742";
}
.custom-icon-zhuzhuangtu:before {
content: "\e650";
}
.custom-icon-list2:before {
content: "\e655";
}
.custom-icon-caidan:before {
content: "\e652";
}
.custom-icon-erweima:before {
content: "\e6bd";
}
.custom-icon-shuxingguanli:before {
content: "\e625";
}
.custom-icon-line-barcodeboxtiaoxingma-02:before {
content: "\e717";
}
.custom-icon-Icon_kebianjibiaoge:before {
content: "\e60b";
}
.custom-icon-sousuo:before {
content: "\e600";
}
.custom-icon-dingdan:before {
content: "\e737";
}
.custom-icon-wodeyushe:before {
content: "\e633";
}
.custom-icon-dingdan-copy:before {
content: "\e738";
}
.custom-icon-sousuo-copy:before {
content: "\e739";
}
.custom-icon-wodeyushe-copy:before {
content: "\e73a";
}
\ No newline at end of file
差异被折叠。
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论