Browse Source

优化样式 新增订单信息页面

Lj 1 week ago
parent
commit
d8aeb592a0
464 changed files with 30249 additions and 298 deletions
  1. +39
    -5
      111/App.uvue
  2. +58
    -0
      111/css/header.css
  3. +1
    -1
      111/manifest.json
  4. +16
    -6
      111/pages.json
  5. +46
    -83
      111/pages/home/home.uvue
  6. +406
    -0
      111/pages/index/PayPal.uvue
  7. +27
    -0
      111/pages/index/dingdan.uvue
  8. +0
    -88
      111/pages/index/index_1.uvue
  9. +57
    -31
      111/pages/index/login.uvue
  10. +1
    -0
      111/pages/index/wode.uvue
  11. +46
    -57
      111/pages/views/dingDanCreate.uvue
  12. +0
    -22
      111/pages/views/payment.uvue
  13. BIN
      111/static/gonggao.png
  14. BIN
      111/static/image/11.png
  15. BIN
      111/static/image/weixuanzhong.png
  16. BIN
      111/static/image/xuanzhong.png
  17. BIN
      111/static/image/图像 4@2x.png
  18. BIN
      111/static/image/图像 4@3x.png
  19. BIN
      111/static/image/图层_6@2x.png
  20. BIN
      111/static/image/图层_6@3x.png
  21. BIN
      111/static/image/矩形 5315@2x.png
  22. BIN
      111/static/image/矩形 5315@3x.png
  23. BIN
      111/static/image/组 70865@2x.png
  24. BIN
      111/static/image/组 70865@3x.png
  25. BIN
      111/static/image/组 71663@2x.png
  26. BIN
      111/static/image/组 71663@3x.png
  27. BIN
      111/static/image/组 71693@2x.png
  28. BIN
      111/static/image/组 71693@3x.png
  29. BIN
      111/static/image/组 71696@2x.png
  30. BIN
      111/static/image/组 71696@3x.png
  31. BIN
      111/static/image/组 71697@2x.png
  32. BIN
      111/static/image/组 71697@3x.png
  33. BIN
      111/static/image/组 71699@2x.png
  34. BIN
      111/static/image/组 71699@3x.png
  35. BIN
      111/static/image/组 71699_1.png
  36. BIN
      111/static/image/组 71699_1@2x.png
  37. BIN
      111/static/image/组件 2 – 1@2x.png
  38. BIN
      111/static/image/组件 2 – 1@3x.png
  39. BIN
      111/static/image/组件 3 – 1@2x.png
  40. BIN
      111/static/image/组件 3 – 1@3x.png
  41. BIN
      111/static/image/组件 4 – 1@2x.png
  42. BIN
      111/static/image/组件 4 – 1@3x.png
  43. BIN
      111/static/image/组件 5 – 1@2x.png
  44. BIN
      111/static/image/组件 5 – 1@3x.png
  45. BIN
      111/static/image/联合 2.png
  46. BIN
      111/static/image/联合 2_1.png
  47. BIN
      111/static/image/路径 24@2x.png
  48. BIN
      111/static/image/路径 24@3x.png
  49. BIN
      111/static/image/路径 25@2x.png
  50. BIN
      111/static/image/路径 25@3x.png
  51. BIN
      111/static/image/路径 3909@2x.png
  52. BIN
      111/static/image/路径 3909@3x.png
  53. BIN
      111/static/image/路径 3909_1.png
  54. BIN
      111/static/image/路径 3909_1@2x.png
  55. BIN
      111/static/image/路径 3909_1@3x.png
  56. BIN
      111/static/image/路径 3917@2x.png
  57. BIN
      111/static/image/路径 3917@3x.png
  58. BIN
      111/static/image/路径 3917_1.png
  59. BIN
      111/static/image/路径 3917_1@2x.png
  60. BIN
      111/static/image/路径 3917_1@3x.png
  61. BIN
      111/static/image/路径 4016@2x.png
  62. BIN
      111/static/image/路径 4016@3x.png
  63. BIN
      111/static/image/路径 4016_1@2x.png
  64. BIN
      111/static/image/路径 4016_1@3x.png
  65. BIN
      111/static/image/路径 4150@2x.png
  66. BIN
      111/static/image/路径 4150@3x.png
  67. BIN
      111/static/image/路径 6111@2x.png
  68. BIN
      111/static/image/路径 6111@3x.png
  69. BIN
      111/static/image/路径 6112@2x.png
  70. BIN
      111/static/image/路径 6112@3x.png
  71. BIN
      111/static/logo.png
  72. +14
    -0
      111/uni_modules/lime-radio/changelog.md
  73. +48
    -0
      111/uni_modules/lime-radio/components/l-radio-group/l-radio-group.uvue
  74. +70
    -0
      111/uni_modules/lime-radio/components/l-radio-group/l-radio-group.vue
  75. +69
    -0
      111/uni_modules/lime-radio/components/l-radio-group/props.ts
  76. +41
    -0
      111/uni_modules/lime-radio/components/l-radio-group/type.ts
  77. +173
    -0
      111/uni_modules/lime-radio/components/l-radio/index-u.scss
  78. +216
    -0
      111/uni_modules/lime-radio/components/l-radio/l-radio.uvue
  79. +128
    -0
      111/uni_modules/lime-radio/components/l-radio/l-radio.vue
  80. +70
    -0
      111/uni_modules/lime-radio/components/l-radio/props.ts
  81. +49
    -0
      111/uni_modules/lime-radio/components/l-radio/type.ts
  82. +181
    -0
      111/uni_modules/lime-radio/components/lime-radio/lime-radio.uvue
  83. +189
    -0
      111/uni_modules/lime-radio/components/lime-radio/lime-radio.vue
  84. +89
    -0
      111/uni_modules/lime-radio/package.json
  85. +199
    -0
      111/uni_modules/lime-radio/readme.md
  86. +42
    -0
      111/uni_modules/lime-shared/addUnit/index.ts
  87. +82
    -0
      111/uni_modules/lime-shared/animation/bezier.ts
  88. +3
    -0
      111/uni_modules/lime-shared/animation/ease.ts
  89. +10
    -0
      111/uni_modules/lime-shared/animation/index.ts
  90. +103
    -0
      111/uni_modules/lime-shared/animation/useTransition.ts
  91. +119
    -0
      111/uni_modules/lime-shared/animation/uvue.uts
  92. +123
    -0
      111/uni_modules/lime-shared/animation/vue.ts
  93. +3888
    -0
      111/uni_modules/lime-shared/areaData/city-china.json
  94. +71
    -0
      111/uni_modules/lime-shared/areaData/index.ts
  95. +8
    -0
      111/uni_modules/lime-shared/arrayBufferToFile/index.ts
  96. +10
    -0
      111/uni_modules/lime-shared/arrayBufferToFile/uvue.uts
  97. +63
    -0
      111/uni_modules/lime-shared/arrayBufferToFile/vue.ts
  98. +13
    -0
      111/uni_modules/lime-shared/base64ToArrayBuffer/index.ts
  99. +9
    -0
      111/uni_modules/lime-shared/base64ToPath/index.ts
  100. +22
    -0
      111/uni_modules/lime-shared/base64ToPath/uvue.uts

+ 39
- 5
111/App.uvue View File

@ -36,14 +36,48 @@
<style>
@import "@/static/iconfont.css";
@import "css/header.css";
/*每个页面公共css */
.uni-row {
flex-direction: row;
}
body{
background-color: #ffffff;
}
.uni-column {
flex-direction: column;
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
}
@media only screen and (-webkit-min-device-pixel-ratio:2),(min-device-pixel-ratio:2){
.uni-hairline{
border-width: 0.5px !important;
}
.uni-nbfc {
background-color: transparent !important;
}
}
@media screen and (min-width: 320px) {
html {font-size: 14px;}
}
@media screen and (min-width: 360px) {
html {font-size: 16px;}
}
@media screen and (min-width: 400px) {
html {font-size: 18px;}
}
@media screen and (min-width: 440px) {
html {font-size: 20px;}
}
@media screen and (min-width: 480px) {
html {font-size: 22px;}
}
@media screen and (min-width: 640px) {
html {font-size: 28px;}
}
</style>

+ 58
- 0
111/css/header.css View File

@ -0,0 +1,58 @@
.container {
display: flex;
flex-direction: column;
height: 100vh;
width: 100%;
background-color: #f5f5f5;
/* position: relative; */
}
/* 头部 */
.header {
height: 15%;
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
padding: 1rem;
background-color: #044f7a;
}
.header_info{
width: 100%;
height: 100%;
display: flex;
flex-direction: row;
align-items: center;
}
.header_info_icons{
display: flex;
align-items: center;
margin: 0 0.5rem 0 0.5rem;
}
.header_info_icon{
display: flex;
height: 100%;
width: 10%;
width: 5%;
align-items: center;
justify-content: center;
}
.header_text{
color: #bdd1dc;
font-size: 1rem;
left : 25%;
}
.header_texts{
color: #bdd1dc;
font-size: 1rem;
}
.header_change{
display: flex;
flex-direction: row;
align-items: center;
font-size: 1rem;
color: #bdd1dc;
}

+ 1
- 1
111/manifest.json View File

