f0ab4214 by 杨炀

no message

1 parent 4c57b42c
Showing 65 changed files with 808 additions and 1598 deletions
......@@ -493,6 +493,36 @@ function getMergePaymentInfo(mergeId) {
}
})
}
// 一键下发
function submitCert(data) {
return request({
url: `/exam/payment/submitCerts/nesting`,
method: 'put',
params: data
})
}
function getCertsLList(query) {
return request({
url: '/exam/payment/certsList',
method: 'get',
params: query
})
}
function getExamListByPayId(params) {
return request({
url: `/exam/payment/examList/${params.payId}`,
method: 'get',
params: params
})
}
function certStudentList(query) {
return request({
url: '/exam/person/cert/studentList',
method: 'get',
params: query
})
}
export {
getMessage,
......@@ -539,5 +569,7 @@ export {
groupCommitPaymentVoucher,getFeeBillById,
personalCommit,
delPayment,editYear,addPersonPaymentGroup,
commitRenew,getVerityMergeList,doMergeFlows,getMergePaymentInfo
commitRenew,getVerityMergeList,doMergeFlows,getMergePaymentInfo,
submitCert,getCertsLList,getExamListByPayId,
certStudentList
}
\ No newline at end of file
......
......@@ -147,7 +147,16 @@ color: #7D8592;}
font-weight: 500;color: #0A1629;
}
.mt30{margin-top: 30rpx;}
.userlist {
.userlist {
.func{display: flex;justify-content: flex-end;
border-top: 1px dashed #e5e5e5;padding-top: 20rpx;
button{border: 1px solid #AD181F;
border-radius: 30rpx;height: 60rpx;line-height: 60rpx;
font-size: 30rpx;color: #AD181F;background: #fff;
margin: 0 0 0 30rpx;padding: 0 60rpx;
}
text{font-size: 30rpx;padding:30rpx 0 0;}
}
.colorful {
width: 100rpx;
margin-right: 14rpx;
......
<template>
<view class="content">
<swiper class="swiper"
:autoplay="autoplay"
:duration="duration">
<swiper-item>
<view class="swiper-item">
<view class="swiper-item-img"><image src="../../static/guide/title_01.png" mode="aspectFit"></image></view>
<view class="swiper-item-img"><image src="../../static/guide/icon_01.png" mode="aspectFit"></image></view>
</view>
<view class="jump-over" @tap="launchFlag()">{{jumpover}}</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">
<view class="swiper-item-img"><image src="../../static/guide/title_02.png" mode="aspectFit"></image></view>
<view class="swiper-item-img"><image src="../../static/guide/icon_02.png" mode="aspectFit"></image></view>
</view>
<view class="jump-over" @tap="launchFlag()">{{jumpover}}</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">
<view class="swiper-item-img"><image src="../../static/guide/title_03.png" mode="aspectFit"></image></view>
<view class="swiper-item-img"><image src="../../static/guide/icon_03.png" mode="aspectFit"></image></view>
</view>
<view class="jump-over" @tap="launchFlag()">{{jumpover}}</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">
<view class="swiper-item-img"><image src="../../static/guide/title_04.png" mode="aspectFit"></image></view>
<view class="swiper-item-img"><image src="../../static/guide/icon_04.png" mode="aspectFit"></image></view>
</view>
<view class="experience" @tap="launchFlag()">{{experience}}</view>
</swiper-item>
</swiper>
<view class="uniapp-img"><image src="../../static/guide/uniapp4@2x.png" mode="aspectFit"></image></view>
</view>
</template>
<script>
export default {
data() {
return {
background: ['color1', 'color2', 'color3'],
autoplay: false,
duration: 500,
jumpover: '跳过',
experience: '立即体验'
}
},
methods: {
launchFlag: function(){
/**
* 向本地存储中设置launchFlag的值,即启动标识;
*/
uni.setStorage({
key: 'launchFlag',
data: true,
});
uni.switchTab({
url: '/pages/tabBar/component/component'
});
}
}
}
</script>
<style>
page,
.content{
width: 100%;
height: 100%;
background-size: 100% auto ;
padding: 0;
}
.swiper{
width: 100%;
height: 80%;
background: #FFFFFF;
}
.swiper-item {
width: 100%;
height: 100%;
text-align: center;
position: relative;
display: flex;
/* justify-content: center; */
align-items:flex-end;
flex-direction:column-reverse
}
.swiper-item-img{
width: 100%;
height: auto;
margin: 0 auto;
}
.swiper-item-img image{
width: 80%;
}
.uniapp-img{
height: 20%;
background: #FFFFFF;
display: flex;
justify-content: center;
align-items:center;
overflow: hidden;
}
.uniapp-img image{
width: 40%;
}
.jump-over,.experience{
position: absolute;
height: 60upx;
line-height: 60upx;
padding: 0 40upx;
border-radius: 30upx;
font-size: 32upx;
color: #454343;
border: 1px solid #454343;
z-index: 999;
}
.jump-over{
right: 45upx;
top: 125upx;
}
.experience{
right: 50%;
margin-right: -105upx;
bottom: 0;
}
</style>
# 引导页
### 基于uni-app框架的swiper组件打开的时候启动。
> 首次启动展示引导页,之后启动不再展示。那么就意味着,我们需要一个标识来确定,App是否已经启动过。
> 我们可以在本地存储一个key来做为已经启动过App的标识。那么,我们在入口这里,就可以读取这个key,来决定是否展示引导页。
> 因工作繁忙目前该程序金对安卓做了适配,IOS可根据环境自己适配。谢谢
## 目录结构
* /pages/index/index.vue //入口页
### 存储key
* 向本地存储中设置launchFlag的值,即启动标识;
### 获取key
* 向本地存储中设置launchFlag的值,即启动标识;
* 获取本地存储中launchFlag的值
* 若存在,说明不是首次启动,直接进入首页;
* 若不存在,说明是首次启动,进入引导页;
```html
<view class="main">
<code-elf-guide v-if="guidePages"></code-elf-guide>
</view>
```
```javascript
import codeElfGuide from '@/components/code-elf-guide/code-elf-guide.vue'
export default {
components: {
codeElfGuide
},
data() {
return {
guidePages:true
}
},
onLoad(){
this.loadExecution()
},
methods: {
loadExecution: function(){
/**
* 获取本地存储中launchFlag的值
* 若存在,说明不是首次启动,直接进入首页;
* 若不存在,说明是首次启动,进入引导页;
*/
try {
// 获取本地存储中launchFlag标识
const value = uni.getStorageSync('launchFlag');
if (value) {
// launchFlag=true直接跳转到首页
uni.switchTab({
url: '/pages/tabBar/component/component'
});
} else {
// launchFlag!=true显示引导页
this.guidePages = true
}
} catch(e) {
// error
uni.setStorage({
key: 'launchFlag',
data: true,
success: function () {
console.log('error时存储launchFlag');
}
});
this.guidePages = true
}
}
}
}
```
```css
page,.main{
width: 100%;
height: 100%;
}
```
### 首页清除key,进行测试
* 清除本地存储中设置launchFlag的值,即启动标识;
* 两秒后重启APP,进行测试
```javascript
uni.showModal({
title: '清除launchFlag值',
content: '确定要清除launchFlag值,进行重启测试?',
success: function (res) {
if (res.confirm) {
console.log('用户点击确定');
// 清除缓存
uni.clearStorage();
uni.showToast({
icon: 'none',
duration:3000,
title: '清除成功2秒后重启'
});
// 两秒后重启
setTimeout(function() {
uni.hideToast();
plus.runtime.restart();
}, 2000);
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
```
\ No newline at end of file
# 日历组件 lx-calendar可选择周与月支持左右滑动切换
```
<template>
<view class="content">
<lxCalendar @change="change"></lxCalendar>
</view>
</template>
<script>
import lxCalendar from '../../components/lx-calendar/lx-calendar.vue'
export default {
components:{
lxCalendar,
},
data() {
return {
title: 'Hello'
}
},
onLoad() {
},
methods: {
change(e){
console.log(e);
}
}
}
</script>
```
事件 | 说明
---|---
change | 日期改变时执行
参数 | 类型 | 说明
---|---|---
value | 字符串 | 选中的日期
dot_lists | 数组 | 显示点的日期
# slider-range
uni-app 滑块区间选择组件
可根据具体需求,修改、自定义其他内容。
## 属性说明
|属性名|类型|默认值|说明|
| -- | -- | --|--|
| value | Array<Number, Number> | [0,100] |滑块已选中区间的值|
| min | Number| 0 | 滑块区间最小值 |
| max | Number | 100 | 滑块区间最大值 |
| step | Number | 1 | 拖动时的步长 |
| disabled | Boolean | false | 是否为禁用状态 |
| height | Number | 50 | 滑块容器高度 |
| barHeight | Number | 5 | 滑块进度条高度 |
| backgroundColor | String | #e9e9e9| 滑块进度条背景色|
| activeColor | String | #1aad19 | 已选中区间进度条颜色|
| blockSize | Number | 20 | 滑块大小 |
| blockColor | String | #fff | 滑块颜色 |
| decorationVisible | Boolean | false | 是否显示滑块内装饰元素|
| tipVisible | Boolean | true | 是否显示滑块值提示文本 |
| fomat| Function | | 滑块值提示文本格式化函数,**注意**:小程序中此属性必传,否则会报错,如果无需格式化,可以简单返回原始值: `format(val) { return val }`;H5中可以不传。|
## 使用示例
```html
<slider-range
:value="rangeValue"
:min="rangeMin"
:max="rangMax"
:step="5"
:bar-height="3"
:block-size="26"
background-color="#EEEEF6"
active-color="#FF6B00"
:format="format"
:decorationVisible="true"
@change="handleRangeChange"
></slider-range>
```
```javascript
import SliderRange from '../components/slider-range/index.vue'
export default {
components: {
SliderRange
},
data() {
return {
rangeMin: 5,
rangMax: 200,
rangeValue: [10, 50]
}
},
methods: {
format(val) {
return val + '%'
},
handleRangeChange(e) {
this.rangeValue = e
}
}
}
```
效果图
![](http://images.alisali.cn/img_20190715175325.png)
<template>
<view
class="slider-range"
:class="{ disabled: disabled }"
:style="{ paddingLeft: blockSize / 2 + 'px', paddingRight: blockSize / 2 + 'px' }"
>
<view class="slider-range-inner" :style="{ height: height + 'px' }">
<view
class="slider-bar"
:style="{
height: barHeight + 'px',
}"
>
<!-- 背景条 -->
<view
class="slider-bar-bg"
:style="{
backgroundColor: backgroundColor,
}"
></view>
<!-- 滑块实际区间 -->
<view
class="slider-bar-inner"
:style="{
width: ((values[1] - values[0]) / (max - min)) * 100 + '%',
left: lowerHandlePosition + '%',
backgroundColor: activeColor,
}"
></view>
</view>
<!-- 滑动块-左 -->
<view
class="slider-handle-block"
:class="{ decoration: decorationVisible }"
:style="{
backgroundColor: blockColor,
width: blockSize + 'px',
height: blockSize + 'px',
left: lowerHandlePosition + '%',
}"
@touchstart="_onTouchStart"
@touchmove="_onBlockTouchMove"
@touchend="_onBlockTouchEnd"
data-tag="lowerBlock"
></view>
<!-- 滑动块-右 -->
<view
class="slider-handle-block"
:class="{ decoration: decorationVisible }"
:style="{
backgroundColor: blockColor,
width: blockSize + 'px',
height: blockSize + 'px',
left: higherHandlePosition + '%',
}"
@touchstart="_onTouchStart"
@touchmove="_onBlockTouchMove"
@touchend="_onBlockTouchEnd"
data-tag="higherBlock"
></view>
<!-- 滑块值提示 -->
<view v-if="tipVisible" class="range-tip" :style="lowerTipStyle">{{ format(values[0]) }}</view>
<view v-if="tipVisible" class="range-tip" :style="higherTipStyle">{{ format(values[1]) }}</view>
</view>
</view>
</template>
<script>
export default {
components: {},
props: {
//滑块区间当前取值
value: {
type: Array,
default: function() {
return [0, 100]
},
},
//最小值
min: {
type: Number,
default: 0,
},
//最大值
max: {
type: Number,
default: 100,
},
step: {
type: Number,
default: 1,
},
format: {
type: Function,
default: function(val) {
return val
},
},
disabled: {
type: Boolean,
default: false,
},
//滑块容器高度
height: {
height: Number,
default: 50,
},
//区间进度条高度
barHeight: {
type: Number,
default: 5,
},
//背景条颜色
backgroundColor: {
type: String,
default: '#e9e9e9',
},
//已选择的颜色
activeColor: {
type: String,
default: '#1aad19',
},
//滑块大小
blockSize: {
type: Number,
default: 20,
},
blockColor: {
type: String,
default: '#fff',
},
tipVisible: {
type: Boolean,
default: true,
},
decorationVisible: {
type: Boolean,
default: false,
},
},
data() {
return {
values: [this.min, this.max],
startDragPos: 0, // 开始拖动时的坐标位置
startVal: 0, //开始拖动时较小点的值
}
},
computed: {
// 较小点滑块的坐标
lowerHandlePosition() {
return ((this.values[0] - this.min) / (this.max - this.min)) * 100
},
// 较大点滑块的坐标
higherHandlePosition() {
return ((this.values[1] - this.min) / (this.max - this.min)) * 100
},
lowerTipStyle() {
if (this.lowerHandlePosition < 90) {
return `left: ${this.lowerHandlePosition}%;`
}
return `right: ${100 - this.lowerHandlePosition}%;transform: translate(50%, -100%);`
},
higherTipStyle() {
if (this.higherHandlePosition < 90) {
return `left: ${this.higherHandlePosition}%;`
}
return `right: ${100 - this.higherHandlePosition}%;transform: translate(50%, -100%);`
},
},
created: function() {},
onLoad: function(option) {},
watch: {
//滑块当前值
value: {
immediate: true,
handler(newVal, oldVal) {
if (this._isValuesValid(newVal) && (newVal[0] !== this.values[0] || newVal[1] !== this.values[1])) {
this._updateValue(newVal)
}
},
},
},
methods: {
_updateValue(newVal) {
// 步长大于区间差,或者区间最大值和最小值相等情况
if (this.step >= this.max - this.min) {
throw new RangeError('Invalid slider step or slider range')
}
let newValues = []
if (Array.isArray(newVal)) {
newValues = [newVal[0], newVal[1]]
}
if (typeof newValues[0] !== 'number') {
newValues[0] = this.values[0]
} else {
newValues[0] = Math.round((newValues[0] - this.min) / this.step) * this.step + this.min
}
if (typeof newValues[1] !== 'number') {
newValues[1] = this.values[1]
} else {
newValues[1] = Math.round((newValues[1] - this.min) / this.step) * this.step + this.min
}
// 新值与原值相等,不做处理
if (this.values[0] === newValues[0] && this.values[1] === newValues[1]) {
return
}
// 左侧滑块值小于最小值时,设置为最小值
if (newValues[0] < this.min) {
newValues[0] = this.min
}
// 右侧滑块值大于最大值时,设置为最大值
if (newValues[1] > this.max) {
newValues[1] = this.max
}
// 两个滑块重叠或左右交错,使两个滑块保持最小步长的间距
if (newValues[0] >= newValues[1]) {
// 左侧未动,右侧滑块滑到左侧滑块之左
if (newValues[0] === this.values[0]) {
newValues[1] = newValues[0] + this.step
} else {
// 右侧未动, 左侧滑块滑到右侧之右
newValues[0] = newValues[1] - this.step
}
}
this.values = newValues
this.$emit('change', this.values)
},
_onTouchStart: function(event) {
if (this.disabled) {
return
}
this.isDragging = true
let tag = event.target.dataset.tag
//兼容h5平台及某版本微信
let e = event.changedTouches ? event.changedTouches[0] : event
this.startDragPos = e.pageX
this.startVal = tag === 'lowerBlock' ? this.values[0] : this.values[1]
},
_onBlockTouchMove: function(e) {
if (this.disabled) {
return
}
this._onDrag(e)
},
_onBlockTouchEnd: function(e) {
if (this.disabled) {
return
}
this.isDragging = false
this._onDrag(e)
},
_onDrag(event) {
if (!this.isDragging) {
return
}
let view = uni
.createSelectorQuery()
.in(this)
.select('.slider-range-inner')
view
.boundingClientRect(data => {
let sliderWidth = data.width
const tag = event.target.dataset.tag
let e = event.changedTouches ? event.changedTouches[0] : event
let diff = ((e.pageX - this.startDragPos) / sliderWidth) * (this.max - this.min)
let nextVal = this.startVal + diff
if (tag === 'lowerBlock') {
this._updateValue([nextVal, null])
} else {
this._updateValue([null, nextVal])
}
})
.exec()
},
_isValuesValid: function(values) {
return Array.isArray(values) && values.length == 2
},
},
}
</script>
<style scoped>
.slider-range {
position: relative;
padding-top: 40rpx;
}
.slider-range-inner {
position: relative;
width: 100%;
}
.slider-range.disabled .slider-bar-inner {
opacity: 0.35;
}
.slider-range.disabled .slider-handle-block {
cursor: not-allowed;
}
.slider-bar {
position: absolute;
top: 50%;
left: 0;
right: 0;
transform: translateY(-50%);
}
.slider-bar-bg {
position: absolute;
width: 100%;
height: 100%;
border-radius: 10000px;
z-index: 10;
}
.slider-bar-inner {
position: absolute;
width: 100%;
height: 100%;
border-radius: 10000px;
z-index: 11;
}
.slider-handle-block {
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;
box-shadow: 0 0 3px 2px rgba(227, 229, 241, 0.5);
z-index: 12;
}
.slider-handle-block.decoration::before {
position: absolute;
content: '';
width: 6upx;
height: 24upx;
top: 50%;
left: 29%;
transform: translateY(-50%);
background: #eeedf2;
border-radius: 3upx;
z-index: 13;
}
.slider-handle-block.decoration::after {
position: absolute;
content: '';
width: 6upx;
height: 24upx;
top: 50%;
right: 29%;
transform: translateY(-50%);
background: #eeedf2;
border-radius: 3upx;
z-index: 13;
}
.range-tip {
position: absolute;
top: 0;
font-size: 24upx;
color: #666;
transform: translate(-50%, -100%);
}
</style>
<template>
<view class="demo-slider-range">
<view class="section-title">普通用法</view>
<view class="slider-item">
<slider-range
:value="slider1.rangeValue"
:min="slider1.min"
:max="slider1.max"
:step="slider1.step"
:bar-height="barHeight"
:block-size="blockSize"
:background-color="backgroundColor"
:format="format1"
@change="handleRangeChange"
></slider-range>
</view>
<view class="section-title">自定义</view>
<view class="slider-item">
<slider-range
:value="slider2.rangeValue"
:min="slider2.min"
:max="slider2.max"
:step="slider2.step"
:bar-height="barHeight"
:block-size="blockSize"
:background-color="backgroundColor"
:active-color="slider2.activeColor"
:format="format2"
:decorationVisible="slider2.decorationVisible"
@change="handleRangeChange"
></slider-range>
</view>
</view>
</template>
<script>
import SliderRange from '../../components/slider-range/index.vue'
export default {
components: {
SliderRange,
},
data() {
return {
barHeight: 3,
blockSize: 26,
backgroundColor: '#EEEEF6',
slider1: {
min: 50,
max: 200,
step: 10,
rangeValue: [50, 150],
},
slider2: {
rangeMin: 0,
rangMax: 100,
rangeValue: [8, 80],
step: 1,
activeColor: '#FF6B00',
decorationVisible: true,
},
}
},
methods: {
format1(val) {
return val
},
format2(val) {
return `${val}%`
},
handleRangeChange(e) {
this.rangeValue = e
},
},
}
</script>
<style>
.demo-slider-range {
background-color: #fff;
padding: 100rpx 40rpx 0;
}
.section-title {
padding: 0 0 20rpx;
color: #666;
}
.slider-item:not(:last-child) {
margin-bottom: 100rpx;
}
</style>
<template>
<view class="box">
<view class="box1">
<view class="title">
<view class="title-left">{{ porps.title }}</view>
<view class="title-icon" @click="changFN">
<uni-icons type="top" color="#95a1a6" v-if="show"></uni-icons>
<uni-icons type="bottom" color="#95a1a6" v-else></uni-icons>
</view>
</view>
<view class="conter-liner-cost">
<view class="liner-left">{{ porps.text }}&nbsp;&nbsp; 合计:</view>
<view class="liner-right">{{ porps.cost }}</view>
</view>
</view>
<view class="box2" v-show="show"><slot></slot></view>
</view>
</template>
<script setup>
import { ref } from 'vue';
const porps = defineProps({
title: String,
text: String,
cost: String
});
const show = ref(false);
function changFN() {
show.value = !show.value;
}
</script>
<style lang="scss" scoped>
.box {
margin: 0;
padding: 0 25rpx;
.box1 {
margin-bottom: 23rpx;
margin-top: 35rpx;
.title {
display: flex;
justify-content: space-between;
margin-bottom: 10rpx;
.title-left {
font-size: 30rpx;
font-family: PingFang SC;
font-weight: 500;
color: #2b3133;
}
}
.conter-liner-cost {
display: flex;
.liner-left {
font-size: 28rpx;
font-family: PingFang SC;
font-weight: 400;
color: #7b7f83;
}
.liner-right {
font-size: 28rpx;
font-family: PingFang SC;
font-weight: 400;
color: #ff8124;
}
}
}
.box2 {
border-top: 1rpx solid #e6e6e6;
}
}
</style>
<template>
<view class=" conter-box">
<view class="box" v-if="props.trainProjectsList.length != 0">
<view class="text">培训科目</view>
<view class="box2">
<checkbox-group>
<view class="box-check" v-for="item in props.trainProjectsList" :key="item.id">
<view class="">
<view class="title">{{ item.projectName }}</view>
<view class="content">
{{ item.isNecessary == 1 ? '必选' : '非必选' }}&nbsp;&nbsp;合计:
<view class="span">{{ item.cost }}</view>
</view>
</view>
<view class="checkbox">
<checkbox
:disabled="item.isNecessary == 1"
:value="item.id"
@click="checkTrain(item)"
:checked="item.check"
/>
</view>
</view>
</checkbox-group>
</view>
</view>
<view class="box" v-if="props.examProjectsList.length != 0">
<view class="text">考试科目</view>
<view class="box2">
<checkbox-group>
<view class="box-check" v-for="item in props.examProjectsList" :key="item.id">
<view class="">
<view class="title">{{ item.projectName }}</view>
<view class="content">
{{ item.isNecessary == 1 ? '必选' : '非必选' }}&nbsp;&nbsp;合计:
<view class="span">{{ item.cost }}</view>
</view>
</view>
<view class="checkbox">
<checkbox
:disabled="item.isNecessary == 1"
:value="item.id"
@click="checkTrain(item)"
:checked="item.check"
/>
</view>
</view>
</checkbox-group>
</view>
</view>
</view>
<view class="foot">
<view class="button1" @click="upFN">上一步</view>
<view class="button" @click="nextFN">下一步</view>
</view>
<view class="nodata " v-if="props.examProjectsList.length == 0 && props.trainProjectsList.length == 0">
没有培训科目
</view>
</template>
<script setup>
import { forEach } from 'lodash';
import { ref, getCurrentInstance, reactive, toRefs } from 'vue';
const props = defineProps({
trainProjectsList: {},
examProjectsList: {},
hotelList: {},
id: {}
});
const data = reactive({
projectIdsArray: []
});
const examIdsArry = ref([]);
const { projectIdsArray } = toRefs(data);
const emit = defineEmits(['nextFN']);
const checkbox1 = ref([0]);
function checkTrain(item) {
if (item.isNecessary == 1) {
item.check = true;
} else {
item.check = !item.check;
}
}
// 上一步
function upFN() {
emit('nextFN', 0);
}
// 下一步
function nextFN() {
let falg = true;
let arr1 = [];
let arr2 = [];
props.examProjectsList.forEach(item => {
if (item.check) {
arr1.push(item.id);
}
});
props.trainProjectsList.forEach(item => {
if (item.check) {
arr2.push(item.id);
}
});
let examList = JSON.parse(JSON.stringify(props.examProjectsList));
let trainList = JSON.parse(JSON.stringify(props.trainProjectsList));
examList.concat(trainList).forEach(item => {
if (item.isNecessary == 1 && item.check == false) {
falg = false;
}
});
if (falg) {
examIdsArry.value = arr1;
projectIdsArray.value = arr2;
if (props.hotelList.length == 0) {
// 没有酒店直接报名
// 页面跳转
let path = `/pages/train/costBreakdown/costBreakdown?id=` + props.id;
wx.navigateTo({
url: path
});
} else {
emit('nextFN', 2, projectIdsArray.value, examIdsArry.value);
}
} else {
uni.showToast({
title: '请选择必选科目!',
duration: 2000,
icon: 'error'
});
return false;
}
}
</script>
<style scoped lang="scss">
.nodata {
background: url(/static/nodata.png) no-repeat;
background-size: 100%;
width: 100%;
height: 835rpx;
color: #aaa59f;
font-size: 50rpx;
}
.conter-box {
padding-bottom: 100rpx;
}
.box {
padding: 34rpx 25rpx;
background-color: #f4f6fa;
padding-bottom: 0;
.box2 {
background-color: #fff;
border-radius: 15rpx;
margin-top: 20rpx;
}
.text {
height: 29px;
font-size: 30rpx;
font-family: PingFang SC;
font-weight: 500;
color: #000000;
line-height: 62rpx;
}
.box-check {
padding: 40rpx;
display: flex;
justify-content: space-between;
border-bottom: 1rpx solid #e6e6e6;
padding-bottom: 20rpx;
:deep(.checkbox__inner) {
background-color: #d9d9d9 !important;
border-color: #d9d9d9 !important;
border-radius: 50% !important;
width: 45rpx !important;
height: 45rpx !important;
line-height: 40rpx;
}
.text {
font-size: 12px;
color: #666;
margin-top: 5px;
}
.title {
font-size: 30rpx;
font-family: PingFang SC;
font-weight: 400;
color: #2b3133;
margin-bottom: 10rpx;
}
.content {
display: flex;
font-size: 30rpx;
font-family: PingFang SC;
font-weight: 400;
color: #2b3133;
.span {
color: #ff8124;
font-size: 28rpx;
font-family: PingFang SC;
font-weight: 400;
}
}
}
:deep(.checkbox__inner-icon) {
position: absolute !important;
top: 4px !important;
left: 7px !important;
color: #000 !important;
}
:deep(.uni-data-checklist .checklist-group .checklist-box) {
margin-right: 0;
}
}
.conter-button {
position: absolute;
left: 0;
bottom: 10rpx;
width: 100%;
display: flex;
justify-content: center;
.button {
height: 80rpx;
width: 500rpx;
text-align: center;
font-size: 32rpx;
font-family: PingFang SC;
font-weight: 500;
color: #ffffff;
line-height: 80rpx;
background: linear-gradient(270deg, #54e1b9, #00caa6);
border-radius: 40rpx;
}
}
.foot {
display: flex;
background-color: #ffffff;
padding: 20rpx 0;
position: absolute;
left: 0;
bottom: 0;
width: 100%;
.button {
margin: 0 auto;
height: 80rpx;
width: 300rpx;
text-align: center;
font-size: 32rpx;
font-family: PingFang SC;
font-weight: 500;
color: #ffffff;
line-height: 80rpx;
background: linear-gradient(270deg, #54e1b9, #00caa6);
border-radius: 40rpx;
}
.button1 {
margin: 0 auto;
height: 80rpx;
width: 300rpx;
text-align: center;
font-size: 32rpx;
font-family: PingFang SC;
font-weight: 500;
line-height: 80rpx;
background: #fff;
border-radius: 40rpx;
border: 1px solid #2ed981;
color: #2ed981;
}
}
</style>
<template>
<view class="box">
<view class="liner" v-for="item in props.scheduleList" :key="item.id">
<view class="timer">
<uni-icons custom-prefix="iconfont" type="icon-ai253" color="#1ec886" size="20"></uni-icons>
&nbsp; {{ item.dayStr }} 10:00-12:00
</view>
<view class="conetr">{{ item.event }}</view>
<view class="data">
<uni-icons custom-prefix="iconfont" type="icon-loufangfangzi"></uni-icons>
{{ item.place }}
</view>
</view>
<view class="nodata" v-if="props?.scheduleList?.length == 0">你还没有日程安排</view>
</view>
</template>
<script setup>
import { ref, getCurrentInstance, reactive, toRefs } from 'vue';
const props = defineProps({
scheduleList: {}
});
</script>
<style scoped lang="scss">
.nodata {
background: url(/static/nodata.png) no-repeat;
background-size: 100%;
width: 100%;
height: 835rpx;
color: #aaa59f;
font-size: 50rpx;
}
.box {
padding-top: 25rpx;
.liner {
margin-bottom: 20rpx;
background-color: #fff;
border-radius: 15rpx;
padding: 20rpx;
}
.timer {
display: flex;
font-size: 28rpx;
font-family: PingFang SC;
font-weight: 400;
color: #1ec886;
}
.conetr {
font-size: 30rpx;
font-family: PingFang SC;
font-weight: 400;
color: #2b3133;
margin: 25rpx 0;
}
.data {
font-size: 28rpx;
font-family: PingFang SC;
font-weight: 400;
color: #7b7f83;
}
}
</style>
<template>
<view class="big-box">
<view class="list-box">
<view class="image">
<image class="img" referrer="no-referrer|origin|unsafe-url" :src="porps.pic" mode="aspectFill"></image>
</view>
<view class="text">
<view class="text-title">{{ porps.title }}</view>
<view class="text-card color" v-if="porps.card == '报名中'">{{ porps.card }}</view>
<view class="text-card color1" v-if="porps.card == '进行中'">{{ porps.card }}</view>
<view class="text-card color2" v-if="porps.card == '即将开始'">{{ porps.card }}</view>
<view class="text-card color3" v-if="porps.card == '已结束'">{{ porps.card }}</view>
<view class="text-card color4" v-if="porps.card == '培训未开始'">{{ porps.card }}</view>
<view class="text-card color4" v-if="porps.card == '报名未开始'">{{ porps.card }}</view>
<view class="text-timer ">报名截止:{{ porps.timer }}</view>
</view>
</view>
<view class="hr"></view>
</view>
</template>
<script setup>
const porps = defineProps({
pic: {
type: String
},
title: {
type: String
},
card: {
type: String
},
timer: {
type: String
}
});
</script>
<style lang="scss">
.big-box {
width: 100%;
padding: 25rpx 0;
.hr {
width: 100%;
border-bottom: 1rpx solid #e5e5e5;
padding-top: 25rpx;
}
.list-box {
width: 100%;
height: 180rpx;
display: flex;
.image {
width: 270rpx;
height: 180rpx;
padding-right: 25rpx;
.img {
width: 270rpx;
height: 180rpx;
border-radius: 15rpx;
}
}
.text {
margin-left: 20rpx;
.text-title {
text-align: left;
font-size: 30rpx;
font-family: PingFang SC;
font-weight: 400;
color: #000000;
}
.text-card {
font-size: 20rpx;
width: 110rpx;
height: 32rpx;
margin-top: 57rpx;
text-align: center;
font-family: PingFang SC;
font-weight: 400;
color: #ffffff;
border-radius: 16px 16px 16px 0px;
}
.color {
background: linear-gradient(270deg, #54e1b9, #00caa6);
}
.color1 {
background: linear-gradient(270deg, #be8efb, #a76df4);
}
.color2 {
background: linear-gradient(270deg, #fea449, #ffb95f);
}
.color3 {
background: linear-gradient(270deg, #d9d9d9, #bcbcbc);
}
.color4 {
background: linear-gradient(270deg, #40d8ee, #53a7f6);
}
.text-timer {
margin-top: 20rpx;
height: 23rpx;
font-size: 24rpx;
font-family: PingFang SC;
font-weight: 400;
color: #7b7f83;
}
}
}
}
</style>
\ No newline at end of file
<template>
<view class="big-box">
<view class="list-box">
<view class="image">
<image
class="img"
referrer="no-referrer|origin|unsafe-url"
:src="porps.item.cover"
mode="aspectFill"
></image>
</view>
<view class="text">
<view class="text-title">{{ porps.item.trainName }}</view>
<view class="text-card color1" v-if="porps.item.statusStr == '审核通过'">
{{ porps.item.statusStr }}
</view>
<view class="text-card color2" v-if="porps.item.statusStr == '待审核'">
{{
porps.item.status == '0' && porps.item.payStatus == '0'
? porps.item.payStatusStr
: porps.item.statusStr
}}
</view>
<view class="text-card color3" v-if="porps.item.statusStr == '报名失败'">
{{ porps.item.statusStr }}
</view>
<view class="text-card color3" v-if="porps.item.statusStr == '审核拒绝'">
{{ porps.item.statusStr }}
</view>
<view class="text-card color4" v-if="porps.item.statusStr == '待支付'">{{ porps.item.statusStr }}</view>
<view class="text-card color4" v-if="porps.item.statusStr == '待提交'">{{ porps.item.statusStr }}</view>
<view class="text-card color5" v-if="porps.item.statusStr == '已取消'">{{ porps.item.statusStr }}</view>
</view>
</view>
<view class="hr"></view>
</view>
</template>
<script setup>
const porps = defineProps({
pic: {
type: String
},
title: {
type: String
},
card: {
type: String
},
timer: {
type: String
},
item: {}
});
</script>
<style lang="scss">
.big-box {
width: 100%;
padding: 25rpx 0;
.hr {
width: 100%;
border-bottom: 1rpx solid #e5e5e5;
padding-top: 25rpx;
}
.list-box {
width: 100%;
height: 180rpx;
display: flex;
.image {
width: 270rpx;
height: 180rpx;
padding-right: 25rpx;
.img {
width: 270rpx;
height: 180rpx;
border-radius: 15rpx;
}
}
.text {
margin-left: 20rpx;
.text-title {
text-align: left;
font-size: 30rpx;
font-family: PingFang SC;
font-weight: 400;
color: #000000;
}
.text-card {
font-size: 20rpx;
width: 94rpx;
height: 32rpx;
margin-top: 57rpx;
text-align: center;
font-family: PingFang SC;
font-weight: 400;
color: #ffffff;
border-radius: 16px 16px 16px 0px;
}
.color1 {
background: linear-gradient(270deg, #54e1b9, #00caa6);
}
.color2 {
background: linear-gradient(270deg, #be8efb, #a76df4);
}
.color3 {
background: linear-gradient(90deg, #f83841, #f76d74);
}
.color4 {
background: linear-gradient(90deg, #fea449, #ffb95f);
}
.color5 {
background: linear-gradient(270deg, #d9d9d9, #bcbcbc);
}
}
}
}
</style>
......@@ -181,6 +181,20 @@
}
}, {
"path": "pages/level/ztx/approval",
"style": {
"navigationBarTitleText": "级位考试审批",
"enablePullDownRefresh": false
}
}, {
"path": "pages/level/ztx/cert",
"style": {
"navigationBarTitleText": "级位证书发布",
"enablePullDownRefresh": false
}
}, {
"path": "pages/rank/approval",
"style": {
"navigationBarTitleText": "段位考试审批",
......@@ -422,7 +436,25 @@
"enablePullDownRefresh": false
}
}
],
,{
"path" : "pages/level/ztx/examList",
"style" :
{
"navigationBarTitleText": "级位考试详情",
"enablePullDownRefresh": false
}
}
,{
"path" : "pages/level/ztx/studentList",
"style" :
{
"navigationBarTitleText": "考生列表",
"enablePullDownRefresh": false
}
}
],
"globalStyle": {
"navigationStyle": "custom",
"navigationBarTextStyle": "white",
......
......@@ -3,7 +3,13 @@
<!-- 团队会员审核 -->
<uni-segmented-control class="whitebg" :current="current" :values="navs" @clickItem="onClickItem"
styleType="text" activeColor="#AD181F"></uni-segmented-control>
<view class="appList">
<view class="appList">
<view class="vipData" v-if="userType == '1'" v-show="totalCost>0">
<view>费用合计:
<text>¥{{ totalCost.toFixed(2) }}</text>
</view>
</view>
<view class="appItem" v-for="item in list">
<view class="status" @click="goDetail(item)">
<text v-if="item.auditStatus == 0" class="text-primary">审核中</text>
......@@ -36,24 +42,21 @@
<view>{{item.content.renewYear}}</view>
</view>
<view v-if="deptType == 1">
团体会员/新会员
<view>{{item.content.allCount}}/{{item.content.newCount}}</view>
会员合计/新会员
<view>{{item.content.allCount}}/<text class="text-danger">{{item.content.newCount}}</text></view>
</view>
<view v-if="deptType == 1">
费用合计
<view> {{ (item?.content?.allFee*1).toFixed(2) }}</view>
<view> ¥{{ (item?.content?.allFee*1).toFixed(2) }}</view>
</view>
</view>
<view class="func" v-if="(userType == '3'||userType == '2') && item.auditStatus == 0">
<button @click="audit(item.recordId,'0')">拒绝</button>
<button @click="audit(item.recordId,'1')">同意</button>
</view>
<view class="func" v-if="(deptType == 1&&item.ztxRes == 0)||((deptType == 2 || deptType == 3)&&item.shenRes == 0)">
<view class="func" v-if="(userType == '1'&&item.auditStatus == 0)">
<button @click="audit(item.recordId,'0')">拒绝</button>
<button @click="audit(item.recordId,'1')">同意</button>
</view>
<view class="func" v-if="(deptType == 6&&(item.status == 0 || item.status == 2))">
<button>提交审核</button>
</view>
</view>
</view>
......@@ -89,7 +92,8 @@
const list = ref([])
const total = ref(0)
const deptType = ref('')
const userType = ref('')
const userType = ref('')
const totalCost = ref(0)
onLoad(() => {
if (app.globalData.isLogin) {
init()
......@@ -125,13 +129,15 @@
queryParams.value.noEmpty = 1
}else if( deptType.value==4||deptType.value==5){
queryParams.value.noEmpty=1
}
}
totalCost.value = 0
api.getGroupList(queryParams.value).then(res => {
uni.hideLoading()
list.value = res.rows
list.value.forEach(item => {
item.content = JSON.parse(item.content)
// item.doc = JSON.parse(item.doc)
// item.doc = JSON.parse(item.doc)
totalCost.value = totalCost.value + (item.content.allFee * 1)
})
total.value = res.total
})
......@@ -194,7 +200,7 @@
if(userType.value=='1'){
// 查看
let path = `/pages/group/apply/applyDetail?rangeId=${item.id}&auditLog=${auditLog}&form=${form}`
let path = `/pages/group/apply/mergeUpDetail?form=${form}`
uni.navigateTo({
url: path
});
......
......@@ -40,16 +40,30 @@
</view>
<view class="flexbox">
<view>
单价
<text>¥{{n.unitPrice}}</text>
<view>
原有效期
<text>{{n.validityTime?.slice(0,10)}}</text>
</view>
<view>
提交日期
<text>{{n.commitTime?.slice(0,10)}}</text>
</view>
</view>
<view>
年限
<text>{{n.renewYear}}</text>
<view v-if="deptType==1">
会员证
<text v-if="form.content.sendJiaoFeiFlag==1" class="text-success">已下发</text>
<text v-else class="text-warning">未下发</text>
</view>
</view>
<view>
总价
<text>¥{{n.allFee}}</text>
单价
<text>¥{{n.unitPrice}}</text>
<view>总价
<text>¥{{n.allFee}}</text>
</view>
</view>
</view>
</view>
......@@ -80,15 +94,15 @@
</view>
</view>
<view class="fixedBottom" v-if="(deptType == 1)&&form.ztxRes == 0">
<!-- <view class="fixedBottom" v-if="(deptType == 1)&&form.auditStatus == 0">
<button class="btn-red-kx" @click="audit(form.id,'2')">拒绝</button>
<button class="btn-red" @click="audit(form.id,'1')">同意</button>
</view>
<view class="fixedBottom" v-if="(deptType == 2 || deptType == 3)&&form.shenRes == 0">
<view class="fixedBottom" v-if="(deptType == 2 || deptType == 3)&&form.auditStatus == 0">
<button class="btn-red-kx" @click="audit(form.id,'2')">拒绝</button>
<button class="btn-red" @click="audit(form.id,'1')">同意</button>
</view>
</view> -->
</view>
</template>
......
......@@ -15,7 +15,7 @@
<view class="item" v-for="n in list">
<view class="w100">
<view class="name">{{n.certName}}</view>
<view class="date" v-if="n.validityTime">{{n.validityTime?.silce(0,10)}}</view>
<view class="date" v-if="n.validityTime">{{n.validityTime?.slice(0,10)}}</view>
<view class="flexbox">
<view>单价
<text>¥{{ (n.unitPrice*1).toFixed(2) }}</text>
......
<template>
<view class="page">
<view class="bgbg">
<view class="bgbg">
<view class="loginOutIcon" @click="loginOut">
<image src="@/static/switch.png"></image>
</view>
<view class="welcome">您好!
{{memberInfo.name}}
<br />欢迎使用中跆协会员管理系统
......@@ -42,7 +45,7 @@
<view v-if="userType=='4'" @click="goPath('/pages/level/apply')">
<image />级位考试申请
</view>
<view v-if="userType!='4'" @click="goPath('/pages/level/approval')">
<view v-if="userType!='4'&&userType!='1'" @click="goPath('/pages/level/approval')">
<image />级位考试审核
</view>
<view v-if="userType=='2'" @click="goPath('/pages/level/apply')">
......@@ -51,7 +54,13 @@
</view>
<view v-if="userType=='1'" class="girdBox">
<view v-if="userType=='1'" class="girdBox">
<view @click="goPath('/pages/level/ztx/approval')">
<image />级位考试审核
</view>
<view @click="goPath('/pages/level/ztx/cert')">
<image />级位证书发布
</view>
<view @click="goPath('/pages/rank/approval')">
<image />段位考试审核
</view>
......@@ -132,7 +141,9 @@
proId = option.proId;
}
});
function loginOut(){
}
function goPath(path) {
uni.navigateTo({
url: path
......@@ -281,7 +292,10 @@
}
</script>
<style scope lang="scss">
<style scope lang="scss">
.loginOutIcon{
image{}
}
.welcome {
padding: 55rpx;
line-height: 55rpx;
......
......@@ -11,7 +11,7 @@
'text-success':item.auditStatus=='1',
'text-danger':item.auditStatus=='2',
'text-warning':item.auditStatus=='3'
}">{{ item.statusStr }}</text>
}">{{ item.statusStr }}</text>
</view>
<view class="date" v-if="item.status!='0'&&item.submitTime">提交时间:{{item.submitTime}}</view>
......@@ -42,6 +42,9 @@
<image mode="aspectFit" src="/static/nodata.png"></image>
<text>暂无数据</text>
</view>
<view v-if="userType=='2'" class="block-btn-box">
<button @click="goMerge" class="btn-red-kx">前往合并 > </button>
</view>
</view>
</template>
......
......@@ -39,8 +39,8 @@
</view>
<view class="nodata" v-if="infoList.length==0">
<image mode="aspectFit" src="/static/nodata.png"></image>
<text>暂无数据</text>
<image mode="aspectFit" src="/static/nodata.png"></image>
<button class="btn-red" @click="gohome">回到首页</button>
</view>
</view>
</template>
......@@ -160,6 +160,12 @@
url: path
});
}
function gohome(){
let path = `/pages/index/index`
uni.reLaunch({
url: path
});
}
</script>
......
<template>
<view>
<uni-segmented-control class="whitebg" :current="current" :values="navs" @clickItem="onClickItem"
styleType="text" activeColor="#AD181F"></uni-segmented-control>
<view v-show="totalCost>0" class="vipData">
<view>费用合计:
<text>{{ totalCost.toFixed(2) }}</text>
</view>
</view>
<view class="appList">
<view class="appItem" v-for="item in infoList">
<view class="status" :class="{
'text-primary':item.status=='0',
'text-success':item.status=='1',
'text-danger':item.status=='2',
'text-warning':item.status=='3'
}" @click="goDetail(item)">
{{ item.statusStr }}
</view>
<view class="date" v-if="item.status!='0'&&item.submitTime">提交时间:{{item.submitTime}}</view>
<view class="name mt0" @click="goDetail(item)">{{item.mergeName}}</view>
<view class="pp esp">上报单位:{{item.memName}}</view>
<view class="flexbox" @click="goDetail(item)">
<view>
考试人数
<view>{{item.totalNum}}</view>
</view>
<view>
缴费状态
<view>
<text :class="{
'text-success':item.examPayStatusStr=='已上传凭证',
'text-danger':item.examPayStatusStr=='未上传凭证',
'text-warning':item.examPayStatusStr=='已结算'
}">{{ item.examPayStatusStr||'--' }}</text>
</view>
</view>
<view>
总金额
<view>¥{{item.totalAmount}}</view>
</view>
</view>
<view class="func" v-if="item.status=='0'">
<button @click="audit(item,'2')">拒绝</button>
<button @click="audit(item,'1')">同意</button>
</view>
</view>
</view>
<view class="nodata" v-if="infoList.length==0">
<image mode="aspectFit" src="/static/nodata.png"></image>
<text>暂无数据</text>
</view>
</view>
</template>
<script setup>
import * as api from '@/common/api.js'
import config from '@/config.js'
import _ from 'lodash'
import {
onMounted,
ref
} from 'vue'
import {
onLoad,
onShow
} from '@dcloudio/uni-app'
const app = getApp();
const queryParams = ref({
// pageNum: 1,
// pageSize: 10
status: '0',
type: '1'
})
const navs = ref(['审核中', '审核通过', '审核拒绝', '审批撤回'])
const statusArr = ['审批中', '审批通过', '审批拒绝', '审批撤回']
const current = ref()
const infoList = ref([])
const total = ref(0)
const totalCost = ref(0)
const deptType = ref('')
const userType = ref('')
onLoad(() => {
})
onShow(() => {
if (app.globalData.isLogin) {
init()
} else {
app.firstLoadCallback = () => {
init()
};
}
})
function init() {
deptType.value = app.globalData.deptType
userType.value = app.globalData.userType
getList()
}
function getList() {
uni.showLoading({
title: '加载中'
})
totalCost.value = 0
api.getVerityMergeList(queryParams.value).then(response => {
uni.hideLoading()
const list = []
_.each(response.rows, r => {
const item = JSON.parse(r.remark)
item.recordId = r.recordId
item.status = r.auditStatus
item.statusStr = statusArr[r.auditStatus]
item.isView = r.isView
item.payStatus = r.payStatus
item.examPayStatusStr = r.examPayStatusStr
item.sourceData = r
item.auditProcess = r.auditProcess
list.push(item)
totalCost.value += (item.totalAmount * 1)
})
infoList.value = list
total.value = response.total
})
}
function onClickItem(e) {
console.log(e)
uni.showLoading({
title: '加载中'
})
queryParams.value.status = e.currentIndex
getList()
}
function goDetail(item) {
const form = encodeURIComponent(JSON.stringify(item))
// 查看
let path = `/pages/level/mergeUpDetail?form=${form}&type=1`
uni.navigateTo({
url: path
});
}
function audit(item, flag) {
var obj = {
flag: flag,
reason: null,
id: item.recordId
}
if (flag == '2') {
// 拒绝
// 弹出框填写理由
uni.showModal({
title: '请输入拒绝理由',
editable: true,
success: function(res) {
if (res.confirm) {
if (!res.content) {
uni.showToast({
title: '请输入拒绝理由',
icon: 'none'
})
} else {
obj.reason = res.content
doApproval(obj)
}
}
}
})
} else if (flag == '1') {
// 二次确认
uni.showModal({
title: '提示',
content: `确定审批通过吗`,
success: function(res) {
if (res.confirm) {
doApproval(obj)
}
}
})
}
}
function doApproval(obj) {
console.log(obj)
api.doMergeFlows(obj).then((res) => {
uni.showToast({
title: '操作成功',
icon: 'none'
})
getList()
})
}
</script>
<style scoped lang="scss">
.mt0 {
margin-top: 0 !important;
}
.appList .appItem .name {
width: 80%;
word-break: break-all;
}
</style>
\ No newline at end of file
<template>
<view>
<!-- 级位证书发布 -->
<view class="appList">
<view class="appItem" v-for="item in infoList">
<view class="status" @click="goDetail(item)">
<text :class="{
'text-warning':item.certStatus=='0',
'text-success':item.certStatus=='1'
}">{{ item.certStatusStr }}</text>
</view>
<view class="date">提交日期:{{item.submitTimeStr}}</view>
<view class="name mt0" @click="goDetail(item)">{{item.name}}</view>
<view class="pp esp" v-if="item.certTime">证书发送时间:{{item.certTimeStr}}</view>
<view class="flexbox" @click="goDetail(item)">
<view>
申请单位
<view>{{item.memberName}}</view>
</view>
<view>
已发证书
<view>{{item.hasCerts}}</view>
</view>
<view>
待发证书
<view>{{item.noCerts}}</view>
</view>
</view>
<view class="func" v-if="item.certStatus != '2'">
<button @click="send(item)">一键生成</button>
</view>
</view>
</view>
<view class="nodata" v-if="infoList.length==0">
<image mode="aspectFit" src="/static/nodata.png"></image>
<text>暂无数据</text>
</view>
</view>
</template>
<script setup>
import * as api from '@/common/api.js'
import config from '@/config.js'
import _ from 'lodash'
import {
onMounted,
ref
} from 'vue'
import {
onLoad,
onShow
} from '@dcloudio/uni-app'
const app = getApp();
const queryParams = ref({
// pageNum: 1,
// pageSize: 10
status: '0',
type: '1'
})
const statusArr = ['审批中', '审批通过', '审批拒绝', '审批撤回']
const current = ref()
const infoList = ref([])
const total = ref(0)
const deptType = ref('')
const userType = ref('')
onLoad((option) => {
})
onShow(() => {
if (app.globalData.isLogin) {
init()
} else {
app.firstLoadCallback = () => {
init()
};
}
})
function init() {
deptType.value = app.globalData.deptType
userType.value = app.globalData.userType
getList()
}
function getList() {
uni.showLoading({
title: '加载中'
})
api.getCertsLList(queryParams.value).then(res => {
infoList.value = res.rows
uni.hideLoading()
})
}
function goDetail(item) {
// const form = encodeURIComponent(JSON.stringify(item))
let path = `/pages/level/ztx/examList?type=1&payId=${item.payId}`
uni.navigateTo({
url: path
});
}
function send(row) {
uni.showModal({
title: '提示',
content: `确定生成 ${row.name} 的证书吗`,
success: function(res) {
if (res.confirm) {
api.submitCert([{
id: row.payId
}]).then(res => {
uni.showToast({
title: `下发成功`
})
getList()
})
}
}
})
}
</script>
<style scoped lang="scss">
.mt0 {
margin-top: 0 !important;
}
.appList .appItem .name {
width: 80%;
word-break: break-all;
}
</style>
\ No newline at end of file
<template>
<view>
<!-- 级位证书发布 -->
<view class="appList">
<view class="appItem" v-for="item in infoList">
<view class="status" @click="goDetail(item)">
<text :class="{
'text-warning':item.isCert=='0',
'text-primary':item.isCert=='1',
'text-success':item.isCert=='2'
}">{{ statusArr[item.isCert]}}</text>
</view>
<view class="date">申请日期: {{item.applyTime?.slice(0,10)}}</view>
<view class="name mt0" @click="goDetail(item)">{{item.name}}</view>
<view class="pp esp">考级考官:{{item.examinerNames}}</view>
<view class="flexbox" @click="goDetail(item)">
<view>
申请单位
<view>{{item.memberName}}</view>
</view>
<view>
已发/待发证书
<view>{{item.hasCerts}}/<text class="text-danger">{{item.noCerts}}</text></view>
</view>
<view>
考生数/通过数
<view>{{item.totalNum}}/<text class="text-danger">{{item.pass}}</text></view>
</view>
</view>
<view class="func" v-if="item.certStatus != '2'">
<button @click="send(item)">一键生成</button>
</view>
</view>
</view>
<view class="nodata" v-if="infoList.length==0">
<image mode="aspectFit" src="/static/nodata.png"></image>
<text>暂无数据</text>
</view>
</view>
</template>
<script setup>
import * as api from '@/common/api.js'
import config from '@/config.js'
import _ from 'lodash'
import {
onMounted,
ref
} from 'vue'
import {
onLoad,
onShow
} from '@dcloudio/uni-app'
const app = getApp();
const queryParams = ref({
// pageNum: 1,
// pageSize: 10
})
const statusArr = ['未发放', '部分发放', '已发放']
const current = ref()
const infoList = ref([])
const total = ref(0)
const deptType = ref('')
const userType = ref('')
onLoad((option) => {
queryParams.value.payId = option.payId
queryParams.value.type = option.type
})
onShow(() => {
if (app.globalData.isLogin) {
init()
} else {
app.firstLoadCallback = () => {
init()
};
}
})
function init() {
deptType.value = app.globalData.deptType
userType.value = app.globalData.userType
getList()
}
function getList() {
uni.showLoading({
title: '加载中'
})
api.getExamListByPayId(queryParams.value).then(res => {
infoList.value = res.rows
uni.hideLoading()
})
}
function goDetail(item) {
// const form = encodeURIComponent(JSON.stringify(item))
let path = `/pages/level/ztx/studentList?type=${queryParams.value.type}&examId=${item.examId}&payId=${queryParams.value.payId}`
uni.navigateTo({
url: path
});
}
function send(row) {
uni.showModal({
title: '提示',
content: `确定生成 ${row.name} 的证书吗`,
success: function(res) {
if (res.confirm) {
api.submitCert([{
id: row.payId
}]).then(res => {
uni.showToast({
title: `下发成功`
})
getList()
})
}
}
})
}
</script>
<style scoped lang="scss">
.mt0 {
margin-top: 0 !important;
}
.appList .appItem .name {
width: 80%;
word-break: break-all;
}
</style>
\ No newline at end of file
<template>
<view class="hasfixedbottom">
<view class="searchbar">
<uni-easyinput placeholderStyle="font-size:30rpx" :input-border="false" prefixIcon="search"
v-model="queryParams.name" placeholder="搜索姓名" @blur="getList()" @clear="getList()">
</uni-easyinput>
</view>
<view class="indexboxre">
<view class="userlist">
<view class="item" v-for="n in list">
<view class="w100">
<view class="status">
<text class="text-success" v-if="n.isCert == '1' ">已发送</text>
<text class="text-warning" v-else>未发送</text>
</view>
<view class="name">{{n.realName}}</view>
<view class="flexbox mtb30">
<view>所属团体
<text>{{n.memName}}</text>
</view>
<view>会员有效期
<text>{{n.vaildityDate?.slice(0,10)}}</text>
</view>
<view>级位
<text>
{{ szToHz(n.levelNew) }}
</text>
</view>
</view>
<div class="func">
<button @click="sendCert(n)">{{ ['发送证书','更新证书'][n.isCert] }}</button>
</div>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
import * as api from '@/common/api.js'
import config from '@/config.js'
import {
ref,
getCurrentInstance
} from 'vue'
import {
onLoad
} from '@dcloudio/uni-app'
const {
proxy
} = getCurrentInstance()
const app = getApp();
const queryParams = ref({})
const list = ref([])
const total = ref(0)
const userType = ref('')
onLoad((option) => {
queryParams.value.examId = option.examId
queryParams.value.payId = option.payId
queryParams.value.type = option.type
getList()
})
function getList() {
uni.showLoading({
title: '加载中'
})
api.certStudentList(queryParams.value).then(res => {
list.value = res.rows
uni.hideLoading()
})
}
function szToHz(num) {
const hzArr = ['〇', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十']
return hzArr[parseInt(num)]
}
function sendCert(row) {
uni.showModal({
title: '提示',
content: `确定下发 ${row.realName} 的证书吗`,
success: function(res) {
if (res.confirm) {
const params = [{
id: queryParams.value.payId,
children: [{
id: queryParams.value.examId,
children: [row.id]
}]
}]
api.submitCert(params).then(res => {
uni.showToast({
title: `下发成功`
})
getList()
})
}
}
})
}
function handleImport() {
var arr = []
for (var n of list.value) {
if (n.checked) {
arr.push(n.perId)
}
}
if (arr.length == 0) {
uni.showToast({
title: "请选择会员",
icon: "none"
})
return
}
api.addPersonPaymentGroup({
rangeId: queryParams.value.paymentRangeId,
personIdArray: arr.join(',')
}).then(res => {
let path = `/pages/personalVip/renew?rangeId=${res.data.rangeId}`
uni.redirectTo({
url: path
});
})
}
</script>
<style scoped lang="scss">
.indexboxre {
padding: 0 30rpx;
.tt {
font-size: 30rpx;
margin: 0 0 30rpx;
color: #4C5359;
}
position: relative;
height: calc(100vh - 280rpx);
overflow: auto;
}
.searchbar {
display: flex;
align-items: center;
padding: 25rpx;
box-sizing: border-box;
:deep(.uni-easyinput .uni-easyinput__content) {
border-radius: 35rpx;
border: none;
height: 70rpx;
}
:deep(.uni-easyinput__content-input) {
font-size: 26rpx;
}
}
</style>
\ No newline at end of file
......@@ -2,7 +2,7 @@
<view class="hasfixedbottom">
<view class="searchbar">
<uni-easyinput placeholderStyle="font-size:30rpx" :input-border="false" prefixIcon="search"
v-model="queryParams.name" placeholder="搜索姓名或证件号码" @blur="getList()" @clear="getList()">
v-model="queryParams.name" placeholder="搜索姓名" @blur="getList()" @clear="getList()">
</uni-easyinput>
</view>
<view class="indexboxre">
......
@font-face {font-family: "iconfont";
src: url('iconfont.eot?t=1587304858380'); /* IE9 */
src: url('iconfont.eot?t=1587304858380#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAKYAAsAAAAABkQAAAJOAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCCcApQZAE2AiQDCAsGAAQgBYRtBzAbigXIrrApw69IkQJyuEPQxl76g4HoIYL6/dje+w8TiUTRZBoiHqpVEmRaIRRCYrpn8t//uczdiITNQB7LUyNSaIv5v7/lNAN0rMlIMv6eHwo3dzBnwGQPk3M8ZxtLDRi4CKu4hFtT9xqbz3M5vQl0IPMDneNqDtrDFk3qBXQvDqQA98IosjJJvGHsApfwmECtQTWVzdXtPRiWWasCcWu0A8O5tCyzWrVQWXMwixcVqtNTegeew+/Hn04Mk1QUrJaD8xUf5j/ZxeKxhE/IENDxChSYBzJxUlve0ycY16e23G8U7Ksx+FSWfkjs1S/YX2fV14N+qN6T5uq3WktwWxN1AL2jriQ6LvSLqs8PXI9IP2WWb82rj+Ho6f7KTwh8/vG/+MEqQLlFX3EFFQR3W5dz1tTif3VdBh/nNUyWm/WLguq9RIK/ofUcyLphBVNWtVpz0nGWtlq1KAnHW/2N9XSc2hyqR0SrDKQoVBsnMzuPCnUWUKnaCmrNWTtepw3rE7kGs64BQrNXJI3eUGjWIzP7iwqd/lGpOfpQ6yzaLqwzGWZ0g8kR8tE9ReNlqXLCMho17pA+jB3OGiF/QFyaHLYbrWJtjVLiObaUR7ojolBxluAqeI7iOMOcs5A8aQQiebfZVHVvanhZAqM2MOIQxIdcp5DhyaSUP1qMlj6/g2iHYg5u6aspDxBWMtOjtoZWD3LNkfbqu5dXSke0DiEUpLBMAq2CeSQWy6C8fl6IeERDMKKY62raw1RfR2N9V/J1x6CW5U1hzypUnjtpcGgAAA==') format('woff2'),
url('iconfont.woff?t=1587304858380') format('woff'),
url('iconfont.ttf?t=1587304858380') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url('iconfont.svg?t=1587304858380#iconfont') format('svg'); /* iOS 4.1- */
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-fanhui:before {
content: "\e65c";
}
No preview for this file type
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<!--
2013-9-30: Created.
-->
<svg>
<metadata>
Created by iconfont
</metadata>
<defs>
<font id="iconfont" horiz-adv-x="1024" >
<font-face
font-family="iconfont"
font-weight="500"
font-stretch="normal"
units-per-em="1024"
ascent="896"
descent="-128"
/>
<missing-glyph />
<glyph glyph-name="fanhui" unicode="&#58972;" d="M349.184 382.976l435.2 432.64c13.824 13.824 13.824 39.424 0 53.76l-13.824 13.824c-13.824 13.824-39.424 13.824-53.76 0L239.616 410.624c-13.824-13.824-13.824-39.424 0-53.76l474.624-472.576c13.824-13.824 39.424-13.824 53.76 0l13.824 13.824c13.824 13.824 13.824 39.424 0 53.76l-432.64 431.104z" horiz-adv-x="1024" />
</font>
</defs></svg>
No preview for this file type
No preview for this file type
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!