369 lines
7.3 KiB
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> |