@ -9,7 +9,7 @@
"quickapp" : {},
/* */
"mp-weixin" : {
"appid" : "wx7d74b5db6c1f7328",
"appid" : "wx5b4b75c83b7485b1",
"setting" : {
"urlCheck" : false
},


+ 16
- 6
111/pages.json View File

@ -1,9 +1,10 @@
{
"pages": [ //pageshttps://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/login",
"style": {
"navigationBarTitleText": "",
"navigationBarTitleText": "登录",
"navigationStyle":"custom"
}
},
@ -32,9 +33,18 @@
"needLogin": true
},
{
"path": "pages/views/payment",
"path": "pages/index/dingdan",
"style": {
"navigationBarTitleText": "付款信息",
"navigationBarTitleText": "订单",
"navigationStyle":"custom"
},
"needLogin": true
},
{
"path" : "pages/index/PayPal",
"style" :
{
"navigationBarTitleText" : "",
"navigationStyle":"custom"
},
"needLogin": true
@ -54,11 +64,11 @@
"backgroundColor": "#ffffff",
"list": [{
"pagePath": "pages/home/home",
"iconPath": "/",
"iconPath": "/static/image/11.png",
"selectedIconPath": "/static/image/路径 3909.png",
"text": "首页"
}, {
"pagePath": "",
"pagePath": "pages/index/dingdan",
"iconPath": "/static/image/路径 4016_1.png",
"selectedIconPath": "/static/image/路径 4016.png",
"text": "订单"
@ -66,7 +76,7 @@
{
"pagePath": "pages/index/wode",
"iconPath": "/static/image/路径 3917.png",
"selectedIconPath": "/static/image/路径 24@2x.png",
"selectedIconPath": "/static/image/路径 24.png",
"text": "我的"
}
]


+ 46
- 83
111/pages/home/home.uvue View File

@ -4,11 +4,11 @@
<view class="header">
<view class="header_info">
<text class="header_text" :title="title">{{title}}</text>
<text style="margin-right: 10rpx; font-size: 40rpx;">|</text>
<text class="header_texts" :title="title">{{title}}</text>
<text class="header_info_icons">|</text>
<view @click="change_text" class="header_change">
<text >切换</text>
<uni-icons type="right" size="30" color="#c2d4de" :size="1"></uni-icons>
<uni-icons type="right" size="30" color="#c2d4de" ></uni-icons>
</view>
</view>
</view>
@ -20,14 +20,14 @@
<view class="order_Entry_container" @click="orderEntry">
<image class="order_Entry_image" src="/static/image/组 71699_1@3x.png"></image>
<text style="color: #115881;font-weight: bold;margin-left: 20rpx;">录入订单</text>
<text style="color: #115881;font-weight: bold;margin-left: 1rem;">录入订单</text>
<uni-icons class="order_Entry_end" type="right" :size="25" color="#306e91"></uni-icons>
</view>
<view v-if="isshow" class="show_container">
<view class="isshow-header">
<uni-icons class=" isshow-header-content-icon" type="search" :size="20"></uni-icons>
<uni-easyinput :inputBorder="false" @input="handleSearch(ServiceName)" class=" isshow-header-content-input" v-model="ServiceName" placeholder="请输入服务名称" />
<uni-easyinput :inputBorder="false" @input="handleSearch" class=" isshow-header-content-input" v-model="ServiceName" placeholder="请输入服务名称" />
<text class="isshow-header-content-text" @click="searchName">搜索</text>
</view>
<view class="isshow-content" >
@ -39,7 +39,7 @@
<image class="show_container_1_image" src="/static/image/图层_6.png"></image>
<view class="show_container_1_footer">
<text>门店已经切换为{{title}}</text>
<button @click="close_view">好的</button>
<button class="show_container_1_footer_button" @click="close_view">好的</button>
</view>
</view>
@ -64,14 +64,7 @@ export default {
{ name: "m3", id: 6 },
{ name: "hahaha", id: 7 }
],
textcontent: [
'公告1:欢迎使用车辆合同生成系统!',
'公告2:请及时查看最新用户协议。',
'公告3:隐私政策已更新,请知悉。',
'公告1:欢迎使用车辆合同生成系统!',
'公告2:请及时查看最新用户协议。',
'公告3:隐私政策已更新,请知悉。'
],
textcontent: [],
};
},
mounted() {
@ -85,8 +78,10 @@ export default {
{ name: "hahaha", id: 7 }
];
this.textcontent = this.allMsg;
},
methods: {
change_text(){
if(this.isshow){
@ -116,9 +111,10 @@ export default {
},
// 模糊匹配
// 右上角搜索框--模糊查询
handleSearch(queryString) {
if(event.target.value){
let queryStringArr = event.target.value.split("");
handleSearch(event) {
console.log(event);
if(event){
let queryStringArr = event.split("");
let str = "(.*?)";
this.textcontent = [];
let regStr = str + queryStringArr.join(str) + str;
@ -139,50 +135,14 @@ export default {
<style>
.container {
display: flex;
flex-direction: column;
height: 100vh;
background-color: #f5f5f5;
}
/* 头部 */
.header {
padding: 20px;
width: 100%;
height: 15%;
background-color: #044f7a;
color: #fff;
display: flex;
flex-direction: row;
align-items: center;
}
.header_info{
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
color: #e0e9ef;
}
.header_text{
width: 45%;
white-space: nowrap;/*设置不换行*/
overflow: hidden; /*设置隐藏*/
text-overflow: ellipsis; /*设置隐藏部分为省略号*/
}
.header_change{
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
}
/* 订单录入 */
.order_Entry_container{
width: 90%;
height: 8%;
background-color: #d9e5eb;
border-radius: 10rpx;
left:5%;
border-radius: 0.6rem;
margin-left:5%;
display: flex;
flex-direction: row;
align-items: center;
@ -215,26 +175,26 @@ white-space: nowrap;/*设置不换行*/
.form {
flex: 1;
padding: 20px;
padding: 1rem;
}
.submit-button {
width: 100%;
height: 40px;
height: 3rem;
background-color: #007aff;
color: #fff;
border: none;
border-radius: 4px;
font-size: 16px;
border-radius: 0.3rem;
font-size: 1rem;
}
.footer {
display: flex;
justify-content: space-around;
padding: 10px;
padding: 0.8rem;
background-color: #fff;
border-top: 1px solid #ccc;
border-top: 1rem solid #ccc;
}
.nav-item {
@ -242,14 +202,14 @@ white-space: nowrap;/*设置不换行*/
}
.nav-item text {
font-size: 14px;
font-size: 0.9rem;
}
.icon-image{
width: 30%;
height: 140px;
height: 10rem;
margin: 0 auto;
margin-top: 20px;
margin-top: 1rem;
}
/* 遮罩层 */
@ -258,9 +218,9 @@ white-space: nowrap;/*设置不换行*/
height: 36%;
background-color: #ffffff;
position: absolute;
border-radius: 20rpx;
/* border: 1px solid; */
box-shadow: 0px 3rpx 0px #e4e4e4;
border-radius: 1rem;
/* border: 1rem solid; */
box-shadow: 0rem 0.2rem 0rem #e4e4e4;
left:5%;
top: 13%;
z-index:999;
@ -284,7 +244,7 @@ white-space: nowrap;/*设置不换行*/
.isshow-header-content-input{
width: 80%;
height: 40%;
margin: 0 20rpx 0 20rpx;
margin: 0 1rem 0 1rem;
border:none;
outline:none;
}
@ -297,11 +257,11 @@ white-space: nowrap;/*设置不换行*/
}
.isshow-content-text{
color: #414141;
height: 30rpx;
height: 1.5rem;
width: 100%;
line-height: 30rpx;
margin: 20rpx 0 20rpx 0;
font-size: 30rpx;
line-height: 1.5rem;
margin: 1rem 0 1rem 0;
font-size: 0.8rem;
}
.isshow-content::-webkit-scrollbar {
display: none;
@ -309,22 +269,22 @@ white-space: nowrap;/*设置不换行*/
/* 提示框*/
.show_container_1{
width: 80%;
height: 40%;
height: 50%;
background-color: #ffffff;
position: absolute;
border-radius: 20rpx;
/* border: 1px solid; */
box-shadow: 0px 3rpx 0px #e4e4e4;
border-radius: 1rem;
/* border: 1rem solid; */
box-shadow: 0rem 0.2rem 0rem #e4e4e4;
left:10%;
top: 30%;
top:25%;
z-index:999;
display: flex;
flex-direction: column;
align-items: center;
}
.show_container_1_image{
height: 50%;
width: 50%;
height: 40%;
width: 60%;
top: 5%;
}
.show_container_1_footer{
@ -335,20 +295,23 @@ white-space: nowrap;/*设置不换行*/
flex-direction: column;
align-items: center;
font-weight: bold;
font-size: 10rpx;
font-size: 0.7rem;
}
.show_container_1_footer text{
margin-top: 10%;
}
.show_container_1_footer button{
.show_container_1_footer_button{
background-color: #ffffff;
color:#0b5583;
height: 30%;
border-radius: 40rpx;
border-radius: 1.8rem;
width: 80%;
margin-top: 5%;
border: 1px solid #0c547e;
border: 0.1rem solid #0c547e;
display: flex;
justify-content: center;
align-items: center;
}
</style>

+ 406
- 0
111/pages/index/PayPal.uvue View File

@ -0,0 +1,406 @@
<template>
<view class="containers">
<view class="header">
<view class="header_info">
<uni-icons class="header_info_icon" type="left" size="30" color="#c2d4de" @click.native.stop.prevent="toBack"></uni-icons>
<text class="header_text">付款信息</text>
</view>
</view>
<view class="idCard-box">
<view class="reverse">
<image :src="upLoadPositiveImg == ''?positiveImg:upLoadPositiveImg" @tap.prevent="uploadPositive">
</image>
</view>
<view class="reverse">
<image :src="upLoadReverseImg == ''?reverseImg:upLoadReverseImg" @tap.prevent="uploadReverse">
</image>
</view>
<view class="reverse">
<image :src="upLoadCarImg == ''?carImg:upLoadCarImg" @tap.prevent="uploadReverse">
</image>
</view>
</view>
<!-- 客户基本信息 -->
<view class="section">
<view class="con_size">
<image src="/static/image/矩形 5315.png" class='con_size_img' ></image>
客户基本信息
</view>
<view class="form-item">
<text class="label">产品名称</text>
<text class="value">{{ selectedProduct }}</text>
</view>
<view class="form-item">
<text class="label">经销商</text>
<text class="value">{{ selectedStore }}</text>
</view>
<view class="form-item">
<text class="label">客户姓名</text>
<input class="input" v-model="clientInfo.name" placeholder="请输入客户姓名" />
</view>
<view class="form-item">
<text class="label">居住地址</text>
<input class="input" v-model="clientInfo.address" placeholder="请输入居住地址" />
</view>
<view class="form-item">
<text class="label">身份证号码</text>
<input class="input" v-model="clientInfo.idNumber" placeholder="请输入身份证号码" />
</view>
<view class="form-item">
<text class="label">联系方式</text>
<input class="input" v-model="clientInfo.contact" placeholder="请输入联系方式" />
</view>
<view class="form-item">
<text class="label">销售部门</text>
<l-radio-group class="radio-group" @change="handleDepartmentChange">
<label class="radio-label" v-for="item in departments" :key="item">
<l-radio :value="item" :checked="clientInfo.department === item" >
<template #icon="{checked}">
<image v-show="checked" style="width:1.2rem; height:1.2rem;" src="/static/image/xuanzhong.png"></image>
<image v-show="!checked" style="width:1.2rem; height:1.2rem" src="/static/image/weixuanzhong.png"></image>
</template>
</l-radio>
<text style="margin-left:0.2rem;">{{ item }}</text>
</label>
</l-radio-group>
</view>
<view class="form-item">
<text class="label">促销销售顾问</text>
<input class="input" v-model="clientInfo.salesAdvisor" placeholder="请输入店铺销售顾问" />
</view>
</view>
<!-- 车辆信息 -->
<view class="section">
<view class="con_size">
<image src="/static/image/矩形 5315.png" class='con_size_img' ></image>车辆信息</view>
<view class="form-item">
<text class="label">车牌车系</text>
<picker class="picker" @change="bindCarBrandChange" :value="carBrandIndex" :range="carBrands">
<view class="picker-text">{{ carBrands[carBrandIndex] || '请选择车辆品牌 >' }}</view>
</picker>
</view>
<view class="form-item">
<text class="label">车牌号</text>
<input class="input" v-model="vehicleInfo.plateNumber" placeholder="456123351" />
</view>
</view>
<!-- 产品描述 -->
<view class="section">
<view class="con_size">
<image src="/static/image/矩形 5315.png" class='con_size_img' ></image>产品描述</view>
<view class="form-item">
<text class="label">产品名称</text>
<text class="value">{{ selectedService }}</text>
</view>
<view class="form-item">
<text class="label">服务年龄</text>
<picker class="picker" @change="bindServiceAgeChange" :value="serviceAgeIndex" :range="serviceAges">
<view class="picker-text">{{ serviceAges[serviceAgeIndex] || '请选择服务年龄 >' }}</view>
</picker>
</view>
<view class="form-item">
<text class="label">销售金额</text>
<input class="input" v-model="productInfo.salesAmount" placeholder="请输入销售金额" />
</view>
</view>
<!-- 付款信息 -->
<view class="section">
<view class="con_size">
<image src="/static/image/矩形 5315.png" class='con_size_img' ></image>付款信息</view>
<view class="form-item">
<text class="label">收款方</text>
<picker class="picker" @change="bindPayeeChange" :value="payeeIndex" :range="payees">
<view class="picker-text">{{ payees[payeeIndex] || '请选择收款方 >' }}</view>
</picker>
</view>
<view class="form-item">
<text class="label">付款时间</text>
<uni-datetime-picker class="timePiker" type="datetime" v-model="paymentInfo.paymentTime" :clear-icon="false" :border="false">
</uni-datetime-picker>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
selectedProduct: "自动填写所选商品服务分类",
selectedStore: "自动填写所选择的门店",
selectedService: "自动填写所选择的服务分类",
clientInfo: {
name: '',
address: '',
idNumber: '',
contact: '',
department: '',
salesAdvisor: ''
},
vehicleInfo: {
plateNumber: '456123351'
},
productInfo: {
salesAmount: ''
},
paymentInfo: {
paymentTime: ''
},
departments: ['售前', '售后', '二网车'],
carBrands: ['品牌A', '品牌B', '品牌C'],
carBrandIndex: -1,
serviceAges: ['1年', '2年', '3年'],
serviceAgeIndex: -1,
payees: ['收款方A', '收款方B', '收款方C'],
payeeIndex: -1,
// 扫描
positiveImg: '/static/image/组件 4 – 1.png',//自己图片路径
upLoadPositiveImg: '',
// 反面身份证
reverseImg: '/static/image/组 71663.png', //自己图片路径
upLoadReverseImg: '',
// 行车驾驶证
carImg: '/static/image/组件 2 – 1.png', //自己图片路径
upLoadCarImg: '',
baidu_token:' '//百度token
}
},
methods: {
toBack(){
let canNavBack = getCurrentPages()
if( canNavBack && canNavBack.length>1) {
uni.navigateBack()
} else {
history.back();
}
},
handleDepartmentChange(e) {
this.clientInfo.department = e.detail.value
},
bindCarBrandChange(e) {
this.carBrandIndex = e.detail.value
},
bindServiceAgeChange(e) {
this.serviceAgeIndex = e.detail.value
},
bindPayeeChange(e) {
this.payeeIndex = e.detail.value
},
// file文件转base64
getImageBase64(blob) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(blob);
reader.onload = () => {
const base64 = reader.result;
resolve(base64);
}
reader.onerror = error => reject(error);
});
},
// 身份证正面上传
uploadPositive() {
uni.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: (res) => {
this.upLoadPositiveImg = res.tempFilePaths[0]
this.getImageBase64(res.tempFiles[0]).then(res => {
this.uploadIdentify(res)
})
}
})
},
// 身份证反面上传
uploadReverse() {
uni.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: (res) => {
this.upLoadReverseImg = res.tempFilePaths[0]
this.getImageBase64(res.tempFiles[0]).then(res => {
this.uploadIdentify(res)
})
}
})
},
// 获取百度token
getACSS_TOKEN() {
let that = this
uni.request({
// url: '/baiduApi/oauth/2.0/token',
url: 'https://aip.baidubce.com/oauth/2.0/token',
method: 'POST',
data: {
grant_type: 'client_credentials',
client_id: '你的',
client_secret: '你的',
},
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
success: res => {
this.baidu_token = res.data.access_token
}
});
},
// 上传识别
uploadIdentify(res) {
uni.request({
url: '/baiduApi/rest/2.0/ocr/v1/idcard?access_token=' + this.baidu_token,
method: 'POST',
data: {
image: res,
id_card_side: 'back' // 身份证 正反面 front:身份证含照片的一面 back:身份证带国徽的一面
},
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
success: res => {
console.log(res.data)
}
})
},
}
}
</script>
<style scoped lang="scss">
.containers {
height: 100%;
width: 100%;
background-color: #fff;
overflow-y:scroll;
}
.container::-webkit-scrollbar {
display: none;
}
.section {
// margin-bottom: 30rpx;
border-bottom: 1rpx solid #eee;
margin: 0 1rem 0 1rem;
}
.form-item {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: 0.5rem 0;
border-bottom: 0.1rem solid #f2f2f2;
color: #767676;
}
.label {
font-size: 28rpx;
color: #666;
width: 200rpx;
}
.input {
flex: 1;
text-align: right;
font-size: 28rpx;
color: #737373;
}
.picker {
flex: 1;
}
.picker-text {
text-align: right;
color: #737373;
font-size: 0.8rem;
}
.radio-group {
display: flex;
flex: 1;
justify-content: flex-end;
flex-direction: row;
}
.radio-label {
padding: 0;
margin-left: 10rpx;
display: flex;
flex-direction: row;
font-size: 1rem;
transform: scale(0.7);
}
.value {
flex: 1;
text-align: right;
color: #737373;
}
.timePiker{
display: flex;
justify-content: center;
/* align-items: center; */
color: #3f3f3f;
}
.idCard-box {
margin-top: 10%;
width: 100%;
height: 50%;
display: flex;
flex-direction: row;
/* background-color: red; */
flex-wrap: wrap;
.reverse {
height: 30%;
width: 40%;
display: flex;
align-items: center;
justify-content: center;
// background-color: blue;
margin: 0 5% 0 5%;
image {
width: 100%;
height: 100%;
}
}
}
/* 表单分区样式 */
.con_size {
font-size: 1rem;
font-weight: bold;
margin: 1rem 0;
color: #000000;
display: flex;
flex-direction: row;
}
.con_size_img{
height: 100%;
width: 2%;
margin-right: 2%;
}
</style>

+ 27
- 0
111/pages/index/dingdan.uvue View File

@ -0,0 +1,27 @@
<template>
<view class="container">
<view class="header">
<view class="header_info">
<uni-icons class="header_info_icon" type="left" size="30" color="#c2d4de" :size="1" @click="toBack"></uni-icons>
<text class="header_text">订单列表</text>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
}
}
</script>
<style>
</style>

+ 0
- 88
111/pages/index/index_1.uvue View File

