Lufaneng 11 months ago
parent d827e4e6c0
commit 0abb3ae117

@ -75,7 +75,8 @@
"path" : "generate-record/generate-record", "path" : "generate-record/generate-record",
"style" : "style" :
{ {
"navigationBarTitleText" : "图纸生成记录" "navigationBarTitleText" : "图纸生成记录",
"enablePullDownRefresh":true
} }
}, },
{ {
@ -119,18 +120,18 @@
"pagePath": "pages/index/index", "pagePath": "pages/index/index",
"iconPath": "static/tabbar/index.png", "iconPath": "static/tabbar/index.png",
"selectedIconPath": "static/tabbar/index_HL.png", "selectedIconPath": "static/tabbar/index_HL.png",
"text": "首页" "text": "图纸"
}, },
{ {
"pagePath": "pages/order/order", "pagePath": "pages/order/order",
"iconPath": "static/tabbar/appointment.png", "iconPath": "static/tabbar/order.png",
"selectedIconPath": "static/tabbar/appointment_HL.png", "selectedIconPath": "static/tabbar/order_HL.png",
"text": "订单" "text": "订单"
}, },
{ {
"pagePath": "pages/consumption/consumption", "pagePath": "pages/consumption/consumption",
"iconPath": "static/tabbar/appointment.png", "iconPath": "static/tabbar/xiaofei.png",
"selectedIconPath": "static/tabbar/appointment_HL.png", "selectedIconPath": "static/tabbar/xiaofei_HL.png",
"text": "消费" "text": "消费"
}, },
{ {

@ -2,11 +2,7 @@
<view class="container"> <view class="container">
<!-- 顶部图片和标题 --> <!-- 顶部图片和标题 -->
<view class="header-section"> <view class="header-section">
<image <image class="header-image" src="/static/imgs/indexImg.png" mode="aspectFill"></image>
class="header-image"
src="/static/imgs/indexImg.png"
mode="aspectFill"
></image>
<view class="header-overlay"> <view class="header-overlay">
<view class="header-title">生成电梯图纸</view> <view class="header-title">生成电梯图纸</view>
<view class="header-subtitle"> <view class="header-subtitle">
@ -18,42 +14,27 @@
<!-- 选择图纸模板 --> <!-- 选择图纸模板 -->
<view class="section"> <view class="section">
<view class="section-title">选择图纸模板</view> <view class="section-title">选择图纸模板</view>
<view class="template-grid"> <uv-skeletons v-if="loading" :loading="loading" :skeleton="[{
<view type: 'flex',
class="template-item" num: 2,
:class="{ active: selectedTemplate === 'passenger' }" gap: '20rpx',
@click="selectTemplate('passenger')" children:[{
> type: 'custom',
<u-icon name="edit-pen" color="#4285f4" size="24"></u-icon> num: 1,
<view class="template-name">乘客电梯标准图纸</view> gap: '20rpx',
<view class="template-desc">适用于住宅商业建筑</view> style: 'width: 300rpx;height:200rpx;marginLeft: 10rpx;'
</view> },{
<view type: 'custom',
class="template-item" num: 1,
:class="{ active: selectedTemplate === 'freight' }" gap: '20rpx',
@click="selectTemplate('freight')" style: 'width: 300rpx;height:200rpx;marginLeft: 10rpx;'
> }]
<u-icon name="car" color="#4285f4" size="24"></u-icon> }]"></uv-skeletons>
<view class="template-name">货运电梯专用图纸</view> <view class="template-grid" v-else>
<view class="template-desc">适用于仓库工厂</view> <view class="template-item" :class="{ active: currentTemplate.id === item.id }"
</view> @click="selectTemplate(item)" v-for="item in templateList" :key="item.id">
<view <view class="template-name">{{item.name}}</view>
class="template-item" <view class="template-desc">{{item.description}}</view>
:class="{ active: selectedTemplate === 'medical' }"
@click="selectTemplate('medical')"
>
<u-icon name="plus-circle" color="#4285f4" size="24"></u-icon>
<view class="template-name">医用电梯专业图纸</view>
<view class="template-desc">适用于医院医疗场所</view>
</view>
<view
class="template-item"
:class="{ active: selectedTemplate === 'sightseeing' }"
@click="selectTemplate('sightseeing')"
>
<u-icon name="eye" color="#4285f4" size="24"></u-icon>
<view class="template-name">观光电梯定制图纸</view>
<view class="template-desc">适用于商场酒店</view>
</view> </view>
</view> </view>
</view> </view>
@ -61,25 +42,19 @@
<!-- 设置参数 --> <!-- 设置参数 -->
<view class="section"> <view class="section">
<view class="section-title">设置参数</view> <view class="section-title">设置参数</view>
<view class="form"> <uv-skeletons v-if="loading" :loading="loading" :skeleton="[{
<uv-form type: 'line',
labelAlign="left" num: 3,
labelWidth="auto" gap: '20rpx'
labelPosition="left" }]"></uv-skeletons>
:model="formField" <view class="form" v-else>
:rules="rules" <uv-form labelAlign="left" labelWidth="auto" labelPosition="left" :model="formField" :rules="rules"
ref="form" ref="form">
> <uv-form-item :prop="item.key" :label="item.name + ''" v-for="item in currentTemplate.params">
<uv-form-item prop="phone" label="电梯类型"> <uv-input :type="item.type === 'number' ? 'digit' : 'text'" v-model="item.value" color="#000"
<uv-input border="bottom" :placeholderStyle="{ color: '#666778' }" placeholder="请输入"></uv-input>
v-model="formField.phone"
color="#000"
border="none"
:placeholderStyle="{ color: '#666778' }"
placeholder="请输入"
></uv-input>
</uv-form-item> </uv-form-item>
<uv-form-item prop="password" label="载重kg"> <!-- <uv-form-item prop="password" label="载重kg">
<uv-input <uv-input
v-model="formField.password" v-model="formField.password"
color="#000" color="#000"
@ -134,56 +109,93 @@
v-model="formField.password" v-model="formField.password"
placeholder="请输入" placeholder="请输入"
></uv-textarea> ></uv-textarea>
</uv-form-item> </uv-form-item> -->
</uv-form> </uv-form>
</view> </view>
</view> </view>
<!-- 底部按钮 --> <!-- 底部按钮 -->
<view class="bottom-actions"> <view class="bottom-actions">
<uv-button <uv-button :loading="generating" @click="() => modalRef.open()" text="生成图纸" color="#3F70FF"></uv-button>
:loading="generating"
@click="viewHistory"
text="生成图纸"
color="#3F70FF"
></uv-button>
<uv-button @click="viewHistory" text="查看记录"></uv-button> <uv-button @click="viewHistory" text="查看记录"></uv-button>
</view> </view>
<uv-modal ref="modalRef" showCancelButton content='确定生成图纸?' @confirm="confirmGenerate"></uv-modal>
</view> </view>
</template> </template>
<script setup> <script setup>
import { ref, onMounted } from "vue"; import {
import { ref,
onMounted
} from "vue";
import {
onShow, onShow,
onLoad, onLoad,
onShareAppMessage, onShareAppMessage,
onShareTimeline, onShareTimeline,
onReachBottom, onReachBottom,
} from "@dcloudio/uni-app"; } from "@dcloudio/uni-app";
import { useAuthStore, useUserStore } from "@/store"; import {
import RPC from "@/utils/request"; useAuthStore,
import { usePermission } from "@/hooks/usePermission"; useUserStore
} from "@/store";
import RPC from "@/utils/request";
import {
usePermission
} from "@/hooks/usePermission";
const authStore = useAuthStore();
const userStore = useUserStore();
const loading = ref(false)
const generating = ref(false);
const modalRef = ref(null)
const confirmGenerate = () => {
const params = {}
currentTemplate.value.params.forEach(item => {
params[item.name] = item.value
})
RPC.post('/template_create_task', {template_id:currentTemplate.value.id,template_data:params}).then(() => {
const authStore = useAuthStore(); uni.showToast({
const userStore = useUserStore(); title: "图纸开始生成",
icon: "success",
const generating = ref(false); });
setTimeout(() => {
// uni.navigateTo({
const selectedTemplate = ref("passenger"); url: "/pagesA/generate-record/generate-record",
});
}, 1000)
modalRef.value.close()
})
}
const templateList = ref([])
const currentTemplate = ref({})
const getList = () => {
loading.value = true
RPC.post('/template/list', {
page: 1,
limit: -1
}).then(res => {
templateList.value = res.rows || []
currentTemplate.value = res.rows[0] ? JSON.parse(JSON.stringify(res.rows[0])) : {}
}).finally(() => {
loading.value = false
})
}
getList()
// //
const selectTemplate = (template) => { const selectTemplate = (item) => {
selectedTemplate.value = template; currentTemplate.value = JSON.parse(JSON.stringify(item));
}; };
const form = ref(null); const form = ref(null);
const formField = ref({ const formField = ref({
phone: "", phone: "",
password: "", password: "",
}); });
const rules = ref({ const rules = ref({
// 'phone': { // 'phone': {
// required: true, // required: true,
// message: '', // message: '',
@ -194,84 +206,42 @@ const rules = ref({
// message: '', // message: '',
// trigger: ['blur', 'change'] // trigger: ['blur', 'change']
// } // }
});
//
const generateDrawing = async () => {
if (!selectedTemplate.value) {
uni.showToast({
title: "请选择图纸模板",
icon: "none",
}); });
return;
}
generating.value = true;
try {
const params = {};
// API
// const result = await RPC.post('/api/generate-drawing', params)
uni.showToast({
title: "图纸生成中...",
icon: "loading",
duration: 2000,
});
//
setTimeout(() => {
uni.showToast({
title: "图纸生成成功",
icon: "success",
});
generating.value = false;
}, 2000);
} catch (error) {
console.error("生成图纸失败:", error);
uni.showToast({
title: "生成失败,请重试",
icon: "none",
});
generating.value = false;
}
};
// //
const viewHistory = () => { const viewHistory = () => {
console.log(111);
uni.navigateTo({ uni.navigateTo({
url: "/pagesA/generate-record/generate-record", url: "/pagesA/generate-record/generate-record",
}); });
}; };
// //
onShareAppMessage((data) => { onShareAppMessage((data) => {
console.log("🚀 ~ onShareAppMessage ~ data:", data); console.log("🚀 ~ onShareAppMessage ~ data:", data);
return { return {
title: "电梯图纸生成平台", title: "电梯图纸生成平台",
path: "/pages/index/index", path: "/pages/index/index",
}; };
}); });
// //
onShareTimeline((data) => { onShareTimeline((data) => {
console.log("🚀 ~ onShareTimeline ~ data:", data); console.log("🚀 ~ onShareTimeline ~ data:", data);
return { return {
title: "电梯图纸生成平台", title: "电梯图纸生成平台",
query: "a=1&b=2", query: "a=1&b=2",
}; };
}); });
onLoad(() => { onLoad(() => {
console.log("index-onLoad"); console.log("index-onLoad");
}); });
onShow(async () => { onShow(async () => {
console.log("test page onShow"); console.log("test page onShow");
const hasPermission = await usePermission(); const hasPermission = await usePermission();
console.log(hasPermission ? "已登录" : "跳转登录"); console.log(hasPermission ? "已登录" : "跳转登录");
// ... // ...
if(!hasPermission) { if (!hasPermission) {
authStore.signOut(); authStore.signOut();
uni.$uv.route("/pages/login/login"); uni.$uv.route("/pages/login/login");
} }
@ -279,18 +249,19 @@ onLoad(() => {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.container { .container {
font-size: 14px; font-size: 14px;
min-height: 100vh; min-height: 100vh;
background-color: #f8f8f8; background-color: #f8f8f8;
padding-bottom: 52px; padding-bottom: 52px;
/* #ifdef H5 */ /* #ifdef H5 */
padding-bottom: 102px; /* H5环境下需要更多空间 (50px按钮 + 50px tabBar + 2px间距) */ padding-bottom: 102px;
/* H5环境下需要更多空间 (50px按钮 + 50px tabBar + 2px间距) */
/* #endif */ /* #endif */
} }
.header-section { .header-section {
position: relative; position: relative;
height: 200px; height: 200px;
overflow: hidden; overflow: hidden;
@ -321,9 +292,9 @@ onLoad(() => {
font-size: 12px; font-size: 12px;
} }
} }
} }
.section { .section {
margin: 16px; margin: 16px;
background: white; background: white;
border-radius: 12px; border-radius: 12px;
@ -335,12 +306,14 @@ onLoad(() => {
color: #333; color: #333;
margin-bottom: 16px; margin-bottom: 16px;
} }
} }
.template-grid { .template-grid {
display: grid; display: grid;
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
gap: 12px; gap: 12px;
max-height: 200px;
overflow-y: auto;
.template-item { .template-item {
border: 1px solid #e5e5e5; border: 1px solid #e5e5e5;
@ -366,9 +339,9 @@ onLoad(() => {
color: #999; color: #999;
} }
} }
} }
.bottom-actions { .bottom-actions {
z-index: 999; z-index: 999;
position: fixed; position: fixed;
bottom: 0; bottom: 0;
@ -385,15 +358,16 @@ onLoad(() => {
width: 100%; width: 100%;
/* #ifdef H5 */ /* #ifdef H5 */
bottom: 50px; /* H5环境下给tabBar留出空间 */ bottom: 50px;
/* H5环境下给tabBar留出空间 */
/* #endif */ /* #endif */
} }
</style> </style>
<style lang="scss"> <style lang="scss">
.bottom-actions { .bottom-actions {
.uv-button-wrapper { .uv-button-wrapper {
width: 48%; width: 48%;
} }
} }
</style> </style>

@ -11,76 +11,40 @@
</view> </view>
<div class="main"> <div class="main">
<view class="form"> <view class="form">
<uv-form <uv-form labelAlign="right" labelWidth="50" labelPosition="top" :model="userInfo" :rules="rules"
labelAlign="right" ref="form">
labelWidth="50"
labelPosition="top"
:model="userInfo"
:rules="rules"
ref="form"
>
<uv-form-item prop="phone"> <uv-form-item prop="phone">
<div class="formLabel"> <div class="formLabel">
<img class="img" src="/static/imgs/phone.png" alt="" /> <img class="img" src="/static/imgs/phone.png" alt="" />
手机号 手机号
</div> </div>
<uv-input <uv-input v-model="userInfo.phone" color="#000" border="bottom"
v-model="userInfo.phone" :placeholderStyle="{ color: '#666778' }" placeholder="请输入用户名"></uv-input>
color="#000"
border="bottom"
:placeholderStyle="{ color: '#666778' }"
placeholder="请输入用户名"
></uv-input>
</uv-form-item> </uv-form-item>
<uv-form-item prop="password"> <uv-form-item prop="password">
<div class="formLabel"> <div class="formLabel">
<img class="img" src="/static/imgs/code.png" alt="" /> <img class="img" src="/static/imgs/code.png" alt="" />
验证码 验证码
</div> </div>
<uv-input <uv-input v-model="userInfo.password" color="#000" border="bottom"
v-model="userInfo.password" :placeholderStyle="{ color: '#666778' }" placeholder="请输入验证码">
color="#000"
border="bottom"
:placeholderStyle="{ color: '#666778' }"
placeholder="请输入验证码"
>
<template v-slot:suffix> <template v-slot:suffix>
<uv-code <uv-code ref="codeRef" @change="codeChange" seconds="20" changeText="X秒重新获取"></uv-code>
ref="codeRef"
@change="codeChange"
seconds="20"
changeText="X秒重新获取"
></uv-code>
<text style="color: #4d82fd" @click="getCode">{{ tips }}</text> <text style="color: #4d82fd" @click="getCode">{{ tips }}</text>
</template> </template>
</uv-input> </uv-input>
</uv-form-item> </uv-form-item>
</uv-form> </uv-form>
</view> </view>
<uv-button <uv-button @click="login" customStyle="margin-top:30px" text="登录" color="#3F70FF"></uv-button>
@click="login"
customStyle="margin-top:30px"
text="登录"
color="#3F70FF"
></uv-button>
<div class="wechatBox" v-if="showWechatLogin"> <div class="wechatBox" v-if="showWechatLogin">
<uv-divider text="第三方登录"></uv-divider> <uv-divider text="第三方登录"></uv-divider>
<uv-icon <uv-icon name="weixin-circle-fill" color="#5fc157" size="50" @click="wechatLogin"></uv-icon>
name="weixin-circle-fill"
color="#5fc157"
size="50"
@click="wechatLogin"
></uv-icon>
</div> </div>
</div> </div>
<!-- 微信登录绑定手机号弹窗 --> <!-- 微信登录绑定手机号弹窗 -->
<uv-popup <uv-popup ref="popup" mode="center" :closeOnClickOverlay="false" :round="10">
ref="popup"
mode="center"
:closeOnClickOverlay="false"
:round="10"
>
<view class="bind-phone-modal"> <view class="bind-phone-modal">
<view class="modal-header"> <view class="modal-header">
<view class="modal-title">绑定手机号</view> <view class="modal-title">绑定手机号</view>
@ -88,37 +52,17 @@
</view> </view>
<view class="modal-form"> <view class="modal-form">
<uv-form <uv-form :model="bindPhoneInfo" :rules="bindPhoneRules" ref="bindPhoneForm">
:model="bindPhoneInfo"
:rules="bindPhoneRules"
ref="bindPhoneForm"
>
<uv-form-item prop="phone"> <uv-form-item prop="phone">
<uv-input <uv-input v-model="bindPhoneInfo.phone" placeholder="请输入手机号" type="number" maxlength="11"
v-model="bindPhoneInfo.phone" border="surround"></uv-input>
placeholder="请输入手机号"
type="number"
maxlength="11"
border="surround"
></uv-input>
</uv-form-item> </uv-form-item>
<uv-form-item prop="code"> <uv-form-item prop="code">
<uv-input <uv-input v-model="bindPhoneInfo.code" placeholder="请输入验证码" border="surround">
v-model="bindPhoneInfo.code"
placeholder="请输入验证码"
border="surround"
>
<template v-slot:suffix> <template v-slot:suffix>
<uv-code <uv-code ref="bindCodeRef" @change="bindCodeChange" seconds="60"
ref="bindCodeRef" changeText="X秒重新获取"></uv-code>
@change="bindCodeChange" <text style="color: #4d82fd; font-size: 12px" @click="getBindCode">
seconds="60"
changeText="X秒重新获取"
></uv-code>
<text
style="color: #4d82fd; font-size: 12px"
@click="getBindCode"
>
{{ bindCodeTips }} {{ bindCodeTips }}
</text> </text>
</template> </template>
@ -135,11 +79,7 @@
> >
取消 取消
</uv-button> --> </uv-button> -->
<uv-button <uv-button type="primary" @click="confirmBindPhone" :loading="bindingPhone">
type="primary"
@click="confirmBindPhone"
:loading="bindingPhone"
>
确认绑定 确认绑定
</uv-button> </uv-button>
</view> </view>
@ -149,38 +89,45 @@
</template> </template>
<script setup> <script setup>
import { ref, onMounted } from "vue"; import {
import { ref,
onMounted
} from "vue";
import {
HOME_PATH, HOME_PATH,
LOGIN_PATH, LOGIN_PATH,
isTabBarPath, isTabBarPath,
removeQueryString, removeQueryString,
} from "@/router"; } from "@/router";
import { useAuthStore, useUserStore } from "@/store"; import {
import { onLoad } from "@dcloudio/uni-app"; useAuthStore,
useUserStore
import RPC from "@/utils/request"; } from "@/store";
import {
const authStore = useAuthStore(); onLoad
const userStore = useUserStore(); } from "@dcloudio/uni-app";
// import RPC from "@/utils/request";
const showWechatLogin = ref(false);
const authStore = useAuthStore();
// const userStore = useUserStore();
// const showBindPhoneModal = ref(false);
const popup = ref(null); //
const bindingPhone = ref(false); const showWechatLogin = ref(false);
const bindCodeTips = ref("获取验证码");
const bindCodeRef = ref(null); //
const bindPhoneForm = ref(null); // const showBindPhoneModal = ref(false);
const bindPhoneInfo = ref({ const popup = ref(null);
const bindingPhone = ref(false);
const bindCodeTips = ref("获取验证码");
const bindCodeRef = ref(null);
const bindPhoneForm = ref(null);
const bindPhoneInfo = ref({
phone: "", phone: "",
code: "", code: "",
}); });
const bindPhoneRules = ref({ const bindPhoneRules = ref({
phone: [ phone: [{
{
required: true, required: true,
message: "请输入手机号", message: "请输入手机号",
trigger: ["blur", "change"], trigger: ["blur", "change"],
@ -196,14 +143,14 @@ const bindPhoneRules = ref({
message: "请输入验证码", message: "请输入验证码",
trigger: ["blur", "change"], trigger: ["blur", "change"],
}, },
}); });
const tips = ref("获取验证码"); const tips = ref("获取验证码");
const codeChange = (text) => { const codeChange = (text) => {
tips.value = text; tips.value = text;
}; };
const codeRef = ref(null); const codeRef = ref(null);
const getCode = () => { const getCode = () => {
if (!userInfo.phone) { if (!userInfo.phone) {
uni.showToast({ uni.showToast({
title: "请填写手机号", title: "请填写手机号",
@ -232,41 +179,40 @@ const getCode = () => {
icon: "none", icon: "none",
}); });
} }
}; };
const form = ref(null); const form = ref(null);
const userInfo = ref({ const userInfo = ref({
phone: "", phone: "",
password: "", password: "",
}); });
const rules = ref({ const rules = ref({
phone: [ phone: [{
{
required: true, required: true,
message: "请输入手机号", message: "请输入手机号",
trigger: ["blur", "change"], trigger: ["blur", "change"],
}, },
{ // {
pattern: /^1[3-9]\d{9}$/, // pattern: /^1[3-9]\d{9}$/,
message: "请输入正确的手机号", // message: "",
trigger: ["blur", "change"], // trigger: ["blur", "change"],
}, // },
], ],
password: { password: {
required: true, required: true,
message: "请填写验证码", message: "请填写验证码",
trigger: ["blur", "change"], trigger: ["blur", "change"],
}, },
}); });
let redirect = HOME_PATH; let redirect = HOME_PATH;
onLoad((options) => { onLoad((options) => {
if (options.redirect && removeQueryString(options.redirect) !== LOGIN_PATH) { if (options.redirect && removeQueryString(options.redirect) !== LOGIN_PATH) {
redirect = decodeURIComponent(options.redirect); redirect = decodeURIComponent(options.redirect);
} }
}); });
// //
const checkEnvironment = () => { const checkEnvironment = () => {
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
// //
showWechatLogin.value = true; showWechatLogin.value = true;
@ -283,10 +229,10 @@ const checkEnvironment = () => {
// App // App
showWechatLogin.value = false; showWechatLogin.value = false;
// #endif // #endif
}; };
// //
const wechatLogin = () => { const wechatLogin = () => {
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
// //
// uni.login({ // uni.login({
@ -333,10 +279,10 @@ const wechatLogin = () => {
}); });
} }
// #endif // #endif
}; };
// //
const getBindCode = () => { const getBindCode = () => {
if (!bindPhoneInfo.value.phone) { if (!bindPhoneInfo.value.phone) {
uni.showToast({ uni.showToast({
title: "请输入手机号", title: "请输入手机号",
@ -392,15 +338,15 @@ const getBindCode = () => {
icon: "none", icon: "none",
}); });
} }
}; };
// //
const bindCodeChange = (text) => { const bindCodeChange = (text) => {
bindCodeTips.value = text; bindCodeTips.value = text;
}; };
// H5 // H5
const wechatH5Login = () => { const wechatH5Login = () => {
// #ifdef H5 // #ifdef H5
// URL // URL
const appId = "YOUR_WECHAT_APP_ID"; // AppID const appId = "YOUR_WECHAT_APP_ID"; // AppID
@ -419,7 +365,8 @@ const wechatH5Login = () => {
handleWechatH5Callback(code); handleWechatH5Callback(code);
} else { } else {
// //
const authUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${redirectUri}&response_type=code&scope=${scope}&state=${state}#wechat_redirect`; const authUrl =
`https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${redirectUri}&response_type=code&scope=${scope}&state=${state}#wechat_redirect`;
uni.showLoading({ uni.showLoading({
title: "正在跳转微信授权...", title: "正在跳转微信授权...",
@ -429,10 +376,10 @@ const wechatH5Login = () => {
window.location.href = authUrl; window.location.href = authUrl;
} }
// #endif // #endif
}; };
// H5 // H5
const handleWechatH5Callback = async (code) => { const handleWechatH5Callback = async (code) => {
// #ifdef H5 // #ifdef H5
try { try {
uni.showLoading({ uni.showLoading({
@ -464,8 +411,7 @@ const handleWechatH5Callback = async (code) => {
const url = new URL(window.location); const url = new URL(window.location);
url.searchParams.delete("code"); url.searchParams.delete("code");
url.searchParams.delete("state"); url.searchParams.delete("state");
window.history.replaceState( window.history.replaceState({},
{},
document.title, document.title,
url.pathname + url.search url.pathname + url.search
); );
@ -479,10 +425,10 @@ const handleWechatH5Callback = async (code) => {
}); });
} }
// #endif // #endif
}; };
// JS-SDK // JS-SDK
const initWechatJSSDK = () => { const initWechatJSSDK = () => {
// #ifdef H5 // #ifdef H5
// 使JS-SDK // 使JS-SDK
// JS-SDKhttps://res.wx.qq.com/open/js/jweixin-1.6.0.js // JS-SDKhttps://res.wx.qq.com/open/js/jweixin-1.6.0.js
@ -506,10 +452,10 @@ const initWechatJSSDK = () => {
// }); // });
// } // }
// #endif // #endif
}; };
// //
const confirmBindPhone = async () => { const confirmBindPhone = async () => {
try { try {
await bindPhoneForm.value.validate(); await bindPhoneForm.value.validate();
@ -549,19 +495,19 @@ const confirmBindPhone = async () => {
console.error("绑定手机号失败:", error); console.error("绑定手机号失败:", error);
bindingPhone.value = false; bindingPhone.value = false;
} }
}; };
// //
const closeBindPhoneModal = () => { const closeBindPhoneModal = () => {
popup.value.close(); popup.value.close();
bindPhoneInfo.value = { bindPhoneInfo.value = {
phone: "", phone: "",
code: "", code: "",
}; };
bindCodeTips.value = "获取验证码"; bindCodeTips.value = "获取验证码";
}; };
const login = async () => { const login = async () => {
await form.value.validate(); await form.value.validate();
console.log(userInfo.value); console.log(userInfo.value);
// RPC.post('/account/login', { // RPC.post('/account/login', {
@ -580,16 +526,37 @@ const login = async () => {
// url: redirect, // url: redirect,
// }); // });
// }) // })
authStore.setAccessToken("accessToken"); RPC.post('/login', {
setTimeout(() => { username: userInfo.value.phone,
password: userInfo.value.password,
}, {
custom: {
loading: true,
loadingText: '正在登录...'
},
})
.then((res) => {
authStore.setAccessToken(res.token);
RPC.post('/user/info', {
token: res.token,
})
.then((res) => {
userStore.setUserInfo(res)
uni.$uv.route({ uni.$uv.route({
type: isTabBarPath(redirect) ? "switchTab" : "redirectTo", type: isTabBarPath(redirect) ? "switchTab" : "redirectTo",
url: redirect, url: redirect,
}); });
}, 800); })
}; .finally(() => {
loading.value = false
})
})
.catch(() => {
loading.value = false
})
};
onMounted(() => { onMounted(() => {
checkEnvironment(); checkEnvironment();
// #ifdef H5 // #ifdef H5
@ -603,19 +570,17 @@ onMounted(() => {
// JS-SDK // JS-SDK
// initWechatJSSDK(); // initWechatJSSDK();
// #endif // #endif
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.container { .container {
height: 100vh; height: 100vh;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
background: linear-gradient( background: linear-gradient(124.92deg,
124.92deg,
rgba(77, 130, 253, 1) 7.66%, rgba(77, 130, 253, 1) 7.66%,
rgba(85, 184, 254, 1) 89.55% rgba(85, 184, 254, 1) 89.55%);
);
.header { .header {
height: 15vh; height: 15vh;
@ -636,16 +601,19 @@ onMounted(() => {
background-color: #fff; background-color: #fff;
border-radius: 20px 20px 0 0; border-radius: 20px 20px 0 0;
padding: 7vw; padding: 7vw;
.formLabel { .formLabel {
display: flex; display: flex;
align-items: center; align-items: center;
margin-bottom: 4px; margin-bottom: 4px;
.img { .img {
width: 20px; width: 20px;
height: 20px; height: 20px;
margin-right: 6px; margin-right: 6px;
} }
} }
.wechatBox { .wechatBox {
position: fixed; position: fixed;
width: 100%; width: 100%;
@ -665,9 +633,9 @@ onMounted(() => {
} }
} }
} }
} }
.bind-phone-modal { .bind-phone-modal {
width: 320px; width: 320px;
padding: 24px; padding: 24px;
@ -704,14 +672,14 @@ onMounted(() => {
flex: 1; flex: 1;
} }
} }
} }
</style> </style>
<style lang="scss"> <style lang="scss">
.wechatBox { .wechatBox {
.uv-divider { .uv-divider {
margin-bottom: 30px; margin-bottom: 30px;
width: 90%; width: 90%;
} }
} }
</style> </style>

@ -16,14 +16,14 @@
></image> --> ></image> -->
<view class="user-details"> <view class="user-details">
<view class="username"> <view class="username">
张三 {{userStore.userInfo.username}}
<u-icon <u-icon
name="checkmark-circle-fill" name="checkmark-circle-fill"
color="#ffa500" color="#ffa500"
size="16" size="16"
></u-icon> ></u-icon>
</view> </view>
<view class="user-id">用户ID: U12345678</view> <view class="user-id">用户ID: {{userStore.userInfo.id}}</view>
<view class="membership"> <view class="membership">
会员等级: 年会员 (有效期至: 2026-05-15) 会员等级: 年会员 (有效期至: 2026-05-15)
</view> </view>

@ -79,7 +79,7 @@
@click="logout" @click="logout"
:loading="logoutLoading" :loading="logoutLoading"
> >
退出登 退出登
</uv-button> </uv-button>
</view> </view>

@ -2,185 +2,111 @@
<view class="container"> <view class="container">
<!-- 生成记录列表 --> <!-- 生成记录列表 -->
<view class="record-list"> <view class="record-list">
<view class="record-item" v-for="record in records" :key="record.id"> <uv-swipe-action>
<uv-swipe-action-item @click="delItem(record)" :options="options" v-for="record in list" :key="record.id">
<view class="record-item">
<!-- 记录信息 --> <!-- 记录信息 -->
<view class="record-info"> <view class="record-info">
<view class="record-title">{{ record.title }}</view> <view class="record-title">{{ record.file_name }}</view>
<view class="record-time">生成时间: {{ record.generateTime }}</view> <view class="record-time">生成时间: {{ record.CreatedAt ? dayjs(record.CreatedAt).format('YYYY-MM-DD') : '' }}</view>
</view> </view>
<!-- 状态标签 --> <!-- 状态标签 -->
<view class="status-tag" :class="record.status"> <view class="status-tag" :class="{completed:record.status == 4,failed:record.status == 5}">
{{ record.statusText }} <span v-if="record.status == 4"></span>
<span v-else-if="record.status == 5">生成失败</span>
<span v-else></span>
</view> </view>
<!-- 操作按钮 --> <!-- 操作按钮 -->
<view class="record-actions"> <view class="record-actions">
<u-button <uv-button v-if="record.status === 4" type="primary" size="small"
v-if="record.status === 'completed'" @click="downloadRecord(record)">
type="primary" <uv-icon name="download" size="14" color="white" style="margin-right: 4px"></uv-icon>
size="small"
@click="downloadRecord(record)"
>
<u-icon
name="download"
size="14"
color="white"
style="margin-right: 4px"
></u-icon>
下载 下载
</u-button> </uv-button>
<u-button v-else type="info" size="small" disabled> <uv-button v-else type="info" size="small" disabled>
<u-icon <uv-icon name="download" size="14" color="#aaa" style="margin-right: 4px"></uv-icon>
name="download"
size="14"
color="white"
style="margin-right: 4px"
></u-icon>
下载 下载
</u-button> </uv-button>
<u-button
v-if="record.status === 'failed'"
type="error"
size="small"
@click="deleteRecord(record)"
style="margin-left: 8px"
>
<u-icon
name="trash"
size="14"
color="white"
style="margin-right: 4px"
></u-icon>
删除
</u-button>
</view> </view>
</view> </view>
</uv-swipe-action-item>
</uv-swipe-action>
</view> </view>
<!-- 空状态 --> <!-- 空状态 -->
<view v-if="records.length === 0" class="empty-state"> <view v-if="list.length === 0" class="empty-state">
<u-icon name="file-text" size="60" color="#ccc"></u-icon> <uv-icon name="file-text" size="60" color="#ccc"></uv-icon>
<text class="empty-text">暂无生成记录</text> <text class="empty-text">暂无生成记录</text>
</view> </view>
<!-- 加载更多 --> <!-- 加载更多 -->
<view v-if="hasMore && records.length > 0" class="load-more"> <uv-load-more :status="loadingStatus" @loadmore="loadmore" />
<u-button
type="default"
size="small"
:loading="loading"
@click="loadMore"
>
{{ loading ? "加载中..." : "加载更多" }}
</u-button>
</view>
</view> </view>
</template> </template>
<script setup> <script setup>
import { ref, onMounted } from "vue"; import {
import { onShow } from "@dcloudio/uni-app"; ref,
onMounted
// } from "vue";
const loading = ref(false); import RPC from "@/utils/request";
const hasMore = ref(true); import dayjs from 'dayjs'
const records = ref([ import {
{ onShow,onPullDownRefresh,onReachBottom
id: 1, } from "@dcloudio/uni-app";
title: "乘客电梯标准图纸",
generateTime: "2025-05-15 14:30", const options = ref([{
status: "completed", text: '删除',
statusText: "已完成", style: {
downloadUrl: "/static/files/passenger-elevator.pdf", backgroundColor: '#f56c6c'
}, }
{ }])
id: 2, const delItem = item => {
title: "货运电梯专用图纸", console.log(item)
generateTime: "2025-05-15 14:30", deleteRecord(item)
status: "failed",
statusText: "未完成",
downloadUrl: null,
},
{
id: 3,
title: "医用电梯专业图纸",
generateTime: "2025-05-15 14:30",
status: "completed",
statusText: "已完成",
downloadUrl: "/static/files/medical-elevator.pdf",
},
{
id: 4,
title: "观光电梯定制图纸",
generateTime: "2025-05-15 14:30",
status: "completed",
statusText: "已完成",
downloadUrl: "/static/files/sightseeing-elevator.pdf",
},
{
id: 5,
title: "货运电梯专用图纸",
generateTime: "2025-05-15 14:30",
status: "failed",
statusText: "未完成",
downloadUrl: null,
},
]);
//
const downloadRecord = (record) => {
if (record.status !== "completed" || !record.downloadUrl) {
uni.showToast({
title: "文件未准备好",
icon: "none",
});
return;
} }
//
const loading = ref(false);
const loadingStatus = ref('loadmore')
const page = ref(1)
const list = ref([])
const count = ref(0)
//
const downloadRecord = (record) => {
uni.showLoading({ uni.showLoading({
title: "准备下载...", title: "准备下载...",
}); });
uni.downloadFile({
// url: record.result_url,
setTimeout(() => { success: (res) => {
uni.hideLoading(); if (res.statusCode === 200) {
uni.saveFile({
// API tempFilePath: res.tempFilePath,
success: () => {
uni.showToast({ uni.showToast({
title: "下载成功", title: '下载成功',
icon: "success", icon: 'success'
}); })
}
// })
// uni.downloadFile({ }
// url: record.downloadUrl, },
// success: (res) => { fail: () => {
// if (res.statusCode === 200) { uni.showToast({
// uni.saveFile({ title: '下载失败',
// tempFilePath: res.tempFilePath, icon: 'none'
// success: () => { })
// uni.showToast({ }
// title: '', })
// icon: 'success' };
// })
// }
// })
// }
// },
// fail: () => {
// uni.showToast({
// title: '',
// icon: 'none'
// })
// }
// })
}, 1500);
};
// //
const deleteRecord = (record) => { const deleteRecord = (record) => {
uni.showModal({ uni.showModal({
title: "确认删除", title: "确认删除",
content: "确定要删除这条生成记录吗?删除后无法恢复。", content: "确定要删除这条生成记录吗?删除后无法恢复。",
@ -206,75 +132,74 @@ const deleteRecord = (record) => {
} }
}, },
}); });
}; };
// //
const loadMore = async () => { const loadRecords = async () => {
if (loading.value) return; loadingStatus.value === 'loading'
RPC.post('/planned_list',{page:page.value,page_size:20}).then(res => {
loading.value = true; list.value = [...list.value, ...res.list]
try { count.value = res.total
// API if (list.value.length >= count.value) {
await new Promise((resolve) => setTimeout(resolve, 1000)); loadingStatus.value = 'nomore'
} else {
// loadingStatus.value = 'loadmore'
hasMore.value = false;
uni.showToast({
title: "没有更多数据了",
icon: "none",
});
} catch (error) {
console.error("加载更多失败:", error);
uni.showToast({
title: "加载失败,请重试",
icon: "none",
});
} finally {
loading.value = false;
} }
}; }).catch(() => {
loadingStatus.value = 'loadmore'
// })
const loadRecords = async () => { };
try {
// API //
// const result = await RPC.get('/api/generate-records') onPullDownRefresh(() => {
// records.value = result.data list.value = []
} catch (error) { page.value = 1
console.error("加载生成记录失败:", error); loadingStatus.value === 'loading'
uni.showToast({ RPC.post('/planned_list',{page:page.value,page_size:20}).then(res => {
title: "加载失败,请重试", list.value = [...list.value, ...res.list]
icon: "none", count.value = res.total
}); if (list.value.length >= count.value) {
loadingStatus.value = 'nomore'
} else {
loadingStatus.value = 'loadmore'
}
}).catch(() => {
loadingStatus.value = 'loadmore'
}).finally(() => {
uni.stopPullDownRefresh()
})
})
onReachBottom(() => {
loadmore()
})
const loadmore = () => {
if (list.value.length >= count.value || loadingStatus.value === 'loading') return
console.log('上拉加载:')
loadingStatus.value = 'loading';
page.value = ++page.value;
loadRecords()
} }
};
//
const onRefresh = async () => {
hasMore.value = true;
await loadRecords();
};
onMounted(() => {
loadRecords();
});
onShow(() => { onShow(() => {
// //
list.value = []
page.value = 1
loadRecords(); loadRecords();
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.container { .container {
font-size: 14px; font-size: 14px;
min-height: 100vh; min-height: 100vh;
background-color: #f8f8f8; background-color: #f8f8f8;
padding: 16px; padding: 16px;
} }
.record-list { .record-list {
.record-item { .record-item {
background: white; background: white;
border-radius: 12px; border-radius: 12px;
@ -305,6 +230,8 @@ onShow(() => {
border-radius: 4px; border-radius: 4px;
font-size: 12px; font-size: 12px;
font-weight: 500; font-weight: 500;
background: #fff7e6;
color: #fa8c16;
&.completed { &.completed {
background: #e8f5e8; background: #e8f5e8;
@ -328,9 +255,9 @@ onShow(() => {
flex-shrink: 0; flex-shrink: 0;
} }
} }
} }
.empty-state { .empty-state {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
@ -342,10 +269,10 @@ onShow(() => {
font-size: 14px; font-size: 14px;
margin-top: 16px; margin-top: 16px;
} }
} }
.load-more { .load-more {
padding: 20px; padding: 20px;
text-align: center; text-align: center;
} }
</style> </style>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 655 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 662 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 636 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 629 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 844 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 809 B

@ -124,7 +124,10 @@ $uv.http.interceptors.request.use(
} }
const method = config.url const method = config.url
config.url = 'https://lift-dev.ruixininfo.com/jsonrpc' config.url = 'https://lift-drawing.ruixininfo.com/jsonrpc'
// #ifdef H5
config.url = '/jsonrpc'
// #endif
// config.url = useUserStore().adressIp + '/jsonrpc' // config.url = useUserStore().adressIp + '/jsonrpc'
const params = config.data const params = config.data
config.data = { config.data = {

@ -26,11 +26,10 @@ export default defineConfig(({ mode }) => {
server: { server: {
port: Number.parseInt(env.VITE_APP_PORT, 10), port: Number.parseInt(env.VITE_APP_PORT, 10),
proxy: { proxy: {
[env.VITE_APP_PROXY_PREFIX]: { ['/jsonrpc']: {
changeOrigin: true, changeOrigin: true,
target: env.VITE_APP_BASE_URL, target: 'https://lift-drawing-h5.ruixininfo.com',
rewrite: (path) => // target: 'https://lift-drawing.ruixininfo.com',
path.replace(new RegExp("^" + env.VITE_APP_PROXY_PREFIX), ""),
}, },
}, },
}, },

Loading…
Cancel
Save