榆钱落尽槿花稀 448712ece5 feat: 添加积分申请系统基础功能与UI组件
本次提交主要包含以下内容:

1. 新增积分申请系统核心功能:
   - 添加登录页面及API接口
   - 实现积分申请记录查看功能
   - 集成微信小程序分享功能
   - 添加请求管理工具类

2. 引入Tuniao UI组件库:
   - 添加时间线、折叠面板、表格等UI组件
   - 集成头像组、单选框组等交互组件
   - 配置全局样式和主题颜色

3. 基础架构搭建:
   - 配置项目manifest和pages.json路由
   - 添加状态管理store
   - 实现自定义导航栏适配
   - 添加工具函数(加解密、数字处理等)

4. 静态资源:
   - 添加项目logo和背景图片
   - 配置uni.scss全局样式变量

本次提交为系统基础功能搭建,后续将进一步完善积分申请流程和审批功能。
2025-05-27 16:40:02 +08:00

266 lines
7.2 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="tn-radio-class tn-radio" :style="[radioStyle]">
<view
class="tn-radio__icon-wrap"
:class="[iconClass]"
:style=[iconStyle]
@tap="toggle"
>
<view class="tn-icon-success tn-radio__icon-wrap__icon"></view>
</view>
<view
class="tn-radio__label"
:style="{
fontSize: labelSize ? labelSize + 'rpx' : ''
}"
@tap="onClickLabel"
>
<slot></slot>
</view>
</view>
</template>
<script>
export default {
name: 'tn-radio',
props: {
// radio名称
name: {
type: [String, Number],
default: ''
},
// 是否禁用
disabled: {
type: Boolean,
default: false
},
// 禁用点击标签进行选择
disabledLabel: {
type: Boolean,
default: false
},
// 选择框的形状 square 方形 circle 圆形
shape: {
type: String,
default: ''
},
// 选中时的颜色
activeColor: {
type: String,
default: ''
},
// 组件尺寸
size: {
type: Number,
default: 0
},
// 图标大小
iconSize: {
type: Number,
default: 0
},
// label字体大小
labelSize: {
type: Number,
default: 0
}
},
computed: {
// 禁用,父组件会覆盖子组件的状态
isDisabled() {
return this.disabled ? this.disabled : (this.parentData.disabled ? this.parentData.disabled : false)
},
// 禁用label点击父组件会覆盖子组件的状态
isDisabledLabel() {
return this.disabledLabel ? this.disabledLabel : (this.parentData.disabledLabel ? this.parentData.disabledLabel : false)
},
// 组件尺寸
elSize() {
return this.size ? this.size : (this.parentData.size ? this.parentData.size : 34)
},
// 组件选中时的颜色
elActiveColor() {
return this.activeColor ? this.activeColor : (this.parentData.activeColor ? this.parentData.activeColor : '#01BEFF')
},
// 组件形状
elShape() {
return this.shape ? this.shape : (this.parentData.shape ? this.parentData.shape : 'circle')
},
iconClass() {
let clazz = ''
clazz += (' tn-radio__icon-wrap--' + this.elShape)
if (this.parentData.value === this.name) clazz += ' tn-radio__icon-wrap--checked'
if (this.isDisabled) clazz += ' tn-radio__icon-wrap--disabled'
if (this.parentData.value === this.name && this.isDisabled) clazz += ' tn-radio__icon-wrap--disabled--checked'
return clazz
},
iconStyle() {
// 当前radio的name等于parent的value才认为时选中
let style = {}
if (this.elActiveColor && this.parentData.value === this.name && !this.isDisabled) {
style.borderColor = this.elActiveColor
style.backgroundColor = this.elActiveColor
}
style.color = this.parentData.value === this.name ? '#FFFFFF' : 'transparent'
style.width = this.elSize + 'rpx'
style.height = style.width
style.fontSize = (this.iconSize ? this.iconSize : (this.parentData.iconSize ? this.parentData.iconSize : 20)) + 'rpx'
return style
},
radioStyle() {
let style = {}
if (this.parent && this.parentData.width) {
// #ifdef MP
// 各家小程序因为它们特殊的编译结构使用float布局
style.float = 'left';
// #endif
// #ifndef MP
// H5和APP使用flex布局
style.flex = `0 0 ${this.parentData.width}`;
// #endif
}
if(this.parent && this.parentData.wrap) {
style.width = '100%';
// #ifndef MP
// H5和APP使用flex布局将宽度设置100%,即可自动换行
style.flex = '0 0 100%';
// #endif
}
return style
}
},
data() {
return {
// 父组件的默认值因为头条小程序不支持在computed中使用this.parent.xxx的形式
// 故只能使用如此方法
parentData: {
value: null,
disabled: null,
disabledLabel: null,
shape: null,
activeColor: null,
size: null,
width: null,
wrap: null,
iconSize: null,
}
}
},
created() {
// 支付宝小程序不支持provide/inject所以使用这个方法获取整个父组件在created定义避免循环引用
this.updateParentData()
this.parent.children.push(this)
},
methods: {
updateParentData() {
this.getParentData('tn-radio-group')
},
onClickLabel() {
if (!this.isDisabledLabel && !this.isDisabled) {
this.setRadioCheckedStatus()
}
},
toggle() {
if (!this.isDisabled) {
this.setRadioCheckedStatus()
}
},
emitEvent() {
// tn-radio的name不等于父组件的v-model的值时(意味着未选中),才发出事件,避免多次点击触发事件
if (this.parentData.value !== this.name) this.$emit('change', this.name)
},
// 改变选中的状态
// 更改本组件的parentData.value的值为本组件的name值同时通过父组件遍历所有的radio实例
// 将本组件外的其他radio的parentData.value都设置为空
setRadioCheckedStatus() {
this.emitEvent()
if (this.parent) {
this.parent.setValue(this.name)
this.parentData.value = this.name
}
}
}
}
</script>
<style lang="scss" scoped>
.tn-radio {
/* #ifndef APP-NVUE */
display: inline-flex;
/* #endif */
align-items: center;
overflow: hidden;
user-select: none;
line-height: 1.8;
&__icon-wrap {
color: $tn-font-color;
display: flex;
flex-direction: row;
flex: none;
align-items: center;
justify-content: center;
box-sizing: border-box;
width: 42rpx;
height: 42rpx;
color: transparent;
text-align: center;
transition-property: color, border-color, background-color;
font-size: 20rpx;
border: 1rpx solid $tn-font-sub-color;
transition-duration: 0.2s;
/* #ifdef MP-TOUTIAO */
// 头条小程序兼容性问题需要设置行高为0否则图标偏下
&__icon {
line-height: 0;
}
/* #endif */
&--circle {
border-radius: 100%;
}
&--square {
border-radius: 6rpx;
}
&--checked {
color: #FFFFFF;
background-color: $tn-main-color;
border-color: $tn-main-color;
}
&--disabled {
background-color: $tn-font-holder-color;
border-color: $tn-font-sub-color;
}
&--disabled--checked {
color: $tn-font-sub-color !important;
}
}
&__label {
word-wrap: break-word;
margin-left: 10rpx;
margin-right: 24rpx;
color: $tn-font-color;
font-size: 30rpx;
&--disabled {
color: $tn-font-sub-color;
}
}
}
</style>