钱包转账

This commit is contained in:
weiwei committed 2025-04-02 19:27:23 +08:00
1 parent fb82c9d3a1
commit 03adc25ca2
10 files changed
+722 -481

No files matched your search

+7
View File
@@ -313,6 +313,13 @@
"navigationBarTitleText": "支付完成",
"disableScroll": true
}
},
{
"path": "transferMoney",
"style": {
"navigationBarTitleText": "转账",
"disableScroll": true
}
}
]
}
+2 -83
View File
@@ -9,63 +9,7 @@
</tm-sheet>
<tm-button class="mt-40" :block="true" @click="disabled ? '' : handlePay()" :disabled="disabled">支付</tm-button>
<view class="bg-[#f5f5f5] px-1 py-2 rounded-4 absolute bottom-0 w-full">
<view class="flex mb-2.5" v-for="(row, rowIndex) in keyboardLayout" :key="rowIndex">
<view
class="flex-1 h-[60px] flex items-center justify-center bg-white text-2xl text-[#333] mx-[5px] rounded-lg cursor-pointer select-none active:bg-[#f0f0f0]"
v-for="(key, keyIndex) in row"
:key="keyIndex"
@click="handleKeyPress(key)"
>
{{ key }}
</view>
</view>
<view class="flex mb-0">
<view
class="flex-1 h-[60px] flex items-center justify-center bg-white text-2xl text-[#333] mx-[5px] rounded-lg cursor-pointer select-none active:bg-[#f0f0f0]"
@click="handleKeyPress('.')"
>
.
</view>
<view
class="flex-auto h-[60px] flex items-center justify-center bg-white text-2xl text-[#333] mx-[5px] rounded-lg cursor-pointer select-none active:bg-[#f0f0f0]"
@click="handleKeyPress('0')"
>
0
</view>
<view
class="flex-1 h-[60px] flex items-center justify-center bg-white mx-[5px] rounded-lg cursor-pointer select-none active:bg-[#f0f0f0]"
@click="handleDelete"
>
<svg
t="1742457305987"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="4499"
width="24"
height="24"
>
<path
d="M897.706667 831.146667H286.72c-8.533333 0-15.36-3.413333-20.48-10.24L39.253333 527.36c-6.826667-8.533333-6.826667-22.186667 0-30.72l226.986667-293.546667c5.12-6.826667 11.946667-10.24 20.48-10.24h610.986667c51.2 0 92.16 40.96 92.16 92.16v453.973334c0 51.2-40.96 92.16-92.16 92.16z m-599.04-51.2h599.04c22.186667 0 40.96-18.773333 40.96-40.96V285.013333c0-22.186667-18.773333-40.96-40.96-40.96H298.666667L92.16 512l206.506667 267.946667z"
fill="#333333"
p-id="4500"
></path>
<path
d="M670.72 650.24c-6.826667 0-13.653333-1.706667-18.773333-6.826667L426.666667 416.426667c-10.24-10.24-10.24-25.6 0-35.84 10.24-10.24 25.6-10.24 35.84 0l226.986666 226.986666c10.24 10.24 10.24 25.6 0 35.84-6.826667 5.12-11.946667 6.826667-18.773333 6.826667z"
fill="#333333"
p-id="4501"
></path>
<path
d="M443.733333 650.24c-6.826667 0-13.653333-1.706667-18.773333-6.826667-10.24-10.24-10.24-25.6 0-35.84l226.986667-226.986666c10.24-10.24 25.6-10.24 35.84 0 10.24 10.24 10.24 25.6 0 35.84L462.506667 643.413333c-5.12 5.12-11.946667 6.826667-18.773334 6.826667z"
fill="#333333"
p-id="4502"
></path>
</svg>
</view>
</view>
</view>
<numberKeyboard v-model="amount" />
</view>
</crud-layout>
</template>
@@ -78,13 +22,9 @@ import payApi from "@@/api/pay"
import { storePrice } from "@/sheep/utils/formatMoney"
import { router } from "@/sheep"
import { merchantApi } from "@/sheep/api"
import numberKeyboard from "@/sheep/components/numberKeyboard.vue"
const amount = ref("")
const keyboardLayout = ref([
["1", "2", "3"],
["4", "5", "6"],
["7", "8", "9"],
])
const scanData = ref<{ id?: string; name?: string }>({})
const disabled = ref(false)
@@ -113,27 +53,6 @@ const displayAmount = computed(() => {
)
})
// 按下键盘
const handleKeyPress = (key) => {
if (key === "." && amount.value.includes(".")) return
if (key === "." && !amount.value) {
amount.value = "0."
return
}
if (amount.value.includes(".")) {
const decimalPlaces = amount.value.split(".")[1]
if (decimalPlaces && decimalPlaces.length >= 2) return
}
amount.value += key
}
// 点击删除
const handleDelete = () => {
amount.value = amount.value.slice(0, -1)
}
// 点击支付
const handlePay = () => {
if (!scanData.value.id || !scanData.value.name) return uni.showToast({ title: "扫码信息不存在", icon: "none" })
+190
View File
@@ -0,0 +1,190 @@
<template>
<view class="bg-gray-100 flex-col min-h-screen">
<view class="flex-row items-center justify-center my-2">
<text class="text-lg font-bold">转入{{ state.targetWalletTypeName }}</text>
</view>
<tm-cell
title="转入方式"
icon="money-cny-circle-fill"
icon-color="#0779FD"
iconSize="64"
:label="state.sourceWalletTypeName"
labelColor="#7f7f7f"
labelSize="30"
@click="sourceWalletSelect"
/>
<tm-sheet>
<text class="text-gray-700 font-bold text-lg">转入金额</text>
<view class="flex-row items-center">
<text class="text-3xl text-[#333] mr-2">¥</text>
<text v-if="!amount" class="text-xl text-gray-300">转入金额</text>
<text v-else class="text-3xl">{{ formattedAmount }}</text>
</view>
</tm-sheet>
<!-- 金额限制提示 -->
<view class="h-30rpx">
<view v-if="storePrice(amount) > curSourceWallet?.balance" class="text-xs c-red px-8">注:转账金额不能超过钱包余额</view>
</view>
<view class="p-4 font-bold mt-10">
<tm-button block @click="confirmTransfer">确定转入</tm-button>
</view>
<number-keyboard v-model="amount" />
<!-- 选择转入方式 -->
<tm-drawer
v-model:show="show"
title="选择转入方式"
size="50%"
bg-color="#efefef"
position="bottom"
:show-footer="true"
:showClose="true"
>
<view class="m-4">
<view
v-for="(v, index) in state.walletList"
:key="index"
class="card mb-2 overflow-hidden relative border-4 border-solid border-white duration-200 flex justify-between items-center p-4"
:class="{ 'border-4 border-solid border-blue!': state.sourceWalletTypeId == v.walletTypeId }"
@click="state.sourceWalletTypeId = v.walletTypeId"
>
<view class="flex items-center">
<image class="w-70 h-70 mr-2" :src="filePath(v.walletTypeIcon)" />
<view class="flex flex-col">
<view class="main-text-32">{{ v.walletTypeName }}</view>
<view class="text-gray-500 text-sm">{{ v.cardNumber }}</view>
</view>
</view>
<view class="main-text-32">余额:{{ hooks.useMoney(v.balance) + "元" }}</view>
</view>
</view>
<template #footer>
<tm-button block @click="confirmSourceWallet" class="flex-1 font-bold">确定</tm-button>
</template>
</tm-drawer>
</view>
</template>
<script setup lang="ts">
import { ref, computed, reactive } from "vue"
import { onLoad } from "@dcloudio/uni-app"
import NumberKeyboard from "@/sheep/components/numberKeyboard.vue"
import { payApi, walletApi } from "@/sheep/api"
import { hooks, router } from "@@/index"
import { filePath } from "@/sheep/utils/file"
import { storePrice } from "@/sheep/utils/formatMoney"
const amount = ref("")
const show = ref(false)
const state = reactive<any>({
targetWalletTypeId: "",
targetWalletTypeName: "",
walletList: [],
sourceWalletTypeId: "",
sourceWalletTypeName: "",
})
const curSourceWallet = computed(() => {
if (!state.sourceWalletTypeId) {
state.sourceWalletTypeId = state.walletList[0]?.walletTypeId
state.sourceWalletTypeName = state.walletList[0]?.walletTypeName
return state.walletList[0]
}
return state.walletList.find((item: any) => item.walletTypeId == state.sourceWalletTypeId)
})
onLoad(async (options) => {
if (options?.walletTypeId) {
state.targetWalletTypeId = options.walletTypeId
state.targetWalletTypeName = options.walletTypeName
} else {
uni.showToast({ title: "钱包id不存在", icon: "none" })
}
const res = await walletApi.all()
if (res.code == 0) {
state.walletList = res.data.records.filter((item: any) => item.walletTypeId != state.targetWalletTypeId)
}
})
// 源钱包选择
const sourceWalletSelect = () => {
state.sourceWalletTypeId = ""
show.value = true
}
// 确认源钱包
const confirmSourceWallet = () => {
show.value = false
state.sourceWalletTypeName = state.walletList.find((item: any) => item.walletTypeId == state.sourceWalletTypeId).walletTypeName
}
// 格式化金额显示
const formattedAmount = computed(() => {
if (!amount.value) return ""
// 处理小数点情况
if (amount.value.endsWith(".")) {
return amount.value
}
const parts = amount.value.split(".")
// 添加千位分隔符
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",")
// 处理小数部分
if (parts.length > 1) {
// 如果小数部分不足两位,不自动补零
return `${parts[0]}.${parts[1]}`
}
return parts[0]
})
// 确认转账
const confirmTransfer = async () => {
if (!amount.value || amount.value === "0" || amount.value === "0." || parseFloat(amount.value) === 0) {
return uni.showToast({ title: "金额不能为零", icon: "none" })
}
const numAmount = storePrice(parseFloat(amount.value.endsWith(".") ? amount.value.slice(0, -1) : amount.value))
if (numAmount > curSourceWallet.value.balance) {
return uni.showToast({ title: "转账金额不能超过钱包余额", icon: "none" })
}
// console.log("state.sourceWalletTypeId", state.sourceWalletTypeId)
// console.log("state.targetWalletTypeId", state.targetWalletTypeId)
// console.log("金额", numAmount)
uni.showModal({
title: "确定转入吗?",
success: async (res) => {
if (res.confirm) {
try {
uni.showLoading({ title: "正在转入...", mask: true })
const res = await payApi.transferMoney({
sourceWalletTypeId: state.sourceWalletTypeId,
targetWalletTypeId: state.targetWalletTypeId,
balance: numAmount,
})
if (res.code == 0) {
uni.showToast({ title: "转账成功", icon: "success" })
router.jump("/pages/wallet/list", {}, 2)
} else {
uni.showToast({ title: res.msg, icon: "none" })
}
} catch (error: any) {
uni.showToast({
title: error.message,
icon: "none",
})
} finally {
uni.hideLoading()
}
}
},
})
}
</script>
+6
View File
@@ -119,6 +119,11 @@ const doFreeze = async () => {
uni.hideLoading()
}
}
// 转账
const doTransferMoney = (v: any) => {
router.jump("/pages/pay/transferMoney", { walletTypeId: v.walletTypeId, walletTypeName: v.walletTypeName }, 2)
}
</script>
<template>
@@ -173,6 +178,7 @@ const doFreeze = async () => {
</view>
<view class="flex-row items-center justify-end space-x-20rpx m-t-10rpx">
<!-- <view v-if="v.walletTypeUniqueCode == 1 && !v.cardNumber" class="botder_btn" @tap.stop="openBindDialog(v)">绑定</view> -->
<view class="botder_btn" @tap.stop="doTransferMoney(v)">转入</view>
<view v-if="v.walletTypeUniqueCode == 1 && v.cardNumber && v.isFreeze != 1" class="botder_btn" @tap.stop="openFreezeDialog(v)">
申请冻结
</view>
+11
View File
@@ -61,4 +61,15 @@ export default {
},
})
},
// 转账
transferMoney: (data): Promise<any> => {
return request({
url: "/wallet/wallet-rule-transaction/app/transfer-accounts",
method: "POST",
data,
custom: {
showLoading: false,
},
})
},
}
+1 -1
View File
@@ -1,7 +1,7 @@
import request from "@/sheep/utils/request"
export default {
all: () =>
all: (): Promise<any> =>
request({
url: "/wallet/wallet-manage/app/get-all",
method: "GET",
+75
View File
@@ -0,0 +1,75 @@
<template>
<view class="bg-[#f5f5f5] px-1 py-2 rounded-4 absolute bottom-0 w-full">
<view class="flex mb-2.5" v-for="(row, rowIndex) in keyboardLayout" :key="rowIndex">
<view
class="flex-1 h-[60px] flex items-center justify-center bg-white text-2xl text-[#333] mx-[5px] rounded-lg cursor-pointer select-none active:bg-[#f0f0f0]"
v-for="(key, keyIndex) in row"
:key="keyIndex"
@click="handleKeyPress(key.toString())"
>
{{ key }}
</view>
</view>
<view class="flex mb-0">
<view
class="flex-1 h-[60px] flex items-center justify-center bg-white text-2xl text-[#333] mx-[5px] rounded-lg cursor-pointer select-none active:bg-[#f0f0f0]"
@click="handleKeyPress('.')"
>
.
</view>
<view
class="flex-auto h-[60px] flex items-center justify-center bg-white text-2xl text-[#333] mx-[5px] rounded-lg cursor-pointer select-none active:bg-[#f0f0f0]"
@click="handleKeyPress('0')"
>
0
</view>
<view
class="flex-1 h-[60px] flex items-center justify-center bg-white mx-[5px] rounded-lg cursor-pointer select-none active:bg-[#f0f0f0]"
@click="handleDelete"
>
<image class="w-[30px] h-[30px]" src="@/static/page/keyboardDelete.svg" />
</view>
</view>
</view>
</template>
<script setup lang="ts">
import { ref } from "vue"
const amount = defineModel<string>("modelValue", { default: "" })
const keyboardLayout = ref([
["1", "2", "3"],
["4", "5", "6"],
["7", "8", "9"],
])
// 按下键盘
const handleKeyPress = (key) => {
if (key === "." && amount.value.includes(".")) return
if (key === "." && !amount.value) {
amount.value = "0."
return
}
// 特殊处理:如果当前为0,新输入不是小数点,则替换0
if (amount.value == "0" && key != ".") {
amount.value = key
return
}
// 特殊处理:如果有小数点且已有两位小数,不再添加数字
if (amount.value.includes(".")) {
const decimalPlaces = amount.value.split(".")[1]
if (decimalPlaces && decimalPlaces.length >= 2) return
}
amount.value += key
}
// 点击删除
const handleDelete = () => {
if (amount.value.length > 0) {
amount.value = amount.value.slice(0, -1)
}
}
</script>
+1 -1
View File
@@ -288,7 +288,7 @@ http.interceptors.response.use(
mask: true,
})
}
return false
return Promise.resolve(error.data)
},
)
+26
View File
@@ -0,0 +1,26 @@
<svg
t="1742457305987"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="4499"
width="24"
height="24"
>
<path
d="M897.706667 831.146667H286.72c-8.533333 0-15.36-3.413333-20.48-10.24L39.253333 527.36c-6.826667-8.533333-6.826667-22.186667 0-30.72l226.986667-293.546667c5.12-6.826667 11.946667-10.24 20.48-10.24h610.986667c51.2 0 92.16 40.96 92.16 92.16v453.973334c0 51.2-40.96 92.16-92.16 92.16z m-599.04-51.2h599.04c22.186667 0 40.96-18.773333 40.96-40.96V285.013333c0-22.186667-18.773333-40.96-40.96-40.96H298.666667L92.16 512l206.506667 267.946667z"
fill="#333333"
p-id="4500"
></path>
<path
d="M670.72 650.24c-6.826667 0-13.653333-1.706667-18.773333-6.826667L426.666667 416.426667c-10.24-10.24-10.24-25.6 0-35.84 10.24-10.24 25.6-10.24 35.84 0l226.986666 226.986666c10.24 10.24 10.24 25.6 0 35.84-6.826667 5.12-11.946667 6.826667-18.773333 6.826667z"
fill="#333333"
p-id="4501"
></path>
<path
d="M443.733333 650.24c-6.826667 0-13.653333-1.706667-18.773333-6.826667-10.24-10.24-10.24-25.6 0-35.84l226.986667-226.986666c10.24-10.24 25.6-10.24 35.84 0 10.24 10.24 10.24 25.6 0 35.84L462.506667 643.413333c-5.12 5.12-11.946667 6.826667-18.773334 6.826667z"
fill="#333333"
p-id="4502"
></path>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

