alipay-emulator/pages/common/hot-icon/hot-icon.vue

369 lines
7.3 KiB
Vue

<template>
<view class="container" v-if="!isOpenCropper">
<!-- 自定义头部导航栏 -->
<navBar :title="data.navbar.title" :bgColor="data.navbar.bgColor" :isBack="true" isRightButton
@right-click="submitBtn">
</navBar>
<view class="icon-box">
<view class="list group" v-for="(group, index) in data.showHotListIcon" :key="index">
<view class="title">
{{ group.classify }}
</view>
<view class="title-box"></view>
<view class="item" v-for="(item, idx) in group.data" :key="idx"
:class="{ active: data.activeId === item.selectId }" @click="onSelect(item)">
<image class="" :src="item.url" mode=""></image>
<view class="" v-if="item.name">
{{ item.name }}
</view>
</view>
</view>
</view>
</view>
<view v-if="isOpenCropper">
<qf-image-cropper :width="500" :height="500" :radius="30" @crop="handleCrop"></qf-image-cropper>
</view>
</template>
<script setup>
// 自定义头部
import navBar from '@/components/nav-bar/nav-bar.vue'
import hotIcon from "@/static/json/hot-icon.json"
import {
reactive,
toRefs
} from "vue";
import {
onLoad,
onShow,
onReady,
onPullDownRefresh,
onReachBottom
} from "@dcloudio/uni-app";
const data = reactive({
navbar: {
title: "热门图标",
bgColor: '#EDEDED',
},
isOpenCropper: false,
activeId: '',
hotIconList: [],
fromPage: "addBill",
activeData: "",
showHotListIcon: []
})
let {
isOpenCropper
} = toRefs(data)
onLoad((option) => {
if (option.page) {
data.fromPage = option.page
}
data.hotIconList = []
console.log(data.hotIconList, hotIcon.moneyHotIcon)
hotIcon.moneyHotIcon.forEach((i, index) => {
data.hotIconList.push({
selectId: index,
name: i.name,
url: `/static/image/common/hot-icon/${i.label}.png`,
isUpLoad: i.isUpLoad,
classify: i.classify
})
})
console.log(data.hotIconList)
getImage()
})
/**
* @param {Object} item
* 选择图片
*/
function onSelect(item) {
if (item.isUpLoad) {
data.activeId = ''
data.activeData = ''
isOpenCropper.value = true
// chooseImage()
} else {
console.log(item);
data.activeId = item.selectId
data.activeData = item
}
}
/**
* @param {Object} e
* 图片裁剪完成
*/
async function handleCrop(e) {
console.log(e);
const savedFilePath = await saveAndDisplayImage(e.tempFilePath)
let arr = [{
selectId: generateAlphanumericCode(10),
name: "",
url: savedFilePath,
isUpLoad: false,
classify: "自定义"
}]
console.log("图片储存成功", arr)
// 合并数组
data.hotIconList = insertAfterFirstInPlace(data.hotIconList, arr);
await addImg(arr[0])
formatJson()
isOpenCropper.value = false
}
const formatJson = () => {
const groupedMap = new Map();
data.hotIconList.forEach(item => {
if (!groupedMap.has(item.classify)) {
groupedMap.set(item.classify, {
classify: item.classify,
data: []
});
}
groupedMap.get(item.classify).data.push(item);
});
const list = Array.from(groupedMap.values()).map((group, index) => {
return {
classify: group.classify,
data: group.data.map((item, idx) => {
return item
})
}
})
data.showHotListIcon = list
console.log("分组后的json", list);
}
/**
* 获取图片
*/
const getImage = () => {
//获取图片列表
// console.log("图片获取成功", res)
// const imgArr = res
// console.log(imgArr)
// imgArr.forEach(i => {
// i.selectId = generateAlphanumericCode()
// i.classify = i.classify ? i.classify : '自定义'
// })
// insertAfterFirstInPlace(data.hotIconList, imgArr);
formatJson()
}
// 生成字母数字混合编码
function generateAlphanumericCode(length = 8) {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
return Array.from({
length
}, () =>
chars.charAt(Math.floor(Math.random() * chars.length))
).join('');
}
/**
* 新增图片
*/
const addImg = (data) => {
// //增加数据
// let sql = `INSERT INTO image (url,type,name) VALUES ('${data.url}','moneyHotIcon','${data.name}')`;
// proxy.$sqliteApi.addTable(sql).then((res) => {
// console.log("图片添加成功", res)
// }).catch(e => {
// console.log("图片添加失败", e)
// })
}
/**
* 从本地选择图片
*/
function chooseImage() {
uni.chooseImage({
count: 9, // 最多可选择9张图片
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图
sourceType: ['album'], // 从相册选择
success: (res) => {
res.tempFilePaths.forEach(async item => {
const savedFilePath = await saveAndDisplayImage(item)
let arr = [{
selectId: generateAlphanumericCode(10),
name: "",
url: savedFilePath,
isUpLoad: item.isUpLoad
}]
console.log("图片储存成功", arr)
// 合并数组
data.hotIconList = insertAfterFirstInPlace(data.hotIconList, arr);
formatJson()
addImg(arr[0])
return obj
})
},
fail: (err) => {
console.error('选择图片失败:', err);
uni.showToast({
title: '选择图片失败',
icon: 'none'
});
}
});
};
/**
* @param {Object} file
* 保存图片到本地
*/
async function saveAndDisplayImage(file) {
try {
// 这里是你保存图片的逻辑
const {
savedFilePath
} = await uni.saveFile({
tempFilePath: file
})
return savedFilePath
} catch (error) {
console.error('保存图片失败:', error)
return ""
}
}
onReady(() => {
})
onShow(() => { })
onPullDownRefresh(() => {
setTimeout(() => {
uni.stopPullDownRefresh();
}, 1000);
})
onReachBottom(() => {
})
function insertAfterFirstInPlace(mainArray, newArray) {
console.log("mainArray", mainArray)
console.log("newArray", newArray)
mainArray.splice(1, 0, ...newArray);
return mainArray;
}
function submitBtn() {
if (data.activeId == '') {
uni.showToast({
icon: "none",
title: "请选择图标"
})
} else {
console.log("来自页面", data.fromPage);
uni.navigateBack({
delta: 1,
success: () => {
// 延迟确保目标页面已准备好
setTimeout(() => {
uni.$emit(data.fromPage, data.activeData);
}, 100);
}
})
}
}
</script>
<style lang="scss">
page {
background-color: #ededed;
}
.container {
padding-bottom: calc(8rpx + constant(safe-area-inset-bottom)); // 兼容 IOS<11.2
padding-bottom: calc(8rpx + env(safe-area-inset-bottom)); // 兼容 IOS>11.2
.icon-box {
background-color: #fff;
padding: 12px 0;
padding-top: 2px;
margin: 0 24rpx;
border-radius: 16rpx 16rpx 16rpx 16rpx;
margin-bottom: 8px;
}
}
.list {
display: flex;
flex-wrap: wrap;
padding: 0 2px;
.item {
background-color: #fff;
width: calc(25% - 20px);
height: 75px;
border-radius: 7px 7px 7px 7px;
border: 1px solid #E8E8E8;
margin: 9px 10px;
// margin-top: 16px;
text-align: center;
font-size: 10px;
color: #1A1A1A;
image {
width: 42px;
height: 42px;
margin-top: 10px;
border-radius: 6px;
}
}
.active {
background: #BCEDD3;
border: 1px solid #07C160;
}
}
.group {
position: relative;
margin-top: 12px;
.title {
position: absolute;
font-family: Alimama ShuHeiTi, Alimama ShuHeiTi;
font-weight: 700;
font-size: 16px;
color: #2C2C2C;
z-index: 2;
margin-left: 12px;
}
.title-box {
width: 100%;
height: 24px;
}
}
.group::before {
position: absolute;
content: "";
width: 41px;
height: 8px;
left: 6px;
background: linear-gradient(90deg, #9AC8FF 0%, rgba(42, 255, 195, 0) 67.86%);
border-radius: 10px 10px 10px 10px;
z-index: 0;
transform: rotate(345deg);
opacity: 0.7;
}
</style>