初始化参股

This commit is contained in:
2026-01-27 18:06:04 +08:00
commit 2774a539bf
254 changed files with 33255 additions and 0 deletions

View File

@@ -0,0 +1,61 @@
"use strict";
const utils_request = require("../utils/request.js");
const getBanners = () => {
return Promise.resolve(new UTSJSONObject({
code: 0,
message: "success",
data: [
new UTSJSONObject({
id: "1",
image: "/static/mock/banner1.svg",
title: "专业沙发翻新服务",
link: "/pages/service/index"
}),
new UTSJSONObject({
id: "2",
image: "/static/mock/banner2.svg",
title: "十年品质保证",
link: "/pages/about/index"
}),
new UTSJSONObject({
id: "3",
image: "/static/mock/banner3.svg",
title: "免费上门评估",
link: "/pages/booking/index"
})
]
}));
};
const getCaseList = (params = null) => {
const queryParams = params ? new UTSJSONObject({
page: params["page"] || 1,
limit: params["pageSize"] || params["limit"] || 10,
serviceType: params["category"],
status: "published"
// 只获取已发布的案例
}) : new UTSJSONObject({});
return utils_request.get("/cases", queryParams);
};
const getCaseDetail = (id) => {
return utils_request.get(`/cases/${id}`);
};
const getHotCases = () => {
return utils_request.get("/cases", new UTSJSONObject({ limit: 4, status: "published" }));
};
const getServiceProcess = () => {
return utils_request.get("/services");
};
const getCompanyInfo = () => {
return utils_request.get("/company/info");
};
const submitBooking = (data) => {
return utils_request.post("/booking", data);
};
exports.getBanners = getBanners;
exports.getCaseDetail = getCaseDetail;
exports.getCaseList = getCaseList;
exports.getCompanyInfo = getCompanyInfo;
exports.getHotCases = getHotCases;
exports.getServiceProcess = getServiceProcess;
exports.submitBooking = submitBooking;
//# sourceMappingURL=../../.sourcemap/mp-weixin/api/index.js.map

View File

@@ -0,0 +1,35 @@
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const common_vendor = require("./common/vendor.js");
if (!Math) {
"./pages/index/index.js";
"./pages/cases/list.js";
"./pages/cases/detail.js";
"./pages/service/index.js";
"./pages/about/index.js";
"./pages/booking/index.js";
"./pages/user/index.js";
}
const _sfc_main = common_vendor.defineComponent({
onLaunch() {
common_vendor.index.__f__("log", "at App.uvue:7", "App Launch");
},
onShow() {
common_vendor.index.__f__("log", "at App.uvue:10", "App Show");
},
onHide() {
common_vendor.index.__f__("log", "at App.uvue:13", "App Hide");
},
onExit() {
common_vendor.index.__f__("log", "at App.uvue:34", "App Exit");
}
});
function createApp() {
const app = common_vendor.createSSRApp(_sfc_main);
return {
app
};
}
createApp().app.mount("#app");
exports.createApp = createApp;
//# sourceMappingURL=../.sourcemap/mp-weixin/app.js.map

View File

@@ -0,0 +1,50 @@
{
"pages": [
"pages/index/index",
"pages/cases/list",
"pages/cases/detail",
"pages/service/index",
"pages/about/index",
"pages/booking/index",
"pages/user/index"
],
"window": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "优艺家沙发翻新",
"navigationBarBackgroundColor": "#ffffff",
"backgroundColor": "#f5f5f5"
},
"tabBar": {
"color": "#999999",
"selectedColor": "#D4A574",
"borderStyle": "black",
"backgroundColor": "#ffffff",
"list": [
{
"pagePath": "pages/index/index",
"iconPath": "static/icons/home.png",
"selectedIconPath": "static/icons/home-active.png",
"text": "首页"
},
{
"pagePath": "pages/cases/list",
"iconPath": "static/icons/cases.png",
"selectedIconPath": "static/icons/cases-active.png",
"text": "案例"
},
{
"pagePath": "pages/service/index",
"iconPath": "static/icons/service.png",
"selectedIconPath": "static/icons/service-active.png",
"text": "服务"
},
{
"pagePath": "pages/user/index",
"iconPath": "static/icons/user.png",
"selectedIconPath": "static/icons/user-active.png",
"text": "我的"
}
]
},
"usingComponents": {}
}

View File

@@ -0,0 +1,9 @@
/*每个页面公共css */
.uni-row {
flex-direction: row;
}
.uni-column {
flex-direction: column;
}
page{--status-bar-height:25px;--top-window-height:0px;--window-top:0px;--window-bottom:0px;--window-left:0px;--window-right:0px;--window-magin:0px;--uni-safe-area-inset-top:0px;--uni-safe-area-inset-left:0px;--uni-safe-area-inset-right:0px;--uni-safe-area-inset-bottom:0px;}[data-c-h="true"]{display: none !important;}

View File