@ -1,88 +0,0 @@
<template>
<view class="container">
<view class="form">
<input class="input" type="text" placeholder="请输入您的账号" v-model="username" />
<input class="input" type="password" placeholder="请输入您的密码" v-model="password" />
<view class="agreement">
<checkbox-group @change="handleAgreementChange">
<label>
<checkbox value="agree" /> 阅读并同意《用户协议》和《隐私政策》
</label>
</checkbox-group>
</view>
<button class="button" @click="handleLogin">登录</button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
username: '',
password: '',
agreed: false
};
},
methods: {
handleAgreementChange(e) {
this.agreed = e.detail.value.includes('agree');
},
handleLogin() {
if (!this.agreed) {
uni.showToast({
title: '请先同意用户协议和隐私政策',
icon: 'none'
});
return;
}
// 这里可以添加登录逻辑
uni.showToast({
title: '登录成功',
icon: 'success'
});
}
}
};
</script>
<style>
.container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #f5f5f5;
}
.form {
width: 80%;
background-color: #fff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
.input {
width: 100%;
height: 40px;
margin-bottom: 15px;
padding: 10px;
border: 1px solid #ccc;
border-radius: 4px;
}
.agreement {
margin-bottom: 15px;
}
.button {
width: 100%;
height: 40px;
background-color: #007aff;
color: #fff;
border: none;
border-radius: 4px;
font-size: 16px;
}
</style>

+ 57
- 31
111/pages/index/login.uvue View File

@ -2,21 +2,22 @@
<view class="login-container">
<!-- 顶部欢迎语 -->
<view class="login_image">
<image src="/static/image/组件 3 – 1.png" draggable ="false"></image>
<image class="login_image_img" src="/static/image/组件 3 – 1.png" ></image>
</view>
<view class="welcome">
<text class="welcome-text">欢迎登陆车辆合同生成</text>
</view>
<!-- 账号输入框 -->
<view class="input-container">
<uni-easyinput prefixIcon="person" class="input" placeholder="请输入您的账号" v-model="username" :inputBorder="false" ></uni-easyinput>
<view class="input-container">
<uni-easyinput prefixIcon="person" class="input" placeholder="请输入您的账号" v-model="username" :inputBorder='false' :clearable='false' >
</uni-easyinput>
<view class="underline"></view>
</view>
<!-- 密码输入框 -->
<view class="input-container">
<uni-easyinput prefixIcon="locked" class="input" type="password" placeholder="请输入您的密码" v-model="password" :inputBorder="false" ></uni-easyinput>
<uni-easyinput prefixIcon="locked" class="input" type="password" placeholder="请输入您的密码" v-model="password" :inputBorder='false' :passwordIcon="false" :clearable='false'></uni-easyinput>
<view class="underline"></view>
</view>
@ -64,6 +65,22 @@ export default {
checked:false,
};
},
onLoad() {
uni.request(
{
url: 'https://gpt.aiym.run/contract/miniapp/product/categories' ,
method:'GET',
header:{
"Content-Type": "application/json",
"X-Access-Token":'11'
},
success:(res)=>{
console.log(res.data)
}
}
);
},
methods: {
// 处理登录逻辑
handleLogin() {
@ -114,6 +131,8 @@ export default {
</script>
<style>
/* 页面容器 */
.login-container {
display: flex;
@ -125,76 +144,80 @@ export default {
}
.button-text {
color: #fff;
font-size: 12px;
font-size: 12rem;
}
/* 登录图片 */
.login_image{
width: 100%;
height: 40%;
}
.login_image image{
.login_image_img{
width: 100%;
height: 100%;
}
/* 欢迎语 */
.welcome {
height: 15%;
margin-bottom: 40rpx;
margin-bottom: 10%;
display: flex;
justify-content: end;
align-items: center;
}
.welcome-text {
font-size: 20px;
font-size: 1.3rem;
font-weight: bold;
color: #044f7a;
}
/* 输入框容器 */
.input-container {
width: 100%;
left:10%;
width: 70%;
height: 7%;
/* background-color: #007aff; */
display: flex;
flex-direction: column;
align-items: center;
}
/* 输入框样式 */
.input {
width: 70%;
height: 40px;
font-size: 16px;
width: 100%;
height: 99%;
font-size: 1rem;
border: none;
outline: none;
background-color: transparent;
/* z-index: 99; */
}
/* 下划线样式 */
.underline {
width: 100%;
height: 1px;
height: 0.1%;
background-color: #f2f2f2;
margin-top: 5px;
}
/* 协议提示 */
.agreement {
font-size: 14px;
font-size: 1rem;
color: #666;
margin-bottom: 20px;
width: 100%;
margin-bottom: 1.2rem;
width: 90%;
left:10%;
display: flex;
flex-direction: row;
align-items: center;
}
.login-agree{
font-size: 20rpx;
font-size: 0.6rem;;
}
.link {
color: #007aff;
text-decoration: underline;
font-size: 20rpx;
font-size: 0.6rem;
}
.button_container{
@ -206,16 +229,19 @@ export default {
/* 登录按钮 */
.login-button {
width: 70%;
height: 70rpx;
line-height: 70rpx;
height: 10%;
line-height: 10%;
background-color: #044f7a;
color: #fff;
border: none;
border-radius: 4px;
font-size: 16px;
border-radius: 4rem;
font-size: 1rem;
position: absolute;
top:15%;
left:20%;
left:15%;
display: flex;
justify-content: center;
align-items: center;
}
/* 弹窗样式 */
@ -234,26 +260,26 @@ line-height: 70rpx;
.modal-content {
width: 80%;
background-color: #fff;
border-radius: 8px;
padding: 20px;
border-radius: 0.5rem;
padding: 1.5rem;
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 18px;
font-size: 1rem;
font-weight: bold;
margin-bottom: 15px;
margin-bottom: 1rem;
}
.close {
font-size: 24px;
font-size: 1.5rem;
cursor: pointer;
}
.modal-body {
font-size: 16px;
font-size: 1rem;
line-height: 1.5;
}


+ 1
- 0
111/pages/index/wode.uvue View File

@ -120,4 +120,5 @@ export default {
.nav-item text {
font-size: 14px;
}
</style>

+ 46
- 57
111/pages/views/dingDanCreate.uvue View File

@ -4,14 +4,14 @@
<view class="header">
<view class="header_info">
<uni-icons class="header_info_icon" type="left" size="30" color="#c2d4de" :size="1" @click="toBack"></uni-icons>
<uni-icons class="header_info_icon" type="left" size="30" color="#c2d4de" @click.native.stop.prevent="toBack"></uni-icons>
<text class="header_text">录入订单</text>
</view>
</view>
<view class="content_container">
<view class="isshow-header">
<uni-icons class=" isshow-header-content-icon" type="search" :size="20"></uni-icons>
<uni-easyinput :inputBorder="false" @input="handleSearch(ServiceName)" class=" isshow-header-content-input" v-model="ServiceName" placeholder="请输入服务名称" focus=true />
<uni-easyinput :inputBorder="false" class=" isshow-header-content-input" v-model="ServiceName" placeholder="请输入服务名称" :focus="firstFocus" />
<text class="isshow-header-content-text" @click="searchName">搜索</text>
</view>
</view>
@ -30,13 +30,15 @@
</scroll-view>
</view>
<!-- 下一步 -->
<button class="buttun" @click="toPayment">下一步</button>
<view class="buttun" @click="toNext">下一步</view>
</view>
</template>
<script>
export default {
data() {
return {
firstFocus:true,
ServiceName:'',
product:[
{
id: 1,
@ -83,11 +85,36 @@
name:''
}
},
onLoad() {
uni.request(
{
url: 'https://gpt.aiym.run/contract/miniapp/product/categories' ,
method:'GET',
header:{
"Content-Type": "application/json",
"X-Access-Token":'11'
},
success:(res)=>{
console.log(res.data.result)
}
}
);
},
methods: {
toBack(){
uni.navigateBack({
delta: 1
});
let canNavBack = getCurrentPages()
if( canNavBack && canNavBack.length>1) {
uni.navigateBack()
} else {
history.back();
}
},
toNext(){
console.log(111);
uni.navigateTo(
{ url: '/pages/index/PayPal' }
)
},
nameClick (){
@ -101,55 +128,14 @@
this.name = name;
}
},
toPayment(){
console.log(111);
uni.navigateTo(
{ url: '/pages/views/payment' }
)
searchName(){
console.log('1');
}
}
</script>
<style>
.container {
display: flex;
flex-direction: column;
height: 100vh;
background-color: #f5f5f5;
position: relative;
}
/* 头部 */
.header {
width: 100%;
height: 15%;
background-color: #044f7a;
color: #fff;
display: flex;
flex-direction: row;
align-items: center;
}
.header_info{
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
color: #e0e9ef;
justify-content: center;
align-items: center;
flex: 15;
}
.header_info_icon{
margin-right: auto;
flex: 1;
}
.header_text{
flex: 14;
display: flex;
/* justify-content: center; */
left:35%;
align-items: center;
}
/* 搜索框 */
.content_container{
width: 100%;
@ -184,7 +170,7 @@
.isshow-header-content-input{
width: 80%;
height: 40%;
margin: 0 20rpx 0 20rpx;
margin: 0 1rem 0 1rem;
border:none;
outline:none;
}
@ -197,11 +183,11 @@
}
.isshow-content-text{
color: #414141;
height: 30rpx;
height: 1.5rem;
width: 100%;
line-height: 30rpx;
margin: 20rpx 0 20rpx 0;
font-size: 30rpx;
line-height: 1,5rem;
margin: 1rem 0 1rem 0;
font-size: 1.5rem;
}
.isshow-content::-webkit-scrollbar {
display: none;
@ -216,7 +202,7 @@
display: flex;
justify-content: center;
align-items: center;
font-size: 27rpx;
font-size: 1rem;
color: #7f7f7f;
}
.content_footer_right{
@ -237,6 +223,7 @@
margin-right: auto;
color:#242424;
margin-left: 5%;
font-size: 1rem;
}
.content_footer_right_content_radio{
margin-left: auto;
@ -253,15 +240,17 @@ margin-right: 5%;
/* 按钮 */
.buttun{
width: 30%;
height: 5%;
position: absolute;
display: flex;
justify-content: center;
align-items: center;
font-size: 25rpx;
border-radius: 30rpx;
font-size: 1.3rem;
border-radius: 1.5rem;
background-color: #05507c;
bottom:5%;
right: 5%;
color: #fafcff;
z-index: 99999;
}
</style>

+ 0
- 22
111/pages/views/payment.uvue View File

@ -1,22 +0,0 @@
<template>
<view>
你好
</view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
}
}
</script>
<style>
</style>

BIN
111/static/gonggao.png View File

Before After
Width: 37  |  Height: 32  |  Size: 2.0 KiB

BIN
111/static/image/11.png View File

Before After
Width: 34  |  Height: 31  |  Size: 846 B

BIN
111/static/image/weixuanzhong.png View File

Before After
Width: 92  |  Height: 86  |  Size: 4.3 KiB

BIN
111/static/image/xuanzhong.png View File

Before After
Width: 87  |  Height: 87  |  Size: 6.4 KiB

BIN
111/static/image/图像 4@2x.png View File

Before After
Width: 248  |  Height: 248  |  Size: 82 KiB

BIN
111/static/image/图像 4@3x.png View File

Before After
Width: 372  |  Height: 372  |  Size: 165 KiB

BIN
111/static/image/图层_6@2x.png View File

Before After
Width: 483  |  Height: 465  |  Size: 56 KiB

BIN
111/static/image/图层_6@3x.png View File

Before After
Width: 725  |  Height: 698  |  Size: 113 KiB

BIN
111/static/image/矩形 5315@2x.png View File

Before After
Width: 30  |  Height: 98  |  Size: 783 B

BIN
111/static/image/矩形 5315@3x.png View File

Before After
Width: 45  |  Height: 147  |  Size: 1.5 KiB

BIN
111/static/image/组 70865@2x.png View File

Before After
Width: 122  |  Height: 110  |  Size: 7.5 KiB

BIN
111/static/image/组 70865@3x.png View File

Before After
Width: 183  |  Height: 164  |  Size: 14 KiB

BIN
111/static/image/组 71663@2x.png View File

Before After
Width: 562  |  Height: 384  |  Size: 18 KiB

BIN
111/static/image/组 71663@3x.png View File

Before After
Width: 843  |  Height: 576  |  Size: 34 KiB

BIN
111/static/image/组 71693@2x.png View File

Before After
Width: 193  |  Height: 168  |  Size: 24 KiB

BIN
111/static/image/组 71693@3x.png View File

Before After
Width: 289  |  Height: 252  |  Size: 37 KiB

BIN
111/static/image/组 71696@2x.png View File

Before After
Width: 103  |  Height: 103  |  Size: 6.8 KiB

BIN
111/static/image/组 71696@3x.png View File

Before After
Width: 155  |  Height: 155  |  Size: 9.4 KiB

BIN
111/static/image/组 71697@2x.png View File

Before After
Width: 209  |  Height: 179  |  Size: 29 KiB

BIN
111/static/image/组 71697@3x.png View File

Before After
Width: 314  |  Height: 269  |  Size: 40 KiB

BIN
111/static/image/组 71699@2x.png View File

Before After
Width: 1500  |  Height: 1100  |  Size: 855 KiB

BIN
111/static/image/组 71699@3x.png View File

Before After
Width: 2250  |  Height: 1650  |  Size: 1.3 MiB

BIN
111/static/image/组 71699_1.png View File

Before After
Width: 750  |  Height: 550  |  Size: 299 KiB

BIN
111/static/image/组 71699_1@2x.png View File

Before After
Width: 1500  |  Height: 1100  |  Size: 862 KiB

BIN
111/static/image/组件 2 – 1@2x.png View File

Before After
Width: 562  |  Height: 384  |  Size: 23 KiB

BIN
111/static/image/组件 2 – 1@3x.png View File

Before After
Width: 843  |  Height: 576  |  Size: 44 KiB

BIN
111/static/image/组件 3 – 1@2x.png View File

Before After
Width: 1500  |  Height: 980  |  Size: 141 KiB

BIN
111/static/image/组件 3 – 1@3x.png View File

Before After
Width: 2250  |  Height: 1470  |  Size: 308 KiB

BIN
111/static/image/组件 4 – 1@2x.png View File

Before After
Width: 562  |  Height: 384  |  Size: 18 KiB

BIN
111/static/image/组件 4 – 1@3x.png View File

Before After
Width: 843  |  Height: 576  |  Size: 36 KiB

BIN
111/static/image/组件 5 – 1@2x.png View File

Before After
Width: 410  |  Height: 310  |  Size: 9.0 KiB

BIN
111/static/image/组件 5 – 1@3x.png View File

Before After
Width: 615  |  Height: 465  |  Size: 18 KiB

BIN
111/static/image/联合 2.png View File

Before After
Width: 768  |  Height: 147  |  Size: 3.1 KiB

BIN
111/static/image/联合 2_1.png View File

Before After
Width: 768  |  Height: 147  |  Size: 3.1 KiB

BIN
111/static/image/路径 24@2x.png View File

Before After
Width: 60  |  Height: 58  |  Size: 1.9 KiB

BIN
111/static/image/路径 24@3x.png View File

Before After
Width: 91  |  Height: 87  |  Size: 2.5 KiB

BIN
111/static/image/路径 25@2x.png View File

Before After
Width: 54  |  Height: 65  |  Size: 1.4 KiB

BIN
111/static/image/路径 25@3x.png View File

Before After
Width: 81  |  Height: 98  |  Size: 2.1 KiB

BIN
111/static/image/路径 3909@2x.png View File

Before After
Width: 118  |  Height: 107  |  Size: 3.7 KiB

BIN
111/static/image/路径 3909@3x.png View File

Before After
Width: 177  |  Height: 161  |  Size: 5.2 KiB

BIN
111/static/image/路径 3909_1.png View File

Before After
Width: 59  |  Height: 54  |  Size: 1.3 KiB

BIN
111/static/image/路径 3909_1@2x.png View File

Before After
Width: 118  |  Height: 107  |  Size: 3.7 KiB

BIN
111/static/image/路径 3909_1@3x.png View File

Before After
Width: 177  |  Height: 161  |  Size: 5.2 KiB

BIN
111/static/image/路径 3917@2x.png View File

Before After
Width: 114  |  Height: 114  |  Size: 3.5 KiB

BIN
111/static/image/路径 3917@3x.png View File

Before After
Width: 172  |  Height: 171  |  Size: 6.6 KiB

BIN
111/static/image/路径 3917_1.png View File

Before After
Width: 57  |  Height: 57  |  Size: 1.3 KiB

BIN
111/static/image/路径 3917_1@2x.png View File

Before After
Width: 114  |  Height: 114  |  Size: 3.5 KiB

BIN
111/static/image/路径 3917_1@3x.png View File

Before After
Width: 172  |  Height: 171  |  Size: 6.6 KiB

BIN
111/static/image/路径 4016@2x.png View File

Before After
Width: 105  |  Height: 122  |  Size: 3.0 KiB

BIN
111/static/image/路径 4016@3x.png View File

Before After
Width: 157  |  Height: 184  |  Size: 4.7 KiB

BIN
111/static/image/路径 4016_1@2x.png View File

Before After
Width: 105  |  Height: 122  |  Size: 2.6 KiB

BIN
111/static/image/路径 4016_1@3x.png View File

Before After
Width: 157  |  Height: 184  |  Size: 4.7 KiB

BIN
111/static/image/路径 4150@2x.png View File

Before After
Width: 90  |  Height: 90  |  Size: 2.7 KiB

BIN
111/static/image/路径 4150@3x.png View File

Before After
Width: 135  |  Height: 135  |  Size: 5.5 KiB

BIN
111/static/image/路径 6111@2x.png View File

Before After
Width: 103  |  Height: 103  |  Size: 5.8 KiB

BIN
111/static/image/路径 6111@3x.png View File

Before After
Width: 155  |  Height: 155  |  Size: 8.1 KiB

BIN
111/static/image/路径 6112@2x.png View File

Before After
Width: 103  |  Height: 103  |  Size: 3.7 KiB

BIN
111/static/image/路径 6112@3x.png View File

Before After
Width: 154  |  Height: 154  |  Size: 7.5 KiB

BIN
111/static/logo.png View File

Before After
Width: 72  |  Height: 72  |  Size: 3.9 KiB

+ 14
- 0
111/uni_modules/lime-radio/changelog.md View File

@ -0,0 +1,14 @@
## 0.0.7(2025-02-09)
- fix: 修复uniappx app端自定义颜色的问题
## 0.0.6(2024-12-16)
- fix: 修复vue2 微信小程序自定义颜色问题
## 0.0.5(2024-12-16)
- feat: 兼容vue2
## 0.0.4(2024-12-16)
- chore: 更新文档
## 0.0.3(2024-12-16)
- chore: 更新文档
## 0.0.2(2024-12-16)
- feat: 增加fontsize
## 0.0.1(2024-12-11)
- init

+ 48
- 0
111/uni_modules/lime-radio/components/l-radio-group/l-radio-group.uvue View File

@ -0,0 +1,48 @@
<template>
<view class="l-radio-group" :class="'l-radio-group--'+ direction">
<slot />
</view>
</template>
<script lang="uts" setup>
import { RadioGroupProps } from './type';
const emit = defineEmits(['change', 'update:modelValue'])
const props = withDefaults(defineProps<RadioGroupProps>(), {
allowUncheck: false,
disabled: false,
direction: 'horizontal'
// size: 'medium'
})
const innerValue = ref<any|null>(null);
const groupValue = computed({
set(value: any|null) {
innerValue.value = value
emit('update:modelValue', value)
emit('change', value)
},
get():any|null {
return props.value ?? props.modelValue ?? props.defaultValue ?? innerValue.value
}
} as WritableComputedOptions<any|null>)
const handleRadioChange = (val: any) => {
if (props.allowUncheck && val == groupValue.value) {
groupValue.value = ''
} else {
groupValue.value = val
}
}
provide('limeRadioGroupProps', props)
provide('limeRadioGroupValue', groupValue)
provide('limeRadioGroupChange', handleRadioChange)
</script>
<style lang="scss">
.l-radio-group {
flex-direction: row;
}
.l-radio-group--vertical {
flex-direction: column;
}
</style>

+ 70
- 0
111/uni_modules/lime-radio/components/l-radio-group/l-radio-group.vue View File

@ -0,0 +1,70 @@
<template>
<view class="l-radio-group" :class="'l-radio-group--'+ direction">
<slot />
</view>
</template>
<script lang="ts">
//@ts-nocheck
import { defineComponent, provide, ref, computed } from '@/uni_modules/lime-shared/vue'
import radioGroupProps from './props'
const name = 'l-radio-group'
export default defineComponent({
name,
props: radioGroupProps,
emits: ['update:value', 'update:modelValue', 'change', 'input'],
setup(props, { emit }) {
const innerValue = ref<any|null>(null);
const groupValue = computed({
set(value: any|null) {
innerValue.value = value;
emit('update:modelValue', value)
emit('change', value)
// #ifdef VUE2
emit('input', value)
// #endif
},
get():any|null {
return props.value || props.name || props.modelValue || props.defaultValue || innerValue.value
}
} as WritableComputedOptions<any|null>)
const handleRadioChange = (val: any) => {
if (props.allowUncheck && val == groupValue.value) {
groupValue.value = ''
} else {
groupValue.value = val
}
}
provide('limeRadioGroupProps', props)
provide('limeRadioGroupValue', groupValue)
provide('limeRadioGroupChange', handleRadioChange)
}
})
</script>
<style lang="scss">
// .l-radio-group {
// display: flex;
// flex-direction: row;
// }
// .l-radio-group--vertical {
// flex-direction: column;
// }
.l-radio-group {
// background-color: antiquewhite;
}
.l-radio-group--vertical {
:deep(.l-radio) {
display: flex;
// line-height: 64rpx;
}
:deep(l-radio) {
display: flex;
// line-height: 64rpx;
}
}
</style>

+ 69
- 0
111/uni_modules/lime-radio/components/l-radio-group/props.ts View File

@ -0,0 +1,69 @@
// @ts-nocheck
export default {
/** 是否允许取消选中 */
allowUncheck: Boolean,
/** 是否禁用全部子单选框。默认为 false。RadioGroup.disabled 优先级低于 Radio.disabled */
disabled: Boolean,
/** HTML 元素原生属性 */
name: {
type: String,
default: null,
},
/** 选中的值 */
value: {
type: [String, Number, Boolean], //as PropType<LRadioGroupProps['value']>,
default: null,
},
modelValue: {
type: [String, Number, Boolean], //as PropType<LRadioGroupProps['value']>,
default: null,
},
/** 选中的值,非受控属性 */
defaultValue: {
type: [String, Number, Boolean] //as PropType<LRadioGroupProps['defaultValue']>,
},
checkedColor: {
type: String,
default: null
},
iconBgColor: {
type: String,
default: null
},
iconBorderColor: {
type: String,
default: null
},
iconDisabledColor: {
type: String,
default: null
},
iconDisabledBgColor: {
type: String,
default: null
},
icon: {
type: String,
default: 'circle'
}, //?: 'circle' | 'line' | 'dot';
size: {
type: String,
default: 'medium'
}, //?: 'small' | 'medium' | 'large';
iconSize: {
type: String,
defalut: null
},
fontSize: {
type: String,
defalut: null
},
direction: {
type: String,
default: 'horizontal'
}, //'horizontal' | 'vertical'
gap: {
type: String,
default: null
},
}

+ 41
- 0
111/uni_modules/lime-radio/components/l-radio-group/type.ts View File

@ -0,0 +1,41 @@
// @ts-nocheck
export type RadioValue = any//string | number | boolean;
export interface RadioGroupProps {
/**
*
*/
allowUncheck: boolean;
/**
* falseRadioGroup.disabled Radio.disabled
*/
disabled: boolean;
/**
* HTML
*/
name ?: string;
/**
*
*/
value ?: RadioValue;
/**
*
*/
defaultValue ?: RadioValue;
/**
*
*/
modelValue ?: RadioValue;
checkedColor?: string;
iconBgColor?: string;
iconBorderColor?: string;
iconDisabledColor?: string;
iconDisabledBgColor?: string;
icon ?: 'circle' | 'line' | 'dot';
size ?: 'small' | 'medium' | 'large';
iconSize ?: string;
fontSize ?: string;
gap ?: string;
direction: 'horizontal' | 'vertical'
}

+ 173
- 0
111/uni_modules/lime-radio/components/l-radio/index-u.scss View File

@ -0,0 +1,173 @@
@import '~@/uni_modules/lime-style/index.scss';
@import '~@/uni_modules/lime-style/functions.scss';
$radio: #{$prefix}-radio;
$icon: #{$radio}__icon;
$radio-icon-size: create-var(radio-icon-size, 40rpx);
$radio-font-size: create-var(radio-font-size, 32rpx);
$radio-small-icon-size: create-var(radio-small-icon-size, 28rpx);
$radio-small-font-size: create-var(radio-small-font-size, 30rpx);
$radio-large-icon-size: create-var(radio-large-icon-size, 44rpx);
$radio-large-font-size: create-var(radio-large-font-size, 36rpx);
$radio-icon-border-width: create-var(radio-icon-border-width, 1rpx);
// $radio-icon-border-color: var(--l-radio-border-color, $border-color);
$radio-icon-border-radius: create-var(radio-icon-border-radius, 999rpx);
$radio-icon-bg-color: create-var(radio-icon-bg-color, white);
$radio-icon-border-color: create-var(radio-border-icon-color, $gray-5);
$radio-icon-disabled-color: create-var(radio-icon-disabled-color, $gray-5);
$radio-icon-disabled-bg-color: create-var(radio-icon-disabled-bg-color, $gray-1);
$radio-icon-checked-color: create-var(radio-icon-checked-color, $primary-color);
.#{$radio} {
/* #ifndef UNI-APP-X */
display: inline-flex;
/* #endif */
flex-direction: row;
align-items: center;
&__icon {
position: relative;
box-sizing: border-box;
width: $radio-icon-size;
height: $radio-icon-size;
align-self: center;
transition-property: all;
transition-duration: 200ms;
transition-timing-function: cubic-bezier(0.78, 0.14, 0.15, 0.86);
/* #ifndef APP-ANDROID || APP-IOS */
&:after {
box-sizing: border-box;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
opacity: 0;
content: "";
transition-property: all;
transition-duration: 200ms;
transition-timing-function: cubic-bezier(0.78, 0.14, 0.15, 0.86);
}
/* #endif */
&--dot,&--circle {
background-color: $radio-icon-bg-color;
border: $radio-icon-border-width solid $radio-icon-border-color;
border-radius: $radio-icon-border-radius;
}
&--circle {
/* #ifndef APP-ANDROID || APP-IOS */
&:after {
top: 48%;
left: 24%;
display: table;
width: divide(100%, 20) * 7;
height: divide(100%, 20) * 12;
border: calc(#{$radio-icon-size} / 7) solid transparent;
border-top: 0;
border-inline-start: 0;
transform: rotate(45deg) scale(0) translate(-50%,-50%);
content: "";
}
/* #endif */
}
&--circle#{&}--checked {
background-color: $radio-icon-checked-color;
border-color: $radio-icon-checked-color;
/* #ifndef APP-ANDROID || APP-IOS */
&:after {
opacity: 1;
transform: rotate(45deg) scale(1) translate(-50%,-50%);
border-color: white;
}
/* #endif */
}
&--dot {
/* #ifndef APP-ANDROID || APP-IOS */
&:after {
background-color: white;
border-radius: $radio-icon-border-radius;
transform: scale(0) translate(-50%,-50%);
}
/* #endif */
}
&--dot#{&}--checked{
background-color: $radio-icon-checked-color;
/* #ifndef APP-ANDROID || APP-IOS */
border-color: $radio-icon-checked-color;
&:after{
opacity: 1;
width: 44%;
height: 44%;
transform: scale(1) translate(-50%,-50%);
}
/* #endif */
}
&--line {
/* #ifndef APP-ANDROID || APP-IOS */
&:after {
top: 46%;
left: 0%;
inset-inline-start: 10%;
display: table;
width: divide(100%, 14) * 7;
height: divide(100%, 14) * 12;
border: calc(#{$radio-icon-size} / 7) solid transparent;
border-top: 0;
border-inline-start: 0;
transform: rotate(45deg) scale(0) translate(-50%,-50%);
content: "";
transition-timing-function: cubic-bezier(0.78, 0.14, 0.15, 0.86);
}
/* #endif */
}
&--line#{&}--checked{
/* #ifndef APP-ANDROID || APP-IOS */
&:after{
opacity: 1;
transform: rotate(45deg) scale(1) translate(-50%,-50%);
border-color: $radio-icon-checked-color;
}
/* #endif */
}
&--circle#{&}--disabled, &--dot#{&}--disabled {
border-color: $radio-icon-disabled-color;
background-color: $radio-icon-disabled-bg-color;
}
&--circle#{&}--disabled#{&}--checked, &--dot#{&}--disabled#{&}--checked {
/* #ifndef APP-ANDROID || APP-IOS */
&:after {
border-color: $radio-icon-disabled-color;
}
/* #endif */
}
&--dot#{&}--disabled#{&}--checked {
/* #ifndef APP-ANDROID || APP-IOS */
&:after {
background-color: $radio-icon-disabled-color;
}
/* #endif */
}
&--line#{&}--disabled#{&}--checked {
/* #ifndef APP-ANDROID || APP-IOS */
&:after {
border-color: $radio-icon-disabled-color;
}
/* #endif */
}
}
&__label {
padding-left: $spacer-xs;
// padding-right: $spacer-xs;
font-size: $radio-font-size;
color: $text-color-1;
&--disabled {
color: $radio-icon-disabled-color;
}
}
}

+ 216
- 0
111/uni_modules/lime-radio/components/l-radio/l-radio.uvue View File

@ -0,0 +1,216 @@
<template>
<view class="l-radio" :class="classes" :style="[styles]" @click="onClick">
<slot name="radio" :checked="radioChecked" :disabled="isDisabled">
<slot name="icon" :checked="radioChecked" :disabled="isDisabled">
<view class="l-radio__icon" ref="iconRef" :class="iconClasses" :style="[iconStyle]"></view>
</slot>
<text class="l-radio__label" :class="labelClass" v-if="label != null || $slots['default'] != null">
<slot>{{label}}</slot>
</text>
</slot>
</view>
</template>
<script lang="uts" setup>
import { RadioProps } from './type';
// #ifndef APP
import type { ComputedRef } from 'vue';
type ComputedRefImpl<T> = ComputedRef<T>
// #endif
const emit = defineEmits(['change', 'update:checked'])
const props = withDefaults(defineProps<RadioProps>(), {
allowUncheck: false,
checked: false,
disabled: false,
icon: 'circle',
size: 'medium'
})
defineSlots<{
radio(props : { checked : boolean, disabled: boolean}) : any,
icon(props : { checked : boolean, disabled: boolean}) : any,
default(props : { checked : boolean, disabled: boolean}) : any,
}>()
const name = 'l-radio' const radioGroupProps = inject<LRadioGroupComponentPublicInstance|null>('limeRadioGroupProps', null); const radioGroupValue = inject<ComputedRefImpl<any>|null>('limeRadioGroupValue', null); const radioGroupChange = inject<((value: any|null) => void)|null>('limeRadioGroupChange', null);
const modelValue = defineModel({type: Boolean, default: false});
const innerChecked = computed({
set(value: boolean){
modelValue.value = value;
emit('change', value)
},
get(): boolean{
return props.checked || modelValue.value
},
} as WritableComputedOptions<boolean>)
const isDisabled = computed(():boolean => (props.disabled || (radioGroupProps?.disabled ?? false)))
const groupDisabled = computed(():boolean|null => radioGroupProps?.disabled);
const radioChecked = computed(():boolean => innerChecked.value || (props.name != null && props.name == radioGroupValue?.value) || (props.value != null && props.value == radioGroupValue?.value));
const finalAllowUncheck = computed(():boolean => props.allowUncheck || (radioGroupProps?.allowUncheck ?? false));
const innerIcon = computed(():string => radioGroupProps?.icon ?? props.icon)
const innerSize = computed(():string => radioGroupProps?.size ?? props.size)
const innerIconSize = computed(():string|null => radioGroupProps?.iconSize ?? props.iconSize)
const innerFontSize = computed(():string|null => radioGroupProps?.fontSize ?? props.fontSize)
const innerCheckedColor = computed(():string|null => radioGroupProps?.checkedColor ?? props.checkedColor)
const innerIconBgColor = computed(():string => props.iconBgColor ?? radioGroupProps?.iconBgColor ?? 'white')
const innerIconBorderColor = computed(():string => props.iconBorderColor ?? radioGroupProps?.iconBorderColor ?? '#c5c5c5')
const innerIconDisabledColor = computed(():string => props.iconDisabledColor ?? radioGroupProps?.iconDisabledColor ?? '#c5c5c5')
const innerIconDisabledBgColor = computed(():string => props.iconDisabledBgColor ?? radioGroupProps?.iconDisabledBgColor ?? '#f3f3f3')
const classes = computed(():Map<string, boolean>=>{
const cls = new Map<string, boolean>();
cls.set(`${name}--disabled`, isDisabled.value)
return cls
})
const iconClasses = computed(():Map<string, boolean>=>{
const cls = new Map<string, boolean>();
// #ifdef APP
cls.set(`${name}__icon--checked`, radioChecked.value && innerCheckedColor.value == null)
cls.set(`${name}__icon--${innerIcon.value}`, true)
cls.set(`${name}__icon--disabled`, isDisabled.value)
// #endif
// #ifndef APP
cls.set(`${name}__icon--checked`, radioChecked.value)
cls.set(`${name}__icon--${innerIcon.value}`, true)
cls.set(`${name}__icon--disabled`, isDisabled.value)
// #endif
return cls
})
const labelClass = computed(():Map<string, boolean>=>{
const cls = new Map<string, boolean>();
cls.set(`${name}__label--disabled`, isDisabled.value)
return cls
})
const styles = computed(():Map<string, any>=>{
const style = new Map<string, any>();
if(radioGroupProps != null && radioGroupProps.gap != null) {
style.set(radioGroupProps.direction == 'horizontal' ? 'margin-right' : 'margin-bottom', radioGroupProps.gap!)
}
// #ifndef APP
if(innerCheckedColor.value != null) {
style.set('--l-radio-icon-checked-color', innerCheckedColor.value!)
}
if(innerIconBorderColor.value != null) {
style.set('--l-radio-icon-border-color', innerIconBorderColor.value!)
}
if(innerIconDisabledColor.value != null) {
style.set('--l-radio-icon-disabled-color', innerIconDisabledColor.value!)
}
if(innerIconDisabledBgColor.value != null) {
style.set('--l-radio-icon-disabled-bg-color', innerIconDisabledBgColor.value!)
}
if(innerFontSize.value != null) {
style.set('--l-radio-font-size', innerFontSize.value!)
}
// #endif
return style
})
const iconStyle = computed(():Map<string, any>=>{
const style = new Map<string, any>();
if(innerIconSize.value != null) {
style.set('width', innerIconSize.value!)
style.set('height', innerIconSize.value!)
// #ifndef APP
style.set('--l-radio-icon-size', innerIconSize.value!)
// #endif
}
if(innerCheckedColor.value != null) {
// #ifndef APP
style.set('--l-radio-icon-checked-color', innerCheckedColor.value!)
// #endif
// #ifdef APP
if(radioChecked.value && ['dot', 'circle'].includes(innerIcon.value)) {
style.set('background', innerCheckedColor.value!)
style.set('border-color', innerCheckedColor.value!)
}
if(!isDisabled.value && !radioChecked.value && ['dot', 'circle'].includes(innerIcon.value)) {
style.set('background', innerIconBgColor.value)
style.set('border-color', innerIconBorderColor.value)
}
if(isDisabled.value && ['dot', 'circle'].includes(innerIcon.value)) {
style.set('background', innerIconDisabledBgColor.value)
style.set('border-color', innerIconDisabledColor.value)
}
// #endif
}
return style
})
const labelStyle = computed(():Map<string, any>=>{
const style = new Map<string, any>();
const fontSize = props.fontSize ?? radioGroupProps?.fontSize
if(fontSize != null) {
style.set('font-size', fontSize)
}
return style
})
const onClick = (e: UniPointerEvent) => {
if(isDisabled.value) return;
const _name = props.value ?? props.name
if(radioGroupChange != null && _name != null) {
const value = finalAllowUncheck.value && radioChecked.value ? null : _name;
radioGroupChange(value);
} else {
const value = finalAllowUncheck.value ? !radioChecked.value : true;
innerChecked.value = value
}
}
// #ifdef APP
const iconRef = ref<UniElement|null>(null)
const update = () => {
if(iconRef.value == null) return
const ctx = iconRef.value!.getDrawableContext()!;
const rect = iconRef.value!.getBoundingClientRect();
const x = rect.width / 2;
const y = rect.height / 2;
ctx.reset();
if(innerIcon.value == 'circle') {
if(radioChecked.value) {
ctx.strokeStyle = isDisabled.value ? innerIconDisabledColor.value : 'white';
ctx.lineWidth = rect.width * 0.12;
ctx.lineCap = 'round';
ctx.moveTo(rect.width * 0.2967, rect.height * 0.53)
ctx.lineTo(rect.width * 0.4342, rect.height * 0.6675)
ctx.lineTo(rect.width * 0.7092, rect.height * 0.3925)
ctx.stroke()
}
} else if(innerIcon.value == 'line') {
if(radioChecked.value) {
ctx.strokeStyle = isDisabled.value ? innerIconDisabledColor.value : props.checkedColor ?? '#3283ff';
ctx.lineWidth = rect.width * 0.16;
ctx.lineCap = 'round';
ctx.moveTo(rect.width * 0.10, rect.height * 0.5466)
ctx.lineTo(rect.width * 0.3666, rect.height * 0.8134)
ctx.lineTo(rect.width * 0.90, rect.height * 0.28)
ctx.stroke()
}
} else if(innerIcon.value == 'dot'){
if(radioChecked.value) {
ctx.fillStyle = isDisabled.value ? innerIconDisabledColor.value : 'white';
ctx.arc(x, y, rect.width * 0.22, 0, Math.PI * 2)
ctx.fill()
}
}
ctx.update();
}
watchEffect(update)
onMounted(()=>{
nextTick(update)
})
// #endif
</script>
<style lang="scss">
@import './index-u';
</style>

+ 128
- 0
111/uni_modules/lime-radio/components/l-radio/l-radio.vue View File

@ -0,0 +1,128 @@
<template>
<view class="l-radio" :class="{'l-radio--disabled': isDisabled}" :style="[styles]" @click="onClick">
<slot name="radio" :checked="radioChecked" :disabled="isDisabled">
<slot name="icon" :checked="radioChecked" :disabled="isDisabled">
<view class="l-radio__icon" ref="iconRef"
:class="['l-radio__icon--' + innerIcon, {
'l-radio__icon--checked': radioChecked,
'l-radio__icon--disabled': isDisabled
}]" :style="[iconStyle]"></view>
</slot>
<view class="l-radio__label" :class="{'l-radio__label--disabled': isDisabled}" v-if="label || $slots['default']">
<slot>{{label}}</slot>
</view>
</slot>
</view>
</template>
<script lang="ts">
//@ts-nocheck
import { defineComponent, computed, inject, Ref , ref} from '@/uni_modules/lime-shared/vue';
import { RadioValue, LRadioProps } from './type'
import radioProps from './props'
const name = 'l-radio'
export default defineComponent({
name,
props: radioProps,
emits: ['update:checked', 'update:modelValue', 'change', 'input'],
setup(props, { emit }) {
const radioGroupProps = inject<LRadioGroupComponentPublicInstance|null>('limeRadioGroupProps', null);
const radioGroupValue = inject<ComputedRefImpl<any>|null>('limeRadioGroupValue', null);
const radioGroupChange = inject<((value: any|null) => void)|null>('limeRadioGroupChange', null);
const modelValue = ref(props.checked || props.modelValue)
const innerChecked = computed({
set(value: boolean){
modelValue.value = value;
emit('update:modelValue', value)
emit('change', value)
// #ifdef VUE2
emit('input', value)
// #endif
},
get(): boolean{
return props.checked || props.modelValue || modelValue.value
},
} as WritableComputedOptions<boolean>)
const isDisabled = computed(():boolean => (props.disabled || (radioGroupProps?.disabled)))
const radioChecked = computed(():boolean => innerChecked.value || (props.name && props.name == radioGroupValue?.value) || (props.value && props.value == radioGroupValue?.value));
const finalAllowUncheck = computed(():boolean => props.allowUncheck || (radioGroupProps?.allowUncheck));
const innerIcon = computed(():string => radioGroupProps?.icon || props.icon)
const innerSize = computed(():string => radioGroupProps?.size || props.size)
const innerIconSize = computed(():string|null => radioGroupProps?.iconSize || props.iconSize)
const innerFontSize = computed(():string|null => radioGroupProps?.fontSize || props.fontSize)
const innerCheckedColor = computed(():string|null => radioGroupProps?.checkedColor || props.checkedColor)
const innerIconBgColor = computed(():string => props.iconBgColor || radioGroupProps?.iconBgColor)
const innerIconBorderColor = computed(():string => props.iconBorderColor || radioGroupProps?.iconBorderColor )
const innerIconDisabledColor = computed(():string => props.iconDisabledColor || radioGroupProps?.iconDisabledColor)
const innerIconDisabledBgColor = computed(():string => props.iconDisabledBgColor || radioGroupProps?.iconDisabledBgColor)
const styles = computed(()=>{
const style:Record<string, any> = {};
if(radioGroupProps&& radioGroupProps.gap) {
style[radioGroupProps.direction == 'horizontal' ? 'margin-right' : 'margin-bottom'] = radioGroupProps.gap!
}
if(innerCheckedColor.value) {
style['--l-radio-icon-checked-color'] = innerCheckedColor.value!
}
if(innerIconBorderColor.value) {
style['--l-radio-icon-border-color'] = innerIconBorderColor.value!
}
if(innerIconDisabledColor.value) {
style['--l-radio-icon-disabled-color'] = innerIconDisabledColor.value!
}
if(innerIconDisabledBgColor.value) {
style['--l-radio-icon-disabled-bg-color'] = innerIconDisabledBgColor.value!
}
if(innerFontSize.value) {
style['--l-radio-font-size'] = innerFontSize.value!
}
if(innerIconBgColor.value) {
style['--l-radio-icon-bg-color'] = innerIconBgColor.value!
}
return style
})
const iconStyle = computed(()=>{
const style:Record<string, any> = {}
if(innerIconSize.valuel) {
style['width'] = innerIconSize.value!
style['height'] = innerIconSize.value!
style['--l-radio-icon-size'] = innerIconSize.value!
}
return style
})
const onClick = (e: UniPointerEvent) => {
if(isDisabled.value) return;
const _name = props.value || props.name
if(radioGroupChange && _name) {
const value = finalAllowUncheck.value && radioChecked.value ? null : _name;
radioGroupChange(value);
} else {
const value = finalAllowUncheck.value ? !radioChecked.value : true;
innerChecked.value = value
}
}
return {
styles,
innerChecked,
iconStyle,
innerIcon,
radioChecked,
isDisabled,
onClick,
}
}
});
</script>
<style lang="scss">
@import './index-u';
</style>

+ 70
- 0
111/uni_modules/lime-radio/components/l-radio/props.ts View File

@ -0,0 +1,70 @@
export default {
/** 是否允许取消选中 */
allowUncheck: Boolean,
/** 是否选中 */
checked: {
type: Boolean,
default: null,
},
modelValue: {
type: Boolean,
default: null,
},
/** 是否选中,非受控属性 */
defaultChecked: Boolean,
/** 是否为禁用态。如果存在父组件 RadioGroup,默认值由 RadioGroup.disabled 控制。Radio.disabled 优先级高于 RadioGroup.disabled */
disabled: {
type: Boolean,
default: false,
},
/** 主文案 */
label: {
type: String,
},
/** 唯一名称 */
name: {
type: [String, Number],
default: null,
},
/** 单选按钮的值 */
value: {
type: [String, Number, Boolean],//as PropType<TdRadioProps['value']>,
default: null,
},
checkedColor: {
type: String,
default: null
},
iconBgColor: {
type: String,
default: null
},
iconBorderColor: {
type: String,
default: null
},
iconDisabledColor: {
type: String,
default: null
},
iconDisabledBgColor: {
type: String,
default: null
},
icon: {
type: String,
default: 'circle'
}, //?: 'circle' | 'line' | 'dot';
size: {
type: String,
default: 'medium'
}, //?: 'small' | 'medium' | 'large';
iconSize: {
type: String,
defalut: null
},
fontSize: {
type: String,
defalut: null
},
}

+ 49
- 0
111/uni_modules/lime-radio/components/l-radio/type.ts View File

@ -0,0 +1,49 @@
// @ts-nocheck
export type RadioValue = any//string | number | boolean;
export interface RadioProps {
/**
*
*/
allowUncheck : boolean;
/**
*
*/
checked : boolean;
/**
*
*/
defaultChecked ?: boolean;
/**
*
*/
// modelValue ?: boolean;
/**
* RadioGroup RadioGroup.disabled Radio.disabled RadioGroup.disabled
*/
disabled : boolean;
/**
* []使 String circle line dot
*/
icon: 'circle' | 'line' | 'dot' //| string[];
// icon ?: 'circle' | 'line' | 'dot';
/**
*
*/
label ?: string;
/**
*
*/
name ?: string;
value ?: RadioValue;
size: 'small' | 'medium' | 'large'
fontSize ?: string;
iconSize?: string;
checkedColor?: string;
iconBgColor?: string;
iconBorderColor?: string;
iconDisabledColor?: string;
iconDisabledBgColor?: string;
}
type ComputedRefImpl<T> = ComputedRef<T>

+ 181
- 0
111/uni_modules/lime-radio/components/lime-radio/lime-radio.uvue View File

@ -0,0 +1,181 @@
<template>
<view class="demo-block">
<text class="demo-block__title-text ultra">单选框</text>
<text class="demo-block__desc-text" style="display: flex;">在一组备选项中进行单选。</text>
<view class="demo-block__body">
<view class="demo-block card">
<text class="demo-block__title-text">基本用法</text>
<view class="demo-block__body">
<l-radio allowUncheck>单选框</l-radio>
</view>
</view>
<view class="demo-block card">
<text class="demo-block__title-text">选项组</text>
<view class="demo-block__body">
<l-radio-group @change="onChange">
<l-radio style="margin-bottom:20px; margin-right: 20px;" value="Beijing" label="北京" />
<l-radio style="margin-bottom:20px; margin-right: 20px;" value="Shanghai" label="上海" />
<l-radio style="margin-bottom:20px; margin-right: 20px;" value="Guangzhou" label="广州" />
<l-radio style="margin-bottom:20px; margin-right: 20px;" value="Shenzen" label="深圳" />
</l-radio-group>
</view>
</view>
<view class="demo-block card">
<text class="demo-block__title-text">禁用</text>
<view class="demo-block__body">
<l-radio-group @change="onChange" disabled>
<l-radio style="margin-bottom:20px;margin-right: 20px;" value="Beijing" label="北京" />
<l-radio style="margin-bottom:20px;margin-right: 20px;" value="Shanghai" label="上海" />
<l-radio style="margin-bottom:20px;margin-right: 20px;" value="Guangzhou" label="广州" />
<l-radio style="margin-bottom:20px;margin-right: 20px;" value="Shenzen" label="深圳" />
</l-radio-group>
</view>
</view>
<view class="demo-block card">
<text class="demo-block__title-text">样式</text>
<view class="demo-block__body">
<l-radio-group @change="onChange" icon="dot">
<l-radio style="margin-bottom:20px; margin-right: 20px;" value="Beijing" label="北京" />
<l-radio style="margin-bottom:20px; margin-right: 20px;" value="Guangzhou" label="广州" />
<l-radio style="margin-bottom:20px; margin-right: 20px;" value="Shenzen" label="深圳" />
</l-radio-group>
<l-radio-group @change="onChange" icon="line">
<l-radio style="margin-bottom:20px; margin-right: 20px;" value="Beijing" label="北京" />
<l-radio style="margin-bottom:20px; margin-right: 20px;" value="Guangzhou" label="广州" />
<l-radio style="margin-bottom:20px; margin-right: 20px;" value="Shenzen" label="深圳" />
</l-radio-group>
</view>
</view>
<view class="demo-block card">
<text class="demo-block__title-text">自定义颜色</text>
<view class="demo-block__body">
<l-radio-group @change="onChange" checked-color="#ee0a24">
<l-radio style="margin-bottom:20px; margin-right: 20px;" value="Beijing" label="北京" />
<l-radio style="margin-bottom:20px; margin-right: 20px;" value="Guangzhou" label="广州" />
<l-radio style="margin-bottom:20px; margin-right: 20px;" value="Shenzen" label="深圳" />
</l-radio-group>
</view>
</view>
<view class="demo-block card">
<text class="demo-block__title-text">自定义大小</text>
<view class="demo-block__body">
<l-radio-group @change="onChange" checked-color="#ee0a24">
<l-radio style="margin-bottom:20px; margin-right: 20px;" icon-size="44px" value="Beijing" label="北京" />
<l-radio style="margin-bottom:20px; margin-right: 20px;" icon-size="34px" value="Guangzhou" label="广州" />
<l-radio style="margin-bottom:20px; margin-right: 20px;" icon-size="24px" value="Shenzen" label="深圳" />
</l-radio-group>
</view>
</view>
<view class="demo-block card">
<text class="demo-block__title-text">自定义图标</text>
<view class="demo-block__body">
<l-radio-group @change="onChange" checked-color="#ee0a24">
<l-radio style="margin-bottom:20px; margin-right: 20px;" value="Beijing" label="北京">
<template #icon="{checked}">
<image v-show="checked" style="width:20px; height:20px" src="https://fastly.jsdelivr.net/npm/@vant/assets/user-active.png"></image>
<image v-show="!checked" style="width:20px; height:20px" src="https://fastly.jsdelivr.net/npm/@vant/assets/user-inactive.png"></image>
</template>
</l-radio>
<l-radio style="margin-bottom:20px; margin-right: 20px;" value="Guangzhou" label="广州">
<template #icon="{checked}">
<image v-show="checked" style="width:20px; height:20px" src="https://fastly.jsdelivr.net/npm/@vant/assets/user-active.png"></image>
<image v-show="!checked" style="width:20px; height:20px" src="https://fastly.jsdelivr.net/npm/@vant/assets/user-inactive.png"></image>
</template>
</l-radio>
<l-radio style="margin-bottom:20px" value="Shenzen" label="深圳">
<template #icon="{checked}">
<image v-show="checked" style="width:20px; height:20px" src="https://fastly.jsdelivr.net/npm/@vant/assets/user-active.png"></image>
<image v-show="!checked" style="width:20px; height:20px" src="https://fastly.jsdelivr.net/npm/@vant/assets/user-inactive.png"></image>
</template>
</l-radio>
</l-radio-group>
</view>
</view>
</view>
</view>
</template>
<script lang="uts" setup>
// const checked = ref(false)
// const disabled = ref(false)
const onChange = (e: any) => {
console.log('e', e)
}
</script>
<style lang="scss">
.row {
flex-direction: row;
flex-wrap: wrap;
}
.custom-radio {
padding: 20rpx 30rpx;
border-radius: 5rpx;
border: 1rpx solid #ddd;
transition: background-color 0.3s;
color: black;
&.checked {
background-color: #007aff;
color: white;
border-color: #007aff;
}
}
.demo-block {
margin: 32px 10px 0;
// overflow: visible;
&.card {
background-color: white;
padding: 30rpx;
margin-bottom: 20rpx !important;
}
&__title {
margin: 0;
margin-top: 8px;
&-text {
color: rgba(0, 0, 0, 0.6);
font-weight: 400;
font-size: 14px;
line-height: 16px;
&.large {
color: rgba(0, 0, 0, 0.9);
font-size: 18px;
font-weight: 700;
line-height: 26px;
}
&.ultra {
color: rgba(0, 0, 0, 0.9);
font-size: 24px;
font-weight: 700;
line-height: 32px;
}
}
}
&__desc-text {
color: rgba(0, 0, 0, 0.6);
margin: 8px 16px 0 0;
font-size: 14px;
line-height: 22px;
}
&__body {
margin: 16px 0;
overflow: visible;
.demo-block {
// margin-top: 0px;
margin: 0;
}
}
}
</style>

+ 189
- 0
111/uni_modules/lime-radio/components/lime-radio/lime-radio.vue View File

@ -0,0 +1,189 @@
<template>
<view class="demo-block">
<text class="demo-block__title-text ultra">单选框</text>
<text class="demo-block__desc-text" style="display: flex;">在一组备选项中进行单选</text>
<view class="demo-block__body">
<view class="demo-block card">
<text class="demo-block__title-text">基本用法</text>
<view class="demo-block__body">
<l-radio allowUncheck>单选框</l-radio>
</view>
</view>
<view class="demo-block card">
<text class="demo-block__title-text">选项组</text>
<view class="demo-block__body">
<l-radio-group @change="onChange">
<l-radio style="margin-bottom:20px; margin-right:20px" name="Beijing" label="北京" />
<l-radio style="margin-bottom:20px; margin-right:20px" name="Shanghai" label="上海" />
<l-radio style="margin-bottom:20px; margin-right:20px" name="Guangzhou" label="广州" />
<l-radio style="margin-bottom:20px; margin-right:20px" name="Shenzen" label="深圳" />
</l-radio-group>
</view>
</view>
<view class="demo-block card">
<text class="demo-block__title-text">禁用</text>
<view class="demo-block__body">
<l-radio-group @change="onChange" disabled>
<l-radio style="margin-bottom:20px; margin-right:20px" name="Beijing" label="北京" />
<l-radio style="margin-bottom:20px; margin-right:20px" name="Shanghai" label="上海" />
<l-radio style="margin-bottom:20px; margin-right:20px" name="Guangzhou" label="广州" />
<l-radio style="margin-bottom:20px; margin-right:20px" name="Shenzen" label="深圳" />
</l-radio-group>
</view>
</view>
<view class="demo-block card">
<text class="demo-block__title-text">样式</text>
<view class="demo-block__body">
<l-radio-group @change="onChange" icon="dot">
<l-radio style="margin-bottom:20px; margin-right:20px" name="Beijing" label="北京" />
<l-radio style="margin-bottom:20px; margin-right:20px" name="Guangzhou" label="广州" />
<l-radio style="margin-bottom:20px; margin-right:20px" name="Shenzen" label="深圳" />
</l-radio-group>
<l-radio-group @change="onChange" icon="line">
<l-radio style="margin-bottom:20px; margin-right:20px" name="Beijing" label="北京" />
<l-radio style="margin-bottom:20px; margin-right:20px" name="Guangzhou" label="广州" />
<l-radio style="margin-bottom:20px; margin-right:20px" name="Shenzen" label="深圳" />
</l-radio-group>
</view>
</view>
<view class="demo-block card">
<text class="demo-block__title-text">自定义颜色</text>
<view class="demo-block__body">
<l-radio-group @change="onChange" checked-color="#ee0a24">
<l-radio style="margin-bottom:20px; margin-right:20px" name="Beijing" label="北京" />
<l-radio style="margin-bottom:20px; margin-right:20px" name="Guangzhou" label="广州" />
<l-radio style="margin-bottom:20px; margin-right:20px" name="Shenzen" label="深圳" />
</l-radio-group>
</view>
</view>
<view class="demo-block card">
<text class="demo-block__title-text">自定义大小</text>
<view class="demo-block__body">
<l-radio-group @change="onChange" checked-color="#ee0a24">
<l-radio style="margin-bottom:20px; margin-right:20px" icon-size="44px" name="Beijing" label="北京" />
<l-radio style="margin-bottom:20px; margin-right:20px" icon-size="34px" name="Guangzhou" label="广州" />
<l-radio style="margin-bottom:20px; margin-right:20px" icon-size="24px" name="Shenzen" label="深圳" />
</l-radio-group>
</view>
</view>
<view class="demo-block card">
<text class="demo-block__title-text">自定义图标</text>
<view class="demo-block__body">
<l-radio-group @change="onChange" checked-color="#ee0a24">
<l-radio style="margin-bottom:20px; margin-right:20px" name="Beijing" label="北京">
<template #icon="{checked}">
<image v-show="checked" style="width:20px; height:20px" src="https://fastly.jsdelivr.net/npm/@vant/assets/user-active.png"></image>
<image v-show="!checked" style="width:20px; height:20px" src="https://fastly.jsdelivr.net/npm/@vant/assets/user-inactive.png"></image>
</template>
</l-radio>
<l-radio style="margin-bottom:20px; margin-right:20px" name="Guangzhou" label="广州">
<template #icon="{checked}">
<image v-show="checked" style="width:20px; height:20px" src="https://fastly.jsdelivr.net/npm/@vant/assets/user-active.png"></image>
<image v-show="!checked" style="width:20px; height:20px" src="https://fastly.jsdelivr.net/npm/@vant/assets/user-inactive.png"></image>
</template>
</l-radio>
<l-radio style="margin-bottom:20px; margin-right:20px" name="Shenzen" label="深圳">
<template #icon="{checked}">
<image v-show="checked" style="width:20px; height:20px" src="https://fastly.jsdelivr.net/npm/@vant/assets/user-active.png"></image>
<image v-show="!checked" style="width:20px; height:20px" src="https://fastly.jsdelivr.net/npm/@vant/assets/user-inactive.png"></image>
</template>
</l-radio>
</l-radio-group>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
onChange(v) {
console.log('?', v)
}
},
mounted() {
}
}
</script>
<style lang="scss">
.row {
flex-direction: row;
flex-wrap: wrap;
}
.custom-radio {
padding: 20rpx 30rpx;
border-radius: 5rpx;
border: 1rpx solid #ddd;
transition: background-color 0.3s;
color: black;
&.checked {
background-color: #007aff;
color: white;
border-color: #007aff;
}
}
.demo-block {
margin: 32px 10px 0;
// overflow: visible;
&.card {
background-color: white;
padding: 30rpx;
margin-bottom: 20rpx !important;
}
&__title {
margin: 0;
margin-top: 8px;
&-text {
color: rgba(0, 0, 0, 0.6);
font-weight: 400;
font-size: 14px;
line-height: 16px;
&.large {
color: rgba(0, 0, 0, 0.9);
font-size: 18px;
font-weight: 700;
line-height: 26px;
}
&.ultra {
color: rgba(0, 0, 0, 0.9);
font-size: 24px;
font-weight: 700;
line-height: 32px;
}
}
}
&__desc-text {
color: rgba(0, 0, 0, 0.6);
margin: 8px 16px 0 0;
font-size: 14px;
line-height: 22px;
}
&__body {
margin: 16px 0;
overflow: visible;
.demo-block {
// margin-top: 0px;
margin: 0;
}
}
}
</style>

