This commit is contained in:
yanran200730
2023-02-09 10:51:24 +08:00
31 changed files with 3008 additions and 39 deletions

View File

@@ -47,6 +47,7 @@
"flyio": "^0.6.14",
"query-string": "^7.1.1",
"regenerator-runtime": "^0.12.1",
"swiper": "^5.4.5",
"uview-ui": "^1.7.8",
"vue": "^2.6.11",
"vuex": "^3.6.2"

View File

@@ -0,0 +1,36 @@
import http from "./http";
class List {
constructor(action) {
this.action = action
this.current = 1
this.total = 0
this.list = []
}
getData(params) {
const {action} = this
return http.post(action, null, {params})
}
init(params) {
this.getData({...params, current: 1}).then(res => {
if (res?.data) {
this.list = res.data.records
this.total = res.data.total
}
})
}
loadMore(params) {
if (this.list.length < this.total) {
this.getData({...params, current: ++this.current}).then(res => {
if (res?.data) {
this.list = [...this.list, ...res.data.records]
}
})
}
}
}
export default List

View File

@@ -22,11 +22,11 @@
<u-icon name="arrow-down" size="28" color="#333333" :custom-style="{marginLeft:'8px'}"></u-icon>
</span>
<div class="total">
<em>{{ total }}</em>个农产品
<em>{{ list.total }}</em>个农产品
</div>
</header>
<div class="card-list" v-if="list.length">
<div class="card" v-for="(item,index) in list" :key="index" @click="toDetail(item)">
<div class="card-list">
<div class="card" v-for="(item,index) in list.list" :key="index" @click="toDetail(item)">
<div class="top">
<div class="title">{{ item.title }}
</div>
@@ -47,7 +47,7 @@
</div>
</div>
</div>
<AiEmpty v-else/>
<AiEmpty v-if="!list.list.length"/>
<div class="btn-wrapper">
<div class="btn" @click="suport" hover-class="text-hover">我要发布</div>
</div>
@@ -57,6 +57,8 @@
</template>
<script>
import List from "dvcp-wui/utils/list";
export default {
name: "AppAgProducts",
appName: "晒农产品",
@@ -64,11 +66,9 @@ export default {
return {
index: 0,
show: false,
current: 1,
type: "",
typeName: "",
list: [],
total: 0,
}
},
@@ -96,7 +96,6 @@ export default {
},
onChange(val) {
this.index = val;
this.current = 1;
if (!!this.index) {
this.getMine();
} else this.getAll();
@@ -107,36 +106,19 @@ export default {
confirm(val) {
this.type = val[0].value;
this.typeName = val[0].label;
this.current = 1;
if (!!this.index) {
this.getMine();
} else this.getAll();
},
getAll() {
this.$instance.post("/app/appshowagriculturalproduce/list", null, {
params: {
type: this.type,
current: this.current,
}
}).then(res => {
if (res?.data) {
this.list = this.current > 1 ? [...this.list, ...res.data.records] : res.data.records;
this.total = res.data.total;
}
})
const {type} = this
this.list = new List("/app/appshowagriculturalproduce/list")
this.list.init({type})
},
getMine() {
this.$instance.post("/app/appshowagriculturalproduce/listByWx", null, {
params: {
type: this.type,
current: this.current,
}
}).then(res => {
if (res?.data) {
this.list = this.current > 1 ? [...this.list, ...res.data.records] : res.data.records;
this.total = res.data.total;
}
})
const {type} = this
this.list = new List("/app/appshowagriculturalproduce/listByWx")
this.list.init({type})
},
toDetail({id}) {
uni.navigateTo({
@@ -150,7 +132,6 @@ export default {
}
},
onShow() {
this.current = 1;
if (!!this.index) {
this.getMine();
} else {
@@ -158,12 +139,8 @@ export default {
}
},
onReachBottom() {
this.current++;
if (!!this.index) {
this.getMine();
} else {
this.getAll();
}
const {type} = this
this.list.loadMore({type})
}
}
</script>
@@ -299,7 +276,6 @@ export default {
box-sizing: border-box;
display: flex;
align-items: center;
box-sizing: border-box;
padding: 32px;
& > img {

View File

@@ -0,0 +1,491 @@
<template>
<div class="page">
<div class="search-wrap">
<div class="search fill" @click="$linkTo('/mods/AppContent/contentManager?moduleId=' + search.moduleId)">
<u-icon name="search" color="#ffffff" size="40"></u-icon>
<span class="desc">请输入需要搜索的内容</span>
</div>
</div>
<div class="header-bg"></div>
<img class="border" :src="`${cdn}/border.png`" alt="">
<div class="swiper-content">
<u-swiper :list="swiperList" mode="none" height="240" bg-color="none" @click="handleBannerClick"/>
</div>
<div class="grid-content">
<u-grid :col="4" hover-class="text-hover" :border="false">
<u-grid-item v-for="(item, index) in grids" :key="index" :custom-style="{padding:'8px 0'}" bg-color="none"
class="grid-item" @click="handleClick(item)">
<img :src="item.pictureUrl" alt=""/>
<div class="grid-text">{{ item.name }}</div>
</u-grid-item>
</u-grid>
</div>
<div class="notice">
<img :src="`${cdn}/notice-new.png`" alt="">
<u-notice-bar mode="vertical" color="#4181FF" style="flex: 1;" :volume-icon="false" :is-circular="false"
duration="5000" speed="5000" :list="noticeList" @click="clickNotice"/>
</div>
<template v-if="activeList.length>0">
<header>推荐专题</header>
<scroll-view :scroll-x="true" style="width: 100%" class="scroll-wrap">
<div class="scroll-card"
:style="{background:'url(' + item.pictureUrl + ') no-repeat no-repeat;background-size:100% 100%;'}"
v-for="(item,index) in activeList" :key="index" @click="handleActive(item)"/>
</scroll-view>
</template>
<template v-if="categorys&&categorys.length>0">
<u-tabs :list="categorys.map(e=>({name:e.categoryName}))" font-size="40" bg-color="transparent"
inactive-color="#999999" :active-item-style="active"
:is-scroll="true" :current="index" @change="tabChange"/>
<div class="list-wrap" v-if="categoryList && categoryList.length>0">
<div class="list-card" v-for="(category,index) in categoryList" :key="index"
@click="$linkTo('/mods/AppContent/contentDetail?id='+category.id)">
<div class="header">{{ category.title }}</div>
<div class="content-wrap"
v-if="category.contentType==0 && category.files && category.files.length<3&&category.files.length>0">
<img class="img" :src="item.url" v-for="(item,index) in category.files.slice(0,1)" :key="index.id">
</div>
<div class="content-wrap" v-if="category.contentType==0 && category.files && category.files.length >= 3">
<img class="min-img" :src="item.url" v-for="(item,index) in category.files.slice(0,3)" :key="index.id">
</div>
<div class="content-wrap" v-if="category.contentType == 1">
<img class="img" :src="category.pictureUrl" alt=""/>
<img class="play-icon" :src="`${cdn}/play.png`" alt=""/>
</div>
<div class="bottom">
<div class="left">
<div class="tag">{{ category.categoryName }}</div>
{{ category.createTime }}
</div>
<div class="right">
<em>{{ category.viewCount }}</em>
人看过
</div>
</div>
</div>
</div>
<AiEmpty v-else/>
</template>
<AiLogin ref="login"/>
</div>
</template>
<script>
import {mapActions, mapState} from 'vuex'
export default {
name: 'AppHome',
appName: "首页",
data() {
return {
cdn: "https://cdn.cunwuyun.cn/wxmp",
swiperList: [],
index: 0,
grids: [],
activeList: [],
notices: [],
categorys: [],
categoryList: [],
search: {areaId: ''},
}
},
computed: {
...mapState(['user', 'token']),
active() {
return {
fontSize: '22px',
color: '#333333',
}
},
noticeList() {
let {notices} = this
return notices?.length > 0 ? notices?.map(e => e.title) || ['暂无公告'] : ['暂无公告']
}
},
onReady() {
uni.setNavigationBarTitle({title: "丰收号"})
},
onLoad() {
this.autoLogin().then(() => {
this.getSwiperList();
this.getName();
this.getGrids();
this.getActive();
this.getNotice();
})
},
methods: {
...mapActions(['autoLogin', 'authCheck']),
getName() {
this.$instance.post("/app/appcontentmoduleinfo/listByName", null, {
params: {names: "新闻发布"},
withoutToken: true
}).then(res => {
if (res?.data[0]?.categoryList?.length) {
this.categorys = res.data[0]["categoryList"];
this.search.moduleId = res.data[0]['id']
this.search.categoryId = res.data[0]['categoryList'][0]['id']
this.getCategoryList()
}
})
},
tabChange(idx) {
this.index = idx
this.search.categoryId = this.categorys[idx]['id']
this.getCategoryList()
},
getCategoryList() {
this.$instance.post("/app/appcontentinfo/list", null, {
params: {...this.search, size: 100}
}).then(res => {
if (res?.data) {
this.categoryList = res.data.records;
}
})
},
clickNotice(val) {
const id = this.notices[val]["id"];
if (id) {
uni.navigateTo({
url: "/mods/AppNotice/AppNotice?id=" + id
})
}
},
handleActive({type, appId, url}) {
if (type == 0) {
uni.navigateToMiniProgram({appId})
} else if (type == 1) {
this.$linkTo("/subPages/h5/webview?link=" + url);
}
},
getNotice() {
this.$instance.post("/app/appmininotice/list", null, {
params: {size: 999},
withoutToken: true
}).then(res => {
if (res?.data) {
this.notices = res.data.records;
}
})
},
getActive() {
this.$instance.post("/app/appminitopicconfig/list", null, {
params: {size: 999},
withoutToken: true
}).then(res => {
if (res?.data) {
this.activeList = res.data.records;
}
})
},
/**
* 获取顶部九宫格
*/
getGrids() {
this.$instance.post("/app/appminihomeconfig/list", null, {
params: {picked: 1},
withoutToken: true
}).then(res => {
if (res?.data) {
this.grids = res.data.records;
}
})
},
getSwiperList() {
this.$instance.post('/app/appbanner/listForWx', null, {
withoutToken: true
}).then((res) => {
if (res?.data) {
this.swiperList = res.data?.map((e) => ({...e, image: e.imgUrl})) || []
}
})
},
handleClick({type, appId, modulePath, url, checkType, corpId}) {
//先判读是不是系统应用
if (type != "0") {
if (type == "1") {
uni.navigateToMiniProgram({appId});
} else if (type == "2") {
uni.navigateTo({url: "/subPages/h5/webview?link=" + url});
} else if (type == "3") {
this.$linkTo(url);
} else if (type == "4") {
uni.openCustomerServiceChat({
extInfo: {url: url},
corpId: corpId,
fail: () => {
this.$u.toast('请使用普通微信打开小程序进行咨询');
}
});
}
} else if (type && type == "0") {
uni.showLoading({title: '正在进入应用...'})
this.authCheck({checkType, modulePath}).finally(() => uni.hideLoading())
}
},
handleBannerClick(index) {
if (!this.swiperList[index].linkUrl) return
if (this.swiperList[index].type == '0') { //0 h5链接 1 小程序链接; 2外部小程序
this.$linkTo(`/subPages/h5/webview?link=${this.swiperList?.[index]?.linkUrl}&title=${this.swiperList?.[index]?.title}`)
} else if (this.swiperList[index].type == '1') {
this.$linkTo(`${this.swiperList?.[index]?.linkUrl}`)
} else {
wx.navigateToMiniProgram({
appId: this.swiperList[index].linkUrl
})
}
},
},
onShareAppMessage() {
return {
title: '欢迎使用数字乡村治理服务一体化平台~',
path: `/pages/AppHome/AppHome`
}
},
}
</script>
<style scoped lang="scss">
@import "~dvcp-wui/common";
.page {
width: 100%;
min-height: 100%;
background-color: #F3F6F9;
position: relative;
.search-wrap {
width: 750px;
height: 112px;
box-sizing: border-box;
padding: 0 32px;
display: flex;
align-items: center;
justify-content: center;
background-color: #4181FF;
.search {
width: 100%;
height: 64px;
background: #000000;
border-radius: 32px;
opacity: 0.2;
box-sizing: border-box;
padding: 0 32px;
display: flex;
align-items: center;
.desc {
font-size: 28px;
color: #FFFFFF;
margin-left: 16px;
}
}
}
.area-content {
height: 96px;
line-height: 96px;
background-color: #2d80fb;
.area-ai {
display: block;
width: 200px;
margin-left: 34px;
text-align: left;
}
.picker-location {
text-align: left;
}
}
.header-bg {
width: 100%;
height: 160px;
background-color: #4181FF;
}
.border {
width: 100%;
height: 40px;
}
.swiper-content {
width: 686px;
height: 240px;
margin: -176px auto 24px;
}
.grid-content {
box-sizing: border-box;
.grid-item {
img {
width: 108px;
height: 108px;
object-fit: fill;
}
.grid-text {
font-size: 26px;
font-weight: 400;
color: #333333;
line-height: 36px;
}
}
}
::v-deep .notice {
width: 686px;
height: 88px;
box-sizing: border-box;
padding: 0 24px;
margin: 30px auto 48px;
background: #FFFFFF;
box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.02);
border-radius: 16px;
display: flex;
align-items: center;
justify-content: center;
& > img {
width: 128px;
height: 52px;
}
.u-news-item {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
}
.list-wrap {
box-sizing: border-box;
padding: 32px;
.list-card {
width: 100%;
min-height: 100px;
background: #FFFFFF;
box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.02);
border-radius: 16px;
box-sizing: border-box;
padding: 32px;
margin-bottom: 24px;
.header {
font-size: 36px;
font-weight: 600;
color: #333333;
line-height: 50px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
.content-wrap {
display: flex;
gap: 4px;
flex-wrap: wrap;
margin-top: 24px;
position: relative;
.img {
width: 100%;
height: 350px;
}
.min-img {
width: 204px;
height: 204px;
}
.play-icon {
width: 80px;
height: 80px;
border-radius: 50%;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
}
.bottom {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 24px;
.left {
display: flex;
align-items: center;
font-size: 28px;
font-weight: 400;
color: #999999;
.tag {
width: 144px;
height: 48px;
background: #EEEEEE;
border-radius: 24px;
display: flex;
align-items: center;
justify-content: center;
font-size: 28px;
font-weight: 400;
color: #999999;
margin-right: 16px;
}
}
.right {
font-size: 28px;
font-weight: 400;
color: #999999;
display: flex;
align-items: center;
em {
font-style: normal;
color: #4181FF;
}
}
}
}
}
header {
font-size: 44px;
font-weight: 600;
color: #333333;
padding: 0 32px;
margin-bottom: 32px;
}
.scroll-wrap {
box-sizing: border-box;
padding: 0 32px;
width: 100%;
white-space: nowrap;
margin-bottom: 24px;
.scroll-card {
display: inline-block;
width: 440px;
height: 240px;
box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.02);
border-radius: 16px;
margin-right: 32px;
&:last-child {
margin-right: 0;
}
}
}
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 965 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1000 B

View File

@@ -0,0 +1,497 @@
<template>
<div class="page">
<u-navbar title="法治曲靖" title-color="#000" title-width="300" title-size="26" :is-back="false" :background="background"></u-navbar>
<div class="header-bg">
<div class="header-info">
<div class="search-wrap">
<div class="search fill" @click="$linkTo('/mods/AppContent/contentManager?moduleId=' + search.moduleId)">
<u-icon name="search" color="#333" size="40"></u-icon>
<span class="desc">请输入需要搜索的内容</span>
</div>
</div>
<div class="swiper-content">
<u-swiper :list="swiperList" mode="none" height="240" bg-color="none" @click="handleBannerClick"/>
</div>
</div>
</div>
<div class="grid-content">
<u-grid :col="4" hover-class="text-hover" :border="false">
<u-grid-item v-for="(item, index) in grids" :key="index" :custom-style="{padding:'8px 0'}" bg-color="none"
class="grid-item" @click="handleClick(item)">
<img :src="item.pictureUrl" alt=""/>
<div class="grid-text">{{ item.name }}</div>
</u-grid-item>
</u-grid>
</div>
<div class="notice">
<img :src="`${cdn}/notice-new.png`" alt="">
<u-notice-bar mode="vertical" color="#4181FF" style="flex: 1;" :volume-icon="false" :is-circular="false"
duration="5000" speed="5000" :list="noticeList" @click="clickNotice"/>
</div>
<!-- <template v-if="activeList.length>0">
<header>推荐专题</header>
<scroll-view :scroll-x="true" style="width: 100%" class="scroll-wrap">
<div class="scroll-card"
:style="{background:'url(' + item.pictureUrl + ') no-repeat no-repeat;background-size:100% 100%;'}"
v-for="(item,index) in activeList" :key="index" @click="handleActive(item)"/>
</scroll-view>
</template> -->
<template v-if="categorys&&categorys.length>0">
<u-tabs :list="categorys.map(e=>({name:e.categoryName}))" font-size="40" bg-color="transparent"
inactive-color="#999999" :active-item-style="active"
:is-scroll="true" :current="index" @change="tabChange"/>
<div class="list-wrap" v-if="categoryList && categoryList.length>0">
<div class="list-card" v-for="(category,index) in categoryList" :key="index"
@click="$linkTo('/mods/AppContent/contentDetail?id='+category.id)">
<div class="header">{{ category.title }}</div>
<div class="content-wrap"
v-if="category.contentType==0 && category.files && category.files.length<3&&category.files.length>0">
<img class="img" :src="item.url" v-for="(item,index) in category.files.slice(0,1)" :key="index.id">
</div>
<div class="content-wrap" v-if="category.contentType==0 && category.files && category.files.length >= 3">
<img class="min-img" :src="item.url" v-for="(item,index) in category.files.slice(0,3)" :key="index.id">
</div>
<div class="content-wrap" v-if="category.contentType == 1">
<img class="img" :src="category.pictureUrl" alt=""/>
<img class="play-icon" :src="`${cdn}/play.png`" alt=""/>
</div>
<div class="bottom">
<div class="left">
<div class="tag">{{ category.categoryName }}</div>
{{ category.createTime }}
</div>
<div class="right">
<em>{{ category.viewCount }}</em>
人看过
</div>
</div>
</div>
</div>
<AiEmpty v-else/>
</template>
<AiLogin ref="login"/>
</div>
</template>
<script>
import {mapActions, mapState} from 'vuex'
export default {
name: 'AppHome',
appName: "首页",
data() {
return {
cdn: "https://cdn.cunwuyun.cn/wxmp",
swiperList: [{image: 'https://img1.baidu.com/it/u=3155988012,1977937542&fm=253&app=138&size=w931&n=0&f=JPG&fmt=auto?sec=1675357200&t=25831b87b8fe5b501fa4665e2c9bcb92'}],
index: 0,
grids: [],
activeList: [],
notices: [],
categorys: [],
categoryList: [],
search: {areaId: ''},
background: {
backgroundImage: 'linear-gradient(45deg, #E6F2FE, #E1F2FA)'
}
}
},
computed: {
...mapState(['user', 'token']),
active() {
return {
fontSize: '22px',
color: '#333333',
}
},
noticeList() {
let {notices} = this
return notices?.length > 0 ? notices?.map(e => e.title) || ['暂无公告'] : ['暂无公告']
}
},
onReady() {
uni.setNavigationBarTitle({title: "法治曲靖"})
},
onLoad() {
this.autoLogin().then(() => {
// this.getSwiperList();
this.getName();
this.getGrids();
this.getActive();
this.getNotice();
})
},
methods: {
...mapActions(['autoLogin', 'authCheck']),
getName() {
this.$instance.post("/app/appcontentmoduleinfo/listByName", null, {
params: {names: "新闻发布"},
withoutToken: true
}).then(res => {
if (res?.data[0]?.categoryList?.length) {
this.categorys = res.data[0]["categoryList"];
this.search.moduleId = res.data[0]['id']
this.search.categoryId = res.data[0]['categoryList'][0]['id']
this.getCategoryList()
}
})
},
tabChange(idx) {
this.index = idx
this.search.categoryId = this.categorys[idx]['id']
this.getCategoryList()
},
getCategoryList() {
this.$instance.post("/app/appcontentinfo/list", null, {
params: {...this.search, size: 100}
}).then(res => {
if (res?.data) {
this.categoryList = res.data.records;
}
})
},
clickNotice(val) {
const id = this.notices[val]["id"];
if (id) {
uni.navigateTo({
url: "/mods/AppNotice/AppNotice?id=" + id
})
}
},
handleActive({type, appId, url}) {
if (type == 0) {
uni.navigateToMiniProgram({appId})
} else if (type == 1) {
this.$linkTo("/subPages/h5/webview?link=" + url);
}
},
getNotice() {
this.$instance.post("/app/appmininotice/list", null, {
params: {size: 999},
withoutToken: true
}).then(res => {
if (res?.data) {
this.notices = res.data.records;
}
})
},
getActive() {
this.$instance.post("/app/appminitopicconfig/list", null, {
params: {size: 999},
withoutToken: true
}).then(res => {
if (res?.data) {
this.activeList = res.data.records;
}
})
},
/**
* 获取顶部九宫格
*/
getGrids() {
this.$instance.post("/app/appminihomeconfig/list", null, {
params: {picked: 1},
withoutToken: true
}).then(res => {
if (res?.data) {
this.grids = res.data.records;
}
})
},
getSwiperList() {
this.$instance.post('/app/appbanner/listForWx', null, {
withoutToken: true
}).then((res) => {
if (res?.data) {
this.swiperList = res.data?.map((e) => ({...e, image: e.imgUrl})) || []
}
})
},
handleClick({type, appId, modulePath, url, checkType, corpId}) {
//先判读是不是系统应用
if (type != "0") {
if (type == "1") {
uni.navigateToMiniProgram({appId});
} else if (type == "2") {
uni.navigateTo({url: "/subPages/h5/webview?link=" + url});
} else if (type == "3") {
this.$linkTo(url);
} else if (type == "4") {
uni.openCustomerServiceChat({
extInfo: {url: url},
corpId: corpId,
fail: () => {
this.$u.toast('请使用普通微信打开小程序进行咨询');
}
});
}
} else if (type && type == "0") {
uni.showLoading({title: '正在进入应用...'})
this.authCheck({checkType, modulePath}).finally(() => uni.hideLoading())
}
},
handleBannerClick(index) {
if (!this.swiperList[index].linkUrl) return
if (this.swiperList[index].type == '0') { //0 h5链接 1 小程序链接; 2外部小程序
this.$linkTo(`/subPages/h5/webview?link=${this.swiperList?.[index]?.linkUrl}&title=${this.swiperList?.[index]?.title}`)
} else if (this.swiperList[index].type == '1') {
this.$linkTo(`${this.swiperList?.[index]?.linkUrl}`)
} else {
wx.navigateToMiniProgram({
appId: this.swiperList[index].linkUrl
})
}
},
},
onShareAppMessage() {
return {
title: '欢迎使用数字乡村治理服务一体化平台~',
path: `/pages/AppHome/AppHome`
}
},
}
</script>
<style scoped lang="scss">
@import "~dvcp-wui/common";
.page {
width: 100%;
min-height: 100%;
background-color: #F3F6F9;
position: relative;
.header-bg {
width: 100%;
height: 424px;
position: relative;
.header-info {
width: 100%;
height: 100%;
background: url("https://cdn.cunwuyun.cn/qj/home-top-bg.png") no-repeat no-repeat;
background-size: 100% 100%;
box-sizing: border-box;
}
}
.search-wrap {
padding: 32px 0 32px 32px;
.search {
width: 686px;
height: 72px;
background: #fff;
border-radius: 36px;
box-sizing: border-box;
padding: 0 32px;
display: flex;
align-items: center;
.desc {
font-size: 28px;
margin-left: 16px;
color: #8891A1;
}
}
}
.area-content {
height: 96px;
line-height: 96px;
background-color: #2d80fb;
.area-ai {
display: block;
width: 200px;
margin-left: 34px;
text-align: left;
}
.picker-location {
text-align: left;
}
}
.border {
width: 100%;
height: 40px;
}
.swiper-content {
width: 686px;
height: 240px;
margin-left: 32px;
}
.grid-content {
box-sizing: border-box;
.grid-item {
img {
width: 108px;
height: 108px;
object-fit: fill;
}
.grid-text {
font-size: 26px;
font-weight: 400;
color: #333333;
line-height: 36px;
}
}
}
::v-deep .notice {
width: 686px;
height: 88px;
box-sizing: border-box;
padding: 0 24px;
margin: 30px auto 48px;
background: #FFFFFF;
box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.02);
border-radius: 16px;
display: flex;
align-items: center;
justify-content: center;
& > img {
width: 128px;
height: 52px;
}
.u-news-item {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
}
.list-wrap {
box-sizing: border-box;
padding: 32px;
.list-card {
width: 100%;
min-height: 100px;
background: #FFFFFF;
box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.02);
border-radius: 16px;
box-sizing: border-box;
padding: 32px;
margin-bottom: 24px;
.header {
font-size: 36px;
font-weight: 600;
color: #333333;
line-height: 50px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
.content-wrap {
display: flex;
gap: 4px;
flex-wrap: wrap;
margin-top: 24px;
position: relative;
.img {
width: 100%;
height: 350px;
}
.min-img {
width: 204px;
height: 204px;
}
.play-icon {
width: 80px;
height: 80px;
border-radius: 50%;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
}
.bottom {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 24px;
.left {
display: flex;
align-items: center;
font-size: 28px;
font-weight: 400;
color: #999999;
.tag {
width: 144px;
height: 48px;
background: #EEEEEE;
border-radius: 24px;
display: flex;
align-items: center;
justify-content: center;
font-size: 28px;
font-weight: 400;
color: #999999;
margin-right: 16px;
}
}
.right {
font-size: 28px;
font-weight: 400;
color: #999999;
display: flex;
align-items: center;
em {
font-style: normal;
color: #4181FF;
}
}
}
}
}
header {
font-size: 44px;
font-weight: 600;
color: #333333;
padding: 0 32px;
margin-bottom: 32px;
}
.scroll-wrap {
box-sizing: border-box;
padding: 0 32px;
width: 100%;
white-space: nowrap;
margin-bottom: 24px;
.scroll-card {
display: inline-block;
width: 440px;
height: 240px;
box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.02);
border-radius: 16px;
margin-right: 32px;
&:last-child {
margin-right: 0;
}
}
}
}
</style>

View File

@@ -0,0 +1,66 @@
<template>
<div class="AppLegalLearning">
<div class="tabs_box">
<u-tabs :list="tabs" font-size="32" bg-color="#f3f5f7" inactive-color="#999999"
:active-item-style="{color: '#222222'}" :is-scroll="true" :current="currIndex" @change="(i) => (currIndex = i)"> </u-tabs>
</div>
<OnlineClass ref="OnlineClass" @toDetail="toDetail" v-show="currIndex == 0"></OnlineClass>
<GeneralLawExam ref="GeneralLawExam" @toTest="toTest" v-show="currIndex == 1"></GeneralLawExam>
</div>
</template>
<script>
import OnlineClass from './components/OnlineClass.vue'
import GeneralLawExam from './components/GeneralLawExam.vue'
export default {
name: 'AppLegalLearning',
appName: '法治学习',
data() {
return {
currIndex: 1,
tabs: [
{
name: '在线课堂',
},
{
name: '普法考试',
}
],
}
},
onShow() {
},
components: {
OnlineClass,
GeneralLawExam
},
watch: {
currIndex: {
handler(v) {
if(v == 0) {
this.$refs.OnlineClass.getList();
} else if(v == 1) {
this.$refs.GeneralLawExam.getList();
}
}
}
},
methods: {
toTest() {
uni.navigateTo({url: "./testForm"})
},
toDetail() {
uni.navigateTo({url: "./classDetail"})
}
}
}
</script>
<style lang="scss" socped>
.AppGeneralLawExam {
.tabs_box {
height: 100px;
line-height: 100px;
}
}
</style>

View File

@@ -0,0 +1,274 @@
<template>
<div class="classDetail">
<div class="media">
<img src="./img/bg.png" alt="">
<!-- <video src="./img/2676.mp4" controls/> -->
</div>
<div class="title">
五一假期若出游如何严格做好疫情防控具体要求来了
</div>
<p class="study_num">23人已学习</p>
<p class="content">
7月13日曲靖这十年系列新闻发布会法治建设专场
获悉党的十八大以来曲靖市深入学习贯彻习近平新时代中国特色社会主义思想坚持以习近平法治思想为根本遵循和行动指南坚持依法治市依法执政依法行政共同推进法治曲靖法治政府法治社会一体建设统筹推动科学立法严格执法公正司法全民守法人民群众法治获得感满意度明显提升法治曲靖建设蹄疾步稳铿锵有力为全市经济社会高质量跨越式发展提供了坚实法治保障
中共曲靖市委政法委副书记刘洁介绍过去十年曲靖市坚持固根本明方向全面加强党对法治建设的领导坚持立良法促善治持续夯实法治建设根基坚持严执法
促规范稳步推进法治政府建设坚持强制约促公正充分彰显社会公平正义坚持广普法重实效遵法守法
观念入脑入心刘洁称2019年机构改革后曲靖市委全面依法治市委员会办公室在市司法局设立在市委市政府的领导下曲靖全市司法行政系统围绕一个统筹四大职能
制定完善法治曲靖建设3个1+3体系开创了法治建设工作新局面当前曲靖以健全行政执法一方案三清单为统领完善制度体系建设全面推行重大行政决策目录化管理
创新推进基层合法性审查全覆盖行政执法人员全部纳入云南执法人员网上管理系统进行管理行政复议案件统一由市县两级人民政府管辖行政复议体制改革落地落实政府
行政行为质量稳步提高2022年上半年市级法院行政案件行政机关负责人出庭应诉率达100%刘洁指出全民守法是法治社会的基础工程曲靖紧跟新时代在针对性和实效性上下功夫不断提升全市公民法治意识和法治素养使法治成为社会共识和基本准则曲靖按照覆盖城乡功能完善便捷高效群众满意的目标深化公共法律服务体系建设推动实现市县乡村四级公共法律服务实体平台全覆盖
</p>
<div class="btn_box">
<div class="input_btn" @click="showSend = true">我来说两句...</div>
<div class="comment" @click="showComment = true">
<img src="./img/message.png" alt="">
<div class="comm_num">
<span>999</span><span>+</span>
</div>
</div>
</div>
<u-popup v-model="showComment" mode="bottom" border-radius="32">
<h4 class="message_num">共16条评论</h4>
<div class="comment_card">
<div class="avatar">
<img src="../../../static/img/avatar.png" alt="">
</div>
<div class="comment_info">
<div class="avatar_info">
<div class="avatar_name">徐逸凡</div>
<div class="avatar_time">9小时前</div>
</div>
<div class="comm_content">中央精神的重要讲话为我们的前进指明了方向</div>
</div>
</div>
<div class="comm_input_btn" @click="showSend = true,showComment= false">
<div>我来说两句...</div>
</div>
</u-popup>
<u-popup v-model="showSend" mode="bottom" border-radius="32">
<div class="send_box">
<div class="text">
<textarea
@blur="height = 0"
placeholder-style="color: #999;font-size: 16px;"
v-model="content"
:cursor-spacing="40"
placeholder="我来说两句..."
@keyboardheightchange="keyboard">
</textarea>
</div>
<div class="send_btn">发送</div>
</div>
</u-popup>
</div>
</template>
<script>
export default {
data() {
return {
showComment: false,
showSend: false,
content: '',
height: 0,
}
},
methods: {
keyboard(e) {
console.log(e.detail.height);
}
}
}
</script>
<style lang="scss" scoped>
.classDetail {
padding-bottom: 140px;
box-sizing: border-box;
.media {
img {
width: 100%;
height: 420px;
}
video {
width: 100%;
height: 420px;
}
}
.title {
margin-top: 30px;
font-weight: 500;
font-size: 46px;
color: #222222;
padding: 0 32px;
box-sizing: border-box;
}
.study_num {
margin-top: 16px;
font-weight: 400;
font-size: 30px;
color: #999999;
padding: 0 32px;
box-sizing: border-box;
}
.content {
margin-top: 48px;
padding: 0 32px;
box-sizing: border-box;
}
.btn_box {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 128px;
background: #fff;
padding: 24px 32px;
box-sizing: border-box;
display: flex;
align-items: center;
.input_btn {
width: 87%;
height: 80px;
line-height: 80px;
padding-left: 32px;
box-sizing: border-box;
background: #F4F5FA;
border-radius: 44px;
font-weight: 400;
font-size: 32px;
color: #666666;
margin-right: 20px;
}
.comment {
position: relative;
img {
width: 48px;
height: 48px;
}
.comm_num {
position: absolute;
left: 34px;
top: -10px;
background: #FFF;
color: #E23C3C;
font-weight: 600;
font-size: 20px;
}
}
}
.message_num {
width: 100%;
height: 100px;
line-height: 100px;
text-align: center;
font-weight: 400;
font-size: 28rpx;
color: #333333;
}
.comment_card {
display: flex;
padding: 24px 32px;
box-sizing: border-box;
.avatar {
width: 64px;
height: 64px;
border-radius: 50%;
img {
width: 100%;
height: 100%;
}
}
.comment_info {
margin-left: 16px;
.avatar_info {
display: flex;
justify-content: space-between;
.avatar_name {
font-weight: 500;
font-size: 28px;
color: #333333;
}
.avatar_time {
font-weight: 400;
font-size: 26px;
color: #999999;
}
}
.comm_content {
margin-top: 8px;
font-weight: 400;
font-size: 32rpx;
color: #333333;
}
}
}
.comm_input_btn {
width: 100%;
height: 128px;
background: #fff;
padding: 24px 32px;
box-sizing: border-box;
div {
width: 100%;
height: 80px;
line-height: 80px;
padding-left: 32px;
box-sizing: border-box;
background: #F4F5FA;
border-radius: 44px;
font-weight: 400;
font-size: 32px;
color: #666666;
}
}
.send_box {
display: flex;
justify-content: space-between;
align-items: center;
padding: 32px;
box-sizing: border-box;
.text {
textarea {
background: #F4F5FA;
border-radius: 16px;
padding: 16px;
box-sizing: border-box;
height: 128px;
width: 80vw;
}
}
.send_btn {
width: 80px;
height: 80px;
line-height: 80px;
text-align: right;
font-weight: 500;
font-size: 34rpx;
color: #2D7DFF;
}
}
}
</style>

View File

@@ -0,0 +1,242 @@
<template>
<div class="GeneralLawExam">
<div class="search_box">
<u-search placeholder="请输入需要搜索的考试" bg-color="#FFF" v-model="keyword" :show-action="false"></u-search>
</div>
<p class="all_test">全部考试</p>
<div class="card_list">
<div class="card">
<div class="card_top">
<div class="card_title">曲靖规则基本考试</div>
<div class="card_count">
<span class="col_blue">10</span>预计<span class="col_blue">10</span>分钟
</div>
<div class="card_statistics">
<span>264</span>人通过/<span>283</span>人参与
</div>
<div class="result">
<img src="../img/youxiu.png" alt="">
</div>
<div class="grade">98</div>
</div>
<div class="card_bottom col_blue" @click="handleToTest()">参加考试</div>
</div>
</div>
<u-popup v-model="showAuth" mode="bottom" border-radius="32">
<div class="auth_box">
<div class="auth_title">居民信息认证</div>
<div class="auth_form">
<div class="form_name">姓名</div>
<input class="form_value" type="text" placeholder="请输入姓名" v-model="form.name"/>
<div class="form_name">身份证号</div>
<input class="form_value" type="idcard" placeholder="请输入18位身份证号" v-model="form.idNumber"/>
<div class="form_name">地区</div>
<AiAreaPicker class="ai-area" v-model="form.areaId" :fullName.sync="form.areaName" all>
<div class="ai-area__wrapper">
<span class="label" v-if="form.areaName">{{ form.areaName }}</span>
<i v-else style="color: #999">请选择</i>
<u-icon name="arrow-right" color="#ddd"/>
</div>
</AiAreaPicker>
</div>
<div class="auth_btn">
<div class="cancel" @click="showAuth = false,form = {}">取消</div>
<div class="submit" @click="comfirm">确定</div>
</div>
</div>
</u-popup>
</div>
</template>
<script>
export default {
data() {
return {
showAuth: false,
keyword: '',
current: 1,
form: {
name: '',
idNumber: '',
areaId: '',
areaName: '',
}
}
},
onLoad() {
},
methods: {
getList() {
console.log('普法考试列表');
},
handleToTest() {
this.$emit('toTest')
},
comfirm() {
}
},
onReachBottom() {
this.current++;
this.getList()
},
}
</script>
<style lang="scss" socped>
.GeneralLawExam {
.search_box {
margin: 24px 0;
padding: 0 32px;
box-sizing: border-box;
}
.all_test {
font-size: 28px;
color: #333333;
font-weight: 600;
padding: 0 32px;
box-sizing: border-box;
}
.card_list {
padding: 8px 32px;
box-sizing: border-box;
.card {
margin-top: 24px;
.card_top,
.card_bottom {
padding: 24px;
box-sizing: border-box;
background: #FCFCFC;
}
.card_top {
position: relative;
border-radius: 16px 16px 0 0;
.card_title {
font-weight: 500;
font-size: 36px;
color: #333333;
overflow: hidden;
text-overflow:ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.card_count,
.card_statistics {
font-weight: 400;
font-size: 26px;
color: #999999;
margin-top: 16px;
}
.result {
position: absolute;
right: 0;
top: 0;
img {
width: 200px;
height: 200px;
}
}
.grade {
position: absolute;
right: 75px;
top: 60px;
font-weight: 500;
font-size: 40px;
color: #0FC484;
}
}
.card_bottom {
border-top: 1px solid #EEEEEE;
border-radius: 0 0 16px 16px;
text-align: center;
}
.col_blue {
color: #2D7DFF;
}
}
}
.auth_box {
padding: 32px;
box-sizing: border-box;
.auth_title {
font-weight: 600;
font-size: 34px;
color: #333333;
text-align: center;
}
.auth_form {
margin-top: 30px;
.form_name {
font-weight: 500;
font-size: 28px;
color: #333333;
margin-bottom: 16px;
}
input {
height: 96px;
background: #F4F5FA;
border-radius: 16px;
margin-bottom: 32px;
padding-left: 24px;
}
.ai-area .ai-area__wrapper {
display: flex;
background: #F4F5FA;
border-radius: 16px;
margin-bottom: 32px;
padding: 24px;
box-sizing: border-box;
}
}
.auth_btn {
display: flex;
justify-content: space-between;
height: 100px;
padding: 10px 0;
box-sizing: border-box;
.cancel {
background: #F2F2F2;
color: #2D7DFF;
}
.submit {
background: #2D7DFF;
color: #FFF;
}
.cancel,
.submit {
width: 48%;
height: 80px;
line-height: 80px;
text-align: center;
border-radius: 16px;
}
}
}
}
</style>

View File

@@ -0,0 +1,111 @@
<template>
<div class="OnlineClass">
<div class="search_box">
<u-search placeholder="请输入需要搜索的课程" bg-color="#FFF" v-model="keyword" :show-action="false"></u-search>
</div>
<p class="all_class">全部课程</p>
<div class="card_list">
<div class="card" @click="handleToDetail">
<div class="card_left">
<img src="../img/youxiu.png" alt="">
</div>
<div class="card_right">
<div class="title">课程名称课程名称课程名称课程名称课程名称课程名称课</div>
<div class="num">47人已学习</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
current: 1,
keyword: '',
}
},
onLoad() {
},
methods: {
getList() {
console.log('在线课堂列表');
},
handleToDetail() {
this.$emit('toDetail')
}
},
onReachBottom() {
this.current ++;
this.getList()
},
}
</script>
<style lang="scss" socped>
.OnlineClass {
.search_box {
margin: 24px 0;
padding: 0 32px;
box-sizing: border-box;
}
.all_class {
font-size: 28px;
color: #333333;
font-weight: 600;
padding: 0 32px;
box-sizing: border-box;
}
.card_list {
padding: 8px 32px;
box-sizing: border-box;
.card {
margin-top: 24px;
background: #FFFFFF;
box-shadow: 0 0 8px 0 rgba(0,0,0,0.02);
border-radius: 16px;
display: flex;
padding: 24px;
box-sizing: border-box;
.card_left {
margin-right: 24px;
img {
width: 160px;
height: 160px;
border-radius: 8px;
}
}
.card_right {
.title {
font-weight: 500;
font-size: 34px;
color: #333333;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.num {
margin-top: 28px;
font-weight: 400;
font-size: 26px;
color: #999999;
}
}
.col_blue {
color: #2D7DFF;
}
}
}
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,143 @@
<template>
<div class="result">
<u-navbar title="考试结果" :background="backgroundNavbar"></u-navbar>
<div class="grade">100</div>
<div class="tips">
<div>考试分数</div>
<div>超过<span>99%</span>的人</div>
</div>
<div class="card_list">
<div class="pass">
<div>结果</div>
<div class="col_pass">通过</div>
</div>
<div class="time">
<div>用时</div>
<div class="col_333">1小时32分</div>
</div>
<div class="pass_num">
<div>对题数</div>
<div class="col_333">10</div>
</div>
<div class="nopass_num">
<div>对题数</div>
<div class="col_333">1</div>
</div>
</div>
<div class="btn" @click="back">返回</div>
</div>
</template>
<script>
export default {
customNavigation: true,
data() {
return {
backgroundNavbar: {
// background: "url('./img/navbar.png') no-repeat",
// backgroundSize: '100% 100%',
},
}
},
methods: {
back() {
uni.navigateBack({
delta: 2,
})
}
},
onShow() {
}
}
</script>
<style lang="scss" scoped>
.result {
padding: 32px;
box-sizing: border-box;
.grade {
height: 112px;
font-size: 96px;
color: #2D7DFF;
line-height: 112px;
font-weight: 600;
padding-left: 16px;
box-sizing: border-box;
}
.tips {
display: flex;
justify-content: space-between;
font-size: 26px;
color: #999999;
padding-left: 16px;
box-sizing: border-box;
div {
& > span {
color: #2D7DFF;
}
}
}
.card_list {
margin-top: 48px;
display: flex;
flex-wrap: wrap;
.pass,
.time,
.pass_num,
.nopass_num {
width: 47%;
height: 172px;
background: #FFFFFF;
box-shadow: 0 0 8px 0 rgba(0,0,0,0.02);
border-radius: 16px;
padding: 24px;
box-sizing: border-box;
& > div:first-child {
font-weight: 400;
font-size: 26rpx;
color: #999999;
margin-bottom: 16px;
}
& > div:last-child {
font-weight: 500;
font-size: 50rpx;
}
.col_pass {
color: #3BBC37;
}
.col_333 {
color: #333333;
}
}
.pass,
.pass_num {
margin: 0 30px 32px 0;
}
}
.btn {
position: fixed;
bottom: 0;
left: 50%;
transform: translate(-50%, -50%);
width: 320px;
height: 88px;
line-height: 88px;
background: #2D7DFF;
border-radius: 44px;
text-align: center;
color: #FFFFFF;
}
}
</style>

View File

@@ -0,0 +1,233 @@
<template>
<div class="testForm">
<u-navbar title="法治学习" :background="backgroundNavbar"></u-navbar>
<div class="type">
<div class="type_left">单选题</div>
<div><span class="col_blue">{{ activeIndex + 1 }}</span>/{{questionList.length}}</div>
</div>
<div class="topic">
<div v-for="(item,index) in questionList" :key="index" >
<div v-if="activeIndex === index">
<!-- 题目 -->
<div>{{ item.subject }}</div>
<!-- 单选 -->
<div class="answer_list">
<div class="answer_item error">
{{ options[index] }}: {{ item.answer}}
</div>
</div>
<!-- 多选 -->
<!-- <div class="answer_list">
<div class="answer_item error">
{{ options[index] }}: {{ item.answer}}
</div>
</div> -->
</div>
</div>
</div>
<div class="type mar-top">
<div class="type_left">答案解析</div>
</div>
<div class="topic mar-top">
<div><span>正确答案</span></div>
<div>获悉党的十八大以来曲靖市深入学习贯彻习近平新时代中国特色社会主义思想坚持以习近平法治思想为根本遵循和行动指南</div>
</div>
<div class="btn" @click="nextTopic" v-if="activeIndex < questionList.length - 1">下一题</div>
<div class="btn" @click="confirm">确定</div>
</div>
</template>
<script>
import dayjs from 'dayjs'
export default {
customNavigation: true,
data() {
return {
backgroundNavbar: {
// background: "url('./img/navbar.png') no-repeat",
// backgroundSize: '100% 100%',
},
options: ['A','B','C','D','E','F','G','H','I','J','K','L','M'],
questionList: [
{
index: 0,
subject: "共产党成立年份是?",
answer: "答案",
jiexi: '解析'
},
{
index: 1,
subject: "第2题",
answer: "答案",
jiexi: '解析'
},
{
index: 2,
subject: "第3题",
answer: "答案",
jiexi: '解析'
},
{
index: 3,
subject: "第4题",
answer: "答案",
jiexi: '解析'
},
{
index: 4,
subject: "第5题",
answer: "答案",
jiexi: '解析'
}
],
startX: 0, // 滑动开始x轴位置
moveX: 0, // 滑动的x轴距离
activeIndex: 0, // 当前第几题
newIndex: 0, // 滑动到第几题
list: [{
image: 'https://cdn.uviewui.com/uview/swiper/1.jpg',
title: '昨夜星辰昨夜风,画楼西畔桂堂东'
},
{
image: 'https://cdn.uviewui.com/uview/swiper/2.jpg',
title: '身无彩凤双飞翼,心有灵犀一点通'
},
{
image: 'https://cdn.uviewui.com/uview/swiper/3.jpg',
title: '谁念西风独自凉,萧萧黄叶闭疏窗,沉思往事立残阳'
}
],
createdTime: '', // 开始答题时间
endTime: '', // 结束时间
}
},
methods: {
onSwiper() {
console.log(e);
},
onSlideChange(o) {
console.log(o);
},
getList() {
console.log('题目列表');
},
nextTopic() {
this.activeIndex ++;
},
touchStart(e) {
this.startX = e.changedTouches[0].pageX
console.log('开始触摸:', this.startX);
},
touchEnd(e, index) { // 手指离开屏幕时触发
// 获取滑动距离
const moveX = e.changedTouches[0].pageX - this.startX
// 判断滑动方向
if (moveX < -100 && index < this.topic.length-1) {
// 【下一题】 判断大幅度左滑且不是最后一题
this.newIndex=this.newIndex+1
this.activeIndex= this.activeIndex+1
console.log('第'+this.index+'题');
}
else if (moveX > 100 && index!= 0) {
// 【上一题】 判断大幅度右滑且不是第一题
this.newIndex=this.newIndex-1
this.activeIndex=this.activeIndex-1
}
},
confirm() {
uni.navigateTo({url: './result'})
},
},
onReachBottom() {
this.current ++;
},
onLoad() {
this.createdTime = Date.parse(new Date())
}
}
</script>
<style lang="scss" scoped>
.testForm {
// background: url("./img/bg.png") no-repeat;
padding: 0 32px;
margin-top: 80px;
.type {
display: flex;
justify-content: space-between;
box-sizing: border-box;
font-size: 28px;
color: #333333;
.type_left {
font-weight: 600;
}
.col_blue {
color: #2D7DFF;
}
}
.topic {
background: #FFF;
margin-top: 32px;
padding: 24px;
margin-top: 80px;
border-radius: 16px;
box-shadow: 0 0 8px 0 rgba(0,0,0,0.02);
.answer_list {
margin-top: 32px;
.answer_item {
background: #FBFCFE;
border: 1px solid #CCCCCC;
border-radius: 16px;
padding: 28px 24px;
box-sizing: border-box;
.myChoice {
width: 136px;
height: 48px;
background: #FFFFFF;
border: 1px solid #E23C3C;
border-radius: 8px;
}
}
.succeed {
border: 2px solid #2D7EFE;
color: #2D7DFF;
}
.error {
border: 2px solid #E23C3C;
color: #E23C3C;
}
}
}
.mar-top {
margin-top: 32px;
}
.btn {
position: fixed;
left: 50%;
transform: translate(-50%, -50%);
bottom: 0;
width: 320px;
height: 88px;
line-height: 88px;
text-align: center;
background: #2D7DFF;
border-radius: 44px;
font-weight: 500;
font-size: 34px;
color: #FFFFFF;
}
}
</style>

View File

@@ -0,0 +1,341 @@
<template>
<div class="page">
<div class="header-bg">
<div class="header-info">
<div class="wrap" @click="handleLogin()">
<div class="user-img-div">
<img :src="user.avatarUrl" alt="" class="user-img" v-if="user.id && user.avatarUrl"/>
<open-data type="userAvatarUrl" lang="zh_CN" class="user-img" v-else/>
</div>
<div class="user-info">
<div class="option">
<template v-if="!user.id">
<p>登录</p>
<p>点击进行登录</p>
</template>
<template v-else>
<p v-if="isApprove">{{ user.realName }}</p>
<p v-else>{{ user.nickName }}</p>
<!-- <p>{{ user.areaName || "" }}</p> -->
<p>共累计学习<span>238</span>分钟</p>
</template>
</div>
<p class="info" @click.stop="$linkTo('./userInfo')">个人信息</p>
</div>
</div>
</div>
</div>
<div class="list-wrap">
<div class="card" v-for="(group,index) in listGroup" :key="index">
<div class="item" v-for="(item) in group" hover-class="bg-hover" :key="item.label"
@click="linkTo(item.path, item.type)">
<div class="block">
<img class="icon" :src="item.icon" alt="">
</div>
<span class="desc">{{ item.label }}</span>
</div>
</div>
</div>
<AiLogin ref="login" @success="getAuth()"/>
</div>
</template>
<script>
import {mapActions, mapState} from "vuex";
export default {
name: "AppPcMine",
appName: "我的",
customNavigation: true,
computed: {
...mapState(['user', 'token']),
isApprove() {
return this.user?.status == 2;
},
listGroup() {
return [
[
{
icon: require('./img/jfmx.png'),
label: "积分明细",
path: "./integralInfo",
type: 'token'
},
],
[
{
icon: require('./img/xxjl.png'),
label: "学习记录",
path: "./studyList",
type: 'token'
},
{
icon: require('./img/ksjl.png'),
label: "考试记录",
path: "./testList",
type: 'token'
},
{
icon: require('./img/wdzs.png'),
label: "我的证书",
path: "/mods/AppHometown/AppHometown",
type: 'token'
}
],
]
}
},
methods: {
...mapActions(['getUserInfo']),
approve() {
if (!this.token) {
this.$refs.login.show();
} else if (!this.isApprove) {
if (this.user.status == 0) {
this.$linkTo('/mods/AppPartyAuth/AppPartyAuth');
} else {
this.$linkTo('/mods/AppPartyAuth/partyAuthSuccess')
}
}
},
linkTo(url, type) {
if (type) {
if (this.token) {
if (type == 'token') {
this.$linkTo(url)
}
if (type == 'idNumber') {
if (this.user.status == 0) {
if (!this.user.phone) {
this.$linkTo('/pages/phone/bingPhoneNumber?from=auth')
} else {
this.$linkTo('/mods/AppAuth/AppAuth')
}
} else {
this.$linkTo(url)
}
}
} else {
this.$refs.login.show()
}
} else {
this.$linkTo(url)
}
},
handleLogin() {
if (!this.token) {
this.$refs.login.show();
}
},
getAuth() {
this.$nextTick(() => {
this.token && this.getUserInfo()
})
}
},
onShow() {
this.getAuth();
},
onShareAppMessage() {
return {
title: `欢迎使用数字平昌~`,
path: `/pages/AppHome/AppHome`
}
},
}
</script>
<style scoped lang="scss">
@import "~dvcp-wui/common";
.page {
width: 100%;
min-height: 100%;
background-color:#F4F5FA;;
position: relative;
.header-bg {
width: 100%;
height: 424px;
position: relative;
.header-info {
width: 100%;
height: 100%;
// background: url("./img/header-banner.png") no-repeat no-repeat;
background-size: 100% 100%;
box-sizing: border-box;
padding: 240px 0 0 48px;
.wrap {
width: 100%;
height: 96px;
display: flex;
align-items: center;
.user-img-div {
display: inline-block;
width: 96px;
height: 96px;
border-radius: 50%;
overflow: hidden;
border: 4px solid #FFFFFF;
flex-shrink: 0;
.user-img {
display: inline-block;
width: 96px;
height: 96px;
border-radius: 58px;
}
}
.user-info {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
margin-left: 26px;
box-sizing: border-box;
padding-right: 32px;
.option {
& > p:first-child {
font-size: 34px;
font-weight: 600;
color: #333333;
line-height: 54px;
}
& > p:last-child {
font-size: 26px;
font-weight: 400;
color: #7088A0;
line-height: 36px;
span {
color: #2D7DFF;
}
}
}
.info {
width: 136px;
height: 48px;
border-radius: 8px;
border: 2px solid #7088A0;
font-size: 26px;
font-weight: 400;
color: #7088A0;
display: flex;
align-items: center;
justify-content: center;
}
}
}
}
}
.approve {
position: absolute;
left: 50%;
top: 400px;
transform: translateX(-50%);
width: 686px;
height: 112px;
background: linear-gradient(90deg, #8FB4FF 0%, #4181FF 100%);
border-radius: 16px;
display: flex;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
padding: 0 20px;
.icon {
width: 296px;
height: 52px;
}
.cert {
font-family: PingFangSC-Regular, PingFang SC;
font-size: 28px;
color: #E7F2FF;
margin-right: 4px;
}
}
.list-wrap {
box-sizing: border-box;
padding: 32px;
.card {
width: 100%;
min-height: 100px;
border-radius: 16px;
background-color: #fff;
margin-bottom: 32px;
.item {
height: 100px;
display: flex;
align-items: center;
&:last-child {
.desc {
border-bottom: none !important;
}
}
.block {
width: 80px;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
.icon {
width: 44px;
height: 44px;
}
}
.desc, & > button {
height: 100%;
flex: 1;
font-size: 30px;
font-weight: 400;
color: #666666;
display: flex;
align-items: center;
& > span {
width: 100%;
height: 100%;
text-align: left;
display: flex;
align-items: center;
}
&::after {
border: none;
}
}
.no-border {
border-bottom: none;
}
}
&:first-of-type {
margin-bottom: 32px;
}
}
}
.point-card {
padding: 0 32px!important;
.card {
margin-bottom: 0!important;
}
}
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,41 @@
<template>
<div class="page">
</div>
</template>
<script>
import {mapState} from 'vuex'
export default {
name: "integralInfo",
appName: "积分明细",
data() {
return {
}
},
computed: {
...mapState(['user', 'token']),
},
onLoad() {
uni.setNavigationBarTitle({
title: '积分明细'
})
uni.setNavigationBarColor({
frontColor: "#000000",
backgroundColor: "#F4F6FA",
})
},
methods: {
}
}
</script>
<style scoped lang="scss">
@import "~dvcp-wui/common";
.page {
width: 100%;
background-color: #F4F5FA;
}
</style>

View File

@@ -0,0 +1,158 @@
<template>
<div class="page">
<div class="list">
<div class="item">
<div class="top">
<div class="flex-left">
<img class="video-img" src="https://cdn.cunwuyun.cn/img/qrcode-sign-fail.png" alt="">
<img class="play-icon" src="https://cdn.cunwuyun.cn/dvcp/pay-btn.png" alt="">
<div class="status status0">未完成</div>
</div>
<div class="flex-right">
<h3>课程名称</h3>
<div class="time">
<span>23人已学习</span>
<span>共3分56秒</span>
</div>
</div>
</div>
<div class="bottom">继续学习</div>
</div>
<div class="item">
<div class="top">
<div class="flex-left">
<img class="video-img" src="https://cdn.cunwuyun.cn/dvcp/pay-btn.png" alt="">
<div class="status status1">已完成</div>
</div>
<div class="flex-right">
<h3>课程名称课程名称课程名称课程名称课程名称课程名称课程名称课程名称课程名称</h3>
<div class="time">
<span>23人已学习</span>
<span>共3分56秒</span>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import {mapState} from 'vuex'
export default {
name: "studyList",
appName: "学习记录",
data() {
return {
}
},
computed: {
...mapState(['user', 'token']),
},
onLoad() {
uni.setNavigationBarTitle({
title: '学习记录'
})
uni.setNavigationBarColor({
frontColor: "#000000",
backgroundColor: "#F4F6FA",
})
},
methods: {
}
}
</script>
<style scoped lang="scss">
@import "~dvcp-wui/common";
.page {
width: 100%;
background-color: #F4F5FA;
.list {
padding: 50px 32px 0;
.item {
width: 100%;
background-color: #fff;
box-shadow: inset 0 0 0 0 #EEEEEE;
border-radius: 16px;
margin-bottom: 24px;
.top {
padding: 24px;
display: flex;
.video-img {
width: 160px;
height: 160px;
margin-right: 24px;
}
.flex-left {
position: relative;
}
.play-icon {
width: 48px;
height: 48px;
position: absolute;
top: 56px;
left: 56px;
}
.status {
position: absolute;
top: 0;
left: 0;
width: 110px;
height: 48px;
line-height: 48px;
text-align: center;
border-radius: 8px;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 26px;
color: #FFF;
}
.status0 {
background-color: #FF883C;
}
.status1 {
background-color: #3BBC37;
}
.flex-right {
width: calc(100% - 184px);
h3 {
width: 100%;
line-height: 48px;
height: 96px;
font-family: PingFangSC-Medium;
font-weight: 500;
font-size: 34px;
color: #333;
overflow:hidden;
text-overflow:ellipsis;
display:-webkit-box;
-webkit-box-orient:vertical;
-webkit-line-clamp:2;
margin-bottom: 24px;
}
.time {
line-height: 36px;
font-family: PingFangSC-Regular;
font-size: 26px;
color: #999;
letter-spacing: 0;
display: flex;
justify-content: space-between;
}
}
}
.bottom {
line-height: 88px;
border-top: 1px solid #eee;
font-family: PingFangSC-Regular;
font-size: 28px;
color: #2D7DFF;
text-align: center;
}
}
}
}
</style>

View File

@@ -0,0 +1,108 @@
<template>
<div class="page">
<div class="list">
<div class="item">
<div class="top">
<div class="flex-left">
<h3>曲靖规则基本考试</h3>
<p class="mar-b16"><span>10</span>,预计<span>10</span>分钟</p>
<p>264人通过/283人参与</p>
</div>
<div class="flex-right">
<img src="https://cdn.cunwuyun.cn/img/qrcode-sign-fail.png" alt="">
</div>
</div>
<div class="bottom">重新考试</div>
</div>
</div>
</div>
</template>
<script>
import {mapState} from 'vuex'
export default {
name: "studyList",
appName: "考试记录",
data() {
return {
}
},
computed: {
...mapState(['user', 'token']),
},
onLoad() {
uni.setNavigationBarTitle({
title: '考试记录'
})
uni.setNavigationBarColor({
frontColor: "#000000",
backgroundColor: "#F4F6FA",
})
},
methods: {
}
}
</script>
<style scoped lang="scss">
@import "~dvcp-wui/common";
.page {
width: 100%;
background-color: #F4F5FA;
.list {
padding: 50px 32px 0;
.item {
width: 100%;
background-color: #fff;
box-shadow: inset 0 0 0 0 #EEEEEE;
border-radius: 16px;
margin-bottom: 24px;
.top {
padding: 24px;
position: relative;
display: flex;
.flex-left {
width: calc(100% - 204px);
h3 {
width: 100%;
line-height: 48px;
font-family: PingFangSC-Medium;
font-weight: 500;
font-size: 34px;
color: #333;
margin-bottom: 32px;
}
p {
color: #999;
font-size: 26px;
font-family: PingFangSC;
line-height: 36px;
span {
color: #2D7DFF;
}
}
.mar-b16 {
margin-bottom: 16px;
}
}
.flex-right {
img {
width: 160px;
height: 160px;
}
}
}
.bottom {
line-height: 88px;
border-top: 1px solid #eee;
font-family: PingFangSC-Regular;
font-size: 28px;
color: #687DA6;
text-align: center;
}
}
}
}
</style>

View File

@@ -0,0 +1,251 @@
<template>
<div class="page">
<div class="info-list">
<div class="item-content mar-b8">
<div class="item solid">
<p class="mar-t22">头像</p>
<button class="user-img-div" open-type="chooseAvatar" @chooseavatar="handleWeixinSync">
<img :src="user.avatarUrl" class="user-img">
</button>
</div>
<div class="item">
<p>用户昵称</p>
<div v-if="!editNickName" @click="editNickName=true">
<div class="name" v-text="nickName"/>
</div>
<input v-else type="nickname" class="editNickName" v-model="nickName" @blur="handleWeixinSync">
</div>
</div>
<div class="item-content mar-b8">
<div class="item">
<p>手机号</p>
<div>{{ user.phone || '' }}</div>
</div>
</div>
<div class="item-content mar-b8">
<div class="item solid">
<p>姓名</p>
<div>{{ user.realName || '' }}</div>
</div>
<div class="item solid">
<p>身份证号</p>
<div>{{ user.idNumber || '' }}</div>
</div>
<div class="item">
<p>地区</p>
<div>{{ user.homeName || '' }}</div>
</div>
</div>
<div class="item-content" @click="onLogout">
<div class="item">
<p class="login-out">退出登录</p>
</div>
</div>
</div>
</div>
</template>
<script>
import {mapActions, mapState} from 'vuex'
export default {
name: "userInfo",
appName: "个人中心",
computed: {
...mapState(['user', 'token']),
nickName: {
set(v) {
},
get() {
const {nickName} = this.user
return nickName
}
}
},
onLoad() {
uni.setNavigationBarTitle({
title: '个人中心'
})
uni.setNavigationBarColor({
frontColor: "#000000",
backgroundColor: "#F4F6FA",
})
this.getUserInfo()
},
data() {
return {
editNickName: false
}
},
methods: {
...mapActions(['getUserInfo', 'autoLogin']),
upLoad(img) {
return new Promise((resolve, reject) => {
uni.uploadFile({
url: `${this.$instance.defaults.baseURL}/admin/file/add`,
filePath: img,
name: 'file',
header: {
'Content-Type': 'multipart/form-data',
Authorization: uni.getStorageSync('token')
},
success: uploadFileRes => {
resolve(uploadFileRes)
},
fail: err => {
reject(err)
}
})
})
},
onLogout() {
uni.showModal({
title: '提示',
content: "是否要退出登录",
success: res => {
if (res.confirm) {
this.$store.commit('logout')
this.$toast('退出成功');
setTimeout(() => {
uni.switchTab({
url: '/pages/AppMine/AppMine'
})
}, 500)
}
}
})
},
handleWeixinSync({detail}) {
const {value: nickName, avatarUrl} = detail
this.autoLogin({nickName, avatarUrl})
}
}
}
</script>
<style scoped lang="scss">
@import "~dvcp-wui/common";
.page {
width: 100%;
background-color: #F4F5FA;
.info-list {
padding: 50px 16px 0;
.item-content {
padding: 0 32px;
background-color: #fff;
border-radius: 32px;
}
.item {
padding: 36px 0;
line-height: 40px;
width: 100%;
box-sizing: content-box;
display: flex;
justify-content: space-between;
font-size: 30px;
p {
font-family: PingFangSC-Regular;
color: #666;
}
div {
font-family: PingFangSC-Medium;
font-weight: 500;
color: #333;
}
.user-img-div {
width: 104px;
height: 104px;
border-radius: 50%;
overflow: hidden;
}
.user-img {
width: 104px;
height: 104px;
vertical-align: middle;
border-radius: 50%;
}
.right-icon {
width: 40px;
height: 40px;
vertical-align: middle;
}
.mar-t22 {
margin-top: 44px;
}
.login-out {
width: 100%;
font-size: 34px;
text-align: center;
font-family: PingFangSC-Regular;
color: #4181FF;
}
}
}
.self-knowledge-show {
position: fixed;
left: 0;
top: 0;
z-index: 100;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.3);
}
.toast-bg {
position: fixed;
z-index: 101;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.toast {
background-color: #fff;
width: 686px;
height: 316px;
font-size: 36px;
}
.toast-msg {
text-align: center;
line-height: 50px;
color: #333;
font-weight: 500;
padding: 84px 0 80px 0;
}
.toast-btn {
display: inline-block;
width: 120px;
text-align: center;
line-height: 50px;
}
.cancel {
margin-left: 394px;
margin-right: 40px;
}
.confirm {
color: #197DF0;
}
.editNickName {
text-align: right;
font-size: 28px;
}
.solid {
border-bottom: 1px solid #eee;
}
}
</style>

View File

@@ -16,7 +16,7 @@ const configs = {
dev: {
areaId: '341021104000',
areaName: '郑村镇',
baseUrl: 'http://192.168.1.87:59998'
baseUrl: 'http://192.168.1.87:9000'
}
}
// 当前选中配置