Selaa lähdekoodia

完善 完整功能

XSXS 2 viikkoa sitten
vanhempi
commit
19d81418d4

+ 610 - 0
common/RgbQuant.js

@@ -0,0 +1,610 @@
+/*
+ * Copyright (c) 2015, Leon Sorokin
+ * All rights reserved. (MIT Licensed)
+ *
+ * RgbQuant.js - an image quantization lib
+ */
+
+/**
+ * @namespace RgbQuant
+ */
+(function() {
+	/**
+	 * @typedef {Object} Palette
+	 * @property {Array} colors - Array of colors, each represented as an array of [R, G, B, A] values.
+	 * @property {Array} aInd - Array of indices mapping original colors to the palette.
+	 */
+
+	/**
+	 * @typedef {Object} Options
+	 * @property {number} [colors=256] - Desired number of colors, up to 256.
+	 * @property {string} [method=2] - 1 = NeuQuant (older, faster), 2 = WuQuant (newer, slower, better quality).
+	 * @property {number} [boxSize=[64,64]] - Bounding box size for mapping image pixels to palette.
+	 * @property {number} [boxPxls=2] - Num of pointers stored per box.
+	 * @property {number} [initColors=4096] - Number of colors used for initial palette selection.
+	 * @property {Function} [progress] - Callback function for progress updates.
+	 * @property {Array} [palette] - Pre-defined palette to use.
+	 */
+
+	/**
+	 * @constructor
+	 * @alias RgbQuant
+	 * @param {Options} [opts] - Options for quantization.
+	 */
+	function RgbQuant(opts) {
+		opts = opts || {};
+
+		// desired final palette size
+		this.colors = opts.colors || 256;
+		// # of highest-frequency colors to start with for palette reduction
+		this.initColors = opts.initColors || 4096;
+		// color-distance threshold for initial reduction pass
+		this.initDist = opts.initDist || 0.01;
+		// subsequent passes threshold
+		this.distIncr = opts.distIncr || 0.005;
+		// method: 1 = NeuQuant, 2 = WuQuant
+		this.method = opts.method || 2;
+		// if > 0, enables handling of alpha transparency
+		this.hasAlpha = opts.hasAlpha || false;
+		// how many passes to run in collecting histogram
+		this.pass = opts.pass === false ? 0 : 1;
+
+		// values that define bounding box for pixels used for palette building
+		// if null, uses full image
+		this.boxSize = opts.boxSize || [64, 64];
+		this.boxPxls = opts.boxPxls || 2;
+		// if provided, use this palette (and skip quant)
+		this.palette = opts.palette;
+
+		this.pruned = this.palette ? true : false;
+		// final reduced palette
+		this.pal = null;
+		// palette index for referring pixels
+		this.pali = null;
+		// sorted palette by hue
+		this.pals = null;
+
+		// for WuQuant
+		this.histogram = {};
+		this.vboxes = [];
+
+		this.progress = opts.progress || function() {};
+
+		this.history = {};
+
+		this.setDefault(opts);
+	}
+
+	RgbQuant.prototype.setDefault = function(opts) {
+		this.pass = (opts.pass === false || this.pruned) ? 0 : 1;
+		this.hasAlpha = opts.hasAlpha || false;
+		if (this.hasAlpha) {
+			this.colors = Math.min(this.colors, 255);
+		}
+	}
+
+	/**
+	 * @param {Image|Array} img - Image element or pixel array.
+	 */
+	RgbQuant.prototype.sample = function(img) {
+		if (this.pass) {
+			if (Array.isArray(img) || typeof img.BYTES_PER_ELEMENT === 'number')
+				var pixels = img;
+			else {
+				var c = document.createElement("canvas");
+				c.width = img.width;
+				c.height = img.height;
+				var ctx = c.getContext("2d");
+				ctx.drawImage(img, 0, 0);
+				var pixels = ctx.getImageData(0, 0, img.width, img.height).data;
+			}
+			this.collect(pixels);
+		}
+	};
+
+	RgbQuant.prototype.collect = function(pixels) {
+		this.vboxes = [];
+		this.histogram = {};
+
+		var vbox = new VBox(0, 0, 0, 0, 0, 0);
+		vbox.r1 = vbox.g1 = vbox.b1 = 255;
+
+		var i = 0;
+		if (this.boxSize) {
+			var width = Math.ceil(Math.sqrt(pixels.length / 4));
+			var height = Math.round(pixels.length / 4 / width);
+			var bWidth = Math.floor(width / this.boxSize[0]);
+			var bHeight = Math.floor(height / this.boxSize[1]);
+			var nPix = this.boxPxls;
+			var x, y;
+			for (var j = 0; j < bWidth; j++) {
+				for (var k = 0; k < bHeight; k++) {
+					for (var l = 0; l < nPix; l++) {
+						x = Math.floor(j * this.boxSize[0] + Math.random() * this.boxSize[0]);
+						y = Math.floor(k * this.boxSize[1] + Math.random() * this.boxSize[1]);
+						i = (y * width + x) * 4;
+						this.addPixel(i, pixels, vbox);
+					}
+				}
+			}
+		}
+		else {
+			for (var len = pixels.length; i < len; i += 4)
+				this.addPixel(i, pixels, vbox);
+		}
+		this.vboxes.push(vbox);
+	};
+
+	RgbQuant.prototype.addPixel = function(i, pixels, vbox) {
+		var r = pixels[i],
+			g = pixels[i+1],
+			b = pixels[i+2],
+			a = pixels[i+3];
+
+		vbox.r2 = Math.max(vbox.r2, r);
+		vbox.g2 = Math.max(vbox.g2, g);
+		vbox.b2 = Math.max(vbox.b2, b);
+
+		vbox.r1 = Math.min(vbox.r1, r);
+		vbox.g1 = Math.min(vbox.g1, g);
+		vbox.b1 = Math.min(vbox.b1, b);
+
+		if (this.method == 1) {
+			if (!(r > 250 && g > 250 && b > 250)) {
+				this.init_add(
+					( (r << 8) + g << 8) + b
+				);
+			}
+		}
+		else {
+			var ind = getColorIndex(r, g, b);
+			if (this.histogram[ind])
+				this.histogram[ind]++;
+			else
+				this.histogram[ind] = 1;
+		}
+	}
+
+	RgbQuant.prototype.medianCut = function(vboxes) {
+		var vbox, cut;
+		var i = 0;
+		while (i < this.colors - 1) {
+			vbox = vboxes.shift();
+			cut = vbox.cut(this.histogram);
+			vboxes.push.apply(vboxes, cut);
+			i++;
+		}
+	}
+
+	/**
+	 * @returns {Palette}
+	 */
+	RgbQuant.prototype.quantize = function() {
+		// short-circuit
+		if (this.palette)
+			this.pal = this.palette.slice(0);
+		else {
+			if (this.method == 1) {
+				this.prune();
+				this.reduce();
+			}
+			// WuQuant
+			else {
+				this.medianCut(this.vboxes);
+
+				var pal = [];
+				for (var i = 0; i < this.vboxes.length; i++) {
+					pal.push(this.vboxes[i].color(this.histogram));
+				}
+				this.pal = pal;
+			}
+		}
+
+		if (this.hasAlpha) {
+			this.pal.push([0,0,0,0]);
+		}
+
+		return this.pal;
+	};
+
+	RgbQuant.prototype.reduce = function() {
+		this.prune();
+
+		var i = 0;
+		var len = this.pal.length;
+		var rd = [], gd = [], bd = [];
+		while (len > this.colors) {
+			var min_d = 1e10, min_i;
+			for (i = 0; i < len; i++) {
+				for (var j = i + 1; j < len; j++) {
+					var d = dist(this.pal[i], this.pal[j]);
+					if (d < min_d) {
+						min_d = d;
+						min_i = [i, j];
+					}
+				}
+			}
+
+			var p1 = this.pal[min_i[0]];
+			var p2 = this.pal[min_i[1]];
+			var n = this.pali[min_i[0]] + this.pali[min_i[1]];
+			var r = (p1[0] * this.pali[min_i[0]] + p2[0] * this.pali[min_i[1]])/n;
+			var g = (p1[1] * this.pali[min_i[0]] + p2[1] * this.pali[min_i[1]])/n;
+			var b = (p1[2] * this.pali[min_i[0]] + p2[2] * this.pali[min_i[1]])/n;
+
+			this.pal[min_i[0]] = [r,g,b];
+			this.pali[min_i[0]] = n;
+
+			this.pal.splice(min_i[1], 1);
+			this.pali.splice(min_i[1], 1);
+
+			len--;
+		}
+
+		return this.pal;
+	};
+
+	RgbQuant.prototype.prune = function() {
+		var dist = this.initDist;
+		for (var p = 0; p < 5; p++) {
+			for (i = 0; i < this.pal.length; i++) {
+				for (var j = i + 1; j < this.pal.length; j++) {
+					if (dist(this.pal[i], this.pal[j]) < dist) {
+						this.pal.splice(j, 1);
+						this.pali.splice(j, 1);
+					}
+				}
+			}
+			dist += this.distIncr;
+		}
+	}
+
+	RgbQuant.prototype.init_add = function(color) {
+		var pali = this.pali,
+			pal = this.pal;
+
+		if (pali[color])
+			pali[color]++;
+		else {
+			pal.push(
+				[
+					(color >> 16) & 0xff,
+					(color >> 8) & 0xff,
+					(color) & 0xff
+				]
+			);
+			pali[color] = 1;
+		}
+	};
+
+	RgbQuant.prototype.init = function(pixels) {
+		this.pal = [];
+		this.pali = {};
+
+		if (this.boxSize) {
+			var width = Math.ceil(Math.sqrt(pixels.length / 4));
+			var height = Math.round(pixels.length / 4 / width);
+			var bWidth = Math.floor(width / this.boxSize[0]);
+			var bHeight = Math.floor(height / this.boxSize[1]);
+			var nPix = this.boxPxls;
+			var x, y;
+			for (var j = 0; j < bWidth; j++) {
+				for (var k = 0; k < bHeight; k++) {
+					for (var l = 0; l < nPix; l++) {
+						x = Math.floor(j * this.boxSize[0] + Math.random() * this.boxSize[0]);
+						y = Math.floor(k * this.boxSize[1] + Math.random() * this.boxSize[1]);
+						i = (y * width + x) * 4;
+						var color = ( (pixels[i] << 8) + pixels[i+1] << 8) + pixels[i+2];
+						this.init_add(color);
+					}
+				}
+			}
+		}
+		else {
+			for (var i = 0, len = pixels.length; i < len; i+=4) {
+				var color = ( (pixels[i] << 8) + pixels[i+1] << 8) + pixels[i+2];
+				this.init_add(color);
+			}
+		}
+
+		var pal = this.pal,
+			pali = this.pali,
+			len = pal.length,
+			newpal = [],
+			newpali = [];
+
+		var hist = [];
+		for (var i = 0; i < len; i++) {
+			hist[i] = [pali[ ((pal[i][0] << 8) + pal[i][1] << 8) + pal[i][2] ], pal[i]];
+		}
+
+		hist.sort(function(a,b) { return b[0] - a[0]; });
+
+		var newlen = Math.min(len, this.initColors);
+		this.pal = []; this.pali = [];
+		for (var i = 0; i < newlen; i++) {
+			this.pal[i] = hist[i][1];
+			this.pali[i] = hist[i][0];
+		}
+	};
+
+	RgbQuant.prototype.map = function(img) {
+		if (img instanceof Array)
+			var pixels = img;
+		else {
+			var c = document.createElement("canvas");
+			c.width = img.width;
+			c.height = img.height;
+			var ctx = c.getContext("2d");
+			ctx.drawImage(img, 0, 0);
+			var pixels = ctx.getImageData(0, 0, img.width, img.height).data;
+		}
+
+		var out = new Uint8Array(pixels.length);
+
+		var pal = this.pal;
+
+		for (var i = 0, len = pixels.length; i < len; i+=4) {
+			var pi = this.nearest(
+				[
+					pixels[i],
+					pixels[i+1],
+					pixels[i+2],
+					pixels[i+3],
+				]
+			);
+			out[i]   = pal[pi][0];
+			out[i+1] = pal[pi][1];
+			out[i+2] = pal[pi][2];
+			out[i+3] = pal[pi][3];
+		}
+
+		return out;
+	}
+
+	RgbQuant.prototype.nearest = function(color) {
+		var min_d = 1e10, min_i;
+		for (var i = 0; i < this.pal.length; i++) {
+			var d = dist(color, this.pal[i]);
+			if (d < min_d) {
+				min_d = d;
+				min_i = i;
+			}
+		}
+		return min_i;
+	};
+
+	RgbQuant.prototype.getHex = function() {
+		var hex = [];
+		for (var i = 0; i < this.pal.length; i++) {
+			hex.push(
+				"#" + ("000000" + ( (this.pal[i][0] << 16) | (this.pal[i][1] << 8) | this.pal[i][2] ).toString(16)).slice(-6)
+			);
+		}
+		return hex;
+	};
+
+	// Rec. 709 (sRGB) luma coeff
+	var Pr = .2126, Pl = .0722, Pg = .7152;
+	function dist(a, b) {
+		var dr = a[0]-b[0],
+			dg = a[1]-b[1],
+			db = a[2]-b[2];
+		return Pr * dr * dr + Pg * dg * dg + Pl * db * db;
+	}
+
+	function getColorIndex(r, g, b) {
+		return (r << 16) + (g << 8) + b;
+	}
+
+	var VBox = (function() {
+		var dim = 3,
+			shift = 5,
+			size = 1 << shift,
+			mask = size - 1;
+
+		function VBox(r1, g1, b1, r2, g2, b2) {
+			this.r1 = r1; this.g1 = g1; this.b1 = b1;
+			this.r2 = r2; this.g2 = g2; this.b2 = b2;
+			this._avg = this._cnt = 0;
+		}
+
+		VBox.prototype.contains = function(r, g, b) {
+			return r >= this.r1 && r <= this.r2 &&
+				   g >= this.g1 && g <= this.g2 &&
+				   b >= this.b1 && b <= this.b2;
+		}
+
+		VBox.prototype.volume = function() {
+			return (this.r2 - this.r1) * (this.g2 - this.g1) * (this.b2 - this.b1);
+		}
+
+		VBox.prototype.size = function(hist) {
+			if (!this._size) {
+				var npix = 0,
+					r, g, b, ind;
+				for (r = this.r1; r <= this.r2; r++) {
+					for (g = this.g1; g <= this.g2; g++) {
+						for (b = this.b1; b <= this.b2; b++) {
+							ind = getColorIndex(r, g, b);
+							if (hist[ind])
+								npix += hist[ind];
+						}
+					}
+				}
+				this._size = npix;
+			}
+
+			return this._size;
+		}
+
+		VBox.prototype.color = function(hist) {
+			if (!this._avg) {
+				var mult = 1 << (8 - shift),
+					sum = [0,0,0],
+					npix = 0,
+					r, g, b, ind;
+
+				for (r = this.r1; r <= this.r2; r++) {
+					for (g = this.g1; g <= this.g2; g++) {
+						for (b = this.b1; b <= this.b2; b++) {
+							ind = getColorIndex(r, g, b);
+							if (hist[ind]) {
+								var h = hist[ind];
+								npix += h;
+								sum[0] += h * (r + 0.5) * mult;
+								sum[1] += h * (g + 0.5) * mult;
+								sum[2] += h * (b + 0.5) * mult;
+							}
+						}
+					}
+				}
+
+				if (npix) {
+					this._avg = [
+						~~(sum[0] / npix),
+						~~(sum[1] / npix),
+						~~(sum[2] / npix)
+					];
+				}
+				else {
+					// empty box
+					this._avg = [
+						~~(mult * (this.r1 + this.r2 + 1) / 2),
+						~~(mult * (this.g1 + this.g2 + 1) / 2),
+						~~(mult * (this.b1 + this.b2 + 1) / 2)
+					];
+				}
+			}
+			return this._avg;
+		}
+
+		VBox.prototype.cut = function(hist) {
+			var self = this;
+
+			function doCut(dim) {
+				var d1 = self[dim + '1'],
+					d2 = self[dim + '2'],
+					count = 0,
+					total = 0,
+					sum = 0,
+					vbox, cut,
+					min, max, i, j, k, ind;
+
+				var left, right;
+				if (dim == 'r') { left = 'g'; right = 'b'; }
+				else if (dim == 'g') { left = 'r'; right = 'b'; }
+				else { left = 'r'; right = 'g'; }
+
+				var partialsum = [], lookaheadsum = [];
+
+				for (i = d1; i <= d2; i++) {
+					sum = 0;
+					for (j = self[left+'1']; j <= self[left+'2']; j++) {
+						for (k = self[right+'1']; k <= self[right+'2']; k++) {
+							ind = getColorIndex(
+								dim == 'r' ? i : (left == 'r' ? j : k),
+								dim == 'g' ? i : (left == 'g' ? j : k),
+								dim == 'b' ? i : (left == 'b' ? j : k)
+							);
+							if (hist[ind])
+								sum += hist[ind];
+						}
+					}
+					total += sum;
+					partialsum[i] = total;
+				}
+
+				for (i = d1; i <= d2; i++) {
+					if (partialsum[i] > total / 2) {
+						vbox = self.clone();
+						cut = self.clone();
+						var d2_1 = i - d1, d2_2 = d2 - i;
+						if (d2_1 >= d2_2)
+							var d2_ = Math.min(d2 - 1, ~~(i + d2_2 / 2));
+						else
+							var d2_ = Math.max(d1 + 1, ~~(i - d2_1 / 2));
+
+						while (!partialsum[d2_]) d2_++;
+						var c = partialsum[d2_ - 1] || 0;
+						while (c == partialsum[d2_] && d2_ < d2) d2_++;
+
+						vbox[dim+'2'] = d2_;
+						cut[dim+'1'] = d2_ + 1;
+
+						return [vbox, cut];
+					}
+				}
+			}
+
+			var lr = this.r2 - this.r1,
+				lg = this.g2 - this.g1,
+				lb = this.b2 - this.b1;
+
+			if (lr >= lg && lr >= lb)
+				return doCut('r');
+			if (lg >= lr && lg >= lb)
+				return doCut('g');
+			if (lb >= lr && lb >= lg)
+				return doCut('b');
+		}
+
+		VBox.prototype.clone = function() {
+			return new VBox(this.r1, this.g1, this.b1, this.r2, this.g2, this.b2);
+		}
+
+		return VBox;
+	})();
+
+	// global functions
+	this.RgbQuant = RgbQuant;
+	this.dist = dist;
+}).call(this);
+
+//
+// NeuQuant
+//
+// NeuQuant Neural-Net Quantization Algorithm
+// ------------------------------------------
+//
+// Copyright (c) 1994 Anthony Dekker
+//
+// E-mail:   dekker@ACM.org
+//
+// Web:      http://www.scientificcia.com
+//
+// With my permission you are free to use this code for non-commercial purposes.
+// For commercial implementations, please contact me to obtain a licensing agreement.
+//
+//
+// DESCRIPTION:
+//
+// NeuQuant is a color quantization algorithm that reduces the number of colors
+// in a true-color image. It is especially suited for reducing images to 256
+// colors and less.
+//
+// The algorithm is based on a neural network that is trained on the input
+// image. The network is a 1D self-organizing map (SOM) that learns the
+// distribution of colors in the image. The neurons in the map represent the
+// colors in the output palette.
+//
+// The algorithm proceeds as follows:
+//
+//  1. The network is initialized with a set of random colors.
+//  2. For each pixel in the input image, the neuron that is closest to the
+//     pixel's color is found.
+//  3. This neuron's color is updated to be closer to the pixel's color.
+//  4. The neuron's neighbors are also updated, but by a smaller amount.
+//  5. The learning rate and neighborhood size are decreased over time.
+//  6. After the network has been trained, the neurons' colors form the
+//     output palette.
+//
+//  7. The input image is then mapped to the output palette by finding the
+//     closest color in the palette for each pixel.
+//
+//  This implementation of the algorithm is based on the original C code by
+//  Anthony Dekker. It has been adapted for JavaScript and modified to
+
+if (typeof(module) !== 'undefined') {
+	module.exports.RgbQuant = this.RgbQuant;
+} 

+ 5 - 1
components/SharePopup/SharePopup.vue

@@ -48,6 +48,10 @@ export default {
     isReportContent: {
       type: Boolean,
       default: false
+    },
+    link: {
+      type: String,
+      default: ''
     }
   },
 
@@ -73,7 +77,7 @@ export default {
         from_id: this.from_id
       }
       const secureParams = generateSecureUrlParams(urlParams)
-      return `${this.$shareUrl}?params=${secureParams}`
+      return `${this.link || this.$shareUrl}?params=${secureParams}`
     }
   },
   created() {

+ 251 - 248
components/card/card.vue

@@ -6,25 +6,24 @@
 		</view>
 		<view class="waterfall-item__ft">
 			<view class="waterfall-item__ft__title">
-				<text class="value" :style="{ color: titleTextColor||textColor }">{{
-          item.title
-        }}</text>
+				<text class="value" :style="{ color: titleTextColor || textColor }">{{
+					item.title
+				}}</text>
 			</view>
 			<view class="waterfall-item__ft__desc" style="margin-top: 4rpx;" @click="goAuthor(item)">
 				<view class="user">
 					<image :src="item.avator" mode="aspectFill" class="avater"> </image>
 					<text class="name one-omit" :style="{ color: textColor }">{{
-            item.nickname
-          }}</text>
+						item.nickname
+					}}</text>
 				</view>
 				<view class="like" @click="changeLike">
-					<image class="like-icon" :src="
-              isLike ? '/static/icon/icon-18.png' : '/static/icon/icon-19.png'
-            " mode="">
+					<image class="like-icon" :src="isLike ? '/static/icon/icon-18.png' : '/static/icon/icon-19.png'
+						" mode="">
 					</image>
 					<text class="value" :style="{ color: textColor }">{{
-            item.num_like
-          }}</text>
+						item.num_like
+					}}</text>
 				</view>
 			</view>
 			<view class="waterfall-item__ft__btn" v-if="false">
@@ -47,310 +46,314 @@
 </template>
 
 <script>