@@ -1,74 +1,89 @@
<template>
<!-- @vue-ignore -->
<view @click="onclick" :hover-start-time="_isLinksHover ? 50 : 0" :hover-stay-time="_isLinksHover ? 100 : 0"
:hover-class="_isLinksHover ? 'cellHover' : ''" class="tmCell "
:class="[_allAttr.card == true ? 'cellCard' : 'cardInset']" :style="{
backgroundColor: _color,
borderRadius: _cardRadius,
minHeight: _minHeight,
borderBottom: _allAttr.bottom && !_allAttr.card && !bottomBorderInsert ? `1px solid ${_bottomBorderColor}` : 'none',
padding: `0px ${_lrPadding}`
}">
<view v-if="_icon != ''" class="tmCellAvatar"
:style="{ width: _leftSize, height: _leftSize, borderRadius: _avatarRound }">
<!--
<!-- @vue-ignore -->
<view
@click="onclick"
:hover-start-time="_isLinksHover ? 50 : 0"
:hover-stay-time="_isLinksHover ? 100 : 0"
:hover-class="_isLinksHover ? 'cellHover' : ''"
class="tmCell"
:class="[_allAttr.card == true ? 'cellCard' : 'cardInset']"
:style="{
backgroundColor: _color,
borderRadius: _cardRadius,
minHeight: _minHeight,
borderBottom: _allAttr.bottom && !_allAttr.card && !bottomBorderInsert ? `1px solid ${_bottomBorderColor}` : 'none',
padding: `0px ${_lrPadding}`,
}"
>
<view v-if="_icon != ''" class="tmCellAvatar" :style="{ width: _leftSize, height: _leftSize, borderRadius: _avatarRound }">
<!--
@slot 头像图标
@binding {string} icon 图标名称
-->
<slot name="avatar" :icon="_icon">
<tm-icon :color="_allAttr.iconColor" :size="_iconSize" :name="_icon"></tm-icon>
</slot>
</view>
<slot name="avatar" :icon="_icon">
<tm-icon :color="_allAttr.iconColor" :size="_iconSize" :name="_icon"></tm-icon>
</slot>
</view>
<view class="tmCellWrap" :style="{
padding: `${_tbPadding} 0px `,
borderBottom: _allAttr.bottom && !_allAttr.card && bottomBorderInsert ? `1px solid ${_bottomBorderColor}` : 'none'
}">
<view class="center">
<!--
<view
class="tmCellWrap"
:style="{
padding: `${_tbPadding} 0px `,
borderBottom: _allAttr.bottom && !_allAttr.card && bottomBorderInsert ? `1px solid ${_bottomBorderColor}` : 'none',
}"
>
<view class="center">
<!--
@slot 默认标题插槽
-->
<slot>
<text class="title" :style="{ color: _titleColor, fontSize: _titleSize }">{{ _allAttr.title
}}</text>
</slot>
<!--
<slot>
<text class="title" :style="{ color: _titleColor, fontSize: _titleSize }">{{ _allAttr.title }}</text>
</slot>
<!--
@slot 简介
@binding {string} desc 简介
-->
<slot name="desc" :desc="_allAttr.desc">
<tm-text v-if="_allAttr.desc != ''" size="28" color='#bfbfbf' dark-color='#bfbfbf' class="desc">{{
_allAttr.desc }}</tm-text>
</slot>
</view>
<view class="tmCellRight">
<!--
<slot name="desc" :desc="_allAttr.desc">
<tm-text v-if="_allAttr.desc != ''" size="28" color="#bfbfbf" dark-color="#bfbfbf" class="desc">{{ _allAttr.desc }}</tm-text>
</slot>
</view>
<view class="tmCellRight">
<!--
@slot 右边文字
@binding {string} label 标签内容
-->
<slot name="label" :label="_allAttr.label">
<text v-if="_allAttr.label != ''" :style="{ color: _allAttr.labelColor, fontSize: _rightLableSize }"
class="rightLabel">{{ _allAttr.label }}</text>
</slot>
<!--
<slot name="label" :label="_allAttr.label">
<text v-if="_allAttr.label != ''" :style="{ color: _allAttr.labelColor, fontSize: _rightLableSize }" class="rightLabel">{{
_allAttr.label
}}</text>
</slot>
<!--
@slot 右插槽
-->
<slot name="right"></slot>
<tm-icon v-if="_allAttr.url != '' || _allAttr.link" color="#bfbfbf" size="36" :name="attrs.linkIcon"
_style="paddingLeft:12rpx"></tm-icon>
</view>
</view>
</view>
<slot name="right"></slot>
<tm-icon
v-if="_allAttr.url != '' || _allAttr.link"
color="#bfbfbf"
size="36"
:name="attrs.linkIcon"
_style="paddingLeft:12rpx"
></tm-icon>
</view>
</view>
</view>
</template>
<script lang="ts" setup>
import { computed, ref, onMounted, PropType } from "vue"
import { arrayNumberValid, arrayNumberValidByStyleMP, covetUniNumber, arrayNumberValidByStyleBorderColor, linearValid, getUnit } from "../../libs/tool";
import { getDefaultColor, getDefaultColorObj, getOutlineColorObj, getTextColorObj, getThinColorObj } from "../../libs/colors";
import { useTmConfig } from "../../libs/config";
import { computed, ref, onMounted } from "vue"
import {
arrayNumberValid,
arrayNumberValidByStyleMP,
covetUniNumber,
arrayNumberValidByStyleBorderColor,
linearValid,
getUnit,
} from "../../libs/tool"
import { getDefaultColor, getDefaultColorObj, getOutlineColorObj, getTextColorObj, getThinColorObj } from "../../libs/colors"
import { useTmConfig } from "../../libs/config"
/**
* @displayName 列表
* @exportName tm-cell
@@ -79,233 +94,231 @@ import { useTmConfig } from "../../libs/config";
| --- | --- | --- | --- |
| ☑️| ☑️ | ☑️ | ☑️ | ☑️ | 1.0.0 |
*/
defineOptions({ name: 'TmCell' });
defineOptions({ name: "TmCell" })
const { config } = useTmConfig()
type tmCellItemType = {
icon: string,
title: string,
desc: string,
label: string,
bottom: boolean,
link: boolean,
url: string,
iconColor: string,
labelColor: string,
card: boolean
icon: string
title: string
desc: string
label: string
bottom: boolean
link: boolean
url: string
iconColor: string
labelColor: string
card: boolean
}
const emits = defineEmits(
[
/**
* 项目点击
*/
"click"
]
)
const emits = defineEmits([
/**
* 项目点击
*/
"click",
])
const attrs = defineProps({
/**
* 左图标
*/
icon: {
type: String,
default: ""
},
/**
* 左侧图标、头像圆角。默认为8
*/
avatarRound: {
type: String,
default: "8"
},
/**
* 背景的主题色
*/
color: {
type: String,
default: 'white'
},
/**
* 暗黑背景的主题色,空值时取sheetDarkColor
*/
darkColor: {
type: String,
default: ''
},
/**
* 图标色,空值时取全局主题值。
*/
iconColor: {
type: String,
default: ""
},
/**
* 标题
*/
title: {
type: String,
default: "标题"
},
/**
* 标题颜色
*/
titleColor: {
type: String,
default: "black"
},
/**
* 暗黑标题颜色,如果不填写取白
*/
darkTitleColor: {
type: String,
default: "white"
},
/**
* 标题大小
*/
titleSize: {
type: [String, Number],
default: "32"
},
/**
* 左边图标大小
*/
iconSize: {
type: [String, Number],
default: "42"
},
/**
* 右边文本
*/
label: {
type: String,
default: ""
},
/**
* 右边文本颜色
*/
labelColor: {
type: String,
default: "#bfbfbf"
},
/**
* 右侧label文字大小
*/
labelSize: {
type: [String, Number],
default: "24"
},
/**
* 标题正文的简介文本
*/
desc: {
type: String,
default: ""
},
/**
* 是否显示下边线
*/
showBottomBorder: {
type: Boolean,
default: true
},
/**
* 是否让下边线显示居右,不贯穿到左边。
*/
bottomBorderInsert: {
type: Boolean,
default: false
},
/**
* 下边线的颜色。如果你设定了的话。
* 暗黑的边颜色失效,采用你自定的颜色。
*/
bottomBorderColor: {
type: String,
default: ""
},
/**
* 是否显示链接状态,有点按效果。包括出现右边跳转指示。
* 关闭的话,事件反应和跳转会更快。
* 如果true右侧箭头图标会显示
*/
link: {
type: Boolean,
default: true
},
/**
* 需要跳转的页面地址。
* 如果填写了右侧箭头图标会显示
*/
url: {
type: String,
default: ""
},
openType: {
type: String as PropType<"navigate" | "redirect" | "switchTab" | "reLaunch" | "navigateBack" | "exit">,
default: "navigate"
},
/**
* 是否是卡片模式
*/
card: {
type: Boolean,
default: true
},
/**
* 卡片模式圆角,不填写采用全局的cardRadius属性值.
*/
round: {
type: [String, Number],
default: ""
},
/**
* 左边图标区域宽和高的大小。
*/
leftSize: {
type: [String, Number],
default: '60'
},
/**
* 最小高度,主要是用来统一风格高度不至于让点击范围过小
* 如果你需要紧凑型可以设置为auto
*/
minHeight: {
type: [String, Number],
default: "88"
},
/**
* 左右的间隙。
*/
lrPadding: {
type: [String, Number],
default: "32"
},
linkIcon: {
type: String,
default: "arrow-right-s-line"
},
/**
* 上下间隙
*/
tbPadding: {
type: [String, Number],
default: "32"
}
/**
* 左图标
*/
icon: {
type: String,
default: "",
},
/**
* 左侧图标、头像圆角。默认为8
*/
avatarRound: {
type: String,
default: "8",
},
/**
* 背景的主题色
*/
color: {
type: String,
default: "white",
},
/**
* 暗黑背景的主题色,空值时取sheetDarkColor
*/
darkColor: {
type: String,
default: "",
},
/**
* 图标色,空值时取全局主题值。
*/
iconColor: {
type: String,
default: "",
},
/**
* 标题
*/
title: {
type: String,
default: "标题",
},
/**
* 标题颜色
*/
titleColor: {
type: String,
default: "black",
},
/**
* 暗黑标题颜色,如果不填写取白
*/
darkTitleColor: {
type: String,
default: "white",
},
/**
* 标题大小
*/
titleSize: {
type: [String, Number],
default: "32",
},
/**
* 左边图标大小
*/
iconSize: {
type: [String, Number],
default: "42",
},
/**
* 右边文本
*/
label: {
type: String,
default: "",
},
/**
* 右边文本颜色
*/
labelColor: {
type: String,
default: "#bfbfbf",
},
/**
* 右侧label文字大小
*/
labelSize: {
type: [String, Number],
default: "24",
},
/**
* 标题正文的简介文本
*/
desc: {
type: String,
default: "",
},
/**
* 是否显示下边线
*/
showBottomBorder: {
type: Boolean,
default: true,
},
/**
* 是否让下边线显示居右,不贯穿到左边。
*/
bottomBorderInsert: {
type: Boolean,
default: false,
},
/**
* 下边线的颜色。如果你设定了的话。
* 暗黑的边颜色失效,采用你自定的颜色。
*/
bottomBorderColor: {
type: String,
default: "",
},
/**
* 是否显示链接状态,有点按效果。包括出现右边跳转指示。
* 关闭的话,事件反应和跳转会更快。
* 如果true右侧箭头图标会显示
*/
link: {
type: Boolean,
default: true,
},
/**
* 需要跳转的页面地址。
* 如果填写了右侧箭头图标会显示
*/
url: {
type: String,
default: "",
},
openType: {
type: String,
default: "navigate",
},
/**
* 是否是卡片模式
*/
card: {
type: Boolean,
default: true,
},
/**
* 卡片模式圆角,不填写采用全局的cardRadius属性值.
*/
round: {
type: [String, Number],
default: "",
},
/**
* 左边图标区域宽和高的大小。
*/
leftSize: {
type: [String, Number],
default: "60",
},
/**
* 最小高度,主要是用来统一风格高度不至于让点击范围过小
* 如果你需要紧凑型可以设置为auto
*/
minHeight: {
type: [String, Number],
default: "88",
},
/**
* 左右的间隙。
*/
lrPadding: {
type: [String, Number],
default: "32",
},
linkIcon: {
type: String,
default: "arrow-right-s-line",
},
/**
* 上下间隙
*/
tbPadding: {
type: [String, Number],
default: "32",
},
})
const _color = computed(() => {
if (config.mode === 'dark') {
if (attrs.darkColor !== '') return getDefaultColor(attrs.darkColor)
return getDefaultColor(config.sheetDarkColor)
}
return getDefaultColor(attrs.color)
if (config.mode === "dark") {
if (attrs.darkColor !== "") return getDefaultColor(attrs.darkColor)
return getDefaultColor(config.sheetDarkColor)
}
return getDefaultColor(attrs.color)
})
const _titleColor = computed(() => {
if (config.mode === 'dark') {
if (attrs.darkTitleColor !== '') return getDefaultColor(attrs.darkTitleColor)
return '#ffffff'
}
return getDefaultColor(attrs.titleColor)
if (config.mode === "dark") {
if (attrs.darkTitleColor !== "") return getDefaultColor(attrs.darkTitleColor)
return "#ffffff"
}
return getDefaultColor(attrs.titleColor)
})
const _leftSize = computed(() => covetUniNumber(attrs.leftSize))
@@ -317,189 +330,183 @@ const _avatarRound = computed(() => covetUniNumber(attrs.avatarRound))
const _minHeight = computed(() => covetUniNumber(attrs.minHeight))
const _bottomBorderColor = computed(() => {
if (attrs.bottomBorderColor !== '') return getDefaultColor(attrs.bottomBorderColor)
if (config.mode === 'dark') return config.borderDarkColor
return "#f5f5f5"
if (attrs.bottomBorderColor !== "") return getDefaultColor(attrs.bottomBorderColor)
if (config.mode === "dark") return config.borderDarkColor
return "#f5f5f5"
})
const icon = ref('')
const icon = ref("")
const _allAttr = computed(() => {
let iconColor = attrs.iconColor;
if (iconColor === '') {
iconColor = config.color;
}
let p = {
icon: icon.value,
title: attrs.title,
desc: attrs.desc,
label: attrs.label,
bottom: attrs.showBottomBorder,
link: attrs.link,
url: attrs.url,
iconColor: getDefaultColor(iconColor),
labelColor: getDefaultColor(attrs.labelColor),
card: attrs.card
} as tmCellItemType
return p
let iconColor = attrs.iconColor
if (iconColor === "") {
iconColor = config.color
}
let p = {
icon: icon.value,
title: attrs.title,
desc: attrs.desc,
label: attrs.label,
bottom: attrs.showBottomBorder,
link: attrs.link,
url: attrs.url,
iconColor: getDefaultColor(iconColor),
labelColor: getDefaultColor(attrs.labelColor),
card: attrs.card,
} as tmCellItemType
return p
})
const _cardRadius = computed(() => {
if (attrs.round === '') return arrayNumberValidByStyleMP(config.cellRadius)
return arrayNumberValidByStyleMP(attrs.round, config.unit)
if (attrs.round === "") return arrayNumberValidByStyleMP(config.cellRadius)
return arrayNumberValidByStyleMP(attrs.round, config.unit)
})
const _titleSize = computed(() => {
let fontSize = covetUniNumber(attrs.titleSize, config.unit);
if (config.fontSizeScale === 1) return fontSize;
let sizeNumber = parseInt(fontSize)
if (isNaN(sizeNumber)) {
sizeNumber = 16
}
return (sizeNumber * config.fontSizeScale).toString() + getUnit(fontSize)
let fontSize = covetUniNumber(attrs.titleSize, config.unit)
if (config.fontSizeScale === 1) return fontSize
let sizeNumber = parseInt(fontSize)
if (isNaN(sizeNumber)) {
sizeNumber = 16
}
return (sizeNumber * config.fontSizeScale).toString() + getUnit(fontSize)
})
const _iconSize = computed(() => {
let fontSize = covetUniNumber(attrs.iconSize, config.unit);
if (config.fontSizeScale === 1) return fontSize;
let sizeNumber = parseInt(fontSize)
if (isNaN(sizeNumber)) {
sizeNumber = 17
}
return (sizeNumber * config.fontSizeScale).toString() + getUnit(fontSize)
let fontSize = covetUniNumber(attrs.iconSize, config.unit)
if (config.fontSizeScale === 1) return fontSize
let sizeNumber = parseInt(fontSize)
if (isNaN(sizeNumber)) {
sizeNumber = 17
}
return (sizeNumber * config.fontSizeScale).toString() + getUnit(fontSize)
})
const _rightLableSize = computed(() => {
let fontSize = covetUniNumber(attrs.labelSize, config.unit);
let fontSize = covetUniNumber(attrs.labelSize, config.unit)
if (config.fontSizeScale === 1) return fontSize;
let sizeNumber = parseInt(fontSize)
if (isNaN(sizeNumber)) {
sizeNumber = 13
}
return (sizeNumber * config.fontSizeScale).toString() + getUnit(fontSize)
if (config.fontSizeScale === 1) return fontSize
let sizeNumber = parseInt(fontSize)
if (isNaN(sizeNumber)) {
sizeNumber = 13
}
return (sizeNumber * config.fontSizeScale).toString() + getUnit(fontSize)
})
const _isLinksHover = computed(() => attrs.link)
const _icon = computed(() => attrs.icon)
const onclick = () => {
/**
* 整个列表被点击
*/
emits("click");
if (attrs.url != "") {
if (attrs.openType == 'navigate') {
uni.navigateTo({
url: attrs.url
})
} else if (attrs.openType == 'navigateBack') {
uni.navigateBack({})
} else if (attrs.openType == 'reLaunch') {
uni.reLaunch({
url: attrs.url
})
} else if (attrs.openType == 'redirect') {
uni.redirectTo({
url: attrs.url
})
} else if (attrs.openType == 'switchTab') {
uni.switchTab({
url: attrs.url
})
}
}
/**
* 整个列表被点击
*/
emits("click")
if (attrs.url != "") {
if (attrs.openType == "navigate") {
uni.navigateTo({
url: attrs.url,
})
} else if (attrs.openType == "navigateBack") {
uni.navigateBack({})
} else if (attrs.openType == "reLaunch") {
uni.reLaunch({
url: attrs.url,
})
} else if (attrs.openType == "redirect") {
uni.redirectTo({
url: attrs.url,
})
} else if (attrs.openType == "switchTab") {
uni.switchTab({
url: attrs.url,
})
}
}
}
</script>
<script lang="ts">
export default {
options: {
styleIsolation: "apply-shared",
virtualHost: true,
addGlobalClass: true,
multipleSlots: true,
},
};
options: {
styleIsolation: "apply-shared",
virtualHost: true,
addGlobalClass: true,
multipleSlots: true,
},
}
</script>
<style scoped lang="scss">
.cellHover {
filter: contrast(90%);
filter: contrast(90%);
}
.tmCell {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.cardInset {
// padding: 0 32rpx;
// padding: 0 32rpx;
}
.cellCard {
// padding: 0 32rpx;
margin-bottom: 12rpx;
margin-left: 24rpx;
margin-right: 24rpx;
// padding: 0 32rpx;
margin-bottom: 12rpx;
margin-left: 24rpx;
margin-right: 24rpx;
}
.tmCellWrap {
flex: 1;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 100%;
// padding: 32rpx 0rpx;
flex: 1;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 100%;
// padding: 32rpx 0rpx;
}
.title {
line-clamp: 2;
display: -webkit-box;
text-overflow: ellipsis;
flex: 1;
line-clamp: 2;
display: -webkit-box;
text-overflow: ellipsis;
flex: 1;
}
.desc {
font-size: 24rpx;
padding-top: 4rpx;
font-size: 24rpx;
padding-top: 4rpx;
}
.tmCellAvatar {
margin-right: 20rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
flex-shrink: 0;
overflow: hidden;
margin-right: 20rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
flex-shrink: 0;
overflow: hidden;
}
.center {
flex: 1;
flex: 1;
}
.tmCellRight {
padding-left: 32rpx;
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
padding-left: 32rpx;
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
}
.rightLabel {
line-clamp: 1;
display: -webkit-box;
text-overflow: ellipsis;
font-size: 24rpx;
text-align: right;
max-width: 200rpx;
line-clamp: 1;
display: -webkit-box;
text-overflow: ellipsis;
font-size: 24rpx;
text-align: right;
max-width: 200rpx;
}
</style>
</style>