+ 89
- 0
111/uni_modules/lime-radio/package.json View File

@ -0,0 +1,89 @@
{
"id": "lime-radio",
"displayName": "lime-radio 单选框",
"version": "0.0.7",
"description": "lime-radio 在一组备选项中进行单选,支持自定义大小,自定义图标等,兼容uniapp/uniappx",
"keywords": [
"lime-radio",
"radio",
"单选框"
],
"repository": "",
"engines": {
"HBuilderX": "^4.34"
},
"dcloudext": {
"type": "component-vue",
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": ""
},
"uni_modules": {
"dependencies": [
"lime-style",
"lime-shared"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y",
"alipay": "y"
},
"client": {
"Vue": {
"vue2": "u",
"vue3": "y"
},
"App": {
"app-vue": "y",
"app-nvue": "u",
"app-uvue": "y",
"app-harmony": "u"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "u",
"IE": "u",
"Edge": "u",
"Firefox": "u",
"Safari": "u"
},
"小程序": {
"微信": "y",
"阿里": "u",
"百度": "u",
"字节跳动": "u",
"QQ": "u",
"钉钉": "u",
"快手": "u",
"飞书": "u",
"京东": "u"
},
"快应用": {
"华为": "u",
"联盟": "u"
}
}
}
}
}

+ 199
- 0
111/uni_modules/lime-radio/readme.md View File

