This commit is contained in:
zpc 2025-07-31 20:06:59 +08:00
parent 2a1dea9732
commit 84d5bc157f
30 changed files with 1883 additions and 232 deletions

295
common/utils.js Normal file
View File

@ -0,0 +1,295 @@
// /**
// * 获取文件大小Promise封装
// * @param {string} filePath
// * @returns {Promise<number>} 文件字节数
// */
// const getFileSize = (filePath) => {
// return new Promise(resolve => {
// uni.getFileInfo({
// filePath,
// success: (res) => resolve(res.size),
// fail: () => resolve(Infinity)
// });
// });
// };
/**
* 获取文件大小兼容新版API
* @param {string} filePath
* @returns {Promise<number>} 文件字节数
*/
const getFileSize = async (filePath) => {
try {
const res = await new Promise((resolve, reject) => {
wx.getFileSystemManager().getFileInfo({
filePath,
success: resolve,
fail: reject
});
});
return res.size || Infinity;
} catch (err) {
console.error('获取文件大小失败:', err);
return Infinity;
}
};
/**
* 执行图片压缩Promise封装
* @param {string} src
* @param {number} quality
* @returns {Promise<string>} 压缩后的临时路径
*/
const doCompressImage = (src, quality) => {
return new Promise(resolve => {
uni.compressImage({
src,
quality,
success: (res) => resolve(res.tempFilePath),
fail: () => resolve(src) // 失败返回原路径
});
});
};
/**
* 智能图片压缩支持多平台
* @param {string} tempFilePath - 图片临时路径
* @param {number} maxSize - 目标最大字节数默认500KB
* @param {number} [initialQuality=80] - 初始压缩质量(1-100)
* @returns {Promise<string>} 压缩后的临时路径
*/
export const compressImage = async (tempFilePath, maxSize = 500 * 1024, initialQuality = 80) => {
let quality = initialQuality;
let compressedPath = tempFilePath;
let currentSize = Infinity;
// 二分法压缩参数
let low = 10;
let high = initialQuality;
while (low <= high) {
quality = Math.floor((low + high) / 2);
// 使用提取的Promise方法
compressedPath = await doCompressImage(tempFilePath, quality);
currentSize = await getFileSize(compressedPath);
if (currentSize <= maxSize) {
low = quality + 1; // 尝试更高质量
} else {
high = quality - 1; // 降低质量
}
if (high - low < 5) break; // 安全阀
}
// 最终强制压缩(如果仍未达标)
if (currentSize > maxSize) {
compressedPath = await doCompressImage(tempFilePath, 10);
}
return compressedPath;
};
/**
* 精准图片压缩优化版
* @param {string} tempFilePath - 图片临时路径
* @param {number} targetSize - 目标字节数默认500KB
* @param {number} [initialQuality=85] - 初始压缩质量(1-100)
* @returns {Promise<{path: string, quality: number, iterations: number, finalSize: number}>}
*/
export const preciseCompress = async (tempFilePath, targetSize = 500 * 1024, initialQuality = 85) => {
let quality = initialQuality;
let compressedPath = tempFilePath;
let currentSize = Infinity;
let iterations = 0;
const maxIterations = 10; // 增加最大迭代次数
const history = []; // 记录每次压缩结果用于分析
// 首先检查原图大小,如果已经满足直接返回
const originalSize = await getFileSize(tempFilePath);
if (originalSize <= targetSize) {
return { path: tempFilePath, quality: 100, iterations: 0, finalSize: originalSize };
}
// 智能预测初始质量范围(新增)
const predictQualityRange = (originalSize, targetSize) => {
const ratio = targetSize / originalSize;
if (ratio > 0.8) return { low: 70, high: 95 };
if (ratio > 0.5) return { low: 45, high: 75 };
if (ratio > 0.3) return { low: 25, high: 50 };
if (ratio > 0.1) return { low: 10, high: 30 };
return { low: 5, high: 15 }; // 极限压缩
};
const { low: predictedLow, high: predictedHigh } = predictQualityRange(originalSize, targetSize);
let low = predictedLow;
let high = Math.min(predictedHigh, initialQuality);
console.log(`预测质量范围: ${low}-${high} (原图${(originalSize/1024).toFixed(2)}KB → 目标${(targetSize/1024).toFixed(2)}KB)`);
// 动态调整二分法边界(优化版)
const adjustBounds = (currentQuality, currentSize, targetSize) => {
const sizeRatio = currentSize / targetSize;
const qualityDelta = Math.max(2, Math.floor(currentQuality * 0.1)); // 动态调整幅度
if (sizeRatio > 2.5) {
return { lowDelta: -qualityDelta * 2, highDelta: -qualityDelta };
} else if (sizeRatio > 1.5) {
return { lowDelta: -qualityDelta, highDelta: -Math.floor(qualityDelta / 2) };
} else if (sizeRatio > 1.1) {
return { lowDelta: -3, highDelta: -1 };
} else {
return { lowDelta: -1, highDelta: 0 };
}
};
let bestResult = null; // 记录最佳结果
while (iterations < maxIterations && low <= high) {
iterations++;
quality = Math.floor((low + high) / 2);
// 跳过已经测试过的quality值
if (history.some(item => item.quality === quality)) {
break;
}
compressedPath = await doCompressImage(tempFilePath, quality);
currentSize = await getFileSize(compressedPath);
history.push({ quality, size: currentSize });
console.log(`${iterations}次尝试: quality=${quality}${(currentSize / 1024).toFixed(2)}KB (目标${(targetSize/1024).toFixed(2)}KB)`);
// 更新最佳结果
if (!bestResult || Math.abs(currentSize - targetSize) < Math.abs(bestResult.size - targetSize)) {
bestResult = { quality, size: currentSize, path: compressedPath };
}
// 精准匹配检查容差范围调整为3%
if (Math.abs(currentSize - targetSize) < targetSize * 0.03) {
console.log('✅ 达到精准匹配,提前结束');
break;
}
if (currentSize > targetSize) {
const { lowDelta, highDelta } = adjustBounds(quality, currentSize, targetSize);
high = Math.max(5, quality + highDelta); // 确保不会低于最小值
} else {
low = quality + 1; // 当小于目标时,尝试更高质量
}
// 收敛检查
if (high - low <= 1) break;
}
// 如果最佳结果仍然超标,尝试极限压缩
if (bestResult && bestResult.size > targetSize * 1.1) {
console.log('🔥 尝试极限压缩...');
const extremePath = await doCompressImage(tempFilePath, 5);
const extremeSize = await getFileSize(extremePath);
console.log(`极限压缩结果: quality=5 → ${(extremeSize / 1024).toFixed(2)}KB`);
if (extremeSize < bestResult.size) {
bestResult = { quality: 5, size: extremeSize, path: extremePath };
}
}
const finalResult = bestResult || { quality: 10, size: currentSize, path: compressedPath };
console.log(`🎯 最终结果quality=${finalResult.quality}${(finalResult.size / 1024).toFixed(2)}KB` +
`(迭代${iterations}次,压缩率${((1 - finalResult.size / originalSize) * 100).toFixed(1)}%`);
return {
path: finalResult.path,
quality: finalResult.quality,
iterations,
finalSize: finalResult.size
};
};
/**
* 图片转Base64兼容多平台
* @param {string} filePath - 图片临时路径
* @returns {Promise<string>} Base64字符串带data:image/前缀
*/
export const imageToBase64 = (filePath) => {
return new Promise((resolve, reject) => {
// 先获取图片类型
uni.getImageInfo({
src: filePath,
success: (info) => {
const type = info.type || 'jpeg';
// 读取文件为Base64
uni.getFileSystemManager().readFile({
filePath,
encoding: 'base64',
success: (res) => resolve(`data:image/${type};base64,${res.data}`),
fail: reject
});
},
fail: () => {
// 类型获取失败时默认jpeg
uni.getFileSystemManager().readFile({
filePath,
encoding: 'base64',
success: (res) => resolve(`data:image/jpeg;base64,${res.data}`),
fail: reject
});
}
});
});
};
/**
* 完整处理流程智能判断是否压缩
* 选择图片 检查大小 按需压缩 转Base64
* @returns {Promise<{ base64: string, path: string, compressed: boolean }>}
*/
export const processImage = async (maxSize = 500 * 1024) => {
// 1. 选择图片
const chooseRes = await new Promise(resolve => {
uni.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
success: resolve,
fail: () => resolve(null)
});
});
if (!chooseRes) throw new Error('选择图片失败');
const tempFilePath = chooseRes.tempFilePaths[0];
let finalPath = tempFilePath;
let isCompressed = false;
// 2. 检查文件大小
const fileSize = await getFileSize(tempFilePath);
console.log(`原图大小: ${(fileSize / 1024).toFixed(2)}KB`);
// 3. 按需压缩
if (fileSize > maxSize) {
console.log('🔄 开始智能压缩...');
const compressResult = await preciseCompress(tempFilePath, maxSize);
finalPath = compressResult.path;
isCompressed = true;
// 验证压缩结果
console.log(`✅ 压缩完成: ${(fileSize / 1024).toFixed(2)}KB → ${(compressResult.finalSize / 1024).toFixed(2)}KB` +
` (节省${((1 - compressResult.finalSize / fileSize) * 100).toFixed(1)}%)`);
}
// 4. 转换为Base64
const base64 = await imageToBase64(finalPath);
console.log(`📄 Base64长度: ${base64.length} 字符`);
return {
base64, // Base64字符串
path: finalPath, // 最终文件路径(可能是原图或压缩图)
compressed: isCompressed // 是否经过压缩
};
};