@@ -0,0 +1,95 @@
module.exports = {
sS: function (newValue, oldValue, _ownerInstance, instance) {
if (newValue) {
instance.setStyle(newValue)
}
},
sA: function (newValue, oldValue, _ownerInstance, instance) {
if (newValue) {
handleStartAnimation(newValue, _ownerInstance, instance)
}
},
}
function handleStartAnimation(newValue, _ownerInstance, instance) {
var info = {}
info = JSON.parse(newValue)
var element = _ownerInstance.selectComponent('#' + info.id)
// playState leftTimes
var state = element.getState()
state.playState = info.playState
var startTime = null
state.leftTimes = info.options.iterations || 1
var currentStep = 0
var duration =
info.options.direction === 'alternate'
? info.options.duration * 2
: info.options.duration
function interpolateKeyframe(keyframes, usedTime) {
var index = 0
for (var i = 0; i < keyframes.length; i++) {
if (keyframes[i]._startTime + keyframes[i]._duration >= usedTime) {
index = i
break
}
}
var currentFrame = keyframes[index]
return {
style: currentFrame,
index: index,
}
}
function step() {
var isCancelled = state.playState === 'cancel'
var currentTime = Date.now()
if (startTime === null) {
startTime = currentTime
}
var elapsedTime = currentTime - startTime
if (isCancelled) {
var lastFrame = info.keyframes[info.keyframes.length - 1]
lastFrame.transition = 'none'
element.setStyle(lastFrame)
element.removeClass('__ct' + currentStep)
return
}
var res = interpolateKeyframe(info.keyframes, elapsedTime)
// currentStep removeClass
if (!element.hasClass('__ct' + res.index) && elapsedTime < duration) {
element.setStyle(res.style).addClass('__ct' + res.index)
}
if (currentStep !== res.index) {
element.removeClass('__ct' + currentStep)
currentStep = res.index
}
if (elapsedTime <= duration) {
instance.requestAnimationFrame(step)
} else {
// done
// element.callMethod('animationEnd')
if (state.leftTimes > 1) {
state.leftTimes--
startTime = null
instance.requestAnimationFrame(step)
return
} else if (state.leftTimes === -1) {
// handle infinite
startTime = null
instance.requestAnimationFrame(step)
}
}
}
instance.requestAnimationFrame(step)
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,39 @@
"use strict";
const common_vendor = require("../../common/vendor.js");
const _sfc_main = /* @__PURE__ */ common_vendor.defineComponent({
__name: "before-after",
props: {
beforeImage: {},
afterImage: {},
showTitle: { type: Boolean }
},
setup(__props) {
const props = __props;
const previewImage = (url, type) => {
const urls = type == "before" ? [props.beforeImage] : [props.afterImage];
common_vendor.index.previewImage({
current: url,
urls
});
};
return (_ctx, _cache) => {
"raw js";
const __returned__ = common_vendor.e({
a: _ctx.showTitle
}, _ctx.showTitle ? {} : {}, {
b: _ctx.beforeImage,
c: common_vendor.o(($event) => {
return previewImage(_ctx.beforeImage, "before");
}),
d: _ctx.afterImage,
e: common_vendor.o(($event) => {
return previewImage(_ctx.afterImage, "after");
}),
f: common_vendor.sei(common_vendor.gei(_ctx, ""), "view")
});
return __returned__;
};
}
});
wx.createComponent(_sfc_main);
//# sourceMappingURL=../../../.sourcemap/mp-weixin/components/before-after/before-after.js.map

View File

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

View File

@@ -0,0 +1 @@
<view id="{{f}}" change:eS="{{uV.sS}}" eS="{{$eS[f]}}" change:eA="{{uV.sA}}" eA="{{$eA[f]}}" class="{{['before-after', virtualHostClass]}}" style="{{virtualHostStyle}}" hidden="{{virtualHostHidden || false}}"><view wx:if="{{a}}" class="ba-title"><text class="ba-title-text">翻新前后对比</text></view><view class="ba-container"><view class="ba-item" bindtap="{{c}}"><view class="ba-label before-label"><text class="ba-label-text">翻新前</text></view><image class="ba-image" src="{{b}}" mode="aspectFill"></image></view><view class="ba-arrow"><text class="ba-arrow-text">→</text></view><view class="ba-item" bindtap="{{e}}"><view class="ba-label after-label"><text class="ba-label-text">翻新后</text></view><image class="ba-image" src="{{d}}" mode="aspectFill"></image></view></view></view><wxs src="/common/uniView.wxs" module="uV"/>

View File

@@ -0,0 +1,81 @@
:host{display:flex;flex-direction:column}
/**
* 优艺家沙发翻新 - 全局样式变量
*/
/* ========== 项目主题色 ========== */
/* 辅助色 */
/* 文字颜色 */
/* 背景色 */
/* 边框颜色 */
/* 间距 */
/* 圆角 */
/* 阴影 */
/* ========== uni-app 内置变量 ========== */
/* 行为相关颜色 */
/* 文字基本颜色 */
/* 背景颜色 */
/* 边框颜色 */
/* 尺寸变量 */
/* 文字尺寸 */
/* 图片尺寸 */
/* Border Radius */
/* 水平间距 */
/* 垂直间距 */
/* 透明度 */
/* 文章场景相关 */
.before-after {
background-color: #ffffff;
border-radius: 16rpx;
padding: 24rpx;
margin-bottom: 24rpx;
}
.ba-title {
margin-bottom: 24rpx;
}
.ba-title-text {
font-size: 32rpx;
font-weight: 600;
color: #333333;
}
.ba-container {
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.ba-item {
flex: 1;
position: relative;
border-radius: 12rpx;
overflow: hidden;
}
.ba-image {
width: 100%;
height: 280rpx;
border-radius: 12rpx;
}
.ba-label {
position: absolute;
bottom: 16rpx;
left: 16rpx;
padding: 8rpx 16rpx;
border-radius: 8rpx;
z-index: 1;
}
.before-label {
background-color: rgba(144, 147, 153, 0.9);
}
.after-label {
background-color: rgba(212, 165, 116, 0.9);
}
.ba-label-text {
font-size: 22rpx;
color: #ffffff;
}
.ba-arrow {
padding: 0 16rpx;
}
.ba-arrow-text {
font-size: 40rpx;
color: #D4A574;
font-weight: bold;
}

View File

@@ -0,0 +1,72 @@
"use strict";
const common_vendor = require("../../common/vendor.js");
class CaseItem extends UTS.UTSType {
static get$UTSMetadata$() {
return {
kind: 2,
get fields() {
return {
id: { type: String, optional: false },
title: { type: String, optional: false },
category: { type: String, optional: false },
categoryName: { type: String, optional: false },
coverImage: { type: String, optional: false },
material: { type: String, optional: false },
duration: { type: String, optional: false },
price: { type: String, optional: false },
views: { type: Number, optional: false },
likes: { type: Number, optional: false }
};
},
name: "CaseItem"
};
}
constructor(options, metadata = CaseItem.get$UTSMetadata$(), isJSONParse = false) {
super();
this.__props__ = UTS.UTSType.initProps(options, metadata, isJSONParse);
this.id = this.__props__.id;
this.title = this.__props__.title;
this.category = this.__props__.category;
this.categoryName = this.__props__.categoryName;
this.coverImage = this.__props__.coverImage;
this.material = this.__props__.material;
this.duration = this.__props__.duration;
this.price = this.__props__.price;
this.views = this.__props__.views;
this.likes = this.__props__.likes;
delete this.__props__;
}
}
const _sfc_main = /* @__PURE__ */ common_vendor.defineComponent({
__name: "case-card",
props: {
caseData: {}
},
emits: ["click"],
setup(__props, _a) {
var __emit = _a.emit;
const props = __props;
const emit = __emit;
const handleClick = () => {
emit("click", props.caseData.id);
};
return (_ctx, _cache) => {
"raw js";
const __returned__ = {
a: _ctx.caseData.coverImage,
b: common_vendor.t(_ctx.caseData.categoryName),
c: common_vendor.t(_ctx.caseData.title),
d: common_vendor.t(_ctx.caseData.material),
e: common_vendor.t(_ctx.caseData.duration),
f: common_vendor.t(_ctx.caseData.price),
g: common_vendor.t(_ctx.caseData.views),
h: common_vendor.t(_ctx.caseData.likes),
i: common_vendor.sei(common_vendor.gei(_ctx, ""), "view"),
j: common_vendor.o(handleClick)
};
return __returned__;
};
}
});
wx.createComponent(_sfc_main);
//# sourceMappingURL=../../../.sourcemap/mp-weixin/components/case-card/case-card.js.map

View File

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

View File

@@ -0,0 +1 @@
<view bindtap="{{j}}" id="{{i}}" change:eS="{{uV.sS}}" eS="{{$eS[i]}}" change:eA="{{uV.sA}}" eA="{{$eA[i]}}" class="{{['case-card', virtualHostClass]}}" style="{{virtualHostStyle}}" hidden="{{virtualHostHidden || false}}"><view class="card-image-wrapper"><image class="card-image" src="{{a}}" mode="aspectFill"></image><view class="card-category">{{b}}</view></view><view class="card-content"><text class="card-title">{{c}}</text><view class="card-info"><view class="info-item"><text class="info-label">材质:</text><text class="info-value">{{d}}</text></view><view class="info-item"><text class="info-label">工期:</text><text class="info-value">{{e}}</text></view></view><view class="card-footer"><text class="card-price">{{f}}</text><view class="card-stats"><text class="stat-item">👁 {{g}}</text><text class="stat-item">❤ {{h}}</text></view></view></view></view><wxs src="/common/uniView.wxs" module="uV"/>

View File

@@ -0,0 +1,100 @@
:host{display:flex;flex-direction:column}
/**
* 优艺家沙发翻新 - 全局样式变量
*/
/* ========== 项目主题色 ========== */
/* 辅助色 */
/* 文字颜色 */
/* 背景色 */
/* 边框颜色 */
/* 间距 */
/* 圆角 */
/* 阴影 */
/* ========== uni-app 内置变量 ========== */
/* 行为相关颜色 */
/* 文字基本颜色 */
/* 背景颜色 */
/* 边框颜色 */
/* 尺寸变量 */
/* 文字尺寸 */
/* 图片尺寸 */
/* Border Radius */
/* 水平间距 */
/* 垂直间距 */
/* 透明度 */
/* 文章场景相关 */
.case-card {
background-color: #ffffff;
border-radius: 16rpx;
overflow: hidden;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
margin-bottom: 24rpx;
}
.card-image-wrapper {
position: relative;
width: 100%;
height: 360rpx;
}
.card-image {
width: 100%;
height: 100%;
}
.card-category {
position: absolute;
top: 16rpx;
left: 16rpx;
background-color: rgba(212, 165, 116, 0.9);
color: #ffffff;
font-size: 22rpx;
padding: 8rpx 16rpx;
border-radius: 8rpx;
}
.card-content {
padding: 24rpx;
}
.card-title {
font-size: 32rpx;
font-weight: 600;
color: #333333;
margin-bottom: 16rpx;
lines: 1;
text-overflow: ellipsis;
}
.card-info {
margin-bottom: 16rpx;
}
.info-item {
flex-direction: row;
margin-bottom: 8rpx;
}
.info-label {
font-size: 26rpx;
color: #909399;
}
.info-value {
font-size: 26rpx;
color: #606266;
}
.card-footer {
flex-direction: row;
justify-content: space-between;
align-items: center;
margin-top: 16rpx;
padding-top: 16rpx;
border-top-width: 1rpx;
border-top-style: solid;
border-top-color: #EBEEF5;
}
.card-price {
font-size: 36rpx;
font-weight: 600;
color: #D4A574;
}
.card-stats {
flex-direction: row;
}
.stat-item {
font-size: 24rpx;
color: #909399;
margin-left: 24rpx;
}

View File

@@ -0,0 +1,47 @@
"use strict";
const common_vendor = require("../../common/vendor.js");
const _sfc_main = /* @__PURE__ */ common_vendor.defineComponent({
__name: "nav-bar",
props: {
title: {},
showBack: { type: Boolean },
titleColor: {},
bgColor: {}
},
setup(__props) {
const statusBarHeight = common_vendor.ref(20);
const navBarHeight = common_vendor.ref(44);
common_vendor.onMounted(() => {
const sysInfo = common_vendor.index.getSystemInfoSync();
statusBarHeight.value = sysInfo.statusBarHeight;
const menuButtonInfo = common_vendor.index.getMenuButtonBoundingClientRect();
navBarHeight.value = (menuButtonInfo.top - sysInfo.statusBarHeight) * 2 + menuButtonInfo.height;
});
const handleBack = () => {
common_vendor.index.navigateBack(new UTSJSONObject({
fail: () => {
common_vendor.index.switchTab({
url: "/pages/index/index"
});
}
}));
};
return (_ctx, _cache) => {
"raw js";
const __returned__ = common_vendor.e({
a: _ctx.showBack
}, _ctx.showBack ? {
b: common_vendor.o(handleBack)
} : {}, {
c: common_vendor.t(_ctx.title),
d: _ctx.titleColor,
e: common_vendor.unref(navBarHeight) + "px",
f: common_vendor.unref(statusBarHeight) + "px",
g: common_vendor.unref(statusBarHeight) + common_vendor.unref(navBarHeight) + "px"
});
return __returned__;
};
}
});
wx.createComponent(_sfc_main);
//# sourceMappingURL=../../../.sourcemap/mp-weixin/components/nav-bar/nav-bar.js.map

View File

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

View File

@@ -0,0 +1 @@
<view class="nav-bar" style="{{'padding-top:' + f}}"><view class="nav-content" style="{{'height:' + e}}"><view wx:if="{{a}}" class="nav-left" bindtap="{{b}}"><text class="nav-back-icon">←</text></view><view wx:else class="nav-left"></view><view class="nav-center"><text class="nav-title" style="{{'color:' + d}}">{{c}}</text></view><view class="nav-right"><slot name="right"></slot></view></view></view><view style="{{'height:' + g}}"></view>

View File

@@ -0,0 +1,64 @@
:host{display:flex;flex-direction:column}
/**
* 优艺家沙发翻新 - 全局样式变量
*/
/* ========== 项目主题色 ========== */
/* 辅助色 */
/* 文字颜色 */
/* 背景色 */
/* 边框颜色 */
/* 间距 */
/* 圆角 */
/* 阴影 */
/* ========== uni-app 内置变量 ========== */
/* 行为相关颜色 */
/* 文字基本颜色 */
/* 背景颜色 */
/* 边框颜色 */
/* 尺寸变量 */
/* 文字尺寸 */
/* 图片尺寸 */
/* Border Radius */
/* 水平间距 */
/* 垂直间距 */
/* 透明度 */
/* 文章场景相关 */
.nav-bar {
position: fixed;
top: 0;
left: 0;
right: 0;
background-color: #ffffff;
z-index: 999;
}
.nav-content {
flex-direction: row;
align-items: center;
justify-content: space-between;
padding: 0 24rpx;
}
.nav-left {
width: 80rpx;
flex-direction: row;
align-items: center;
}
.nav-back-icon {
font-size: 40rpx;
color: #333333;
}
.nav-center {
flex: 1;
align-items: center;
justify-content: center;
}
.nav-title {
font-size: 34rpx;
font-weight: 600;
color: #333333;
}
.nav-right {
width: 80rpx;
flex-direction: row;
align-items: center;
justify-content: flex-end;
}

View File

@@ -0,0 +1,31 @@
"use strict";
const common_vendor = require("../../common/vendor.js");
const _sfc_main = /* @__PURE__ */ common_vendor.defineComponent({
__name: "section-header",
props: {
title: {},
showMore: { type: Boolean }
},
emits: ["more"],
setup(__props, _a) {
var __emit = _a.emit;
const emit = __emit;
const handleMore = () => {
emit("more");
};
return (_ctx, _cache) => {
"raw js";
const __returned__ = common_vendor.e({
a: common_vendor.t(_ctx.title),
b: _ctx.showMore
}, _ctx.showMore ? {
c: common_vendor.o(handleMore)
} : {}, {
d: common_vendor.sei(common_vendor.gei(_ctx, ""), "view")
});
return __returned__;
};
}
});
wx.createComponent(_sfc_main);
//# sourceMappingURL=../../../.sourcemap/mp-weixin/components/section-header/section-header.js.map

View File

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

View File

@@ -0,0 +1 @@
<view id="{{d}}" change:eS="{{uV.sS}}" eS="{{$eS[d]}}" change:eA="{{uV.sA}}" eA="{{$eA[d]}}" class="{{['section-header', virtualHostClass]}}" style="{{virtualHostStyle}}" hidden="{{virtualHostHidden || false}}"><view class="section-left"><view class="section-line"></view><text class="section-title">{{a}}</text></view><view wx:if="{{b}}" class="section-right" bindtap="{{c}}"><text class="section-more">查看更多</text><text class="section-arrow"></text></view></view><wxs src="/common/uniView.wxs" module="uV"/>

View File

@@ -0,0 +1,60 @@
:host{display:flex;flex-direction:column}
/**
* 优艺家沙发翻新 - 全局样式变量
*/
/* ========== 项目主题色 ========== */
/* 辅助色 */
/* 文字颜色 */
/* 背景色 */
/* 边框颜色 */
/* 间距 */
/* 圆角 */
/* 阴影 */
/* ========== uni-app 内置变量 ========== */
/* 行为相关颜色 */
/* 文字基本颜色 */
/* 背景颜色 */
/* 边框颜色 */
/* 尺寸变量 */
/* 文字尺寸 */
/* 图片尺寸 */
/* Border Radius */
/* 水平间距 */
/* 垂直间距 */
/* 透明度 */
/* 文章场景相关 */
.section-header {
flex-direction: row;
align-items: center;
justify-content: space-between;
padding: 32rpx 0 24rpx 0;
}
.section-left {
flex-direction: row;
align-items: center;
}
.section-line {
width: 8rpx;
height: 36rpx;
background-color: #D4A574;
border-radius: 4rpx;
margin-right: 16rpx;
}
.section-title {
font-size: 34rpx;
font-weight: 600;
color: #333333;
}
.section-right {
flex-direction: row;
align-items: center;
}
.section-more {
font-size: 26rpx;
color: #909399;
}
.section-arrow {
font-size: 32rpx;
color: #909399;
margin-left: 8rpx;
}

View File

@@ -0,0 +1,31 @@
"use strict";
const common_vendor = require("../../common/vendor.js");
const _sfc_main = /* @__PURE__ */ common_vendor.defineComponent({
__name: "service-card",
props: {
id: {},
name: {},
icon: {}
},
emits: ["click"],
setup(__props, _a) {
var __emit = _a.emit;
const props = __props;
const emit = __emit;
const handleClick = () => {
emit("click", props.id);
};
return (_ctx, _cache) => {
"raw js";
const __returned__ = {
a: _ctx.icon,
b: common_vendor.t(_ctx.name),
c: common_vendor.sei(common_vendor.gei(_ctx, ""), "view"),
d: common_vendor.o(handleClick)
};
return __returned__;
};
}
});
wx.createComponent(_sfc_main);
//# sourceMappingURL=../../../.sourcemap/mp-weixin/components/service-card/service-card.js.map

View File

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

View File

@@ -0,0 +1 @@
<view bindtap="{{d}}" id="{{c}}" change:eS="{{uV.sS}}" eS="{{$eS[c]}}" change:eA="{{uV.sA}}" eA="{{$eA[c]}}" class="{{['service-card', virtualHostClass]}}" style="{{virtualHostStyle}}" hidden="{{virtualHostHidden || false}}"><view class="service-icon-wrapper"><image class="service-icon" src="{{a}}" mode="aspectFit"></image></view><text class="service-name">{{b}}</text></view><wxs src="/common/uniView.wxs" module="uV"/>

View File

@@ -0,0 +1,51 @@
:host{display:flex;flex-direction:column}
/**
* 优艺家沙发翻新 - 全局样式变量
*/
/* ========== 项目主题色 ========== */
/* 辅助色 */
/* 文字颜色 */
/* 背景色 */
/* 边框颜色 */
/* 间距 */
/* 圆角 */
/* 阴影 */
/* ========== uni-app 内置变量 ========== */
/* 行为相关颜色 */
/* 文字基本颜色 */
/* 背景颜色 */
/* 边框颜色 */
/* 尺寸变量 */
/* 文字尺寸 */
/* 图片尺寸 */
/* Border Radius */
/* 水平间距 */
/* 垂直间距 */
/* 透明度 */
/* 文章场景相关 */
.service-card {
align-items: center;
justify-content: center;
padding: 24rpx 16rpx;
background-color: #ffffff;
border-radius: 16rpx;
width: 160rpx;
}
.service-icon-wrapper {
width: 80rpx;
height: 80rpx;
background-color: #FDF6EE;
border-radius: 50%;
align-items: center;
justify-content: center;
margin-bottom: 16rpx;
}
.service-icon {
width: 48rpx;
height: 48rpx;
}
.service-name {
font-size: 26rpx;
color: #333333;
text-align: center;
}

View File

@@ -0,0 +1,181 @@
"use strict";
const common_vendor = require("../../common/vendor.js");
const api_index = require("../../api/index.js");
if (!Array) {
const _easycom_section_header_1 = common_vendor.resolveComponent("section-header");
_easycom_section_header_1();
}
const _easycom_section_header = () => "../../components/section-header/section-header.js";
if (!Math) {
_easycom_section_header();
}
class FeatureItem extends UTS.UTSType {
static get$UTSMetadata$() {
return {
kind: 2,
get fields() {
return {
title: { type: String, optional: false },
desc: { type: String, optional: false }
};
},
name: "FeatureItem"
};
}
constructor(options, metadata = FeatureItem.get$UTSMetadata$(), isJSONParse = false) {
super();
this.__props__ = UTS.UTSType.initProps(options, metadata, isJSONParse);
this.title = this.__props__.title;
this.desc = this.__props__.desc;
delete this.__props__;
}
}
class CompanyInfo extends UTS.UTSType {
static get$UTSMetadata$() {
return {
kind: 2,
get fields() {
return {
name: { type: String, optional: false },
slogan: { type: String, optional: false },
description: { type: String, optional: false },
phone: { type: String, optional: false },
wechat: { type: String, optional: false },
address: { type: String, optional: false },
workTime: { type: String, optional: false },
features: { type: UTS.UTSType.withGenerics(Array, [FeatureItem]), optional: false }
};
},
name: "CompanyInfo"
};
}
constructor(options, metadata = CompanyInfo.get$UTSMetadata$(), isJSONParse = false) {
super();
this.__props__ = UTS.UTSType.initProps(options, metadata, isJSONParse);
this.name = this.__props__.name;
this.slogan = this.__props__.slogan;
this.description = this.__props__.description;
this.phone = this.__props__.phone;
this.wechat = this.__props__.wechat;
this.address = this.__props__.address;
this.workTime = this.__props__.workTime;
this.features = this.__props__.features;
delete this.__props__;
}
}
const _sfc_main = /* @__PURE__ */ common_vendor.defineComponent({
__name: "index",
setup(__props) {
const companyInfo = common_vendor.ref(new CompanyInfo({
name: "优艺家沙发翻新",
slogan: "让旧沙发焕发新生",
description: "",
phone: "400-888-8888",
wechat: "youyijia2026",
address: "",
workTime: "",
features: []
}));
const fetchCompanyInfo = () => {
return common_vendor.__awaiter(this, void 0, void 0, function* () {
try {
const res = yield api_index.getCompanyInfo();
const data = res.data;
const featuresData = data["features"];
const features = featuresData.map((item) => {
return new FeatureItem({
title: item["title"],
desc: item["desc"]
});
});
companyInfo.value = new CompanyInfo({
name: data["name"],
slogan: data["slogan"],
description: data["description"],
phone: data["phone"],
wechat: data["wechat"],
address: data["address"],
workTime: data["workTime"],
features
});
} catch (e) {
common_vendor.index.__f__("error", "at pages/about/index.uvue:148", "获取公司信息失败", e);
}
});
};
const callPhone = () => {
common_vendor.index.makePhoneCall({
phoneNumber: companyInfo.value.phone,
fail: () => {
common_vendor.index.showToast({
title: "拨打电话失败",
icon: "none"
});
}
});
};
const copyWechat = () => {
common_vendor.index.setClipboardData({
data: companyInfo.value.wechat,
success: () => {
common_vendor.index.showToast({
title: "微信号已复制",
icon: "success"
});
}
});
};
const openLocation = () => {
common_vendor.index.openLocation({
latitude: 31.2,
longitude: 121.5,
name: companyInfo.value.name,
address: companyInfo.value.address,
fail: () => {
common_vendor.index.showToast({
title: "无法打开地图",
icon: "none"
});
}
});
};
common_vendor.onLoad(() => {
fetchCompanyInfo();
});
return (_ctx, _cache) => {
"raw js";
const __returned__ = {
a: common_vendor.t(common_vendor.unref(companyInfo).name),
b: common_vendor.t(common_vendor.unref(companyInfo).slogan),
c: common_vendor.p({
title: "公司简介"
}),
d: common_vendor.t(common_vendor.unref(companyInfo).description),
e: common_vendor.p({
title: "我们的优势"
}),
f: common_vendor.f(common_vendor.unref(companyInfo).features, (item, k0, i0) => {
return {
a: common_vendor.t(item.title),
b: common_vendor.t(item.desc),
c: item.title
};
}),
g: common_vendor.p({
title: "联系我们"
}),
h: common_vendor.t(common_vendor.unref(companyInfo).phone),
i: common_vendor.o(callPhone),
j: common_vendor.t(common_vendor.unref(companyInfo).wechat),
k: common_vendor.o(copyWechat),
l: common_vendor.t(common_vendor.unref(companyInfo).address),
m: common_vendor.o(openLocation),
n: common_vendor.t(common_vendor.unref(companyInfo).workTime),
o: common_vendor.sei(common_vendor.gei(_ctx, ""), "view")
};
return __returned__;
};
}
});
wx.createPage(_sfc_main);
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/about/index.js.map

View File

@@ -0,0 +1,6 @@
{
"navigationBarTitleText": "关于我们",
"usingComponents": {
"section-header": "../../components/section-header/section-header"
}
}

View File

@@ -0,0 +1 @@
<view id="{{o}}" change:eS="{{uV.sS}}" eS="{{$eS[o]}}" change:eA="{{uV.sA}}" eA="{{$eA[o]}}" class="{{['page', virtualHostClass]}}" style="{{virtualHostStyle}}" hidden="{{virtualHostHidden || false}}"><scroll-view class="page-scroll" scroll-y enable-flex="true" enhanced="true"><view class="header-section"><view class="company-logo"><text class="logo-text">优艺家</text></view><text class="company-name">{{a}}</text><text class="company-slogan">{{b}}</text></view><view class="section"><section-header u-i="00470dc0-0" bind:__l="__l" u-p="{{c||''}}"></section-header><view class="intro-card"><text class="intro-text">{{d}}</text></view></view><view class="section"><section-header u-i="00470dc0-1" bind:__l="__l" u-p="{{e||''}}"></section-header><view class="features-grid"><view wx:for="{{f}}" wx:for-item="item" wx:key="c" class="feature-item"><view class="feature-icon-bg"><text class="feature-icon">✓</text></view><text class="feature-title">{{item.a}}</text><text class="feature-desc">{{item.b}}</text></view></view></view><view class="section"><section-header u-i="00470dc0-2" bind:__l="__l" u-p="{{g||''}}"></section-header><view class="contact-card"><view class="contact-item" bindtap="{{i}}"><view class="contact-icon-bg"><text class="contact-icon">📞</text></view><view class="contact-info"><text class="contact-label">客服电话</text><text class="contact-value">{{h}}</text></view><text class="contact-arrow"></text></view><view class="contact-item" bindtap="{{k}}"><view class="contact-icon-bg"><text class="contact-icon">💬</text></view><view class="contact-info"><text class="contact-label">微信号</text><text class="contact-value">{{j}}</text></view><text class="contact-arrow"></text></view><view class="contact-item" bindtap="{{m}}"><view class="contact-icon-bg"><text class="contact-icon">📍</text></view><view class="contact-info"><text class="contact-label">公司地址</text><text class="contact-value">{{l}}</text></view><text class="contact-arrow"></text></view><view class="contact-item"><view class="contact-icon-bg"><text class="contact-icon">🕐</text></view><view class="contact-info"><text class="contact-label">营业时间</text><text class="contact-value">{{n}}</text></view></view></view></view><view class="bottom-space"></view></scroll-view></view><wxs src="/common/uniView.wxs" module="uV"/>

View File

@@ -0,0 +1,169 @@
@import "../../uvue.wxss";
:host{display:flex;flex-direction:column}
/**
* 优艺家沙发翻新 - 全局样式变量
*/
/* ========== 项目主题色 ========== */
/* 辅助色 */
/* 文字颜色 */
/* 背景色 */
/* 边框颜色 */
/* 间距 */
/* 圆角 */
/* 阴影 */
/* ========== uni-app 内置变量 ========== */
/* 行为相关颜色 */
/* 文字基本颜色 */
/* 背景颜色 */
/* 边框颜色 */
/* 尺寸变量 */
/* 文字尺寸 */
/* 图片尺寸 */
/* Border Radius */
/* 水平间距 */
/* 垂直间距 */
/* 透明度 */
/* 文章场景相关 */
.page {
flex: 1;
background-color: #f5f5f5;
}
.page-scroll {
flex: 1;
}
/* 头部区域 */
.header-section {
background: linear-gradient(135deg, #D4A574 0%, #B8895A 100%);
padding: 60rpx 32rpx;
align-items: center;
}
.company-logo {
width: 140rpx;
height: 140rpx;
background-color: #ffffff;
border-radius: 50%;
align-items: center;
justify-content: center;
margin-bottom: 24rpx;
}
.logo-text {
font-size: 36rpx;
font-weight: 600;
color: #D4A574;
}
.company-name {
font-size: 40rpx;
font-weight: 600;
color: #ffffff;
margin-bottom: 12rpx;
}
.company-slogan {
font-size: 28rpx;
color: rgba(255, 255, 255, 0.8);
}
/* 通用section */
.section {
padding: 0 24rpx;
margin-bottom: 24rpx;
}
/* 公司介绍 */
.intro-card {
background-color: #ffffff;
border-radius: 16rpx;
padding: 32rpx;
}
.intro-text {
font-size: 28rpx;
color: #606266;
line-height: 48rpx;
}
/* 优势 */
.features-grid {
flex-direction: row;
flex-wrap: wrap;
background-color: #ffffff;
border-radius: 16rpx;
padding: 16rpx;
}
.feature-item {
width: 50%;
padding: 24rpx;
align-items: center;
}
.feature-icon-bg {
width: 80rpx;
height: 80rpx;
background-color: #D4A574;
border-radius: 50%;
align-items: center;
justify-content: center;
margin-bottom: 16rpx;
}
.feature-icon {
font-size: 40rpx;
color: #ffffff;
}
.feature-title {
font-size: 30rpx;
font-weight: 600;
color: #333333;
margin-bottom: 8rpx;
}
.feature-desc {
font-size: 24rpx;
color: #909399;
}
/* 联系方式 */
.contact-card {
background-color: #ffffff;
border-radius: 16rpx;
}
.contact-item {
flex-direction: row;
align-items: center;
padding: 32rpx;
border-bottom-width: 1rpx;
border-bottom-style: solid;
border-bottom-color: #EBEEF5;
}
.contact-item:last-child {
border-bottom-width: 0;
}
.contact-icon-bg {
width: 72rpx;
height: 72rpx;
background-color: #FDF6EE;
border-radius: 50%;
align-items: center;
justify-content: center;
margin-right: 24rpx;
}
.contact-icon {
font-size: 36rpx;
}
.contact-info {
flex: 1;
}
.contact-label {
font-size: 24rpx;
color: #909399;
margin-bottom: 8rpx;
}
.contact-value {
font-size: 30rpx;
color: #333333;
}
.contact-arrow {
font-size: 36rpx;
color: #909399;
}
/* 底部间距 */
.bottom-space {
height: 60rpx;
}

View File

@@ -0,0 +1,221 @@
"use strict";
const common_vendor = require("../../common/vendor.js");
const api_index = require("../../api/index.js");
const utils_config = require("../../utils/config.js");
class FormData extends UTS.UTSType {
static get$UTSMetadata$() {
return {
kind: 2,
get fields() {
return {
userName: { type: String, optional: false },
phone: { type: String, optional: false },
address: { type: String, optional: false },
sofaType: { type: String, optional: false },
problem: { type: String, optional: false }
};
},
name: "FormData"
};
}
constructor(options, metadata = FormData.get$UTSMetadata$(), isJSONParse = false) {
super();
this.__props__ = UTS.UTSType.initProps(options, metadata, isJSONParse);
this.userName = this.__props__.userName;
this.phone = this.__props__.phone;
this.address = this.__props__.address;
this.sofaType = this.__props__.sofaType;
this.problem = this.__props__.problem;
delete this.__props__;
}
}
class SofaType extends UTS.UTSType {
static get$UTSMetadata$() {
return {
kind: 2,
get fields() {
return {
id: { type: String, optional: false },
name: { type: String, optional: false }
};
},
name: "SofaType"
};
}
constructor(options, metadata = SofaType.get$UTSMetadata$(), isJSONParse = false) {
super();
this.__props__ = UTS.UTSType.initProps(options, metadata, isJSONParse);
this.id = this.__props__.id;
this.name = this.__props__.name;
delete this.__props__;
}
}
const _sfc_main = /* @__PURE__ */ common_vendor.defineComponent({
__name: "index",
setup(__props) {
const formData = common_vendor.ref(new FormData({
userName: "",
phone: "",
address: "",
sofaType: "",
problem: ""
}));
const imageList = common_vendor.ref([]);
const sofaTypes = common_vendor.ref([]);
const submitting = common_vendor.ref(false);
const initSofaTypes = () => {
sofaTypes.value = utils_config.SOFA_CATEGORIES.filter((item) => {
return item.id != "all";
}).map((item) => {
return new SofaType({
id: item.id,
name: item.name
});
});
};
const selectSofaType = (id) => {
formData.value.sofaType = id;
};
const chooseImage = () => {
common_vendor.index.chooseImage(new UTSJSONObject({
count: 9 - imageList.value.length,
sizeType: ["compressed"],
sourceType: ["album", "camera"],
success: (res) => {
imageList.value = [...imageList.value, ...res.tempFilePaths];
}
}));
};
const deleteImage = (index) => {
imageList.value.splice(index, 1);
};
const validateForm = () => {
if (formData.value.userName.trim() == "") {
common_vendor.index.showToast({
title: "请输入您的姓名",
icon: "none"
});
return false;
}
const phone = formData.value.phone.trim();
if (phone == "") {
common_vendor.index.showToast({
title: "请输入联系电话",
icon: "none"
});
return false;
}
if (phone.length != 11) {
common_vendor.index.showToast({
title: "请输入正确的手机号",
icon: "none"
});
return false;
}
if (formData.value.address.trim() == "") {
common_vendor.index.showToast({
title: "请输入您的地址",
icon: "none"
});
return false;
}
return true;
};
const handleSubmit = () => {
return common_vendor.__awaiter(this, void 0, void 0, function* () {
if (!validateForm())
return Promise.resolve(null);
if (submitting.value)
return Promise.resolve(null);
submitting.value = true;
try {
const data = new UTSJSONObject({
userName: formData.value.userName,
phone: formData.value.phone,
address: formData.value.address,
sofaType: formData.value.sofaType,
problem: formData.value.problem,
images: imageList.value
});
const res = yield api_index.submitBooking(data);
const result = res.data;
common_vendor.index.showModal(new UTSJSONObject({
title: "预约成功",
content: result["message"],
showCancel: false,
success: () => {
common_vendor.index.navigateBack(new UTSJSONObject({
fail: () => {
common_vendor.index.switchTab({
url: "/pages/index/index"
});
}
}));
}
}));
} catch (e) {
common_vendor.index.__f__("error", "at pages/booking/index.uvue:270", "提交预约失败", e);
common_vendor.index.showToast({
title: "提交失败,请重试",
icon: "none"
});
}
submitting.value = false;
});
};
common_vendor.onLoad(() => {
initSofaTypes();
});
return (_ctx, _cache) => {
"raw js";
const __returned__ = common_vendor.e({
a: common_vendor.unref(formData).userName,
b: common_vendor.o(($event) => {
return common_vendor.unref(formData).userName = $event.detail.value;
}),
c: common_vendor.unref(formData).phone,
d: common_vendor.o(($event) => {
return common_vendor.unref(formData).phone = $event.detail.value;
}),
e: common_vendor.unref(formData).address,
f: common_vendor.o(($event) => {
return common_vendor.unref(formData).address = $event.detail.value;
}),
g: common_vendor.f(common_vendor.unref(sofaTypes), (item, k0, i0) => {
return {
a: common_vendor.t(item.name),
b: common_vendor.unref(formData).sofaType == item.id ? 1 : "",
c: common_vendor.unref(formData).sofaType == item.id ? 1 : "",
d: item.id,
e: common_vendor.o(($event) => {
return selectSofaType(item.id);
}, item.id)
};
}),
h: common_vendor.unref(formData).problem,
i: common_vendor.o(($event) => {
return common_vendor.unref(formData).problem = $event.detail.value;
}),
j: common_vendor.t(common_vendor.unref(formData).problem.length),
k: common_vendor.f(common_vendor.unref(imageList), (item, index, i0) => {
return {
a: item,
b: common_vendor.o(($event) => {
return deleteImage(index);
}, index),
c: index
};
}),
l: common_vendor.unref(imageList).length < 9
}, common_vendor.unref(imageList).length < 9 ? {
m: common_vendor.o(chooseImage)
} : {}, {
n: common_vendor.o(handleSubmit),
o: common_vendor.sei(common_vendor.gei(_ctx, ""), "view")
});
return __returned__;
};
}
});
wx.createPage(_sfc_main);
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/booking/index.js.map

View File

@@ -0,0 +1,4 @@
{
"navigationBarTitleText": "预约咨询",
"usingComponents": {}
}

View File

@@ -0,0 +1 @@
<view id="{{o}}" change:eS="{{uV.sS}}" eS="{{$eS[o]}}" change:eA="{{uV.sA}}" eA="{{$eA[o]}}" class="{{['page', virtualHostClass]}}" style="{{virtualHostStyle}}" hidden="{{virtualHostHidden || false}}"><scroll-view class="page-scroll" scroll-y enable-flex="true" enhanced="true"><view class="header-section"><text class="header-title">预约翻新服务</text><text class="header-desc">填写以下信息,我们会尽快与您联系</text></view><view class="form-section"><view class="form-item"><text class="form-label"><text class="required">*</text> 您的姓名 </text><input class="form-input" type="text" placeholder="请输入您的姓名" placeholder-class="placeholder" value="{{a}}" bindinput="{{b}}"/></view><view class="form-item"><text class="form-label"><text class="required">*</text> 联系电话 </text><input class="form-input" type="number" placeholder="请输入您的手机号" placeholder-class="placeholder" maxlength="11" value="{{c}}" bindinput="{{d}}"/></view><view class="form-item"><text class="form-label"><text class="required">*</text> 您的地址 </text><input class="form-input" type="text" placeholder="请输入详细地址" placeholder-class="placeholder" value="{{e}}" bindinput="{{f}}"/></view><view class="form-item"><text class="form-label">沙发类型</text><view class="type-grid"><view wx:for="{{g}}" wx:for-item="item" wx:key="d" class="{{['type-item', item.c && 'type-active']}}" bindtap="{{item.e}}"><text class="{{['type-text', item.b && 'type-text-active']}}">{{item.a}}</text></view></view></view><view class="form-item"><text class="form-label">问题描述</text><block wx:if="{{r0}}"><textarea class="form-textarea" placeholder="请描述沙发的问题(如:皮面开裂、褪色、塌陷等)" placeholder-class="placeholder" maxlength="500" value="{{h}}" bindinput="{{i}}"></textarea></block><text class="textarea-count">{{j}}/500</text></view><view class="form-item"><text class="form-label">上传图片(可选)</text><view class="upload-grid"><view wx:for="{{k}}" wx:for-item="item" wx:key="c" class="upload-item"><image class="upload-image" src="{{item.a}}" mode="aspectFill"></image><view class="upload-delete" bindtap="{{item.b}}"><text class="delete-icon">×</text></view></view><view wx:if="{{l}}" class="upload-add" bindtap="{{m}}"><text class="add-icon">+</text><text class="add-text">添加图片</text></view></view><text class="upload-tip">最多可上传9张图片</text></view></view><view class="bottom-space"></view></scroll-view><view class="submit-bar"><view class="submit-btn" bindtap="{{n}}"><text class="submit-text">提交预约</text></view></view></view><wxs src="/common/uniView.wxs" module="uV"/>

View File

@@ -0,0 +1,206 @@
@import "../../uvue.wxss";
:host{display:flex;flex-direction:column}
/**
* 优艺家沙发翻新 - 全局样式变量
*/
/* ========== 项目主题色 ========== */
/* 辅助色 */
/* 文字颜色 */
/* 背景色 */
/* 边框颜色 */
/* 间距 */
/* 圆角 */
/* 阴影 */
/* ========== uni-app 内置变量 ========== */
/* 行为相关颜色 */
/* 文字基本颜色 */
/* 背景颜色 */
/* 边框颜色 */
/* 尺寸变量 */
/* 文字尺寸 */
/* 图片尺寸 */
/* Border Radius */
/* 水平间距 */
/* 垂直间距 */
/* 透明度 */
/* 文章场景相关 */
.page {
flex: 1;
background-color: #f5f5f5;
}
.page-scroll {
flex: 1;
}
/* 头部 */
.header-section {
background: linear-gradient(135deg, #D4A574 0%, #B8895A 100%);
padding: 48rpx 32rpx;
align-items: center;
}
.header-title {
font-size: 40rpx;
font-weight: 600;
color: #ffffff;
margin-bottom: 12rpx;
}
.header-desc {
font-size: 28rpx;
color: rgba(255, 255, 255, 0.8);
}
/* 表单区域 */
.form-section {
background-color: #ffffff;
margin: 24rpx;
border-radius: 16rpx;
padding: 32rpx;
}
.form-item {
margin-bottom: 32rpx;
}
.form-label {
font-size: 28rpx;
font-weight: 600;
color: #333333;
margin-bottom: 16rpx;
}
.required {
color: #F56C6C;
margin-right: 4rpx;
}
.form-input {
background-color: #f5f5f5;
border-radius: 12rpx;
padding: 24rpx;
font-size: 28rpx;
height: 40px;
}
.placeholder {
color: #C0C4CC;
}
/* 沙发类型选择 */
.type-grid {
flex-direction: row;
flex-wrap: wrap;
}
.type-item {
padding: 16rpx 32rpx;
background-color: #f5f5f5;
border-radius: 8rpx;
margin-right: 16rpx;
margin-bottom: 16rpx;
}
.type-active {
background-color: #D4A574;
}
.type-text {
font-size: 26rpx;
color: #606266;
}
.type-text-active {
color: #ffffff;
}
/* 文本域 */
.form-textarea {
background-color: #f5f5f5;
border-radius: 12rpx;
padding: 24rpx;
font-size: 28rpx;
height: 200rpx;
width: 100%;
}
.textarea-count {
font-size: 24rpx;
color: #909399;
text-align: right;
margin-top: 8rpx;
}
/* 图片上传 */
.upload-grid {
flex-direction: row;
flex-wrap: wrap;
}
.upload-item {
width: 200rpx;
height: 200rpx;
margin-right: 16rpx;
margin-bottom: 16rpx;
position: relative;
}
.upload-image {
width: 100%;
height: 100%;
border-radius: 12rpx;
}
.upload-delete {
position: absolute;
top: -16rpx;
right: -16rpx;
width: 40rpx;
height: 40rpx;
background-color: #F56C6C;
border-radius: 50%;
align-items: center;
justify-content: center;
}
.delete-icon {
font-size: 28rpx;
color: #ffffff;
}
.upload-add {
width: 200rpx;
height: 200rpx;
background-color: #f5f5f5;
border-radius: 12rpx;
align-items: center;
justify-content: center;
border-width: 2rpx;
border-style: dashed;
border-color: #DCDFE6;
}
.add-icon {
font-size: 48rpx;
color: #909399;
}
.add-text {
font-size: 24rpx;
color: #909399;
margin-top: 8rpx;
}
.upload-tip {
font-size: 24rpx;
color: #909399;
margin-top: 16rpx;
}
/* 底部间距 */
.bottom-space {
height: 160rpx;
}
/* 提交按钮 */
.submit-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background-color: #ffffff;
padding: 24rpx 32rpx;
padding-bottom: 48rpx;
box-shadow: 0 -4rpx 16rpx rgba(0, 0, 0, 0.08);
}
.submit-btn {
background-color: #D4A574;
border-radius: 999rpx;
padding: 28rpx 0;
align-items: center;
}
.submit-text {
font-size: 32rpx;
font-weight: 600;
color: #ffffff;
}

View File

@@ -0,0 +1,186 @@
"use strict";
const common_vendor = require("../../common/vendor.js");
const api_index = require("../../api/index.js");
if (!Array) {
const _easycom_before_after_1 = common_vendor.resolveComponent("before-after");
_easycom_before_after_1();
}
const _easycom_before_after = () => "../../components/before-after/before-after.js";
if (!Math) {
_easycom_before_after();
}
class CaseDetail extends UTS.UTSType {
static get$UTSMetadata$() {
return {
kind: 2,
get fields() {
return {
id: { type: String, optional: false },
title: { type: String, optional: false },
category: { type: String, optional: false },
categoryName: { type: String, optional: false },
beforeImages: { type: UTS.UTSType.withGenerics(Array, [String]), optional: false },
afterImages: { type: UTS.UTSType.withGenerics(Array, [String]), optional: false },
description: { type: String, optional: false },
material: { type: String, optional: false },
duration: { type: String, optional: false },
price: { type: String, optional: false },
views: { type: Number, optional: false },
likes: { type: Number, optional: false },
createTime: { type: String, optional: false }
};
},
name: "CaseDetail"
};
}
constructor(options, metadata = CaseDetail.get$UTSMetadata$(), isJSONParse = false) {
super();
this.__props__ = UTS.UTSType.initProps(options, metadata, isJSONParse);
this.id = this.__props__.id;
this.title = this.__props__.title;
this.category = this.__props__.category;
this.categoryName = this.__props__.categoryName;
this.beforeImages = this.__props__.beforeImages;
this.afterImages = this.__props__.afterImages;
this.description = this.__props__.description;
this.material = this.__props__.material;
this.duration = this.__props__.duration;
this.price = this.__props__.price;
this.views = this.__props__.views;
this.likes = this.__props__.likes;
this.createTime = this.__props__.createTime;
delete this.__props__;
}
}
const _sfc_main = /* @__PURE__ */ common_vendor.defineComponent({
__name: "detail",
setup(__props) {
const caseId = common_vendor.ref("");
const caseDetail = common_vendor.ref(new CaseDetail({
id: "",
title: "",
category: "",
categoryName: "",
beforeImages: [],
afterImages: [],
description: "",
material: "",
duration: "",
price: "",
views: 0,
likes: 0,
createTime: ""
}));
const isFavorite = common_vendor.ref(false);
const fetchCaseDetail = () => {
return common_vendor.__awaiter(this, void 0, void 0, function* () {
try {
const res = yield api_index.getCaseDetail(caseId.value);
const data = res.data;
caseDetail.value = new CaseDetail(
{
id: data["id"],
title: data["title"],
category: data["category"],
categoryName: data["categoryName"],
beforeImages: data["beforeImages"],
afterImages: data["afterImages"],
description: data["description"],
material: data["material"],
duration: data["duration"],
price: data["price"],
views: data["views"],
likes: data["likes"],
createTime: data["createTime"]
}
// 更新标题
);
common_vendor.index.setNavigationBarTitle({
title: caseDetail.value.title
});
} catch (e) {
common_vendor.index.__f__("error", "at pages/cases/detail.uvue:173", "获取案例详情失败", e);
}
});
};
const previewImages = (index) => {
common_vendor.index.previewImage({
current: index,
urls: caseDetail.value.afterImages
});
};
const handleFavorite = () => {
isFavorite.value = !isFavorite.value;
common_vendor.index.showToast({
title: isFavorite.value ? "已收藏" : "已取消收藏",
icon: "none"
});
};
const handleShare = () => {
common_vendor.index.showToast({
title: "分享功能开发中",
icon: "none"
});
};
const handleContact = () => {
common_vendor.index.makePhoneCall({
phoneNumber: "400-888-8888",
fail: () => {
common_vendor.index.showToast({
title: "拨打电话失败",
icon: "none"
});
}
});
};
const goToBooking = () => {
common_vendor.index.navigateTo({
url: "/pages/booking/index"
});
};
common_vendor.onLoad((options) => {
var _a;
caseId.value = (_a = options["id"]) !== null && _a !== void 0 ? _a : "";
if (caseId.value != "") {
fetchCaseDetail();
}
});
return (_ctx, _cache) => {
"raw js";
const __returned__ = {
a: common_vendor.f(common_vendor.unref(caseDetail).afterImages, (item, index, i0) => {
return {
a: item,
b: common_vendor.o(($event) => {
return previewImages(index);
}, index),
c: index
};
}),
b: common_vendor.t(common_vendor.unref(caseDetail).categoryName),
c: common_vendor.t(common_vendor.unref(caseDetail).title),
d: common_vendor.t(common_vendor.unref(caseDetail).price),
e: common_vendor.t(common_vendor.unref(caseDetail).views),
f: common_vendor.t(common_vendor.unref(caseDetail).likes),
g: common_vendor.p({
beforeImage: common_vendor.unref(caseDetail).beforeImages[0] || "",
afterImage: common_vendor.unref(caseDetail).afterImages[0] || "",
showTitle: true
}),
h: common_vendor.t(common_vendor.unref(caseDetail).material),
i: common_vendor.t(common_vendor.unref(caseDetail).duration),
j: common_vendor.t(common_vendor.unref(caseDetail).createTime),
k: common_vendor.t(common_vendor.unref(caseDetail).description),
l: common_vendor.t(common_vendor.unref(isFavorite) ? "❤️" : "🤍"),
m: common_vendor.o(handleFavorite),
n: common_vendor.o(handleShare),
o: common_vendor.o(handleContact),
p: common_vendor.o(goToBooking),
q: common_vendor.sei(common_vendor.gei(_ctx, ""), "view")
};
return __returned__;
};
}
});
wx.createPage(_sfc_main);
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/cases/detail.js.map

View File

@@ -0,0 +1,7 @@
{
"navigationBarTitleText": "案例详情",
"navigationBarBackgroundColor": "#ffffff",
"usingComponents": {
"before-after": "../../components/before-after/before-after"
}
}

View File

@@ -0,0 +1 @@
<view id="{{q}}" change:eS="{{uV.sS}}" eS="{{$eS[q]}}" change:eA="{{uV.sA}}" eA="{{$eA[q]}}" class="{{['page', virtualHostClass]}}" style="{{virtualHostStyle}}" hidden="{{virtualHostHidden || false}}"><scroll-view class="page-scroll" scroll-y enable-flex="true" enhanced="true"><view class="gallery-section"><swiper class="gallery-swiper" circular indicator-dots indicator-color="rgba(255,255,255,0.5)" indicator-active-color="#ffffff"><swiper-item wx:for="{{a}}" wx:for-item="item" wx:key="c"><image class="gallery-image" src="{{item.a}}" mode="aspectFill" bindtap="{{item.b}}"></image></swiper-item></swiper><view class="gallery-tag"><text class="gallery-tag-text">{{b}}</text></view></view><view class="info-section"><text class="case-title">{{c}}</text><view class="case-meta"><text class="case-price">{{d}}</text><view class="case-stats"><text class="stat-text">👁 {{e}}</text><text class="stat-text">❤ {{f}}</text></view></view></view><view class="compare-section"><before-after u-i="eec33e1e-0" bind:__l="__l" u-p="{{g||''}}"></before-after></view><view class="detail-section"><view class="detail-header"><text class="detail-title">翻新详情</text></view><view class="detail-list"><view class="detail-item"><text class="detail-label">使用材质</text><text class="detail-value">{{h}}</text></view><view class="detail-item"><text class="detail-label">翻新工期</text><text class="detail-value">{{i}}</text></view><view class="detail-item"><text class="detail-label">完成日期</text><text class="detail-value">{{j}}</text></view></view><view class="detail-desc"><text class="desc-title">案例描述</text><text class="desc-content">{{k}}</text></view></view><view class="bottom-space"></view></scroll-view><view class="bottom-bar"><view class="bar-left"><view class="bar-btn" bindtap="{{m}}"><text class="bar-icon">{{l}}</text><text class="bar-label">收藏</text></view><view class="bar-btn" bindtap="{{n}}"><text class="bar-icon">📤</text><text class="bar-label">分享</text></view></view><view class="bar-right"><view class="contact-btn" bindtap="{{o}}"><text class="contact-text">在线咨询</text></view><view class="booking-btn" bindtap="{{p}}"><text class="booking-text">立即预约</text></view></view></view></view><wxs src="/common/uniView.wxs" module="uV"/>

View File

@@ -0,0 +1,202 @@
@import "../../uvue.wxss";
:host{display:flex;flex-direction:column}
/**
* 优艺家沙发翻新 - 全局样式变量
*/
/* ========== 项目主题色 ========== */
/* 辅助色 */
/* 文字颜色 */
/* 背景色 */
/* 边框颜色 */
/* 间距 */
/* 圆角 */
/* 阴影 */
/* ========== uni-app 内置变量 ========== */
/* 行为相关颜色 */
/* 文字基本颜色 */
/* 背景颜色 */
/* 边框颜色 */
/* 尺寸变量 */
/* 文字尺寸 */
/* 图片尺寸 */
/* Border Radius */
/* 水平间距 */
/* 垂直间距 */
/* 透明度 */
/* 文章场景相关 */
.page {
flex: 1;
background-color: #f5f5f5;
}
.page-scroll {
flex: 1;
}
/* 图片画廊 */
.gallery-section {
position: relative;
}
.gallery-swiper {
height: 500rpx;
}
.gallery-image {
width: 100%;
height: 100%;
}
.gallery-tag {
position: absolute;
top: 24rpx;
left: 24rpx;
background-color: rgba(212, 165, 116, 0.9);
padding: 8rpx 20rpx;
border-radius: 8rpx;
}
.gallery-tag-text {
font-size: 24rpx;
color: #ffffff;
}
/* 基本信息 */
.info-section {
background-color: #ffffff;
padding: 32rpx;
margin-bottom: 24rpx;
}
.case-title {
font-size: 36rpx;
font-weight: 600;
color: #333333;
margin-bottom: 24rpx;
}
.case-meta {
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.case-price {
font-size: 40rpx;
font-weight: 600;
color: #D4A574;
}
.case-stats {
flex-direction: row;
}
.stat-text {
font-size: 26rpx;
color: #909399;
margin-left: 24rpx;
}
/* 对比区域 */
.compare-section {
padding: 0 24rpx;
}
/* 详细信息 */
.detail-section {
background-color: #ffffff;
margin: 24rpx;
border-radius: 16rpx;
padding: 32rpx;
}
.detail-header {
margin-bottom: 24rpx;
}
.detail-title {
font-size: 32rpx;
font-weight: 600;
color: #333333;
}
.detail-list {
margin-bottom: 32rpx;
}
.detail-item {
flex-direction: row;
justify-content: space-between;
padding: 16rpx 0;
border-bottom-width: 1rpx;
border-bottom-style: solid;
border-bottom-color: #EBEEF5;
}
.detail-label {
font-size: 28rpx;
color: #909399;
}
.detail-value {
font-size: 28rpx;
color: #333333;
}
.detail-desc {
padding-top: 16rpx;
}
.desc-title {
font-size: 28rpx;
font-weight: 600;
color: #333333;
margin-bottom: 16rpx;
}
.desc-content {
font-size: 28rpx;
color: #606266;
line-height: 48rpx;
}
/* 底部间距 */
.bottom-space {
height: 160rpx;
}
/* 底部操作栏 */
.bottom-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
flex-direction: row;
align-items: center;
justify-content: space-between;
background-color: #ffffff;
padding: 16rpx 24rpx;
padding-bottom: 32rpx;
box-shadow: 0 -4rpx 16rpx rgba(0, 0, 0, 0.08);
}
.bar-left {
flex-direction: row;
}
.bar-btn {
align-items: center;
padding: 0 24rpx;
}
.bar-icon {
font-size: 40rpx;
}
.bar-label {
font-size: 22rpx;
color: #606266;
margin-top: 4rpx;
}
.bar-right {
flex-direction: row;
flex: 1;
justify-content: flex-end;
}
.contact-btn {
background-color: #f5f5f5;
padding: 20rpx 40rpx;
border-radius: 999rpx;
margin-right: 16rpx;
}
.contact-text {
font-size: 28rpx;
color: #606266;
}
.booking-btn {
background-color: #D4A574;
padding: 20rpx 48rpx;
border-radius: 999rpx;
}
.booking-text {
font-size: 28rpx;
font-weight: 600;
color: #ffffff;
}

View File

@@ -0,0 +1,193 @@
"use strict";
const common_vendor = require("../../common/vendor.js");
const api_index = require("../../api/index.js");
const utils_config = require("../../utils/config.js");
if (!Array) {
const _easycom_case_card_1 = common_vendor.resolveComponent("case-card");
_easycom_case_card_1();
}
const _easycom_case_card = () => "../../components/case-card/case-card.js";
if (!Math) {
_easycom_case_card();
}
class CategoryItem extends UTS.UTSType {
static get$UTSMetadata$() {
return {
kind: 2,
get fields() {
return {
id: { type: String, optional: false },
name: { type: String, optional: false }
};
},
name: "CategoryItem"
};
}
constructor(options, metadata = CategoryItem.get$UTSMetadata$(), isJSONParse = false) {
super();
this.__props__ = UTS.UTSType.initProps(options, metadata, isJSONParse);
this.id = this.__props__.id;
this.name = this.__props__.name;
delete this.__props__;
}
}
class CaseItem extends UTS.UTSType {
static get$UTSMetadata$() {
return {
kind: 2,
get fields() {
return {
id: { type: String, optional: false },
title: { type: String, optional: false },
category: { type: String, optional: false },
categoryName: { type: String, optional: false },
coverImage: { type: String, optional: false },
material: { type: String, optional: false },
duration: { type: String, optional: false },
price: { type: String, optional: false },
views: { type: Number, optional: false },
likes: { type: Number, optional: false }
};
},
name: "CaseItem"
};
}
constructor(options, metadata = CaseItem.get$UTSMetadata$(), isJSONParse = false) {
super();
this.__props__ = UTS.UTSType.initProps(options, metadata, isJSONParse);
this.id = this.__props__.id;
this.title = this.__props__.title;
this.category = this.__props__.category;
this.categoryName = this.__props__.categoryName;
this.coverImage = this.__props__.coverImage;
this.material = this.__props__.material;
this.duration = this.__props__.duration;
this.price = this.__props__.price;
this.views = this.__props__.views;
this.likes = this.__props__.likes;
delete this.__props__;
}
}
const _sfc_main = /* @__PURE__ */ common_vendor.defineComponent({
__name: "list",
setup(__props) {
const categories = common_vendor.ref([]);
const currentCategory = common_vendor.ref("all");
const caseList = common_vendor.ref([]);
const page = common_vendor.ref(1);
const total = common_vendor.ref(0);
const loading = common_vendor.ref(false);
const noMore = common_vendor.ref(false);
const initCategories = () => {
categories.value = utils_config.SOFA_CATEGORIES.map((item) => {
return new CategoryItem({
id: item.id,
name: item.name
});
});
};
const selectCategory = (id) => {
if (currentCategory.value == id)
return null;
currentCategory.value = id;
page.value = 1;
caseList.value = [];
noMore.value = false;
fetchCaseList();
};
const fetchCaseList = () => {
return common_vendor.__awaiter(this, void 0, void 0, function* () {
if (loading.value || noMore.value)
return Promise.resolve(null);
loading.value = true;
try {
const params = new UTSJSONObject({
category: currentCategory.value,
page: page.value,
pageSize: utils_config.PAGE_SIZE
});
const res = yield api_index.getCaseList(params);
const data = res.data;
const list = data["items"] || [];
total.value = data["total"] || 0;
const newList = list.map((item) => {
return new CaseItem({
id: item["id"],
title: item["title"],
category: item["category"],
categoryName: item["categoryName"],
coverImage: item["coverImage"],
material: item["material"],
duration: item["duration"],
price: item["price"],
views: item["views"],
likes: item["likes"]
});
});
if (page.value == 1) {
caseList.value = newList;
} else {
caseList.value = [...caseList.value, ...newList];
}
if (caseList.value.length >= total.value) {
noMore.value = true;
}
} catch (e) {
common_vendor.index.__f__("error", "at pages/cases/list.uvue:160", "获取案例列表失败", e);
}
loading.value = false;
});
};
const loadMore = () => {
if (!noMore.value && !loading.value) {
page.value++;
fetchCaseList();
}
};
const goToDetail = (id) => {
common_vendor.index.navigateTo({
url: `/pages/cases/detail?id=${id}`
});
};
common_vendor.onLoad(() => {
initCategories();
fetchCaseList();
});
return (_ctx, _cache) => {
"raw js";
const __returned__ = common_vendor.e({
a: common_vendor.f(common_vendor.unref(categories), (item, k0, i0) => {
return {
a: common_vendor.t(item.name),
b: common_vendor.unref(currentCategory) == item.id ? 1 : "",
c: common_vendor.unref(currentCategory) == item.id ? 1 : "",
d: item.id,
e: common_vendor.o(($event) => {
return selectCategory(item.id);
}, item.id)
};
}),
b: common_vendor.f(common_vendor.unref(caseList), (item, k0, i0) => {
return {
a: item.id,
b: common_vendor.o(goToDetail, item.id),
c: "15d594f8-0-" + i0,
d: common_vendor.p({
caseData: item
})
};
}),
c: common_vendor.unref(loading)
}, common_vendor.unref(loading) ? {} : common_vendor.unref(noMore) ? {} : {}, {
d: common_vendor.unref(noMore),
e: !common_vendor.unref(loading) && common_vendor.unref(caseList).length == 0
}, !common_vendor.unref(loading) && common_vendor.unref(caseList).length == 0 ? {} : {}, {
f: common_vendor.o(loadMore),
g: common_vendor.sei(common_vendor.gei(_ctx, ""), "view")
});
return __returned__;
};
}
});
wx.createPage(_sfc_main);
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/cases/list.js.map

View File

@@ -0,0 +1,6 @@
{
"navigationBarTitleText": "案例展示",
"usingComponents": {
"case-card": "../../components/case-card/case-card"
}
}

View File

@@ -0,0 +1 @@
<view id="{{g}}" change:eS="{{uV.sS}}" eS="{{$eS[g]}}" change:eA="{{uV.sA}}" eA="{{$eA[g]}}" class="{{['page', virtualHostClass]}}" style="{{virtualHostStyle}}" hidden="{{virtualHostHidden || false}}"><view class="category-bar"><scroll-view class="category-scroll" scroll-x enable-flex="true" enhanced="true"><view class="category-list"><view wx:for="{{a}}" wx:for-item="item" wx:key="d" class="{{['category-item', item.c && 'category-active']}}" bindtap="{{item.e}}"><text class="{{['category-text', item.b && 'category-text-active']}}">{{item.a}}</text></view></view></scroll-view></view><scroll-view class="case-scroll" scroll-y bindscrolltolower="{{f}}" enable-flex="true" enhanced="true"><view class="case-list"><case-card wx:for="{{b}}" wx:for-item="item" wx:key="a" bindclick="{{item.b}}" u-i="{{item.c}}" bind:__l="__l" u-p="{{item.d||''}}"></case-card></view><view class="load-status"><text wx:if="{{c}}" class="load-text">加载中...</text><text wx:elif="{{d}}" class="load-text">没有更多了</text></view><view wx:if="{{e}}" class="empty-state"><text class="empty-icon">📭</text><text class="empty-text">暂无相关案例</text></view><view class="bottom-space"></view></scroll-view></view><wxs src="/common/uniView.wxs" module="uV"/>

View File

@@ -0,0 +1,102 @@
@import "../../uvue.wxss";
:host{display:flex;flex-direction:column}
/**
* 优艺家沙发翻新 - 全局样式变量
*/
/* ========== 项目主题色 ========== */
/* 辅助色 */
/* 文字颜色 */
/* 背景色 */
/* 边框颜色 */
/* 间距 */
/* 圆角 */
/* 阴影 */
/* ========== uni-app 内置变量 ========== */
/* 行为相关颜色 */
/* 文字基本颜色 */
/* 背景颜色 */
/* 边框颜色 */
/* 尺寸变量 */
/* 文字尺寸 */
/* 图片尺寸 */
/* Border Radius */
/* 水平间距 */
/* 垂直间距 */
/* 透明度 */
/* 文章场景相关 */
.page {
flex: 1;
background-color: #f5f5f5;
}
/* 分类栏 */
.category-bar {
background-color: #ffffff;
padding: 24rpx 0;
border-bottom-width: 1rpx;
border-bottom-style: solid;
border-bottom-color: #EBEEF5;
}
.category-scroll {
flex-direction: row;
}
.category-scroll ::-webkit-scrollbar {
display: none;
}
.category-list {
flex-direction: row;
padding: 0 24rpx;
}
.category-item {
padding: 16rpx 32rpx;
margin-right: 16rpx;
border-radius: 999rpx;
background-color: #f5f5f5;
}
.category-active {
background-color: #D4A574;
}
.category-text {
font-size: 28rpx;
color: #606266;
}
.category-text-active {
color: #ffffff;
}
/* 案例列表 */
.case-scroll {
flex: 1;
}
.case-list {
padding: 24rpx;
}
/* 加载状态 */
.load-status {
padding: 32rpx 0;
align-items: center;
}
.load-text {
font-size: 26rpx;
color: #909399;
}
/* 空状态 */
.empty-state {
padding: 120rpx 0;
align-items: center;
}
.empty-icon {
font-size: 80rpx;
margin-bottom: 24rpx;
}
.empty-text {
font-size: 28rpx;
color: #909399;
}
/* 底部间距 */
.bottom-space {
height: 120rpx;
}

View File

@@ -0,0 +1,287 @@
"use strict";
const common_vendor = require("../../common/vendor.js");
const api_index = require("../../api/index.js");
const utils_config = require("../../utils/config.js");
if (!Array) {
const _easycom_nav_bar_1 = common_vendor.resolveComponent("nav-bar");
const _easycom_service_card_1 = common_vendor.resolveComponent("service-card");
const _easycom_section_header_1 = common_vendor.resolveComponent("section-header");
const _easycom_case_card_1 = common_vendor.resolveComponent("case-card");
(_easycom_nav_bar_1 + _easycom_service_card_1 + _easycom_section_header_1 + _easycom_case_card_1)();
}
const _easycom_nav_bar = () => "../../components/nav-bar/nav-bar.js";
const _easycom_service_card = () => "../../components/service-card/service-card.js";
const _easycom_section_header = () => "../../components/section-header/section-header.js";
const _easycom_case_card = () => "../../components/case-card/case-card.js";
if (!Math) {
(_easycom_nav_bar + _easycom_service_card + _easycom_section_header + _easycom_case_card)();
}
class BannerItem extends UTS.UTSType {
static get$UTSMetadata$() {
return {
kind: 2,
get fields() {
return {
id: { type: String, optional: false },
image: { type: String, optional: false },
title: { type: String, optional: false },
link: { type: String, optional: false }
};
},
name: "BannerItem"
};
}
constructor(options, metadata = BannerItem.get$UTSMetadata$(), isJSONParse = false) {
super();
this.__props__ = UTS.UTSType.initProps(options, metadata, isJSONParse);
this.id = this.__props__.id;
this.image = this.__props__.image;
this.title = this.__props__.title;
this.link = this.__props__.link;
delete this.__props__;
}
}
class CaseItem extends UTS.UTSType {
static get$UTSMetadata$() {
return {
kind: 2,
get fields() {
return {
id: { type: String, optional: false },
title: { type: String, optional: false },
category: { type: String, optional: false },
categoryName: { type: String, optional: false },
coverImage: { type: String, optional: false },
material: { type: String, optional: false },
duration: { type: String, optional: false },
price: { type: String, optional: false },
views: { type: Number, optional: false },
likes: { type: Number, optional: false }
};
},
name: "CaseItem"
};
}
constructor(options, metadata = CaseItem.get$UTSMetadata$(), isJSONParse = false) {
super();
this.__props__ = UTS.UTSType.initProps(options, metadata, isJSONParse);
this.id = this.__props__.id;
this.title = this.__props__.title;
this.category = this.__props__.category;
this.categoryName = this.__props__.categoryName;
this.coverImage = this.__props__.coverImage;
this.material = this.__props__.material;
this.duration = this.__props__.duration;
this.price = this.__props__.price;
this.views = this.__props__.views;
this.likes = this.__props__.likes;
delete this.__props__;
}
}
class ServiceType extends UTS.UTSType {
static get$UTSMetadata$() {
return {
kind: 2,
get fields() {
return {
id: { type: String, optional: false },
name: { type: String, optional: false },
icon: { type: String, optional: false }
};
},
name: "ServiceType"
};
}
constructor(options, metadata = ServiceType.get$UTSMetadata$(), isJSONParse = false) {
super();
this.__props__ = UTS.UTSType.initProps(options, metadata, isJSONParse);
this.id = this.__props__.id;
this.name = this.__props__.name;
this.icon = this.__props__.icon;
delete this.__props__;
}
}
class AdvantageItem extends UTS.UTSType {
static get$UTSMetadata$() {
return {
kind: 2,
get fields() {
return {
icon: { type: String, optional: false },
title: { type: String, optional: false },
desc: { type: String, optional: false }
};
},
name: "AdvantageItem"
};
}
constructor(options, metadata = AdvantageItem.get$UTSMetadata$(), isJSONParse = false) {
super();
this.__props__ = UTS.UTSType.initProps(options, metadata, isJSONParse);
this.icon = this.__props__.icon;
this.title = this.__props__.title;
this.desc = this.__props__.desc;
delete this.__props__;
}
}
const _sfc_main = /* @__PURE__ */ common_vendor.defineComponent({
__name: "index",
setup(__props) {
const bannerList = common_vendor.ref([]);
const serviceTypes = common_vendor.ref([]);
const hotCases = common_vendor.ref([]);
const advantages = common_vendor.ref([
new AdvantageItem({ icon: "👨‍🔧", title: "专业团队", desc: "10年+经验" }),
new AdvantageItem({ icon: "✅", title: "品质保证", desc: "质保2年" }),
new AdvantageItem({ icon: "🚗", title: "上门服务", desc: "免费评估" }),
new AdvantageItem({ icon: "💰", title: "价格透明", desc: "无隐形消费" })
]);
const initServiceTypes = () => {
serviceTypes.value = utils_config.SERVICE_TYPES.map((item) => {
return new ServiceType({
id: item.id,
name: item.name,
icon: item.icon
});
});
};
const fetchBanners = () => {
return common_vendor.__awaiter(this, void 0, void 0, function* () {
try {
const res = yield api_index.getBanners();
const data = res.data;
bannerList.value = data.map((item) => {
return new BannerItem({
id: item["id"],
image: item["image"],
title: item["title"],
link: item["link"]
});
});
} catch (e) {
common_vendor.index.__f__("error", "at pages/index/index.uvue:174", "获取轮播图失败", e);
}
});
};
const fetchHotCases = () => {
return common_vendor.__awaiter(this, void 0, void 0, function* () {
try {
const res = yield api_index.getHotCases();
const data = res.data;
const list = data["items"] || [];
hotCases.value = list.map((item) => {
return new CaseItem({
id: item["id"],
title: item["title"],
category: item["category"],
categoryName: item["categoryName"],
coverImage: item["coverImage"],
material: item["material"],
duration: item["duration"],
price: item["price"],
views: item["views"],
likes: item["likes"]
});
});
} catch (e) {
common_vendor.index.__f__("error", "at pages/index/index.uvue:200", "获取热门案例失败", e);
}
});
};
const handleBannerClick = (item) => {
if (item.link != "") {
common_vendor.index.navigateTo({
url: item.link,
fail: () => {
common_vendor.index.switchTab({
url: item.link
});
}
});
}
};
const handleServiceClick = (id) => {
common_vendor.index.switchTab({
url: "/pages/service/index"
});
};
const goToCaseList = () => {
common_vendor.index.switchTab({
url: "/pages/cases/list"
});
};
const goToCaseDetail = (id) => {
common_vendor.index.navigateTo({
url: `/pages/cases/detail?id=${id}`
});
};
const goToBooking = () => {
common_vendor.index.navigateTo({
url: "/pages/booking/index"
});
};
common_vendor.onLoad(() => {
initServiceTypes();
fetchBanners();
fetchHotCases();
});
return (_ctx, _cache) => {
"raw js";
const __returned__ = {
a: common_vendor.p({
title: "优艺家沙发翻新"
}),
b: common_vendor.f(common_vendor.unref(bannerList), (item, k0, i0) => {
return {
a: item.image,
b: common_vendor.o(($event) => {
return handleBannerClick(item);
}, item.id),
c: item.id
};
}),
c: common_vendor.f(common_vendor.unref(serviceTypes), (item, k0, i0) => {
return {
a: item.id,
b: item.id,
c: common_vendor.o(handleServiceClick, item.id),
d: "767a328a-1-" + i0,
e: common_vendor.p({
id: item.id,
name: item.name,
icon: item.icon
})
};
}),
d: common_vendor.f(common_vendor.unref(advantages), (item, k0, i0) => {
return {
a: common_vendor.t(item.icon),
b: common_vendor.t(item.title),
c: common_vendor.t(item.desc),
d: item.title
};
}),
e: common_vendor.o(goToCaseList),
f: common_vendor.p({
title: "热门案例",
showMore: true
}),
g: common_vendor.f(common_vendor.unref(hotCases), (item, k0, i0) => {
return {
a: item.id,
b: common_vendor.o(goToCaseDetail, item.id),
c: "767a328a-3-" + i0,
d: common_vendor.p({
caseData: item
})
};
}),
h: common_vendor.o(goToBooking),
i: common_vendor.sei(common_vendor.gei(_ctx, ""), "view")
};
return __returned__;
};
}
});
wx.createPage(_sfc_main);
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/index/index.js.map

View File

@@ -0,0 +1,10 @@
{
"navigationBarTitleText": "优艺家沙发翻新",
"navigationStyle": "custom",
"usingComponents": {
"nav-bar": "../../components/nav-bar/nav-bar",
"service-card": "../../components/service-card/service-card",
"section-header": "../../components/section-header/section-header",
"case-card": "../../components/case-card/case-card"
}
}

View File

@@ -0,0 +1 @@
<view id="{{i}}" change:eS="{{uV.sS}}" eS="{{$eS[i]}}" change:eA="{{uV.sA}}" eA="{{$eA[i]}}" class="{{['page', virtualHostClass]}}" style="{{virtualHostStyle}}" hidden="{{virtualHostHidden || false}}"><nav-bar u-i="767a328a-0" bind:__l="__l" u-p="{{a||''}}"></nav-bar><scroll-view class="page-content" scroll-y enable-flex="true" enhanced="true"><view class="banner-section"><swiper class="banner-swiper" circular autoplay indicator-dots indicator-color="rgba(255,255,255,0.5)" indicator-active-color="#ffffff"><swiper-item wx:for="{{b}}" wx:for-item="item" wx:key="c"><image class="banner-image" src="{{item.a}}" mode="aspectFill" bindtap="{{item.b}}"></image></swiper-item></swiper></view><view class="service-section"><view class="service-grid"><service-card wx:for="{{c}}" wx:for-item="item" wx:key="b" id="{{item.a}}" virtualHostId="{{item.a}}" bindclick="{{item.c}}" u-i="{{item.d}}" bind:__l="__l" u-p="{{item.e||''}}"></service-card></view></view><view class="advantage-section"><view class="advantage-list"><view wx:for="{{d}}" wx:for-item="item" wx:key="d" class="advantage-item"><text class="advantage-icon">{{item.a}}</text><view class="advantage-info"><text class="advantage-title">{{item.b}}</text><text class="advantage-desc">{{item.c}}</text></view></view></view></view><view class="case-section"><section-header bindmore="{{e}}" u-i="767a328a-2" bind:__l="__l" u-p="{{f||''}}"></section-header><view class="case-list"><case-card wx:for="{{g}}" wx:for-item="item" wx:key="a" bindclick="{{item.b}}" u-i="{{item.c}}" bind:__l="__l" u-p="{{item.d||''}}"></case-card></view></view><view class="booking-section" bindtap="{{h}}"><view class="booking-content"><view class="booking-left"><text class="booking-title">免费上门评估</text><text class="booking-desc">专业师傅免费上门,为您的沙发量身定制翻新方案</text></view><view class="booking-btn"><text class="booking-btn-text">立即预约</text></view></view></view><view class="bottom-space"></view></scroll-view></view><wxs src="/common/uniView.wxs" module="uV"/>

View File

@@ -0,0 +1,144 @@
@import "../../uvue.wxss";
:host{display:flex;flex-direction:column}
/**
* 优艺家沙发翻新 - 全局样式变量
*/
/* ========== 项目主题色 ========== */
/* 辅助色 */
/* 文字颜色 */
/* 背景色 */
/* 边框颜色 */
/* 间距 */
/* 圆角 */
/* 阴影 */
/* ========== uni-app 内置变量 ========== */
/* 行为相关颜色 */
/* 文字基本颜色 */
/* 背景颜色 */
/* 边框颜色 */
/* 尺寸变量 */
/* 文字尺寸 */
/* 图片尺寸 */
/* Border Radius */
/* 水平间距 */
/* 垂直间距 */
/* 透明度 */
/* 文章场景相关 */
.page {
flex: 1;
background-color: #f5f5f5;
}
.page-content {
flex: 1;
}
/* 轮播图 */
.banner-section {
padding: 24rpx;
}
.banner-swiper {
height: 320rpx;
border-radius: 16rpx;
overflow: hidden;
}
.banner-image {
width: 100%;
height: 100%;
}
/* 服务入口 */
.service-section {
padding: 0 24rpx 24rpx;
}
.service-grid {
flex-direction: row;
justify-content: space-between;
background-color: #ffffff;
border-radius: 16rpx;
padding: 24rpx 16rpx;
}
/* 公司优势 */
.advantage-section {
padding: 0 24rpx 24rpx;
}
.advantage-list {
flex-direction: row;
flex-wrap: wrap;
background-color: #ffffff;
border-radius: 16rpx;
padding: 24rpx;
}
.advantage-item {
width: 50%;
flex-direction: row;
align-items: center;
padding: 16rpx 0;
}
.advantage-icon {
font-size: 48rpx;
margin-right: 16rpx;
}
.advantage-info {
flex: 1;
}
.advantage-title {
font-size: 28rpx;
font-weight: 600;
color: #333333;
margin-bottom: 4rpx;
}
.advantage-desc {
font-size: 24rpx;
color: #909399;
}
/* 热门案例 */
.case-section {
padding: 0 24rpx;
}
.case-list {
padding-bottom: 24rpx;
}
/* 预约入口 */
.booking-section {
margin: 0 24rpx 24rpx;
background: linear-gradient(135deg, #D4A574 0%, #B8895A 100%);
border-radius: 16rpx;
padding: 32rpx;
}
.booking-content {
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.booking-left {
flex: 1;
}
.booking-title {
font-size: 34rpx;
font-weight: 600;
color: #ffffff;
margin-bottom: 8rpx;
}
.booking-desc {
font-size: 24rpx;
color: rgba(255, 255, 255, 0.8);
}
.booking-btn {
background-color: #ffffff;
padding: 16rpx 32rpx;
border-radius: 999rpx;
margin-left: 24rpx;
}
.booking-btn-text {
font-size: 28rpx;
font-weight: 600;
color: #D4A574;
}
/* 底部间距 */
.bottom-space {
height: 120rpx;
}

View File

@@ -0,0 +1,276 @@
"use strict";
const common_vendor = require("../../common/vendor.js");
const api_index = require("../../api/index.js");
if (!Array) {
const _easycom_section_header_1 = common_vendor.resolveComponent("section-header");
_easycom_section_header_1();
}
const _easycom_section_header = () => "../../components/section-header/section-header.js";
if (!Math) {
_easycom_section_header();
}
class ServiceType extends UTS.UTSType {
static get$UTSMetadata$() {
return {
kind: 2,
get fields() {
return {
id: { type: String, optional: false },
name: { type: String, optional: false },
desc: { type: String, optional: false },
emoji: { type: String, optional: false }
};
},
name: "ServiceType"
};
}
constructor(options, metadata = ServiceType.get$UTSMetadata$(), isJSONParse = false) {
super();
this.__props__ = UTS.UTSType.initProps(options, metadata, isJSONParse);
this.id = this.__props__.id;
this.name = this.__props__.name;
this.desc = this.__props__.desc;
this.emoji = this.__props__.emoji;
delete this.__props__;
}
}
class ProcessItem extends UTS.UTSType {
static get$UTSMetadata$() {
return {
kind: 2,
get fields() {
return {
step: { type: Number, optional: false },
title: { type: String, optional: false },
description: { type: String, optional: false }
};
},
name: "ProcessItem"
};
}
constructor(options, metadata = ProcessItem.get$UTSMetadata$(), isJSONParse = false) {
super();
this.__props__ = UTS.UTSType.initProps(options, metadata, isJSONParse);
this.step = this.__props__.step;
this.title = this.__props__.title;
this.description = this.__props__.description;
delete this.__props__;
}
}
class MaterialItem extends UTS.UTSType {
static get$UTSMetadata$() {
return {
kind: 2,
get fields() {
return {
name: { type: String, optional: false },
price: { type: String, optional: false },
desc: { type: String, optional: false },
tags: { type: UTS.UTSType.withGenerics(Array, [String]), optional: false }
};
},
name: "MaterialItem"
};
}
constructor(options, metadata = MaterialItem.get$UTSMetadata$(), isJSONParse = false) {
super();
this.__props__ = UTS.UTSType.initProps(options, metadata, isJSONParse);
this.name = this.__props__.name;
this.price = this.__props__.price;
this.desc = this.__props__.desc;
this.tags = this.__props__.tags;
delete this.__props__;
}
}
class FaqItem extends UTS.UTSType {
static get$UTSMetadata$() {
return {
kind: 2,
get fields() {
return {
question: { type: String, optional: false },
answer: { type: String, optional: false },
expanded: { type: Boolean, optional: false }
};
},
name: "FaqItem"
};
}
constructor(options, metadata = FaqItem.get$UTSMetadata$(), isJSONParse = false) {
super();
this.__props__ = UTS.UTSType.initProps(options, metadata, isJSONParse);
this.question = this.__props__.question;
this.answer = this.__props__.answer;
this.expanded = this.__props__.expanded;
delete this.__props__;
}
}
const _sfc_main = /* @__PURE__ */ common_vendor.defineComponent({
__name: "index",
setup(__props) {
const serviceTypes = common_vendor.ref([
new ServiceType({ id: "repair", name: "局部修复", desc: "破损、划痕修复", emoji: "🔧" }),
new ServiceType({ id: "recolor", name: "改色翻新", desc: "皮面改色换新", emoji: "🎨" }),
new ServiceType({ id: "refurbish", name: "整体翻新", desc: "全面翻新升级", emoji: "✨" }),
new ServiceType({ id: "custom", name: "定制换皮", desc: "个性化定制", emoji: "💎" })
]);
const processList = common_vendor.ref([]);
const materials = common_vendor.ref([
new MaterialItem({
name: "头层牛皮",
price: "¥800-1500/平",
desc: "采用进口头层牛皮,质地柔软,透气性好,使用寿命长",
tags: ["进口原料", "透气舒适", "耐用耐磨"]
}),
new MaterialItem({
name: "二层牛皮",
price: "¥400-800/平",
desc: "经济实惠的选择,经过特殊处理后外观与头层相近",
tags: ["性价比高", "外观精美", "易打理"]
}),
new MaterialItem({
name: "科技布",
price: "¥200-500/平",
desc: "新型环保面料,防水防污,清洁方便,触感舒适",
tags: ["防水防污", "易清洁", "环保健康"]
}),
new MaterialItem({
name: "棉麻布艺",
price: "¥150-400/平",
desc: "天然面料,透气舒适,适合追求自然风格的客户",
tags: ["天然环保", "透气清爽", "风格多样"]
})
]);
const faqList = common_vendor.ref([
new FaqItem({
question: "翻新需要多长时间?",
answer: "根据沙发的大小和翻新程度不同一般需要3-10个工作日。局部修复1-3天整体翻新5-10天。",
expanded: false
}),
new FaqItem({
question: "翻新后能保证多久?",
answer: "我们提供2年质保服务质保期内如有非人为损坏免费维修。头层牛皮正常使用可达10年以上。",
expanded: false
}),
new FaqItem({
question: "可以上门取送吗?",
answer: "是的,我们提供免费上门取送服务(市区范围内),郊区会收取少量运输费用。",
expanded: false
}),
new FaqItem({
question: "如何报价?",
answer: "我们提供免费上门评估服务,师傅会根据沙发的实际情况给出详细报价,价格透明无隐形消费。",
expanded: false
}),
new FaqItem({
question: "定金和尾款如何支付?",
answer: "确认订单后支付30%定金,翻新完成验收满意后支付尾款。支持微信、支付宝、银行转账等多种方式。",
expanded: false
})
]);
const fetchServiceProcess = () => {
return common_vendor.__awaiter(this, void 0, void 0, function* () {
try {
const res = yield api_index.getServiceProcess();
const data = res.data;
processList.value = data.map((item) => {
return new ProcessItem({
step: item["step"],
title: item["title"],
description: item["description"]
});
});
} catch (e) {
common_vendor.index.__f__("error", "at pages/service/index.uvue:217", "获取服务流程失败", e);
}
});
};
const toggleFaq = (index) => {
faqList.value[index].expanded = !faqList.value[index].expanded;
};
const handleServiceClick = (item) => {
common_vendor.index.navigateTo({
url: "/pages/booking/index"
});
};
const goToBooking = () => {
common_vendor.index.navigateTo({
url: "/pages/booking/index"
});
};
common_vendor.onLoad(() => {
fetchServiceProcess();
});
return (_ctx, _cache) => {
"raw js";
const __returned__ = {
a: common_vendor.p({
title: "服务类型"
}),
b: common_vendor.f(common_vendor.unref(serviceTypes), (item, k0, i0) => {
return {
a: common_vendor.t(item.emoji),
b: common_vendor.t(item.name),
c: common_vendor.t(item.desc),
d: item.id,
e: common_vendor.o(($event) => {
return handleServiceClick();
}, item.id)
};
}),
c: common_vendor.p({
title: "服务流程"
}),
d: common_vendor.f(common_vendor.unref(processList), (item, index, i0) => {
return common_vendor.e({
a: common_vendor.t(item.step),
b: common_vendor.t(item.title),
c: common_vendor.t(item.description),
d: index < common_vendor.unref(processList).length - 1
}, index < common_vendor.unref(processList).length - 1 ? {} : {}, {
e: item.step
});
}),
e: common_vendor.p({
title: "材质说明"
}),
f: common_vendor.f(common_vendor.unref(materials), (item, k0, i0) => {
return {
a: common_vendor.t(item.name),
b: common_vendor.t(item.price),
c: common_vendor.t(item.desc),
d: common_vendor.f(item.tags, (tag, k1, i1) => {
return {
a: common_vendor.t(tag),
b: tag
};
}),
e: item.name
};
}),
g: common_vendor.p({
title: "常见问题"
}),
h: common_vendor.f(common_vendor.unref(faqList), (item, index, i0) => {
return common_vendor.e({
a: common_vendor.t(item.question),
b: common_vendor.t(item.expanded ? "" : "+"),
c: item.expanded
}, item.expanded ? {
d: common_vendor.t(item.answer)
} : {}, {
e: index,
f: common_vendor.o(($event) => {
return toggleFaq(index);
}, index)
});
}),
i: common_vendor.o(goToBooking),
j: common_vendor.sei(common_vendor.gei(_ctx, ""), "view")
};
return __returned__;
};
}
});
wx.createPage(_sfc_main);
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/service/index.js.map

View File

@@ -0,0 +1,6 @@
{
"navigationBarTitleText": "服务介绍",
"usingComponents": {
"section-header": "../../components/section-header/section-header"
}
}

View File

@@ -0,0 +1 @@
<view id="{{j}}" change:eS="{{uV.sS}}" eS="{{$eS[j]}}" change:eA="{{uV.sA}}" eA="{{$eA[j]}}" class="{{['page', virtualHostClass]}}" style="{{virtualHostStyle}}" hidden="{{virtualHostHidden || false}}"><scroll-view class="page-scroll" scroll-y enable-flex="true" enhanced="true"><view class="banner"><view class="banner-content"><text class="banner-title">专业沙发翻新服务</text><text class="banner-desc">让旧沙发焕发新生</text></view></view><view class="section"><section-header u-i="7558dcb8-0" bind:__l="__l" u-p="{{a||''}}"></section-header><view class="service-grid"><view wx:for="{{b}}" wx:for-item="item" wx:key="d" class="service-item" bindtap="{{item.e}}"><view class="service-icon-bg"><text class="service-icon">{{item.a}}</text></view><text class="service-name">{{item.b}}</text><text class="service-desc">{{item.c}}</text></view></view></view><view class="section"><section-header u-i="7558dcb8-1" bind:__l="__l" u-p="{{c||''}}"></section-header><view class="process-list"><view wx:for="{{d}}" wx:for-item="item" wx:key="e" class="process-item"><view class="process-step"><text class="step-num">{{item.a}}</text></view><view class="process-content"><text class="process-title">{{item.b}}</text><text class="process-desc">{{item.c}}</text></view><view wx:if="{{item.d}}" class="process-line"></view></view></view></view><view class="section"><section-header u-i="7558dcb8-2" bind:__l="__l" u-p="{{e||''}}"></section-header><view class="material-list"><view wx:for="{{f}}" wx:for-item="item" wx:key="e" class="material-item"><view class="material-header"><text class="material-name">{{item.a}}</text><text class="material-price">{{item.b}}</text></view><text class="material-desc">{{item.c}}</text><view class="material-tags"><text wx:for="{{item.d}}" wx:for-item="tag" wx:key="b" class="material-tag">{{tag.a}}</text></view></view></view></view><view class="section"><section-header u-i="7558dcb8-3" bind:__l="__l" u-p="{{g||''}}"></section-header><view class="faq-list"><view wx:for="{{h}}" wx:for-item="item" wx:key="e" class="faq-item" bindtap="{{item.f}}"><view class="faq-header"><text class="faq-question">{{item.a}}</text><text class="faq-arrow">{{item.b}}</text></view><view wx:if="{{item.c}}" class="faq-answer"><text class="faq-answer-text">{{item.d}}</text></view></view></view></view><view class="bottom-space"></view></scroll-view><view class="bottom-bar"><view class="bar-info"><text class="bar-title">免费上门评估</text><text class="bar-desc">专业师傅为您量身定制方案</text></view><view class="bar-btn" bindtap="{{i}}"><text class="bar-btn-text">立即预约</text></view></view></view><wxs src="/common/uniView.wxs" module="uV"/>

View File

@@ -0,0 +1,281 @@
@import "../../uvue.wxss";
:host{display:flex;flex-direction:column}
/**
* 优艺家沙发翻新 - 全局样式变量
*/
/* ========== 项目主题色 ========== */
/* 辅助色 */
/* 文字颜色 */
/* 背景色 */
/* 边框颜色 */
/* 间距 */
/* 圆角 */
/* 阴影 */
/* ========== uni-app 内置变量 ========== */
/* 行为相关颜色 */
/* 文字基本颜色 */
/* 背景颜色 */
/* 边框颜色 */
/* 尺寸变量 */
/* 文字尺寸 */
/* 图片尺寸 */
/* Border Radius */
/* 水平间距 */
/* 垂直间距 */
/* 透明度 */
/* 文章场景相关 */
.page {
flex: 1;
background-color: #f5f5f5;
}
.page-scroll {
flex: 1;
}
/* 顶部横幅 */
.banner {
height: 280rpx;
background: linear-gradient(135deg, #D4A574 0%, #B8895A 100%);
justify-content: center;
align-items: center;
}
.banner-content {
align-items: center;
}
.banner-title {
font-size: 40rpx;
font-weight: 600;
color: #ffffff;
margin-bottom: 16rpx;
}
.banner-desc {
font-size: 28rpx;
color: rgba(255, 255, 255, 0.8);
}
/* 通用section */
.section {
padding: 0 24rpx;
margin-bottom: 24rpx;
}
/* 服务类型 */
.service-grid {
flex-direction: row;
flex-wrap: wrap;
background-color: #ffffff;
border-radius: 16rpx;
padding: 16rpx;
}
.service-item {
width: 50%;
padding: 24rpx;
align-items: center;
}
.service-icon-bg {
width: 100rpx;
height: 100rpx;
background-color: #FDF6EE;
border-radius: 50%;
align-items: center;
justify-content: center;
margin-bottom: 16rpx;
}
.service-icon {
font-size: 48rpx;
}
.service-name {
font-size: 30rpx;
font-weight: 600;
color: #333333;
margin-bottom: 8rpx;
}
.service-desc {
font-size: 24rpx;
color: #909399;
}
/* 服务流程 */
.process-list {
background-color: #ffffff;
border-radius: 16rpx;
padding: 32rpx;
}
.process-item {
flex-direction: row;
position: relative;
padding-bottom: 32rpx;
}
.process-step {
width: 48rpx;
height: 48rpx;
background-color: #D4A574;
border-radius: 50%;
align-items: center;
justify-content: center;
margin-right: 24rpx;
z-index: 1;
}
.step-num {
font-size: 24rpx;
font-weight: 600;
color: #ffffff;
}
.process-content {
flex: 1;
}
.process-title {
font-size: 30rpx;
font-weight: 600;
color: #333333;
margin-bottom: 8rpx;
}
.process-desc {
font-size: 26rpx;
color: #909399;
}
.process-line {
position: absolute;
left: 22rpx;
top: 56rpx;
width: 4rpx;
height: 60rpx;
background-color: #E8C9A8;
}
/* 材质说明 */
.material-list {
background-color: #ffffff;
border-radius: 16rpx;
}
.material-item {
padding: 32rpx;
border-bottom-width: 1rpx;
border-bottom-style: solid;
border-bottom-color: #EBEEF5;
}
.material-item:last-child {
border-bottom-width: 0;
}
.material-header {
flex-direction: row;
justify-content: space-between;
align-items: center;
margin-bottom: 12rpx;
}
.material-name {
font-size: 30rpx;
font-weight: 600;
color: #333333;
}
.material-price {
font-size: 28rpx;
color: #D4A574;
font-weight: 600;
}
.material-desc {
font-size: 26rpx;
color: #606266;
margin-bottom: 16rpx;
line-height: 40rpx;
}
.material-tags {
flex-direction: row;
flex-wrap: wrap;
}
.material-tag {
font-size: 22rpx;
color: #D4A574;
background-color: #FDF6EE;
padding: 8rpx 16rpx;
border-radius: 8rpx;
margin-right: 16rpx;
margin-bottom: 8rpx;
}
/* 常见问题 */
.faq-list {
background-color: #ffffff;
border-radius: 16rpx;
}
.faq-item {
padding: 32rpx;
border-bottom-width: 1rpx;
border-bottom-style: solid;
border-bottom-color: #EBEEF5;
}
.faq-item:last-child {
border-bottom-width: 0;
}
.faq-header {
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.faq-question {
font-size: 28rpx;
font-weight: 600;
color: #333333;
flex: 1;
}
.faq-arrow {
font-size: 36rpx;
color: #909399;
margin-left: 16rpx;
}
.faq-answer {
margin-top: 16rpx;
padding-top: 16rpx;
border-top-width: 1rpx;
border-top-style: dashed;
border-top-color: #EBEEF5;
}
.faq-answer-text {
font-size: 26rpx;
color: #606266;
line-height: 44rpx;
}
/* 底部间距 */
.bottom-space {
height: 160rpx;
}
/* 底部操作栏 */
.bottom-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 2;
flex-direction: row;
align-items: center;
justify-content: space-between;
background-color: #ffffff;
padding: 20rpx 32rpx;
padding-bottom: 40rpx;
box-shadow: 0 -4rpx 16rpx rgba(0, 0, 0, 0.08);
}
.bar-info {
flex: 1;
}
.bar-title {
font-size: 30rpx;
font-weight: 600;
color: #333333;
}
.bar-desc {
font-size: 24rpx;
color: #909399;
margin-top: 4rpx;
}
.bar-btn {
background-color: #D4A574;
padding: 24rpx 56rpx;
border-radius: 999rpx;
}
.bar-btn-text {
font-size: 30rpx;
font-weight: 600;
color: #ffffff;
}

View File

@@ -0,0 +1,228 @@
"use strict";
const common_vendor = require("../../common/vendor.js");
const utils_config = require("../../utils/config.js");
class UserInfo extends UTS.UTSType {
static get$UTSMetadata$() {
return {
kind: 2,
get fields() {
return {
id: { type: String, optional: false },
nickName: { type: String, optional: false },
avatar: { type: String, optional: false },
phone: { type: String, optional: false }
};
},
name: "UserInfo"
};
}
constructor(options, metadata = UserInfo.get$UTSMetadata$(), isJSONParse = false) {
super();
this.__props__ = UTS.UTSType.initProps(options, metadata, isJSONParse);
this.id = this.__props__.id;
this.nickName = this.__props__.nickName;
this.avatar = this.__props__.avatar;
this.phone = this.__props__.phone;
delete this.__props__;
}
}
const _sfc_main = /* @__PURE__ */ common_vendor.defineComponent({
__name: "index",
setup(__props) {
const userInfo = common_vendor.ref(new UserInfo({
id: "",
nickName: "",
avatar: "",
phone: ""
}));
const isLoggedIn = common_vendor.ref(false);
const bookingCount = common_vendor.ref(0);
const favoriteCount = common_vendor.ref(0);
const cacheSize = common_vendor.ref("0KB");
const checkLoginStatus = () => {
var _a, _b, _c, _d;
const token = common_vendor.index.getStorageSync(utils_config.STORAGE_KEYS.TOKEN);
isLoggedIn.value = token != "";
if (isLoggedIn.value) {
const info = common_vendor.index.getStorageSync(utils_config.STORAGE_KEYS.USER_INFO);
if (info != null) {
userInfo.value = new UserInfo({
id: (_a = info["id"]) !== null && _a !== void 0 ? _a : "",
nickName: (_b = info["nickName"]) !== null && _b !== void 0 ? _b : "",
avatar: (_c = info["avatar"]) !== null && _c !== void 0 ? _c : "",
phone: (_d = info["phone"]) !== null && _d !== void 0 ? _d : ""
});
}
}
};
const getCacheSize = () => {
common_vendor.index.getStorageInfo(new UTSJSONObject({
success: (res) => {
const size = res.currentSize;
if (size < 1024) {
cacheSize.value = `${size}KB`;
} else {
cacheSize.value = `${(size / 1024).toFixed(2)}MB`;
}
}
}));
};
const handleLogin = () => {
common_vendor.index.getUserProfile(new UTSJSONObject({
desc: "用于完善用户资料",
success: (res = null) => {
userInfo.value = new UserInfo(
{
id: "",
nickName: res.userInfo.nickName,
avatar: res.userInfo.avatarUrl,
phone: ""
}
// 保存用户信息
);
common_vendor.index.setStorageSync(utils_config.STORAGE_KEYS.USER_INFO, new UTSJSONObject({
nickName: res.userInfo.nickName,
avatar: res.userInfo.avatarUrl
}));
common_vendor.index.setStorageSync(utils_config.STORAGE_KEYS.TOKEN, "mock_token_" + Date.now().toString());
isLoggedIn.value = true;
common_vendor.index.showToast({
title: "登录成功",
icon: "success"
});
},
fail: () => {
common_vendor.index.showToast({
title: "登录失败",
icon: "none"
});
}
}));
};
const handleLogout = () => {
common_vendor.index.showModal(new UTSJSONObject({
title: "提示",
content: "确定要退出登录吗?",
success: (res) => {
if (res.confirm) {
common_vendor.index.removeStorageSync(utils_config.STORAGE_KEYS.TOKEN);
common_vendor.index.removeStorageSync(utils_config.STORAGE_KEYS.USER_INFO);
isLoggedIn.value = false;
userInfo.value = new UserInfo({
id: "",
nickName: "",
avatar: "",
phone: ""
});
common_vendor.index.showToast({
title: "已退出登录",
icon: "success"
});
}
}
}));
};
const goToBookingList = () => {
common_vendor.index.showToast({
title: "功能开发中",
icon: "none"
});
};
const goToFavorites = () => {
common_vendor.index.showToast({
title: "功能开发中",
icon: "none"
});
};
const goToAbout = () => {
common_vendor.index.navigateTo({
url: "/pages/about/index"
});
};
const callService = () => {
common_vendor.index.makePhoneCall({
phoneNumber: "400-888-8888",
fail: () => {
common_vendor.index.showToast({
title: "拨打电话失败",
icon: "none"
});
}
});
};
const openFeedback = () => {
common_vendor.index.showToast({
title: "功能开发中",
icon: "none"
});
};
const checkUpdate = () => {
common_vendor.index.showToast({
title: "已是最新版本",
icon: "success"
});
};
const clearCache = () => {
common_vendor.index.showModal(new UTSJSONObject({
title: "提示",
content: "确定要清除缓存吗?",
success: (res) => {
if (res.confirm) {
common_vendor.index.clearStorage(new UTSJSONObject({
success: () => {
cacheSize.value = "0KB";
common_vendor.index.showToast({
title: "清除成功",
icon: "success"
});
}
}));
}
}
}));
};
common_vendor.onShow(() => {
checkLoginStatus();
getCacheSize();
});
return (_ctx, _cache) => {
"raw js";
const __returned__ = common_vendor.e({
a: common_vendor.unref(userInfo).avatar || "/static/images/default-avatar.png",
b: common_vendor.t(common_vendor.unref(userInfo).nickName || "点击登录"),
c: common_vendor.unref(userInfo).phone
}, common_vendor.unref(userInfo).phone ? {
d: common_vendor.t(common_vendor.unref(userInfo).phone)
} : {}, {
e: !common_vendor.unref(isLoggedIn)
}, !common_vendor.unref(isLoggedIn) ? {
f: common_vendor.o(handleLogin)
} : {}, {
g: common_vendor.unref(bookingCount) > 0
}, common_vendor.unref(bookingCount) > 0 ? {
h: common_vendor.t(common_vendor.unref(bookingCount))
} : {}, {
i: common_vendor.o(goToBookingList),
j: common_vendor.unref(favoriteCount) > 0
}, common_vendor.unref(favoriteCount) > 0 ? {
k: common_vendor.t(common_vendor.unref(favoriteCount))
} : {}, {
l: common_vendor.o(goToFavorites),
m: common_vendor.o(goToAbout),
n: common_vendor.o(callService),
o: common_vendor.o(openFeedback),
p: common_vendor.o(checkUpdate),
q: common_vendor.t(common_vendor.unref(cacheSize)),
r: common_vendor.o(clearCache),
s: common_vendor.unref(isLoggedIn)
}, common_vendor.unref(isLoggedIn) ? {
t: common_vendor.o(handleLogout)
} : {}, {
v: common_vendor.sei(common_vendor.gei(_ctx, ""), "view")
});
return __returned__;
};
}
});
wx.createPage(_sfc_main);
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/user/index.js.map

View File

@@ -0,0 +1,4 @@
{
"navigationBarTitleText": "我的",
"usingComponents": {}
}

View File

@@ -0,0 +1 @@
<view id="{{v}}" change:eS="{{uV.sS}}" eS="{{$eS[v]}}" change:eA="{{uV.sA}}" eA="{{$eA[v]}}" class="{{['page', virtualHostClass]}}" style="{{virtualHostStyle}}" hidden="{{virtualHostHidden || false}}"><scroll-view class="page-scroll" scroll-y enable-flex="true" enhanced="true"><view class="user-section"><view class="user-card"><view class="avatar-wrapper"><image class="user-avatar" src="{{a}}" mode="aspectFill"></image></view><view class="user-info"><text class="user-name">{{b}}</text><text wx:if="{{c}}" class="user-phone">{{d}}</text></view><view wx:if="{{e}}" class="user-action" bindtap="{{f}}"><text class="action-text">登录</text></view></view></view><view class="menu-section"><view class="menu-group"><view class="menu-item" bindtap="{{i}}"><view class="menu-left"><text class="menu-icon">📋</text><text class="menu-text">我的预约</text></view><view class="menu-right"><text wx:if="{{g}}" class="menu-badge">{{h}}</text><text class="menu-arrow"></text></view></view><view class="menu-item" bindtap="{{l}}"><view class="menu-left"><text class="menu-icon">❤️</text><text class="menu-text">我的收藏</text></view><view class="menu-right"><text wx:if="{{j}}" class="menu-badge">{{k}}</text><text class="menu-arrow"></text></view></view></view><view class="menu-group"><view class="menu-item" bindtap="{{m}}"><view class="menu-left"><text class="menu-icon">🏠</text><text class="menu-text">关于我们</text></view><view class="menu-right"><text class="menu-arrow"></text></view></view><view class="menu-item" bindtap="{{n}}"><view class="menu-left"><text class="menu-icon">📞</text><text class="menu-text">联系客服</text></view><view class="menu-right"><text class="menu-value">400-888-8888</text><text class="menu-arrow"></text></view></view><view class="menu-item" bindtap="{{o}}"><view class="menu-left"><text class="menu-icon">💬</text><text class="menu-text">意见反馈</text></view><view class="menu-right"><text class="menu-arrow"></text></view></view></view><view class="menu-group"><view class="menu-item" bindtap="{{p}}"><view class="menu-left"><text class="menu-icon">🔄</text><text class="menu-text">检查更新</text></view><view class="menu-right"><text class="menu-value">v1.0.0</text><text class="menu-arrow"></text></view></view><view class="menu-item" bindtap="{{r}}"><view class="menu-left"><text class="menu-icon">🧹</text><text class="menu-text">清除缓存</text></view><view class="menu-right"><text class="menu-value">{{q}}</text><text class="menu-arrow"></text></view></view></view></view><view wx:if="{{s}}" class="logout-section"><view class="logout-btn" bindtap="{{t}}"><text class="logout-text">退出登录</text></view></view><view class="bottom-space"></view></scroll-view></view><wxs src="/common/uniView.wxs" module="uV"/>

View File

@@ -0,0 +1,156 @@
@import "../../uvue.wxss";
:host{display:flex;flex-direction:column}
/**
* 优艺家沙发翻新 - 全局样式变量
*/
/* ========== 项目主题色 ========== */
/* 辅助色 */
/* 文字颜色 */
/* 背景色 */
/* 边框颜色 */
/* 间距 */
/* 圆角 */
/* 阴影 */
/* ========== uni-app 内置变量 ========== */
/* 行为相关颜色 */
/* 文字基本颜色 */
/* 背景颜色 */
/* 边框颜色 */
/* 尺寸变量 */
/* 文字尺寸 */
/* 图片尺寸 */
/* Border Radius */
/* 水平间距 */
/* 垂直间距 */
/* 透明度 */
/* 文章场景相关 */
.page {
flex: 1;
background-color: #f5f5f5;
}
.page-scroll {
flex: 1;
}
/* 用户信息 */
.user-section {
background: linear-gradient(135deg, #D4A574 0%, #B8895A 100%);
padding: 48rpx 32rpx 64rpx;
}
.user-card {
flex-direction: row;
align-items: center;
}
.avatar-wrapper {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
overflow: hidden;
border-width: 4rpx;
border-style: solid;
border-color: rgba(255, 255, 255, 0.5);
}
.user-avatar {
width: 100%;
height: 100%;
}
.user-info {
flex: 1;
margin-left: 24rpx;
}
.user-name {
font-size: 36rpx;
font-weight: 600;
color: #ffffff;
}
.user-phone {
font-size: 26rpx;
color: rgba(255, 255, 255, 0.8);
margin-top: 8rpx;
}
.user-action {
background-color: rgba(255, 255, 255, 0.2);
padding: 16rpx 32rpx;
border-radius: 999rpx;
}
.action-text {
font-size: 28rpx;
color: #ffffff;
}
/* 菜单区域 */
.menu-section {
margin-top: -32rpx;
padding: 0 24rpx;
}
.menu-group {
background-color: #ffffff;
border-radius: 16rpx;
margin-bottom: 24rpx;
overflow: hidden;
}
.menu-item {
flex-direction: row;
align-items: center;
justify-content: space-between;
padding: 32rpx;
border-bottom-width: 1rpx;
border-bottom-style: solid;
border-bottom-color: #EBEEF5;
}
.menu-item:last-child {
border-bottom-width: 0;
}
.menu-left {
flex-direction: row;
align-items: center;
}
.menu-icon {
font-size: 40rpx;
margin-right: 24rpx;
}
.menu-text {
font-size: 30rpx;
color: #333333;
}
.menu-right {
flex-direction: row;
align-items: center;
}
.menu-value {
font-size: 26rpx;
color: #909399;
margin-right: 8rpx;
}
.menu-badge {
background-color: #F56C6C;
color: #ffffff;
font-size: 22rpx;
padding: 4rpx 12rpx;
border-radius: 999rpx;
margin-right: 8rpx;
}
.menu-arrow {
font-size: 32rpx;
color: #909399;
}
/* 退出登录 */
.logout-section {
padding: 24rpx;
}
.logout-btn {
background-color: #ffffff;
border-radius: 16rpx;
padding: 28rpx 0;
align-items: center;
}
.logout-text {
font-size: 30rpx;
color: #F56C6C;
}
/* 底部间距 */
.bottom-space {
height: 120rpx;
}

View File

@@ -0,0 +1,36 @@
{
"description": "项目配置文件。",
"packOptions": {
"ignore": []
},
"setting": {
"urlCheck": false,
"es6": true,
"postcss": false,
"minified": false,
"newFeature": true,
"bigPackageSizeSupport": true
},
"compileType": "miniprogram",
"libVersion": "",
"appid": "wx89f1cd89fbc55f54",
"projectname": "优艺家沙发翻新",
"condition": {
"search": {
"current": -1,
"list": []
},
"conversation": {
"current": -1,
"list": []
},
"game": {
"current": -1,
"list": []
},
"miniprogram": {
"current": -1,
"list": []
}
}
}

View File

@@ -0,0 +1,22 @@
{
"libVersion": "3.13.0",
"projectname": "mp-weixin",
"condition": {},
"setting": {
"urlCheck": false,
"coverView": false,
"lazyloadPlaceholderEnable": false,
"skylineRenderEnable": false,
"preloadBackgroundData": false,
"autoAudits": false,
"useApiHook": true,
"showShadowRootInWxmlPanel": false,
"useStaticServer": false,
"useLanDebug": false,
"showES6CompileOption": false,
"compileHotReLoad": true,
"checkInvalidKey": true,
"ignoreDevUnusedFiles": true,
"bigPackageSizeSupport": true
}
}

View File

@@ -0,0 +1,48 @@
# 静态资源说明
## 目录结构
```
static/
├── icons/ # 图标文件
│ ├── home.svg # 首页图标(未选中)
│ ├── home-active.svg # 首页图标(选中)
│ ├── cases.svg # 案例图标(未选中)
│ ├── cases-active.svg # 案例图标(选中)
│ ├── service.svg # 服务图标(未选中)
│ ├── service-active.svg # 服务图标(选中)
│ ├── user.svg # 我的图标(未选中)
│ ├── user-active.svg # 我的图标(选中)
│ └── README.md # 图标转换说明
├── images/ # 图片资源
│ ├── default-avatar.svg # 默认头像
│ └── logo.svg # 公司Logo
└── mock/ # Mock数据图片
├── banner1.svg # 轮播图1
├── banner2.svg # 轮播图2
├── banner3.svg # 轮播图3
├── case1-before.svg # 案例1翻新前
├── case1-after.svg # 案例1翻新后
└── ... # 更多案例图片
```
## 重要说明
### TabBar 图标
微信小程序 TabBar **只支持 PNG 格式**,请参考 `icons/README.md` 将 SVG 转换为 PNG。
### 图片尺寸规范
1. **轮播图**:建议尺寸 750x320 像素
2. **案例图片**:建议尺寸 750x500 像素
3. **图标**:建议使用 PNG 格式,支持透明背景
4. **颜色规范**
- 主色:#D4A574
- 选中色:#D4A574
- 未选中色:#999999
## 注意事项
- 图片需要进行压缩优化,减小文件体积
- 图标建议使用纯色,便于主题切换
- 正式上线前需替换 Mock 图片为真实图片

View File

@@ -0,0 +1,54 @@
# 图标转换说明
## 问题
微信小程序 TabBar 图标只支持 PNG 格式,不支持 SVG。
## 解决方案
### 方法一:在线转换(推荐)
1. 访问 https://svgtopng.com/ 或 https://cloudconvert.com/svg-to-png
2. 上传 SVG 文件
3. 设置输出尺寸为 81x81 像素
4. 下载 PNG 文件并替换到 static/icons/ 目录
### 方法二:使用设计工具
1. 使用 Figma / Sketch / PS 打开 SVG
2. 导出为 81x81 像素的 PNG
3. 保存到 static/icons/ 目录
### 方法三:使用命令行工具
安装 sharp 或 imagemagick
```bash
# 使用 Node.js sharp
npm install sharp
node convert-icons.js
# 或使用 ImageMagick
convert home.svg -resize 81x81 home.png
```
## 需要转换的文件
| SVG 文件 | 输出 PNG | 尺寸 |
|----------|----------|------|
| home.svg | home.png | 81x81 |
| home-active.svg | home-active.png | 81x81 |
| cases.svg | cases.png | 81x81 |
| cases-active.svg | cases-active.png | 81x81 |
| service.svg | service.png | 81x81 |
| service-active.svg | service-active.png | 81x81 |
| user.svg | user.png | 81x81 |
| user-active.svg | user-active.png | 81x81 |
## 配色参考
- 未选中颜色:#999999
- 选中颜色:#D4A574(主题色)
## 图标设计规范
1. 图标尺寸81x81 像素
2. 安全区域:边距 10 像素
3. 图标风格:线性或填充图标
4. 背景:透明

Binary file not shown.

After

Width:  |  Height:  |  Size: 481 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 481 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 833 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 830 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 533 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 530 B

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="200" height="200">
<circle cx="100" cy="100" r="100" fill="#E8E8E8"/>
<circle cx="100" cy="75" r="35" fill="#BDBDBD"/>
<ellipse cx="100" cy="155" rx="50" ry="35" fill="#BDBDBD"/>
</svg>

After

Width:  |  Height:  |  Size: 261 B

View File

@@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="200" height="200">
<defs>
<linearGradient id="logoGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#D4A574"/>
<stop offset="100%" style="stop-color:#B8895A"/>
</linearGradient>
</defs>
<circle cx="100" cy="100" r="95" fill="url(#logoGradient)"/>
<text x="100" y="115" text-anchor="middle" font-size="48" font-weight="bold" fill="white" font-family="Arial">优艺家</text>
</svg>

After

Width:  |  Height:  |  Size: 511 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -0,0 +1,11 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 750 320" width="750" height="320">
<defs>
<linearGradient id="bannerGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#D4A574"/>
<stop offset="100%" style="stop-color:#B8895A"/>
</linearGradient>
</defs>
<rect width="750" height="320" fill="url(#bannerGradient)"/>
<text x="375" y="140" text-anchor="middle" font-size="48" font-weight="bold" fill="white" font-family="Arial">专业沙发翻新服务</text>
<text x="375" y="200" text-anchor="middle" font-size="28" fill="rgba(255,255,255,0.8)" font-family="Arial">让旧沙发焕发新生</text>
</svg>

After

Width:  |  Height:  |  Size: 669 B

View File

@@ -0,0 +1,11 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 750 320" width="750" height="320">
<defs>
<linearGradient id="bannerGradient2" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#67C23A"/>
<stop offset="100%" style="stop-color:#529b2e"/>
</linearGradient>
</defs>
<rect width="750" height="320" fill="url(#bannerGradient2)"/>
<text x="375" y="140" text-anchor="middle" font-size="48" font-weight="bold" fill="white" font-family="Arial">十年品质保证</text>
<text x="375" y="200" text-anchor="middle" font-size="28" fill="rgba(255,255,255,0.8)" font-family="Arial">质保期内免费维护</text>
</svg>

After

Width:  |  Height:  |  Size: 665 B

View File

@@ -0,0 +1,11 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 750 320" width="750" height="320">
<defs>
<linearGradient id="bannerGradient3" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#409EFF"/>
<stop offset="100%" style="stop-color:#337ecc"/>
</linearGradient>
</defs>
<rect width="750" height="320" fill="url(#bannerGradient3)"/>
<text x="375" y="140" text-anchor="middle" font-size="48" font-weight="bold" fill="white" font-family="Arial">免费上门评估</text>
<text x="375" y="200" text-anchor="middle" font-size="28" fill="rgba(255,255,255,0.8)" font-family="Arial">专业师傅为您量身定制方案</text>
</svg>

After

Width:  |  Height:  |  Size: 677 B

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 750 500" width="750" height="500">
<rect width="750" height="500" fill="#D4A574"/>
<text x="375" y="230" text-anchor="middle" font-size="36" fill="rgba(255,255,255,0.8)" font-family="Arial">翻新后</text>
<text x="375" y="280" text-anchor="middle" font-size="24" fill="rgba(255,255,255,0.6)" font-family="Arial">欧式真皮沙发</text>
</svg>

After

Width:  |  Height:  |  Size: 406 B

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 750 500" width="750" height="500">
<rect width="750" height="500" fill="#8B7355"/>
<text x="375" y="230" text-anchor="middle" font-size="36" fill="rgba(255,255,255,0.6)" font-family="Arial">翻新前</text>
<text x="375" y="280" text-anchor="middle" font-size="24" fill="rgba(255,255,255,0.4)" font-family="Arial">欧式真皮沙发</text>
</svg>

After

Width:  |  Height:  |  Size: 406 B

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 750 500" width="750" height="500">
<rect width="750" height="500" fill="#67C23A"/>
<text x="375" y="230" text-anchor="middle" font-size="36" fill="rgba(255,255,255,0.8)" font-family="Arial">翻新后</text>
<text x="375" y="280" text-anchor="middle" font-size="24" fill="rgba(255,255,255,0.6)" font-family="Arial">现代简约布艺沙发</text>
</svg>

After

Width:  |  Height:  |  Size: 412 B

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 750 500" width="750" height="500">
<rect width="750" height="500" fill="#6B8E6B"/>
<text x="375" y="230" text-anchor="middle" font-size="36" fill="rgba(255,255,255,0.6)" font-family="Arial">翻新前</text>
<text x="375" y="280" text-anchor="middle" font-size="24" fill="rgba(255,255,255,0.4)" font-family="Arial">现代简约布艺沙发</text>
</svg>

After

Width:  |  Height:  |  Size: 412 B

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 750 500" width="750" height="500">
<rect width="750" height="500" fill="#F5F5DC"/>
<text x="375" y="230" text-anchor="middle" font-size="36" fill="rgba(0,0,0,0.5)" font-family="Arial">翻新后</text>
<text x="375" y="280" text-anchor="middle" font-size="24" fill="rgba(0,0,0,0.3)" font-family="Arial">美式复古沙发</text>
</svg>

After

Width:  |  Height:  |  Size: 394 B

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 750 500" width="750" height="500">
<rect width="750" height="500" fill="#5D4037"/>
<text x="375" y="230" text-anchor="middle" font-size="36" fill="rgba(255,255,255,0.6)" font-family="Arial">翻新前</text>
<text x="375" y="280" text-anchor="middle" font-size="24" fill="rgba(255,255,255,0.4)" font-family="Arial">美式复古沙发</text>
</svg>

After

Width:  |  Height:  |  Size: 406 B

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 750 500" width="750" height="500">
<rect width="750" height="500" fill="#607D8B"/>
<text x="375" y="230" text-anchor="middle" font-size="36" fill="rgba(255,255,255,0.8)" font-family="Arial">翻新后</text>
<text x="375" y="280" text-anchor="middle" font-size="24" fill="rgba(255,255,255,0.6)" font-family="Arial">功能沙发</text>
</svg>

After

Width:  |  Height:  |  Size: 400 B

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 750 500" width="750" height="500">
<rect width="750" height="500" fill="#455A64"/>
<text x="375" y="230" text-anchor="middle" font-size="36" fill="rgba(255,255,255,0.6)" font-family="Arial">翻新前</text>
<text x="375" y="280" text-anchor="middle" font-size="24" fill="rgba(255,255,255,0.4)" font-family="Arial">功能沙发</text>
</svg>

After

Width:  |  Height:  |  Size: 400 B

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 750 500" width="750" height="500">
<rect width="750" height="500" fill="#A1887F"/>
<text x="375" y="230" text-anchor="middle" font-size="36" fill="rgba(255,255,255,0.8)" font-family="Arial">翻新后</text>
<text x="375" y="280" text-anchor="middle" font-size="24" fill="rgba(255,255,255,0.6)" font-family="Arial">中式红木沙发垫</text>
</svg>

After

Width:  |  Height:  |  Size: 409 B

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 750 500" width="750" height="500">
<rect width="750" height="500" fill="#8D6E63"/>
<text x="375" y="230" text-anchor="middle" font-size="36" fill="rgba(255,255,255,0.6)" font-family="Arial">翻新前</text>
<text x="375" y="280" text-anchor="middle" font-size="24" fill="rgba(255,255,255,0.4)" font-family="Arial">中式红木沙发垫</text>
</svg>

After

Width:  |  Height:  |  Size: 409 B

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 750 500" width="750" height="500">
<rect width="750" height="500" fill="#263238"/>
<text x="375" y="230" text-anchor="middle" font-size="36" fill="rgba(255,255,255,0.8)" font-family="Arial">翻新后</text>
<text x="375" y="280" text-anchor="middle" font-size="24" fill="rgba(255,255,255,0.6)" font-family="Arial">办公室皮沙发组合</text>
</svg>

After

Width:  |  Height:  |  Size: 412 B

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 750 500" width="750" height="500">
<rect width="750" height="500" fill="#37474F"/>
<text x="375" y="230" text-anchor="middle" font-size="36" fill="rgba(255,255,255,0.6)" font-family="Arial">翻新前</text>
<text x="375" y="280" text-anchor="middle" font-size="24" fill="rgba(255,255,255,0.4)" font-family="Arial">办公室皮沙发组合</text>
</svg>

After

Width:  |  Height:  |  Size: 412 B

View File

@@ -0,0 +1,60 @@
"use strict";
const ENV = new UTSJSONObject(
{
// 开发环境
development: new UTSJSONObject({
baseUrl: "http://localhost:3000/api",
imageBaseUrl: "http://localhost:3000"
}),
// 生产环境
production: new UTSJSONObject({
baseUrl: "https://api.youyijia.com/api",
imageBaseUrl: "https://api.youyijia.com"
})
}
// 当前环境 - 切换为 'production' 上线
);
const getEnvConfig = () => {
return new UTSJSONObject({
baseUrl: ENV.development.baseUrl,
imageBaseUrl: ENV.development.imageBaseUrl
});
};
const PAGE_SIZE = 10;
new UTSJSONObject(
{
maxSize: 5 * 1024 * 1024,
maxCount: 9,
accept: ["image/jpeg", "image/png", "image/gif"]
}
// 缓存Key
);
const STORAGE_KEYS = new UTSJSONObject(
{
TOKEN: "user_token",
USER_INFO: "user_info",
FAVORITES: "user_favorites",
SEARCH_HISTORY: "search_history"
}
// 沙发分类
);
const SOFA_CATEGORIES = [
new UTSJSONObject({ id: "all", name: "全部" }),
new UTSJSONObject({ id: "leather", name: "皮沙发" }),
new UTSJSONObject({ id: "fabric", name: "布艺沙发" }),
new UTSJSONObject({ id: "functional", name: "功能沙发" }),
new UTSJSONObject({ id: "antique", name: "古典沙发" }),
new UTSJSONObject({ id: "office", name: "办公沙发" })
];
const SERVICE_TYPES = [
new UTSJSONObject({ id: "repair", name: "局部修复", icon: "/static/icons/repair.png" }),
new UTSJSONObject({ id: "recolor", name: "改色翻新", icon: "/static/icons/recolor.png" }),
new UTSJSONObject({ id: "refurbish", name: "整体翻新", icon: "/static/icons/refurbish.png" }),
new UTSJSONObject({ id: "custom", name: "定制换皮", icon: "/static/icons/custom.png" })
];
exports.PAGE_SIZE = PAGE_SIZE;
exports.SERVICE_TYPES = SERVICE_TYPES;
exports.SOFA_CATEGORIES = SOFA_CATEGORIES;
exports.STORAGE_KEYS = STORAGE_KEYS;
exports.getEnvConfig = getEnvConfig;
//# sourceMappingURL=../../.sourcemap/mp-weixin/utils/config.js.map

View File

@@ -0,0 +1,178 @@
"use strict";
[
new UTSJSONObject({
id: "1",
image: "/static/mock/banner1.svg",
title: "专业沙发翻新服务",
link: "/pages/service/index"
}),
new UTSJSONObject({
id: "2",
image: "/static/mock/banner2.svg",
title: "十年品质保证",
link: "/pages/about/index"
}),
new UTSJSONObject({
id: "3",
image: "/static/mock/banner3.svg",
title: "免费上门评估",
link: "/pages/booking/index"
})
];
[
new UTSJSONObject({
id: "1",
title: "欧式真皮沙发翻新",
category: "leather",
categoryName: "皮沙发",
beforeImages: ["/static/mock/case1-before.svg"],
afterImages: ["/static/mock/case1-after.svg"],
coverImage: "/static/mock/case1-after.svg",
description: "这款欧式真皮沙发使用多年后出现皮面老化、褪色问题,经过我们专业的翻新处理,焕然一新。采用进口头层牛皮,色泽均匀,手感细腻。",
material: "进口头层牛皮",
duration: "7天",
price: "¥3800",
views: 1256,
likes: 89,
createTime: "2026-01-15"
}),
new UTSJSONObject({
id: "2",
title: "现代简约布艺沙发翻新",
category: "fabric",
categoryName: "布艺沙发",
beforeImages: ["/static/mock/case2-before.svg"],
afterImages: ["/static/mock/case2-after.svg"],
coverImage: "/static/mock/case2-after.svg",
description: "布艺沙发使用时间长了容易脏污、起球,这款沙发经过整体换布处理,选用高品质科技布,防水防污,易于打理。",
material: "高品质科技布",
duration: "5天",
price: "¥2200",
views: 986,
likes: 67,
createTime: "2026-01-12"
}),
new UTSJSONObject({
id: "3",
title: "美式复古沙发改色翻新",
category: "leather",
categoryName: "皮沙发",
beforeImages: ["/static/mock/case3-before.svg"],
afterImages: ["/static/mock/case3-after.svg"],
coverImage: "/static/mock/case3-after.svg",
description: "客户希望将原本深棕色的沙发改为更现代的米白色,我们采用专业改色工艺,色泽持久不脱落,触感保持柔软。",
material: "专业皮革改色",
duration: "6天",
price: "¥2800",
views: 756,
likes: 45,
createTime: "2026-01-10"
}),
new UTSJSONObject({
id: "4",
title: "功能沙发维修翻新",
category: "functional",
categoryName: "功能沙发",
beforeImages: ["/static/mock/case4-before.svg"],
afterImages: ["/static/mock/case4-after.svg"],
coverImage: "/static/mock/case4-after.svg",
description: "功能沙发的电动机构出现故障,同时皮面也有磨损。我们更换了电机和控制系统,并对皮面进行了局部修复。",
material: "原装配件+局部修复",
duration: "4天",
price: "¥1800",
views: 623,
likes: 38,
createTime: "2026-01-08"
}),
new UTSJSONObject({
id: "5",
title: "中式红木沙发垫翻新",
category: "antique",
categoryName: "古典沙发",
beforeImages: ["/static/mock/case5-before.svg"],
afterImages: ["/static/mock/case5-after.svg"],
coverImage: "/static/mock/case5-after.svg",
description: "红木沙发的坐垫和靠垫使用多年已经塌陷变形,我们重新填充高密度海绵,并更换了丝绸面料,古典韵味十足。",
material: "高密度海绵+丝绸面料",
duration: "5天",
price: "¥2500",
views: 512,
likes: 32,
createTime: "2026-01-05"
}),
new UTSJSONObject({
id: "6",
title: "办公室皮沙发组合翻新",
category: "office",
categoryName: "办公沙发",
beforeImages: ["/static/mock/case6-before.svg"],
afterImages: ["/static/mock/case6-after.svg"],
coverImage: "/static/mock/case6-after.svg",
description: "企业办公室的沙发组合整体翻新包括一套3+1+1沙发。采用耐磨商务皮革简约大气提升企业形象。",
material: "商务耐磨皮革",
duration: "10天",
price: "¥8800",
views: 445,
likes: 28,
createTime: "2026-01-02"
})
];
[
new UTSJSONObject({
step: 1,
title: "在线预约",
description: "通过小程序或电话预约上门服务",
icon: "/static/icons/step1.png"
}),
new UTSJSONObject({
step: 2,
title: "上门评估",
description: "专业师傅免费上门查看沙发状况",
icon: "/static/icons/step2.png"
}),
new UTSJSONObject({
step: 3,
title: "方案报价",
description: "根据沙发情况提供翻新方案和报价",
icon: "/static/icons/step3.png"
}),
new UTSJSONObject({
step: 4,
title: "确认订单",
description: "确认方案后签订服务合同",
icon: "/static/icons/step4.png"
}),
new UTSJSONObject({
step: 5,
title: "专业翻新",
description: "工厂或上门进行专业翻新作业",
icon: "/static/icons/step5.png"
}),
new UTSJSONObject({
step: 6,
title: "验收交付",
description: "翻新完成后客户验收,满意付款",
icon: "/static/icons/step6.png"
})
];
new UTSJSONObject(
{
name: "优艺家沙发翻新",
slogan: "让旧沙发焕发新生",
description: '优艺家是一家专业从事沙发翻新、维修、改色的服务公司,拥有十余年行业经验。我们秉承"品质至上、客户第一"的服务理念,为千家万户提供专业的沙发翻新服务。',
phone: "400-888-8888",
wechat: "youyijia2026",
address: "上海市浦东新区张江高科技园区",
workTime: "周一至周日 9:00-18:00",
features: [
new UTSJSONObject({ title: "专业团队", desc: "10年+从业经验" }),
new UTSJSONObject({ title: "品质保证", desc: "质保期内免费维护" }),
new UTSJSONObject({ title: "上门服务", desc: "免费上门评估" }),
new UTSJSONObject({ title: "价格透明", desc: "无隐形消费" })
]
}
/**
* 获取Mock数据
*/
);
//# sourceMappingURL=../../.sourcemap/mp-weixin/utils/mock.js.map

View File

@@ -0,0 +1,169 @@
"use strict";
const common_vendor = require("../common/vendor.js");
const utils_config = require("./config.js");
require("./mock.js");
class RequestOptions extends UTS.UTSType {
static get$UTSMetadata$() {
return {
kind: 2,
get fields() {
return {
url: { type: String, optional: false },
method: { type: "Unknown", optional: true },
data: { type: "Unknown", optional: true },
header: { type: "Unknown", optional: true },
showLoading: { type: Boolean, optional: true },
loadingText: { type: String, optional: true }
};
},
name: "RequestOptions"
};
}
constructor(options, metadata = RequestOptions.get$UTSMetadata$(), isJSONParse = false) {
super();
this.__props__ = UTS.UTSType.initProps(options, metadata, isJSONParse);
this.url = this.__props__.url;
this.method = this.__props__.method;
this.data = this.__props__.data;
this.header = this.__props__.header;
this.showLoading = this.__props__.showLoading;
this.loadingText = this.__props__.loadingText;
delete this.__props__;
}
}
class ResponseData extends UTS.UTSType {
static get$UTSMetadata$() {
return {
kind: 2,
get fields() {
return {
code: { type: Number, optional: false },
message: { type: String, optional: false },
data: { type: "Any", optional: false }
};
},
name: "ResponseData"
};
}
constructor(options, metadata = ResponseData.get$UTSMetadata$(), isJSONParse = false) {
super();
this.__props__ = UTS.UTSType.initProps(options, metadata, isJSONParse);
this.code = this.__props__.code;
this.message = this.__props__.message;
this.data = this.__props__.data;
delete this.__props__;
}
}
const requestInterceptor = (options) => {
const token = common_vendor.index.getStorageSync(utils_config.STORAGE_KEYS.TOKEN);
if (token != "") {
if (options.header == null) {
options.header = new UTSJSONObject({});
}
options.header["Authorization"] = `Bearer ${token}`;
}
return options;
};
const responseInterceptor = (response) => {
var _a, _b, _c;
const statusCode = response["statusCode"];
const data = response["data"];
if (statusCode == 200) {
const code = (_a = data["code"]) !== null && _a !== void 0 ? _a : 0;
if (code == 0 || code == 200) {
return new ResponseData({
code: 0,
message: "success",
data: data["data"]
});
} else if (code == 401) {
common_vendor.index.removeStorageSync(utils_config.STORAGE_KEYS.TOKEN);
common_vendor.index.showToast({
title: "请重新登录",
icon: "none"
});
return new ResponseData({
code,
message: (_b = data["message"]) !== null && _b !== void 0 ? _b : "请重新登录",
data: null
});
} else {
return new ResponseData({
code,
message: (_c = data["message"]) !== null && _c !== void 0 ? _c : "请求失败",
data: null
});
}
} else {
return new ResponseData({
code: statusCode,
message: "网络请求失败",
data: null
});
}
};
const request = (options) => {
return new Promise((resolve, reject) => {
var _b, _c;
const finalOptions = requestInterceptor(options);
if (finalOptions.showLoading == true) {
common_vendor.index.showLoading({
title: (_b = finalOptions.loadingText) !== null && _b !== void 0 ? _b : "加载中..."
});
}
const config = utils_config.getEnvConfig();
const baseUrl = config["baseUrl"];
common_vendor.index.request({
url: baseUrl + finalOptions.url,
method: (_c = finalOptions.method) !== null && _c !== void 0 ? _c : "GET",
data: finalOptions.data,
header: finalOptions.header,
success: (res) => {
if (finalOptions.showLoading == true) {
common_vendor.index.hideLoading();
}
const result = responseInterceptor(res);
if (result.code == 0) {
resolve(result);
} else {
common_vendor.index.showToast({
title: result.message,
icon: "none"
});
reject(result);
}
},
fail: (err) => {
if (finalOptions.showLoading == true) {
common_vendor.index.hideLoading();
}
common_vendor.index.showToast({
title: "网络连接失败",
icon: "none"
});
reject(new ResponseData({
code: -1,
message: "网络连接失败",
data: null
}));
}
});
});
};
const get = (url, data = null) => {
return request(new RequestOptions({
url,
method: "GET",
data
}));
};
const post = (url, data = null) => {
return request(new RequestOptions({
url,
method: "POST",
data
}));
};
exports.get = get;
exports.post = post;
//# sourceMappingURL=../../.sourcemap/mp-weixin/utils/request.js.map

View File

@@ -0,0 +1,209 @@
page {
height: 100%;
display: flex;
flex-direction: column;
}
ad-draw,
ad-fullscreen-video,
ad-interactive,
ad-interstitial,
ad-rewarded-video,
ad,
animation-view,
audio,
block,
button,
camera,
canvas,
checkbox-group,
checkbox,
cover-image,
cover-view,
custom-tab-bar,
editor,
form,
icon,
image,
input,
label,
list-item,
list-view,
live-player,
live-pusher,
map,
match-media,
movable-area,
movable-view,
navigation-bar,
navigator,
open-data,
page-meta,
picker-view,
picker,
progress,
radio-group,
radio,
rich-text,
scroll-view,
slider,
sticky-header,
sticky-section,
swiper-item,
swiper,
switch,
template,
text,
textarea,
unicloud-db,
video,
view,
web-view {
position: relative;
box-sizing: border-box;
display: flex;
flex-direction: column;
flex-shrink: 0;
flex-grow: 0;
flex-basis: auto;
align-items: stretch;
align-content: stretch;
justify-content: flex-start;
min-height: 0px;
min-width: 0px;
border-width: medium;
}
ad-draw[hidden],
ad-fullscreen-video[hidden],
ad-interactive[hidden],
ad-interstitial[hidden],
ad-rewarded-video[hidden],
ad[hidden],
animation-view[hidden],
audio[hidden],
block[hidden],
button[hidden],
camera[hidden],
canvas[hidden],
checkbox-group[hidden],
checkbox[hidden],
cover-image[hidden],
cover-view[hidden],
custom-tab-bar[hidden],
editor[hidden],
form[hidden],
icon[hidden],
image[hidden],
input[hidden],
label[hidden],
list-item[hidden],
list-view[hidden],
live-player[hidden],
live-pusher[hidden],
map[hidden],
match-media[hidden],
movable-area[hidden],
movable-view[hidden],
navigation-bar[hidden],
navigator[hidden],
open-data[hidden],
page-meta[hidden],
picker-view[hidden],
picker[hidden],
progress[hidden],
radio-group[hidden],
radio[hidden],
rich-text[hidden],
scroll-view[hidden],
slider[hidden],
sticky-header[hidden],
sticky-section[hidden],
swiper-item[hidden],
swiper[hidden],
switch[hidden],
template[hidden],
text[hidden],
textarea[hidden],
unicloud-db[hidden],
video[hidden],
view[hidden],
web-view[hidden] {
display: none !important;
}
/* 与开发者元素接触的非滚动容器 */
view,
label,
swiper,
swiper-item,
movable-area,
movable-view,
cover-view,
list-item,
navigator,
radio-group,
checkbox-group {
overflow: hidden;
}
scroll-view {
width: auto;
}
swiper-item {
position: absolute;
}
button {
margin: 0;
}
slider {
margin: 0px;
padding: 5px 0px;
}
text {
display: inline;
}
text[hidden] {
display: none !important;
}
text,
textarea,
label {
line-height: 1.2;
overflow: hidden;
flex-basis: auto;
letter-spacing: 0;
}
rich-text {
line-height: 1.5;
}
progress {
flex-direction: row;
align-items: center;
}
radio,
checkbox {
flex-direction: row;
align-items: center;
}
/*
* 目前仅适配微信小程序,其他小程序平台需要额外适配
*/
radio .wx-radio-wrapper{
display: flex;
flex-direction: inherit;
align-content: inherit;
justify-content: inherit;
align-items: inherit;
flex: 1;
}