-	export default {
-		name: "card",
-		props: {
-			width: {
-				type: String,
-				default: "",
-			},
-			item: {
-				type: Object,
-				default: () => ({}),
-			},
-			textColor: {
-				type: String,
-				default: "#ff0000",
-			},
-			titleTextColor: {
-				type: String,
-				default: "",
-			},
-			customStyle: {
-				type: Object,
-				default: () => ({
-					background: "#3F4141",
-				}),
-			},
-			goLink: {
-				type: String,
-				default: "",
-			},
-			findType: {
-				type: String,
-				default: "",
-			},
+export default {
+	name: "card",
+	props: {
+		width: {
+			type: String,
+			default: "",
 		},
-		data() {
-			return {
-				isLike: false,
-				isLiking: false,
-				localLikeCount: 0,
-			};
+		item: {
+			type: Object,
+			default: () => ({}),
 		},
-		created() {
-			this.isLike = this.item.is_like || false;
-			this.localLikeCount = this.item.num_like || 0;
+		textColor: {
+			type: String,
+			default: "#ff0000",
 		},
-		methods: {
-			changeLike(e) {
-				return;
-				e && e.stopPropagation();
+		titleTextColor: {
+			type: String,
+			default: "",
+		},
+		customStyle: {
+			type: Object,
+			default: () => ({
+				background: "#3F4141",
+			}),
+		},
+		goLink: {
+			type: String,
+			default: "",
+		},
+		findType: {
+			type: String,
+			default: "",
+		},
+	},
+	data() {
+		return {
+			isLike: false,
+			isLiking: false,
+			localLikeCount: 0,
+		};
+	},
+	created() {
+		this.isLike = this.item.is_like || false;
+		this.localLikeCount = this.item.num_like || 0;
+	},
+	methods: {
+		changeLike(e) {
+			return;
+			e && e.stopPropagation();
 
-				if (this.isLiking) return;
-				this.isLiking = true;
+			if (this.isLiking) return;
+			this.isLiking = true;
 
-				const prevLikeState = this.isLike;
-				const prevLikeCount = this.localLikeCount;
+			const prevLikeState = this.isLike;
+			const prevLikeCount = this.localLikeCount;
 
-				this.isLike = !this.isLike;
-				this.localLikeCount = this.isLike ? prevLikeCount + 1 : prevLikeCount - 1;
-				this.item.num_like = this.localLikeCount;
+			this.isLike = !this.isLike;
+			this.localLikeCount = this.isLike ? prevLikeCount + 1 : prevLikeCount - 1;
+			this.item.num_like = this.localLikeCount;
 
-				if (!getApp().globalData.uuid) {
-					uni.showToast({
-						title: "请先登录",
-						icon: "none",
-					});
-					this.isLike = prevLikeState;
-					this.localLikeCount = prevLikeCount;
-					this.item.num_like = prevLikeCount;
-					this.isLiking = false;
-					return;
-				}
-
-				uni.request({
-					url: this.$apiHost + "/Work/zanTA",
-					data: {
-						uuid: getApp().globalData.uuid,
-						id: this.item.id,
-					},
-					header: {
-						"content-type": "application/json",
-						sign: getApp().globalData.headerSign,
-					},
-					success: (res) => {
-						if (res.data.success === "yes") {
-							uni.showToast({
-								title: this.isLike ? "点赞成功" : "取消点赞",
-								icon: "none",
-							});
-						} else {
-							this.isLike = prevLikeState;
-							this.localLikeCount = prevLikeCount;
-							this.item.num_like = prevLikeCount;
+			if (!getApp().globalData.uuid) {
+				uni.showToast({
+					title: "请先登录",
+					icon: "none",
+				});
+				this.isLike = prevLikeState;
+				this.localLikeCount = prevLikeCount;
+				this.item.num_like = prevLikeCount;
+				this.isLiking = false;
+				return;
+			}
 
-							uni.showToast({
-								title: res.data.str || "操作失败",
-								icon: "none",
-							});
-						}
-					},
-					fail: (e) => {
-						console.error("点赞失败:", e);
+			uni.request({
+				url: this.$apiHost + "/Work/zanTA",
+				data: {
+					uuid: getApp().globalData.uuid,
+					id: this.item.id,
+				},
+				header: {
+					"content-type": "application/json",
+					sign: getApp().globalData.headerSign,
+				},
+				success: (res) => {
+					if (res.data.success === "yes") {
+						uni.showToast({
+							title: this.isLike ? "点赞成功" : "取消点赞",
+							icon: "none",
+						});
+					} else {
 						this.isLike = prevLikeState;
 						this.localLikeCount = prevLikeCount;
 						this.item.num_like = prevLikeCount;
 
 						uni.showToast({
-							title: "网络请求失败",
+							title: res.data.str || "操作失败",
 							icon: "none",
 						});
-					},
-					complete: () => {
-						setTimeout(() => {
-							this.isLiking = false;
-						}, 500);
-					},
-				});
-			},
-			goWork(item) {
-				var url = "/pages/index/workDetail?id=";
-				if (this.goLink) {
-					url = this.goLink;
-				}
-				console.log("goWork", this.goLink);
-
-				// uni.$emit('check_login', () => {
-				uni.navigateTo({
-					url: url + item.id,
-				});
-				// })
-			},
-			goAuthor(item) {
-				console.log("goAuthor", item);
-				uni.$emit("check_login", () => {
-					if (!item.userID) {
-						return;
 					}
-					uni.navigateTo({
-						url: "/pages/my/userHomepage?id=" + item.userID,
+				},
+				fail: (e) => {
+					console.error("点赞失败:", e);
+					this.isLike = prevLikeState;
+					this.localLikeCount = prevLikeCount;
+					this.item.num_like = prevLikeCount;
+
+					uni.showToast({
+						title: "网络请求失败",
+						icon: "none",
 					});
+				},
+				complete: () => {
+					setTimeout(() => {
+						this.isLiking = false;
+					}, 500);
+				},
+			});
+		},
+		goWork(item) {
+			var url = "/pages/index/workDetail?id=";
+			if (this.goLink) {
+				url = this.goLink;
+			}
+			console.log("goWork", this.goLink);
+			console.log(item, 888888888);
+			if (item.type == 'crowdfund') {
+				url = "/pages/crowdFunding/crowdfundingDetailsDesign?id="
+			}
+			// uni.$emit('check_login', () => {
+			uni.navigateTo({
+				url: url + item.id,
+			});
+			// })
+		},
+		goAuthor(item) {
+			console.log("goAuthor", item);
+			uni.$emit("check_login", () => {
+				if (!item.userID) {
+					return;
+				}
+				uni.navigateTo({
+					url: "/pages/my/userHomepage?id=" + item.userID,
 				});
-			},
+			});
 		},
-	};
+	},
+};
 </script>
 
 <style lang="scss">
-	.waterfall-item {
-		margin-bottom: 0rpx;
-		border-radius: 30rpx;
-		position: relative;
+.waterfall-item {
+	margin-bottom: 0rpx;
+	border-radius: 30rpx;
+	position: relative;
+	border-radius: 16rpx;
+	overflow: hidden;
+	transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+	// box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
+
+	&:active {
+		transform: scale(0.98);
+		box-shadow: 0 1rpx 4rpx rgba(0, 0, 0, 0.05);
+	}
+
+	// #ifndef APP-NVUE
+	.waterfall-item__image {
 		border-radius: 16rpx;
-		overflow: hidden;
-		transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
-		// box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
+		width: 100%;
+		height: auto;
+		box-sizing: border-box;
+		padding: 28rpx 20rpx;
+		transition: all 0.3s ease;
 
 		&:active {
-			transform: scale(0.98);
-			box-shadow: 0 1rpx 4rpx rgba(0, 0, 0, 0.05);
+			opacity: 0.9;
 		}
 
-		// #ifndef APP-NVUE
-		.waterfall-item__image {
-			border-radius: 16rpx;
+		image {
 			width: 100%;
-			height: auto;
-			box-sizing: border-box;
-			padding: 28rpx 20rpx;
+			height: 100%;
 			transition: all 0.3s ease;
+		}
+	}
+
+	// #endif
+	.waterfall-item__tips {
+		position: absolute;
+		top: 10rpx;
+		padding: 0rpx 10rpx;
+		// #ifndef APP-NVUE
+		box-sizing: border-box;
+		// #endif
+		width: 100%;
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		justify-content: space-between;
+
+		.item {
+			// #ifndef APP-NVUE
+			// #endif
+			display: flex;
+			flex-direction: row;
+			align-items: center;
+			background: rgba(0, 0, 0, 0.2);
+			padding: 8rpx 14rpx;
+			border-radius: 12rpx;
 
-			&:active {
-				opacity: 0.9;
+			.look-icon {
+				width: 26rpx;
+				height: 26rpx;
+				margin-right: 10rpx;
 			}
 
-			image {
-				width: 100%;
-				height: 100%;
-				transition: all 0.3s ease;
+			.value {
+				font-size: 20rpx;
 			}
 		}
+	}
 
-		// #endif
-		.waterfall-item__tips {
-			position: absolute;
-			top: 10rpx;
-			padding: 0rpx 10rpx;
-			// #ifndef APP-NVUE
-			box-sizing: border-box;
-			// #endif
+	.waterfall-item__ft {
+		padding: 10rpx 20rpx;
+		padding-left: 0;
+
+		&__title {
+			line-height: 48rpx;
+			font-weight: 700;
+
+			.value {
+				font-size: 30rpx;
+			}
+		}
+
+		&__desc {
 			width: 100%;
+			// #ifndef APP-NVUE
 			display: flex;
+			// #endif
+			// #ifdef APP-NVUE
+			// #endif
 			flex-direction: row;
 			align-items: center;
 			justify-content: space-between;
+			margin: 20rpx 0;
 
-			.item {
+			.user {
 				// #ifndef APP-NVUE
-				// #endif
 				display: flex;
+				// #endif
+				// #ifdef APP-NVUE
 				flex-direction: row;
+				// #endif
 				align-items: center;
-				background: rgba(0, 0, 0, 0.2);
-				padding: 8rpx 14rpx;
-				border-radius: 12rpx;
 
-				.look-icon {
-					width: 26rpx;
-					height: 26rpx;
+				.avater {
+					width: 44rpx;
+					height: 44rpx;
+					border-radius: 50%;
 					margin-right: 10rpx;
 				}
 
-				.value {
-					font-size: 20rpx;
+				.name {
+					font-size: 24rpx;
+					max-width: 80px;
+					display: inline-block;
 				}
 			}
-		}
 
-		.waterfall-item__ft {
-			padding: 10rpx 20rpx;
-			padding-left: 0; 
-
-			&__title {
-				line-height: 48rpx;
-				font-weight: 700;
-
-				.value {
-					font-size: 30rpx;
-				}
-			}
-
-			&__desc {
-				width: 100%;
+			.like {
 				// #ifndef APP-NVUE
 				display: flex;
 				// #endif
 				// #ifdef APP-NVUE
-				// #endif
 				flex-direction: row;
+				// #endif
 				align-items: center;
-				justify-content: space-between;
-				margin: 20rpx 0;
-
-				.user {
-					// #ifndef APP-NVUE
-					display: flex;
-					// #endif
-					// #ifdef APP-NVUE
-					flex-direction: row;
-					// #endif
-					align-items: center;
+				font-weight: bold;
 
-					.avater {
-						width: 44rpx;
-						height: 44rpx;
-						border-radius: 50%;
-						margin-right: 10rpx;
-					}
-
-					.name {
-						font-size: 24rpx;
-						max-width: 80px;
-						display: inline-block;
-					}
+				.like-icon {
+					width: 30rpx;
+					height: 30rpx;
+					margin-right: 10rpx;
 				}
 
-				.like {
-					// #ifndef APP-NVUE
-					display: flex;
-					// #endif
-					// #ifdef APP-NVUE
-					flex-direction: row;
-					// #endif
-					align-items: center;
-					font-weight: bold;
-					.like-icon {
-						width: 30rpx;
-						height: 30rpx;
-						margin-right: 10rpx;
-					}
-
-					.value {
-						font-size: 24rpx;
-					}
+				.value {
+					font-size: 24rpx;
 				}
 			}
+		}
 
-			&__btn {
-				height: 65rpx;
-				border-radius: 18px;
-				background-image: linear-gradient(to bottom, #bffe9c, #aee75d);
-				// #ifndef APP-NVUE
-				background: linear-gradient(180deg,
-						#bffe9c 0%,
-						#aee75d 62%,
-						#aee75d 100%);
-				display: flex;
-				// #endif
-				justify-content: center;
-				align-items: center;
+		&__btn {
+			height: 65rpx;
+			border-radius: 18px;
+			background-image: linear-gradient(to bottom, #bffe9c, #aee75d);
+			// #ifndef APP-NVUE
+			background: linear-gradient(180deg,
+					#bffe9c 0%,
+					#aee75d 62%,
+					#aee75d 100%);
+			display: flex;
+			// #endif
+			justify-content: center;
+			align-items: center;
 
-				&__icon {
-					width: 155rpx;
-					height: 32rpx;
-				}
+			&__icon {
+				width: 155rpx;
+				height: 32rpx;
 			}
 		}
 	}
+}
 </style>

+ 2 - 2
manifest.json

@@ -2,8 +2,8 @@
     "name" : "萌创星球",
     "appid" : "__UNI__00BD11F",
     "description" : "这里是创意与灵魂汇聚的起点",
-    "versionName" : "1.0.2",
-    "versionCode" : 102,
+    "versionName" : "1.0.3",
+    "versionCode" : 103,
     "transformPx" : false,
     "app-plus" : {
         "compatible" : {

+ 15 - 0
pages.json

@@ -461,6 +461,13 @@
 				"navigationStyle": "custom"
 			}
 		},
+		{
+			"path": "pages/crowdFunding/crowdfundingDetailsDesign",
+			"style": {
+				"navigationBarTitleText": "",
+				"navigationStyle": "custom"
+			}
+		},
 		{
 			"path": "pages/crowdFunding/discussionArea",
 			"style": {
@@ -544,6 +551,14 @@
 				"navigationBarTitleText" : "我的钱包",
 				"navigationBarBackgroundColor": "#F2F6F2"
 			}
+		},
+		{
+			"path" : "pages/my/initiateCrowdfunding",
+			"style" : 
+			{
+				"navigationBarTitleText" : "",
+				"navigationStyle": "custom"
+			}
 		}
 	],
 	"globalStyle": {

+ 1096 - 0
pages/crowdFunding/crowdfundingDetails - 副本.vue

@@ -0,0 +1,1096 @@
+<template>
+	<view class="crowdfunding-details">
+		<view class="custom-navbar" :style="navBgStyle">
+			<view class="navbar-left scale-tap" @click="goBack">
+				<image src="@/static/crowdFunding/back.png" mode="widthFix"></image>
+			</view>
+			<view class="navbar-center one-omit" style="max-width: 70vw; " :style="{ opacity: navBgOpacity }">
+				{{ detail.title }}
+			</view>
+			<view class="navbar-right scale-tap" @click="showShare = true">
+				<image src="@/static/crowdFunding/share.png" mode="widthFix"></image>
+			</view>
+		</view>
+		<!-- 顶部视频图片混合轮播 -->
+		<view class="swiper-container">
+			<swiper class="top-swiper" :indicator-dots="false" circular :current="currentMediaIndex"
+				@change="handleSwiperChange" :duration="300">
+				<swiper-item v-for="(item, idx) in mediaList" :key="idx" class="swiper-item">
+					<view v-if="item.type === 'video'" class="media-wrapper">
+						<video class="swiper-video" :src="item.src" :poster="item.poster" :id="'video-' + idx" controls
+							object-fit="contain" enable-progress-gesture="false" :loop="false"
+							:show-fullscreen-btn="false" :show-play-btn="true" :enable-play-gesture="false"
+							@ended="onVideoEnded" @play="onVideoPlay(idx)" @pause="onVideoPause"></video>
+					</view>
+					<image v-else class="swiper-img" :src="item.src" mode="aspectFill" />
+				</swiper-item>
+			</swiper>
+			<!-- 自定义指示点 -->
+			<view class="custom-dots">
+				<view v-for="(item, index) in mediaList" :key="index"
+					:class="['dot', currentMediaIndex === index ? 'active' : '']" @click="switchMedia(index)"></view>
+			</view>
+		</view>
+
+		<view class="content">
+			<!-- 项目信息 -->
+			<view class="section project-card">
+				<view class="project-title">{{ detail.title }}</view>
+				<view class="progress-bar-wrap">
+					<uv-line-progress height="8rpx" :showText="false"
+						:percentage="(detail.current_amount / detail.goal_amount * 100).toFixed(2)"
+						inactiveColor="#F0F0F0" activeColor="#ACF934"></uv-line-progress>
+					<view class="progress-percent">{{ (detail.current_amount / detail.goal_amount * 100).toFixed(2) + '%'
+						}}</view>
+				</view>
+				<view class="project-stats">
+					<view class="stat-block">
+						<view class="stat-main amountOfMoney">¥{{ detail.current_amount }}</view>
+						<view class="stat-sub">{{ detail.supporter_count }}人支持</view>
+					</view>
+					<view class="stat-block">
+						<view class="stat-main">{{ detail.daysRemaining }}天</view>
+						<view class="stat-sub">剩余时间</view>
+					</view>
+					<view class="stat-block">
+						<view class="stat-main">¥{{ detail.goal_amount }}</view>
+						<view class="stat-sub">众筹目标</view>
+					</view>
+				</view>
+			</view>
+
+
+			<!-- 项目更新 -->
+			<view class="section project-update" v-if="projectUpdate && projectUpdate.numb">
+				<view class="project-update-left scale-tap"
+					@click="goPage('/pages/crowdFunding/projectUpdateDetails?id=' + projectUpdate.id)">
+					<view class="project-update-left-title">
+						<view>·第{{ projectUpdate.numb }}次更新</view>
+						<view style="color: #999;">{{ projectUpdate.create_time }}</view>
+					</view>
+					<view class="project-update-left-content">
+						<view class="two-omit">{{ projectUpdate.title }}</view>
+						<view class="image">
+							<image :src="projectUpdate.image" />
+						</view>
+					</view>
+				</view>
+				<view class="project-update-right scale-tap"
+					@click="goPage('/pages/crowdFunding/discussionArea?tags=update&id=' + projectId)">
+					<view>历史更新</view>
+					<image src="@/static/crowdFunding/updateDetails.png"></image>
+
+				</view>
+			</view>
+
+			<view class="section comment scale-tap"
+				@click="goPage('/pages/crowdFunding/discussionArea?tags=comment&id=' + projectId)">
+				<view class="comment-title">
+					<view>项目讨论({{ totalNumberOfComments }})</view>
+					<view class="comment-more">查看更多
+						<image src=" @/static/crowdFunding/right.png">
+						</image>
+					</view>
+				</view>
+				<view class="comment-content">
+					<block v-for="(item, idx) in commentList" :key="idx">
+						<view class="comment-item">
+							<image class="comment-avatar" :src="item.avatar"></image>
+							<view class="comment-item-main">
+								<view class="comment-item-content">{{ item.content }}</view>
+							</view>
+							<view class="comment-item-like">
+								<image class="like-icon"
+									:src="item.liked ? '/static/icon/icon-18.png' : '/static/icon/icon-19.png'"></image>
+								<text class="like-num">{{ item.likeNum }}</text>
+							</view>
+						</view>
+					</block>
+				</view>
+			</view>
+
+			<!-- 塔罗牌介绍 -->
+			<view class="section poster">
+				<view class="initiator-bar">
+					<image class="initiator-avatar" :src="detail.creator_avatar" />
+					<view class="initiator-info">
+						<text class="initiator-name">{{ detail.creator_nickname }}</text>
+						<div class="initiator-tag" @click="certificationTips()"><image src="@/static/crowdFunding/authentication.png" mode="widthFix"></image> <div>发起人</div></div>
+					</view>
+					<view class="initiator-service-btn  blick-btn-animation"
+						@click="goPage('/pages/crowdFunding/customerService?id=' + detail.creator_id + '&zc_id=' + detail.id)">
+						<image class="service-icon" src="@/static/crowdFunding/service.png" />
+						<text>客服</text>
+					</view>
+				</view>
+				<block v-for="(item, idx) in detail.content_images" :key="idx">
+					<image class="intro-img" :src="item" mode="widthFix" />
+				</block>
+			</view>
+
+
+
+			<!-- 风险说明 -->
+			<view class="section risk-section">
+				<view class="risk-row"  @click="goWeb('https://e.zhichao.art/web/refund.php', '退款说明')">
+					<view class="risk-title">退款政策</view>
+					<view class="risk-more  ">查看更多
+						<image src="@/static/crowdFunding/right.png" class="risk-more-icon" />
+					</view>
+				</view>
+				<view class="risk-desc">众筹结束前最后1个小时无法申请退款</view>
+				<view class="risk-row risk-row-border"  @click="goWeb('https://e.zhichao.art/web/crowdtips.php', '风险提示')">
+					<view class="risk-title">风险提示</view>
+					<view class="risk-more  ">查看更多
+						<image src="@/static/crowdFunding/right.png" class="risk-more-icon" />
+					</view>
+				</view>
+				<view class="risk-content" >
+					<view>1. 您参与众筹是支持将创意变为现实的过程,而不是直接的商品交易,因此存在一定风险。请您根据自己的判断选择,支持众筹项目。</view>
+					<view>2. 众筹存在于发起人与支持者之间,摩点作为第三方平台,提供网络空间、技术支持等服务。众筹的回报产品和承诺由发起人负责。</view>
+				</view>
+			</view>
+		</view>
+		<view class="bottom-bar-reserveASeat"></view>
+		<view class="bottom-bar">
+			<view class="bottom-bar-left">
+				<view class="bar-btn" @click="toggleFavorite">
+					<image v-if="isFavorite" src="@/static/crowdFunding/collect-active.png"
+						class="scale-tap bar-icon" />
+					<image v-else src="@/static/crowdFunding/collect.png" class="scale-tap bar-icon" />
+					<view class="bar-text">{{ isFavorite ? '已收藏' : '收藏' }}</view>
+				</view>
+				<!-- <view class="bar-btn">
+					<image v-if="true" src="@/static/crowdFunding/like.png" class=" scale-tap bar-icon" />
+					<image v-else src="@/static/crowdFunding/like-active.png" class=" scale-tap bar-icon" />
+					<view class="bar-text">看好</view>
+				</view> -->
+			</view>
+			<button class="buy-btn blick-btn-animation" @click="specificationsOpen()">立即购买支持</button>
+		</view>
+		<image src="@/static/crowdFunding/backToTop.png" class="back-top scale-tap" v-show="navBgOpacity > 0.9"
+			@click="scrollToTop"></image>
+
+		<!-- 分享弹窗 -->
+		<SharePopup :visible="showShare" :userId="0" :share-title="shareTitle" :share-desc="shareDesc"
+			:share-img="shareImg" view="crowdfundingDetails" :link="shareLink" @close="showShare = false" :isReportContent="true" />
+
+		<productSpecifications ref="specSheet" :rewards="rewards" :title="detail.title" @confirm="onSpecConfirm" />
+
+	</view>
+</template>
+
+<script>
+import VideoPlayer from "@/components/VideoPlayer/VideoPlayer.vue";
+import SharePopup from "@/components/SharePopup/SharePopup.vue";
+import productSpecifications from "./components/productSpecifications/productSpecifications.vue";
+
+export default {
+	components: {
+		VideoPlayer,
+		SharePopup,
+		productSpecifications
+	},
+	data() {
+		return {
+			mediaList: [],
+			videoPlaying: false,
+			currentMediaIndex: 0,
+			commentList: [
+			],
+			navBgOpacity: 0,
+			swiperHeight: 0,
+			showShare: false,
+			shareTitle: '',
+			shareDesc: '',
+			shareImg: '',
+			shareLink:"https://e.zhichao.art/site/#/mobile-download",
+			userId: 0, // 可根据实际登录用户赋值
+			isFavorite: false, // 是否已收藏
+			projectId: null, // 当前项目id
+			detail: {}, // 众筹详情
+			projectUpdate: '',
+			rewards: [],
+			totalNumberOfComments: 0
+		}
+	},
+	computed: {
+		navBgStyle() {
+			return {
+				background: `rgba(255,255,255,${this.navBgOpacity})`,
+				transition: 'background 0.3s'
+			}
+		}
+	},
+	methods: {
+		// 返回上一页
+		goBack() {
+			uni.navigateBack({
+				delta: 1,
+			});
+		},
+		scrollToTop() {
+			uni.pageScrollTo({
+				scrollTop: 0,
+				duration: 300
+			});
+		},
+		switchMedia(index) {
+			if (this.currentMediaIndex === index) return;
+
+			// 如果当前在播放视频,先暂停
+			if (this.mediaList[this.currentMediaIndex]?.type === 'video') {
+				const videoContext = uni.createVideoContext('video-' + this.currentMediaIndex, this);
+				if (videoContext) {
+					videoContext.pause();
+				}
+			}
+
+			this.currentMediaIndex = index;
+		},
+		handleSwiperChange(e) {
+			const lastIndex = this.currentMediaIndex;
+			this.currentMediaIndex = e.detail.current;
+
+			// 如果上一个是视频,暂停它
+			if (this.mediaList[lastIndex]?.type === 'video') {
+				const videoContext = uni.createVideoContext('video-' + lastIndex, this);
+				if (videoContext) {
+					videoContext.pause();
+					this.videoPlaying = false;
+				}
+			}
+		},
+		onVideoPlay(idx) {
+			// 更新当前播放的视频索引
+			this.videoPlaying = true;
+			if (this.currentMediaIndex !== idx) {
+				this.currentMediaIndex = idx;
+			}
+		},
+		onVideoPause() {
+			this.videoPlaying = false;
+		},
+		onVideoEnded() {
+			this.videoPlaying = false;
+		},
+		goPage(url) {
+			uni.navigateTo({
+				url: url
+			});
+		},
+		onSpecConfirm(selectedSpec) {
+			uni.navigateTo({
+				url: '/pages/crowdFunding/orderConfirm',
+				success: function (res) {
+					// 通过 eventChannel 向被打开页面传送数据
+					res.eventChannel.emit('acceptDataFromOpener', { selectedSpec: selectedSpec, detail: this.detail });
+				}.bind(this)
+			});
+		},
+		specificationsOpen() {
+			this.$refs.specSheet.show();
+		},
+		toggleFavorite() {
+			if (!this.projectId) {
+
+				return;
+			}
+			const action = this.isFavorite ? 'remove' : 'add';
+			uni.request({
+				url: this.$apiHost + '/crowdfund/favorite',
+				method: 'POST',
+				header: {
+					"content-type": "application/x-www-form-urlencoded",
+				},
+				data: {
+					uuid: getApp().globalData.uuid,
+					skey: getApp().globalData.skey,
+					crowdfund_id: this.projectId,
+					action
+				},
+				success: (res) => {
+					console.log(res.data, "收藏");
+
+					if (res.data && res.data.success && res.data.success == 'yes') {
+						this.isFavorite = !this.isFavorite;
+						uni.showToast({ title: this.isFavorite ? '已收藏' : '已取消收藏', icon: 'none' });
+					} else {
+						uni.showToast({ title: res.data.msg || '操作失败', icon: 'none' });
+					}
+				},
+				fail: () => {
+					uni.showToast({ title: '网络错误', icon: 'none' });
+				}
+			});
+
+		},
+		getDetail() {
+			if (!this.projectId) return;
+			uni.request({
+				url: this.$apiHost + '/crowdfund/detail',
+				method: 'GET',
+				data: {
+					id: this.projectId,
+					uuid: getApp().globalData.uuid,
+					skey: getApp().globalData.skey
+
+				},
+				success: (res) => {
+					if (res.data && res.data.success === 'yes' && res.data.data) {
+						this.processingDataDetails(res.data.data);
+						// 可根据接口返回字段设置isFavorite等
+					}
+				}
+			});
+			uni.request({
+				url: this.$apiHost + '/crowdfund/favorite/status',
+				method: 'GET',
+				data: {
+					crowdfund_id: this.projectId,
+					uuid: getApp().globalData.uuid,
+					skey: getApp().globalData.skey
+				},
+				success: (res) => {
+					if (res.data && res.data.success === 'yes' && res.data.data) {
+						console.log(res.data.data, "收藏");
+						this.isFavorite = res.data.data.is_favorited;
+						// 可根据接口返回字段设置isFavorite等
+					}
+				}
+			});
+			uni.request({
+				url: this.$apiHost + '/crowdfund/articles',
+				method: 'GET',
+				data: {
+					crowdfund_id: this.projectId,
+					page: 1,
+					pageSize: 1,
+					uuid: getApp().globalData.uuid,
+					skey: getApp().globalData.skey
+				},
+				success: (res) => {
+					if (res.data && res.data.success === 'yes' && res.data.data) {
+						if (Array.isArray(res.data.data.list)) {
+							this.projectUpdate = res.data.data.list[0]
+							this.projectUpdate.create_time = this.projectUpdate.create_time.replace(/-/g, '.').slice(0, 16)
+							console.log(this.projectUpdate, 8888);
+
+						}
+					}
+				}
+			});
+			uni.request({
+				url: this.$apiHost + '/Article/getcomments',
+				data: {
+					uuid: getApp().globalData.uuid,
+					type: 'crowdfund',
+					id: this.projectId,
+					page: 1,
+					limit: 2,
+				},
+				header: {
+					"content-type": "application/json",
+					'sign': getApp().globalData.headerSign
+				},
+				success: (res) => {
+					console.log("评论列表:", res.data);
+					if (res.data.success == "yes") {
+						this.totalNumberOfComments = res.data.total
+						// 确保数据存在且是数组,然后只取前两条
+						this.commentList = (res.data.list || []).slice(0, 2).map(item => ({
+							avatar: item.user_avatar || '',
+							content: item.user_content || '',
+							likeNum: item.like_count || 0,
+							liked: item.is_like || false
+						}));
+
+					} else {
+						// 如果请求失败,使用默认空数组
+						this.commentList = [];
+						uni.showToast({
+							title: '获取评论列表失败',
+							icon: 'none'
+						});
+					}
+				},
+				fail: (e) => {
+					console.log("----e:", e);
+					// 请求失败时使用默认空数组
+					this.commentList = [];
+				}
+			});
+			
+		},
+		goWeb(url, title) {
+		uni.navigateTo({
+			url: `/pages/webview/index?url=${encodeURIComponent(url)}&title=${encodeURIComponent(title)}`
+		})
+	},
+		processingDataDetails(data) {
+			
+			this.detail = data;
+			// 确保 image_list 始终是一个数组
+			data.image_list = data.image_list || [];
+
+			const videoItem = data.video_url ? [{
+				type: 'video',
+				poster: data.main_image,
+				src: data.video_url,
+			}] : [];
+			
+			const imageItems = data.image_list.map(v => ({
+				type: 'image',
+				src: v
+			}));
+
+			// 计算剩余天数
+			if (data.start_time && data.end_time) {
+				const startDate = new Date(data.start_time.replace(/-/g, '/'));
+				const endDate = new Date(data.end_time.replace(/-/g, '/'));
+				const now = new Date();
+
+				// 如果当前时间在开始时间之前,显示总天数
+				if (now < startDate) {
+					this.detail.daysRemaining = Math.ceil((endDate - startDate) / (1000 * 60 * 60 * 24));
+				}
+				// 如果当前时间在结束时间之后,显示0天
+				else if (now > endDate) {
+					this.detail.daysRemaining = 0;
+				}
+				// 如果当前时间在开始和结束时间之间,显示剩余天数
+				else {
+					this.detail.daysRemaining = Math.ceil((endDate - now) / (1000 * 60 * 60 * 24));
+				}
+			} else {
+				this.detail.daysRemaining = 0;
+			}
+			// 计算进度
+			this.detail.progress = (data.current_amount / data.goal_amount * 100).toFixed(2)
+			console.log(this.detail.progress, "进度");
+
+			if (Number.isNaN) this.detail.progress = 0
+			this.mediaList = [...videoItem, ...imageItems];
+
+			this.rewards = data.rewards
+
+			this.shareTitle = data.title;
+			this.shareDesc = data.description;
+			this.shareImg = data.image_list[0];
+
+			console.log("回报数据", this.rewards);
+			console.log("顶部轮播数据", this.mediaList, "mediaList");
+			console.log("详情", this.detail, "detail");
+		},
+		certificationTips(){
+			uni.showToast({
+				title: '官方已实名认证',
+				icon: 'none'
+			});
+		}
+	},
+	mounted() {
+		this.$nextTick(() => {
+			// 动态获取轮播图高度
+			uni.createSelectorQuery().in(this).select('.top-swiper').boundingClientRect(rect => {
+				if (rect) {
+					this.swiperHeight = rect.height;
+				}
+			}).exec();
+		});
+	},  
+	onPageScroll(e) {
+		const threshold = this.swiperHeight || uni.upx2px(400); // 优先用实际高度
+		let opacity = 0;
+		if (e.scrollTop > 0) {
+			opacity = Math.min(e.scrollTop / threshold, 1);
+		}
+		this.navBgOpacity = opacity;
+	},
+	onLoad(options) {
+		// 获取id
+		this.projectId = options.id || null;
+		this.getDetail();
+	},
+	
+}
+</script>
+
+
+<style lang="scss" scoped>
+.crowdfunding-details {
+
+	/* 自定义导航栏样式 */
+	.custom-navbar {
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		justify-content: space-between;
+		width: 100%;
+		height: calc(90rpx + var(--status-bar-height));
+		padding: 0 20rpx;
+		position: fixed;
+		top: 0;
+		z-index: 100;
+		padding: 12rpx 24rpx;
+		padding-top: calc(var(--status-bar-height) + 12rpx);
+		background: transparent;
+		transition: background 0.3s;
+
+		image {
+			width: 64rpx;
+			height: 64rpx;
+		}
+	}
+
+	.swiper-container {
+		position: relative;
+		width: 100vw;
+		height: 100vw;
+		background: #000;
+
+		.top-swiper {
+			width: 100%;
+			height: 100%;
+
+			.swiper-item {
+				width: 100%;
+				height: 100%;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+			}
+
+			.media-wrapper {
+				width: 100%;
+				height: 100%;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				background: #000;
+			}
+
+			.swiper-video {
+				width: 100%;
+				height: 100%;
+			}
+
+			.swiper-img {
+				width: 100%;
+				height: 100%;
+				object-fit: cover;
+			}
+		}
+
+		.custom-dots {
+			position: absolute;
+			bottom: 20rpx;
+			left: 50%;
+			transform: translateX(-50%);
+			display: flex;
+			gap: 16rpx;
+
+			.dot {
+				width: 12rpx;
+				height: 12rpx;
+				border-radius: 50%;
+				background: rgba(255, 255, 255, 0.5);
+				transition: all 0.3s;
+
+				&.active {
+					width: 24rpx;
+					border-radius: 6rpx;
+					background: #fff;
+				}
+			}
+		}
+	}
+
+	.content {
+		background: #f2f6f2;
+		padding: 20rpx;
+
+		.section {
+			background: #fff;
+			border-radius: 12rpx;
+			padding: 16rpx;
+			padding-bottom: 20rpx;
+			margin: 12rpx 0;
+
+			.section-title {
+				font-size: 28rpx;
+				font-family: 'PingFang SC-Medium';
+				margin-bottom: 6rpx;
+			}
+
+			.section-content {
+				color: #333;
+				font-size: 24rpx;
+				line-height: 1.8;
+			}
+
+			.intro-img {
+				width: 100%;
+				margin: 0;
+				padding: 0;
+				margin-bottom: -10rpx;
+			}
+		}
+
+		.project-card {
+			padding-bottom: 15rpx;
+
+			.project-title {
+				font-size: 36rpx;
+				color: 1f1f1f;
+				font-family: "PingFang SC-Bold";
+				font-weight: 400;
+			}
+
+			.progress-bar-wrap {
+				display: flex;
+				align-items: center;
+				font-size: 20rpx;
+				color: #1F1F1F;
+				padding-top: 30rpx;
+				padding-bottom: 14rpx;
+
+				.progress-percent {
+					padding-left: 12rpx;
+				}
+			}
+
+			.project-stats {
+				display: flex;
+				justify-content: space-between;
+				padding-top: 0;
+
+				.stat-block {
+					display: flex;
+					flex-direction: column;
+					align-items: center;
+					text-align: center;
+					justify-content: center;
+					color: #1F1F1F;
+
+					&:first-child {
+						align-items: flex-start;
+					}
+
+					&:last-child {
+						display: flex;
+						flex-direction: column;
+						align-items: center;
+						text-align: center;
+						justify-content: center;
+						color: #1F1F1F;
+
+						&:first-child {
+							align-items: flex-start;
+						}
+
+						&:last-child {
+							align-items: flex-end;
+						}
+
+						.stat-main {
+							font-size: 28rpx;
+
+							&.amountOfMoney {
+								font-size: 32rpx;
+								font-family: "PingFang SC-Bold";
+							}
+						}
+
+						.stat-sub {
+							font-size: 20rpx;
+						}
+					}
+				}
+			}
+		}
+
+		.project-update {
+			background: transparent;
+			height: 166rpx;
+			display: flex;
+			width: 100%;
+			justify-content: space-between;
+			padding: 0;
+
+			>view {
+				border-radius: 12rpx;
+				background: #fff;
+				flex-shrink: 0;
+			}
+
+			.project-update-left {
+				width: 590rpx;
+				height: 100%;
+				padding: 16rpx;
+
+				.project-update-left-title {
+					display: flex;
+					justify-content: space-between;
+					align-items: center;
+					font-size: 22rpx;
+				}
+
+				.project-update-left-content {
+					display: flex;
+					align-items: center;
+					margin-top: 8rpx;
+
+					>view {
+						font-size: 24rpx;
+						font-weight: 400;
+						font-family: "PingFang SC-Bold";
+					}
+
+					.image {
+						width: 180rpx;
+						height: 78rpx;
+						overflow: hidden;
+						margin-left: 26rpx;
+						border-radius: 8rpx;
+
+						image {
+							overflow: hidden;
+							width: 100%;
+						}
+					}
+				}
+
+			}
+
+			.project-update-right {
+				width: 108rpx;
+				height: 100%;
+				font-size: 22rpx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				flex-direction: column;
+
+				image {
+					margin-top: 12rpx;
+					width: 28rpx;
+					height: 28rpx;
+				}
+			}
+		}
+
+		.poster {
+			padding: 0;
+			padding-top: 16rpx;
+		}
+	}
+
+	.comment {
+		border-radius: 12rpx;
+		background: #fff;
+		margin-top: 24rpx;
+		padding: 0 0 16rpx 0;
+
+		.comment-title {
+			display: flex;
+			justify-content: space-between;
+			align-items: center;
+			font-size: 26rpx;
+			color: #333;
+			padding: 18rpx 20rpx 0 20rpx;
+
+			.comment-more {
+				color: #999;
+				font-size: 22rpx;
+				display: flex;
+				align-items: center;
+
+				image {
+					width: 20rpx;
+					height: 20rpx;
+					margin-left: 4rpx;
+				}
+			}
+		}
+
+		.comment-content {
+			padding: 0 20rpx;
+
+			.comment-item {
+				display: flex;
+				//align-items: flex-start;
+				align-items: center;
+				padding: 18rpx 0 0 0;
+				border-bottom: 1rpx solid #f5f5f5;
+
+				&:last-child {
+					border-bottom: none;
+				}
+
+				.comment-avatar {
+					width: 48rpx;
+					height: 48rpx;
+					border-radius: 50%;
+					margin-right: 16rpx;
+					flex-shrink: 0;
+				}
+
+				.comment-item-main {
+					flex: 1;
+					display: flex;
+					flex-direction: column;
+
+					.comment-item-content {
+						color: #1f1f1f;
+						font-size: 24rpx;
+						line-height: 1.7;
+						margin-bottom: 8rpx;
+						display: -webkit-box;
+						-webkit-line-clamp: 2;
+						-webkit-box-orient: vertical;
+						overflow: hidden;
+						text-overflow: ellipsis;
+						word-break: break-all;
+					}
+				}
+
+				.comment-item-like {
+					display: flex;
+					align-items: center;
+					margin-left: 36rpx;
+
+					.like-icon {
+						width: 28rpx;
+						height: 28rpx;
+						margin-right: 4rpx;
+					}
+
+					.like-num {
+						font-size: 22rpx;
+						color: #888;
+					}
+				}
+			}
+		}
+	}
+
+	.bottom-bar-reserveASeat {
+		width: 100%;
+		height: calc(12rpx + 88rpx + var(--window-bottom) + 30rpx);
+	}
+
+	.bottom-bar {
+		position: fixed;
+		left: 0;
+		right: 0;
+		bottom: 0;
+		z-index: 999;
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		background: #fff;
+		padding: 14rpx 40rpx;
+		padding-bottom: calc(14rpx + var(--window-bottom));
+		box-sizing: border-box;
+
+		.bottom-bar-left {
+			display: flex;
+			align-items: center;
+			gap: 32rpx;
+
+			.bar-btn {
+				display: flex;
+				flex-direction: column;
+				align-items: center;
+				justify-content: center;
+				width: 80rpx;
+				height: 80rpx;
+				border-radius: 12rpx;
+
+				.bar-icon {
+					width: 48rpx;
+					height: 48rpx;
+					margin-bottom: 4rpx;
+				}
+
+				.bar-text {
+					font-size: 20rpx;
+					color: #1f1f1f;
+					font-family: "PingFang SC";
+				}
+			}
+		}
+
+
+		.buy-btn {
+			width: 588rpx;
+			height: 88rpx;
+			background: #1f1f1f;
+			color: #ACF934;
+			font-size: 32rpx;
+			border-radius: 80rpx;
+			border: none;
+			font-weight: bold;
+			text-align: center;
+			line-height: 80rpx;
+			margin-left: 24rpx;
+		}
+
+	}
+}
+
+.back-top {
+	position: fixed;
+	bottom: calc(126rpx + var(--window-bottom));
+	right: 16rpx;
+	width: 82rpx;
+	height: 82rpx;
+}
+
+.initiator-bar {
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	background: #fff;
+	border-radius: 10rpx;
+	padding: 18rpx 24rpx 18rpx 18rpx;
+	margin: 0;
+
+	.initiator-avatar {
+		width: 64rpx;
+		height: 64rpx;
+		border-radius: 50%;
+		margin-right: 18rpx;
+		flex-shrink: 0;
+	}
+
+	.initiator-info {
+		display: flex;
+		align-items: center;
+		flex: 1;
+		min-width: 0;
+	}
+
+	.initiator-name {
+		font-size: 30rpx;
+		color: #222;
+		font-weight: bold;
+		margin-right: 12rpx;
+		max-width: 260rpx;
+		overflow: hidden;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+	}
+
+	.initiator-tag {
+		background: #1a1a1a;
+		color: #b6ff4b;
+		font-size: 20rpx;
+		border-radius: 8rpx;
+		padding: 2rpx 12rpx;
+		margin-left: 2rpx;
+		display: inline-flex;
+		align-items: center;
+		image{
+			width: 28rpx;
+			height: 28rpx; 
+		}
+	}
+
+	.initiator-service-btn {
+		display: flex;
+		align-items: center;
+		background: #1a1a1a;
+		color: #b6ff4b;
+		font-size: 28rpx;
+		border-radius: 128rpx;
+		padding: 0 24rpx 0 12rpx;
+		height: 56rpx;
+		margin-left: 18rpx;
+		font-weight: bold;
+	}
+
+	.service-icon {
+		width: 32rpx;
+		height: 32rpx;
+		margin-right: 8rpx;
+	}
+}
+
+.scale-tap {
+	transition: transform 0.15s;
+}
+
+.scale-tap:active {
+	transform: scale(0.92);
+}
+
+.risk-section {
+	background: #fff;
+	border-radius: 12rpx;
+	margin: 24rpx 0 0 0;
+	padding: 0 0 18rpx 0;
+	position: relative;
+	overflow: hidden;
+
+	.risk-row {
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		padding: 18rpx 24rpx 0 0rpx;
+		font-size: 28rpx;
+		color: #1f1f1f;
+		background: #fff;
+
+		&.risk-row-border {
+			border-top: 1rpx solid #f2f2f2;
+			margin-top: 18rpx;
+			padding-top: 18rpx;
+		}
+	}
+
+	.risk-title {
+		font-size: 28rpx;
+		color: #1f1f1f;
+		font-family: 'PingFang SC-Bold';
+		font-weight: 400;
+
+	}
+
+	.risk-more {
+		color: #1f1f1f;
+		font-size: 24rpx;
+		display: flex;
+		align-items: center;
+		font-weight: 400;
+		font-family: 'PingFang SC-Bold';
+
+		.risk-more-icon {
+			width: 24rpx;
+			height: 24rpx;
+			margin-left: 4rpx;
+			margin-top: 4rpx;
+		}
+	}
+
+	.risk-desc {
+		font-size: 24rpx;
+		color: #999;
+		padding: 8rpx 24rpx 0 0;
+		font-family: 'PingFang SC-Regular';
+	}
+
+	.risk-content {
+		font-size: 24rpx;
+		color: #999;
+		padding: 12rpx 24rpx 0 0;
+		font-family: 'PingFang SC-Regular';
+		line-height: 1.7;
+
+		>view {
+			margin-bottom: 6rpx;
+		}
+	}
+}
+</style>

+ 24 - 6
pages/crowdFunding/crowdfundingDetails.vue

@@ -115,7 +115,7 @@
 					<image class="initiator-avatar" :src="detail.creator_avatar" />
 					<view class="initiator-info">
 						<text class="initiator-name">{{ detail.creator_nickname }}</text>
-						<text class="initiator-tag">发起人</text>
+						<div class="initiator-tag" @click="certificationTips()"><image src="@/static/crowdFunding/authentication.png" mode="widthFix"></image> <div>发起人</div></div>
 					</view>
 					<view class="initiator-service-btn  blick-btn-animation"
 						@click="goPage('/pages/crowdFunding/customerService?id=' + detail.creator_id + '&zc_id=' + detail.id)">
@@ -173,7 +173,7 @@
 
 		<!-- 分享弹窗 -->
 		<SharePopup :visible="showShare" :userId="0" :share-title="shareTitle" :share-desc="shareDesc"
-			:share-img="shareImg" view="crowdfundingDetails" @close="showShare = false" :isReportContent="true" />
+			:share-img="shareImg" view="crowdfundingDetails" :link="shareLink" @close="showShare = false" :isReportContent="true" />
 
 		<productSpecifications ref="specSheet" :rewards="rewards" :title="detail.title" @confirm="onSpecConfirm" />
 
@@ -201,9 +201,10 @@ export default {
 			navBgOpacity: 0,
 			swiperHeight: 0,
 			showShare: false,
-			shareTitle: '【Woh】灯塔 塔罗牌 治愈风泛传特系',
-			shareDesc: '快来支持这个有趣的众筹项目吧!',
-			shareImg: require('@/static/crowdFunding/top-img.png'),
+			shareTitle: '',
+			shareDesc: '',
+			shareImg: '',
+			shareLink:"https://e.zhichao.art/site/#/mobile-download",
 			userId: 0, // 可根据实际登录用户赋值
 			isFavorite: false, // 是否已收藏
 			projectId: null, // 当前项目id
@@ -427,6 +428,7 @@ export default {
 		})
 	},
 		processingDataDetails(data) {
+			
 			this.detail = data;
 			// 确保 image_list 始终是一个数组
 			data.image_list = data.image_list || [];
@@ -472,9 +474,19 @@ export default {
 
 			this.rewards = data.rewards
 
+			this.shareTitle = data.title;
+			this.shareDesc = data.description;
+			this.shareImg = data.image_list[0];
+
 			console.log("回报数据", this.rewards);
 			console.log("顶部轮播数据", this.mediaList, "mediaList");
 			console.log("详情", this.detail, "detail");
+		},
+		certificationTips(){
+			uni.showToast({
+				title: '官方已实名认证',
+				icon: 'none'
+			});
 		}
 	},
 	mounted() {
@@ -486,7 +498,7 @@ export default {
 				}
 			}).exec();
 		});
-	},
+	},  
 	onPageScroll(e) {
 		const threshold = this.swiperHeight || uni.upx2px(400); // 优先用实际高度
 		let opacity = 0;
@@ -978,6 +990,12 @@ export default {
 		border-radius: 8rpx;
 		padding: 2rpx 12rpx;
 		margin-left: 2rpx;
+		display: inline-flex;
+		align-items: center;
+		image{
+			width: 28rpx;
+			height: 28rpx; 
+		}
 	}
 
 	.initiator-service-btn {

+ 1180 - 0
pages/crowdFunding/crowdfundingDetailsDesign.vue

@@ -0,0 +1,1180 @@
+<template>
+	<view class="crowdfunding-details">
+		<view class="custom-navbar" :style="navBgStyle">
+			<view class="navbar-left scale-tap" @click="goBack">
+				<image src="@/static/crowdFunding/back.png" mode="widthFix"></image>
+			</view>
+			<view class="navbar-center one-omit" style="max-width: 70vw; " :style="{ opacity: navBgOpacity }">
+				{{ detail.title }}
+			</view>
+			<view class="navbar-right scale-tap" @click="showShare = true">
+				<image src="@/static/crowdFunding/share.png" mode="widthFix"></image>
+			</view>
+		</view>
+		<!-- 顶部视频图片混合轮播 -->
+		<view class="swiper-container">
+			<swiper class="top-swiper" :indicator-dots="false" circular :current="currentMediaIndex"
+				@change="handleSwiperChange" :duration="300">
+				<swiper-item v-for="(item, idx) in mediaList" :key="idx" class="swiper-item">
+					<view v-if="item.type === 'video'" class="media-wrapper">
+						<video class="swiper-video" :src="item.src" :poster="item.poster" :id="'video-' + idx" controls
+							object-fit="contain" enable-progress-gesture="false" :loop="false"
+							:show-fullscreen-btn="false" :show-play-btn="true" :enable-play-gesture="false"
+							@ended="onVideoEnded" @play="onVideoPlay(idx)" @pause="onVideoPause"></video>
+					</view>
+					<image v-else class="swiper-img" :src="item.src" mode="aspectFill" />
+				</swiper-item>
+			</swiper>
+			<!-- 自定义指示点 -->
+			<view class="custom-dots">
+				<view v-for="(item, index) in mediaList" :key="index"
+					:class="['dot', currentMediaIndex === index ? 'active' : '']" @click="switchMedia(index)"></view>
+			</view>
+		</view>
+
+		<view class="content">
+			<!-- 项目信息 -->
+			<view class="section project-card">
+				<view class="project-title">{{ detail.title }}</view>
+				<view class="progress-bar-wrap">
+					<uv-line-progress height="8rpx" :showText="false"
+						:percentage="(detail.current_amount / detail.goal_amount * 100).toFixed(2)"
+						inactiveColor="#F0F0F0" activeColor="#ACF934"></uv-line-progress>
+					<view class="progress-percent">{{ (detail.current_amount / detail.goal_amount * 100).toFixed(2) +
+						'%'
+					}}</view>
+				</view>
+				<view class="project-stats">
+					<view class="stat-block">
+						<view class="stat-main amountOfMoney">¥{{ detail.current_amount }}</view>
+						<view class="stat-sub">{{ detail.supporter_count }}人支持</view>
+					</view>
+					<view class="stat-block">
+						<!-- <view class="stat-main">{{ detail.daysRemaining }}天</view>
+						<view class="stat-sub">剩余时间</view> -->
+					</view>
+					<view class="stat-block">
+						<view class="stat-main">¥{{ detail.goal_amount }}</view>
+						<view class="stat-sub">众筹目标</view>
+					</view>
+				</view>
+			</view>
+
+
+			<!-- 项目更新 -->
+			<view class="section project-update" v-if="projectUpdate && projectUpdate.numb">
+				<view class="project-update-left scale-tap"
+					@click="goPage('/pages/crowdFunding/projectUpdateDetails?id=' + projectUpdate.id)">
+					<view class="project-update-left-title">
+						<view>·第{{ projectUpdate.numb }}次更新</view>
+						<view style="color: #999;">{{ projectUpdate.create_time }}</view>
+					</view>
+					<view class="project-update-left-content">
+						<view class="two-omit">{{ projectUpdate.title }}</view>
+						<view class="image">
+							<image :src="projectUpdate.image" />
+						</view>
+					</view>
+				</view>
+				<view class="project-update-right scale-tap"
+					@click="goPage('/pages/crowdFunding/discussionArea?tags=update&id=' + projectId)">
+					<view>历史更新</view>
+					<image src="@/static/crowdFunding/updateDetails.png"></image>
+
+				</view>
+			</view>
+
+			<view class="section comment scale-tap"
+				@click="goPage('/pages/crowdFunding/discussionArea?tags=comment&id=' + projectId)">
+				<view class="comment-title">
+					<view>项目讨论({{ totalNumberOfComments }})</view>
+					<view class="comment-more">查看更多
+						<image src=" @/static/crowdFunding/right.png">
+						</image>
+					</view>
+				</view>
+				<view class="comment-content">
+					<block v-for="(item, idx) in commentList" :key="idx">
+						<view class="comment-item">
+							<image class="comment-avatar" :src="item.avatar"></image>
+							<view class="comment-item-main">
+								<view class="comment-item-content">{{ item.content }}</view>
+							</view>
+							<view class="comment-item-like">
+								<image class="like-icon"
+									:src="item.liked ? '/static/icon/icon-18.png' : '/static/icon/icon-19.png'"></image>
+								<text class="like-num">{{ item.likeNum }}</text>
+							</view>
+						</view>
+					</block>
+				</view>
+			</view>
+
+			<!-- 塔罗牌介绍 -->
+			<view class="section poster">
+				<view class="initiator-bar">
+					<image class="initiator-avatar" :src="detail.creator_avatar" />
+					<view class="initiator-info">
+						<text class="initiator-name">{{ detail.creator_nickname }}</text>
+						<text class="initiator-tag">发起人</text>
+					</view>
+					<!-- <view class="initiator-service-btn  blick-btn-animation"
+						@click="goPage('/pages/crowdFunding/customerService?id=' + detail.creator_id + '&zc_id=' + detail.id)">
+						<image class="service-icon" src="@/static/crowdFunding/service.png" />
+						<text>客服</text>
+					</view> -->
+					<text class="followTheAuthor followTheAuthor1" v-if="detail.is_attention == 0"
+						@click="followTheAuthor(1)">+关注</text>
+					<text class="followTheAuthor followTheAuthor0" v-if="detail.is_attention == 1"
+						@click="followTheAuthor(0)">已关注</text>
+				</view>
+				<block v-for="(item, idx) in detail.content_images" :key="idx">
+					<image class="intro-img" :src="item" mode="widthFix" />
+				</block>
+			</view>
+
+
+
+			<!-- 风险说明 -->
+			<view class="section risk-section">
+				<view class="risk-row" @click="goWeb('https://e.zhichao.art/web/refund.php', '退款说明')">
+					<view class="risk-title">退款政策</view>
+					<view class="risk-more  ">查看更多
+						<image src="@/static/crowdFunding/right.png" class="risk-more-icon" />
+					</view>
+				</view>
+				<view class="risk-desc">众筹结束前最后1个小时无法申请退款</view>
+				<view class="risk-row risk-row-border"
+					@click="goWeb('https://e.zhichao.art/web/crowdtips.php', '风险提示')">
+					<view class="risk-title">风险提示</view>
+					<view class="risk-more  ">查看更多
+						<image src="@/static/crowdFunding/right.png" class="risk-more-icon" />
+					</view>
+				</view>
+				<view class="risk-content">
+					<view>1. 您参与众筹是支持将创意变为现实的过程,而不是直接的商品交易,因此存在一定风险。请您根据自己的判断选择,支持众筹项目。</view>
+					<view>2. 众筹存在于发起人与支持者之间,摩点作为第三方平台,提供网络空间、技术支持等服务。众筹的回报产品和承诺由发起人负责。</view>
+				</view>
+			</view>
+		</view>
+		<view class="bottom-bar-reserveASeat"></view>
+		<view class="bottom-bar">
+
+			<button class="buy-btn blick-btn-animation followTheAuthor0"
+				v-if="detail.is_like == 1 || detail.is_like == '1'" @click="specificationsOpen()">不看好取消支持</button>
+			<button class="buy-btn blick-btn-animation followTheAuthor1" v-else @click="specificationsOpen()">
+				看好并支持</button>
+		</view>
+		<image src="@/static/crowdFunding/backToTop.png" class="back-top scale-tap" v-show="navBgOpacity > 0.9"
+			@click="scrollToTop"></image>
+
+		<!-- 分享弹窗 -->
+		<SharePopup :visible="showShare" :userId="0" :share-title="shareTitle" :share-desc="shareDesc"
+			:share-img="shareImg" view="crowdfundingDetails" :link="shareLink" @close="showShare = false" :isReportContent="true" />
+
+		<!-- <productSpecifications ref="specSheet" :rewards="rewards" :title="detail.title" @confirm="onSpecConfirm" /> -->
+
+	</view>
+</template>
+
+<script>
+import VideoPlayer from "@/components/VideoPlayer/VideoPlayer.vue";
+import SharePopup from "@/components/SharePopup/SharePopup.vue";
+import productSpecifications from "./components/productSpecifications/productSpecifications.vue";
+
+export default {
+	components: {
+		VideoPlayer,
+		SharePopup,
+		productSpecifications
+	},
+	data() {
+		return {
+			mediaList: [],
+			videoPlaying: false,
+			currentMediaIndex: 0,
+			commentList: [
+			],
+			navBgOpacity: 0,
+			swiperHeight: 0,
+			showShare: false,
+			shareTitle: '',
+			shareDesc: '',
+			shareImg: '',
+			shareLink:"https://e.zhichao.art/site/#/mobile-download",
+			userId: 0, // 可根据实际登录用户赋值
+			isFavorite: false, // 是否已收藏
+			projectId: null, // 当前项目id
+			detail: {}, // 众筹详情
+			projectUpdate: '',
+			rewards: [],
+			totalNumberOfComments: 0
+		}
+	},
+	computed: {
+		navBgStyle() {
+			return {
+				background: `rgba(255,255,255,${this.navBgOpacity})`,
+				transition: 'background 0.3s'
+			}
+		}
+	},
+	methods: {
+		// 返回上一页
+		goBack() {
+			uni.navigateBack({
+				delta: 1,
+			});
+		},
+		scrollToTop() {
+			uni.pageScrollTo({
+				scrollTop: 0,
+				duration: 300
+			});
+		},
+		switchMedia(index) {
+			if (this.currentMediaIndex === index) return;
+
+			// 如果当前在播放视频,先暂停
+			if (this.mediaList[this.currentMediaIndex]?.type === 'video') {
+				const videoContext = uni.createVideoContext('video-' + this.currentMediaIndex, this);
+				if (videoContext) {
+					videoContext.pause();
+				}
+			}
+
+			this.currentMediaIndex = index;
+		},
+		handleSwiperChange(e) {
+			const lastIndex = this.currentMediaIndex;
+			this.currentMediaIndex = e.detail.current;
+
+			// 如果上一个是视频,暂停它
+			if (this.mediaList[lastIndex]?.type === 'video') {
+				const videoContext = uni.createVideoContext('video-' + lastIndex, this);
+				if (videoContext) {
+					videoContext.pause();
+					this.videoPlaying = false;
+				}
+			}
+		},
+		onVideoPlay(idx) {
+			// 更新当前播放的视频索引
+			this.videoPlaying = true;
+			if (this.currentMediaIndex !== idx) {
+				this.currentMediaIndex = idx;
+			}
+		},
+		onVideoPause() {
+			this.videoPlaying = false;
+		},
+		onVideoEnded() {
+			this.videoPlaying = false;
+		},
+		goPage(url) {
+			uni.navigateTo({
+				url: url
+			});
+		},
+		onSpecConfirm(selectedSpec) {
+			uni.navigateTo({
+				url: '/pages/crowdFunding/orderConfirm',
+				success: function (res) {
+					// 通过 eventChannel 向被打开页面传送数据
+					res.eventChannel.emit('acceptDataFromOpener', { selectedSpec: selectedSpec, detail: this.detail });
+				}.bind(this)
+			});
+		},
+		specificationsOpen() {
+			uni.request({
+				url: this.$apiHost + '/Article/like',
+				data: {
+					uuid: getApp().globalData.uuid,
+					id: this.projectId
+				},
+				header: {
+					"content-type": "application/json",
+					'sign': getApp().globalData.headerSign
+				},
+				success: (res) => {
+					if (res.data.str == "点赞成功") {
+						uni.showToast({
+							title: "支持成功",
+							icon: 'none'
+						});
+						// 动态修改页面数据
+						this.detail.is_like = 1;
+						this.detail.like_count += 1;
+						// 强制更新视图
+						this.$forceUpdate();
+					}else if (res.data.str == "取消点赞") {
+						uni.showToast({
+							title: '取消支持',
+							icon: 'none'
+						});
+						// 动态修改页面数据
+						this.detail.is_like = 0;
+						this.detail.like_count -= 1;
+						// 强制更新视图
+						this.$forceUpdate();
+					}else{
+						uni.showToast({
+							title: res.data.str,
+							icon: 'none'
+						});
+					}
+				}
+			});
+		},
+		toggleFavorite() {
+			if (!this.projectId) {
+
+				return;
+			}
+			const action = this.isFavorite ? 'remove' : 'add';
+			uni.request({
+				url: this.$apiHost + '/crowdfund/favorite',
+				method: 'POST',
+				header: {
+					"content-type": "application/x-www-form-urlencoded",
+				},
+				data: {
+					uuid: getApp().globalData.uuid,
+					skey: getApp().globalData.skey,
+					crowdfund_id: this.projectId,
+					action
+				},
+				success: (res) => {
+					console.log(res.data, "收藏");
+
+					if (res.data && res.data.success && res.data.success == 'yes') {
+						this.isFavorite = !this.isFavorite;
+						uni.showToast({ title: this.isFavorite ? '已收藏' : '已取消收藏', icon: 'none' });
+					} else {
+						uni.showToast({ title: res.data.msg || '操作失败', icon: 'none' });
+					}
+				},
+				fail: () => {
+					uni.showToast({ title: '网络错误', icon: 'none' });
+				}
+			});
+
+		},
+
+		getDetail() {
+			if (!this.projectId) return;
+			uni.request({
+				url: this.$apiHost + '/Article/getinfo',
+				method: 'GET',
+				data: {
+					id: this.projectId,
+					uuid: getApp().globalData.uuid,
+					skey: getApp().globalData.skey
+
+				},
+				success: (res) => {
+					console.log(res.data.article, 9999);
+
+					if (res.data && res.data.article) {
+						this.processingDataDetails(res.data.article, res.data);
+						// 可根据接口返回字段设置isFavorite等
+
+					}
+				}
+			});
+			uni.request({
+				url: this.$apiHost + '/crowdfund/favorite/status',
+				method: 'GET',
+				data: {
+					crowdfund_id: this.projectId,
+					uuid: getApp().globalData.uuid,
+					skey: getApp().globalData.skey
+				},
+				success: (res) => {
+					if (res.data && res.data.success === 'yes' && res.data.data) {
+						console.log(res.data.data, "收藏");
+						this.isFavorite = res.data.data.is_favorited;
+						// 可根据接口返回字段设置isFavorite等
+					}
+				}
+			});
+			uni.request({
+				url: this.$apiHost + '/crowdfund/articles',
+				method: 'GET',
+				data: {
+					crowdfund_id: this.projectId,
+					page: 1,
+					pageSize: 1,
+					uuid: getApp().globalData.uuid,
+					skey: getApp().globalData.skey
+				},
+				success: (res) => {
+					if (res.data && res.data.success === 'yes' && res.data.data) {
+						if (Array.isArray(res.data.data.list)) {
+							this.projectUpdate = res.data.data.list[0]
+							this.projectUpdate.create_time = this.projectUpdate.create_time.replace(/-/g, '.').slice(0, 16)
+							console.log(this.projectUpdate, 8888);
+
+						}
+					}
+				}
+			});
+			uni.request({
+				url: this.$apiHost + '/Article/getcomments',
+				data: {
+					uuid: getApp().globalData.uuid,
+					type: 'crowdfund',
+					id: this.projectId,
+					page: 1,
+					limit: 2,
+				},
+				header: {
+					"content-type": "application/json",
+					'sign': getApp().globalData.headerSign
+				},
+				success: (res) => {
+					console.log("评论列表:", res.data);
+					if (res.data.success == "yes") {
+						this.totalNumberOfComments = res.data.total
+						// 确保数据存在且是数组,然后只取前两条
+						this.commentList = (res.data.list || []).slice(0, 2).map(item => ({
+							avatar: item.user_avatar || '',
+							content: item.user_content || '',
+							likeNum: item.like_count || 0,
+							liked: item.is_like || false
+						}));
+
+					} else {
+						// 如果请求失败,使用默认空数组
+						this.commentList = [];
+						uni.showToast({
+							title: '获取评论列表失败',
+							icon: 'none'
+						});
+					}
+				},
+				fail: (e) => {
+					console.log("----e:", e);
+					// 请求失败时使用默认空数组
+					this.commentList = [];
+				}
+			});
+
+		},
+		goWeb(url, title) {
+			uni.navigateTo({
+				url: `/pages/webview/index?url=${encodeURIComponent(url)}&title=${encodeURIComponent(title)}`
+			})
+		},
+		processingDataDetails(data, datas) {
+			this.detail = data;
+			this.detail.creator_avatar = datas.author.avator
+			this.detail.creator_nickname = datas.author.nickname
+			this.detail.is_attention = datas.author.is_attention
+			this.detail.creator_id = datas.author.id
+			// 确保 image_list 始终是一个数组
+			data.content_images = data.content_images.split('|') || [];
+			data.images = data.images.split('|') || [];
+
+			const videoItem = data.video_url ? [{
+				type: 'video',
+				poster: data.main_image,
+				src: data.video_url,
+			}] : [];
+
+			const imageItems = data.images.map(v => ({
+				type: 'image',
+				src: v
+			}));
+			// 计算进度
+			data.goal_amount = data.num_crowd_people
+			data.current_amount = data.like_count
+			this.detail.progress = (data.current_amount / data.goal_amount * 100).toFixed(2)
+			console.log(this.detail.progress, "进度");
+
+			if (Number.isNaN) this.detail.progress = 0
+			this.mediaList = [...videoItem, ...imageItems];
+
+
+			
+			this.shareTitle = data.title;
+			this.shareDesc = data.content;
+			this.shareImg = data.image;
+			// this.rewards = data.rewards
+
+			// console.log("回报数据", this.rewards);
+			console.log("顶部轮播数据", this.mediaList, "mediaList");
+			console.log("详情", this.detail, "detail");
+			console.log(this.detail.is_like, "is_like");
+
+		},
+		followTheAuthor(n) {
+			uni.$emit('check_login', () => {
+				uni.request({
+					url: this.$apiHost + "/Member/attention",
+					data: {
+						uuid: getApp().globalData.uuid,
+						id: this.detail.creator_id,
+					},
+					header: {
+						"content-type": "application/json",
+						sign: getApp().globalData.headerSign,
+					},
+					success: (res) => {
+						console.log("点赞结果:", res.data);
+						uni.showToast({
+							title: res.data.str,
+							icon: "none",
+						});
+
+						if (res.data.success === "yes") {
+							// 动态修改页面数据
+							if (res.data.str == "关注成功") {
+								console.log(1);
+								this.detail.is_attention = 1;
+							} else {
+								console.log(2);
+								this.detail.is_attention = 0;
+							}
+							// 强制更新视图
+							this.$forceUpdate();
+						}
+					},
+					fail: (e) => {
+						console.log("关注失败:", e);
+						uni.showToast({
+							title: "网络请求失败",
+							icon: "none",
+						});
+					},
+				});
+			})
+		},
+	},
+	mounted() {
+		this.$nextTick(() => {
+			// 动态获取轮播图高度
+			uni.createSelectorQuery().in(this).select('.top-swiper').boundingClientRect(rect => {
+				if (rect) {
+					this.swiperHeight = rect.height;
+				}
+			}).exec();
+		});
+	},
+	onPageScroll(e) {
+		const threshold = this.swiperHeight || uni.upx2px(400); // 优先用实际高度
+		let opacity = 0;
+		if (e.scrollTop > 0) {
+			opacity = Math.min(e.scrollTop / threshold, 1);
+		}
+		this.navBgOpacity = opacity;
+	},
+	onLoad(options) {
+		// 获取id
+		this.projectId = options.id || null;
+		this.getDetail();
+	},
+
+}
+</script>
+
+
+<style lang="scss" scoped>
+.crowdfunding-details {
+
+	/* 自定义导航栏样式 */
+	.custom-navbar {
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		justify-content: space-between;
+		width: 100%;
+		height: calc(90rpx + var(--status-bar-height));
+		padding: 0 20rpx;
+		position: fixed;
+		top: 0;
+		z-index: 100;
+		padding: 12rpx 24rpx;
+		padding-top: calc(var(--status-bar-height) + 12rpx);
+		background: transparent;
+		transition: background 0.3s;
+
+		image {
+			width: 64rpx;
+			height: 64rpx;
+		}
+	}
+
+	.swiper-container {
+		position: relative;
+		width: 100vw;
+		height: 100vw;
+		background: #000;
+
+		.top-swiper {
+			width: 100%;
+			height: 100%;
+
+			.swiper-item {
+				width: 100%;
+				height: 100%;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+			}
+
+			.media-wrapper {
+				width: 100%;
+				height: 100%;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				background: #000;
+			}
+
+			.swiper-video {
+				width: 100%;
+				height: 100%;
+			}
+
+			.swiper-img {
+				width: 100%;
+				height: 100%;
+				object-fit: cover;
+			}
+		}
+
+		.custom-dots {
+			position: absolute;
+			bottom: 20rpx;
+			left: 50%;
+			transform: translateX(-50%);
+			display: flex;
+			gap: 16rpx;
+
+			.dot {
+				width: 12rpx;
+				height: 12rpx;
+				border-radius: 50%;
+				background: rgba(255, 255, 255, 0.5);
+				transition: all 0.3s;
+
+				&.active {
+					width: 24rpx;
+					border-radius: 6rpx;
+					background: #fff;
+				}
+			}
+		}
+	}
+
+	.content {
+		background: #f2f6f2;
+		padding: 20rpx;
+
+		.section {
+			background: #fff;
+			border-radius: 12rpx;
+			padding: 16rpx;
+			padding-bottom: 20rpx;
+			margin: 12rpx 0;
+
+			.section-title {
+				font-size: 28rpx;
+				font-family: 'PingFang SC-Medium';
+				margin-bottom: 6rpx;
+			}
+
+			.section-content {
+				color: #333;
+				font-size: 24rpx;
+				line-height: 1.8;
+			}
+
+			.intro-img {
+				width: 100%;
+				margin: 0;
+				padding: 0;
+				margin-bottom: -10rpx;
+			}
+		}
+
+		.project-card {
+			padding-bottom: 15rpx;
+
+			.project-title {
+				font-size: 36rpx;
+				color: 1f1f1f;
+				font-family: "PingFang SC-Bold";
+				font-weight: 400;
+			}
+
+			.progress-bar-wrap {
+				display: flex;
+				align-items: center;
+				font-size: 20rpx;
+				color: #1F1F1F;
+				padding-top: 30rpx;
+				padding-bottom: 14rpx;
+
+				.progress-percent {
+					padding-left: 12rpx;
+				}
+			}
+
+			.project-stats {
+				display: flex;
+				justify-content: space-between;
+				padding-top: 0;
+
+				.stat-block {
+					display: flex;
+					flex-direction: column;
+					align-items: center;
+					text-align: center;
+					justify-content: center;
+					color: #1F1F1F;
+
+					&:first-child {
+						align-items: flex-start;
+					}
+
+					&:last-child {
+						display: flex;
+						flex-direction: column;
+						align-items: center;
+						text-align: center;
+						justify-content: center;
+						color: #1F1F1F;
+
+						&:first-child {
+							align-items: flex-start;
+						}
+
+						&:last-child {
+							align-items: flex-end;
+						}
+
+						.stat-main {
+							font-size: 28rpx;
+
+							&.amountOfMoney {
+								font-size: 32rpx;
+								font-family: "PingFang SC-Bold";
+							}
+						}
+
+						.stat-sub {
+							font-size: 20rpx;
+						}
+					}
+				}
+			}
+		}
+
+		.project-update {
+			background: transparent;
+			height: 166rpx;
+			display: flex;
+			width: 100%;
+			justify-content: space-between;
+			padding: 0;
+
+			>view {
+				border-radius: 12rpx;
+				background: #fff;
+				flex-shrink: 0;
+			}
+
+			.project-update-left {
+				width: 590rpx;
+				height: 100%;
+				padding: 16rpx;
+
+				.project-update-left-title {
+					display: flex;
+					justify-content: space-between;
+					align-items: center;
+					font-size: 22rpx;
+				}
+
+				.project-update-left-content {
+					display: flex;
+					align-items: center;
+					margin-top: 8rpx;
+
+					>view {
+						font-size: 24rpx;
+						font-weight: 400;
+						font-family: "PingFang SC-Bold";
+					}
+
+					.image {
+						width: 180rpx;
+						height: 78rpx;
+						overflow: hidden;
+						margin-left: 26rpx;
+						border-radius: 8rpx;
+
+						image {
+							overflow: hidden;
+							width: 100%;
+						}
+					}
+				}
+
+			}
+
+			.project-update-right {
+				width: 108rpx;
+				height: 100%;
+				font-size: 22rpx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				flex-direction: column;
+
+				image {
+					margin-top: 12rpx;
+					width: 28rpx;
+					height: 28rpx;
+				}
+			}
+		}
+
+		.poster {
+			padding: 0;
+			padding-top: 16rpx;
+		}
+	}
+
+	.comment {
+		border-radius: 12rpx;
+		background: #fff;
+		margin-top: 24rpx;
+		padding: 0 0 16rpx 0;
+
+		.comment-title {
+			display: flex;
+			justify-content: space-between;
+			align-items: center;
+			font-size: 26rpx;
+			color: #333;
+			padding: 18rpx 20rpx 0 20rpx;
+
+			.comment-more {
+				color: #999;
+				font-size: 22rpx;
+				display: flex;
+				align-items: center;
+
+				image {
+					width: 20rpx;
+					height: 20rpx;
+					margin-left: 4rpx;
+				}
+			}
+		}
+
+		.comment-content {
+			padding: 0 20rpx;
+
+			.comment-item {
+				display: flex;
+				//align-items: flex-start;
+				align-items: center;
+				padding: 18rpx 0 0 0;
+				border-bottom: 1rpx solid #f5f5f5;
+
+				&:last-child {
+					border-bottom: none;
+				}
+
+				.comment-avatar {
+					width: 48rpx;
+					height: 48rpx;
+					border-radius: 50%;
+					margin-right: 16rpx;
+					flex-shrink: 0;
+				}
+
+				.comment-item-main {
+					flex: 1;
+					display: flex;
+					flex-direction: column;
+
+					.comment-item-content {
+						color: #1f1f1f;
+						font-size: 24rpx;
+						line-height: 1.7;
+						margin-bottom: 8rpx;
+						display: -webkit-box;
+						-webkit-line-clamp: 2;
+						-webkit-box-orient: vertical;
+						overflow: hidden;
+						text-overflow: ellipsis;
+						word-break: break-all;
+					}
+				}
+
+				.comment-item-like {
+					display: flex;
+					align-items: center;
+					margin-left: 36rpx;
+
+					.like-icon {
+						width: 28rpx;
+						height: 28rpx;
+						margin-right: 4rpx;
+					}
+
+					.like-num {
+						font-size: 22rpx;
+						color: #888;
+					}
+				}
+			}
+		}
+	}
+
+	.bottom-bar-reserveASeat {
+		width: 100%;
+		height: calc(12rpx + 88rpx + var(--window-bottom) + 30rpx);
+	}
+
+	.bottom-bar {
+		position: fixed;
+		left: 0;
+		right: 0;
+		bottom: 0;
+		z-index: 999;
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		background: #fff;
+		padding: 14rpx 40rpx;
+		padding-bottom: calc(14rpx + var(--window-bottom));
+		box-sizing: border-box;
+
+		.bottom-bar-left {
+			display: flex;
+			align-items: center;
+			gap: 32rpx;
+
+			.bar-btn {
+				display: flex;
+				flex-direction: column;
+				align-items: center;
+				justify-content: center;
+				width: 80rpx;
+				height: 80rpx;
+				border-radius: 12rpx;
+
+				.bar-icon {
+					width: 48rpx;
+					height: 48rpx;
+					margin-bottom: 4rpx;
+				}
+
+				.bar-text {
+					font-size: 20rpx;
+					color: #1f1f1f;
+					font-family: "PingFang SC";
+				}
+			}
+		}
+
+
+		.buy-btn {
+			width: 588rpx;
+			height: 88rpx;
+			background: #1f1f1f;
+			color: #ACF934;
+			font-size: 32rpx;
+			border-radius: 80rpx;
+			border: none;
+			font-weight: bold;
+			text-align: center;
+			line-height: 80rpx;
+
+			&.followTheAuthor1 {
+				color: #acf934;
+				background: #1f1f1f;
+			}
+
+			&.followTheAuthor0 {
+				border: 2rpx solid #1f1f1f;
+				background: #fff;
+				color: #1f1f1f;
+			}
+		}
+
+	}
+}
+
+.back-top {
+	position: fixed;
+	bottom: calc(126rpx + var(--window-bottom));
+	right: 16rpx;
+	width: 82rpx;
+	height: 82rpx;
+}
+
+.initiator-bar {
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	background: #fff;
+	border-radius: 10rpx;
+	padding: 18rpx 24rpx 18rpx 18rpx;
+	margin: 0;
+
+	.initiator-avatar {
+		width: 64rpx;
+		height: 64rpx;
+		border-radius: 50%;
+		margin-right: 18rpx;
+		flex-shrink: 0;
+	}
+
+	.initiator-info {
+		display: flex;
+		align-items: center;
+		flex: 1;
+		min-width: 0;
+	}
+
+	.initiator-name {
+		font-size: 30rpx;
+		color: #222;
+		font-weight: bold;
+		margin-right: 12rpx;
+		max-width: 260rpx;
+		overflow: hidden;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+	}
+
+	.initiator-tag {
+		background: #1a1a1a;
+		color: #b6ff4b;
+		font-size: 20rpx;
+		border-radius: 8rpx;
+		padding: 2rpx 12rpx;
+		margin-left: 2rpx;
+	}
+
+	.initiator-service-btn {
+		display: flex;
+		align-items: center;
+		background: #1a1a1a;
+		color: #b6ff4b;
+		font-size: 28rpx;
+		border-radius: 128rpx;
+		padding: 0 24rpx 0 12rpx;
+		height: 56rpx;
+		margin-left: 18rpx;
+		font-weight: bold;
+	}
+
+	.service-icon {
+		width: 32rpx;
+		height: 32rpx;
+		margin-right: 8rpx;
+	}
+}
+
+.scale-tap {
+	transition: transform 0.15s;
+}
+
+.scale-tap:active {
+	transform: scale(0.92);
+}
+
+.risk-section {
+	background: #fff;
+	border-radius: 12rpx;
+	margin: 24rpx 0 0 0;
+	padding: 0 0 18rpx 0;
+	position: relative;
+	overflow: hidden;
+
+	.risk-row {
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		padding: 18rpx 24rpx 0 0rpx;
+		font-size: 28rpx;
+		color: #1f1f1f;
+		background: #fff;
+
+		&.risk-row-border {
+			border-top: 1rpx solid #f2f2f2;
+			margin-top: 18rpx;
+			padding-top: 18rpx;
+		}
+	}
+
+	.risk-title {
+		font-size: 28rpx;
+		color: #1f1f1f;
+		font-family: 'PingFang SC-Bold';
+		font-weight: 400;
+
+	}
+
+	.risk-more {
+		color: #1f1f1f;
+		font-size: 24rpx;
+		display: flex;
+		align-items: center;
+		font-weight: 400;
+		font-family: 'PingFang SC-Bold';
+
+		.risk-more-icon {
+			width: 24rpx;
+			height: 24rpx;
+			margin-left: 4rpx;
+			margin-top: 4rpx;
+		}
+	}
+
+	.risk-desc {
+		font-size: 24rpx;
+		color: #999;
+		padding: 8rpx 24rpx 0 0;
+		font-family: 'PingFang SC-Regular';
+	}
+
+	.risk-content {
+		font-size: 24rpx;
+		color: #999;
+		padding: 12rpx 24rpx 0 0;
+		font-family: 'PingFang SC-Regular';
+		line-height: 1.7;
+
+		>view {
+			margin-bottom: 6rpx;
+		}
+	}
+}
+
+.followTheAuthor {
+	padding: 6rpx 20rpx 8rpx 15rpx;
+	border-radius: 26rpx;
+	margin-right: 16rpx;
+	transition: all 0.6s;
+	border: 2rpx solid transparent;
+
+	&.followTheAuthor1 {
+		color: #acf934;
+		background: #1f1f1f;
+	}
+
+	&.followTheAuthor0 {
+		border: 2rpx solid #1f1f1f;
+		background: #fff;
+	}
+}
+</style>

+ 29 - 33
pages/crowdFunding/favorites.vue

@@ -1,42 +1,31 @@
 <template>
   <view class="favorites-page">
+    
     <!-- 列表 -->
-    <view class="fav-list">
+    <view class="fav-list"> 
+      <view class="fav-card" v-for="(item, idx) in list" :key="idx">
+        <image  @click="goPage('/pages/crowdFunding/crowdfundingDetails?id='+ item.id)" :src="item.main_image" class="fav-img"></image>
 
-   <uv-swipe-action>
-        <uv-swipe-action-item v-if="show1" :options="[{
-          text: '删除',
-          style: {
-            backgroundColor: '#f56c6c'
-          }
-        }]" @click="handleOption('cancelCollection', idx)">  
- 
-</uv-swipe-action-item> 
-</uv-swipe-action>
-
-          <view class="fav-card" v-for="(item, idx) in list" :key="idx">
-            <image :src="item.main_image" class="fav-img"></image>
-
-            <view class="fav-content">
-              <view class="fav-header">
-                <image :src="item.creator_avatar" class="avatar"></image>
-                <text class="nickname">{{ item.creator_username }}</text>
-                <text class="tag">发起人</text>
-                <view style="position: relative;left: 0;top: 0;">
-                  <image src="/static/crowdFunding/more.png" class="more-img" @click="toggleDropdown(idx)"></image>
-                  <view class="dropdown-menu" v-if="currentDropdownIndex === idx">
-                    <view class="dropdown-item" @tap="handleOption('cancelCollection', idx)">取消收藏</view>
-                  </view>
-                </view>
-              </view>
-              <view class="fav-title two-omit">{{ item.title }}</view>
-              <view class="fav-bottom">
-                <text class="amount">已筹 ¥{{ item.current_amount }}</text>
-                <!-- <text class="favorite-time">收藏于{{ item.favorite_time }}</text> -->
+        <view class="fav-content">
+          <view class="fav-header">
+            <image :src="item.creator_avatar" class="avatar"></image>
+            <text class="nickname"  @click="goPage('/pages/crowdFunding/crowdfundingDetails?id='+ item.id)">{{ item.creator_username }}</text>
+            <text class="tag"  @click="goPage('/pages/crowdFunding/crowdfundingDetails?id='+ item.id)">发起人</text>
+            <view style="position: relative;left: 0;top: 0;">
+              <image src="/static/crowdFunding/more.png" class="more-img" @click="toggleDropdown(idx)"></image>
+              <view class="dropdown-menu" v-if="currentDropdownIndex === idx">
+                <view class="dropdown-item" @tap="handleOption('cancelCollection', idx)">取消收藏</view>
               </view>
             </view>
           </view>
-        
+          <view class="fav-title two-omit"  @click="goPage('/pages/crowdFunding/crowdfundingDetails?id='+ item.id)">{{ item.title }}</view>
+          <view class="fav-bottom">
+            <text class="amount">已筹 ¥{{ item.current_amount }}</text>
+            <!-- <text class="favorite-time">收藏于{{ item.favorite_time }}</text> -->
+          </view>
+        </view>
+      </view>
+
     </view>
     <view v-if="!isLoading && list.length === 0" class="no-data">
       <text>暂无数据</text>
@@ -118,6 +107,13 @@ export default {
       this.currentDropdownIndex = this.currentDropdownIndex === idx ? null : idx;
 
     },
+	goPage(url) {
+    console.log(url,888);
+    
+		uni.navigateTo({
+			url,
+		});
+	},
     // 处理下拉菜单选项点击
     handleOption(type, idx) {
       this.currentDropdownIndex = null;
@@ -293,7 +289,7 @@ export default {
         right: 0;
         bottom: 0;
         height: 1rpx;
-        background-color: #eeeeee; 
+        background-color: #eeeeee;
       }
 
       &:active {

+ 1 - 1
pages/crowdFunding/orderDetail.vue

@@ -254,7 +254,7 @@ export default {
         success: (res) => {
           console.log(res.data, "订单操作结果");
           if (res.data && res.data.success == 'yes') {
-            uni.showToast({ title: res.data.str, icon: 'success' });
+            uni.showToast({ title: res.data.str, icon: 'none' });
             this.getOrderDetail(this.order.orderNo);
           } else {
             uni.showToast({ title: res.data.message || '操作失败', icon: 'none' });

+ 4 - 1
pages/crowdFunding/orderList.vue

@@ -147,7 +147,10 @@ export default {
     };
   },
   onLoad() {
-    this.getdataList();
+    // this.getdataList();
+  },
+  onShow() {
+  this.getdataList();
   },
   computed: {
     filteredOrders() {

+ 4 - 3
pages/crowdFunding/projectUpdateDetails.vue

@@ -41,9 +41,10 @@ export default {
       datails: {},
       author: {},
       showShare: false,
-      shareTitle: '【Woh】灯塔 塔罗牌 治愈风泛传特系',
-      shareDesc: '快来支持这个有趣的众筹项目吧!',
-      shareImg: require('@/static/crowdFunding/top-img.png'),
+      shareTitle: '',
+      shareDesc: '',
+      shareImg: '',
+      shareLink:"",
     };
   },
   computed: {

+ 8 - 2
pages/index/index.vue

@@ -127,7 +127,7 @@
 									<swiper-item v-for="(page, pageIndex) in topicPages" :key="pageIndex">
 										<view class="hot-topics-list">
 											<view v-for="(topic, index) in page" :key="index" class="topic-item"
-												@click="goToArticleDetail(topic.id)">
+												@click="goToArticleDetail(topic.id,topic)">
 												<view class="hot-topics-left">
 													<image v-if="pageIndex * 4 + index == 0"
 														src="@/static/icon/icon-first.png"
@@ -263,6 +263,10 @@ export default {
 			},
 			windowHeight: uni.getWindowInfo().windowHeight,
 			bannerList: [
+			{
+					image: "../../static/home/home-swper3.png",
+					url: "/pages/crowdFunding/crowdFunding",
+				},
 				{
 					image: "../../static/home/home-swper.png",
 					url: "/pages/makedetail/makeImgDetail",
@@ -723,10 +727,11 @@ export default {
 				desc: item.desc || "",
 				userID: item.userID || 0,
 				backgroundColor: "#f6f6f6",
+				type: item.type || "",
 			};
 		},
 
-		goToArticleDetail(id) {
+		goToArticleDetail(id,item) {
 			if (!id) {
 				uni.showToast({
 					title: "文章ID不存在",
@@ -734,6 +739,7 @@ export default {
 				});
 				return;
 			}
+			
 			// uni.$emit("check_login", () => {
 			uni.navigateTo({
 				url: "/pages/index/articleDetail?id=" + id,

+ 298 - 0
pages/make/index copy.scss

@@ -0,0 +1,298 @@
+page {
+
+}
+.container {
+  min-height: 100vh;
+  background: linear-gradient(180deg, #f0f7ff 0%, #fff1f9 100%);
+  padding: 0; 
+   background: url("../../static/make/wd_bg_bianjiziliao.png") center top/100% auto
+    no-repeat,#f2f6f2;
+}
+
+.header-box {
+  padding: calc(44rpx + var(--status-bar-height)) 20rpx 12rpx 36rpx;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+
+
+  .title {
+    font-size: 40rpx;
+    font-weight: bold;
+    color: #333;
+    font-family: "CustomFont" !important;
+  }
+
+  .currency-area {
+    display: flex;
+    gap: 20rpx;
+	align-items: center;
+  // min-width: 400rpx;
+    // width: 260rpx;
+    .coin-box,
+    .gold-box {
+      display: flex;
+      align-items: center;
+      background: #fff;
+      border-radius: 30rpx;
+      // box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
+      padding: 6rpx 12rpx 6rpx 8rpx;
+      transition: transform 0.2s;
+      &:active {
+        transform: scale(0.98);
+      }
+      text{
+        display: inline-block;
+        padding-left: 4rpx;
+        line-height: 0;
+      }
+      image {
+        width: 40rpx;
+        height: 40rpx;
+        // margin-right: 12rpx;
+      }
+    }
+  }
+}
+
+// 添加点击动画的混入
+@mixin click-animation {
+  transition: transform 0.2s ease;
+
+  &:active {
+    transform: scale(0.95);
+  }
+}
+
+.card-grid {
+  padding-left: 20rpx;
+  padding-right: 20rpx;
+  display: grid;
+  grid-template-columns: repeat(2, 1fr);
+  grid-template-areas:
+    "character music"
+    "character cube";
+  gap: 20rpx;
+  margin-bottom: 32rpx;
+
+  .card {
+    @include click-animation; // 添加点击动画
+    border-radius: 20rpx;
+    position: relative;
+    overflow: hidden;
+
+    &.character {
+      position: relative;
+      left: 0;
+      top: 0;
+      grid-area: character;
+      //   background: linear-gradient(to right, #59c2ff, #1b84ff);
+      background: url("../../static/make/cz_btn_chuangjue.png") center/100% auto
+        no-repeat;
+      height: 268rpx;
+      width: 346rpx;
+      padding: 34rpx 0 0 28rpx !important;
+      .text-area {
+        display: flex;
+        flex-direction: column;
+        .card-title {
+          margin-bottom: 4rpx;
+        }
+        .card-desc {
+          width: 150rpx;
+          font-weight: 400;
+          font-size: 20rpx;
+          color: rgba(255, 255, 255, 0.8);
+        }
+      }
+      .btn-box {
+        font-weight: 600;
+        font-size: 22rpx;
+        color: #1966ed;
+        background: #ffffff;
+        border-radius: 24rpx;
+       width: 120rpx;
+       height: 44rpx;
+        display: inline-flex;
+        align-items: center;
+        justify-content: center;
+        position: absolute;
+        left: 0rpx;
+        bottom: 32rpx;
+      }
+    }
+
+    &.music {
+      grid-area: music;
+      //   background: linear-gradient(to right, #ff88d1, #ff3b9a);
+      background: url("../../static/make/cz_btn_lingganxiege.png") center/100%
+        auto no-repeat;
+      height: 124rpx;
+    }
+
+    &.cube {
+      grid-area: cube;
+      //   background: linear-gradient(to right, #9d8bff, #6e54ec);
+      background: url("../../static/make/cz_btn_zhihuimofang.png") center/100%
+        auto no-repeat;
+      height: 124rpx;
+    }
+
+    &.gray {
+      background: #4b5563;
+      height: 160rpx;
+      padding: 30rpx;
+    }
+
+    &.card-large {
+      padding: 40rpx;
+    }
+
+    &.card-medium {
+      padding:0 30rpx; 
+    }
+
+    .card-content {
+      height: 100%;
+      position: relative;  
+      .text-area {
+        z-index: 1;
+        width: 100%; 
+        height: 100%;
+        display: flex;
+        align-items: center;
+        >view{
+          display: flex;
+          flex-direction: column;
+        }
+      }
+
+      .card-title {
+        font-size: 32rpx;
+        color: #fff;
+        font-weight: bold;
+        margin-bottom: 8rpx;
+      }
+
+      .card-desc {
+        font-size: 22rpx;
+        color: rgba(255, 255, 255, 0.9);
+      }
+    }
+
+    // AI创角卡片的特殊样式
+    &.blue .card-content {
+      .card-image {
+        position: absolute;
+        right: -20rpx;
+        bottom: -40rpx;
+        width: 280rpx;
+        height: 280rpx;
+        z-index: 0;
+      }
+
+      .star-icon {
+        position: absolute;
+        width: 40rpx;
+        height: 40rpx;
+        &.star-1 {
+          top: 20rpx;
+          right: 100rpx;
+        }
+        &.star-2 {
+          top: 80rpx;
+          right: 180rpx;
+        }
+      }
+    }
+
+    // AI灵感写歌卡片的特殊样式
+    &.pink .card-content {
+      .card-image {
+        position: absolute;
+        right: -10rpx;
+        bottom: -20rpx;
+        width: 160rpx;
+        height: 160rpx;
+        z-index: 0;
+      }
+    }
+
+    // 萌萌智绘魔方卡片的特殊样式
+    &.purple .card-content {
+      .card-image {
+        position: absolute;
+        right: -10rpx;
+        bottom: -20rpx;
+        width: 160rpx;
+        height: 160rpx;
+        z-index: 0;
+      }
+    }
+  }
+}
+.guide-title {
+  font-size: 16px;
+  color: #1f1f1f;
+  font-family: "PingFang SC-Bold";
+  padding-left: 36rpx;
+  padding-bottom: 12rpx;
+}
+.tutorial {
+  padding: 0 20rpx;
+
+  .tutorial-block {
+    @include click-animation; // 添加点击动画
+    width: 100%;
+    min-height: 212rpx;
+    background: #fff;
+    border-radius: 20rpx;
+    padding: 30rpx;
+    margin-bottom: 20rpx;
+    display: flex;
+    flex-direction: column;
+    &:nth-child(1) {
+      background: url("../../static/make/cz_bg_jiaocheng01.png") center/100%
+        auto no-repeat;
+    }
+    &:nth-child(2) {
+      background: url("../../static/make/cz_bg_jiaocheng02.png") center/100%
+        auto no-repeat;
+    }
+    &:nth-child(3) {
+      background: url("../../static/make/cz_bg_jiaocheng03.png") center/100%
+        auto no-repeat;
+    }
+    .tutorial-btn {
+      image {
+        width: 24rpx;
+        height: 24rpx;
+      }
+      display: inline-flex;
+      align-items: center;
+      justify-content: space-between;
+      font-family: "PingFang SC-Bold";
+      font-weight: 400;
+      font-size: 24rpx;
+      color: #ffffff;
+      background: #1f1f1f;
+      padding: 0 6rpx;
+      border-radius: 8rpx;
+      line-height: 1.5;
+    }
+    .tutorial-title {
+      font-weight: 200;
+      font-size: 34rpx;
+      color: #1f1f1f;
+		margin-top: 10rpx;
+		margin-bottom: 10rpx;
+      font-family: "PingFang SC-Bold";
+    }
+
+    .tutorial-content {
+      font-weight: 400;
+      font-size: 11px;
+      color: #1f1f1f;
+    }
+  }
+}

+ 226 - 0
pages/make/index copy.vue

@@ -0,0 +1,226 @@
+<template>
+	<view class="container">
+
+		<!-- 顶部导航栏 -->
+		<view class="header-box">
+			<text class="title">星球造物</text>
+			<view class="currency-area">
+				<view class="coin-box" @click="isRecharge ? goPage('/pages/vip/M_purchase') : ''">
+					<image src="/static/icon/coin_m.png" mode="aspectFit"></image>
+					<text>{{ myinfo.num_gmm | formatNumberToK }}</text>
+					<image class="money-add" v-if="isRecharge" src="/static/icon/coin_add.png" mode="aspectFit"></image>
+				</view>
+				<view class="gold-box" @click="isRecharge ? goPage('/pages/my/job?type=recharge') : ''">
+					<image src="/static/icon/coin_cd.png" mode="aspectFit"></image>
+					<text>{{ myinfo.num_gmd | formatNumberToK }}</text>
+					<image class="money-add" v-if="isRecharge" src="/static/icon/coin_add.png" mode="aspectFit"></image>
+				</view>
+<!-- 
+				<image style="width: 64rpx ; height: 64rpx;" src="/static/icon/renwu.png" mode="aspectFit"
+					@click="goPage('/pages/my/job')"></image> -->
+
+			</view>
+		</view>
+
+		<!-- 功能卡片区域 -->
+		<view class="card-grid">
+			<!-- AI创角卡片 -->
+			<view class="card card-large character" @click="handleCardClick('character')">
+				<view class="card-content">
+					<view class="text-area" style="align-items: flex-start;">
+						<view>
+							<text class="card-title">AI创角</text>
+							<text class="card-desc">生成独一无二的星球成员</text>
+						</view>
+					</view>
+					<view class="btn-box">立即查看</view>
+					<!-- <image src="/static/icon/star.png" class="star-icon star-1" mode="aspectFit"></image>
+					<image src="/static/icon/star.png" class="star-icon star-2" mode="aspectFit"></image>
+					<image src="/static/make/character.png" class="card-image" mode="aspectFit"></image> -->
+				</view>
+			</view>
+
+			<!-- AI灵感写歌卡片 -->
+			<view class="card card-medium music" @click="handleCardClick('music')">
+				<view class="card-content">
+					<view class="text-area"   >
+						<view>
+							<text class="card-title">AI灵感写歌</text>
+							<text class="card-desc">快速生成专属原创曲目</text>
+						</view>
+
+					</view>
+					<image src="/static/make/planet.png" class="card-image" mode="aspectFit"></image>
+				</view>
+			</view>
+
+			<!-- 萌萌智绘魔方卡片 -->
+			<view class="card card-medium cube" @click="handleCardClick('cube')">
+				<view class="card-content">
+					<view class="text-area"  >
+						<view>
+							<text class="card-title">萌萌智绘魔方</text>
+							<text class="card-desc">AI随机生成萌玩原型</text>
+						</view>
+					</view>
+					<image src="/static/make/book.png" class="card-image" mode="aspectFit"></image>
+				</view>
+			</view>
+
+		</view>
+		<view class="guide-title"> 引导教程</view>
+		<!-- 引导教程区域 -->
+		<view class="tutorial">
+			<view class="tutorial-block " @click="goWeb(item.url, item.subheading)" v-for="(item, index) in tutorial"
+				:key="index">
+				<text class="tutorial-btn-box">
+					<view class="tutorial-btn">
+						<image src="../../static/make/cz_icon_guanfangjiaocheng.png"></image>
+						<text>{{ item.title }}</text>
+					</view>
+				</text>
+				<text class="tutorial-title"> {{ item.subheading }}</text>
+				<view class="tutorial-content">{{ item.content }}</view>
+			</view>
+		</view>
+		<tabbar-view :tabbars="tabbars" :currentIndex="1" ref="tabbar"></tabbar-view>
+		<!-- 新手引导组件 -->
+		<novice-guidance :step="step"></novice-guidance>
+	</view>
+</template>
+
+<script>
+import tabbarView from "@/components/tabbar/tabbar.vue";
+import tabbar from "@/mixins/tabbar";
+import { mapState } from 'vuex'
+export default {
+	components: {
+		tabbarView,
+	},
+	mixins: [tabbar],
+	data() {
+		return {
+			myinfo: {},
+			windowHeight: uni.getWindowInfo().windowHeight,
+			tabCurrent: 0,
+			step: {
+				name: "make",
+				guideList: [
+					{
+						el: ".currency-area",
+						tips: "积分可在这里查看,每日签到可获得积分!",
+						next: "知道了",
+					},
+					{
+						el: ".character",
+						tips: "创建星灵,入驻星球",
+						next: "知道了",
+						tipesStyle: "left: 40px;"
+					},
+					{
+						el: ".music",
+						tips: "输入灵感,生成歌曲",
+						next: "知道了",
+					},
+					{
+						el: ".cube",
+						tips: "输入关键词,生成萌玩",
+						next: "完成",
+					}]
+			},
+			tutorial: [
+				{ title: "官方教程", url: "https://docs.qingque.cn/d/home/eZQBj5luSHVkaqpJmL5PTuFfZ?identityId=2HSXOrUAEOx", subheading: "萌萌智绘魔方", content: "教你如何创作内容,激发创作灵感!" },
+				{ title: "官方教程", url: "https://docs.qingque.cn/d/home/eZQDGgIXzR08ssYlwoy2tjiNA?identityId=2HSXOrUAEOx", subheading: "AI灵感写歌", content: "使用AI超能力释放你的无限创造力!" },
+				{ title: "官方教程", url: "https://docs.qingque.cn/d/home/eZQC3yyQj9gK-KnVUZOT6vYmn?identityId=2HSXOrUAEOx", subheading: "星球造物,AI创角", content: "使用自然语言,创建独属于你的智能体" },
+			]
+		}
+	},
+	computed: {
+		...mapState('switchingModule', ['isRecharge', 'isGuiding'])
+	},
+	onLoad() {
+
+	},
+	onShow() {
+		this.getMyInfo();
+	},
+
+	// 下拉刷新数据
+	methods: {
+		goWeb(url, title) {
+			uni.navigateTo({
+				url: `/pages/webview/index?url=${encodeURIComponent(url)}&title=${encodeURIComponent(title)}`
+			})
+		},
+		getMyInfo() {
+			uni.request({
+				url: this.$apiHost + '/My/getnum',
+				method: 'GET',
+				header: {
+					'content-type': 'application/json',
+					'sign': getApp().globalData.headerSign
+				},
+				data: {
+					uuid: getApp().globalData.uuid
+				},
+				success: (res) => {
+					console.log("获取用户信息:", res.data);
+					this.myinfo = res.data
+				}
+			})
+
+		},
+		tabChange(index) {
+			this.tabCurrent = index;
+		},
+		handleCardClick(type) {
+			console.log('Card clicked:', type);
+			uni.$emit('check_login', () => {
+				if (type == 'cube') {
+					uni.navigateTo({
+						// url: '/pages/makedetail/makeImgDetail'
+						url: '/pages/makedetail/intelligentLifeChart'
+						// url: '/pages/my/dome/dome'
+					})
+				} else if (type == 'music') {
+					uni.navigateTo({
+						//url: '/pages/makedetail/makeMusicDetail'
+						url: '/pages/makedetail/intelligentMusicProduction'
+					})
+				} else if (type == 'character') {
+					uni.navigateTo({
+						url: '/pages/my/myStar'
+					})
+				} else {
+					uni.showToast({
+						title: '待开放'
+					})
+				}
+			})
+		},
+		handleTutorialClick(index) {
+			console.log('Tutorial clicked:', index + 1);
+		},
+		goPage(page) {
+			console.log('page: ', page);
+			if (page.includes('/pages/my/job') || page.includes('vip')) {
+				uni.$emit("check_login", () => {
+					uni.navigateTo({
+						url: page,
+					});
+				})
+			} else {
+				uni.navigateTo({
+					url: page,
+				});
+			}
+
+
+		},
+	}
+}
+</script>
+
+<style lang="scss">
+@import './index.scss';
+</style>

+ 37 - 227
pages/make/index.scss

@@ -1,12 +1,12 @@
 page {
-
 }
 .container {
   min-height: 100vh;
   background: linear-gradient(180deg, #f0f7ff 0%, #fff1f9 100%);
-  padding: 0; 
-   background: url("../../static/make/wd_bg_bianjiziliao.png") center top/100% auto
-    no-repeat,#f2f6f2;
+  padding: 0;
+  background: url("../../static/make/make_bg.png") center top/100% auto
+      no-repeat,
+    #f2f6f2;
 }
 
 .header-box {
@@ -15,7 +15,6 @@ page {
   align-items: center;
   justify-content: space-between;
 
-
   .title {
     font-size: 40rpx;
     font-weight: bold;
@@ -26,8 +25,8 @@ page {
   .currency-area {
     display: flex;
     gap: 20rpx;
-	align-items: center;
-  // min-width: 400rpx;
+    align-items: center;
+    // min-width: 400rpx;
     // width: 260rpx;
     .coin-box,
     .gold-box {
@@ -41,7 +40,7 @@ page {
       &:active {
         transform: scale(0.98);
       }
-      text{
+      text {
         display: inline-block;
         padding-left: 4rpx;
         line-height: 0;
@@ -64,173 +63,7 @@ page {
   }
 }
 
-.card-grid {
-  padding-left: 20rpx;
-  padding-right: 20rpx;
-  display: grid;
-  grid-template-columns: repeat(2, 1fr);
-  grid-template-areas:
-    "character music"
-    "character cube";
-  gap: 20rpx;
-  margin-bottom: 32rpx;
-
-  .card {
-    @include click-animation; // 添加点击动画
-    border-radius: 20rpx;
-    position: relative;
-    overflow: hidden;
-
-    &.character {
-      position: relative;
-      left: 0;
-      top: 0;
-      grid-area: character;
-      //   background: linear-gradient(to right, #59c2ff, #1b84ff);
-      background: url("../../static/make/cz_btn_chuangjue.png") center/100% auto
-        no-repeat;
-      height: 268rpx;
-      width: 346rpx;
-      padding: 34rpx 0 0 28rpx !important;
-      .text-area {
-        display: flex;
-        flex-direction: column;
-        .card-title {
-          margin-bottom: 4rpx;
-        }
-        .card-desc {
-          width: 150rpx;
-          font-weight: 400;
-          font-size: 20rpx;
-          color: rgba(255, 255, 255, 0.8);
-        }
-      }
-      .btn-box {
-        font-weight: 600;
-        font-size: 22rpx;
-        color: #1966ed;
-        background: #ffffff;
-        border-radius: 24rpx;
-       width: 120rpx;
-       height: 44rpx;
-        display: inline-flex;
-        align-items: center;
-        justify-content: center;
-        position: absolute;
-        left: 0rpx;
-        bottom: 32rpx;
-      }
-    }
-
-    &.music {
-      grid-area: music;
-      //   background: linear-gradient(to right, #ff88d1, #ff3b9a);
-      background: url("../../static/make/cz_btn_lingganxiege.png") center/100%
-        auto no-repeat;
-      height: 124rpx;
-    }
-
-    &.cube {
-      grid-area: cube;
-      //   background: linear-gradient(to right, #9d8bff, #6e54ec);
-      background: url("../../static/make/cz_btn_zhihuimofang.png") center/100%
-        auto no-repeat;
-      height: 124rpx;
-    }
-
-    &.gray {
-      background: #4b5563;
-      height: 160rpx;
-      padding: 30rpx;
-    }
-
-    &.card-large {
-      padding: 40rpx;
-    }
-
-    &.card-medium {
-      padding:0 30rpx; 
-    }
-
-    .card-content {
-      height: 100%;
-      position: relative;  
-      .text-area {
-        z-index: 1;
-        width: 100%; 
-        height: 100%;
-        display: flex;
-        align-items: center;
-        >view{
-          display: flex;
-          flex-direction: column;
-        }
-      }
-
-      .card-title {
-        font-size: 32rpx;
-        color: #fff;
-        font-weight: bold;
-        margin-bottom: 8rpx;
-      }
-
-      .card-desc {
-        font-size: 22rpx;
-        color: rgba(255, 255, 255, 0.9);
-      }
-    }
-
-    // AI创角卡片的特殊样式
-    &.blue .card-content {
-      .card-image {
-        position: absolute;
-        right: -20rpx;
-        bottom: -40rpx;
-        width: 280rpx;
-        height: 280rpx;
-        z-index: 0;
-      }
-
-      .star-icon {
-        position: absolute;
-        width: 40rpx;
-        height: 40rpx;
-        &.star-1 {
-          top: 20rpx;
-          right: 100rpx;
-        }
-        &.star-2 {
-          top: 80rpx;
-          right: 180rpx;
-        }
-      }
-    }
-
-    // AI灵感写歌卡片的特殊样式
-    &.pink .card-content {
-      .card-image {
-        position: absolute;
-        right: -10rpx;
-        bottom: -20rpx;
-        width: 160rpx;
-        height: 160rpx;
-        z-index: 0;
-      }
-    }
-
-    // 萌萌智绘魔方卡片的特殊样式
-    &.purple .card-content {
-      .card-image {
-        position: absolute;
-        right: -10rpx;
-        bottom: -20rpx;
-        width: 160rpx;
-        height: 160rpx;
-        z-index: 0;
-      }
-    }
-  }
-}
+ 
 .guide-title {
   font-size: 16px;
   color: #1f1f1f;
@@ -238,61 +71,38 @@ page {
   padding-left: 36rpx;
   padding-bottom: 12rpx;
 }
-.tutorial {
+ .guide-content{
   padding: 0 20rpx;
-
-  .tutorial-block {
-    @include click-animation; // 添加点击动画
+  display: grid;
+  grid-template-columns: 1fr 1fr;
+  gap: 20rpx;
+  padding-bottom: 200rpx;
+  image{
     width: 100%;
-    min-height: 212rpx;
-    background: #fff;
-    border-radius: 20rpx;
-    padding: 30rpx;
-    margin-bottom: 20rpx;
-    display: flex;
-    flex-direction: column;
-    &:nth-child(1) {
-      background: url("../../static/make/cz_bg_jiaocheng01.png") center/100%
-        auto no-repeat;
-    }
-    &:nth-child(2) {
-      background: url("../../static/make/cz_bg_jiaocheng02.png") center/100%
-        auto no-repeat;
-    }
-    &:nth-child(3) {
-      background: url("../../static/make/cz_bg_jiaocheng03.png") center/100%
-        auto no-repeat;
-    }
-    .tutorial-btn {
-      image {
-        width: 24rpx;
-        height: 24rpx;
-      }
-      display: inline-flex;
-      align-items: center;
-      justify-content: space-between;
-      font-family: "PingFang SC-Bold";
-      font-weight: 400;
-      font-size: 24rpx;
-      color: #ffffff;
-      background: #1f1f1f;
-      padding: 0 6rpx;
-      border-radius: 8rpx;
-      line-height: 1.5;
-    }
-    .tutorial-title {
-      font-weight: 200;
-      font-size: 34rpx;
-      color: #1f1f1f;
-		margin-top: 10rpx;
-		margin-bottom: 10rpx;
-      font-family: "PingFang SC-Bold";
-    }
+    height: 100%;
+  }
+ }
 
-    .tutorial-content {
-      font-weight: 400;
-      font-size: 11px;
-      color: #1f1f1f;
+.major-function {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  height: 336rpx;
+  width: 100vw;
+  box-sizing: border-box;
+  padding: 0 20rpx;
+  .major-function-left,
+  .major-function-right {
+    width: 346rpx;
+    height: 336rp;
+  }
+  .major-function-right{
+    padding-top: 10rpx;
+    box-sizing: border-box;
+    image{
+      width: 100%;
+      margin-top: 10rpx;
     }
+
   }
 }

+ 37 - 86
pages/make/index.vue

@@ -5,84 +5,33 @@
 		<view class="header-box">
 			<text class="title">星球造物</text>
 			<view class="currency-area">
-				<view class="coin-box" @click="isRecharge ? goPage('/pages/vip/M_purchase') : ''">
-					<image src="/static/icon/coin_m.png" mode="aspectFit"></image>
-					<text>{{ myinfo.num_gmm | formatNumberToK }}</text>
-					<image class="money-add" v-if="isRecharge" src="/static/icon/coin_add.png" mode="aspectFit"></image>
-				</view>
-				<view class="gold-box" @click="isRecharge ? goPage('/pages/my/job?type=recharge') : ''">
-					<image src="/static/icon/coin_cd.png" mode="aspectFit"></image>
-					<text>{{ myinfo.num_gmd | formatNumberToK }}</text>
-					<image class="money-add" v-if="isRecharge" src="/static/icon/coin_add.png" mode="aspectFit"></image>
-				</view>
-<!-- 
-				<image style="width: 64rpx ; height: 64rpx;" src="/static/icon/renwu.png" mode="aspectFit"
-					@click="goPage('/pages/my/job')"></image> -->
-
 			</view>
 		</view>
-
 		<!-- 功能卡片区域 -->
-		<view class="card-grid">
-			<!-- AI创角卡片 -->
-			<view class="card card-large character" @click="handleCardClick('character')">
-				<view class="card-content">
-					<view class="text-area" style="align-items: flex-start;">
-						<view>
-							<text class="card-title">AI创角</text>
-							<text class="card-desc">生成独一无二的星球成员</text>
-						</view>
-					</view>
-					<view class="btn-box">立即查看</view>
-					<!-- <image src="/static/icon/star.png" class="star-icon star-1" mode="aspectFit"></image>
-					<image src="/static/icon/star.png" class="star-icon star-2" mode="aspectFit"></image>
-					<image src="/static/make/character.png" class="card-image" mode="aspectFit"></image> -->
-				</view>
+		<view class="major-function">
+			<view class="major-function-left" @click="handleCardClick('character')">
+				<image src="../../static/make/chuangjiao.png" class="scale-tap card-image" mode="widthFix"></image>
+			</view>
+			<view class="major-function-right">
+				<image src="../../static/make/songwriting.png" @click="handleCardClick('music')"
+					class="scale-tap card-image" mode="widthFix"></image>
+				<image src="../../static/make/shengTu.png" @click="handleCardClick('cube')" class="scale-tap card-image"
+					mode="widthFix"></image>
 			</view>
+		</view>
+
 
-			<!-- AI灵感写歌卡片 -->
-			<view class="card card-medium music" @click="handleCardClick('music')">
-				<view class="card-content">
-					<view class="text-area"   >
-						<view>
-							<text class="card-title">AI灵感写歌</text>
-							<text class="card-desc">快速生成专属原创曲目</text>
-						</view>
 
-					</view>
-					<image src="/static/make/planet.png" class="card-image" mode="aspectFit"></image>
-				</view>
-			</view>
 
-			<!-- 萌萌智绘魔方卡片 -->
-			<view class="card card-medium cube" @click="handleCardClick('cube')">
-				<view class="card-content">
-					<view class="text-area"  >
-						<view>
-							<text class="card-title">萌萌智绘魔方</text>
-							<text class="card-desc">AI随机生成萌玩原型</text>
-						</view>
-					</view>
-					<image src="/static/make/book.png" class="card-image" mode="aspectFit"></image>
-				</view>
-			</view>
 
-		</view>
 		<view class="guide-title"> 引导教程</view>
-		<!-- 引导教程区域 -->
-		<view class="tutorial">
-			<view class="tutorial-block " @click="goWeb(item.url, item.subheading)" v-for="(item, index) in tutorial"
-				:key="index">
-				<text class="tutorial-btn-box">
-					<view class="tutorial-btn">
-						<image src="../../static/make/cz_icon_guanfangjiaocheng.png"></image>
-						<text>{{ item.title }}</text>
-					</view>
-				</text>
-				<text class="tutorial-title"> {{ item.subheading }}</text>
-				<view class="tutorial-content">{{ item.content }}</view>
-			</view>
+
+		<view class="guide-content">
+			<block v-for="(item, index) in guideList" :key="index" >
+				<image :src="item.url" class="scale-tap card-image"  @click="goWeb(item.webUrl, item.subheading)" mode="widthFix"></image>
+			</block>
 		</view>
+
 		<tabbar-view :tabbars="tabbars" :currentIndex="1" ref="tabbar"></tabbar-view>
 		<!-- 新手引导组件 -->
 		<novice-guidance :step="step"></novice-guidance>
@@ -129,9 +78,24 @@ export default {
 					}]
 			},
 			tutorial: [
-				{ title: "官方教程", url: "https://docs.qingque.cn/d/home/eZQBj5luSHVkaqpJmL5PTuFfZ?identityId=2HSXOrUAEOx", subheading: "萌萌智绘魔方", content: "教你如何创作内容,激发创作灵感!" },
-				{ title: "官方教程", url: "https://docs.qingque.cn/d/home/eZQDGgIXzR08ssYlwoy2tjiNA?identityId=2HSXOrUAEOx", subheading: "AI灵感写歌", content: "使用AI超能力释放你的无限创造力!" },
-				{ title: "官方教程", url: "https://docs.qingque.cn/d/home/eZQC3yyQj9gK-KnVUZOT6vYmn?identityId=2HSXOrUAEOx", subheading: "星球造物,AI创角", content: "使用自然语言,创建独属于你的智能体" },
+				{
+					title: "官方教程"
+					, url: "https://docs.qingque.cn/d/home/eZQBj5luSHVkaqpJmL5PTuFfZ?identityId=2HSXOrUAEOx"
+				},
+				{
+					title: "官方教程"
+					, url: "https://docs.qingque.cn/d/home/eZQDGgIXzR08ssYlwoy2tjiNA?identityId=2HSXOrUAEOx"
+				},
+				{
+					title: "官方教程"
+					, url: "https://docs.qingque.cn/d/home/eZQC3yyQj9gK-KnVUZOT6vYmn?identityId=2HSXOrUAEOx"
+				},
+			],
+			guideList: [
+				{ url: '../../static/make/guide-item1.png', webUrl: "https://docs.qingque.cn/d/home/eZQBj5luSHVkaqpJmL5PTuFfZ?identityId=2HSXOrUAEOx", content: "教你如何创作内容,激发创作灵感!", subheading: "萌萌智绘魔方" },
+				{ url: '../../static/make/guide-item2.png', webUrl: "https://docs.qingque.cn/d/home/eZQDGgIXzR08ssYlwoy2tjiNA?identityId=2HSXOrUAEOx", content: "使用AI超能力释放你的无限创造力!", subheading: "AI灵感写歌" },
+				{ url: '../../static/make/guide-item3.png', webUrl: "https://docs.qingque.cn/d/home/eZQC3yyQj9gK-KnVUZOT6vYmn?identityId=2HSXOrUAEOx", content: "使用自然语言,创建独属于你的智能体", subheading: "星球造物,AI创角" },
+				{ url: '../../static/make/guide-item4.png', webUrl: "https://docs.qingque.cn/d/home/eZQCk1MWQJHxZvrIXODj-3ALk?identityId=2HSXOrUAEOx", content: "使用自然语言,创建独属于你的智能体", subheading: "星球造物,AI创角" },
 			]
 		}
 	},
@@ -148,26 +112,13 @@ export default {
 	// 下拉刷新数据
 	methods: {
 		goWeb(url, title) {
+			console.log(1);
+			
 			uni.navigateTo({
 				url: `/pages/webview/index?url=${encodeURIComponent(url)}&title=${encodeURIComponent(title)}`
 			})
 		},
 		getMyInfo() {
-			uni.request({
-				url: this.$apiHost + '/My/getnum',
-				method: 'GET',
-				header: {
-					'content-type': 'application/json',
-					'sign': getApp().globalData.headerSign
-				},
-				data: {
-					uuid: getApp().globalData.uuid
-				},
-				success: (res) => {
-					console.log("获取用户信息:", res.data);
-					this.myinfo = res.data
-				}
-			})
 
 		},
 		tabChange(index) {

+ 40 - 40
pages/my/editInfo.vue

@@ -166,20 +166,20 @@
 			<NicknamePopup title="背景图" subtitle="" ref="backgroundImage" class="NicknamePopup-backgroundImage">
 				<template v-slot:content>
 					<view class="content">
-					<view style="padding: 20rpx 0;">
-						<uv-swiper :list="bgList" height="80" indicator :autoplay="false" keyName="url"
+						<view style="padding: 20rpx 0;">
+							<uv-swiper :list="bgList" height="80" indicator :autoplay="false" keyName="url"
 							:displayMultipleItems="2" next-margin="40"  
 							imgMode="aspectFit" :indicator="false" :current="currentBgIndex" @click="changeBgSwiper"
 
-							style="width: 100%;    overflow: hidden; background: transparent;" />
-					</view>
-					<view class="info_item" @click="chooseBgImage">
-						<text class="label">上传背景图</text>
-						<view class="content"> 
-							<image class="arrow" src="../../static/me/arrow_right_gray.png" mode="widthFix" />
+								style="width: 100%;    overflow: hidden; background: transparent;" />
+						</view>
+						<view class="info_item" @click="chooseBgImage">
+							<text class="label">上传背景图</text>
+							<view class="content">
+								<image class="arrow" src="../../static/me/arrow_right_gray.png" mode="widthFix" />
+							</view>
 						</view>
 					</view>
-				</view>
 				</template>
 			</NicknamePopup>
 		</view>
@@ -684,8 +684,8 @@ export default {
 										title: resdata.str || '上传失败',
 										icon: 'none'
 									});
-								}
-							},
+					}
+				},
 							fail: function (uploadFileFail) {
 								console.log('Error:', uploadFileFail.data);
 								uni.showToast({
@@ -979,43 +979,43 @@ page {
 
 .NicknamePopup-backgroundImage {
 	.info_item {
-	height: 100rpx;
-	display: flex;
-	align-items: center;
-	padding: 0 30rpx;
-	border-bottom: 1rpx solid #f5f5f5;
-	padding-right: 20rpx;
-	background: #fff;
-	border-radius: 12rpx;
-	&:last-child {
-		border-bottom: none;
-	}
-
-	.label {
-		width: 160rpx;
-		font-size: 28rpx;
-		color: #1f1f1f;
-		font-family: "PingFang SC-Medium";
-	}
-
-	.content {
-		flex: 1;
+		height: 100rpx;
 		display: flex;
 		align-items: center;
-		justify-content: flex-end;
+		padding: 0 30rpx;
+		border-bottom: 1rpx solid #f5f5f5;
+		padding-right: 20rpx;
+		background: #fff;
+	border-radius: 12rpx;
+		&:last-child {
+			border-bottom: none;
+		}
 
-		input {
-			text-align: right;
+		.label {
+			width: 160rpx;
 			font-size: 28rpx;
-			color: #333;
+			color: #1f1f1f;
+			font-family: "PingFang SC-Medium";
 		}
 
-		.arrow {
-			width: 36rpx;
-			margin-left: 10rpx;
+		.content {
+			flex: 1;
+			display: flex;
+			align-items: center;
+			justify-content: flex-end;
+
+			input {
+				text-align: right;
+				font-size: 28rpx;
+				color: #333;
+			}
+
+			.arrow {
+				width: 36rpx;
+				margin-left: 10rpx;
+			}
 		}
 	}
-}
 	::v-deep .uv-popup__content {
 		background: #f2f6f2 !important;
 	}

+ 737 - 0
pages/my/initiateCrowdfunding.vue

@@ -0,0 +1,737 @@
+<template>
+	<view class="page">
+
+		<view class="nav-bar">
+			<view class="left">
+				<view class="uni-btn-icon" @click="goBack">&#xe601;</view>
+				<view class="center">发表想法</view>
+			</view>
+			<view class="right">
+				<!-- <view class="btn" @click="onManage">管理</view> -->
+				<view class="btn" @click="onSubmit" v-if="id && id < 1">发布</view>
+				<view class="btn" @click="onSubmit" v-else>更新</view>
+			</view>
+		</view>
+
+		<view class="enterContentDetails">
+			<!-- 上限五张图片或一个视频 -->
+			<view class="img_list">
+				<view class="image" v-for="(item, index) in img_list" :key="index">
+					<image class="upimg" :src="item" mode="aspectFill"></image>
+					<image class="del" src="@/static/icon/img-del.png" @click="delIt(index)"></image>
+					<view class="loading" v-if="item.startsWith('http') === false">
+						<view class="loading-icon"></view>
+					</view>
+				</view>
+				<view v-if="video_path" class="image">
+					<video :src="video_path" controls style="width:100%;height:100%"></video>
+					<image class="del" src="@/static/icon/img-del.png" @click="delVideo"></image>
+				</view>
+				<view class="image" @click="upload('list')" v-if="img_list.length < 9">
+					<image class="txt" src="../../static/icon/sy_icon_jiahao02.png"></image>
+				</view>
+			</view>
+			<view class="content-title">
+				<input class="edit" v-model="ainfo.title" maxlength="20" placeholder="标题(必填)" />
+			</view>
+			<view class="content-textarea">
+				<textarea class="edit2" auto-height v-model="ainfo.content" :maxlength="1000"
+					placeholder="添加描述"></textarea>
+			</view>
+
+			<view class="agree">
+				<text class="xy">{{ ainfo.content.length }}/1000</text>
+			</view>
+
+
+		</view>
+
+		<view class="worksBox scale-tap" @click="upload4">
+			<view class="optionalWorks">
+				<view class="title">
+					上传详情页
+					<text style="font-weight: normal;">(支持长图)</text>
+				</view>
+			</view>
+			<view class="select-box">
+				<image src="../../static/icon/upload-icon.png"></image>
+			</view>
+		</view>
+
+
+
+
+
+
+
+
+	</view>
+</template>
+
+<script>
+import permission from '@/common/permission.js';
+export default {
+	components: {},
+	data() {
+		return {
+			skey: '',
+			pop_sel: false,
+			cid: 0,
+			catename: '',
+			img2: '',
+			ainfo: {
+				id: 0,
+				title: '',
+				content: '',
+				name: '',
+				telphone: '',
+				address: '',
+				contact: '',
+				num: '',
+			},
+			img_list: [],
+			video_path: '',
+			is_agree: 0,
+			selectedWork: {},
+			content_images: [],
+		}
+	},
+
+	onLoad(params) {
+		if (getApp().globalData.skey != "") {
+			this.skey = getApp().globalData.skey;
+		} else {
+			this.skey = params.skey || ''; //1234567xef
+		}
+		if (params.id) {
+
+			this.id = params.id;
+		} else {
+			this.id = -1;
+
+		}
+		let that = this;
+		// this.getCate();
+		that.getInfo();
+		// this.getData();
+
+		// 添加事件监听
+		uni.$on('selectItem', this.handleSelect);
+
+
+	},
+	onUnload() {
+		uni.$off('selectItem', this.handleSelect);
+	},
+	onShow() {
+		let that = this;
+	},
+	methods: {
+		goBack() {
+			uni.navigateBack();
+		},
+		handleSelect(item) {
+			this.selectedWork = item;
+		},
+		delIt(ind) {
+			let arr = [];
+			if (this.img_list.length > 0) {
+				for (let i = 0; i < this.img_list.length; i++) {
+					if (i !== ind) {
+						arr.push(this.img_list[i]);
+					}
+				}
+				this.img_list = arr;
+			}
+		},
+		getInfo() {
+			var that = this;
+			uni.request({
+				url: this.$apiHost + '/Article/getinfo',
+				data: {
+					uuid: getApp().globalData.uuid,
+					id: this.id
+				},
+				header: {
+					'content-type': 'application/json'
+				},
+				success: (res) => {
+					this.ainfo = res.data.article;
+					this.img_list = [];
+					this.selectedWork = res.data.work_info;
+					if (res.data.article.images.length > 1) {
+						let arr = res.data.article.images.split("|");
+						if (arr.length > 0) {
+							for (let i = 0; i < arr.length; i++) {
+								if (arr[i].length > 10) {
+									this.img_list.push(arr[i]);
+								}
+							}
+						}
+					}
+				}
+			});
+		},
+		checkField(str, tips) {
+			if (str.length < 2) {
+				uni.showToast({ title: tips, icon: 'none' });
+				return false;
+			}
+			return true;
+		},
+		onSubmit() {
+			if (this.checkField(this.ainfo.title, "请输入名称") == false) return;
+			if (this.checkField(this.ainfo.content, "请输入具体内容") == false) return;
+			if (this.is_submit > 0) return;
+			let img_str = '';
+			if (this.img_list.length > 0) {
+				for (let i = 0; i < this.img_list.length; i++) {
+					img_str += this.img_list[i] + "|";
+				}
+			}
+			if (this.img_list.length < 1 && !this.selectedWork.id) {
+				uni.showToast({ title: '请上传 图片 或 选择一个作品', icon: 'none' });
+				return;
+			} else {
+				if (!this.selectedWork.id) {
+					if (!img_str || img_str.trim().length < 2) {
+						uni.showToast({ title: '请确保至少上传一张有效图片作为封面', icon: 'none' });
+						return;
+					}
+					if (this.img_list.length > 5) {
+						uni.showToast({ title: '最多只能上传 5 张图片', icon: 'none' });
+						return;
+					}
+				}
+			}
+			let that = this;
+			let contentImagesStr = '';
+			if (this.content_images.length > 0) {
+				for (let i = 0; i < this.content_images.length; i++) {
+					contentImagesStr += this.content_images[i] + "|";
+				}
+			}
+			this.is_submit = 1;
+			console.log( {
+					uuid: getApp().globalData.uuid,
+					id: this.ainfo.id,
+					title: this.ainfo.title,
+					content: this.ainfo.content,
+					images: img_str,
+					content_images: contentImagesStr,
+					video_url: this.video_path,
+				},9999999999);
+			
+			uni.request({
+				url: this.$apiHost + '/crowdfund/seji/save',
+				data: {
+					uuid: getApp().globalData.uuid,
+					id: this.ainfo.id,
+					title: this.ainfo.title,
+					content: this.ainfo.content,
+					images: img_str,
+					content_images: contentImagesStr,
+					video_url: this.video_path,
+				},
+				method: 'POST',
+				header: {
+					'Content-Type': 'application/x-www-form-urlencoded',
+					'sign': getApp().globalData.headerSign
+				},
+				dataType: 'json',
+				success: (res) => {
+					uni.showToast({ title: res.data.str, icon: 'none' });
+					if (res.data.success == "yes") {
+						setTimeout(function () {
+							uni.$emit('switchToMyPage', { type: 'article' });
+							uni.switchTab({ url: '/pages/my/my' })
+						}, 500);
+						that.ainfo.title = '';
+						that.ainfo.content = '';
+						that.ainfo.num = '';
+						that.img_list = [];
+					}
+					this.is_submit = 0;
+				},
+				fail: (err) => {
+					this.is_submit = 0;
+				},
+				complete: (com) => { }
+			})
+		},
+		async upload(type) {
+			// 权限弹窗校验
+			let hasPermission = false;
+			try {
+				hasPermission = await permission.request('photoLibrary', {
+					title: '相册/视频权限说明',
+					describe: '便于您上传图片或视频,请您确认授权,否则无法使用该功能'
+				});
+				if (!hasPermission) {
+					uni.showToast({ title: '未获得相册权限', icon: 'none' });
+					return;
+				}
+			} catch (e) {
+				uni.showToast({ title: '权限检查失败', icon: 'none' });
+				return;
+			}
+			if (this.img_list.length >= 9 && !this.video_path) {
+				uni.showToast({ title: '最多只能上传9张图片', icon: 'none' });
+				return;
+			}
+			uni.chooseMedia({
+				count: 9 - this.img_list.length,
+				mediaType: ['image', 'video'],
+				sourceType: ['album', 'camera'],
+				maxDuration: 60,
+				success: (res) => {
+					console.log(res, 'res');
+
+					if (res.tempFiles && res.tempFiles.length > 0) {
+						// 判断是否有视频
+						let videoFiles = res.tempFiles.filter(file => file.fileType === 'video');
+						if (videoFiles.length > 0) {
+							// 如果多选视频,只处理第一个并提示
+							if (videoFiles.length > 1) {
+								uni.showToast({ title: '只能上传一个视频,已自动选取第一个', icon: 'none' });
+							}
+							// 如果已存在视频,替换并提示
+							if (this.video_path) {
+								uni.showToast({ title: '已替换为新上传的视频', icon: 'none' });
+							}
+							this.upload2(type, videoFiles[0].tempFilePath, 'video', '/Xweb/upload_video?skey=');
+							console.log(videoFiles, 'videoFiles');
+
+						}
+						let imageFiles = res.tempFiles.filter(file => file.fileType === 'image');
+						console.log(imageFiles, 'imageFiles');
+						if (imageFiles.length > 0) {
+							// 多图全部上传
+							imageFiles.forEach(img => {
+								this.upload2(type, img.tempFilePath, 'image', '/Xweb/upload_img?skey=');
+							});
+						}
+					}
+				}
+			});
+		},
+		delVideo() {
+			this.video_path = '';
+		},
+		upload2(type, filepath, fileType, url) {
+			console.log(filepath, 'filepath');
+			console.log(fileType, 'fileType');
+
+			// 上传前先显示临时图
+			if (fileType === 'image') {
+				this.img_list.push(filepath);
+			} else if (fileType === 'video') {
+				this.video_path = filepath;
+			}
+
+			let uploadUrl = this.$apiHost + url + this.skey;
+			console.log({
+				url: uploadUrl,
+				filePath: filepath,
+				name: 'file',
+			}, 99999);
+
+			uni.uploadFile({
+				url: uploadUrl,
+				filePath: filepath,
+				name: 'file',
+				success: (uploadFileRes) => {
+					console.log(uploadFileRes, 'uploadFileRes');
+
+					let resdata = JSON.parse(uploadFileRes.data);
+					if (resdata.success == 'no') {
+						uni.showToast({ title: resdata.str, icon: 'none' });
+						// 上传失败时移除临时图
+						if (fileType === 'image') {
+							this.img_list.pop();
+						} else if (fileType === 'video') {
+							this.video_path = '';
+						}
+						return;
+					}
+					if (resdata.code == 0) {
+						if (fileType === 'image') {
+							// 替换临时图为服务端路径
+							const index = this.img_list.indexOf(filepath);
+							if (index !== -1) {
+								this.img_list[index] = resdata.data.path;
+							}
+						} else if (fileType === 'video') {
+							this.video_path = resdata.data.path;
+						}
+					}
+				},
+				fail: () => {
+					// 上传失败时移除临时图
+					if (fileType === 'image') {
+						this.img_list.pop();
+					} else if (fileType === 'video') {
+						this.video_path = '';
+					}
+				}
+			});
+		},
+
+
+
+		upload4(type) {
+			if (this.content_images.length >= 5) {
+				uni.showToast({
+					title: '最多只能上传5张图片',
+					icon: 'none'
+				});
+				return
+			}
+			uni.showActionSheet({
+				itemList: ['拍照', '从相册选择'],
+				success: (res) => {
+					const sourceType = res.tapIndex === 0 ? 'camera' : 'album';
+					this.checkRights1(sourceType);
+				}
+			});
+		},
+		async checkRights1(sourceType) {
+			try {
+				let hasPermission = false;
+
+				if (sourceType === 'camera') {
+					hasPermission = await permission.request(permission.PermissionType.CAMERA, {
+						title: '“萌创星球”想访问你的相机',
+						describe: '萌创星球想访问您的摄像头,便于拍摄获取图片来与其他用户进行交流'
+					});
+
+					if (!hasPermission) {
+						uni.showToast({
+							title: '未获得相机权限',
+							icon: 'none'
+						});
+						return;
+					}
+				} else {
+					hasPermission = await permission.request(permission.PermissionType.PHOTO_LIBRARY, {
+						title: '“萌创星球”想访问你的照片图库',
+						describe: '萌创星球想访问您本地照片图库,便于获取图片来与其他用户进行交流'
+					});
+
+					if (!hasPermission) {
+						uni.showToast({
+							title: '未获得相册权限',
+							icon: 'none'
+						});
+						return;
+					}
+				}
+
+				// 权限获取成功后,继续执行上传
+				this.upload5('list', sourceType);
+			} catch (error) {
+				console.error('权限检查失败:', error);
+				uni.showToast({
+					title: '权限检查失败',
+					icon: 'none'
+				});
+			}
+		},
+		upload5(type, sourceType) {
+			console.log("----upload");
+			var _self = this;
+			uni.chooseImage({
+				count: 5,
+				sizeType: ['compressed'],
+				sourceType: [sourceType],
+				success: function (res) {
+					console.log('res:', res)
+					for (let index = 0; index < res.tempFilePaths.length; index++) {
+						let filepath = "";
+						// #ifdef H5
+						filepath = res.tempFiles[index].path;
+						// #endif
+
+						// #ifdef APP-PLUS
+						filepath = res.tempFilePaths[index];
+						// #endif
+
+						_self.imglocal = filepath; //res.tempFilePaths[0]
+						const uploadTask = uni.uploadFile({
+							url: _self.$apiHost + '/Xweb/upload_img?skey=' + _self.skey, // post请求地址
+							filePath: filepath,
+							name: 'file', // 待确认
+							success: function (uploadFileRes) {
+								let resdata = JSON.parse(uploadFileRes.data)
+								console.log('Success1:', uploadFileRes);
+								if (resdata.success == 'no') {
+									uni.showToast({
+										title: resdata.str,
+										icon: 'none'
+									});
+									return;
+								}
+								if (resdata.code == 0) {
+									console.log('Success2:', resdata.data.path);
+
+									_self.content_images.push(resdata.data.path)
+									console.log('_self.content_images:', _self.content_images);
+.0
+								}
+							},
+							fail: function (uploadFileFail) {
+								console.log('Error:', uploadFileFail.data);
+							},
+							complete: () => {
+								console.log('Complete:');
+							}
+						});
+					}
+				},
+
+				error: function (e) {
+
+					console.log(e);
+
+				}
+
+			});
+
+
+		},
+	}
+}
+</script>
+
+<style scoped lang="scss">
+page {
+	position: absolute;
+	left: 0;
+	top: 0;
+	width: 100%;
+	display: flex;
+	background-color: #f2f6f2;
+	min-height: 100vh;
+}
+
+.status_bar {
+	height: 44rpx;
+	width: 100%;
+}
+
+.page {
+	background-color: #f2f6f2;
+	display: flex;
+	flex-direction: column;
+	width: 750rpx;
+	min-height: 100vh;
+}
+
+.nav-bar {
+	width: calc(100ve - 73rpx);
+	height: calc(96rpx + var(--status-bar-height));
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	padding: 0;
+	padding-right: 40rpx;
+	padding-left: 33rpx;
+	padding-top: var(--status-bar-height);
+	box-sizing: border-box;
+
+	.left {
+		display: flex;
+		align-items: center;
+		font-family: PingFang SC-Bold;
+		font-weight: 400;
+		font-size: 32rpx;
+		color: #1f1f1f;
+
+		.uni-btn-icon {
+			font-size: 45rpx;
+			font-weight: bold;
+			color: #1f1f1f;
+			transition: color 0.2s;
+			margin-right: 20rpx;
+
+			&:active {
+				color: #2b85e4;
+			}
+		}
+	}
+
+	.right {
+		display: flex;
+		align-items: center;
+		font-size: 28rpx;
+		font-family: "PingFang SC-Bold";
+		font-weight: 400;
+
+		.btn {
+			border-radius: 26rpx;
+			background: #1f1f1f;
+			padding: 6rpx 32rpx;
+			color: #acf934;
+			font-size: 28rpx;
+		}
+	}
+}
+
+.enterContentDetails {
+	width: calc(100% - 40rpx);
+	min-height: 726rpx;
+	background: #ffffff;
+	border-radius: 20rpx;
+	margin: 0 20rpx;
+	padding: 0rpx 24rpx 24rpx 24rpx;
+	box-sizing: border-box;
+
+	.edit {
+		height: 92rpx;
+		border-bottom: 2rpx solid #f2f6f2;
+	}
+
+	.edit2 {
+		min-height: 350rpx;
+		width: 100%;
+	}
+
+	.content-textarea {
+		padding-top: 24rpx;
+	}
+
+	::v-deep.input-placeholder,
+	::v-deep.textarea-placeholder {
+		font-family: PingFang SC;
+		font-weight: 400;
+		font-size: 32rpx;
+		color: #999999;
+	}
+
+	.agree {
+		font-family: PingFang SC, PingFang SC;
+		font-weight: 400;
+		font-size: 24rpx;
+		color: #999999;
+		display: flex;
+		align-items: center;
+		justify-content: flex-end;
+	}
+
+	.img_list {
+		width: 100%;
+		display: grid;
+		grid-template-columns: repeat(3, 1fr);
+		row-gap: 20rpx;
+		flex-wrap: wrap;
+		margin-top: 15rpx;
+
+		.image {
+			display: flex;
+			width: 208rpx;
+			height: 208rpx;
+			position: relative;
+			box-sizing: border-box;
+			justify-content: center;
+			align-items: center;
+			background: #f2f6f2;
+			border-radius: 16rpx;
+
+			.txt {
+				font-size: 120rpx;
+				color: #999;
+				width: 40rpx;
+				height: 40rpx;
+			}
+
+			.upimg {
+				position: absolute;
+				left: 0;
+				top: 0;
+				width: 100%;
+				height: 100%;
+				border-radius: 8rpx;
+			}
+
+			.del {
+				width: 40rpx;
+				height: 40rpx;
+				position: absolute;
+				right: 0rpx;
+				top: 0rpx;
+			}
+
+			.loading {
+				position: absolute;
+				left: 0;
+				top: 0;
+				width: 100%;
+				height: 100%;
+				background: rgba(0, 0, 0, 0.5);
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				border-radius: 8rpx;
+
+				.loading-icon {
+					width: 40rpx;
+					height: 40rpx;
+					border: 4rpx solid #fff;
+					border-top-color: transparent;
+					border-radius: 50%;
+					animation: spin 1s linear infinite;
+				}
+			}
+		}
+	}
+}
+
+.worksBox {
+	border-radius: 20rpx;
+	overflow: hidden;
+	margin: 0 24rpx;
+	background: #fff;
+	margin-top: 20rpx;
+	padding-left: 24rpx;
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+
+	.optionalWorks {
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		padding: 24rpx;
+		height: 88rpx;
+		padding-left: 0;
+
+		.title {
+			font-family: "PingFang SC-Bold";
+			font-weight: bold;
+			font-size: 28rpx;
+
+			text {
+				color: #bbb;
+				font-size: 24rpx;
+				padding-left: 10rpx;
+			}
+		}
+	}
+
+	.select-box {
+		width: 64rpx;
+		height: 64rpx;
+
+		image {
+			width: 64rpx;
+			height: 64rpx;
+		}
+	}
+}
+
+@keyframes spin {
+	to {
+		transform: rotate(360deg);
+	}
+}
+</style>

+ 113 - 46
pages/my/my.vue

@@ -1,5 +1,9 @@
 <template>
 	<view class="page">
+		<!-- 用于计算主题色的隐藏Canvas -->
+		<view style="position: absolute; top: -9999px; left: -9999px;">
+			<canvas canvas-id="themeCanvas" id="themeCanvas" style="width: 100px; height: 100px;"></canvas>
+		</view>
 		<view class="topBody">
 			<!-- <view class="header" :class="{ 'header-isvip': !isRecharge }"> -->
 			<view class="header" :style="{ backgroundImage: `url(${bgImage || '../../static/me/theme3.jpg'})` }">
@@ -15,7 +19,8 @@
 							</view>
 						</view>
 						<view class="profilePicture-box">
-							<CircleAvatar class="avator" @click="goPage('/pages/my/editInfo')" :src="myinfo.avator"></CircleAvatar>
+							<CircleAvatar class="avator" @click="goPage('/pages/my/editInfo')" :src="myinfo.avator">
+							</CircleAvatar>
 							<view class="profilePicture-box-right" @click="goPage('/pages/my/creativeExpert')">
 								<view class="one-omit">{{ myinfo.nickname }}</view>
 								<image v-if="myinfo.my_level || myinfo.my_level == 0"
@@ -30,7 +35,7 @@
 								<image src="@/static/me/xiugai.png" mode="widthFix" class="add_icon">
 								</image>
 							</block>
-							<uv-text color="#fff" v-else :text="formatText(myinfo.content)" class="intro_text two-omit"> 
+							<uv-text color="#fff" v-else :text="formatText(myinfo.content)" class="intro_text two-omit">
 							</uv-text>
 						</view>
 
@@ -40,8 +45,7 @@
 
 								<image src="../../static/icon/wd_icon_nv.png" mode="widthFix" v-if="myinfo.sex_id == 2">
 								</image>
-								<image src="../../static/icon/wd_icon_nan.png" mode="widthFix"
-									v-else></image>
+								<image src="../../static/icon/wd_icon_nan.png" mode="widthFix" v-else></image>
 							</view>
 							<view class="label-item" v-for="(item, index) in aihao_tags" :key="index + item">
 								{{ item }}
@@ -70,7 +74,7 @@
 								<view class="bom-item-subtitle">查看我的钱包</view>
 							</view>
 							<view class="bom-item bom-item2 scale-tap">
-								<view class="bom-item-title">发起募集</view>
+								<view class="bom-item-title" @click="initiateFundraising()">发起募集</view>
 								<view class="bom-item-subtitle">查看我的众筹</view>
 							</view>
 							<view class="bom-item bom-item3 scale-tap" @click="goPage('/pages/crowdFunding/orderList')">
@@ -128,7 +132,7 @@
 				</view>
 			</view>
 
-			<view class="myinfo" >
+			<view class="myinfo">
 				<view class="vip-box" @click="isRecharge ? goPage('/pages/vip/index') : ''">
 					<view class="content-box">
 						<image v-if="false" src="@/static/me/icon-vip2.png" mode=""></image>
@@ -306,7 +310,7 @@
 		<!-- SharePopup组件 -->
 		<SharePopup :visible="showShare" :userId="userId" :share-title="shareTitle" :share-desc="shareDesc"
 			:share-img="shareImg" view="makeDetail" @close="showShare = false" />
-
+		<DialogBox ref="DialogBox"></DialogBox>
 	</view>
 </template>
 
@@ -318,6 +322,8 @@ import CircleAvatar from "@/components/CircleAvatar/CircleAvatar.vue";
 import meCard from "@/components/meCard/meCard.vue";
 import WorkItem from "@/components/WorkItem/WorkItem.vue";
 import { mapState } from 'vuex'
+import { scientificCounting } from "@/common/util.js";
+import { RgbQuant } from '@/common/RgbQuant.js';
 export default {
 	components: {
 		tabbarView,
@@ -446,50 +452,108 @@ export default {
 		},
 		goPage(page) {
 			console.log(999);
-			
+
 			uni.navigateTo({
 				url: page,
 			});
 
 		},
+		initiateFundraising() { 
+			if (this.myinfo.my_level < 3) {
+				this.$refs["DialogBox"]
+					.confirm({
+						title: "提示",
+						content: "您当前的等级为1级,需要达到3级才能发起募集",
+						DialogType: "inquiry",
+						btn1: "取消",
+						btn2: "去查看等级",
+						animation: 0,
+					})
+					.then((res) => {
+						 this.goPage('/pages/my/creativeExpert')
+						
+					},(res)=>{ 
+					});
+				return;
+			}
+			this.goPage('/pages/my/initiateCrowdfunding')
+		},
 		async calculateThemeColor(imageUrl) {
-			return new Promise((resolve) => {
-				const img = new Image();
-				img.crossOrigin = 'Anonymous';
-				img.onload = () => {
-					const canvas = document.createElement('canvas');
-					const ctx = canvas.getContext('2d');
-					canvas.width = img.width;
-					canvas.height = img.height;
-					ctx.drawImage(img, 0, 0);
-					
-					// 获取图片数据
-					const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
-					
-					// 计算平均颜色
-					let r = 0, g = 0, b = 0;
-					for (let i = 0; i < imageData.length; i += 4) {
-						r += imageData[i];
-						g += imageData[i + 1];
-						b += imageData[i + 2];
-					}
-					
-					const pixelCount = imageData.length / 4;
-					r = Math.round(r / pixelCount);
-					g = Math.round(g / pixelCount);
-					b = Math.round(b / pixelCount);
-					
-					// 调整颜色使其更暗
-					// r = Math.floor(r * 0.1);
-					// g = Math.floor(g * 0.1);
-					// b = Math.floor(b * 0.1);
-					
-					resolve(`linear-gradient(360deg, rgba(${r},${g},${b},0.1) 0%, rgba(${r},${g},${b},0.4) 100%)`);
+			if (!imageUrl) {
+				// 如果没有图片,则使用默认样式
+				this.headerBoxStyle = {
+					background: 'linear-gradient(to bottom, rgba(0, 0, 0, 0.5), transparent)'
 				};
-				img.onerror = () => {
-					resolve('linear-gradient(360deg, #16210E 0%, rgba(55,73,36,0) 100%)');
-				};
-				img.src = imageUrl;
+				return;
+			}
+			console.log('开始计算主题色, imageUrl:', imageUrl);
+			const canvasId = 'themeCanvas';
+			const ctx = uni.createCanvasContext(canvasId, this);
+
+			uni.getImageInfo({
+				src: imageUrl,
+				success: (imageInfo) => {
+					console.log('图片信息获取成功:', imageInfo);
+					const canvasWidth = 100; // 缩小图片以加快处理速度
+					const canvasHeight = Math.floor(canvasWidth * (imageInfo.height / imageInfo.width));
+
+					// 绘制图片到canvas
+					ctx.drawImage(imageInfo.path, 0, 0, canvasWidth, canvasHeight);
+					ctx.draw(false, () => {
+						console.log('Canvas 绘制完成');
+						// 获取像素数据
+						uni.canvasGetImageData({
+							canvasId: canvasId,
+							x: 0,
+							y: 0,
+							width: canvasWidth,
+							height: canvasHeight,
+							success: (res) => {
+								console.log('像素数据获取成功');
+								const pixels = res.data;
+
+								// 使用 RgbQuant 提取主要颜色
+								const quant = new RgbQuant({
+									colors: 16, // 提取16种主要颜色
+									method: 2, // 使用 WuQuant 算法
+								});
+								quant.sample(pixels);
+								const palette = quant.quantize();
+
+								if (quant.vboxes && quant.vboxes.length > 0) {
+									let dominantColor = null;
+									let maxPopulation = 0;
+
+									// 找到像素数最多的颜色区域
+									quant.vboxes.forEach(vbox => {
+										const population = vbox.size(quant.histogram);
+										if (population > maxPopulation) {
+											maxPopulation = population;
+											dominantColor = vbox.color(quant.histogram);
+										}
+									});
+
+									if (dominantColor) {
+										const [r, g, b] = dominantColor.map(value => Math.min(255, Math.max(0, value)));
+										const themeColor = `rgba(${r}, ${g}, ${b}, 0.5)`;
+										console.log('计算出的主题色 (Dominant):', themeColor);
+
+										// 更新 header-box 的背景样式
+										this.headerBoxStyle = {
+											background: `linear-gradient(to bottom, ${themeColor}, transparent)`
+										};
+									}
+								}
+							},
+							fail: (err) => {
+								console.error('获取像素数据失败:', err);
+							}
+						});
+					});
+				},
+				fail: (err) => {
+					console.error('获取图片信息失败:', err);
+				}
 			});
 		},
 		async loadInfo() {
@@ -530,6 +594,9 @@ export default {
 						this.aihao_tags = res.data.aihao.split(",");
 					}
 					this.myinfo = res.data;
+					this.bgImage = res.data.bgimg;
+					// 在获取到背景图片后,计算主题色
+					// this.calculateThemeColor(this.bgImage);
 				},
 				complete: (com) => {
 					// uni.hideLoading();
@@ -551,12 +618,12 @@ export default {
 				},
 				success: async (res) => {
 					console.log("----:", JSON.parse(JSON.stringify(res.data)));
-					if (res.data) { 
+					if (res.data) {
 						this.bgImage = res.data.bgimg;
 						if (this.bgImage) {
 							// 计算主题色并更新蒙版背景
-							const gradient = `linear-gradient(360deg, rgba(0,0,0,0.8) 0%, rgba(0,0,0,0 ) 100%)`
 							// const gradient = await this.calculateThemeColor(this.bgImage);
+							const gradient = `linear-gradient(to bottom,transparent, rgba(0, 0, 0, .8))`;
 							this.headerBoxStyle = {
 								background: gradient
 							};

BIN
static/crowdFunding/authentication.png


BIN
static/crowdFunding/crowdfundingDetails-poster.png


BIN
static/crowdFunding/img_v3_02mi_cdde7569-6e1b-4556-bcc3-162292752a5g@3x.png


BIN
static/home/home-swper3.png


BIN
static/icon/upload-icon.png


BIN
static/make/chuangjiao.png


BIN
static/make/guide-item1.png


BIN
static/make/guide-item2.png


BIN
static/make/guide-item3.png


BIN
static/make/guide-item4.png


BIN
static/make/make_bg.png


BIN
static/make/shengTu.png


BIN
static/make/songwriting.png


+ 1 - 1
store/modules/hideModule.js

@@ -1,5 +1,5 @@
 const state = { 
-  isSmsLogin: false, // 隐藏短信登录
+  isSmsLogin: true  , // 隐藏短信登录
   isWeChatPay: true, // 隐藏微信支付
 }
 

+ 2 - 2
uni_modules/z-paging/components/z-paging/z-paging.vue

@@ -141,7 +141,7 @@ by ZXLee
 									<view v-if="safeAreaInsetBottom&&useSafeAreaPlaceholder&&!useChatRecordMode" class="zp-safe-area-placeholder" :style="[{height:safeAreaBottom+'px'}]" />
 								</view>
 								<!-- 空数据图 -->
-								<view v-if="showEmpty" :class="{'zp-empty-view':true,'zp-empty-view-center':emptyViewCenter}" :style="[emptyViewSuperStyle,chatRecordRotateStyle]">
+								<view v-if="showEmpty && false" :class="{'zp-empty-view':true,'zp-empty-view-center':emptyViewCenter}" :style="[emptyViewSuperStyle,chatRecordRotateStyle]">
 									<slot v-if="zSlots.empty" name="empty" :isLoadFailed="isLoadFailed"/>
 									<z-paging-empty-view v-else :emptyViewImg="finalEmptyViewImg" :emptyViewText="finalEmptyViewText" :showEmptyViewReload="finalShowEmptyViewReload" 
 									:emptyViewReloadText="finalEmptyViewReloadText" :isLoadFailed="isLoadFailed" :emptyViewStyle="emptyViewStyle" :emptyViewTitleStyle="emptyViewTitleStyle" 
@@ -273,7 +273,7 @@ by ZXLee
 					</view>
 				</component>
 				<!-- 空数据图 -->
-				<component :is="nViewIs" v-if="showEmpty" :class="{'z-paging-content-fixed':usePageScroll}" :style="[{flex:emptyViewCenter?1:0},emptyViewSuperStyle,chatRecordRotateStyle]">
+				<component :is="nViewIs" v-if="showEmpty&&false" :class="{'z-paging-content-fixed':usePageScroll}" :style="[{flex:emptyViewCenter?1:0},emptyViewSuperStyle,chatRecordRotateStyle]">
 					<view :class="{'zp-empty-view':true,'zp-empty-view-center':emptyViewCenter}">
 						<slot v-if="zSlots.empty" name="empty" :isLoadFailed="isLoadFailed" />
 						<z-paging-empty-view v-else :emptyViewImg="finalEmptyViewImg" :emptyViewText="finalEmptyViewText" :showEmptyViewReload="finalShowEmptyViewReload"