View File

@ -50,7 +50,7 @@
"quickapp" : {},
/* */
"mp-weixin" : {
"appid" : "",
"appid" : "wx595ec949c6efd72b",
"setting" : {
"urlCheck" : false
},

View File

@ -2,10 +2,11 @@
<view class="content">
<image src="" style="width: 100%; height: 100%; background-color: bisque; position: absolute;" mode=""></image>
<uniNoticeBar showIcon single scrollable text="赠品仅限线下购买设备的用户领取需人工审核预计3个工作日内完成"
style="width: 100%;position:fixed;top:10%" background-color="transparent" color="#000" />
<view class="center" @click="openReceivePop"
style="width: 386rpx; height: 102rpx; background-color: #0877FF; border-radius: 16rpx; position: absolute; bottom: 200rpx;">
<text style="font-size: 35rpx; color: white;">免费领取</text>
<text style="font-size: 35rpx; color: white;">设备专属权益兑换</text>
</view>
<view class="center" @click="openRecordPop"
@ -15,7 +16,7 @@
<!-- 领奖弹窗 -->
<uni-popup ref="receivePop" type="center">
<uni-popup ref="receivePop" type="center" :is-mask-click="false">
<view class="column"
style="width: 600rpx; height: 1250rpx; background-color: #F5F5F5; border-radius: 16rpx; align-items: center; font-size: 25rpx;">
@ -76,24 +77,28 @@
style="border-bottom: 0.86px solid #000; margin-left: 50rpx; width: 350rpx;" />
</view>
<view class="" style="width: 100%; margin-top: 40rpx;">
<view class="row" style="width: 100%; margin-top: 40rpx; align-items: flex-start; flex-wrap: wrap;">
<view class="center" @click="seleImg"
style="width: 150rpx; height:150rpx; background-color: gainsboro; margin-left: 30rpx; position: relative;">
style="width: 150rpx; height:150rpx; background-color: gainsboro; margin-left: 30rpx; margin-right: 20rpx; position: relative;">
<text style="position: absolute;">+</text>
<image style="position: absolute;" v-if="imagePath" :src="imagePath" mode="aspectFit">
</image>
</view>
<image style="width: 150rpx; height:150rpx; margin-right: 20rpx;" v-if="imagePath"
:src="imagePath" mode="aspectFit" @click="previewImage">
</image>
</view>
<text style="font-size: 22rpx; margin-top: 20rpx;width: 90%;">拍摄并上传清晰的产品铭牌信息用于辅助审核通过后立即发货</text>
</view>
<view class="center"
style="width: 356rpx; height: 100rpx; background-color: #0877FF; margin-top: 40rpx; border-radius: 16rpx;">
<text style="font-size: 30rpx; color: white;">提交</text>
<view class="row" style="width: 100%; justify-content: space-around; margin-top: 40rpx;">
<view class="center" @click="closeReceivePop"
style="width: 150rpx; height: 80rpx; background-color: #CCCCCC; border-radius: 16rpx;">
<text style="font-size: 28rpx; color: #333;">关闭</text>
</view>
<view class="center" @click="submitForm"
style="width: 350rpx; height: 80rpx; background-color: #0877FF; border-radius: 16rpx;position: relative;left: -20rpx;">
<text style="font-size: 28rpx; color: white;">提交</text>
</view>
</view>
</view>
</uni-popup>
@ -121,130 +126,286 @@
style="width: 100%; height: 460rpx; margin-top: 30rpx; overflow-y: auto; font-size: 25rpx; align-items: center;">
<view class="column" v-for="(item,index) in recordList"
<view class="column" v-for="item in recordList" :key="item.phone + item.time"
style="width: 90%; height: 180rpx; margin-bottom: 10rpx; position: relative; background-color: white; padding: 10rpx; border-radius: 16rpx;">
<view class="row" style="justify-content: space-between; margin-top: 20rpx;">
<view class="row">
<text>{{item.name}}</text>
<text style="margin-left: 20rpx;">{{item.phone}}</text>
<text>{{ item.name }}</text>
<text style="margin-left: 20rpx;">{{ item.phone }}</text>
</view>
<text>{{item.time}}</text>
<text>{{ item.time }}</text>
</view>
<text style="margin-top: 20rpx;">{{item.address}}</text>
<text style="margin-top: 20rpx;">{{ item.address }}</text>
</view>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
export default {
data() {
return {
imagePath: '',
name: "",
phone: "",
workUnit: "",
address: "",
createTime: "",
number: "",
model: "",
recordList: [{
name: "苏家辉",
time: "2025-5-25",
address: "江苏省徐州市睢宁县xx小区xx花园20-601",
phone: "13025555555"
import uniNoticeBar from '@/uni_modules/uni-notice-bar/components/uni-notice-bar/uni-notice-bar.vue'
import { processImage } from '@/common/utils'
export default {
components: {
uniNoticeBar
},
onLoad() {
var userId = uni.getStorageSync("user_id");
if (!userId || userId == 0) {
this.login();
}
this.userId = userId;
},
data() {
return {
userId: 0,
imagePath: '',
name: "",
phone: "",
base64: "",
workUnit: "",
address: "",
createTime: "",
number: "",
model: "",
recordList: []
}
},
methods: {
request(url, method, data) {
return new Promise((resolve, reject) => {
const header = {
};
if (method == "post") {
header['content-type'] = 'application/json';
}
uni.request({
url: "http://localhost:8888/" + url,
method: method,
data: data,
header: header,
timeout: 10000,
success: (res) => {
console.log('API响应:', res);
if (res.statusCode === 200) {
resolve(res.data);
} else {
reject(new Error(`请求失败,状态码: ${res.statusCode}`));
}
},
{
name: "苏家辉",
time: "2025-5-25",
address: "江苏省徐州市睢宁县",
phone: "13025555555"
},
{
name: "苏家辉",
time: "2025-5-25",
address: "江苏省徐州市睢宁县",
phone: "13025555555"
},
{
name: "苏家辉",
time: "2025-5-25",
address: "江苏省徐州市睢宁县",
phone: "13025555555"
},
{
name: "苏家辉",
time: "2025-5-25",
address: "江苏省徐州市睢宁县",
phone: "13025555555"
fail: (err) => {
console.error('API请求失败:', err);
reject(err);
}
]
});
})
},
wxLogin() {
return new Promise((resolve, reject) => {
uni.login({
provider: 'weixin', //使
onlyAuthorize: true,
success: async function (res) {
// if()
resolve(res.code);
},
fail: function (err) {
reject(err);
}
})
})
},
async login() {
try {
const wxCode = await this.wxLogin();
if (wxCode) {
const res = await this.request("userLogin?code=" + wxCode, "post", {});
if (res.code == 200) {
uni.setStorageSync("user_id", res.data.user_id);
this.userId = res.data.user_id;
console.log('登录成功, userId:', this.userId);
} else {
console.error('登录失败:', res.message);
}
}
} catch (error) {
console.error('登录过程出错:', error);
}
},
onLoad() {
openReceivePop() {
this.$refs.receivePop.open();
},
closeReceivePop() {
this.$refs.receivePop.close();
},
async openRecordPop() {
await this.loadRecordList();
this.$refs.recordPop.open();
},
async loadRecordList() {
try {
uni.showLoading({ title: '加载中...' });
// API
const result = await this.request('getRecord?userId=' + this.userId, 'GET', {});
console.log(result);
this.recordList = result.data;
// 使
console.log('加载领取记录...');
} catch (error) {
console.error('加载领取记录失败:', error);
}
uni.hideLoading();
},
closeRecordPop() {
this.$refs.recordPop.close();
},
async seleImg() {
try {
uni.showLoading({ title: '处理中...' });
const { base64, path } = await processImage();
console.log('最终Base64长度:', base64.length, path);
this.imagePath = path;
this.base64 = base64;
uni.showToast({ title: '上传成功' });
} catch (err) {
console.error('处理失败', err);
uni.showToast({ title: '处理失败', icon: 'none' });
} finally {
uni.hideLoading();
}
},
methods: {
openReceivePop() {
this.$refs.receivePop.open();
},
validateForm() {
if (!this.name.trim()) {
uni.showToast({ title: '请填写姓名', icon: 'none' });
return false;
}
if (!this.phone.trim()) {
uni.showToast({ title: '请填写联系方式', icon: 'none' });
return false;
}
if (!this.workUnit.trim()) {
uni.showToast({ title: '请填写工作单位', icon: 'none' });
return false;
}
if (!this.address.trim()) {
uni.showToast({ title: '请填写收货地址', icon: 'none' });
return false;
}
if (!this.model.trim()) {
uni.showToast({ title: '请填写设备型号', icon: 'none' });
return false;
}
if (!this.number.trim()) {
uni.showToast({ title: '请填写出品编号', icon: 'none' });
return false;
}
if (!this.createTime.trim()) {
uni.showToast({ title: '请填写出品年月', icon: 'none' });
return false;
}
if (!this.imagePath) {
uni.showToast({ title: '请上传产品铭牌照片', icon: 'none' });
return false;
}
return true;
},
closeReceivePop() {
this.$refs.receivePop.close();
},
async submitForm() {
if (!this.validateForm()) {
return;
}
openRecordPop() {
this.$refs.recordPop.open();
},
uni.showLoading({ title: '提交中...' });
closeRecordPop() {
this.$refs.recordPop.close();
},
try {
const formData = {
UserId: this.userId,
Name: this.name,
Phone: this.phone,
Company: this.workUnit,
Address: this.address,
ProductModel: this.model,
ProductSerialNumber: this.number,
ProductDate: this.createTime,
ProductImage: this.base64
};
seleImg() {
uni.chooseImage({
count: 1, // 9
sizeType: ['original', 'compressed'], //
sourceType: ['album', 'camera'], //
success: function(res) {
//
this.imagePath = res.tempFilePaths[0];
// API
const result = await this.request('addRecord', 'POST', formData);
console.log(result);
if (result.code == 200) {
uni.showToast({ title: '提交成功,请等待审核', icon: 'success' });
this.closeReceivePop();
this.clearForm();
} else {
uni.showToast({ title: '提交失败,请重试', icon: 'none' });
console.log('选择的图片路径:', tempFilePaths);
//
}
uni.hideLoading();
} catch (error) {
uni.hideLoading();
uni.showToast({ title: '提交失败,请重试', icon: 'none' });
console.error('提交失败:', error);
}
},
clearForm() {
this.name = '';
this.phone = '';
this.workUnit = '';
this.address = '';
this.model = '';
this.number = '';
this.createTime = '';
this.imagePath = '';
this.base64 = '';
},
previewImage() {
if (this.imagePath) {
uni.previewImage({
current: this.imagePath,
urls: [this.imagePath],
success: function (res) {
console.log('预览图片成功');
},
fail: function(err) {
console.log('选择图片失败:', err);
fail: function (err) {
console.error('预览图片失败:', err);
uni.showToast({ title: '预览失败', icon: 'none' });
}
});
}
}
}
}
</script>
<style>
.content {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: relative;
}
.content {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: relative;
}
</style>

View File

@ -0,0 +1,22 @@
## 1.2.32025-04-14
- 新增 左侧自定义插槽,可自定义文字或图标
## 1.2.22023-12-20
- 修复动态绑定title时滚动速度不一致的问题
## 1.2.12022-09-05
- 新增 属性 fontSize可修改文字大小。
## 1.2.02021-11-19
- 优化 组件UI并提供设计资源详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-notice-bar](https://uniapp.dcloud.io/component/uniui/uni-notice-bar)
## 1.1.12021-11-09
- 新增 提供组件设计资源,组件样式调整
## 1.1.02021-07-30
- 组件兼容 vue3如何创建vue3项目详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.0.92021-05-12
- 新增 组件示例地址
## 1.0.82021-04-21
- 优化 添加依赖 uni-icons, 导入后自动下载依赖
## 1.0.72021-02-05
- 优化 组件引用关系通过uni_modules引用组件
## 1.0.62021-02-05
- 调整为uni_modules目录规范

View File

@ -0,0 +1,423 @@
<template>
<view v-if="show" class="uni-noticebar" :style="{ backgroundColor }" @click="onClick">
<slot v-if="showIcon === true || showIcon === 'true'" name="noticebarIcon">
<uni-icons class="uni-noticebar-icon" type="sound" :color="color" :size="fontSize * 1.5" />
</slot>
<view ref="textBox" class="uni-noticebar__content-wrapper" :class="{
'uni-noticebar__content-wrapper--scrollable': scrollable,
'uni-noticebar__content-wrapper--single': !scrollable && (single || moreText)
}" :style="{ height: scrollable ? fontSize * 1.5 + 'px' : 'auto' }">
<view :id="elIdBox" class="uni-noticebar__content" :class="{
'uni-noticebar__content--scrollable': scrollable,
'uni-noticebar__content--single': !scrollable && (single || moreText)
}">
<text :id="elId" ref="animationEle" class="uni-noticebar__content-text" :class="{
'uni-noticebar__content-text--scrollable': scrollable,
'uni-noticebar__content-text--single': !scrollable && (single || showGetMore)
}" :style="{
color: color,
fontSize: fontSize + 'px',
lineHeight: fontSize * 1.5 + 'px',
width: wrapWidth + 'px',
'animationDuration': animationDuration,
'-webkit-animationDuration': animationDuration,
animationPlayState: webviewHide ? 'paused' : animationPlayState,
'-webkit-animationPlayState': webviewHide ? 'paused' : animationPlayState,
animationDelay: animationDelay,
'-webkit-animationDelay': animationDelay
}">{{text}}</text>
</view>
</view>
<view v-if="isShowGetMore" class="uni-noticebar__more uni-cursor-point" @click="clickMore">
<text v-if="moreText.length > 0" :style="{ color: moreColor, fontSize: fontSize + 'px' }">{{ moreText }}</text>
<uni-icons v-else type="right" :color="moreColor" :size="fontSize * 1.1" />
</view>
<view class="uni-noticebar-close uni-cursor-point" v-if="isShowClose">
<uni-icons type="closeempty" :color="color" :size="fontSize * 1.1" @click="close" />
</view>
</view>
</template>
<script>
// #ifdef APP-NVUE
const dom = weex.requireModule('dom');
const animation = weex.requireModule('animation');
// #endif
/**
* NoticeBar 自定义导航栏
* @description 通告栏组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=30
* @property {Number} speed 文字滚动的速度默认100px/
* @property {String} text 显示文字
* @property {String} backgroundColor 背景颜色
* @property {String} color 文字颜色
* @property {String} moreColor 查看更多文字的颜色
* @property {String} moreText 设置查看更多的文本
* @property {Boolean} single = [true|false] 是否单行
* @property {Boolean} scrollable = [true|false] 是否滚动为true时NoticeBar为单行
* @property {Boolean} showIcon = [true|false] 是否显示左侧喇叭图标
* @property {Boolean} showClose = [true|false] 是否显示左侧关闭按钮
* @property {Boolean} showGetMore = [true|false] 是否显示右侧查看更多图标为true时NoticeBar为单行
* @event {Function} click 点击 NoticeBar 触发事件
* @event {Function} close 关闭 NoticeBar 触发事件
* @event {Function} getmore 点击查看更多时触发事件
*/
export default {
name: 'UniNoticeBar',
emits: ['click', 'getmore', 'close'],
props: {
text: {
type: String,
default: ''
},
moreText: {
type: String,
default: ''
},
backgroundColor: {
type: String,
default: '#FFF9EA'
},
speed: {
// 1s100px
type: Number,
default: 100
},
color: {
type: String,
default: '#FF9A43'
},
fontSize: {
type: Number,
default: 14
},
moreColor: {
type: String,
default: '#FF9A43'
},
single: {
//
type: [Boolean, String],
default: false
},
scrollable: {
//
type: [Boolean, String],
default: false
},
showIcon: {
// icon
type: [Boolean, String],
default: false
},
showGetMore: {
//
type: [Boolean, String],
default: false
},
showClose: {
//
type: [Boolean, String],
default: false
}
},
data() {
const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
const elIdBox = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
return {
textWidth: 0,
boxWidth: 0,
wrapWidth: '',
webviewHide: false,
// #ifdef APP-NVUE
stopAnimation: false,
// #endif
elId: elId,
elIdBox: elIdBox,
show: true,
animationDuration: 'none',
animationPlayState: 'paused',
animationDelay: '0s'
}
},
watch: {
text(newValue, oldValue) {
this.initSize();
}
},
computed: {
isShowGetMore() {
return this.showGetMore === true || this.showGetMore === 'true'
},
isShowClose() {
return (this.showClose === true || this.showClose === 'true') &&
(this.showGetMore === false || this.showGetMore === 'false')
}
},
mounted() {
// #ifdef APP-PLUS
var pages = getCurrentPages();
var page = pages[pages.length - 1];
var currentWebview = page.$getAppWebview();
currentWebview.addEventListener('hide', () => {
this.webviewHide = true
})
currentWebview.addEventListener('show', () => {
this.webviewHide = false
})
// #endif
this.$nextTick(() => {
this.initSize()
})
},
// #ifdef APP-NVUE
beforeDestroy() {
this.stopAnimation = true
},
// #endif
methods: {
initSize() {
if (this.scrollable) {
// #ifndef APP-NVUE
let query = [],
boxWidth = 0,
textWidth = 0;
let textQuery = new Promise((resolve, reject) => {
uni.createSelectorQuery()
// #ifndef MP-ALIPAY
.in(this)
// #endif
.select(`#${this.elId}`)
.boundingClientRect()
.exec(ret => {
this.textWidth = ret[0].width
resolve()
})
})
let boxQuery = new Promise((resolve, reject) => {
uni.createSelectorQuery()
// #ifndef MP-ALIPAY
.in(this)
// #endif
.select(`#${this.elIdBox}`)
.boundingClientRect()
.exec(ret => {
this.boxWidth = ret[0].width
resolve()
})
})
query.push(textQuery)
query.push(boxQuery)
Promise.all(query).then(() => {
this.animationDuration = `${this.textWidth / this.speed}s`
this.animationDelay = `-${this.boxWidth / this.speed}s`
setTimeout(() => {
this.animationPlayState = 'running'
}, 1000)
})
// #endif
// #ifdef APP-NVUE
dom.getComponentRect(this.$refs['animationEle'], (res) => {
let winWidth = uni.getSystemInfoSync().windowWidth
this.textWidth = res.size.width
animation.transition(this.$refs['animationEle'], {
styles: {
transform: `translateX(-${winWidth}px)`
},
duration: 0,
timingFunction: 'linear',
delay: 0
}, () => {
if (!this.stopAnimation) {
animation.transition(this.$refs['animationEle'], {
styles: {
transform: `translateX(-${this.textWidth}px)`
},
timingFunction: 'linear',
duration: (this.textWidth - winWidth) / this.speed * 1000,
delay: 1000
}, () => {
if (!this.stopAnimation) {
this.loopAnimation()
}
});
}
});
})
// #endif
}
// #ifdef APP-NVUE
if (!this.scrollable && (this.single || this.moreText)) {
dom.getComponentRect(this.$refs['textBox'], (res) => {
this.wrapWidth = res.size.width
})
}
// #endif
},
loopAnimation() {
// #ifdef APP-NVUE
animation.transition(this.$refs['animationEle'], {
styles: {
transform: `translateX(0px)`
},
duration: 0
}, () => {
if (!this.stopAnimation) {
animation.transition(this.$refs['animationEle'], {
styles: {
transform: `translateX(-${this.textWidth}px)`
},
duration: this.textWidth / this.speed * 1000,
timingFunction: 'linear',
delay: 0
}, () => {
if (!this.stopAnimation) {
this.loopAnimation()
}
});
}
});
// #endif
},
clickMore() {
this.$emit('getmore')
},
close() {
this.show = false;
this.$emit('close')
},
onClick() {
this.$emit('click')
}
}
}
</script>
<style lang="scss" scoped>
.uni-noticebar {
/* #ifndef APP-NVUE */
display: flex;
width: 100%;
box-sizing: border-box;
/* #endif */
flex-direction: row;
align-items: center;
padding: 10px 12px;
margin-bottom: 10px;
}
.uni-cursor-point {
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-noticebar-close {
margin-left: 8px;
margin-right: 5px;
}
.uni-noticebar-icon {
margin-right: 5px;
}
.uni-noticebar__content-wrapper {
flex: 1;
flex-direction: column;
overflow: hidden;
}
.uni-noticebar__content-wrapper--single {
/* #ifndef APP-NVUE */
line-height: 18px;
/* #endif */
}
.uni-noticebar__content-wrapper--single,
.uni-noticebar__content-wrapper--scrollable {
flex-direction: row;
}
/* #ifndef APP-NVUE */
.uni-noticebar__content-wrapper--scrollable {
position: relative;
}
/* #endif */
.uni-noticebar__content--scrollable {
/* #ifdef APP-NVUE */
flex: 0;
/* #endif */
/* #ifndef APP-NVUE */
flex: 1;
display: block;
overflow: hidden;
/* #endif */
}
.uni-noticebar__content--single {
/* #ifndef APP-NVUE */
display: flex;
flex: none;
width: 100%;
justify-content: center;
/* #endif */
}
.uni-noticebar__content-text {
font-size: 14px;
line-height: 18px;
/* #ifndef APP-NVUE */
word-break: break-all;
/* #endif */
}
.uni-noticebar__content-text--single {
/* #ifdef APP-NVUE */
lines: 1;
/* #endif */
/* #ifndef APP-NVUE */
display: block;
width: 100%;
white-space: nowrap;
/* #endif */
overflow: hidden;
text-overflow: ellipsis;
}
.uni-noticebar__content-text--scrollable {
/* #ifdef APP-NVUE */
lines: 1;
padding-left: 750rpx;
/* #endif */
/* #ifndef APP-NVUE */
position: absolute;
display: block;
height: 18px;
line-height: 18px;
white-space: nowrap;
padding-left: 100%;
animation: notice 10s 0s linear infinite both;
animation-play-state: paused;
/* #endif */
}
.uni-noticebar__more {
/* #ifndef APP-NVUE */
display: inline-flex;
/* #endif */
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
padding-left: 5px;
}
@keyframes notice {
100% {
transform: translate3d(-100%, 0, 0);
}
}
</style>

View File

@ -0,0 +1,90 @@
{
"id": "uni-notice-bar",
"displayName": "uni-notice-bar 通告栏",
"version": "1.2.3",
"description": "NoticeBar 通告栏组件,常用于展示公告信息,可设为滚动公告",
"keywords": [
"uni-ui",
"uniui",
"通告栏",
"公告",
"跑马灯"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
"type": "component-vue"
},
"uni_modules": {
"dependencies": [
"uni-scss",
"uni-icons"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y",
"alipay": "n"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y",
"app-harmony": "u",
"app-uvue": "u"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}

View File

@ -0,0 +1,13 @@
## NoticeBar 通告栏
> **组件名uni-notice-bar**
> 代码块: `uNoticeBar`
通告栏组件 。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-notice-bar)
#### 如使用过程中有任何问题或者您对uni-ui有一些好的建议欢迎加入 uni-ui 交流群871950839

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"version":3,"file":"app.js","sources":["App.vue","main.js"],"sourcesContent":["<script>\r\n\texport default {\r\n\t\tonLaunch: function() {\r\n\t\t\tconsole.log('App Launch')\r\n\t\t},\r\n\t\tonShow: function() {\r\n\t\t\tconsole.log('App Show')\r\n\t\t},\r\n\t\tonHide: function() {\r\n\t\t\tconsole.log('App Hide')\r\n\t\t}\r\n\t}\r\n</script>\r\n\r\n<style>\r\n\t/*每个页面公共css */\r\n\t.column {\r\n\t\tdisplay: flex;\r\n\t\tflex-direction: column;\r\n\t}\r\n\r\n\t.row {\r\n\t\tdisplay: flex;\r\n\t\tflex-direction: row;\r\n\t}\r\n\r\n\t.center {\r\n\t\tdisplay: flex;\r\n\t\talign-items: center;\r\n\t\tjustify-content: center;\r\n\t}\r\n</style>","import App from './App'\n\n// #ifndef VUE3\nimport Vue from 'vue'\nimport './uni.promisify.adaptor'\nVue.config.productionTip = false\nApp.mpType = 'app'\nconst app = new Vue({\n ...App\n})\napp.$mount()\n// #endif\n\n// #ifdef VUE3\nimport { createSSRApp } from 'vue'\nexport function createApp() {\n const app = createSSRApp(App)\n return {\n app\n }\n}\n// #endif"],"names":["uni","createSSRApp","App"],"mappings":";;;;;;AACC,MAAK,YAAU;AAAA,EACd,UAAU,WAAW;AACpBA,kBAAAA,MAAA,MAAA,OAAA,gBAAY,YAAY;AAAA,EACxB;AAAA,EACD,QAAQ,WAAW;AAClBA,kBAAAA,MAAY,MAAA,OAAA,gBAAA,UAAU;AAAA,EACtB;AAAA,EACD,QAAQ,WAAW;AAClBA,kBAAAA,MAAY,MAAA,OAAA,iBAAA,UAAU;AAAA,EACvB;AACD;ACIM,SAAS,YAAY;AAC1B,QAAM,MAAMC,cAAY,aAACC,SAAG;AAC5B,SAAO;AAAA,IACL;AAAA,EACD;AACH;;;"}
{"version":3,"file":"app.js","sources":["App.vue","main.js"],"sourcesContent":["<script>\r\n\texport default {\r\n\t\tonLaunch: function() {\r\n\t\t\tconsole.log('App Launch')\r\n\t\t},\r\n\t\tonShow: function() {\r\n\t\t\tconsole.log('App Show')\r\n\t\t},\r\n\t\tonHide: function() {\r\n\t\t\tconsole.log('App Hide')\r\n\t\t}\r\n\t}\r\n</script>\r\n\r\n<style>\r\n\t/*每个页面公共css */\r\n\t.column {\r\n\t\tdisplay: flex;\r\n\t\tflex-direction: column;\r\n\t}\r\n\r\n\t.row {\r\n\t\tdisplay: flex;\r\n\t\tflex-direction: row;\r\n\t}\r\n\r\n\t.center {\r\n\t\tdisplay: flex;\r\n\t\talign-items: center;\r\n\t\tjustify-content: center;\r\n\t}\r\n</style>","import App from './App'\r\n\r\n// #ifndef VUE3\r\nimport Vue from 'vue'\r\nimport './uni.promisify.adaptor'\r\nVue.config.productionTip = false\r\nApp.mpType = 'app'\r\nconst app = new Vue({\r\n ...App\r\n})\r\napp.$mount()\r\n// #endif\r\n\r\n// #ifdef VUE3\r\nimport { createSSRApp } from 'vue'\r\nexport function createApp() {\r\n const app = createSSRApp(App)\r\n return {\r\n app\r\n }\r\n}\r\n// #endif"],"names":["uni","createSSRApp","App"],"mappings":";;;;;;AACC,MAAK,YAAU;AAAA,EACd,UAAU,WAAW;AACpBA,kBAAAA,MAAA,MAAA,OAAA,gBAAY,YAAY;AAAA,EACxB;AAAA,EACD,QAAQ,WAAW;AAClBA,kBAAAA,MAAY,MAAA,OAAA,gBAAA,UAAU;AAAA,EACtB;AAAA,EACD,QAAQ,WAAW;AAClBA,kBAAAA,MAAY,MAAA,OAAA,iBAAA,UAAU;AAAA,EACvB;AACD;ACIM,SAAS,YAAY;AAC1B,QAAM,MAAMC,cAAY,aAACC,SAAG;AAC5B,SAAO;AAAA,IACL;AAAA,EACD;AACH;;;"}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,173 @@
"use strict";
const common_vendor = require("./vendor.js");
const getFileSize = async (filePath) => {
try {
const res = await new Promise((resolve, reject) => {
common_vendor.wx$1.getFileSystemManager().getFileInfo({
filePath,
success: resolve,
fail: reject
});
});
return res.size || Infinity;
} catch (err) {
common_vendor.index.__f__("error", "at common/utils.js:34", "获取文件大小失败:", err);
return Infinity;
}
};
const doCompressImage = (src, quality) => {
return new Promise((resolve) => {
common_vendor.index.compressImage({
src,
quality,
success: (res) => resolve(res.tempFilePath),
fail: () => resolve(src)
// 失败返回原路径
});
});
};
const preciseCompress = async (tempFilePath, targetSize = 500 * 1024, initialQuality = 85) => {
let quality = initialQuality;
let compressedPath = tempFilePath;
let currentSize = Infinity;
let iterations = 0;
const maxIterations = 10;
const history = [];
const originalSize = await getFileSize(tempFilePath);
if (originalSize <= targetSize) {
return { path: tempFilePath, quality: 100, iterations: 0, finalSize: originalSize };
}
const predictQualityRange = (originalSize2, targetSize2) => {
const ratio = targetSize2 / originalSize2;
if (ratio > 0.8)
return { low: 70, high: 95 };
if (ratio > 0.5)
return { low: 45, high: 75 };
if (ratio > 0.3)
return { low: 25, high: 50 };
if (ratio > 0.1)
return { low: 10, high: 30 };
return { low: 5, high: 15 };
};
const { low: predictedLow, high: predictedHigh } = predictQualityRange(originalSize, targetSize);
let low = predictedLow;
let high = Math.min(predictedHigh, initialQuality);
common_vendor.index.__f__("log", "at common/utils.js:132", `预测质量范围: ${low}-${high} (原图${(originalSize / 1024).toFixed(2)}KB → 目标${(targetSize / 1024).toFixed(2)}KB)`);
const adjustBounds = (currentQuality, currentSize2, targetSize2) => {
const sizeRatio = currentSize2 / targetSize2;
const qualityDelta = Math.max(2, Math.floor(currentQuality * 0.1));
if (sizeRatio > 2.5) {
return { lowDelta: -qualityDelta * 2, highDelta: -qualityDelta };
} else if (sizeRatio > 1.5) {
return { lowDelta: -qualityDelta, highDelta: -Math.floor(qualityDelta / 2) };
} else if (sizeRatio > 1.1) {
return { lowDelta: -3, highDelta: -1 };
} else {
return { lowDelta: -1, highDelta: 0 };
}
};
let bestResult = null;
while (iterations < maxIterations && low <= high) {
iterations++;
quality = Math.floor((low + high) / 2);
if (history.some((item) => item.quality === quality)) {
break;
}
compressedPath = await doCompressImage(tempFilePath, quality);
currentSize = await getFileSize(compressedPath);
history.push({ quality, size: currentSize });
common_vendor.index.__f__("log", "at common/utils.js:165", `${iterations}次尝试: quality=${quality}${(currentSize / 1024).toFixed(2)}KB (目标${(targetSize / 1024).toFixed(2)}KB)`);
if (!bestResult || Math.abs(currentSize - targetSize) < Math.abs(bestResult.size - targetSize)) {
bestResult = { quality, size: currentSize, path: compressedPath };
}
if (Math.abs(currentSize - targetSize) < targetSize * 0.03) {
common_vendor.index.__f__("log", "at common/utils.js:174", "✅ 达到精准匹配,提前结束");
break;
}
if (currentSize > targetSize) {
const { lowDelta, highDelta } = adjustBounds(quality, currentSize, targetSize);
high = Math.max(5, quality + highDelta);
} else {
low = quality + 1;
}
if (high - low <= 1)
break;
}
if (bestResult && bestResult.size > targetSize * 1.1) {
common_vendor.index.__f__("log", "at common/utils.js:191", "🔥 尝试极限压缩...");
const extremePath = await doCompressImage(tempFilePath, 5);
const extremeSize = await getFileSize(extremePath);
common_vendor.index.__f__("log", "at common/utils.js:194", `极限压缩结果: quality=5 → ${(extremeSize / 1024).toFixed(2)}KB`);
if (extremeSize < bestResult.size) {
bestResult = { quality: 5, size: extremeSize, path: extremePath };
}
}
const finalResult = bestResult || { quality: 10, size: currentSize, path: compressedPath };
common_vendor.index.__f__("log", "at common/utils.js:203", `🎯 最终结果quality=${finalResult.quality}${(finalResult.size / 1024).toFixed(2)}KB迭代${iterations}次,压缩率${((1 - finalResult.size / originalSize) * 100).toFixed(1)}%`);
return {
path: finalResult.path,
quality: finalResult.quality,
iterations,
finalSize: finalResult.size
};
};
const imageToBase64 = (filePath) => {
return new Promise((resolve, reject) => {
common_vendor.index.getImageInfo({
src: filePath,
success: (info) => {
const type = info.type || "jpeg";
common_vendor.index.getFileSystemManager().readFile({
filePath,
encoding: "base64",
success: (res) => resolve(`data:image/${type};base64,${res.data}`),
fail: reject
});
},
fail: () => {
common_vendor.index.getFileSystemManager().readFile({
filePath,
encoding: "base64",
success: (res) => resolve(`data:image/jpeg;base64,${res.data}`),
fail: reject
});
}
});
});
};
const processImage = async (maxSize = 500 * 1024) => {
const chooseRes = await new Promise((resolve) => {
common_vendor.index.chooseImage({
count: 1,
sizeType: ["original", "compressed"],
success: resolve,
fail: () => resolve(null)
});
});
if (!chooseRes)
throw new Error("选择图片失败");
const tempFilePath = chooseRes.tempFilePaths[0];
let finalPath = tempFilePath;
let isCompressed = false;
const fileSize = await getFileSize(tempFilePath);
common_vendor.index.__f__("log", "at common/utils.js:272", `原图大小: ${(fileSize / 1024).toFixed(2)}KB`);
if (fileSize > maxSize) {
common_vendor.index.__f__("log", "at common/utils.js:276", "🔄 开始智能压缩...");
const compressResult = await preciseCompress(tempFilePath, maxSize);
finalPath = compressResult.path;
isCompressed = true;
common_vendor.index.__f__("log", "at common/utils.js:282", `✅ 压缩完成: ${(fileSize / 1024).toFixed(2)}KB → ${(compressResult.finalSize / 1024).toFixed(2)}KB (节省${((1 - compressResult.finalSize / fileSize) * 100).toFixed(1)}%)`);
}
const base64 = await imageToBase64(finalPath);
common_vendor.index.__f__("log", "at common/utils.js:288", `📄 Base64长度: ${base64.length} 字符`);
return {
base64,
// Base64字符串
path: finalPath,
// 最终文件路径(可能是原图或压缩图)
compressed: isCompressed
// 是否经过压缩
};
};
exports.processImage = processImage;
//# sourceMappingURL=../../.sourcemap/mp-weixin/common/utils.js.map

View File

@ -2671,11 +2671,15 @@ const getPublicInstance = (i) => {
return getExposeProxy(i) || i.proxy;
return getPublicInstance(i.parent);
};
function getComponentInternalInstance(i) {
return i;
}
const publicPropertiesMap = (
// Move PURE marker to new line to workaround compiler discarding it
// due to type annotation
/* @__PURE__ */ extend(/* @__PURE__ */ Object.create(null), {
$: (i) => i,
// fixed by xxxxxx
$: getComponentInternalInstance,
// fixed by xxxxxx vue-i18n 在 dev 模式,访问了 $el故模拟一个假的
// $el: i => i.vnode.el,
$el: (i) => i.__$el || (i.__$el = {}),
@ -4546,6 +4550,7 @@ function warnRef(ref2) {
const queuePostRenderEffect = queuePostFlushCb;
function mountComponent(initialVNode, options) {
const instance = initialVNode.component = createComponentInstance(initialVNode, options.parentComponent, null);
instance.renderer = options.mpType ? options.mpType : "component";
{
instance.ctx.$onApplyOptions = onApplyOptions;
instance.ctx.$children = [];
@ -4884,7 +4889,8 @@ function injectLifecycleHook(name, hook, publicThis, instance) {
}
function initHooks$1(options, instance, publicThis) {
const mpType = options.mpType || publicThis.$mpType;
if (!mpType || mpType === "component") {
if (!mpType || mpType === "component" || // instance.renderer 标识页面是否作为组件渲染
mpType === "page" && instance.renderer === "component") {
return;
}
Object.keys(options).forEach((name) => {
@ -5540,10 +5546,10 @@ function handlePromise(promise) {
function promisify$1(name, fn) {
return (args = {}, ...rest) => {
if (hasCallback(args)) {
return wrapperReturnValue(name, invokeApi(name, fn, args, rest));
return wrapperReturnValue(name, invokeApi(name, fn, extend({}, args), rest));
}
return wrapperReturnValue(name, handlePromise(new Promise((resolve2, reject) => {
invokeApi(name, fn, extend(args, { success: resolve2, fail: reject }), rest);
invokeApi(name, fn, extend({}, args, { success: resolve2, fail: reject }), rest);
})));
};
}
@ -5940,7 +5946,7 @@ function promisify(name, api) {
}
return function promiseApi(options = {}, ...rest) {
if (isFunction(options.success) || isFunction(options.fail) || isFunction(options.complete)) {
return wrapperReturnValue(name, invokeApi(name, api, options, rest));
return wrapperReturnValue(name, invokeApi(name, api, extend({}, options), rest));
}
return wrapperReturnValue(name, handlePromise(new Promise((resolve2, reject) => {
invokeApi(name, api, extend({}, options, {
@ -6107,7 +6113,7 @@ function getOSInfo(system, platform) {
osName = system.split(" ")[0] || platform;
osVersion = system.split(" ")[1] || "";
}
osName = osName.toLocaleLowerCase();
osName = osName.toLowerCase();
switch (osName) {
case "harmony":
case "ohos":
@ -6147,9 +6153,9 @@ function populateParameters(fromRes, toRes) {
appVersion: "1.0.0",
appVersionCode: "100",
appLanguage: getAppLanguage(hostLanguage),
uniCompileVersion: "4.65",
uniCompilerVersion: "4.65",
uniRuntimeVersion: "4.65",
uniCompileVersion: "4.75",
uniCompilerVersion: "4.75",
uniRuntimeVersion: "4.75",
uniPlatform: "mp-weixin",
deviceBrand,
deviceModel: model,
@ -6186,7 +6192,7 @@ function getGetDeviceType(fromRes, model) {
mac: "pc"
};
const deviceTypeMapsKeys = Object.keys(deviceTypeMaps);
const _model = model.toLocaleLowerCase();
const _model = model.toLowerCase();
for (let index2 = 0; index2 < deviceTypeMapsKeys.length; index2++) {
const _m = deviceTypeMapsKeys[index2];
if (_model.indexOf(_m) !== -1) {
@ -6200,7 +6206,7 @@ function getGetDeviceType(fromRes, model) {
function getDeviceBrand(brand) {
let deviceBrand = brand;
if (deviceBrand) {
deviceBrand = deviceBrand.toLocaleLowerCase();
deviceBrand = deviceBrand.toLowerCase();
}
return deviceBrand;
}
@ -6298,9 +6304,9 @@ const getAppBaseInfo = {
appLanguage: getAppLanguage(hostLanguage),
isUniAppX: false,
uniPlatform: "mp-weixin",
uniCompileVersion: "4.65",
uniCompilerVersion: "4.65",
uniRuntimeVersion: "4.65"
uniCompileVersion: "4.75",
uniCompilerVersion: "4.75",
uniRuntimeVersion: "4.75"
};
extend(toRes, parameters);
}
@ -6973,14 +6979,14 @@ const atFileRegex = /^\s*at\s+[\w/./-]+:\d+$/;
function rewriteConsole() {
function wrapConsole(type) {
return function(...args) {
const originalArgs = [...args];
if (originalArgs.length) {
const maybeAtFile = originalArgs[originalArgs.length - 1];
if (typeof maybeAtFile === "string" && atFileRegex.test(maybeAtFile)) {
originalArgs.pop();
}
}
{
const originalArgs = [...args];
if (originalArgs.length) {
const maybeAtFile = originalArgs[originalArgs.length - 1];
if (typeof maybeAtFile === "string" && atFileRegex.test(maybeAtFile)) {
originalArgs.pop();
}
}
originalConsole[type](...originalArgs);
}
if (type === "error" && args.length === 1) {
@ -7040,9 +7046,9 @@ function isConsoleWritable() {
return isWritable;
}
function initRuntimeSocketService() {
const hosts = "172.23.128.1,192.168.1.7,192.168.195.32,127.0.0.1";
const hosts = "192.168.1.21,192.168.195.35,127.0.0.1";
const port = "8090";
const id = "mp-weixin_GnOukJ";
const id = "mp-weixin_XlaJbP";
const lazy = typeof swan !== "undefined";
let restoreError = lazy ? () => {
} : initOnError();
@ -8000,4 +8006,5 @@ exports.resolveComponent = resolveComponent;
exports.s = s;
exports.sr = sr;
exports.t = t;
exports.wx$1 = wx$1;
//# sourceMappingURL=../../.sourcemap/mp-weixin/common/vendor.js.map

View File

@ -1,88 +1,234 @@
"use strict";
const common_vendor = require("../../common/vendor.js");
const common_utils = require("../../common/utils.js");
const common_assets = require("../../common/assets.js");
const uniNoticeBar = () => "../../uni_modules/uni-notice-bar/components/uni-notice-bar/uni-notice-bar.js";
const _sfc_main = {
components: {
uniNoticeBar
},
onLoad() {
var userId = common_vendor.index.getStorageSync("user_id");
if (!userId || userId == 0) {
this.login();
}
this.userId = userId;
},
data() {
return {
userId: 0,
imagePath: "",
name: "",
phone: "",
base64: "",
workUnit: "",
address: "",
createTime: "",
number: "",
model: "",
recordList: [
{
name: "苏家辉",
time: "2025-5-25",
address: "江苏省徐州市睢宁县xx小区xx花园20-601",
phone: "13025555555"
},
{
name: "苏家辉",
time: "2025-5-25",
address: "江苏省徐州市睢宁县",
phone: "13025555555"
},
{
name: "苏家辉",
time: "2025-5-25",
address: "江苏省徐州市睢宁县",
phone: "13025555555"
},
{
name: "苏家辉",
time: "2025-5-25",
address: "江苏省徐州市睢宁县",
phone: "13025555555"
},
{
name: "苏家辉",
time: "2025-5-25",
address: "江苏省徐州市睢宁县",
phone: "13025555555"
}
]
recordList: []
};
},
onLoad() {
},
methods: {
request(url, method, data) {
return new Promise((resolve, reject) => {
const header = {};
if (method == "post") {
header["content-type"] = "application/json";
}
common_vendor.index.request({
url: "http://localhost:8888/" + url,
method,
data,
header,
timeout: 1e4,
success: (res) => {
common_vendor.index.__f__("log", "at pages/index/index.vue:194", "API响应:", res);
if (res.statusCode === 200) {
resolve(res.data);
} else {
reject(new Error(`请求失败,状态码: ${res.statusCode}`));
}
},
fail: (err) => {
common_vendor.index.__f__("error", "at pages/index/index.vue:202", "API请求失败:", err);
reject(err);
}
});
});
},
wxLogin() {
return new Promise((resolve, reject) => {
common_vendor.index.login({
provider: "weixin",
//使用微信登录
onlyAuthorize: true,
success: async function(res) {
resolve(res.code);
},
fail: function(err) {
reject(err);
}
});
});
},
async login() {
try {
const wxCode = await this.wxLogin();
if (wxCode) {
const res = await this.request("userLogin?code=" + wxCode, "post", {});
if (res.code == 200) {
common_vendor.index.setStorageSync("user_id", res.data.user_id);
this.userId = res.data.user_id;
common_vendor.index.__f__("log", "at pages/index/index.vue:232", "登录成功, userId:", this.userId);
} else {
common_vendor.index.__f__("error", "at pages/index/index.vue:234", "登录失败:", res.message);
}
}
} catch (error) {
common_vendor.index.__f__("error", "at pages/index/index.vue:238", "登录过程出错:", error);
}
},
openReceivePop() {
this.$refs.receivePop.open();
},
closeReceivePop() {
this.$refs.receivePop.close();
},
openRecordPop() {
async openRecordPop() {
await this.loadRecordList();
this.$refs.recordPop.open();
},
async loadRecordList() {
try {
common_vendor.index.showLoading({ title: "加载中..." });
const result = await this.request("getRecord?userId=" + this.userId, "GET", {});
common_vendor.index.__f__("log", "at pages/index/index.vue:259", result);
this.recordList = result.data;
common_vendor.index.__f__("log", "at pages/index/index.vue:264", "加载领取记录...");
} catch (error) {
common_vendor.index.__f__("error", "at pages/index/index.vue:266", "加载领取记录失败:", error);
}
common_vendor.index.hideLoading();
},
closeRecordPop() {
this.$refs.recordPop.close();
},
seleImg() {
common_vendor.index.chooseImage({
count: 1,
// 最多可选择图片数量默认9
sizeType: ["original", "compressed"],
// 可以指定是原图还是压缩图
sourceType: ["album", "camera"],
// 可以指定来源是相册还是相机
success: function(res) {
this.imagePath = res.tempFilePaths[0];
common_vendor.index.__f__("log", "at pages/index/index.vue:227", "选择的图片路径:", tempFilePaths);
},
fail: function(err) {
common_vendor.index.__f__("log", "at pages/index/index.vue:231", "选择图片失败:", err);
async seleImg() {
try {
common_vendor.index.showLoading({ title: "处理中..." });
const { base64, path } = await common_utils.processImage();
common_vendor.index.__f__("log", "at pages/index/index.vue:280", "最终Base64长度:", base64.length, path);
this.imagePath = path;
this.base64 = base64;
common_vendor.index.showToast({ title: "上传成功" });
} catch (err) {
common_vendor.index.__f__("error", "at pages/index/index.vue:285", "处理失败", err);
common_vendor.index.showToast({ title: "处理失败", icon: "none" });
} finally {
common_vendor.index.hideLoading();
}
},
validateForm() {
if (!this.name.trim()) {
common_vendor.index.showToast({ title: "请填写姓名", icon: "none" });
return false;
}
if (!this.phone.trim()) {
common_vendor.index.showToast({ title: "请填写联系方式", icon: "none" });
return false;
}
if (!this.workUnit.trim()) {
common_vendor.index.showToast({ title: "请填写工作单位", icon: "none" });
return false;
}
if (!this.address.trim()) {
common_vendor.index.showToast({ title: "请填写收货地址", icon: "none" });
return false;
}
if (!this.model.trim()) {
common_vendor.index.showToast({ title: "请填写设备型号", icon: "none" });
return false;
}
if (!this.number.trim()) {
common_vendor.index.showToast({ title: "请填写出品编号", icon: "none" });
return false;
}
if (!this.createTime.trim()) {
common_vendor.index.showToast({ title: "请填写出品年月", icon: "none" });
return false;
}
if (!this.imagePath) {
common_vendor.index.showToast({ title: "请上传产品铭牌照片", icon: "none" });
return false;
}
return true;
},
async submitForm() {
if (!this.validateForm()) {
return;
}
common_vendor.index.showLoading({ title: "提交中..." });
try {
const formData = {
UserId: this.userId,
Name: this.name,
Phone: this.phone,
Company: this.workUnit,
Address: this.address,
ProductModel: this.model,
ProductSerialNumber: this.number,
ProductDate: this.createTime,
ProductImage: this.base64
};
const result = await this.request("addRecord", "POST", formData);
common_vendor.index.__f__("log", "at pages/index/index.vue:351", result);
if (result.code == 200) {
common_vendor.index.showToast({ title: "提交成功,请等待审核", icon: "success" });
this.closeReceivePop();
this.clearForm();
} else {
common_vendor.index.showToast({ title: "提交失败,请重试", icon: "none" });
}
});
common_vendor.index.hideLoading();
} catch (error) {
common_vendor.index.hideLoading();
common_vendor.index.showToast({ title: "提交失败,请重试", icon: "none" });
common_vendor.index.__f__("error", "at pages/index/index.vue:365", "提交失败:", error);
}
},
clearForm() {
this.name = "";
this.phone = "";
this.workUnit = "";
this.address = "";
this.model = "";
this.number = "";
this.createTime = "";
this.imagePath = "";
this.base64 = "";
},
previewImage() {
if (this.imagePath) {
common_vendor.index.previewImage({
current: this.imagePath,
urls: [this.imagePath],
success: function(res) {
common_vendor.index.__f__("log", "at pages/index/index.vue:387", "预览图片成功");
},
fail: function(err) {
common_vendor.index.__f__("error", "at pages/index/index.vue:390", "预览图片失败:", err);
common_vendor.index.showToast({ title: "预览失败", icon: "none" });
}
});
}
}
}
};
if (!Array) {
const _component_uniNoticeBar = common_vendor.resolveComponent("uniNoticeBar");
const _easycom_uni_popup2 = common_vendor.resolveComponent("uni-popup");
_easycom_uni_popup2();
(_component_uniNoticeBar + _easycom_uni_popup2)();
}
const _easycom_uni_popup = () => "../../uni_modules/uni-popup/components/uni-popup/uni-popup.js";
if (!Math) {
@ -90,44 +236,57 @@ if (!Math) {
}
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
return common_vendor.e({
a: common_vendor.o((...args) => $options.openReceivePop && $options.openReceivePop(...args)),
b: common_vendor.o((...args) => $options.openRecordPop && $options.openRecordPop(...args)),
c: $data.name,
d: common_vendor.o(($event) => $data.name = $event.detail.value),
e: $data.phone,
f: common_vendor.o(($event) => $data.phone = $event.detail.value),
g: $data.workUnit,
h: common_vendor.o(($event) => $data.workUnit = $event.detail.value),
i: -1,
j: $data.address,
k: common_vendor.o(($event) => $data.address = $event.detail.value),
l: $data.model,
m: common_vendor.o(($event) => $data.model = $event.detail.value),
n: $data.number,
o: common_vendor.o(($event) => $data.number = $event.detail.value),
p: $data.createTime,
q: common_vendor.o(($event) => $data.createTime = $event.detail.value),
r: $data.imagePath
}, $data.imagePath ? {
s: $data.imagePath
} : {}, {
t: common_vendor.o((...args) => $options.seleImg && $options.seleImg(...args)),
v: common_vendor.sr("receivePop", "2241685c-0"),
w: common_vendor.p({
type: "center"
a: common_vendor.p({
showIcon: true,
single: true,
scrollable: true,
text: "赠品仅限线下购买设备的用户领取需人工审核预计3个工作日内完成",
["background-color"]: "transparent",
color: "#000"
}),
x: common_assets._imports_0,
y: common_vendor.o(($event) => $options.closeRecordPop()),
z: common_vendor.f($data.recordList, (item, index, i0) => {
b: common_vendor.o((...args) => $options.openReceivePop && $options.openReceivePop(...args)),
c: common_vendor.o((...args) => $options.openRecordPop && $options.openRecordPop(...args)),
d: $data.name,
e: common_vendor.o(($event) => $data.name = $event.detail.value),
f: $data.phone,
g: common_vendor.o(($event) => $data.phone = $event.detail.value),
h: $data.workUnit,
i: common_vendor.o(($event) => $data.workUnit = $event.detail.value),
j: -1,
k: $data.address,
l: common_vendor.o(($event) => $data.address = $event.detail.value),
m: $data.model,
n: common_vendor.o(($event) => $data.model = $event.detail.value),
o: $data.number,
p: common_vendor.o(($event) => $data.number = $event.detail.value),
q: $data.createTime,
r: common_vendor.o(($event) => $data.createTime = $event.detail.value),
s: common_vendor.o((...args) => $options.seleImg && $options.seleImg(...args)),
t: $data.imagePath
}, $data.imagePath ? {
v: $data.imagePath,
w: common_vendor.o((...args) => $options.previewImage && $options.previewImage(...args))
} : {}, {
x: common_vendor.o((...args) => $options.closeReceivePop && $options.closeReceivePop(...args)),
y: common_vendor.o((...args) => $options.submitForm && $options.submitForm(...args)),
z: common_vendor.sr("receivePop", "6e486efd-1"),
A: common_vendor.p({
type: "center",
["is-mask-click"]: false
}),
B: common_assets._imports_0,
C: common_vendor.o(($event) => $options.closeRecordPop()),
D: common_vendor.f($data.recordList, (item, k0, i0) => {
return {
a: common_vendor.t(item.name),
b: common_vendor.t(item.phone),
c: common_vendor.t(item.time),
d: common_vendor.t(item.address)
d: common_vendor.t(item.address),
e: item.phone + item.time
};
}),
A: common_vendor.sr("recordPop", "2241685c-1"),
B: common_vendor.p({
E: common_vendor.sr("recordPop", "6e486efd-2"),
F: common_vendor.p({
type: "center"
})
});

View File

@ -2,6 +2,7 @@
"navigationStyle": "custom",
"navigationBarTitleText": "",
"usingComponents": {
"uni-notice-bar": "../../uni_modules/uni-notice-bar/components/uni-notice-bar/uni-notice-bar",
"uni-popup": "../../uni_modules/uni-popup/components/uni-popup/uni-popup"
}
}

File diff suppressed because one or more lines are too long

View File

@ -1,10 +1,10 @@
.content {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: relative;
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: relative;
}

View File

@ -19,7 +19,7 @@
},
"compileType": "miniprogram",
"libVersion": "3.8.12",
"appid": "touristappid",
"appid": "wx595ec949c6efd72b",
"projectname": "gift",
"condition": {},
"editorSetting": {

View File

@ -1,7 +0,0 @@
{
"description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
"projectname": "gift",
"setting": {
"compileHotReLoad": true
}
}

View File

@ -0,0 +1,204 @@
"use strict";
const common_vendor = require("../../../../common/vendor.js");
const _sfc_main = {
name: "UniNoticeBar",
emits: ["click", "getmore", "close"],
props: {
text: {
type: String,
default: ""
},
moreText: {
type: String,
default: ""
},
backgroundColor: {
type: String,
default: "#FFF9EA"
},
speed: {
// 默认1s滚动100px
type: Number,
default: 100
},
color: {
type: String,
default: "#FF9A43"
},
fontSize: {
type: Number,
default: 14
},
moreColor: {
type: String,
default: "#FF9A43"
},
single: {
// 是否单行
type: [Boolean, String],
default: false
},
scrollable: {
// 是否滚动,添加后控制单行效果取消
type: [Boolean, String],
default: false
},
showIcon: {
// 是否显示左侧icon
type: [Boolean, String],
default: false
},
showGetMore: {
// 是否显示右侧查看更多
type: [Boolean, String],
default: false
},
showClose: {
// 是否显示左侧关闭按钮
type: [Boolean, String],
default: false
}
},
data() {
const elId = `Uni_${Math.ceil(Math.random() * 1e6).toString(36)}`;
const elIdBox = `Uni_${Math.ceil(Math.random() * 1e6).toString(36)}`;
return {
textWidth: 0,
boxWidth: 0,
wrapWidth: "",
webviewHide: false,
elId,
elIdBox,
show: true,
animationDuration: "none",
animationPlayState: "paused",
animationDelay: "0s"
};
},
watch: {
text(newValue, oldValue) {
this.initSize();
}
},
computed: {
isShowGetMore() {
return this.showGetMore === true || this.showGetMore === "true";
},
isShowClose() {
return (this.showClose === true || this.showClose === "true") && (this.showGetMore === false || this.showGetMore === "false");
}
},
mounted() {
this.$nextTick(() => {
this.initSize();
});
},
methods: {
initSize() {
if (this.scrollable) {
let query = [];
let textQuery = new Promise((resolve, reject) => {
common_vendor.index.createSelectorQuery().in(this).select(`#${this.elId}`).boundingClientRect().exec((ret) => {
this.textWidth = ret[0].width;
resolve();
});
});
let boxQuery = new Promise((resolve, reject) => {
common_vendor.index.createSelectorQuery().in(this).select(`#${this.elIdBox}`).boundingClientRect().exec((ret) => {
this.boxWidth = ret[0].width;
resolve();
});
});
query.push(textQuery);
query.push(boxQuery);
Promise.all(query).then(() => {
this.animationDuration = `${this.textWidth / this.speed}s`;
this.animationDelay = `-${this.boxWidth / this.speed}s`;
setTimeout(() => {
this.animationPlayState = "running";
}, 1e3);
});
}
},
loopAnimation() {
},
clickMore() {
this.$emit("getmore");
},
close() {
this.show = false;
this.$emit("close");
},
onClick() {
this.$emit("click");
}
}
};
if (!Array) {
const _component_uni_icons = common_vendor.resolveComponent("uni-icons");
_component_uni_icons();
}
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
return common_vendor.e({
a: $data.show
}, $data.show ? common_vendor.e({
b: $props.showIcon === true || $props.showIcon === "true"
}, $props.showIcon === true || $props.showIcon === "true" ? {
c: common_vendor.p({
type: "sound",
color: $props.color,
size: $props.fontSize * 1.5
})
} : {}, {
d: common_vendor.t($props.text),
e: $data.elId,
f: $props.scrollable ? 1 : "",
g: !$props.scrollable && ($props.single || $props.showGetMore) ? 1 : "",
h: $props.color,
i: $props.fontSize + "px",
j: $props.fontSize * 1.5 + "px",
k: $data.wrapWidth + "px",
l: $data.animationDuration,
m: $data.animationDuration,
n: $data.webviewHide ? "paused" : $data.animationPlayState,
o: $data.webviewHide ? "paused" : $data.animationPlayState,
p: $data.animationDelay,
q: $data.animationDelay,
r: $data.elIdBox,
s: $props.scrollable ? 1 : "",
t: !$props.scrollable && ($props.single || $props.moreText) ? 1 : "",
v: $props.scrollable ? 1 : "",
w: !$props.scrollable && ($props.single || $props.moreText) ? 1 : "",
x: $props.scrollable ? $props.fontSize * 1.5 + "px" : "auto",
y: $options.isShowGetMore
}, $options.isShowGetMore ? common_vendor.e({
z: $props.moreText.length > 0
}, $props.moreText.length > 0 ? {
A: common_vendor.t($props.moreText),
B: $props.moreColor,
C: $props.fontSize + "px"
} : {
D: common_vendor.p({
type: "right",
color: $props.moreColor,
size: $props.fontSize * 1.1
})
}, {
E: common_vendor.o((...args) => $options.clickMore && $options.clickMore(...args))
}) : {}, {
F: $options.isShowClose
}, $options.isShowClose ? {
G: common_vendor.o($options.close),
H: common_vendor.p({
type: "closeempty",
color: $props.color,
size: $props.fontSize * 1.1
})
} : {}, {
I: $props.backgroundColor,
J: common_vendor.o((...args) => $options.onClick && $options.onClick(...args))
}) : {});
}
const Component = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-c3453ea3"]]);
wx.createComponent(Component);
//# sourceMappingURL=../../../../../.sourcemap/mp-weixin/uni_modules/uni-notice-bar/components/uni-notice-bar/uni-notice-bar.js.map

View File

@ -0,0 +1,4 @@
{
"component": true,
"usingComponents": {}
}

View File

@ -0,0 +1 @@
<view wx:if="{{a}}" class="uni-noticebar data-v-c3453ea3" style="{{'background-color:' + I}}" bindtap="{{J}}"><block wx:if="{{b}}"><block wx:if="{{$slots.noticebarIcon}}"><slot name="noticebarIcon"></slot></block><block wx:else><uni-icons wx:if="{{c}}" class="uni-noticebar-icon data-v-c3453ea3" u-i="c3453ea3-0" bind:__l="__l" u-p="{{c}}"/></block></block><view ref="textBox" class="{{['uni-noticebar__content-wrapper', 'data-v-c3453ea3', v && 'uni-noticebar__content-wrapper--scrollable', w && 'uni-noticebar__content-wrapper--single']}}" style="{{'height:' + x}}"><view id="{{r}}" class="{{['uni-noticebar__content', 'data-v-c3453ea3', s && 'uni-noticebar__content--scrollable', t && 'uni-noticebar__content--single']}}"><text id="{{e}}" ref="animationEle" class="{{['uni-noticebar__content-text', 'data-v-c3453ea3', f && 'uni-noticebar__content-text--scrollable', g && 'uni-noticebar__content-text--single']}}" style="{{'color:' + h + ';' + ('font-size:' + i) + ';' + ('line-height:' + j) + ';' + ('width:' + k) + ';' + ('animation-duration:' + l) + ';' + ('-webkit-animation-duration:' + m) + ';' + ('animation-play-state:' + n) + ';' + ('-webkit-animation-play-state:' + o) + ';' + ('animation-delay:' + p) + ';' + ('-webkit-animation-delay:' + q)}}">{{d}}</text></view></view><view wx:if="{{y}}" class="uni-noticebar__more uni-cursor-point data-v-c3453ea3" bindtap="{{E}}"><text wx:if="{{z}}" class="data-v-c3453ea3" style="{{'color:' + B + ';' + ('font-size:' + C)}}">{{A}}</text><uni-icons wx:else class="data-v-c3453ea3" u-i="c3453ea3-1" bind:__l="__l" u-p="{{D||''}}"/></view><view wx:if="{{F}}" class="uni-noticebar-close uni-cursor-point data-v-c3453ea3"><uni-icons wx:if="{{H}}" class="data-v-c3453ea3" bindclick="{{G}}" u-i="c3453ea3-2" bind:__l="__l" u-p="{{H}}"/></view></view>

View File

@ -0,0 +1,101 @@
/**
* 这里是uni-app内置的常用样式变量
*
* uni-app 官方扩展插件及插件市场https://ext.dcloud.net.cn上很多三方插件均使用了这些样式变量
* 如果你是插件开发者建议你使用scss预处理并在插件代码中直接使用这些变量无需 import 这个文件方便用户通过搭积木的方式开发整体风格一致的App
*
*/
/**
* 如果你是App开发者插件使用者你可以通过修改这些变量来定制自己的插件主题实现自定义主题功能
*
* 如果你的项目同样使用了scss预处理你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
*/
/* 颜色变量 */
/* 行为相关颜色 */
/* 文字基本颜色 */
/* 背景颜色 */
/* 边框颜色 */
/* 尺寸变量 */
/* 文字尺寸 */
/* 图片尺寸 */
/* Border Radius */
/* 水平间距 */
/* 垂直间距 */
/* 透明度 */
/* 文章场景相关 */
.uni-noticebar.data-v-c3453ea3 {
display: flex;
width: 100%;
box-sizing: border-box;
flex-direction: row;
align-items: center;
padding: 10px 12px;
margin-bottom: 10px;
}
.uni-noticebar-close.data-v-c3453ea3 {
margin-left: 8px;
margin-right: 5px;
}
.uni-noticebar-icon.data-v-c3453ea3 {
margin-right: 5px;
}
.uni-noticebar__content-wrapper.data-v-c3453ea3 {
flex: 1;
flex-direction: column;
overflow: hidden;
}
.uni-noticebar__content-wrapper--single.data-v-c3453ea3 {
line-height: 18px;
}
.uni-noticebar__content-wrapper--single.data-v-c3453ea3,
.uni-noticebar__content-wrapper--scrollable.data-v-c3453ea3 {
flex-direction: row;
}
.uni-noticebar__content-wrapper--scrollable.data-v-c3453ea3 {
position: relative;
}
.uni-noticebar__content--scrollable.data-v-c3453ea3 {
flex: 1;
display: block;
overflow: hidden;
}
.uni-noticebar__content--single.data-v-c3453ea3 {
display: flex;
flex: none;
width: 100%;
justify-content: center;
}
.uni-noticebar__content-text.data-v-c3453ea3 {
font-size: 14px;
line-height: 18px;
word-break: break-all;
}
.uni-noticebar__content-text--single.data-v-c3453ea3 {
display: block;
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.uni-noticebar__content-text--scrollable.data-v-c3453ea3 {
position: absolute;
display: block;
height: 18px;
line-height: 18px;
white-space: nowrap;
padding-left: 100%;
animation: notice-c3453ea3 10s 0s linear infinite both;
animation-play-state: paused;
}
.uni-noticebar__more.data-v-c3453ea3 {
display: inline-flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
padding-left: 5px;
}
@keyframes notice-c3453ea3 {
100% {
transform: translate3d(-100%, 0, 0);
}
}

View File

@ -1 +1 @@
<view wx:if="{{a}}" class="{{['uni-popup', k, l]}}"><view bindtouchstart="{{j}}"><uni-transition wx:if="{{b}}" key="1" bindclick="{{c}}" u-i="7fd316aa-0" bind:__l="__l" u-p="{{d}}"/><uni-transition wx:if="{{i}}" u-s="{{['d']}}" key="2" bindclick="{{h}}" u-i="7fd316aa-1" bind:__l="__l" u-p="{{i}}"><view style="{{e}}" class="{{['uni-popup__wrapper', f]}}" bindtap="{{g}}"><slot/></view></uni-transition></view></view>
<view wx:if="{{a}}" class="{{['uni-popup', k, l]}}"><view bindtouchstart="{{j}}"><uni-transition wx:if="{{b}}" key="1" bindclick="{{c}}" u-i="15c4226a-0" bind:__l="__l" u-p="{{d}}"/><uni-transition wx:if="{{i}}" u-s="{{['d']}}" key="2" bindclick="{{h}}" u-i="15c4226a-1" bind:__l="__l" u-p="{{i}}"><view style="{{e}}" class="{{['uni-popup__wrapper', f]}}" bindtap="{{g}}"><slot/></view></uni-transition></view></view>