@ -0,0 +1,199 @@
# lime-radio 单选框
- 在一组备选项中进行单选。
## 安装
在插件市场导入即可,首次导入可能需要重新编译
## 代码演示
### 基础演示
通过`allowUncheck`可设置单个是否允许取消选中
```html
<l-radio allowUncheck>单选框</l-radio>
```
### 选项组
通过 v-model 绑定值当前选中项的 `value`或`name`,vue2使用的`value`被占用,故可以使用`name`。
```html
<l-radio-group v-model="checked" @change="onChange">
<l-radio value="Beijing" label="北京" />
<l-radio value="Shanghai" label="上海" />
<l-radio value="Guangzhou" label="广州" />
<l-radio value="Shenzen" label="深圳" />
</l-radio-group>
<!-- vue2使用的`value`被占用,故可以使用`name` -->
<l-radio-group v-model="checked" @change="onChange">
<l-radio name="Beijing" label="北京" />
<l-radio name="Shanghai" label="上海" />
<l-radio name="Guangzhou" label="广州" />
<l-radio name="Shenzen" label="深圳" />
</l-radio-group>
```
```js
const checked = ref('Beijing');
```
### 禁用
通过 `disabled` 属性禁止选项切换,在 Radio 上设置 `disabled` 可以禁用单个选项。
```html
<l-radio-group v-model="checked" disabled>
<l-radio value="Beijing" label="北京" />
<l-radio value="Shanghai" label="上海" />
<l-radio value="Guangzhou" label="广州" />
<l-radio value="Shenzen" label="深圳" />
</l-radio-group>
```
### 样式
`icon` 属性可选值为 `line``dot`,单选框形状分别对应线勾和圆点形。
```html
<l-radio-group icon="dot">
<l-radio value="Beijing" label="北京" />
<l-radio value="Guangzhou" label="广州" />
<l-radio value="Shenzen" label="深圳" />
</l-radio-group>
<l-radio-group icon="line">
<l-radio value="Beijing" label="北京" />
<l-radio value="Guangzhou" label="广州" />
<l-radio value="Shenzen" label="深圳" />
</l-radio-group>
```
### 自定义颜色
通过 `checked-color` 属性设置选中状态的图标颜色。
```html
<l-radio-group checked-color="#ee0a24">
<l-radio value="Beijing" label="北京" />
<l-radio value="Guangzhou" label="广州" />
<l-radio value="Shenzen" label="深圳" />
</l-radio-group>
```
### 自定义大小
通过 `icon-size` 属性可以自定义图标的大小。
```html
<l-radio-group>
<l-radio icon-size="44px" value="Beijing" label="北京" />
<l-radio icon-size="34px" value="Guangzhou" label="广州" />
<l-radio icon-size="24px" value="Shenzen" label="深圳" />
</l-radio-group>
```
### 自定义图标
通过 icon 插槽自定义图标,并通过 slotProps 判断是否为选中状态。
```html
<l-radio-group>
<l-radio value="Beijing" label="北京">
<template #icon="{checked}">
<image v-show="checked" style="width:20px; height:20px" src="https://fastly.jsdelivr.net/npm/@vant/assets/user-active.png"></image>
<image v-show="!checked" style="width:20px; height:20px" src="https://fastly.jsdelivr.net/npm/@vant/assets/user-inactive.png"></image>
</template>
</l-radio>
<l-radio value="Guangzhou" label="广州">
<template #icon="{checked}">
<image v-show="checked" style="width:20px; height:20px" src="https://fastly.jsdelivr.net/npm/@vant/assets/user-active.png"></image>
<image v-show="!checked" style="width:20px; height:20px" src="https://fastly.jsdelivr.net/npm/@vant/assets/user-inactive.png"></image>
</template>
</l-radio>
<l-radio value="Shenzen" label="深圳">
<template #icon="{checked}">
<image v-show="checked" style="width:20px; height:20px" src="https://fastly.jsdelivr.net/npm/@vant/assets/user-active.png"></image>
<image v-show="!checked" style="width:20px; height:20px" src="https://fastly.jsdelivr.net/npm/@vant/assets/user-inactive.png"></image>
</template>
</l-radio>
</l-radio-group>
```
### 插件标签
- 默认 l-radio 为 component
- 默认 lime-radio 为 demo
### 关于vue2的使用方式
- 插件使用了`composition-api`, 如果你希望在vue2中使用请按官方的教程[vue-composition-api](https://uniapp.dcloud.net.cn/tutorial/vue-composition-api.html)配置
- 关键代码是: 在main.js中 在vue2部分加上这一段即可.
```js
// vue2
import Vue from 'vue'
import VueCompositionAPI from '@vue/composition-api'
Vue.use(VueCompositionAPI)
```
## API
### Radio Props
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| name | 标识符,通常为一个唯一的字符串或数字 | _string\|number_ | - |
| value | 单选按钮的值 | _any_ | - |
| allowUncheck | 是否允许取消选中 | _boolean_ | `false` |
| checked | 是否选中 | _boolean_ | `false` |
| disabled | 是否为禁用态 | _boolean_ | `false` |
| icon | 自定义选中图标和非选中图标可选值`'circle' | 'line' | 'dot'` | _string_ | `circle` |
| label | 主文案 | _string_ | `` |
| fontSize | 文本大小 | _string_ | `` |
| iconSize | 图标大小 | _string_ | `` |
| checkedColor | 选中状态颜色 | _string_ | `` |
| iconBgColor | 图标背景颜色 | _string_ | `` |
| iconBorderColor | 图标描边颜色 | _string_ | `` |
| iconDisabledColor | 图标禁用颜色 | _string_ | `` |
| iconDisabledBgColor | 图标禁用背景颜色 | _string_ | `` |
### RadioGroup Props
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| v-model | 标识符,通常为一个唯一的字符串或数字 | _string\|number_ | - |
| name | 标识符,通常为一个唯一的字符串或数字 | _string\|number_ | - |
| value | 单选按钮的值 | _any_ | - |
| allowUncheck | 是否允许取消选中 | _boolean_ | `false` |
| disabled | 是否为禁用态 | _boolean_ | `false` |
| direction | 排列方向,可选值为vertical | _string_ | `horizontal` |
| fontSize | 文本大小 | _string_ | `` |
| iconSize | 图标大小 | _string_ | `` |
| checkedColor | 选中状态颜色 | _string_ | `` |
| iconBgColor | 图标背景颜色 | _string_ | `` |
| iconBorderColor | 图标描边颜色 | _string_ | `` |
| iconDisabledColor | 图标禁用颜色 | _string_ | `` |
| iconDisabledBgColor | 图标禁用背景颜色 | _string_ | `` |
### Events
| 事件名 | 说明 | 回调参数 |
| ------ | ------------------------ | ---------------------- |
| change | 当绑定值变化时触发的事件 | _currentValue: any_ |
### Radio Slots
| 插槽名 | 说明 | 回调参数 |
| ------ | ------------------------ | ---------------------- |
| default | 自定义文本 | _-_ |
| radio | 整体 | _{ checked: boolean, disabled: boolean }_ |
| icon | 自定义图标 | _{ checked: boolean, disabled: boolean }_ |
## 主题定制
### 样式变量
组件提供了下列 CSS 变量,可用于自定义样式,uvue app无效。
| 名称 | 默认值 | 描述 |
| ------------------------ | -------------------- | ---- |
| --l-radio-icon-size | _40rpx_ | - |
| --l-radio-font-size | _32rpx_ | - |
| --l-radio-icon-bg-color | _white_ | - |
| --l-radio-border-icon-color | _$gray-5_ | - |
| --l-radio-icon-disabled-color | _$gray-5_ | - |
| --l-radio-icon-disabled-bg-color | _$gray-1_ | - |
| --l-radio-icon-checked-color | _$primary-color_ | - |
## 打赏
如果你觉得本插件,解决了你的问题,赠人玫瑰,手留余香。
![](https://testingcf.jsdelivr.net/gh/liangei/image@1.9/alipay.png)
![](https://testingcf.jsdelivr.net/gh/liangei/image@1.9/wpay.png)

+ 42
- 0
111/uni_modules/lime-shared/addUnit/index.ts View File

@ -0,0 +1,42 @@
// @ts-nocheck
import {isNumeric} from '../isNumeric'
import {isDef} from '../isDef'
/**
* px
* @param value
* @returns null null
*/
// #ifndef UNI-APP-X && APP
export function addUnit(value?: string | number): string | null {
if (!isDef(value)) {
return null;
}
value = String(value); // 将值转换为字符串
// 如果值是数字,则在后面添加单位 "px",否则保持原始值
return isNumeric(value) ? `${value}px` : value;
}
// #endif
// #ifdef UNI-APP-X && APP
function addUnit(value: string): string
function addUnit(value: number): string
function addUnit(value: any|null): string|null {
if (!isDef(value)) {
return null;
}
value = `${value}` //value.toString(); // 将值转换为字符串
// 如果值是数字,则在后面添加单位 "px",否则保持原始值
return isNumeric(value) ? `${value}px` : value;
}
export {addUnit}
// #endif
// console.log(addUnit(100)); // 输出: "100px"
// console.log(addUnit("200")); // 输出: "200px"
// console.log(addUnit("300px")); // 输出: "300px"(已经包含单位)
// console.log(addUnit()); // 输出: undefined(值为 undefined)
// console.log(addUnit(null)); // 输出: undefined(值为 null)

+ 82
- 0
111/uni_modules/lime-shared/animation/bezier.ts View File

@ -0,0 +1,82 @@
export function cubicBezier(p1x : number, p1y : number, p2x : number, p2y : number):(x: number)=> number {
const ZERO_LIMIT = 1e-6;
// Calculate the polynomial coefficients,
// implicit first and last control points are (0,0) and (1,1).
const ax = 3 * p1x - 3 * p2x + 1;
const bx = 3 * p2x - 6 * p1x;
const cx = 3 * p1x;
const ay = 3 * p1y - 3 * p2y + 1;
const by = 3 * p2y - 6 * p1y;
const cy = 3 * p1y;
function sampleCurveDerivativeX(t : number) : number {
// `ax t^3 + bx t^2 + cx t` expanded using Horner's rule
return (3 * ax * t + 2 * bx) * t + cx;
}
function sampleCurveX(t : number) : number {
return ((ax * t + bx) * t + cx) * t;
}
function sampleCurveY(t : number) : number {
return ((ay * t + by) * t + cy) * t;
}
// Given an x value, find a parametric value it came from.
function solveCurveX(x : number) : number {
let t2 = x;
let derivative : number;
let x2 : number;
// https://trac.webkit.org/browser/trunk/Source/WebCore/platform/animation
// first try a few iterations of Newton's method -- normally very fast.
// http://en.wikipedia.org/wikiNewton's_method
for (let i = 0; i < 8; i++) {
// f(t) - x = 0
x2 = sampleCurveX(t2) - x;
if (Math.abs(x2) < ZERO_LIMIT) {
return t2;
}
derivative = sampleCurveDerivativeX(t2);
// == 0, failure
/* istanbul ignore if */
if (Math.abs(derivative) < ZERO_LIMIT) {
break;
}
t2 -= x2 / derivative;
}
// Fall back to the bisection method for reliability.
// bisection
// http://en.wikipedia.org/wiki/Bisection_method
let t1 = 1;
/* istanbul ignore next */
let t0 = 0;
/* istanbul ignore next */
t2 = x;
/* istanbul ignore next */
while (t1 > t0) {
x2 = sampleCurveX(t2) - x;
if (Math.abs(x2) < ZERO_LIMIT) {
return t2;
}
if (x2 > 0) {
t1 = t2;
} else {
t0 = t2;
}
t2 = (t1 + t0) / 2;
}
// Failure
return t2;
}
return function (x : number) : number {
return sampleCurveY(solveCurveX(x));
}
// return solve;
}

+ 3
- 0
111/uni_modules/lime-shared/animation/ease.ts View File

@ -0,0 +1,3 @@
import {cubicBezier} from './bezier';
export let ease = cubicBezier(0.25, 0.1, 0.25, 1);
export let linear = cubicBezier(0,0,1,1);

+ 10
- 0
111/uni_modules/lime-shared/animation/index.ts View File

@ -0,0 +1,10 @@
// @ts-nocheck
// #ifdef UNI-APP-X && APP
export * from './uvue.uts'
// #endif
// #ifndef UNI-APP-X && APP
export * from './vue.ts'
// #endif

+ 103
- 0
111/uni_modules/lime-shared/animation/useTransition.ts View File

@ -0,0 +1,103 @@
// @ts-nocheck
import type { ComponentPublicInstance } from 'vue'
import { ease, linear } from './ease';
import { Timeline, Animation } from './';
export type UseTransitionOptions = {
duration ?: number
immediate ?: boolean
context ?: ComponentPublicInstance
}
// #ifndef UNI-APP-X && APP
import { ref, watch, type Ref } from '@/uni_modules/lime-shared/vue'
export function useTransition(percent : Ref<number>|(() => number), options : UseTransitionOptions) : Ref<number> {
const current = ref(0)
const { immediate, duration = 300 } = options
let tl:Timeline|null = null;
let timer = -1
const isFunction = typeof percent === 'function'
watch(isFunction ? percent : () => percent.value, (v) => {
if(tl == null){
tl = new Timeline()
}
tl.start();
tl.add(
new Animation(
current.value,
v,
duration,
0,
ease,
nowValue => {
current.value = nowValue
clearTimeout(timer)
if(current.value == v){
timer = setTimeout(()=>{
tl?.pause();
tl = null
}, duration)
}
}
)
);
}, { immediate })
return current
}
// #endif
// #ifdef UNI-APP-X && APP
type UseTransitionReturnType = Ref<number>
export function useTransition(source : any, options : UseTransitionOptions) : UseTransitionReturnType {
const outputRef : Ref<number> = ref(0)
const immediate = options.immediate ?? false
const duration = options.duration ?? 300
const context = options.context //as ComponentPublicInstance | null
let tl:Timeline|null = null;
let timer = -1
const watchFunc = (v : number) => {
if(tl == null){
tl = new Timeline()
}
tl!.start();
tl!.add(
new Animation(
outputRef.value,
v,
duration,
0,
ease,
nowValue => {
outputRef.value = nowValue
clearTimeout(timer)
if(outputRef.value == v){
timer = setTimeout(()=>{
tl?.pause();
tl = null
}, duration)
}
}
),
null
);
}
if (context != null && typeof source == 'string') {
context.$watch(source, watchFunc, { immediate } as WatchOptions)
} else if(typeof source == 'function'){
watch(source, watchFunc, { immediate })
} else if(isRef(source) && typeof source.value == 'number') {
watch(source as Ref<number>, watchFunc, { immediate })
}
// else if(source instanceof Ref<number>){
// watch(source as Ref<number>, watchFunc, { immediate })
// }
const stop = ()=>{
}
return outputRef //as UseTransitionReturnType
}
// #endif

+ 119
- 0
111/uni_modules/lime-shared/animation/uvue.uts View File

@ -0,0 +1,119 @@
import { raf, cancelRaf} from '../raf'
// @ts-nocheck
export class Timeline {
state : string
animations : Set<Animation> = new Set<Animation>()
delAnimations : Animation[] = []
startTimes : Map<Animation, number> = new Map<Animation, number>()
pauseTime : number = 0
pauseStart : number = Date.now()
tickHandler : number = 0
tickHandlers : number[] = []
tick : (() => void) | null = null
constructor() {
this.state = 'Initiated';
}
start() {
if (!(this.state == 'Initiated')) return;
this.state = 'Started';
let startTime = Date.now();
this.pauseTime = 0;
this.tick = () => {
let now = Date.now();
this.animations.forEach((animation : Animation) => {
let t:number;
const ani = this.startTimes.get(animation)
if (ani == null) return
if (ani < startTime) {
t = now - startTime - animation.delay - this.pauseTime;
} else {
t = now - ani - animation.delay - this.pauseTime;
}
if (t > animation.duration) {
this.delAnimations.push(animation)
// 不能在 foreach 里面 对 集合进行删除操作
// this.animations.delete(animation);
t = animation.duration;
}
if (t > 0) animation.run(t);
})
// 不能在 foreach 里面 对 集合进行删除操作
while (this.delAnimations.length > 0) {
const animation = this.delAnimations.pop();
if (animation == null) return
this.animations.delete(animation);
}
// cancelAnimationFrame(this.tickHandler);
if (this.state != 'Started') return
this.tickHandler = raf(()=>{
this.tick!()
})
this.tickHandlers.push(this.tickHandler)
}
if(this.tick != null) {
this.tick!()
}
}
pause() {
if (!(this.state === 'Started')) return;
this.state = 'Paused';
this.pauseStart = Date.now();
cancelRaf(this.tickHandler);
// cancelRaf(this.tickHandler);
}
resume() {
if (!(this.state === 'Paused')) return;
this.state = 'Started';
this.pauseTime += Date.now() - this.pauseStart;
this.tick!();
}
reset() {
this.pause();
this.state = 'Initiated';
this.pauseTime = 0;
this.pauseStart = 0;
this.animations.clear()
this.delAnimations.clear()
this.startTimes.clear()
this.tickHandler = 0;
}
add(animation : Animation, startTime ?: number | null) {
if (startTime == null) startTime = Date.now();
this.animations.add(animation);
this.startTimes.set(animation, startTime);
}
}
export class Animation {
startValue : number
endValue : number
duration : number
timingFunction : (t : number) => number
delay : number
template : (t : number) => void
constructor(
startValue : number,
endValue : number,
duration : number,
delay : number,
timingFunction : (t : number) => number,
template : (v : number) => void) {
this.startValue = startValue;
this.endValue = endValue;
this.duration = duration;
this.timingFunction = timingFunction;
this.delay = delay;
this.template = template;
}
run(time : number) {
let range = this.endValue - this.startValue;
let progress = time / this.duration
if(progress != 1) progress = this.timingFunction(progress)
this.template(this.startValue + range * progress)
}
}

+ 123
- 0
111/uni_modules/lime-shared/animation/vue.ts View File

@ -0,0 +1,123 @@
// @ts-nocheck
const TICK = Symbol('tick');
const TICK_HANDLER = Symbol('tick-handler');
const ANIMATIONS = Symbol('animations');
const START_TIMES = Symbol('start-times');
const PAUSE_START = Symbol('pause-start');
const PAUSE_TIME = Symbol('pause-time');
const _raf = typeof requestAnimationFrame !== 'undefined' ? requestAnimationFrame : function(cb: Function) {return setTimeout(cb, 1000/60)}
const _caf = typeof cancelAnimationFrame !== 'undefined' ? cancelAnimationFrame: function(id: any) {clearTimeout(id)}
// const TICK = 'tick';
// const TICK_HANDLER = 'tick-handler';
// const ANIMATIONS = 'animations';
// const START_TIMES = 'start-times';
// const PAUSE_START = 'pause-start';
// const PAUSE_TIME = 'pause-time';
// const _raf = function(callback):number|null {return setTimeout(callback, 1000/60)}
// const _caf = function(id: number):void {clearTimeout(id)}
export class Timeline {
state: string
constructor() {
this.state = 'Initiated';
this[ANIMATIONS] = new Set();
this[START_TIMES] = new Map();
}
start() {
if (!(this.state === 'Initiated')) return;
this.state = 'Started';
let startTime = Date.now();
this[PAUSE_TIME] = 0;
this[TICK] = () => {
let now = Date.now();
this[ANIMATIONS].forEach((animation) => {
let t: number;
if (this[START_TIMES].get(animation) < startTime) {
t = now - startTime - animation.delay - this[PAUSE_TIME];
} else {
t = now - this[START_TIMES].get(animation) - animation.delay - this[PAUSE_TIME];
}
if (t > animation.duration) {
this[ANIMATIONS].delete(animation);
t = animation.duration;
}
if (t > 0) animation.run(t);
})
// for (let animation of this[ANIMATIONS]) {
// let t: number;
// console.log('animation', animation)
// if (this[START_TIMES].get(animation) < startTime) {
// t = now - startTime - animation.delay - this[PAUSE_TIME];
// } else {
// t = now - this[START_TIMES].get(animation) - animation.delay - this[PAUSE_TIME];
// }
// if (t > animation.duration) {
// this[ANIMATIONS].delete(animation);
// t = animation.duration;
// }
// if (t > 0) animation.run(t);
// }
this[TICK_HANDLER] = _raf(this[TICK]);
};
this[TICK]();
}
pause() {
if (!(this.state === 'Started')) return;
this.state = 'Paused';
this[PAUSE_START] = Date.now();
_caf(this[TICK_HANDLER]);
}
resume() {
if (!(this.state === 'Paused')) return;
this.state = 'Started';
this[PAUSE_TIME] += Date.now() - this[PAUSE_START];
this[TICK]();
}
reset() {
this.pause();
this.state = 'Initiated';
this[PAUSE_TIME] = 0;
this[PAUSE_START] = 0;
this[ANIMATIONS] = new Set();
this[START_TIMES] = new Map();
this[TICK_HANDLER] = null;
}
add(animation: any, startTime?: number) {
if (arguments.length < 2) startTime = Date.now();
this[ANIMATIONS].add(animation);
this[START_TIMES].set(animation, startTime);
}
}
export class Animation {
startValue: number
endValue: number
duration: number
timingFunction: (t: number) => number
delay: number
template: (t: number) => void
constructor(startValue: number, endValue: number, duration: number, delay: number, timingFunction: (t: number) => number, template: (v: number) => void) {
timingFunction = timingFunction || (v => v);
template = template || (v => v);
this.startValue = startValue;
this.endValue = endValue;
this.duration = duration;
this.timingFunction = timingFunction;
this.delay = delay;
this.template = template;
}
run(time: number) {
let range = this.endValue - this.startValue;
let progress = time / this.duration
if(progress != 1) progress = this.timingFunction(progress)
this.template(this.startValue + range * progress)
}
}

+ 3888
- 0
111/uni_modules/lime-shared/areaData/city-china.json
File diff suppressed because it is too large
View File


+ 71
- 0
111/uni_modules/lime-shared/areaData/index.ts View File

@ -0,0 +1,71 @@
// @ts-nocheck
import _areaList from './city-china.json';
export const areaList = _areaList
// #ifndef UNI-APP-X
type UTSJSONObject = Record<string, string>
// #endif
// #ifdef UNI-APP-X
type Object = UTSJSONObject
// #endif
type AreaList = {
province_list : Map<string, string>;
city_list : Map<string, string>;
county_list : Map<string, string>;
}
// type CascaderOption = {
// text : string;
// value : string;
// children ?: CascaderOption[];
// };
const makeOption = (
label : string,
value : string,
children ?: UTSJSONObject[],
) : UTSJSONObject => ({
label,
value,
children,
});
export function useCascaderAreaData() : UTSJSONObject[] {
const city = areaList['city_list'] as UTSJSONObject
const county = areaList['county_list'] as UTSJSONObject
const province = areaList['province_list'] as UTSJSONObject
const provinceMap = new Map<string, UTSJSONObject>();
Object.keys(province).forEach((code) => {
provinceMap.set(code.slice(0, 2), makeOption(`${province[code]}`, code, []));
});
const cityMap = new Map<string, UTSJSONObject>();
Object.keys(city).forEach((code) => {
const option = makeOption(`${city[code]}`, code, []);
cityMap.set(code.slice(0, 4), option);
const _province = provinceMap.get(code.slice(0, 2));
if (_province != null) {
(_province['children'] as UTSJSONObject[]).push(option)
}
});
Object.keys(county).forEach((code) => {
const _city = cityMap.get(code.slice(0, 4));
if (_city != null) {
(_city['children'] as UTSJSONObject[]).push(makeOption(`${county[code]}`, code, null));
}
});
// #ifndef APP-ANDROID || APP-IOS
return Array.from(provinceMap.values());
// #endif
// #ifdef APP-ANDROID || APP-IOS
const obj : UTSJSONObject[] = []
provinceMap.forEach((value, code) => {
obj.push(value)
})
return obj
// #endif
}

+ 8
- 0
111/uni_modules/lime-shared/arrayBufferToFile/index.ts View File

@ -0,0 +1,8 @@
// @ts-nocheck
// #ifndef UNI-APP-X && APP
export * from './vue.ts'
// #endif
// #ifdef UNI-APP-X && APP
export * from './uvue.uts'
// #endif

+ 10
- 0
111/uni_modules/lime-shared/arrayBufferToFile/uvue.uts View File

@ -0,0 +1,10 @@
// @ts-nocheck
// import {platform} from '../platform'
/**
* buffer转路径
* @param {Object} buffer
*/
// @ts-nocheck
export function arrayBufferToFile(buffer: ArrayBuffer, name?: string, format?:string):Promise<(File|string)> {
console.error('[arrayBufferToFile] 当前环境不支持')
}

+ 63
- 0
111/uni_modules/lime-shared/arrayBufferToFile/vue.ts View File

@ -0,0 +1,63 @@
// @ts-nocheck
import {platform} from '../platform'
/**
* buffer转路径
* @param {Object} buffer
*/
// @ts-nocheck
export function arrayBufferToFile(buffer: ArrayBuffer | Blob, name?: string, format?:string):Promise<(File|string)> {
return new Promise((resolve, reject) => {
// #ifdef MP
const fs = uni.getFileSystemManager()
//自定义文件名
if (!name && !format) {
reject(new Error('ERROR_NAME_PARSE'))
}
const fileName = `${name || new Date().getTime()}.${format.replace(/(.+)?\//,'')}`;
let pre = platform()
const filePath = `${pre.env.USER_DATA_PATH}/${fileName}`
fs.writeFile({
filePath,
data: buffer,
success() {
resolve(filePath)
},
fail(err) {
console.error(err)
reject(err)
}
})
// #endif
// #ifdef H5
const file = new File([buffer], name, {
type: format,
});
resolve(file)
// #endif
// #ifdef APP-PLUS
const bitmap = new plus.nativeObj.Bitmap('bitmap' + Date.now())
const base64 = uni.arrayBufferToBase64(buffer)
bitmap.loadBase64Data(base64, () => {
if (!name && !format) {
reject(new Error('ERROR_NAME_PARSE'))
}
const fileNmae = `${name || new Date().getTime()}.${format.replace(/(.+)?\//,'')}`;
const filePath = `_doc/uniapp_temp/${fileNmae}`
bitmap.save(filePath, {},
() => {
bitmap.clear()
resolve(filePath)
},
(error) => {
bitmap.clear()
reject(error)
})
}, (error) => {
bitmap.clear()
reject(error)
})
// #endif
})
}

+ 13
- 0
111/uni_modules/lime-shared/base64ToArrayBuffer/index.ts View File

@ -0,0 +1,13 @@
// @ts-nocheck
// 未完成
export function base64ToArrayBuffer(base64 : string) {
const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64) || [];
if (!format) {
new Error('ERROR_BASE64SRC_PARSE')
}
if(uni.base64ToArrayBuffer) {
return uni.base64ToArrayBuffer(bodyData)
} else {
}
}

+ 9
- 0
111/uni_modules/lime-shared/base64ToPath/index.ts View File

@ -0,0 +1,9 @@
// @ts-nocheck
// #ifndef UNI-APP-X && APP
export * from './vue.ts'
// #endif
// #ifdef UNI-APP-X && APP
export * from './uvue.uts'
// #endif

+ 22
- 0
111/uni_modules/lime-shared/base64ToPath/uvue.uts View File

@ -0,0 +1,22 @@
// @ts-nocheck
import { processFile, type ProcessFileOptions } from '@/uni_modules/lime-file-utils'
/**
* base64转路径
* @param {Object} base64
*/
export function base64ToPath(base64: string, filename: string | null = null):Promise<string> {
return new Promise((resolve,reject) => {
processFile({
type: 'toDataURL',
path: base64,
filename,
success(res: string){
resolve(res)
},
fail(err){
reject(err)
}
} as ProcessFileOptions)
})
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save