From 4648a3bee638e9a99d2d80b66f8833b261a2db91 Mon Sep 17 00:00:00 2001
From: wlzboy <66905212@qq.com>
Date: 星期四, 25 九月 2025 22:39:24 +0800
Subject: [PATCH] feat:设计 app ui
---
app/plugins/modal.js | 20
app/static/icons/tasks.svg | 6
app/static/icons/create.svg | 4
app/static/icons/home.svg | 3
app/pages.json | 63
app/static/images/qrcode.png | 222 ++
app/static/icons/create.png | 0
app/README.md | 80
app/store/modules/user.js | 16
app/pages/mine/index.vue | 170 +
app/api/wechat.js | 36
app/static/images/tabbar/add_.png | 5
app/static/images/wechat.png | 5
app/static/images/tabbar/message_.png | 4
app/pages/bind-vehicle.vue | 214 ++
app/pages/task/settlement.vue | 747 ++++++++
app/pages/task/detail.vue | 600 ++++++
app/pages/task/create.vue | 856 +++++++++
app/static/icons/messages.svg | 5
app/static/icons/profile.svg | 4
app/.gitignore | 2
app/static/icons/profile-active.svg | 4
app/pages/index.vue | 605 ++++++
app/static/icons/messages.png | 0
app/static/icons/messages-active.png | 0
app/static/icons/profile-active.png | 0
app/static/icons/home-active.png | 0
app/pages/message/index.vue | 239 ++
app/pages/mine/info/index.vue | 56
app/static/icons/messages-active.svg | 5
app/static/icons/profile.png | 0
app/pages/task/index.vue | 798 ++++++++
app/static/icons/home-active.svg | 3
app/static/images/tabbar/message.png | 4
app/static/images/tabbar/task.png | 4
app/static/scss/global.scss | 33
app/static/images/tabbar/add.png | 5
app/pages/login.vue | 178 +
app/static/icons/tasks-active.svg | 6
app/static/icons/create-active.png | 0
app/static/icons/create-active.svg | 4
app/static/icons/README.md | 23
app/static/icons/tasks.png | 0
app/pages/login/wechat.vue | 258 ++
app/static/icons/home.png | 0
app/static/icons/tasks-active.png | 0
app/static/images/tabbar/task_.png | 4
47 files changed, 5,169 insertions(+), 122 deletions(-)
diff --git a/app/.gitignore b/app/.gitignore
index 59c9154..40acdf6 100644
--- a/app/.gitignore
+++ b/app/.gitignore
@@ -3,7 +3,7 @@
/unpackage/*
/node_modules/*
-
+/uni_modules/*
######################################################################
# Development Tools
diff --git a/app/README.md b/app/README.md
index d396dc7..48faa2f 100644
--- a/app/README.md
+++ b/app/README.md
@@ -1,51 +1,47 @@
-<p align="center">
- <img alt="logo" src="https://oscimg.oschina.net/oscnet/up-43e3941654fa3054c9684bf53d1b1d356a1.png">
-</p>
-<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v1.1.0</h1>
-<h4 align="center">鍩轰簬UniApp寮�鍙戠殑杞婚噺绾хЩ鍔ㄧ妗嗘灦</h4>
-<p align="center">
- <a href="https://gitee.com/y_project/RuoYi-App/stargazers"><img src="https://gitee.com/y_project/RuoYi-App/badge/star.svg?theme=dark"></a>
- <a href="https://gitee.com/y_project/RuoYi-App"><img src="https://img.shields.io/badge/RuoYi-v1.1.0-brightgreen.svg"></a>
- <a href="https://gitee.com/y_project/RuoYi-App/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
-</p>
+# 鑻ヤ緷浠诲姟璋冨害绉诲姩搴旂敤
-## 骞冲彴绠�浠�
+## 椤圭洰浠嬬粛
+杩欐槸涓�涓熀浜巙ni-app寮�鍙戠殑浠诲姟璋冨害绉诲姩搴旂敤锛屽寘鍚换鍔$鐞嗐�佹秷鎭�氱煡銆佸井淇$櫥褰曠瓑鍔熻兘銆�
-RuoYi App 绉诲姩瑙e喅鏂规锛岄噰鐢╱niapp妗嗘灦锛屼竴浠戒唬鐮佸缁堢閫傞厤锛屽悓鏃舵敮鎸丄PP銆佸皬绋嬪簭銆丠5锛佸疄鐜颁簡涓嶽RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue)銆乕RuoYi-Cloud](https://gitee.com/y_project/RuoYi-Cloud)瀹岀編瀵规帴鐨勭Щ鍔ㄨВ鍐虫柟妗堬紒鐩墠宸茬粡瀹炵幇鐧诲綍銆佹垜鐨勩�佸伐浣滃彴銆佺紪杈戣祫鏂欍�佸ご鍍忎慨鏀广�佸瘑鐮佷慨鏀广�佸父瑙侀棶棰樸�佸叧浜庢垜浠瓑鍩虹鍔熻兘銆�
+## 鍔熻兘妯″潡
+1. **棣栭〉** - 搴旂敤鍏ュ彛鍜屾瑙�
+2. **浠诲姟** - 浠诲姟鍒楄〃鏌ョ湅鍜岀鐞�
+3. **鍒涘缓浠诲姟** - 鏂板缓浠诲姟
+4. **娑堟伅** - 绯荤粺娑堟伅鍜岄�氱煡
+5. **鎴戠殑** - 涓汉涓績鍜岃缃�
-* 閰嶅鍚庣浠g爜浠撳簱鍦板潃[RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue) 鎴� [RuoYi-Cloud](https://github.com/yangzongzhuan/RuoYi-Cloud) 鐗堟湰銆�
-* 搴旂敤妗嗘灦鍩轰簬[uniapp](https://uniapp.dcloud.net.cn/)锛屾敮鎸佸皬绋嬪簭銆丠5銆丄ndroid鍜孖OS銆�
-* 鍓嶇缁勪欢閲囩敤[uni-ui](https://github.com/dcloudio/uni-ui)锛屽叏绔吋瀹圭殑楂樻�ц兘UI妗嗘灦銆�
-* 闃块噷浜戞姌鎵e満锛歔鐐规垜杩涘叆](http://aly.ruoyi.vip)锛岃吘璁簯绉掓潃鍦猴細[鐐规垜杩涘叆](http://txy.ruoyi.vip)
+## 鐧诲綍鍔熻兘
+- 璐﹀彿瀵嗙爜鐧诲綍
+- 寰俊涓�閿櫥褰曪紙鏀寔寰俊灏忕▼搴忥級
+## 杩愯鏂瑰紡
+```bash
+# 瀹夎渚濊禆
+npm install
-## 鎶�鏈枃妗�
+# 杩愯鍒癏5
+npm run dev:h5
-- 瀹樼綉缃戠珯锛歔http://ruoyi.vip](http://ruoyi.vip)
-- 鏂囨。鍦板潃锛歔http://doc.ruoyi.vip](http://doc.ruoyi.vip)
-- H5椤典綋楠岋細[http://h5.ruoyi.vip](http://h5.ruoyi.vip)
-- QQ浜ゆ祦缇わ細 鈶�133713780(婊�)銆佲憽146013835(婊�)銆佲憿189091635
-- 灏忕▼搴忎綋楠�
+# 杩愯鍒板井淇″皬绋嬪簭
+npm run dev:mp-weixin
-<img src="https://oscimg.oschina.net/oscnet/up-26c76dc90b92acdbd9ac8cd5252f07c8ad9.jpg" alt="灏忕▼搴忔紨绀�"/>
-
+# 鏋勫缓鐢熶骇鐗堟湰
+npm run build
+```
-## 婕旂ず鍥�
+## 鐩綍缁撴瀯
+```
+app/
+鈹溾攢鈹� api/ # 鎺ュ彛璇锋眰
+鈹溾攢鈹� components/ # 缁勪欢
+鈹溾攢鈹� pages/ # 椤甸潰
+鈹溾攢鈹� static/ # 闈欐�佽祫婧�
+鈹溾攢鈹� store/ # 鐘舵�佺鐞�
+鈹溾攢鈹� utils/ # 宸ュ叿鍑芥暟
+鈹斺攢鈹� ...
+```
-<table>
- <tr>
- <td><img src="https://oscimg.oschina.net/oscnet/up-21f6f842fdc94540469b4eb43fdadbaf7f8.png"/></td>
- <td><img src="https://oscimg.oschina.net/oscnet/up-a6f23cf9a371a30165e135eff6d9ae89a9d.png"/></td>
- <td><img src="https://oscimg.oschina.net/oscnet/up-ff5f62016bf6624c1ff27eee57499dccd44.png"/></td>
- </tr>
- <tr>
- <td><img src="https://oscimg.oschina.net/oscnet/up-b9a582fdb26ec69d407fabd044d2c8494df.png"/></td>
- <td><img src="https://oscimg.oschina.net/oscnet/up-96427ee08fca29d77934cfc8d1b1a637cef.png"/></td>
- <td><img src="https://oscimg.oschina.net/oscnet/up-5fdadc582d24cccd7727030d397b63185a3.png"/></td>
- </tr>
- <tr>
- <td><img src="https://oscimg.oschina.net/oscnet/up-0a36797b6bcc50c36d40c3c782665b89efc.png"/></td>
- <td><img src="https://oscimg.oschina.net/oscnet/up-d77995cc00687cedd00d5ac7d68a07ea276.png"/></td>
- <td><img src="https://oscimg.oschina.net/oscnet/up-fa8f5ab20becf59b4b38c1b92a9989e7109.png"/></td>
- </tr>
-</table>
+## 娉ㄦ剰浜嬮」
+1. 寰俊鐧诲綍鍔熻兘闇�瑕佸湪寰俊寮�鍙戣�呭伐鍏蜂腑娴嬭瘯
+2. 鍚庣鎺ュ彛闇�瑕佹牴鎹疄闄呮儏鍐佃皟鏁�
+3. 鍥炬爣璧勬簮宸插寘鍚湪static/icons鐩綍涓�
\ No newline at end of file
diff --git a/app/api/wechat.js b/app/api/wechat.js
new file mode 100644
index 0000000..4f1e3e1
--- /dev/null
+++ b/app/api/wechat.js
@@ -0,0 +1,36 @@
+import request from '@/utils/request'
+
+// 寰俊鐧诲綍
+export function wechatLogin(data) {
+ return request({
+ url: '/wechat/login',
+ method: 'post',
+ data: data
+ })
+}
+
+// 鑾峰彇寰俊鐢ㄦ埛淇℃伅
+export function getWechatUserInfo(openid) {
+ return request({
+ url: '/wechat/user/' + openid,
+ method: 'get'
+ })
+}
+
+// 缁戝畾寰俊璐﹀彿
+export function bindWechat(data) {
+ return request({
+ url: '/wechat/bind',
+ method: 'post',
+ data: data
+ })
+}
+
+// 瑙g粦寰俊璐﹀彿
+export function unbindWechat(data) {
+ return request({
+ url: '/wechat/unbind',
+ method: 'post',
+ data: data
+ })
+}
\ No newline at end of file
diff --git a/app/pages.json b/app/pages.json
index 333251c..ee9557c 100644
--- a/app/pages.json
+++ b/app/pages.json
@@ -5,6 +5,11 @@
"navigationBarTitleText": "鐧诲綍"
}
}, {
+ "path": "pages/login/wechat",
+ "style": {
+ "navigationBarTitleText": "寰俊鐧诲綍"
+ }
+ }, {
"path": "pages/register",
"style": {
"navigationBarTitleText": "娉ㄥ唽"
@@ -14,6 +19,11 @@
"style": {
"navigationBarTitleText": "鑻ヤ緷绉诲姩绔鏋�",
"navigationStyle": "custom"
+ }
+ }, {
+ "path": "pages/bind-vehicle",
+ "style": {
+ "navigationBarTitleText": "缁戝畾杞﹁締"
}
}, {
"path": "pages/work/index",
@@ -70,6 +80,31 @@
"style": {
"navigationBarTitleText": "娴忚鏂囨湰"
}
+ }, {
+ "path": "pages/task/index",
+ "style": {
+ "navigationBarTitleText": "浠诲姟鍒楄〃"
+ }
+ }, {
+ "path": "pages/task/create",
+ "style": {
+ "navigationBarTitleText": "鍒涘缓浠诲姟"
+ }
+ }, {
+ "path": "pages/task/detail",
+ "style": {
+ "navigationBarTitleText": "浠诲姟璇︽儏"
+ }
+ }, {
+ "path": "pages/task/settlement",
+ "style": {
+ "navigationBarTitleText": "浠诲姟缁撶畻"
+ }
+ }, {
+ "path": "pages/message/index",
+ "style": {
+ "navigationBarTitleText": "娑堟伅涓績"
+ }
}],
"tabBar": {
"color": "#000000",
@@ -78,18 +113,28 @@
"backgroundColor": "#ffffff",
"list": [{
"pagePath": "pages/index",
- "iconPath": "static/images/tabbar/home.png",
- "selectedIconPath": "static/images/tabbar/home_.png",
+ "iconPath": "static/icons/home.png",
+ "selectedIconPath": "static/icons/home-active.png",
"text": "棣栭〉"
}, {
- "pagePath": "pages/work/index",
- "iconPath": "static/images/tabbar/work.png",
- "selectedIconPath": "static/images/tabbar/work_.png",
- "text": "宸ヤ綔鍙�"
+ "pagePath": "pages/task/index",
+ "iconPath": "static/icons/tasks.png",
+ "selectedIconPath": "static/icons/tasks-active.png",
+ "text": "浠诲姟"
+ }, {
+ "pagePath": "pages/task/create",
+ "iconPath": "static/icons/create.png",
+ "selectedIconPath": "static/icons/create-active.png",
+ "text": "鍒涘缓浠诲姟"
+ }, {
+ "pagePath": "pages/message/index",
+ "iconPath": "static/icons/messages.png",
+ "selectedIconPath": "static/icons/messages-active.png",
+ "text": "娑堟伅"
}, {
"pagePath": "pages/mine/index",
- "iconPath": "static/images/tabbar/mine.png",
- "selectedIconPath": "static/images/tabbar/mine_.png",
+ "iconPath": "static/icons/profile.png",
+ "selectedIconPath": "static/icons/profile-active.png",
"text": "鎴戠殑"
}
]
@@ -99,4 +144,4 @@
"navigationBarTitleText": "RuoYi",
"navigationBarBackgroundColor": "#FFFFFF"
}
-}
+}
\ No newline at end of file
diff --git a/app/pages/bind-vehicle.vue b/app/pages/bind-vehicle.vue
new file mode 100644
index 0000000..4897419
--- /dev/null
+++ b/app/pages/bind-vehicle.vue
@@ -0,0 +1,214 @@
+<template>
+ <view class="bind-vehicle-container">
+ <view class="header">
+ <text class="title">缁戝畾杞﹁締</text>
+ </view>
+
+ <!-- 鎵爜缁戝畾 -->
+ <view class="scan-section">
+ <view class="section-title">鎵竴鎵粦瀹�</view>
+ <view class="scan-content">
+ <view class="scan-icon" @click="scanQRCode">
+ <uni-icons type="scan" size="40" color="#007AFF"></uni-icons>
+ <text class="scan-text">鐐瑰嚮鎵爜缁戝畾杞﹁締</text>
+ </view>
+ </view>
+ </view>
+
+ <!-- 涓嬫媺閫夋嫨缁戝畾 -->
+ <view class="form-section">
+ <view class="section-title">閫夋嫨杞︾墝鍙风粦瀹�</view>
+ <view class="form-item">
+ <view class="form-label">杞︾墝鍙�</view>
+ <picker mode="selector" :range="vehiclePlates" @change="onVehiclePlateChange">
+ <view class="form-input picker-input">
+ {{ selectedVehiclePlate || '璇烽�夋嫨杞︾墝鍙�' }}
+ <uni-icons type="arrowright" size="16" color="#999"></uni-icons>
+ </view>
+ </picker>
+ </view>
+
+ <view class="form-actions">
+ <button class="submit-btn" @click="bindVehicle" :disabled="!selectedVehiclePlate">纭缁戝畾</button>
+ <button class="cancel-btn" @click="goBack">鍙栨秷</button>
+ </view>
+ </view>
+ </view>
+</template>
+
+<script>
+ export default {
+ data() {
+ return {
+ selectedVehiclePlate: '',
+ // 妯℃嫙杞﹁締鍒楄〃鏁版嵁
+ vehiclePlates: ['绮12345', '绮67890', '绮11111', '绮22222', '绮33333']
+ }
+ },
+ methods: {
+ // 鎵爜缁戝畾杞﹁締
+ scanQRCode() {
+ // #ifdef H5
+ this.$modal.showToast('H5鐜鏆備笉鏀寔鎵爜鍔熻兘')
+ // #endif
+
+ // #ifndef H5
+ uni.scanCode({
+ success: (res) => {
+ console.log('鎵爜缁撴灉锛�', res)
+ // 瑙f瀽鎵爜缁撴灉锛岃繖閲屽亣璁炬壂鐮佺粨鏋滄槸杞︾墝鍙�
+ this.selectedVehiclePlate = res.result
+ this.$modal.showToast('鎵爜鎴愬姛锛屾鍦ㄧ粦瀹氳溅杈�...')
+ // 鎵爜鎴愬姛鍚庤嚜鍔ㄧ粦瀹�
+ this.bindVehicle()
+ },
+ fail: (err) => {
+ console.log('鎵爜澶辫触锛�', err)
+ this.$modal.showToast('鎵爜澶辫触锛岃閲嶈瘯')
+ }
+ })
+ // #endif
+ },
+
+ // 杞︾墝鍙烽�夋嫨
+ onVehiclePlateChange(e) {
+ this.selectedVehiclePlate = this.vehiclePlates[e.detail.value]
+ },
+
+ // 缁戝畾杞﹁締
+ bindVehicle() {
+ if (!this.selectedVehiclePlate) {
+ this.$modal.showToast('璇烽�夋嫨杞︾墝鍙�')
+ return
+ }
+
+ // 杩欓噷鍙互璋冪敤API杩涜杞﹁締缁戝畾
+ this.$modal.confirm('纭缁戝畾杞﹁締 ' + this.selectedVehiclePlate + ' 鍚楋紵').then(() => {
+ this.$modal.showToast('杞﹁締缁戝畾鎴愬姛')
+ // 杩斿洖涓婁竴椤�
+ this.$tab.navigateBack()
+ }).catch(() => {
+ // 鐢ㄦ埛鍙栨秷鎿嶄綔
+ })
+ },
+
+ goBack() {
+ this.$tab.navigateBack()
+ }
+ }
+ }
+</script>
+
+<style lang="scss">
+ .bind-vehicle-container {
+ padding: 20rpx;
+ background-color: #f5f5f5;
+ min-height: 100vh;
+ }
+
+ .header {
+ text-align: center;
+ padding: 40rpx 0;
+
+ .title {
+ font-size: 40rpx;
+ font-weight: bold;
+ color: #333;
+ }
+ }
+
+ .section-title {
+ font-size: 32rpx;
+ font-weight: bold;
+ margin: 30rpx 0 20rpx 0;
+ color: #333;
+ }
+
+ .scan-section {
+ background-color: white;
+ border-radius: 15rpx;
+ padding: 30rpx;
+ margin-bottom: 20rpx;
+ box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+
+ .scan-content {
+ text-align: center;
+ padding: 40rpx 0;
+
+ .scan-icon {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+
+ .scan-text {
+ margin-top: 20rpx;
+ font-size: 28rpx;
+ color: #007AFF;
+ }
+ }
+ }
+ }
+
+ .form-section {
+ background-color: white;
+ border-radius: 15rpx;
+ padding: 30rpx;
+ box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+
+ .form-item {
+ margin-bottom: 40rpx;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+
+ .form-label {
+ font-size: 28rpx;
+ margin-bottom: 15rpx;
+ color: #333;
+ }
+
+ .form-input {
+ height: 70rpx;
+ padding: 0 20rpx;
+ border: 1rpx solid #eee;
+ border-radius: 10rpx;
+ font-size: 28rpx;
+
+ &.picker-input {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ }
+ }
+ }
+
+ .form-actions {
+ display: flex;
+ margin-top: 50rpx;
+
+ .submit-btn, .cancel-btn {
+ flex: 1;
+ height: 80rpx;
+ border-radius: 10rpx;
+ font-size: 32rpx;
+ margin: 0 10rpx;
+ }
+
+ .submit-btn {
+ background-color: #007AFF;
+ color: white;
+
+ &[disabled] {
+ background-color: #cccccc;
+ }
+ }
+
+ .cancel-btn {
+ background-color: #f0f0f0;
+ color: #333;
+ }
+ }
+ }
+</style>
\ No newline at end of file
diff --git a/app/pages/index.vue b/app/pages/index.vue
index 4646807..5539ffa 100644
--- a/app/pages/index.vue
+++ b/app/pages/index.vue
@@ -1,43 +1,598 @@
<template>
- <view class="content">
- <image class="logo" src="@/static/logo.png"></image>
- <view class="text-area">
- <text class="title">Hello RuoYi</text>
+ <view class="home-container">
+ <!-- 椤堕儴鐢ㄦ埛淇℃伅鍖哄煙 -->
+ <view class="user-info-section">
+ <view class="user-info-content">
+ <view class="user-details">
+ <view class="user-name">{{ userName || '鏈櫥褰�' }}</view>
+ <view class="vehicle-info">
+ <text v-if="boundVehicle">鍏宠仈杞︾墝鍙凤細{{ boundVehicle }}</text>
+ <text v-else>鏈粦瀹氳溅鐗屽彿</text>
+ </view>
+ </view>
+ <button
+ class="bind-vehicle-btn"
+ @click="goToBindVehicle"
+ >
+ {{ boundVehicle ? '鏇存崲杞﹁締' : '缁戝畾杞﹁締' }}
+ </button>
+ </view>
</view>
+
+ <!-- 娑堟伅鍏ュ彛 -->
+ <view class="message-entry" @click="goToMessages">
+ <view class="message-icon">
+ <uni-icons type="chat" size="24" color="#007AFF"></uni-icons>
+ </view>
+ <view class="message-text">娑堟伅涓績</view>
+ <view class="unread-dot" v-if="unreadMessageCount > 0">{{ unreadMessageCount }}</view>
+ <view class="arrow">
+ <uni-icons type="arrowright" size="16" color="#999"></uni-icons>
+ </view>
+ </view>
+
+ <!-- 姝e湪杩愯鐨勪换鍔℃爣棰� -->
+ <view class="running-tasks-header">
+ <text class="header-title">姝e湪杩愯鐨勪换鍔�</text>
+ </view>
+
+ <!-- 姝e湪杩愯鐨勪换鍔″垪琛� -->
+ <scroll-view class="running-tasks-section" scroll-y="true">
+ <view class="task-list">
+ <view class="task-item" v-for="task in runningTasks" :key="task.id">
+ <view class="task-main" @click="viewTaskDetail(task)">
+ <view class="task-title">{{ getTaskTypeText(task.type) }} - {{ task.vehicle }}</view>
+ <view class="task-info">
+ <view class="info-row">
+ <view class="info-item">
+ <view class="label">浠诲姟缂栧彿:</view>
+ <view class="value">{{ task.taskNo }}</view>
+ </view>
+ <view class="info-item">
+ <view class="label">浠诲姟鐘舵��:</view>
+ <view class="value">{{ getStatusText(task.status) }}</view>
+ </view>
+ </view>
+ <view class="info-row">
+ <view class="info-item">
+ <view class="label">鍑哄彂鍦�:</view>
+ <view class="value">{{ task.startLocation }}</view>
+ </view>
+ <view class="info-item">
+ <view class="label">鐩殑鍦�:</view>
+ <view class="value">{{ task.endLocation }}</view>
+ </view>
+ </view>
+ <view class="info-row">
+ <view class="info-item">
+ <view class="label">鍑哄彂鏃堕棿:</view>
+ <view class="value">{{ task.startTime }}</view>
+ </view>
+ <view class="info-item">
+ <view class="label">鎵ц浜哄憳:</view>
+ <view class="value">{{ task.assignee }}</view>
+ </view>
+ </view>
+ </view>
+ </view>
+
+ <!-- 鎿嶄綔鎸夐挳 -->
+ <view class="task-actions">
+ <button
+ class="action-btn"
+ :class="{ disabled: isActionDisabled(task, 'depart') }"
+ @click="handleTaskAction(task, 'depart')"
+ v-if="task.status !== 'completed'"
+ >
+ 鍑哄彂
+ </button>
+ <button
+ class="action-btn"
+ :class="{ disabled: isActionDisabled(task, 'arrive') }"
+ @click="handleTaskAction(task, 'arrive')"
+ v-if="task.status !== 'completed'"
+ >
+ 宸插埌杈�
+ </button>
+ <button
+ class="action-btn"
+ :class="{ disabled: isActionDisabled(task, 'return') }"
+ @click="handleTaskAction(task, 'return')"
+ v-if="task.status !== 'completed'"
+ >
+ 杩旂▼
+ </button>
+ <button
+ class="action-btn"
+ :class="{ disabled: isActionDisabled(task, 'settle') }"
+ @click="handleTaskAction(task, 'settle')"
+ v-if="task.status !== 'completed'"
+ >
+ 缁撶畻
+ </button>
+ <button
+ class="action-btn primary"
+ :class="{ disabled: isActionDisabled(task, 'complete') }"
+ @click="handleTaskAction(task, 'complete')"
+ v-if="task.status !== 'completed'"
+ >
+ 宸插畬鎴�
+ </button>
+ </view>
+ </view>
+
+ <view class="no-data" v-if="runningTasks.length === 0">
+ <uni-icons type="info" size="40" color="#ccc"></uni-icons>
+ <text>鏆傛棤姝e湪杩愯鐨勪换鍔�</text>
+ </view>
+ </view>
+ </scroll-view>
</view>
</template>
<script>
+ import { mapState } from 'vuex'
+
export default {
- onLoad: function() {
+ data() {
+ return {
+ // 妯℃嫙鐢ㄦ埛缁戝畾鐨勮溅杈嗕俊鎭�
+ boundVehicle: '绮12345', // 妯℃嫙宸茬粦瀹氳溅杈�
+
+ // 妯℃嫙娑堟伅鏁版嵁
+ messages: [
+ {
+ id: 1,
+ type: 'create', // 鍒涘缓鎴愬姛
+ content: 'TD 1011 骞垮窞澶╂渤->骞垮窞涓滅珯锛屾椂闂达細13锛�20 浠诲姟鍒涘缓鎴愬姛',
+ time: '2023-05-15 13:20',
+ read: false,
+ taskId: 1
+ },
+ {
+ id: 2,
+ type: 'push', // 浠诲姟鎺ㄩ��
+ content: 'TD1021 骞垮窞澶╂渤->骞垮窞涓滅珯锛屾椂闂达細13锛�20 鍑哄彂锛岃鍙婃椂澶勭悊',
+ time: '2023-05-15 13:25',
+ read: false,
+ taskId: 2
+ },
+ {
+ id: 3,
+ type: 'status', // 浠诲姟鐘舵�佸彉鏇�
+ content: 'TD1021 骞垮窞澶╂渤->骞垮窞涓滅珯锛屾椂闂达細13锛�20锛屼换鍔℃鍦ㄨ浆杩愪腑',
+ time: '2023-05-15 14:30',
+ read: true,
+ taskId: 2
+ },
+ {
+ id: 4,
+ type: 'create', // 鍒涘缓鎴愬姛
+ content: 'TD 1022 娣卞湷鍗楀北->娣卞湷绂忕敯锛屾椂闂达細15锛�10 浠诲姟鍒涘缓鎴愬姛',
+ time: '2023-05-15 15:10',
+ read: false,
+ taskId: 3
+ },
+ {
+ id: 5,
+ type: 'push', // 浠诲姟鎺ㄩ��
+ content: 'TD1023 娣卞湷鍗楀北->娣卞湷绂忕敯锛屾椂闂达細16锛�00 鍑哄彂锛岃鍙婃椂澶勭悊',
+ time: '2023-05-15 16:00',
+ read: true,
+ taskId: 4
+ }
+ ],
+
+ // 妯℃嫙姝e湪杩愯鐨勪换鍔″垪琛�
+ taskList: [
+ {
+ id: 1,
+ title: '绱ф�ョ淮淇换鍔�',
+ type: 'maintenance', // 缁翠慨淇濆吇
+ startLocation: '骞垮窞甯傚ぉ娌冲尯XX璺�123鍙�',
+ endLocation: '骞垮窞甯傜櫧浜戝尯YY璺�456鍙�',
+ startTime: '2023-05-15 15:00',
+ assignee: '寮犱笁',
+ status: 'pending',
+ vehicle: '绮12345',
+ taskNo: 'RW20230515001'
+ },
+ {
+ id: 2,
+ title: '瀹氭湡淇濆吇浠诲姟',
+ type: 'maintenance', // 缁翠慨淇濆吇
+ startLocation: '娣卞湷甯傚崡灞卞尯XX璺�789鍙�',
+ endLocation: '娣卞湷甯傜鐢板尯YY璺�999鍙�',
+ startTime: '2023-05-14 10:00',
+ assignee: '鏉庡洓',
+ status: 'processing',
+ vehicle: '绮67890',
+ taskNo: 'RW20230514002'
+ },
+ {
+ id: 5,
+ title: '鎬ユ晳杞繍浠诲姟',
+ type: 'emergency', // 鎬ユ晳杞繍
+ startLocation: '骞垮窞甯傝秺绉�鍖哄尰闄㈣矾1鍙�',
+ endLocation: '骞垮窞甯傛捣鐝犲尯鍖婚櫌璺�2鍙�',
+ startTime: '2023-05-16 14:00',
+ assignee: '寮犲尰鐢�,鏉庢姢澹�',
+ status: 'pending',
+ vehicle: '绮33333',
+ taskNo: 'RW20230516005'
+ },
+ {
+ id: 6,
+ title: '绂忕杞︿换鍔�',
+ type: 'welfare', // 绂忕杞�
+ startLocation: '骞垮窞甯傝崝婀惧尯绀惧尯璺�10鍙�',
+ endLocation: '骞垮窞甯傚ぉ娌冲尯鍏昏�侀櫌璺�20鍙�',
+ startTime: '2023-05-17 08:00',
+ assignee: '鐜嬪徃鏈�',
+ status: 'processing',
+ vehicle: '绮44444',
+ taskNo: 'RW20230517006'
+ }
+ ]
+ }
+ },
+ computed: {
+ ...mapState({
+ userName: state => state.user.name
+ }),
+
+ // 姝e湪杩愯鐨勪换鍔★紙寰呭鐞嗗拰澶勭悊涓殑浠诲姟锛�
+ runningTasks() {
+ return this.taskList.filter(task =>
+ task.status === 'pending' || task.status === 'processing'
+ );
+ },
+
+ // 鏈娑堟伅鏁伴噺
+ unreadMessageCount() {
+ return this.messages.filter(message => !message.read).length;
+ }
+ },
+ methods: {
+ // 璺宠浆鍒扮粦瀹氳溅杈嗛〉闈�
+ goToBindVehicle() {
+ // 璺宠浆鍒扮粦瀹氳溅杈嗙殑椤甸潰
+ this.$tab.navigateTo('/pages/bind-vehicle');
+ },
+
+ // 璺宠浆鍒版秷鎭〉闈�
+ goToMessages() {
+ this.$tab.switchTab('/pages/message/index');
+ },
+
+ // 鏌ョ湅浠诲姟璇︽儏
+ viewTaskDetail(task) {
+ // 璺宠浆鍒颁换鍔¤鎯呴〉闈�
+ this.$tab.navigateTo(`/pages/task/detail?id=${task.id}`);
+ },
+
+ // 鍒ゆ柇鎿嶄綔鎸夐挳鏄惁绂佺敤
+ isActionDisabled(task, action) {
+ // 鏍规嵁浠诲姟鐘舵�佸拰鎿嶄綔绫诲瀷鍒ゆ柇鏄惁绂佺敤
+ switch (action) {
+ case 'depart':
+ return task.status !== 'pending';
+ case 'arrive':
+ return task.status !== 'processing';
+ case 'return':
+ return task.status !== 'processing';
+ case 'settle':
+ return task.status !== 'processing';
+ case 'complete':
+ return task.status !== 'processing';
+ default:
+ return false;
+ }
+ },
+
+ // 澶勭悊浠诲姟鎿嶄綔
+ handleTaskAction(task, action) {
+ if (this.isActionDisabled(task, action)) {
+ return;
+ }
+
+ switch (action) {
+ case 'depart':
+ // 鍑哄彂鎿嶄綔锛屾牴鎹换鍔$被鍨嬫樉绀轰笉鍚岀殑纭淇℃伅
+ let departMessage = '纭畾瑕佹爣璁颁负宸插嚭鍙戝悧锛�';
+ if (task.type !== 'maintenance' && task.type !== 'refuel' && task.type !== 'inspection') {
+ departMessage = '鍙戝嚭鍘荤洰鐨勫湴,纭锛�';
+ }
+ this.$modal.confirm(departMessage).then(() => {
+ task.status = 'processing';
+ this.$modal.showToast('宸插嚭鍙�');
+ // 杩欓噷鍙互璋冪敤API鏇存柊浠诲姟鐘舵��
+ }).catch(() => {});
+ break;
+ case 'arrive':
+ // 宸插埌杈炬搷浣�
+ this.$modal.confirm('宸茬粡鍒拌揪鐩殑鍦帮紝纭锛�').then(() => {
+ this.$modal.showToast('宸插埌杈�');
+ // 杩欓噷鍙互璋冪敤API鏇存柊浠诲姟鐘舵��
+ }).catch(() => {});
+ break;
+ case 'return':
+ // 杩旂▼鎿嶄綔
+ this.$modal.confirm('鐜板湪宸茬粡杩旂▼涓紝纭锛�').then(() => {
+ this.$modal.showToast('杩旂▼涓�');
+ // 杩欓噷鍙互璋冪敤API鏇存柊浠诲姟鐘舵��
+ }).catch(() => {});
+ break;
+ case 'settle':
+ // 缁撶畻鎿嶄綔锛岃烦杞埌缁撶畻椤甸潰
+ this.$tab.navigateTo(`/pages/task/settlement?id=${task.id}`);
+ break;
+ case 'complete':
+ // 宸插畬鎴愭搷浣�
+ this.$modal.confirm('浠诲姟鏄惁宸茬粡鍏ㄩ儴瀹屾垚锛岀‘璁わ紵').then(() => {
+ task.status = 'completed';
+ this.$modal.showToast('浠诲姟宸插畬鎴�');
+ // 杩欓噷鍙互璋冪敤API鏇存柊浠诲姟鐘舵��
+ }).catch(() => {});
+ break;
+ }
+ },
+
+ getStatusText(status) {
+ const statusMap = {
+ 'pending': '寰呭鐞�',
+ 'processing': '澶勭悊涓�',
+ 'completed': '宸插畬鎴�'
+ }
+ return statusMap[status] || '鏈煡'
+ },
+
+ getTaskTypeText(type) {
+ const typeMap = {
+ 'maintenance': '缁翠慨淇濆吇',
+ 'refuel': '鍔犳补',
+ 'inspection': '宸℃',
+ 'emergency': '鎬ユ晳杞繍',
+ 'welfare': '绂忕杞�'
+ }
+ return typeMap[type] || '鏈煡绫诲瀷'
+ }
}
}
</script>
-<style>
- .content {
+<style lang="scss">
+ .home-container {
+ padding: 20rpx;
+ background-color: #f5f5f5;
+ height: 100vh;
display: flex;
flex-direction: column;
- align-items: center;
- justify-content: center;
+ // 闅愯棌婊氬姩鏉′絾淇濇寔婊氬姩鍔熻兘
+ ::-webkit-scrollbar {
+ display: none;
+ width: 0 !important;
+ height: 0 !important;
+ background: transparent;
+ }
+
+ // Firefox婊氬姩鏉¢殣钘�
+ * {
+ scrollbar-width: none; /* Firefox */
+ }
+
+ // IE/Edge婊氬姩鏉¢殣钘�
+ * {
+ -ms-overflow-style: none; /* IE 10+ */
+ }
}
-
- .logo {
- height: 200rpx;
- width: 200rpx;
- margin-top: 200rpx;
- margin-left: auto;
- margin-right: auto;
- margin-bottom: 50rpx;
+
+ // 鐢ㄦ埛淇℃伅鍖哄煙
+ .user-info-section {
+ background-color: white;
+ border-radius: 15rpx;
+ padding: 30rpx;
+ margin-bottom: 20rpx;
+ box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+ flex-shrink: 0; // 闃叉鏀剁缉
+
+ .user-info-content {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+
+ .user-details {
+ .user-name {
+ font-size: 36rpx;
+ font-weight: bold;
+ margin-bottom: 10rpx;
+ color: #333;
+ }
+
+ .vehicle-info {
+ font-size: 28rpx;
+ color: #666;
+ }
+ }
+
+ .bind-vehicle-btn {
+ background-color: #007AFF;
+ color: white;
+ border-radius: 10rpx;
+ padding: 15rpx 30rpx;
+ font-size: 28rpx;
+ }
+ }
}
-
- .text-area {
+
+ // 娑堟伅鍏ュ彛
+ .message-entry {
display: flex;
- justify-content: center;
+ align-items: center;
+ background-color: white;
+ border-radius: 15rpx;
+ padding: 30rpx;
+ margin-bottom: 20rpx;
+ box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+ position: relative;
+
+ .message-icon {
+ margin-right: 20rpx;
+ }
+
+ .message-text {
+ flex: 1;
+ font-size: 32rpx;
+ color: #333;
+ }
+
+ .unread-dot {
+ position: absolute;
+ top: 15rpx;
+ right: 60rpx;
+ background-color: #ff4d4f;
+ color: white;
+ border-radius: 50%;
+ width: 32rpx;
+ height: 32rpx;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 20rpx;
+ }
+
+ .arrow {
+ margin-left: 20rpx;
+ }
}
-
- .title {
- font-size: 36rpx;
- color: #8f8f94;
+
+ // 姝e湪杩愯鐨勪换鍔℃爣棰�
+ .running-tasks-header {
+ margin-bottom: 20rpx;
+ flex-shrink: 0; // 闃叉鏀剁缉
+
+ .header-title {
+ font-size: 36rpx;
+ font-weight: bold;
+ color: #333;
+ }
}
-</style>
+
+ // 姝e湪杩愯鐨勪换鍔″垪琛�
+ .running-tasks-section {
+ flex: 1;
+ background-color: white;
+ border-radius: 15rpx;
+ padding: 30rpx;
+ box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+ // 闅愯棌婊氬姩鏉′絾淇濇寔婊氬姩鍔熻兘
+ ::-webkit-scrollbar {
+ display: none;
+ width: 0 !important;
+ height: 0 !important;
+ background: transparent;
+ }
+
+ // Firefox婊氬姩鏉¢殣钘�
+ * {
+ scrollbar-width: none; /* Firefox */
+ }
+
+ // IE/Edge婊氬姩鏉¢殣钘�
+ * {
+ -ms-overflow-style: none; /* IE 10+ */
+ }
+
+ .task-list {
+ .task-item {
+ background-color: #fafafa;
+ border-radius: 15rpx;
+ margin-bottom: 30rpx;
+ overflow: hidden;
+
+ .task-main {
+ padding: 30rpx;
+ border-bottom: 1rpx solid #f0f0f0;
+
+ .task-title {
+ font-size: 32rpx;
+ font-weight: bold;
+ margin-bottom: 20rpx;
+ }
+
+ .task-info {
+ .info-row {
+ display: flex;
+ margin-bottom: 15rpx;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+
+ .info-item {
+ flex: 1;
+ display: flex;
+
+ .label {
+ font-size: 26rpx;
+ color: #666;
+ margin-right: 10rpx;
+ white-space: nowrap;
+ }
+
+ .value {
+ font-size: 26rpx;
+ flex: 1;
+ word-break: break-all;
+ }
+ }
+ }
+ }
+ }
+
+ .task-actions {
+ display: flex;
+ padding: 20rpx;
+
+ .action-btn {
+ flex: 1;
+ height: 70rpx;
+ border-radius: 10rpx;
+ font-size: 26rpx;
+ margin: 0 5rpx;
+ background-color: #f0f0f0;
+ color: #333;
+
+ &.primary {
+ background-color: #007AFF;
+ color: white;
+ }
+
+ &.disabled {
+ opacity: 0.5;
+ }
+
+ &:first-child {
+ margin-left: 0;
+ }
+
+ &:last-child {
+ margin-right: 0;
+ }
+ }
+ }
+ }
+
+ .no-data {
+ text-align: center;
+ padding: 100rpx 0;
+ color: #999;
+
+ text {
+ display: block;
+ margin-top: 20rpx;
+ }
+ }
+ }
+ }
+</style>
\ No newline at end of file
diff --git a/app/pages/login.vue b/app/pages/login.vue
index 7f0e8c8..f440b1e 100644
--- a/app/pages/login.vue
+++ b/app/pages/login.vue
@@ -1,5 +1,5 @@
<template>
- <view class="normal-login-container">
+ <scroll-view class="normal-login-container" scroll-y="true">
<view class="logo-content align-center justify-center flex">
<image style="width: 100rpx;height: 100rpx;" :src="globalConfig.appInfo.logo" mode="widthFix">
</image>
@@ -14,15 +14,21 @@
<view class="iconfont icon-password icon"></view>
<input v-model="loginForm.password" type="password" class="input" placeholder="璇疯緭鍏ュ瘑鐮�" maxlength="20" />
</view>
- <view class="input-item flex align-center" style="width: 60%;margin: 0px;" v-if="captchaEnabled">
+ <view class="input-item flex align-center captcha-container" v-if="captchaEnabled">
<view class="iconfont icon-code icon"></view>
<input v-model="loginForm.code" type="number" class="input" placeholder="璇疯緭鍏ラ獙璇佺爜" maxlength="4" />
<view class="login-code">
- <image :src="codeUrl" @click="getCode" class="login-code-img"></image>
+ <image :src="codeUrl" @click="getCode" class="login-code-img" mode="aspectFit"></image>
</view>
</view>
<view class="action-btn">
<button @click="handleLogin" class="login-btn cu-btn block bg-blue lg round">鐧诲綍</button>
+ </view>
+ <view class="wechat-login" @click="handleWechatLogin">
+ <view class="wechat-btn">
+ <image class="wechat-icon" src="/static/icons/profile.png"></image>
+ <text class="wechat-text">寰俊涓�閿櫥褰�</text>
+ </view>
</view>
<view class="reg text-center" v-if="register">
<text class="text-grey1">娌℃湁璐﹀彿锛�</text>
@@ -34,8 +40,7 @@
<text @click="handlePrivacy" class="text-blue">銆婇殣绉佸崗璁��</text>
</view>
</view>
-
- </view>
+ </scroll-view>
</template>
<script>
@@ -98,6 +103,40 @@
this.pwdLogin()
}
},
+ // 寰俊鐧诲綍鏂规硶
+ async handleWechatLogin() {
+ // #ifdef MP-WEIXIN
+ // 寰俊灏忕▼搴忕櫥褰�
+ uni.login({
+ provider: 'weixin',
+ success: (loginRes) => {
+ console.log('寰俊鐧诲綍鎴愬姛', loginRes);
+ // 鑾峰彇鐢ㄦ埛淇℃伅
+ uni.getUserInfo({
+ provider: 'weixin',
+ success: (infoRes) => {
+ console.log('鐢ㄦ埛淇℃伅鑾峰彇鎴愬姛', infoRes);
+ // 璺宠浆鍒板井淇$櫥褰曠‘璁ら〉闈�
+ this.$tab.navigateTo(`/pages/login/wechat?userInfo=${encodeURIComponent(JSON.stringify(infoRes.userInfo))}`);
+ },
+ fail: (error) => {
+ console.error('鑾峰彇鐢ㄦ埛淇℃伅澶辫触', error);
+ this.$modal.msgError("鑾峰彇寰俊鐢ㄦ埛淇℃伅澶辫触");
+ }
+ });
+ },
+ fail: (error) => {
+ console.error('寰俊鐧诲綍澶辫触', error);
+ this.$modal.msgError("寰俊鐧诲綍澶辫触");
+ }
+ });
+ // #endif
+
+ // #ifndef MP-WEIXIN
+ // H5鎴栧叾浠栧钩鍙版彁绀�
+ this.$modal.msgError("璇峰湪寰俊瀹㈡埛绔腑浣跨敤寰俊鐧诲綍鍔熻兘");
+ // #endif
+ },
// 瀵嗙爜鐧诲綍
async pwdLogin() {
this.$store.dispatch('Login', this.loginForm).then(() => {
@@ -127,6 +166,24 @@
.normal-login-container {
width: 100%;
+ min-height: 100vh;
+ // 闅愯棌婊氬姩鏉′絾淇濇寔婊氬姩鍔熻兘
+ ::-webkit-scrollbar {
+ display: none;
+ width: 0 !important;
+ height: 0 !important;
+ background: transparent;
+ }
+
+ // Firefox婊氬姩鏉¢殣钘�
+ * {
+ scrollbar-width: none; /* Firefox */
+ }
+
+ // IE/Edge婊氬姩鏉¢殣钘�
+ * {
+ -ms-overflow-style: none; /* IE 10+ */
+ }
.logo-content {
width: 100%;
@@ -158,45 +215,100 @@
.icon {
font-size: 38rpx;
margin-left: 10px;
- color: #999;
}
.input {
+ margin-left: 20rpx;
width: 100%;
- font-size: 14px;
- line-height: 20px;
- text-align: left;
- padding-left: 15px;
+ height: 45px;
+ background: none;
+ }
+ }
+
+ .captcha-container {
+ width: 100%;
+ margin: 20px auto;
+ background-color: #f5f6f7;
+ height: 45px;
+ border-radius: 20px;
+ padding-right: 10rpx;
+ box-sizing: border-box;
+
+ .icon {
+ font-size: 38rpx;
+ margin-left: 10px;
}
+ .input {
+ margin-left: 20rpx;
+ width: 60%;
+ height: 45px;
+ background: none;
+ }
+
+ .login-code {
+ width: 30%;
+ height: 45px;
+ margin-left: 10rpx;
+ border-left: 1px solid #e0e0e0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ .login-code-img {
+ max-width: 100%;
+ max-height: 45px;
+ object-fit: contain;
+ cursor: pointer;
+ }
+ }
}
- .login-btn {
- margin-top: 40px;
- height: 45px;
+ .action-btn {
+ margin: 40rpx 0;
+
+ .login-btn {
+ height: 90rpx;
+ font-size: 32rpx;
+ }
}
-
- .reg {
- margin-top: 15px;
+
+ .wechat-login {
+ margin: 20rpx 0;
+
+ .wechat-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background-color: #07c160;
+ height: 90rpx;
+ border-radius: 20px;
+
+ .wechat-icon {
+ width: 40rpx;
+ height: 40rpx;
+ margin-right: 10rpx;
+ }
+
+ .wechat-text {
+ color: white;
+ font-size: 32rpx;
+ }
+ }
}
-
- .xieyi {
- color: #333;
- margin-top: 20px;
- }
-
- .login-code {
- height: 38px;
- float: right;
-
- .login-code-img {
- height: 38px;
- position: absolute;
- margin-left: 10px;
- width: 200rpx;
+
+ .reg, .xieyi {
+ margin: 20rpx 0;
+
+ .text-grey1 {
+ color: #888;
+ }
+
+ .text-blue {
+ margin: 0 10rpx;
+ color: #007AFF;
}
}
}
}
-
-</style>
+</style>
\ No newline at end of file
diff --git a/app/pages/login/wechat.vue b/app/pages/login/wechat.vue
new file mode 100644
index 0000000..c38f8f8
--- /dev/null
+++ b/app/pages/login/wechat.vue
@@ -0,0 +1,258 @@
+<template>
+ <view class="wechat-login-container">
+ <view class="header">
+ <view class="title">寰俊鎺堟潈鐧诲綍</view>
+ <view class="subtitle">鍗冲皢鐧诲綍鍒拌嫢渚濈鐞嗙郴缁�</view>
+ </view>
+
+ <view class="user-info-card">
+ <view class="avatar-section">
+ <image
+ class="user-avatar"
+ :src="wechatUserInfo.avatarUrl || '/static/images/profile.jpg'"
+ mode="aspectFill"
+ ></image>
+ </view>
+
+ <view class="info-section">
+ <view class="info-item">
+ <view class="label">鏄电О</view>
+ <view class="value">{{ wechatUserInfo.nickName || '鏈煡鐢ㄦ埛' }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">鎬у埆</view>
+ <view class="value">{{ genderText }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">鍦板尯</view>
+ <view class="value">{{ wechatUserInfo.country }} {{ wechatUserInfo.province }} {{ wechatUserInfo.city }}</view>
+ </view>
+ </view>
+ </view>
+
+ <view class="agreement-section">
+ <label class="checkbox">
+ <checkbox :checked="agreed" @click="toggleAgreement" />
+ <text class="agreement-text">鎴戝凡闃呰骞跺悓鎰�</text>
+ <text class="link" @click="handleUserAgrement">銆婄敤鎴峰崗璁��</text>
+ <text>鍜�</text>
+ <text class="link" @click="handlePrivacy">銆婇殣绉佸崗璁��</text>
+ </label>
+ </view>
+
+ <view class="action-buttons">
+ <button
+ class="confirm-btn"
+ :class="{ disabled: !agreed }"
+ :disabled="!agreed"
+ @click="confirmLogin"
+ >
+ 纭鐧诲綍
+ </button>
+ <button class="cancel-btn" @click="cancelLogin">鍙栨秷</button>
+ </view>
+ </view>
+</template>
+
+<script>
+ export default {
+ data() {
+ return {
+ agreed: false,
+ wechatUserInfo: {},
+ globalConfig: getApp().globalData.config
+ }
+ },
+ onLoad(options) {
+ // 鎺ユ敹浠庣櫥褰曢〉闈紶閫掔殑寰俊鐢ㄦ埛淇℃伅
+ if (options.userInfo) {
+ this.wechatUserInfo = JSON.parse(decodeURIComponent(options.userInfo))
+ console.log('寰俊鐢ㄦ埛淇℃伅:', this.wechatUserInfo)
+ }
+ },
+ computed: {
+ genderText() {
+ const genderMap = {
+ 0: '鏈煡',
+ 1: '鐢�',
+ 2: '濂�'
+ }
+ return genderMap[this.wechatUserInfo.gender] || '鏈煡'
+ }
+ },
+ methods: {
+ toggleAgreement() {
+ this.agreed = !this.agreed
+ },
+ // 闅愮鍗忚
+ handlePrivacy() {
+ let site = this.globalConfig.appInfo.agreements[0]
+ this.$tab.navigateTo(`/pages/common/webview/index?title=${site.title}&url=${site.url}`)
+ },
+ // 鐢ㄦ埛鍗忚
+ handleUserAgrement() {
+ let site = this.globalConfig.appInfo.agreements[1]
+ this.$tab.navigateTo(`/pages/common/webview/index?title=${site.title}&url=${site.url}`)
+ },
+ // 纭鐧诲綍
+ async confirmLogin() {
+ if (!this.agreed) {
+ this.$modal.msgError("璇峰厛鍚屾剰鐢ㄦ埛鍗忚鍜岄殣绉佸崗璁�")
+ return
+ }
+
+ this.$modal.loading("鐧诲綍涓�...")
+
+ // 杩欓噷搴旇璋冪敤鍚庣寰俊鐧诲綍鎺ュ彛
+ // 绀轰緥浠g爜锛屽疄闄呴渶瑕佹牴鎹悗绔帴鍙h皟鏁�
+ /*
+ this.$store.dispatch('WechatLogin', {
+ openid: this.wechatUserInfo.openId,
+ userInfo: this.wechatUserInfo
+ }).then(() => {
+ this.$modal.closeLoading()
+ this.loginSuccess()
+ }).catch(() => {
+ this.$modal.closeLoading()
+ this.$modal.msgError("寰俊鐧诲綍澶辫触")
+ })
+ */
+
+ // 涓存椂婕旂ず鐢�
+ setTimeout(() => {
+ this.$modal.closeLoading()
+ this.$modal.showToast("寰俊鐧诲綍鎴愬姛")
+ this.$tab.reLaunch('/pages/index')
+ }, 1000)
+ },
+ // 鍙栨秷鐧诲綍
+ cancelLogin() {
+ this.$modal.confirm('纭畾瑕佸彇娑堢櫥褰曞悧锛�').then(() => {
+ this.$tab.reLaunch('/pages/login')
+ }).catch(() => {
+ // 鍙栨秷鎿嶄綔
+ })
+ },
+ // 鐧诲綍鎴愬姛鍚庯紝澶勭悊鍑芥暟
+ loginSuccess(result) {
+ // 璁剧疆鐢ㄦ埛淇℃伅
+ this.$store.dispatch('GetInfo').then(res => {
+ this.$tab.reLaunch('/pages/index')
+ })
+ }
+ }
+ }
+</script>
+
+<style lang="scss">
+ .wechat-login-container {
+ padding: 40rpx;
+ background-color: #f5f5f5;
+ min-height: 100vh;
+
+ .header {
+ text-align: center;
+ margin-bottom: 60rpx;
+
+ .title {
+ font-size: 36rpx;
+ font-weight: bold;
+ margin-bottom: 20rpx;
+ }
+
+ .subtitle {
+ font-size: 28rpx;
+ color: #666;
+ }
+ }
+
+ .user-info-card {
+ background-color: white;
+ border-radius: 20rpx;
+ padding: 40rpx;
+ margin-bottom: 40rpx;
+ box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
+
+ .avatar-section {
+ text-align: center;
+ margin-bottom: 40rpx;
+
+ .user-avatar {
+ width: 120rpx;
+ height: 120rpx;
+ border-radius: 50%;
+ border: 4rpx solid #f0f0f0;
+ }
+ }
+
+ .info-section {
+ .info-item {
+ display: flex;
+ justify-content: space-between;
+ padding: 20rpx 0;
+ border-bottom: 1rpx solid #f0f0f0;
+
+ &:last-child {
+ border-bottom: none;
+ }
+
+ .label {
+ font-size: 28rpx;
+ color: #666;
+ }
+
+ .value {
+ font-size: 28rpx;
+ font-weight: bold;
+ }
+ }
+ }
+ }
+
+ .agreement-section {
+ margin-bottom: 60rpx;
+
+ .checkbox {
+ display: flex;
+ align-items: center;
+
+ .agreement-text {
+ margin: 0 10rpx;
+ }
+
+ .link {
+ color: #007AFF;
+ margin: 0 5rpx;
+ }
+ }
+ }
+
+ .action-buttons {
+ .confirm-btn {
+ width: 100%;
+ height: 80rpx;
+ background-color: #07c160;
+ color: white;
+ border-radius: 10rpx;
+ font-size: 32rpx;
+ margin-bottom: 20rpx;
+
+ &.disabled {
+ background-color: #cccccc;
+ }
+ }
+
+ .cancel-btn {
+ width: 100%;
+ height: 80rpx;
+ background-color: white;
+ color: #333;
+ border: 1rpx solid #ddd;
+ border-radius: 10rpx;
+ font-size: 32rpx;
+ }
+ }
+ }
+</style>
\ No newline at end of file
diff --git a/app/pages/message/index.vue b/app/pages/message/index.vue
new file mode 100644
index 0000000..2aaa9e5
--- /dev/null
+++ b/app/pages/message/index.vue
@@ -0,0 +1,239 @@
+<template>
+ <view class="message-container">
+ <view class="message-header">
+ <view class="header-title">娑堟伅涓績</view>
+ </view>
+
+ <scroll-view class="message-list-scroll" scroll-y="true">
+ <view class="message-list">
+ <!-- 鏈娑堟伅鍦ㄥ墠 -->
+ <view
+ class="message-item"
+ v-for="message in sortedMessages"
+ :key="message.id"
+ @click="viewMessageDetail(message)"
+ >
+ <view class="message-main">
+ <view class="message-title">
+ <text class="title-text">{{ getMessageTypeText(message.type) }}</text>
+ <view class="unread-dot" v-if="!message.read"></view>
+ </view>
+ <view class="message-content">{{ message.content }}</view>
+ <view class="message-time">{{ message.time }}</view>
+ </view>
+ </view>
+
+ <view class="no-data" v-if="sortedMessages.length === 0">
+ <uni-icons type="info" size="40" color="#ccc"></uni-icons>
+ <text>鏆傛棤娑堟伅</text>
+ </view>
+ </view>
+ </scroll-view>
+ </view>
+</template>
+
+<script>
+ export default {
+ data() {
+ return {
+ // 娑堟伅鍒楄〃
+ messages: [
+ {
+ id: 1,
+ type: 'create', // 鍒涘缓鎴愬姛
+ content: 'TD 1011 骞垮窞澶╂渤->骞垮窞涓滅珯锛屾椂闂达細13锛�20 浠诲姟鍒涘缓鎴愬姛',
+ time: '2023-05-15 13:20',
+ read: false,
+ taskId: 1
+ },
+ {
+ id: 2,
+ type: 'push', // 浠诲姟鎺ㄩ��
+ content: 'TD1021 骞垮窞澶╂渤->骞垮窞涓滅珯锛屾椂闂达細13锛�20 鍑哄彂锛岃鍙婃椂澶勭悊',
+ time: '2023-05-15 13:25',
+ read: false,
+ taskId: 2
+ },
+ {
+ id: 3,
+ type: 'status', // 浠诲姟鐘舵�佸彉鏇�
+ content: 'TD1021 骞垮窞澶╂渤->骞垮窞涓滅珯锛屾椂闂达細13锛�20锛屼换鍔℃鍦ㄨ浆杩愪腑',
+ time: '2023-05-15 14:30',
+ read: true,
+ taskId: 2
+ },
+ {
+ id: 4,
+ type: 'create', // 鍒涘缓鎴愬姛
+ content: 'TD 1022 娣卞湷鍗楀北->娣卞湷绂忕敯锛屾椂闂达細15锛�10 浠诲姟鍒涘缓鎴愬姛',
+ time: '2023-05-15 15:10',
+ read: false,
+ taskId: 3
+ },
+ {
+ id: 5,
+ type: 'push', // 浠诲姟鎺ㄩ��
+ content: 'TD1023 娣卞湷鍗楀北->娣卞湷绂忕敯锛屾椂闂达細16锛�00 鍑哄彂锛岃鍙婃椂澶勭悊',
+ time: '2023-05-15 16:00',
+ read: true,
+ taskId: 4
+ }
+ ]
+ }
+ },
+ computed: {
+ // 鎸夋湭璇�/宸茶鎺掑簭锛屾湭璇荤殑鍦ㄥ墠闈�
+ sortedMessages() {
+ return [...this.messages].sort((a, b) => {
+ if (a.read === b.read) {
+ // 鐩稿悓鐘舵�佹寜鏃堕棿鍊掑簭
+ return new Date(b.time) - new Date(a.time);
+ }
+ // 鏈鐨勬帓鍦ㄥ墠闈�
+ return a.read ? 1 : -1;
+ });
+ }
+ },
+ methods: {
+ // 鑾峰彇娑堟伅绫诲瀷鏂囨湰
+ getMessageTypeText(type) {
+ const typeMap = {
+ 'create': '鍒涘缓鎴愬姛',
+ 'push': '浠诲姟鎺ㄩ��',
+ 'status': '浠诲姟鐘舵��'
+ }
+ return typeMap[type] || '绯荤粺娑堟伅';
+ },
+
+ // 鏌ョ湅娑堟伅璇︽儏锛堣烦杞埌浠诲姟璇︽儏锛�
+ viewMessageDetail(message) {
+ // 鏍囪涓哄凡璇�
+ message.read = true;
+
+ // 璺宠浆鍒颁换鍔¤鎯呴〉闈�
+ if (message.taskId) {
+ this.$tab.navigateTo(`/pages/task/detail?id=${message.taskId}`);
+ } else {
+ this.$modal.showToast('鏃犳硶鎵惧埌鍏宠仈浠诲姟');
+ }
+ }
+ }
+ }
+</script>
+
+<style lang="scss">
+ .message-container {
+ padding: 20rpx;
+ background-color: #f5f5f5;
+ height: 100vh;
+ display: flex;
+ flex-direction: column;
+ // 闅愯棌婊氬姩鏉′絾淇濇寔婊氬姩鍔熻兘
+ ::-webkit-scrollbar {
+ display: none;
+ width: 0 !important;
+ height: 0 !important;
+ background: transparent;
+ }
+
+ // Firefox婊氬姩鏉¢殣钘�
+ * {
+ scrollbar-width: none; /* Firefox */
+ }
+
+ // IE/Edge婊氬姩鏉¢殣钘�
+ * {
+ -ms-overflow-style: none; /* IE 10+ */
+ }
+ }
+
+ .message-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 20rpx 0;
+ flex-shrink: 0; // 闃叉鏀剁缉
+
+ .header-title {
+ font-size: 36rpx;
+ font-weight: bold;
+ }
+ }
+
+ .message-list-scroll {
+ flex: 1;
+ // 闅愯棌婊氬姩鏉′絾淇濇寔婊氬姩鍔熻兘
+ ::-webkit-scrollbar {
+ display: none;
+ width: 0 !important;
+ height: 0 !important;
+ background: transparent;
+ }
+
+ // Firefox婊氬姩鏉¢殣钘�
+ * {
+ scrollbar-width: none; /* Firefox */
+ }
+
+ // IE/Edge婊氬姩鏉¢殣钘�
+ * {
+ -ms-overflow-style: none; /* IE 10+ */
+ }
+ }
+
+ .message-list {
+ .message-item {
+ background-color: white;
+ border-radius: 15rpx;
+ margin-bottom: 20rpx;
+ padding: 30rpx;
+ box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+
+ .message-main {
+ .message-title {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 20rpx;
+
+ .title-text {
+ font-size: 32rpx;
+ font-weight: bold;
+ color: #333;
+ }
+
+ .unread-dot {
+ width: 16rpx;
+ height: 16rpx;
+ border-radius: 50%;
+ background-color: #ff4d4f;
+ }
+ }
+
+ .message-content {
+ font-size: 28rpx;
+ color: #666;
+ margin-bottom: 20rpx;
+ line-height: 1.5;
+ }
+
+ .message-time {
+ font-size: 24rpx;
+ color: #999;
+ text-align: right;
+ }
+ }
+ }
+
+ .no-data {
+ text-align: center;
+ padding: 100rpx 0;
+ color: #999;
+
+ text {
+ display: block;
+ margin-top: 20rpx;
+ }
+ }
+ }
+</style>
\ No newline at end of file
diff --git a/app/pages/mine/index.vue b/app/pages/mine/index.vue
index 33c3a6e..e936762 100644
--- a/app/pages/mine/index.vue
+++ b/app/pages/mine/index.vue
@@ -1,5 +1,5 @@
<template>
- <view class="mine-container" :style="{height: `${windowHeight}px`}">
+ <view class="mine-container">
<!--椤堕儴涓汉淇℃伅鏍�-->
<view class="header-section">
<view class="flex padding justify-between">
@@ -25,7 +25,7 @@
</view>
</view>
- <view class="content-section">
+ <scroll-view class="content-section" scroll-y="true">
<view class="mine-actions grid col-4 text-center">
<view class="action-item" @click="handleJiaoLiuQun">
<view class="iconfont icon-friendfill text-pink icon"></view>
@@ -42,6 +42,34 @@
<view class="action-item" @click="handleBuilding">
<view class="iconfont icon-dianzan text-green icon"></view>
<text class="text">鐐硅禐鎴戜滑</text>
+ </view>
+ </view>
+
+ <!-- 鐢ㄦ埛淇℃伅灞曠ず -->
+ <view class="user-info-section">
+ <view class="info-item">
+ <view class="info-label">鐢ㄦ埛鍚嶏細</view>
+ <view class="info-value">{{ name || '鏈櫥褰�' }}</view>
+ </view>
+ <view class="info-item">
+ <view class="info-label">鎵嬫満鍙风爜锛�</view>
+ <view class="info-value">{{ phonenumber || '鏈粦瀹�' }}</view>
+ </view>
+ <view class="info-item">
+ <view class="info-label">缁戝畾杞﹁締锛�</view>
+ <view class="info-value">{{ boundVehicle || '鏈粦瀹�' }}</view>
+ </view>
+ <view class="info-item">
+ <view class="info-label">App鐗堟湰鍙凤細</view>
+ <view class="info-value">{{ version || '1.0.0' }}</view>
+ </view>
+
+ <!-- 缁戝畾/瑙g粦杞﹁締鎿嶄綔 -->
+ <view class="vehicle-actions" v-if="boundVehicle && boundVehicle !== '鏈粦瀹�'">
+ <button class="unbind-btn" @click="unbindVehicle">鍙栨秷缁戝畾杞﹁締</button>
+ </view>
+ <view class="vehicle-actions" v-else>
+ <button class="bind-btn" @click="goToBindVehicle">缁戝畾杞﹁締</button>
</view>
</view>
@@ -71,18 +99,20 @@
</view>
</view>
</view>
-
- </view>
+ </scroll-view>
</view>
</template>
<script>
import storage from '@/utils/storage'
+ import { getUserProfile } from "@/api/system/user"
export default {
data() {
return {
name: this.$store.state.user.name,
+ phonenumber: '',
+ boundVehicle: '', // 妯℃嫙缁戝畾鐨勮溅杈嗕俊鎭�
version: getApp().globalData.config.appInfo.version
}
},
@@ -94,7 +124,42 @@
return uni.getSystemInfoSync().windowHeight - 50
}
},
+ onLoad() {
+ this.getUserInfo()
+ },
methods: {
+ // 鑾峰彇鐢ㄦ埛淇℃伅
+ getUserInfo() {
+ getUserProfile().then(response => {
+ const user = response.data
+ this.name = user.userName
+ this.phonenumber = user.phonenumber
+ // 妯℃嫙缁戝畾杞﹁締淇℃伅锛屽疄闄呴」鐩腑搴斾粠鐢ㄦ埛淇℃伅鎴栬溅杈嗘帴鍙h幏鍙�
+ this.boundVehicle = '绮12345'
+ }).catch(() => {
+ // 鑾峰彇鐢ㄦ埛淇℃伅澶辫触鏃朵娇鐢ㄩ粯璁ゅ��
+ this.name = this.$store.state.user.name || '鏈櫥褰�'
+ this.phonenumber = '鏈粦瀹�'
+ this.boundVehicle = '鏈粦瀹�'
+ })
+ },
+
+ // 璺宠浆鍒扮粦瀹氳溅杈嗛〉闈�
+ goToBindVehicle() {
+ this.$tab.navigateTo('/pages/bind-vehicle')
+ },
+
+ // 鍙栨秷缁戝畾杞﹁締
+ unbindVehicle() {
+ this.$modal.confirm('鏄惁鍙栨秷缁戝畾杞﹁締锛�').then(() => {
+ // 杩欓噷鍙互璋冪敤API鍙栨秷缁戝畾杞﹁締
+ this.boundVehicle = '鏈粦瀹�'
+ this.$modal.showToast('鍙栨秷缁戝畾鎴愬姛')
+ }).catch(() => {
+ // 鐢ㄦ埛鍙栨秷鎿嶄綔
+ })
+ },
+
handleToInfo() {
this.$tab.navigateTo('/pages/mine/info/index')
},
@@ -140,13 +205,32 @@
.mine-container {
width: 100%;
- height: 100%;
-
+ height: 100vh;
+ display: flex;
+ flex-direction: column;
+ // 闅愯棌婊氬姩鏉′絾淇濇寔婊氬姩鍔熻兘
+ ::-webkit-scrollbar {
+ display: none;
+ width: 0 !important;
+ height: 0 !important;
+ background: transparent;
+ }
+
+ // Firefox婊氬姩鏉¢殣钘�
+ * {
+ scrollbar-width: none; /* Firefox */
+ }
+
+ // IE/Edge婊氬姩鏉¢殣钘�
+ * {
+ -ms-overflow-style: none; /* IE 10+ */
+ }
.header-section {
padding: 15px 15px 45px 15px;
background-color: #3c96f3;
color: white;
+ flex-shrink: 0; // 闃叉鏀剁缉
.login-tip {
font-size: 18px;
@@ -172,8 +256,26 @@
}
.content-section {
+ flex: 1;
position: relative;
top: -50px;
+ // 闅愯棌婊氬姩鏉′絾淇濇寔婊氬姩鍔熻兘
+ ::-webkit-scrollbar {
+ display: none;
+ width: 0 !important;
+ height: 0 !important;
+ background: transparent;
+ }
+
+ // Firefox婊氬姩鏉¢殣钘�
+ * {
+ scrollbar-width: none; /* Firefox */
+ }
+
+ // IE/Edge婊氬姩鏉¢殣钘�
+ * {
+ -ms-overflow-style: none; /* IE 10+ */
+ }
.mine-actions {
margin: 15px 15px;
@@ -193,6 +295,60 @@
}
}
}
+
+ // 鐢ㄦ埛淇℃伅灞曠ず鍖哄煙
+ .user-info-section {
+ background-color: white;
+ border-radius: 8px;
+ padding: 20rpx 30rpx;
+ margin: 15rpx;
+ box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+
+ .info-item {
+ display: flex;
+ padding: 15rpx 0;
+ border-bottom: 1rpx solid #f0f0f0;
+
+ &:last-child {
+ border-bottom: none;
+ }
+
+ .info-label {
+ font-size: 28rpx;
+ color: #666;
+ width: 180rpx;
+ flex-shrink: 0;
+ }
+
+ .info-value {
+ font-size: 28rpx;
+ color: #333;
+ flex: 1;
+ }
+ }
+
+ .vehicle-actions {
+ padding: 30rpx 0 10rpx 0;
+ text-align: center;
+
+ .bind-btn, .unbind-btn {
+ width: 80%;
+ height: 80rpx;
+ border-radius: 10rpx;
+ font-size: 32rpx;
+ }
+
+ .bind-btn {
+ background-color: #007AFF;
+ color: white;
+ }
+
+ .unbind-btn {
+ background-color: #ff4d4f;
+ color: white;
+ }
+ }
+ }
}
}
-</style>
+</style>
\ No newline at end of file
diff --git a/app/pages/mine/info/index.vue b/app/pages/mine/info/index.vue
index 65c861a..3a1b9de 100644
--- a/app/pages/mine/info/index.vue
+++ b/app/pages/mine/info/index.vue
@@ -1,13 +1,23 @@
<template>
<view class="container">
<uni-list>
- <uni-list-item showExtraIcon="true" :extraIcon="{type: 'person-filled'}" title="鏄电О" :rightText="user.nickName" />
+ <uni-list-item showExtraIcon="true" :extraIcon="{type: 'person-filled'}" title="鐢ㄦ埛鍚�" :rightText="user.userName" />
<uni-list-item showExtraIcon="true" :extraIcon="{type: 'phone-filled'}" title="鎵嬫満鍙风爜" :rightText="user.phonenumber" />
+ <uni-list-item showExtraIcon="true" :extraIcon="{type: 'location-filled'}" title="缁戝畾杞﹁締" :rightText="boundVehicle || '鏈粦瀹�'" />
+ <uni-list-item showExtraIcon="true" :extraIcon="{type: 'info-filled'}" title="App鐗堟湰鍙�" :rightText="version" />
<uni-list-item showExtraIcon="true" :extraIcon="{type: 'email-filled'}" title="閭" :rightText="user.email" />
<uni-list-item showExtraIcon="true" :extraIcon="{type: 'auth-filled'}" title="宀椾綅" :rightText="postGroup" />
<uni-list-item showExtraIcon="true" :extraIcon="{type: 'staff-filled'}" title="瑙掕壊" :rightText="roleGroup" />
<uni-list-item showExtraIcon="true" :extraIcon="{type: 'calendar-filled'}" title="鍒涘缓鏃ユ湡" :rightText="user.createTime" />
</uni-list>
+
+ <!-- 缁戝畾/瑙g粦杞﹁締鎿嶄綔 -->
+ <view class="vehicle-actions" v-if="boundVehicle">
+ <button class="unbind-btn" @click="unbindVehicle">鍙栨秷缁戝畾杞﹁締</button>
+ </view>
+ <view class="vehicle-actions" v-else>
+ <button class="bind-btn" @click="goToBindVehicle">缁戝畾杞﹁締</button>
+ </view>
</view>
</template>
@@ -19,7 +29,9 @@
return {
user: {},
roleGroup: "",
- postGroup: ""
+ postGroup: "",
+ boundVehicle: "", // 妯℃嫙缁戝畾鐨勮溅杈嗕俊鎭�
+ version: getApp().globalData.config.appInfo.version || "1.0.0" // App鐗堟湰鍙�
}
},
onLoad() {
@@ -32,6 +44,22 @@
this.roleGroup = response.roleGroup
this.postGroup = response.postGroup
})
+ },
+
+ // 璺宠浆鍒扮粦瀹氳溅杈嗛〉闈�
+ goToBindVehicle() {
+ this.$tab.navigateTo('/pages/bind-vehicle')
+ },
+
+ // 鍙栨秷缁戝畾杞﹁締
+ unbindVehicle() {
+ this.$modal.confirm('鏄惁鍙栨秷缁戝畾杞﹁締锛�').then(() => {
+ // 杩欓噷鍙互璋冪敤API鍙栨秷缁戝畾杞﹁締
+ this.boundVehicle = ""
+ this.$modal.showToast('鍙栨秷缁戝畾鎴愬姛')
+ }).catch(() => {
+ // 鐢ㄦ埛鍙栨秷鎿嶄綔
+ })
}
}
}
@@ -41,4 +69,26 @@
page {
background-color: #ffffff;
}
-</style>
+
+ .vehicle-actions {
+ padding: 30rpx;
+ text-align: center;
+
+ .bind-btn, .unbind-btn {
+ width: 80%;
+ height: 80rpx;
+ border-radius: 10rpx;
+ font-size: 32rpx;
+ }
+
+ .bind-btn {
+ background-color: #007AFF;
+ color: white;
+ }
+
+ .unbind-btn {
+ background-color: #ff4d4f;
+ color: white;
+ }
+ }
+</style>
\ No newline at end of file
diff --git a/app/pages/task/create.vue b/app/pages/task/create.vue
new file mode 100644
index 0000000..1cf4741
--- /dev/null
+++ b/app/pages/task/create.vue
@@ -0,0 +1,856 @@
+<template>
+ <scroll-view class="create-task-container" scroll-y="true">
+ <!-- 浠诲姟绫诲瀷閫夋嫨鐣岄潰 -->
+ <view v-if="!selectedTaskCategory" class="task-category-container">
+ <view class="header">
+ <view class="title">閫夋嫨浠诲姟绫诲瀷</view>
+ <view class="subtitle">璇烽�夋嫨鎮ㄨ鍒涘缓鐨勪换鍔$被鍨�</view>
+ </view>
+
+ <view class="category-list">
+ <view
+ class="category-item"
+ v-for="(category, index) in taskCategories"
+ :key="index"
+ @click="selectTaskCategory(category)"
+ >
+ <view class="icon">
+ <uni-icons :type="category.icon" size="30" :color="category.color"></uni-icons>
+ </view>
+ <view class="info">
+ <view class="name">{{ category.name }}</view>
+ <view class="desc">{{ category.description }}</view>
+ </view>
+ <view class="arrow">
+ <uni-icons type="arrowright" size="20" color="#999"></uni-icons>
+ </view>
+ </view>
+ </view>
+ </view>
+
+ <!-- 浠诲姟鍒涘缓琛ㄥ崟 -->
+ <view v-else class="task-form-container">
+ <view class="form-header">
+ <view class="back-btn" @click="backToCategory">
+ <uni-icons type="arrowleft" size="20"></uni-icons>
+ </view>
+ <view class="title">鍒涘缓{{ selectedTaskCategory.name }}浠诲姟</view>
+ </view>
+
+ <view class="form-section">
+ <!-- 鏅�氫换鍔¤〃鍗� -->
+ <view v-if="selectedTaskCategory.type === 'normal'">
+ <view class="form-item">
+ <view class="form-label">浠诲姟杞﹁締</view>
+ <picker mode="selector" :range="vehicles" @change="onVehicleChange">
+ <view class="form-input picker-input">
+ {{ selectedVehicle || '璇烽�夋嫨浠诲姟杞﹁締' }}
+ <uni-icons type="arrowright" size="16" color="#999"></uni-icons>
+ </view>
+ </picker>
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">浠诲姟绫诲瀷</view>
+ <input
+ class="form-input"
+ :value="selectedTaskCategory.name"
+ disabled
+ />
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">浠诲姟鎻忚堪</view>
+ <textarea
+ class="form-textarea"
+ placeholder="璇疯緭鍏ヤ换鍔℃弿杩�"
+ v-model="taskForm.description"
+ />
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">浠诲姟鍑哄彂鍦�</view>
+ <view class="form-input picker-input" @click="selectStartLocation">
+ {{ taskForm.startLocation || '璇烽�夋嫨浠诲姟鍑哄彂鍦�' }}
+ <uni-icons type="arrowright" size="16" color="#999"></uni-icons>
+ </view>
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">浠诲姟鐩殑鍦�</view>
+ <view class="form-input picker-input" @click="selectEndLocation">
+ {{ taskForm.endLocation || '璇烽�夋嫨浠诲姟鐩殑鍦�' }}
+ <uni-icons type="arrowright" size="16" color="#999"></uni-icons>
+ </view>
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">琛岄┒鍏噷鏁�</view>
+ <input
+ class="form-input"
+ type="digit"
+ placeholder="璇疯緭鍏ヨ椹跺叕閲屾暟"
+ v-model="taskForm.distance"
+ />
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">寮�濮嬫椂闂�</view>
+ <!-- 浣跨敤uni-datetime-picker缁勪欢 -->
+ <uni-datetime-picker
+ v-model="taskForm.startTime"
+ type="datetime"
+ :placeholder="'璇烽�夋嫨寮�濮嬫椂闂�'"
+ class="form-input"
+ />
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">缁撴潫鏃堕棿</view>
+ <!-- 浣跨敤uni-datetime-picker缁勪欢 -->
+ <uni-datetime-picker
+ v-model="taskForm.endTime"
+ type="datetime"
+ :placeholder="'璇烽�夋嫨缁撴潫鏃堕棿'"
+ class="form-input"
+ />
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">鎵ц浜�</view>
+ <input
+ class="form-input"
+ :value="currentUser.name"
+ disabled
+ />
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">澶囨敞</view>
+ <textarea
+ class="form-textarea"
+ placeholder="璇疯緭鍏ュ娉ㄤ俊鎭紙鏈�澶�200瀛楋級"
+ v-model="taskForm.remark"
+ maxlength="200"
+ />
+ </view>
+ </view>
+
+ <!-- 鎬ユ晳杞繍浠诲姟琛ㄥ崟 -->
+ <view v-else-if="selectedTaskCategory.type === 'emergency'">
+ <view class="form-item">
+ <view class="form-label">浠诲姟杞﹁締</view>
+ <picker mode="selector" :range="vehicles" @change="onVehicleChange">
+ <view class="form-input picker-input">
+ {{ selectedVehicle || '璇烽�夋嫨浠诲姟杞﹁締' }}
+ <uni-icons type="arrowright" size="16" color="#999"></uni-icons>
+ </view>
+ </picker>
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">鎵ц浠诲姟浜哄憳</view>
+ <view class="staff-list">
+ <view class="staff-item">
+ <text>{{ currentUser.name }} ({{ currentUser.position }})</text>
+ <uni-icons type="checkmarkempty" size="20" color="#007AFF"></uni-icons>
+ </view>
+ <view
+ class="staff-item"
+ v-for="(staff, index) in additionalStaff"
+ :key="index"
+ @click="removeStaff(index)"
+ >
+ <text>{{ staff.name }} ({{ staff.position }})</text>
+ <uni-icons type="closeempty" size="20" color="#ff4d4f"></uni-icons>
+ </view>
+ <view class="add-staff" @click="addStaff">
+ <uni-icons type="plusempty" size="20" color="#007AFF"></uni-icons>
+ <text>娣诲姞浜哄憳</text>
+ </view>
+ </view>
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">褰掑睘鏈烘瀯</view>
+ <picker mode="selector" :range="organizations" @change="onOrganizationChange">
+ <view class="form-input picker-input">
+ {{ selectedOrganization || '璇烽�夋嫨褰掑睘鏈烘瀯' }}
+ <uni-icons type="arrowright" size="16" color="#999"></uni-icons>
+ </view>
+ </picker>
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">浠诲姟绫诲瀷</view>
+ <picker mode="selector" :range="emergencyTaskTypes" @change="onEmergencyTaskTypeChange">
+ <view class="form-input picker-input">
+ {{ selectedEmergencyTaskType || '璇烽�夋嫨浠诲姟绫诲瀷' }}
+ <uni-icons type="arrowright" size="16" color="#999"></uni-icons>
+ </view>
+ </picker>
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">杞繍鏃堕棿</view>
+ <!-- 浣跨敤uni-datetime-picker缁勪欢 -->
+ <uni-datetime-picker
+ v-model="taskForm.transferTime"
+ type="datetime"
+ :placeholder="'璇烽�夋嫨杞繍鏃堕棿'"
+ class="form-input"
+ />
+ </view>
+
+ <view class="form-section-title">鎮h�呬俊鎭�</view>
+ <view class="form-item">
+ <view class="form-label">鑱旂郴浜�</view>
+ <input
+ class="form-input"
+ placeholder="璇疯緭鍏ヨ仈绯讳汉"
+ v-model="taskForm.patient.contact"
+ />
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">鑱旂郴鐢佃瘽</view>
+ <input
+ class="form-input"
+ type="number"
+ placeholder="璇疯緭鍏ヨ仈绯荤數璇�"
+ v-model="taskForm.patient.phone"
+ />
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">鎮h�呭鍚�</view>
+ <input
+ class="form-input"
+ placeholder="璇疯緭鍏ユ偅鑰呭鍚�"
+ v-model="taskForm.patient.name"
+ />
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">鎬у埆</view>
+ <view class="radio-group">
+ <label class="radio-item">
+ <radio value="male" :checked="taskForm.patient.gender === 'male'" @click="taskForm.patient.gender = 'male'" />
+ <text>鐢�</text>
+ </label>
+ <label class="radio-item">
+ <radio value="female" :checked="taskForm.patient.gender === 'female'" @click="taskForm.patient.gender = 'female'" />
+ <text>濂�</text>
+ </label>
+ </view>
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">鎮h�呰韩浠借瘉</view>
+ <input
+ class="form-input"
+ type="idcard"
+ placeholder="璇疯緭鍏ユ偅鑰呰韩浠借瘉鍙�"
+ v-model="taskForm.patient.idCard"
+ />
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">鐥呮儏</view>
+ <textarea
+ class="form-textarea"
+ placeholder="璇疯緭鍏ユ偅鑰呯梾鎯呮弿杩�"
+ v-model="taskForm.patient.condition"
+ />
+ </view>
+
+ <view class="form-section-title">杞嚭鍖婚櫌淇℃伅</view>
+ <view class="form-item">
+ <view class="form-label">鍖婚櫌鍚嶇О</view>
+ <input
+ class="form-input"
+ placeholder="璇疯緭鍏ヨ浆鍑哄尰闄㈠悕绉�"
+ v-model="taskForm.hospitalOut.name"
+ />
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">绉戝</view>
+ <input
+ class="form-input"
+ placeholder="璇疯緭鍏ョ瀹�"
+ v-model="taskForm.hospitalOut.department"
+ />
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">搴婂彿</view>
+ <input
+ class="form-input"
+ placeholder="璇疯緭鍏ュ簥鍙�"
+ v-model="taskForm.hospitalOut.bedNumber"
+ />
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">杞嚭鍦板潃</view>
+ <view class="form-input picker-input" @click="selectHospitalOutAddress">
+ {{ taskForm.hospitalOut.address || '璇烽�夋嫨杞嚭鍦板潃' }}
+ <uni-icons type="arrowright" size="16" color="#999"></uni-icons>
+ </view>
+ </view>
+
+ <view class="form-section-title">杞叆鍖婚櫌淇℃伅</view>
+ <view class="form-item">
+ <view class="form-label">鍖婚櫌鍚嶇О</view>
+ <input
+ class="form-input"
+ placeholder="璇疯緭鍏ヨ浆鍏ュ尰闄㈠悕绉�"
+ v-model="taskForm.hospitalIn.name"
+ />
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">绉戝</view>
+ <input
+ class="form-input"
+ placeholder="璇疯緭鍏ョ瀹�"
+ v-model="taskForm.hospitalIn.department"
+ />
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">搴婂彿</view>
+ <input
+ class="form-input"
+ placeholder="璇疯緭鍏ュ簥鍙�"
+ v-model="taskForm.hospitalIn.bedNumber"
+ />
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">杞叆鍦板潃</view>
+ <view class="form-input picker-input" @click="selectHospitalInAddress">
+ {{ taskForm.hospitalIn.address || '璇烽�夋嫨杞叆鍦板潃' }}
+ <uni-icons type="arrowright" size="16" color="#999"></uni-icons>
+ </view>
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">杞繍鍏噷鏁�</view>
+ <input
+ class="form-input"
+ type="digit"
+ placeholder="璇疯緭鍏ヨ浆杩愬叕閲屾暟"
+ v-model="taskForm.transferDistance"
+ />
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">鎴愪氦浠�</view>
+ <input
+ class="form-input"
+ type="digit"
+ placeholder="璇疯緭鍏ユ垚浜や环"
+ v-model="taskForm.price"
+ />
+ </view>
+ </view>
+
+ <!-- 绂忕杞︿换鍔¤〃鍗� -->
+ <view v-else-if="selectedTaskCategory.type === 'welfare'">
+ <view class="form-item">
+ <view class="form-label">浠诲姟杞﹁締</view>
+ <picker mode="selector" :range="vehicles" @change="onVehicleChange">
+ <view class="form-input picker-input">
+ {{ selectedVehicle || '璇烽�夋嫨浠诲姟杞﹁締' }}
+ <uni-icons type="arrowright" size="16" color="#999"></uni-icons>
+ </view>
+ </picker>
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">鎵ц浠诲姟浜哄憳</view>
+ <view class="staff-list">
+ <view class="staff-item">
+ <text>{{ currentUser.name }} ({{ currentUser.position }})</text>
+ <uni-icons type="checkmarkempty" size="20" color="#007AFF"></uni-icons>
+ </view>
+ <view
+ class="staff-item"
+ v-for="(staff, index) in additionalStaff"
+ :key="index"
+ @click="removeStaff(index)"
+ >
+ <text>{{ staff.name }} ({{ staff.position }})</text>
+ <uni-icons type="closeempty" size="20" color="#ff4d4f"></uni-icons>
+ </view>
+ <view class="add-staff" @click="addStaff">
+ <uni-icons type="plusempty" size="20" color="#007AFF"></uni-icons>
+ <text>娣诲姞浜哄憳</text>
+ </view>
+ </view>
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">褰掑睘鏈烘瀯</view>
+ <picker mode="selector" :range="organizations" @change="onOrganizationChange">
+ <view class="form-input picker-input">
+ {{ selectedOrganization || '璇烽�夋嫨褰掑睘鏈烘瀯' }}
+ <uni-icons type="arrowright" size="16" color="#999"></uni-icons>
+ </view>
+ </picker>
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">鏈嶅姟鏃堕棿</view>
+ <!-- 浣跨敤uni-datetime-picker缁勪欢 -->
+ <uni-datetime-picker
+ v-model="taskForm.serviceTime"
+ type="datetime"
+ :placeholder="'璇烽�夋嫨鏈嶅姟鏃堕棿'"
+ class="form-input"
+ />
+ </view>
+
+ <view class="form-section-title">涔樺淇℃伅</view>
+ <view class="form-item">
+ <view class="form-label">鑱旂郴浜�</view>
+ <input
+ class="form-input"
+ placeholder="璇疯緭鍏ヨ仈绯讳汉"
+ v-model="taskForm.passenger.contact"
+ />
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">鑱旂郴鐢佃瘽</view>
+ <input
+ class="form-input"
+ type="number"
+ placeholder="璇疯緭鍏ヨ仈绯荤數璇�"
+ v-model="taskForm.passenger.phone"
+ />
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">鍑哄彂鍦板潃</view>
+ <view class="form-input picker-input" @click="selectStartAddress">
+ {{ taskForm.startAddress || '璇烽�夋嫨鍑哄彂鍦板潃' }}
+ <uni-icons type="arrowright" size="16" color="#999"></uni-icons>
+ </view>
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">鐩殑鍦板潃</view>
+ <view class="form-input picker-input" @click="selectEndAddress">
+ {{ taskForm.endAddress || '璇烽�夋嫨鐩殑鍦板潃' }}
+ <uni-icons type="arrowright" size="16" color="#999"></uni-icons>
+ </view>
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">鍏噷鏁�</view>
+ <input
+ class="form-input"
+ type="digit"
+ placeholder="璇疯緭鍏ュ叕閲屾暟"
+ v-model="taskForm.distance"
+ />
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">鎴愪氦浠�</view>
+ <input
+ class="form-input"
+ type="digit"
+ placeholder="璇疯緭鍏ユ垚浜や环"
+ v-model="taskForm.price"
+ />
+ </view>
+ </view>
+
+ <view class="form-actions">
+ <button class="submit-btn" @click="submitTask">淇濆瓨</button>
+ </view>
+ </view>
+ </view>
+ </scroll-view>
+</template>
+
+<script>
+ import { mapState } from 'vuex'
+ import uniDatetimePicker from '@/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue'
+
+ export default {
+ components: {
+ uniDatetimePicker
+ },
+ data() {
+ return {
+ selectedTaskCategory: null,
+ selectedVehicle: '',
+ selectedOrganization: '',
+ selectedEmergencyTaskType: '',
+ taskForm: {
+ description: '',
+ startLocation: '',
+ endLocation: '',
+ distance: '',
+ startTime: '',
+ endTime: '',
+ remark: '',
+ transferTime: '',
+ patient: {
+ contact: '',
+ phone: '',
+ name: '',
+ gender: 'male',
+ idCard: '',
+ condition: ''
+ },
+ hospitalOut: {
+ name: '',
+ department: '',
+ bedNumber: '',
+ address: ''
+ },
+ hospitalIn: {
+ name: '',
+ department: '',
+ bedNumber: '',
+ address: ''
+ },
+ transferDistance: '',
+ price: '',
+ serviceTime: '',
+ passenger: {
+ contact: '',
+ phone: ''
+ },
+ startAddress: '',
+ endAddress: ''
+ },
+ taskCategories: [
+ {
+ type: 'normal',
+ name: '缁翠慨淇濆吇',
+ icon: 'repair',
+ color: '#007AFF',
+ description: '璁惧缁翠慨銆佷繚鍏荤瓑鏃ュ父浠诲姟'
+ },
+ {
+ type: 'normal',
+ name: '鍔犳补',
+ icon: 'fuel',
+ color: '#1AAD19',
+ description: '杞﹁締鍔犳补绛変换鍔�'
+ },
+ {
+ type: 'emergency',
+ name: '鎬ユ晳杞繍',
+ icon: 'hospital',
+ color: '#E54D42',
+ description: '绱ф�ュ尰鐤楄浆杩愪换鍔�'
+ },
+ {
+ type: 'welfare',
+ name: '绂忕杞�',
+ icon: 'car',
+ color: '#F37B1D',
+ description: '鑰佸勾浜恒�佹畫鐤句汉绛夌壒娈婄兢浣撶敤杞︽湇鍔�'
+ }
+ ],
+ vehicles: ['绮12345', '绮67890', '绮11111', '绮22222', '绮33333'],
+ organizations: ['骞垮窞鍒嗗叕鍙�', '娣卞湷鍒嗗叕鍙�', '鐝犳捣鍒嗗叕鍙�', '浣涘北鍒嗗叕鍙�'],
+ emergencyTaskTypes: ['鎬ユ晳杞繍', '鑸┖杞繍'],
+ additionalStaff: []
+ }
+ },
+ computed: {
+ ...mapState({
+ currentUser: state => ({
+ name: state.user.name || '寮犱笁',
+ position: '鍙告満'
+ })
+ })
+ },
+ methods: {
+ selectTaskCategory(category) {
+ this.selectedTaskCategory = category
+ },
+
+ backToCategory() {
+ this.selectedTaskCategory = null
+ },
+
+ onVehicleChange(e) {
+ this.selectedVehicle = this.vehicles[e.detail.value]
+ },
+
+ onOrganizationChange(e) {
+ this.selectedOrganization = this.organizations[e.detail.value]
+ },
+
+ onEmergencyTaskTypeChange(e) {
+ this.selectedEmergencyTaskType = this.emergencyTaskTypes[e.detail.value]
+ },
+
+ selectStartLocation() {
+ this.$modal.showToast('閫夋嫨鍑哄彂鍦板姛鑳藉紑鍙戜腑')
+ },
+
+ selectEndLocation() {
+ this.$modal.showToast('閫夋嫨鐩殑鍦板姛鑳藉紑鍙戜腑')
+ },
+
+ selectHospitalOutAddress() {
+ this.$modal.showToast('閫夋嫨杞嚭鍖婚櫌鍦板潃鍔熻兘寮�鍙戜腑')
+ },
+
+ selectHospitalInAddress() {
+ this.$modal.showToast('閫夋嫨杞叆鍖婚櫌鍦板潃鍔熻兘寮�鍙戜腑')
+ },
+
+ selectStartAddress() {
+ this.$modal.showToast('閫夋嫨鍑哄彂鍦板潃鍔熻兘寮�鍙戜腑')
+ },
+
+ selectEndAddress() {
+ this.$modal.showToast('閫夋嫨鐩殑鍦板潃鍔熻兘寮�鍙戜腑')
+ },
+
+ addStaff() {
+ this.$modal.showToast('娣诲姞浜哄憳鍔熻兘寮�鍙戜腑')
+ },
+
+ removeStaff(index) {
+ this.additionalStaff.splice(index, 1)
+ },
+
+ submitTask() {
+ this.$modal.confirm('纭畾瑕佷繚瀛樹换鍔″悧锛�').then(() => {
+ this.$modal.showToast('浠诲姟淇濆瓨鎴愬姛')
+ // 杩欓噷鍙互璋冪敤API淇濆瓨浠诲姟
+ // 淇濆瓨鎴愬姛鍚庤烦杞埌浠诲姟鍒楄〃
+ this.$tab.navigateTo('/pages/task/index')
+ }).catch(() => {
+ // 鍙栨秷鎿嶄綔
+ })
+ }
+ }
+ }
+</script>
+
+<style lang="scss">
+ .create-task-container {
+ padding: 20rpx;
+ background-color: #f5f5f5;
+ min-height: 100vh;
+ // 闅愯棌婊氬姩鏉′絾淇濇寔婊氬姩鍔熻兘
+ ::-webkit-scrollbar {
+ display: none;
+ width: 0 !important;
+ height: 0 !important;
+ background: transparent;
+ }
+
+ // Firefox婊氬姩鏉¢殣钘�
+ * {
+ scrollbar-width: none; /* Firefox */
+ }
+
+ // IE/Edge婊氬姩鏉¢殣钘�
+ * {
+ -ms-overflow-style: none; /* IE 10+ */
+ }
+
+ .task-category-container {
+ .header {
+ text-align: center;
+ padding: 40rpx 0;
+
+ .title {
+ font-size: 40rpx;
+ font-weight: bold;
+ color: #333;
+ margin-bottom: 20rpx;
+ }
+
+ .subtitle {
+ font-size: 28rpx;
+ color: #666;
+ }
+ }
+
+ .category-list {
+ .category-item {
+ display: flex;
+ align-items: center;
+ background-color: white;
+ border-radius: 15rpx;
+ padding: 30rpx;
+ margin-bottom: 20rpx;
+ box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+
+ .icon {
+ margin-right: 20rpx;
+ }
+
+ .info {
+ flex: 1;
+
+ .name {
+ font-size: 32rpx;
+ font-weight: bold;
+ margin-bottom: 10rpx;
+ }
+
+ .desc {
+ font-size: 26rpx;
+ color: #666;
+ }
+ }
+
+ .arrow {
+ margin-left: 20rpx;
+ }
+ }
+ }
+ }
+
+ .task-form-container {
+ .form-header {
+ display: flex;
+ align-items: center;
+ padding: 20rpx 0;
+ margin-bottom: 30rpx;
+
+ .back-btn {
+ width: 60rpx;
+ height: 60rpx;
+ border-radius: 50%;
+ background-color: #f0f0f0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-right: 20rpx;
+ }
+
+ .title {
+ font-size: 36rpx;
+ font-weight: bold;
+ color: #333;
+ }
+ }
+
+ .form-section {
+ background-color: white;
+ border-radius: 15rpx;
+ padding: 30rpx;
+ box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+
+ .form-section-title {
+ font-size: 32rpx;
+ font-weight: bold;
+ margin: 40rpx 0 20rpx 0;
+ padding-bottom: 10rpx;
+ border-bottom: 1rpx solid #f0f0f0;
+ }
+
+ .form-item {
+ margin-bottom: 40rpx;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+
+ .form-label {
+ font-size: 28rpx;
+ margin-bottom: 15rpx;
+ color: #333;
+ }
+
+ .form-input {
+ height: 70rpx;
+ padding: 0 20rpx;
+ border: 1rpx solid #eee;
+ border-radius: 10rpx;
+ font-size: 28rpx;
+
+ &.picker-input {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ }
+
+ &[disabled] {
+ background-color: #f5f5f5;
+ color: #999;
+ }
+ }
+
+ .form-textarea {
+ width: 100%;
+ min-height: 150rpx;
+ padding: 20rpx;
+ border: 1rpx solid #eee;
+ border-radius: 10rpx;
+ font-size: 28rpx;
+ resize: none;
+ }
+
+ .radio-group {
+ display: flex;
+
+ .radio-item {
+ display: flex;
+ align-items: center;
+ margin-right: 30rpx;
+
+ radio {
+ margin-right: 10rpx;
+ }
+ }
+ }
+
+ .staff-list {
+ .staff-item {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 20rpx;
+ background-color: #f9f9f9;
+ border-radius: 10rpx;
+ margin-bottom: 20rpx;
+ }
+
+ .add-staff {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 20rpx;
+ border: 1rpx dashed #007AFF;
+ border-radius: 10rpx;
+ color: #007AFF;
+ }
+ }
+ }
+
+ .form-actions {
+ margin-top: 50rpx;
+ text-align: center;
+
+ .submit-btn {
+ width: 80%;
+ height: 80rpx;
+ background-color: #007AFF;
+ color: white;
+ border-radius: 10rpx;
+ font-size: 32rpx;
+ }
+ }
+ }
+ }
+ }
+</style>
\ No newline at end of file
diff --git a/app/pages/task/detail.vue b/app/pages/task/detail.vue
new file mode 100644
index 0000000..e23ecff
--- /dev/null
+++ b/app/pages/task/detail.vue
@@ -0,0 +1,600 @@
+<template>
+ <view class="task-detail-container">
+ <view class="task-header">
+ <text class="task-title">{{ task.title }}</text>
+ <view class="task-status" :class="'status-' + task.status">
+ {{ getStatusText(task.status) }}
+ </view>
+ </view>
+
+ <!-- 鏅�氫换鍔¤鎯� -->
+ <view class="task-info-section" v-if="isNormalTask">
+ <view class="info-item">
+ <view class="label">浠诲姟缂栧彿:</view>
+ <view class="value">{{ task.taskNo }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">浠诲姟绫诲瀷:</view>
+ <view class="value">{{ getTaskTypeText(task.type) }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">杞﹁締淇℃伅:</view>
+ <view class="value">{{ task.vehicle }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">鍑哄彂鍦�:</view>
+ <view class="value">{{ task.startLocation }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">鐩殑鍦�:</view>
+ <view class="value">{{ task.endLocation }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">鍑哄彂鏃堕棿:</view>
+ <view class="value">{{ task.startTime }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">鎵ц浜哄憳:</view>
+ <view class="value">{{ task.assignee }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">浠诲姟鎻忚堪:</view>
+ <view class="value">{{ task.description || '鏃犳弿杩颁俊鎭�' }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">琛岄┒鍏噷鏁�:</view>
+ <view class="value">{{ task.distance || '鏈~鍐�' }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">缁撴潫鏃堕棿:</view>
+ <view class="value">{{ task.endTime || '鏈~鍐�' }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">澶囨敞:</view>
+ <view class="value">{{ task.remark || '鏃犲娉�' }}</view>
+ </view>
+ </view>
+
+ <!-- 鎬ユ晳杞繍浠诲姟璇︽儏 -->
+ <view class="task-info-section" v-else-if="task.type === 'emergency'">
+ <view class="info-item">
+ <view class="label">浠诲姟缂栧彿:</view>
+ <view class="value">{{ task.taskNo }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">浠诲姟绫诲瀷:</view>
+ <view class="value">{{ getTaskTypeText(task.type) }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">杞﹁締淇℃伅:</view>
+ <view class="value">{{ task.vehicle }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">鎵ц浜哄憳:</view>
+ <view class="value">{{ task.assignee }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">褰掑睘鏈烘瀯:</view>
+ <view class="value">{{ task.organization || '鏈~鍐�' }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">浠诲姟绫诲瀷:</view>
+ <view class="value">{{ task.emergencyTaskType || '鏈~鍐�' }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">杞繍鏃堕棿:</view>
+ <view class="value">{{ task.transferTime || '鏈~鍐�' }}</view>
+ </view>
+
+ <view class="section-title">鎮h�呬俊鎭�</view>
+ <view class="info-item">
+ <view class="label">鑱旂郴浜�:</view>
+ <view class="value">{{ task.patient.contact || '鏈~鍐�' }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">鑱旂郴鐢佃瘽:</view>
+ <view class="value">{{ task.patient.phone || '鏈~鍐�' }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">鎮h�呭鍚�:</view>
+ <view class="value">{{ task.patient.name || '鏈~鍐�' }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">鎬у埆:</view>
+ <view class="value">{{ task.patient.gender === 'male' ? '鐢�' : '濂�' }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">韬唤璇�:</view>
+ <view class="value">{{ task.patient.idCard || '鏈~鍐�' }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">鐥呮儏:</view>
+ <view class="value">{{ task.patient.condition || '鏈~鍐�' }}</view>
+ </view>
+
+ <view class="section-title">杞嚭鍖婚櫌淇℃伅</view>
+ <view class="info-item">
+ <view class="label">鍖婚櫌鍚嶇О:</view>
+ <view class="value">{{ task.hospitalOut.name || '鏈~鍐�' }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">绉戝:</view>
+ <view class="value">{{ task.hospitalOut.department || '鏈~鍐�' }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">搴婂彿:</view>
+ <view class="value">{{ task.hospitalOut.bedNumber || '鏈~鍐�' }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">鍦板潃:</view>
+ <view class="value">{{ task.hospitalOut.address || '鏈~鍐�' }}</view>
+ </view>
+
+ <view class="section-title">杞叆鍖婚櫌淇℃伅</view>
+ <view class="info-item">
+ <view class="label">鍖婚櫌鍚嶇О:</view>
+ <view class="value">{{ task.hospitalIn.name || '鏈~鍐�' }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">绉戝:</view>
+ <view class="value">{{ task.hospitalIn.department || '鏈~鍐�' }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">搴婂彿:</view>
+ <view class="value">{{ task.hospitalIn.bedNumber || '鏈~鍐�' }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">鍦板潃:</view>
+ <view class="value">{{ task.hospitalIn.address || '鏈~鍐�' }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">杞繍鍏噷鏁�:</view>
+ <view class="value">{{ task.transferDistance || '鏈~鍐�' }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">鎴愪氦浠�:</view>
+ <view class="value">楼{{ task.price || '鏈~鍐�' }}</view>
+ </view>
+ </view>
+
+ <!-- 绂忕杞︿换鍔¤鎯� -->
+ <view class="task-info-section" v-else-if="task.type === 'welfare'">
+ <view class="info-item">
+ <view class="label">浠诲姟缂栧彿:</view>
+ <view class="value">{{ task.taskNo }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">浠诲姟绫诲瀷:</view>
+ <view class="value">{{ getTaskTypeText(task.type) }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">杞﹁締淇℃伅:</view>
+ <view class="value">{{ task.vehicle }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">鎵ц浜哄憳:</view>
+ <view class="value">{{ task.assignee }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">褰掑睘鏈烘瀯:</view>
+ <view class="value">{{ task.organization || '鏈~鍐�' }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">鏈嶅姟鏃堕棿:</view>
+ <view class="value">{{ task.serviceTime || '鏈~鍐�' }}</view>
+ </view>
+
+ <view class="section-title">涔樺淇℃伅</view>
+ <view class="info-item">
+ <view class="label">鑱旂郴浜�:</view>
+ <view class="value">{{ task.passenger.contact || '鏈~鍐�' }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">鑱旂郴鐢佃瘽:</view>
+ <view class="value">{{ task.passenger.phone || '鏈~鍐�' }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">鍑哄彂鍦板潃:</view>
+ <view class="value">{{ task.startAddress || '鏈~鍐�' }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">鐩殑鍦板潃:</view>
+ <view class="value">{{ task.endAddress || '鏈~鍐�' }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">鍏噷鏁�:</view>
+ <view class="value">{{ task.distance || '鏈~鍐�' }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">鎴愪氦浠�:</view>
+ <view class="value">楼{{ task.price || '鏈~鍐�' }}</view>
+ </view>
+ </view>
+
+ <!-- 浠诲姟鎿嶄綔鎸夐挳 (浠诲姟鏈畬鎴愭椂鏄剧ず) -->
+ <view class="task-actions" v-if="task.status !== 'completed'">
+ <button
+ class="action-btn"
+ :class="{ disabled: isActionDisabled('depart') }"
+ @click="handleTaskAction('depart')"
+ >
+ 鍑哄彂
+ </button>
+ <button
+ class="action-btn"
+ :class="{ disabled: isActionDisabled('arrive') }"
+ @click="handleTaskAction('arrive')"
+ >
+ 宸插埌杈�
+ </button>
+ <button
+ class="action-btn"
+ :class="{ disabled: isActionDisabled('return') }"
+ @click="handleTaskAction('return')"
+ >
+ 杩旂▼
+ </button>
+ <button
+ class="action-btn"
+ :class="{ disabled: isActionDisabled('settle') }"
+ @click="handleTaskAction('settle')"
+ >
+ 缁撶畻
+ </button>
+ <button
+ class="action-btn primary"
+ :class="{ disabled: isActionDisabled('complete') }"
+ @click="handleTaskAction('complete')"
+ >
+ 宸插畬鎴�
+ </button>
+ </view>
+
+ <view class="action-section">
+ <button class="back-btn" @click="goBack">杩斿洖</button>
+ </view>
+ </view>
+</template>
+
+<script>
+ export default {
+ data() {
+ return {
+ task: {
+ id: 1,
+ title: '绱ф�ョ淮淇换鍔�',
+ type: 'maintenance',
+ startLocation: '骞垮窞甯傚ぉ娌冲尯XX璺�123鍙�',
+ endLocation: '骞垮窞甯傜櫧浜戝尯YY璺�456鍙�',
+ startTime: '2023-05-15 15:00',
+ assignee: '寮犱笁',
+ status: 'pending',
+ vehicle: '绮12345',
+ taskNo: 'RW20230515001',
+ description: '璁惧鏁呴殰锛岄渶瑕佺揣鎬ョ淮淇�',
+ // 鏅�氫换鍔″瓧娈�
+ distance: '25',
+ endTime: '2023-05-15 17:00',
+ remark: '缁翠慨瀹屾垚鍚庨渶瑕佹祴璇�',
+ // 鎬ユ晳杞繍浠诲姟瀛楁
+ organization: '骞垮窞鎬ユ晳涓績',
+ emergencyTaskType: '鎬ユ晳杞繍',
+ transferTime: '2023-05-15 16:00',
+ patient: {
+ contact: '鏉庡洓',
+ phone: '13800138000',
+ name: '鐜嬩簲',
+ gender: 'male',
+ idCard: '440100198001011234',
+ condition: '绐佸彂蹇冭剰鐥�'
+ },
+ hospitalOut: {
+ name: '骞垮窞甯傜涓�浜烘皯鍖婚櫌',
+ department: '蹇冨唴绉�',
+ bedNumber: '101',
+ address: '骞垮窞甯傝秺绉�鍖哄尰闄㈣矾1鍙�'
+ },
+ hospitalIn: {
+ name: '骞夸笢鐪佷汉姘戝尰闄�',
+ department: '蹇冨唴绉�',
+ bedNumber: '205',
+ address: '骞垮窞甯傚ぉ娌冲尯鍖婚櫌璺�2鍙�'
+ },
+ transferDistance: '15',
+ price: '800',
+ // 绂忕杞︿换鍔″瓧娈�
+ serviceTime: '2023-05-16 09:00',
+ passenger: {
+ contact: '璧靛叚',
+ phone: '13900139000'
+ },
+ startAddress: '骞垮窞甯傝崝婀惧尯绀惧尯璺�10鍙�',
+ endAddress: '骞垮窞甯傚ぉ娌冲尯鍏昏�侀櫌璺�20鍙�'
+ }
+ }
+ },
+ computed: {
+ // 鍒ゆ柇鏄惁涓烘櫘閫氫换鍔�
+ isNormalTask() {
+ return this.task.type === 'maintenance' || this.task.type === 'refuel' || this.task.type === 'inspection';
+ }
+ },
+ onLoad(options) {
+ // 瀹為檯椤圭洰涓繖閲屼細閫氳繃API鑾峰彇浠诲姟璇︽儏
+ // const taskId = options.id;
+ // this.getTaskDetail(taskId);
+ },
+ methods: {
+ goBack() {
+ this.$tab.navigateBack();
+ },
+
+ getStatusText(status) {
+ const statusMap = {
+ 'pending': '寰呭鐞�',
+ 'processing': '澶勭悊涓�',
+ 'completed': '宸插畬鎴�'
+ }
+ return statusMap[status] || '鏈煡'
+ },
+
+ getTaskTypeText(type) {
+ const typeMap = {
+ 'maintenance': '缁翠慨淇濆吇',
+ 'refuel': '鍔犳补',
+ 'inspection': '宸℃',
+ 'emergency': '鎬ユ晳杞繍',
+ 'welfare': '绂忕杞�'
+ }
+ return typeMap[type] || '鏈煡绫诲瀷'
+ },
+
+ // 鍒ゆ柇鎿嶄綔鎸夐挳鏄惁绂佺敤
+ isActionDisabled(action) {
+ // 鏍规嵁浠诲姟鐘舵�佸拰鎿嶄綔绫诲瀷鍒ゆ柇鏄惁绂佺敤
+ switch (action) {
+ case 'depart':
+ return this.task.status !== 'pending';
+ case 'arrive':
+ return this.task.status !== 'processing';
+ case 'return':
+ return this.task.status !== 'processing';
+ case 'settle':
+ return this.task.status !== 'processing';
+ case 'complete':
+ return this.task.status !== 'processing';
+ default:
+ return false;
+ }
+ },
+
+ // 澶勭悊浠诲姟鎿嶄綔
+ handleTaskAction(action) {
+ if (this.isActionDisabled(action)) {
+ return;
+ }
+
+ switch (action) {
+ case 'depart':
+ // 鍑哄彂鎿嶄綔锛屾牴鎹换鍔$被鍨嬫樉绀轰笉鍚岀殑纭淇℃伅
+ let departMessage = '纭畾瑕佹爣璁颁负宸插嚭鍙戝悧锛�';
+ if (this.task.type !== 'maintenance' && this.task.type !== 'refuel' && this.task.type !== 'inspection') {
+ departMessage = '鍙戝嚭鍘荤洰鐨勫湴,纭锛�';
+ }
+ this.$modal.confirm(departMessage).then(() => {
+ this.task.status = 'processing';
+ this.$modal.showToast('宸插嚭鍙�');
+ // 杩欓噷鍙互璋冪敤API鏇存柊浠诲姟鐘舵��
+ }).catch(() => {});
+ break;
+ case 'arrive':
+ // 宸插埌杈炬搷浣�
+ this.$modal.confirm('宸茬粡鍒拌揪鐩殑鍦帮紝纭锛�').then(() => {
+ this.$modal.showToast('宸插埌杈�');
+ // 杩欓噷鍙互璋冪敤API鏇存柊浠诲姟鐘舵��
+ }).catch(() => {});
+ break;
+ case 'return':
+ // 杩旂▼鎿嶄綔
+ this.$modal.confirm('鐜板湪宸茬粡杩旂▼涓紝纭锛�').then(() => {
+ this.$modal.showToast('杩旂▼涓�');
+ // 杩欓噷鍙互璋冪敤API鏇存柊浠诲姟鐘舵��
+ }).catch(() => {});
+ break;
+ case 'settle':
+ // 缁撶畻鎿嶄綔锛岃烦杞埌缁撶畻椤甸潰
+ this.$tab.navigateTo(`/pages/task/settlement?id=${this.task.id}`);
+ break;
+ case 'complete':
+ // 宸插畬鎴愭搷浣�
+ this.$modal.confirm('浠诲姟鏄惁宸茬粡鍏ㄩ儴瀹屾垚锛岀‘璁わ紵').then(() => {
+ this.task.status = 'completed';
+ this.$modal.showToast('浠诲姟宸插畬鎴�');
+ // 杩欓噷鍙互璋冪敤API鏇存柊浠诲姟鐘舵��
+ }).catch(() => {});
+ break;
+ }
+ },
+
+ // 妯℃嫙鑾峰彇浠诲姟璇︽儏
+ getTaskDetail(taskId) {
+ // 杩欓噷搴旇璋冪敤API鑾峰彇浠诲姟璇︽儏
+ // 鏆傛椂浣跨敤妯℃嫙鏁版嵁
+ }
+ }
+ }
+</script>
+
+<style lang="scss">
+ .task-detail-container {
+ padding: 20rpx;
+ background-color: #f5f5f5;
+ min-height: 100vh;
+ }
+
+ .task-header {
+ background-color: white;
+ border-radius: 15rpx;
+ padding: 30rpx;
+ margin-bottom: 20rpx;
+ box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+
+ .task-title {
+ font-size: 36rpx;
+ font-weight: bold;
+ color: #333;
+ }
+
+ .task-status {
+ padding: 10rpx 20rpx;
+ border-radius: 10rpx;
+ font-size: 24rpx;
+ font-weight: bold;
+
+ &.status-pending {
+ background-color: #fff3cd;
+ color: #856404;
+ }
+
+ &.status-processing {
+ background-color: #cce5ff;
+ color: #004085;
+ }
+
+ &.status-completed {
+ background-color: #d4edda;
+ color: #155724;
+ }
+ }
+ }
+
+ .task-info-section {
+ background-color: white;
+ border-radius: 15rpx;
+ padding: 30rpx;
+ margin-bottom: 20rpx;
+ box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+
+ .section-title {
+ font-size: 32rpx;
+ font-weight: bold;
+ margin: 30rpx 0 20rpx 0;
+ padding-bottom: 10rpx;
+ border-bottom: 1rpx solid #f0f0f0;
+ color: #333;
+ }
+
+ .info-item {
+ display: flex;
+ margin-bottom: 20rpx;
+ padding-bottom: 20rpx;
+ border-bottom: 1rpx solid #f0f0f0;
+
+ &:last-child {
+ margin-bottom: 0;
+ padding-bottom: 0;
+ border-bottom: none;
+ }
+
+ .label {
+ font-size: 28rpx;
+ color: #666;
+ margin-right: 20rpx;
+ white-space: nowrap;
+ width: 150rpx;
+ }
+
+ .value {
+ font-size: 28rpx;
+ flex: 1;
+ word-break: break-all;
+ }
+ }
+ }
+
+ .task-actions {
+ display: flex;
+ flex-wrap: wrap;
+ background-color: white;
+ border-radius: 15rpx;
+ padding: 30rpx;
+ margin-bottom: 20rpx;
+ box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+
+ .action-btn {
+ flex: 1;
+ min-width: 30%;
+ height: 70rpx;
+ border-radius: 10rpx;
+ font-size: 26rpx;
+ margin: 10rpx 5rpx;
+ background-color: #f0f0f0;
+ color: #333;
+
+ &.primary {
+ background-color: #007AFF;
+ color: white;
+ }
+
+ &.disabled {
+ opacity: 0.5;
+ }
+ }
+ }
+
+ .action-section {
+ margin-top: 40rpx;
+ text-align: center;
+
+ .back-btn {
+ width: 80%;
+ height: 80rpx;
+ background-color: #007AFF;
+ color: white;
+ border-radius: 10rpx;
+ font-size: 32rpx;
+ }
+ }
+</style>
\ No newline at end of file
diff --git a/app/pages/task/index.vue b/app/pages/task/index.vue
new file mode 100644
index 0000000..ff9746c
--- /dev/null
+++ b/app/pages/task/index.vue
@@ -0,0 +1,798 @@
+<template>
+ <view class="task-container">
+ <!-- 浠诲姟鍒楄〃澶撮儴 -->
+ <view class="task-list-section">
+ <view class="task-header">
+ <view class="header-title">浠诲姟鍒楄〃</view>
+ <view class="header-actions">
+ <button class="search-toggle-btn" @click="toggleSearch">
+ <uni-icons :type="showSearch ? 'close' : 'search'" size="20"></uni-icons>
+ </button>
+ <button class="refresh-btn" @click="refreshList">
+ <uni-icons type="refresh" size="20"></uni-icons>
+ </button>
+ </view>
+ </view>
+
+ <!-- 鏌ヨ鏉′欢鍖哄煙 -->
+ <view class="search-section" v-show="showSearch">
+ <view class="search-form">
+ <view class="form-item">
+ <view class="form-label">浠诲姟鐘舵��</view>
+ <picker mode="selector" :range="statusOptions" @change="onStatusChange">
+ <view class="form-input picker-input">
+ {{ selectedStatusText || '鍏ㄩ儴鐘舵��' }}
+ <uni-icons type="arrowright" size="16" color="#999"></uni-icons>
+ </view>
+ </picker>
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">浠诲姟鏃堕棿</view>
+ <view class="date-range">
+ <!-- 浣跨敤uni-datetime-picker缁勪欢 -->
+ <uni-datetime-picker
+ v-model="startDate"
+ type="date"
+ :placeholder="'寮�濮嬫椂闂�'"
+ class="date-input"
+ />
+ <text class="divider">鑷�</text>
+ <!-- 浣跨敤uni-datetime-picker缁勪欢 -->
+ <uni-datetime-picker
+ v-model="endDate"
+ type="date"
+ :placeholder="'缁撴潫鏃堕棿'"
+ class="date-input"
+ />
+ </view>
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">杞︾墝鍙�</view>
+ <input
+ class="form-input"
+ placeholder="璇疯緭鍏ヨ溅鐗屽彿"
+ v-model="searchForm.vehicle"
+ />
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">浠诲姟缂栧彿</view>
+ <input
+ class="form-input"
+ placeholder="璇疯緭鍏ヤ换鍔$紪鍙�"
+ v-model="searchForm.taskNo"
+ />
+ </view>
+
+ <view class="form-actions">
+ <button class="search-btn" @click="handleSearch">鏌ヨ</button>
+ <button class="reset-btn" @click="resetSearch">閲嶇疆</button>
+ </view>
+ </view>
+ </view>
+
+ <view class="task-filter">
+ <scroll-view class="filter-tabs" scroll-x="true">
+ <view
+ class="filter-item"
+ :class="{ active: currentFilter === 'all' }"
+ @click="changeFilter('all')"
+ >
+ 鍏ㄩ儴
+ </view>
+ <view
+ class="filter-item"
+ :class="{ active: currentFilter === 'pending' }"
+ @click="changeFilter('pending')"
+ >
+ 寰呭鐞�
+ </view>
+ <view
+ class="filter-item"
+ :class="{ active: currentFilter === 'processing' }"
+ @click="changeFilter('processing')"
+ >
+ 澶勭悊涓�
+ </view>
+ <view
+ class="filter-item"
+ :class="{ active: currentFilter === 'completed' }"
+ @click="changeFilter('completed')"
+ >
+ 宸插畬鎴�
+ </view>
+ </scroll-view>
+ </view>
+
+ <scroll-view class="task-list-scroll" scroll-y="true">
+ <view class="task-list">
+ <view class="task-item" v-for="task in filteredTaskList" :key="task.id">
+ <view class="task-main" @click="viewTaskDetail(task)">
+ <view class="task-title">{{ getTaskTypeText(task.type) }} - {{ task.vehicle }}</view>
+ <view class="task-info">
+ <view class="info-row">
+ <view class="info-item">
+ <view class="label">浠诲姟缂栧彿:</view>
+ <view class="value">{{ task.taskNo }}</view>
+ </view>
+ <view class="info-item">
+ <view class="label">浠诲姟鐘舵��:</view>
+ <view class="value">{{ getStatusText(task.status) }}</view>
+ </view>
+ </view>
+ <view class="info-row">
+ <view class="info-item">
+ <view class="label">鍑哄彂鍦�:</view>
+ <view class="value">{{ task.startLocation }}</view>
+ </view>
+ <view class="info-item">
+ <view class="label">鐩殑鍦�:</view>
+ <view class="value">{{ task.endLocation }}</view>
+ </view>
+ </view>
+ <view class="info-row">
+ <view class="info-item">
+ <view class="label">鍑哄彂鏃堕棿:</view>
+ <view class="value">{{ task.startTime }}</view>
+ </view>
+ <view class="info-item">
+ <view class="label">鎵ц浜哄憳:</view>
+ <view class="value">{{ task.assignee }}</view>
+ </view>
+ </view>
+ </view>
+ </view>
+
+ <!-- 鎿嶄綔鎸夐挳 -->
+ <view class="task-actions">
+ <button
+ class="action-btn"
+ :class="{ disabled: isActionDisabled(task, 'depart') }"
+ @click="handleTaskAction(task, 'depart')"
+ v-if="task.status !== 'completed'"
+ >
+ 鍑哄彂
+ </button>
+ <button
+ class="action-btn"
+ :class="{ disabled: isActionDisabled(task, 'arrive') }"
+ @click="handleTaskAction(task, 'arrive')"
+ v-if="task.status !== 'completed'"
+ >
+ 宸插埌杈�
+ </button>
+ <button
+ class="action-btn"
+ :class="{ disabled: isActionDisabled(task, 'return') }"
+ @click="handleTaskAction(task, 'return')"
+ v-if="task.status !== 'completed'"
+ >
+ 杩旂▼
+ </button>
+ <button
+ class="action-btn"
+ :class="{ disabled: isActionDisabled(task, 'settle') }"
+ @click="handleTaskAction(task, 'settle')"
+ v-if="task.status !== 'completed'"
+ >
+ 缁撶畻
+ </button>
+ <button
+ class="action-btn primary"
+ :class="{ disabled: isActionDisabled(task, 'complete') }"
+ @click="handleTaskAction(task, 'complete')"
+ v-if="task.status !== 'completed'"
+ >
+ 宸插畬鎴�
+ </button>
+ </view>
+ </view>
+
+ <view class="no-data" v-if="filteredTaskList.length === 0">
+ <uni-icons type="info" size="40" color="#ccc"></uni-icons>
+ <text>鏆傛棤浠诲姟鏁版嵁</text>
+ </view>
+ </view>
+ </scroll-view>
+ </view>
+ </view>
+</template>
+
+<script>
+ import uniDatetimePicker from '@/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue'
+
+ export default {
+ components: {
+ uniDatetimePicker
+ },
+ data() {
+ return {
+ // 鎺у埗鏌ヨ鐣岄潰鏄剧ず/闅愯棌
+ showSearch: false,
+
+ // 鏌ヨ鏉′欢
+ searchForm: {
+ vehicle: '',
+ taskNo: ''
+ },
+ statusOptions: ['鍏ㄩ儴鐘舵��', '寰呭鐞�', '澶勭悊涓�', '宸插畬鎴�'],
+ statusValues: ['', 'pending', 'processing', 'completed'],
+ selectedStatus: '',
+ selectedStatusText: '',
+ startDate: '',
+ endDate: '',
+ currentFilter: 'all',
+
+ // 浠诲姟鍒楄〃
+ taskList: [
+ {
+ id: 1,
+ title: '绱ф�ョ淮淇换鍔�',
+ type: 'maintenance', // 缁翠慨淇濆吇
+ startLocation: '骞垮窞甯傚ぉ娌冲尯XX璺�123鍙�',
+ endLocation: '骞垮窞甯傜櫧浜戝尯YY璺�456鍙�',
+ startTime: '2023-05-15 15:00',
+ assignee: '寮犱笁',
+ status: 'pending',
+ vehicle: '绮12345',
+ taskNo: 'RW20230515001'
+ },
+ {
+ id: 2,
+ title: '瀹氭湡淇濆吇浠诲姟',
+ type: 'maintenance', // 缁翠慨淇濆吇
+ startLocation: '娣卞湷甯傚崡灞卞尯XX璺�789鍙�',
+ endLocation: '娣卞湷甯傜鐢板尯YY璺�999鍙�',
+ startTime: '2023-05-14 10:00',
+ assignee: '鏉庡洓',
+ status: 'processing',
+ vehicle: '绮67890',
+ taskNo: 'RW20230514002'
+ },
+ {
+ id: 3,
+ title: '璁惧宸℃浠诲姟',
+ type: 'inspection', // 宸℃浠诲姟
+ startLocation: '鐝犳捣甯傞娲插尯XX璺�321鍙�',
+ endLocation: '鐝犳捣甯傞噾婀惧尯YY璺�654鍙�',
+ startTime: '2023-05-13 17:00',
+ assignee: '鐜嬩簲',
+ status: 'completed',
+ vehicle: '绮11111',
+ taskNo: 'RW20230513003'
+ },
+ {
+ id: 4,
+ title: '鍔犳补浠诲姟',
+ type: 'refuel', // 鍔犳补
+ startLocation: '浣涘北甯傜鍩庡尯AA璺�555鍙�',
+ endLocation: '浣涘北甯傚崡娴峰尯BB璺�888鍙�',
+ startTime: '2023-05-12 09:00',
+ assignee: '璧靛叚',
+ status: 'completed',
+ vehicle: '绮22222',
+ taskNo: 'RW20230512004'
+ },
+ {
+ id: 5,
+ title: '鎬ユ晳杞繍浠诲姟',
+ type: 'emergency', // 鎬ユ晳杞繍
+ startLocation: '骞垮窞甯傝秺绉�鍖哄尰闄㈣矾1鍙�',
+ endLocation: '骞垮窞甯傛捣鐝犲尯鍖婚櫌璺�2鍙�',
+ startTime: '2023-05-16 14:00',
+ assignee: '寮犲尰鐢�,鏉庢姢澹�',
+ status: 'pending',
+ vehicle: '绮33333',
+ taskNo: 'RW20230516005'
+ },
+ {
+ id: 6,
+ title: '绂忕杞︿换鍔�',
+ type: 'welfare', // 绂忕杞�
+ startLocation: '骞垮窞甯傝崝婀惧尯绀惧尯璺�10鍙�',
+ endLocation: '骞垮窞甯傚ぉ娌冲尯鍏昏�侀櫌璺�20鍙�',
+ startTime: '2023-05-17 08:00',
+ assignee: '鐜嬪徃鏈�',
+ status: 'processing',
+ vehicle: '绮44444',
+ taskNo: 'RW20230517006'
+ }
+ ]
+ }
+ },
+ computed: {
+ filteredTaskList() {
+ let filtered = this.taskList;
+
+ // 搴旂敤绛涢�夊櫒
+ if (this.currentFilter !== 'all') {
+ filtered = filtered.filter(task => {
+ if (this.currentFilter === 'pending') return task.status === 'pending';
+ if (this.currentFilter === 'processing') return task.status === 'processing';
+ if (this.currentFilter === 'completed') return task.status === 'completed';
+ return true;
+ });
+ }
+
+ // 搴旂敤鐘舵�佺瓫閫�
+ if (this.selectedStatus) {
+ filtered = filtered.filter(task => task.status === this.selectedStatus);
+ }
+
+ // 搴旂敤杞︾墝鍙风瓫閫�
+ if (this.searchForm.vehicle) {
+ filtered = filtered.filter(task =>
+ task.vehicle.includes(this.searchForm.vehicle)
+ );
+ }
+
+ // 搴旂敤浠诲姟缂栧彿绛涢��
+ if (this.searchForm.taskNo) {
+ filtered = filtered.filter(task =>
+ task.taskNo.includes(this.searchForm.taskNo)
+ );
+ }
+
+ // 搴旂敤鏃堕棿鑼冨洿绛涢��
+ if (this.startDate) {
+ filtered = filtered.filter(task =>
+ task.startTime >= this.startDate
+ );
+ }
+
+ if (this.endDate) {
+ // 缁撴潫鏃ユ湡鍔犱竴澶╋紝浠ヤ究鍖呭惈褰撳ぉ鐨勬暟鎹�
+ const end = new Date(this.endDate);
+ end.setDate(end.getDate() + 1);
+ const endDateStr = end.toISOString().split('T')[0];
+
+ filtered = filtered.filter(task =>
+ task.startTime < endDateStr
+ );
+ }
+
+ return filtered;
+ }
+ },
+ methods: {
+ // 鍒囨崲鏌ヨ鐣岄潰鏄剧ず/闅愯棌
+ toggleSearch() {
+ this.showSearch = !this.showSearch;
+ },
+
+ // 鐘舵�侀�夋嫨
+ onStatusChange(e) {
+ this.selectedStatus = this.statusValues[e.detail.value];
+ this.selectedStatusText = this.statusOptions[e.detail.value];
+ },
+
+ // 鏌ヨ
+ handleSearch() {
+ this.$modal.showToast('鏌ヨ鎴愬姛');
+ console.log('鏌ヨ鏉′欢:', {
+ status: this.selectedStatus,
+ startDate: this.startDate,
+ endDate: this.endDate,
+ vehicle: this.searchForm.vehicle,
+ taskNo: this.searchForm.taskNo
+ });
+ // 鏌ヨ瀹屾垚鍚庨殣钘忔煡璇㈢晫闈�
+ this.showSearch = false;
+ // 杩欓噷鍙互璋冪敤API杩涜鏌ヨ
+ },
+
+ // 閲嶇疆鏌ヨ鏉′欢
+ resetSearch() {
+ this.selectedStatus = '';
+ this.selectedStatusText = '';
+ this.startDate = '';
+ this.endDate = '';
+ this.searchForm.vehicle = '';
+ this.searchForm.taskNo = '';
+ },
+
+ // 鍒锋柊鍒楄〃
+ refreshList() {
+ this.$modal.showToast('鍒楄〃宸插埛鏂�');
+ // 杩欓噷鍙互閲嶆柊鍔犺浇鏁版嵁
+ },
+
+ // 绛涢��
+ changeFilter(filter) {
+ this.currentFilter = filter;
+ },
+
+ // 鏌ョ湅浠诲姟璇︽儏
+ viewTaskDetail(task) {
+ // 璺宠浆鍒颁换鍔¤鎯呴〉闈�
+ this.$tab.navigateTo(`/pages/task/detail?id=${task.id}`);
+ },
+
+ // 鍒ゆ柇鎿嶄綔鎸夐挳鏄惁绂佺敤
+ isActionDisabled(task, action) {
+ // 鏍规嵁浠诲姟鐘舵�佸拰鎿嶄綔绫诲瀷鍒ゆ柇鏄惁绂佺敤
+ switch (action) {
+ case 'depart':
+ return task.status !== 'pending';
+ case 'arrive':
+ return task.status !== 'processing';
+ case 'return':
+ return task.status !== 'processing';
+ case 'settle':
+ return task.status !== 'processing';
+ case 'complete':
+ return task.status !== 'processing';
+ default:
+ return false;
+ }
+ },
+
+ // 澶勭悊浠诲姟鎿嶄綔
+ handleTaskAction(task, action) {
+ if (this.isActionDisabled(task, action)) {
+ return;
+ }
+
+ switch (action) {
+ case 'depart':
+ // 鍑哄彂鎿嶄綔锛屾牴鎹换鍔$被鍨嬫樉绀轰笉鍚岀殑纭淇℃伅
+ let departMessage = '纭畾瑕佹爣璁颁负宸插嚭鍙戝悧锛�';
+ if (task.type !== 'maintenance' && task.type !== 'refuel' && task.type !== 'inspection') {
+ departMessage = '鍙戝嚭鍘荤洰鐨勫湴,纭锛�';
+ }
+ this.$modal.confirm(departMessage).then(() => {
+ task.status = 'processing';
+ this.$modal.showToast('宸插嚭鍙�');
+ // 杩欓噷鍙互璋冪敤API鏇存柊浠诲姟鐘舵��
+ }).catch(() => {});
+ break;
+ case 'arrive':
+ // 宸插埌杈炬搷浣�
+ this.$modal.confirm('宸茬粡鍒拌揪鐩殑鍦帮紝纭锛�').then(() => {
+ this.$modal.showToast('宸插埌杈�');
+ // 杩欓噷鍙互璋冪敤API鏇存柊浠诲姟鐘舵��
+ }).catch(() => {});
+ break;
+ case 'return':
+ // 杩旂▼鎿嶄綔
+ this.$modal.confirm('鐜板湪宸茬粡杩旂▼涓紝纭锛�').then(() => {
+ this.$modal.showToast('杩旂▼涓�');
+ // 杩欓噷鍙互璋冪敤API鏇存柊浠诲姟鐘舵��
+ }).catch(() => {});
+ break;
+ case 'settle':
+ // 缁撶畻鎿嶄綔锛岃烦杞埌缁撶畻椤甸潰
+ this.$tab.navigateTo(`/pages/task/settlement?id=${task.id}`);
+ break;
+ case 'complete':
+ // 宸插畬鎴愭搷浣�
+ this.$modal.confirm('浠诲姟鏄惁宸茬粡鍏ㄩ儴瀹屾垚锛岀‘璁わ紵').then(() => {
+ task.status = 'completed';
+ this.$modal.showToast('浠诲姟宸插畬鎴�');
+ // 杩欓噷鍙互璋冪敤API鏇存柊浠诲姟鐘舵��
+ }).catch(() => {});
+ break;
+ }
+ },
+
+ getStatusText(status) {
+ const statusMap = {
+ 'pending': '寰呭鐞�',
+ 'processing': '澶勭悊涓�',
+ 'completed': '宸插畬鎴�'
+ }
+ return statusMap[status] || '鏈煡'
+ },
+
+ getTaskTypeText(type) {
+ const typeMap = {
+ 'maintenance': '缁翠慨淇濆吇',
+ 'refuel': '鍔犳补',
+ 'inspection': '宸℃',
+ 'emergency': '鎬ユ晳杞繍',
+ 'welfare': '绂忕杞�'
+ }
+ return typeMap[type] || '鏈煡绫诲瀷'
+ }
+ }
+ }
+</script>
+
+<style lang="scss">
+ .task-container {
+ padding: 20rpx;
+ background-color: #f5f5f5;
+ height: 100vh;
+ display: flex;
+ flex-direction: column;
+ // 闅愯棌婊氬姩鏉′絾淇濇寔婊氬姩鍔熻兘
+ ::-webkit-scrollbar {
+ display: none;
+ width: 0 !important;
+ height: 0 !important;
+ background: transparent;
+ }
+
+ // Firefox婊氬姩鏉¢殣钘�
+ * {
+ scrollbar-width: none; /* Firefox */
+ }
+
+ // IE/Edge婊氬姩鏉¢殣钘�
+ * {
+ -ms-overflow-style: none; /* IE 10+ */
+ }
+ }
+
+ // 浠诲姟鍒楄〃鍖哄煙
+ .task-list-section {
+ flex: 1;
+ background-color: white;
+ border-radius: 15rpx;
+ padding: 30rpx;
+ box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+ display: flex;
+ flex-direction: column;
+ }
+
+ .task-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 20rpx 0;
+ flex-shrink: 0; // 闃叉鏀剁缉
+
+ .header-title {
+ font-size: 36rpx;
+ font-weight: bold;
+ }
+
+ .header-actions {
+ display: flex;
+
+ .search-toggle-btn, .refresh-btn {
+ width: 60rpx;
+ height: 60rpx;
+ border-radius: 50%;
+ background-color: #f0f0f0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-left: 20rpx;
+ }
+ }
+ }
+
+ // 鏌ヨ鏉′欢鍖哄煙
+ .search-section {
+ background-color: #f9f9f9;
+ border-radius: 15rpx;
+ padding: 30rpx;
+ margin: 20rpx 0;
+ box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+ flex-shrink: 0; // 闃叉鏀剁缉
+
+ .form-item {
+ margin-bottom: 30rpx;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+
+ .form-label {
+ font-size: 28rpx;
+ margin-bottom: 15rpx;
+ color: #333;
+ }
+
+ .form-input {
+ height: 70rpx;
+ padding: 0 20rpx;
+ border: 1rpx solid #eee;
+ border-radius: 10rpx;
+ font-size: 28rpx;
+
+ &.picker-input {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ }
+ }
+
+ .date-range {
+ display: flex;
+ align-items: center;
+
+ .date-input {
+ flex: 1;
+ height: 70rpx;
+ padding: 0 20rpx;
+ border: 1rpx solid #eee;
+ border-radius: 10rpx;
+ font-size: 28rpx;
+ display: flex;
+ align-items: center;
+ }
+
+ .divider {
+ margin: 0 20rpx;
+ color: #999;
+ }
+ }
+ }
+
+ .form-actions {
+ display: flex;
+ margin-top: 20rpx;
+
+ .search-btn, .reset-btn {
+ flex: 1;
+ height: 70rpx;
+ border-radius: 10rpx;
+ font-size: 28rpx;
+ margin: 0 10rpx;
+ }
+
+ .search-btn {
+ background-color: #007AFF;
+ color: white;
+ }
+ }
+ }
+
+ .task-filter {
+ margin-bottom: 30rpx;
+ flex-shrink: 0; // 闃叉鏀剁缉
+
+ .filter-tabs {
+ white-space: nowrap;
+ padding: 10rpx 0;
+ // 闅愯棌婊氬姩鏉′絾淇濇寔婊氬姩鍔熻兘
+ ::-webkit-scrollbar {
+ display: none;
+ width: 0 !important;
+ height: 0 !important;
+ background: transparent;
+ }
+
+ // Firefox婊氬姩鏉¢殣钘�
+ * {
+ scrollbar-width: none; /* Firefox */
+ }
+
+ // IE/Edge婊氬姩鏉¢殣钘�
+ * {
+ -ms-overflow-style: none; /* IE 10+ */
+ }
+
+ .filter-item {
+ display: inline-block;
+ padding: 15rpx 30rpx;
+ margin-right: 20rpx;
+ background-color: #f5f5f5;
+ border-radius: 30rpx;
+ font-size: 28rpx;
+
+ &.active {
+ background-color: #007AFF;
+ color: white;
+ }
+ }
+ }
+ }
+
+ .task-list-scroll {
+ flex: 1;
+ // 闅愯棌婊氬姩鏉′絾淇濇寔婊氬姩鍔熻兘
+ ::-webkit-scrollbar {
+ display: none;
+ width: 0 !important;
+ height: 0 !important;
+ background: transparent;
+ }
+
+ // Firefox婊氬姩鏉¢殣钘�
+ * {
+ scrollbar-width: none; /* Firefox */
+ }
+
+ // IE/Edge婊氬姩鏉¢殣钘�
+ * {
+ -ms-overflow-style: none; /* IE 10+ */
+ }
+ }
+
+ .task-list {
+ .task-item {
+ background-color: #fafafa;
+ border-radius: 15rpx;
+ margin-bottom: 30rpx;
+ overflow: hidden;
+
+ .task-main {
+ padding: 30rpx;
+ border-bottom: 1rpx solid #f0f0f0;
+
+ .task-title {
+ font-size: 32rpx;
+ font-weight: bold;
+ margin-bottom: 20rpx;
+ }
+
+ .task-info {
+ .info-row {
+ display: flex;
+ margin-bottom: 15rpx;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+
+ .info-item {
+ flex: 1;
+ display: flex;
+
+ .label {
+ font-size: 26rpx;
+ color: #666;
+ margin-right: 10rpx;
+ white-space: nowrap;
+ }
+
+ .value {
+ font-size: 26rpx;
+ flex: 1;
+ word-break: break-all;
+ }
+ }
+ }
+ }
+ }
+
+ .task-actions {
+ display: flex;
+ padding: 20rpx;
+
+ .action-btn {
+ flex: 1;
+ height: 70rpx;
+ border-radius: 10rpx;
+ font-size: 26rpx;
+ margin: 0 5rpx;
+ background-color: #f0f0f0;
+ color: #333;
+
+ &.primary {
+ background-color: #007AFF;
+ color: white;
+ }
+
+ &.disabled {
+ opacity: 0.5;
+ }
+
+ &:first-child {
+ margin-left: 0;
+ }
+
+ &:last-child {
+ margin-right: 0;
+ }
+ }
+ }
+ }
+
+ .no-data {
+ text-align: center;
+ padding: 100rpx 0;
+ color: #999;
+
+ text {
+ display: block;
+ margin-top: 20rpx;
+ }
+ }
+ }
+</style>
\ No newline at end of file
diff --git a/app/pages/task/settlement.vue b/app/pages/task/settlement.vue
new file mode 100644
index 0000000..865269b
--- /dev/null
+++ b/app/pages/task/settlement.vue
@@ -0,0 +1,747 @@
+<template>
+ <view class="settlement-container">
+ <view class="settlement-header">
+ <text class="header-title">浠诲姟缁撶畻</text>
+ </view>
+
+ <scroll-view class="settlement-content" scroll-y="true">
+ <view class="task-info-section">
+ <view class="info-item">
+ <view class="label">浠诲姟缂栧彿:</view>
+ <view class="value">{{ task.taskNo }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">浠诲姟绫诲瀷:</view>
+ <view class="value">{{ getTaskTypeText(task.type) }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">杞﹁締淇℃伅:</view>
+ <view class="value">{{ task.vehicle }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">鍑哄彂鍦�:</view>
+ <view class="value">{{ task.startLocation }}</view>
+ </view>
+
+ <view class="info-item">
+ <view class="label">鐩殑鍦�:</view>
+ <view class="value">{{ task.endLocation }}</view>
+ </view>
+ </view>
+
+ <view class="amount-section">
+ <view class="section-title">璐圭敤淇℃伅</view>
+
+ <view class="amount-item">
+ <view class="label">鍩虹璐圭敤:</view>
+ <view class="value">楼{{ baseAmount }}</view>
+ </view>
+
+ <view class="amount-item additional-fees" @click="showAdditionalFees">
+ <view class="label">闄勫姞璐圭敤:</view>
+ <view class="value">楼{{ additionalAmount }}
+ <uni-icons type="arrowright" size="16" color="#999"></uni-icons>
+ </view>
+ </view>
+
+ <view class="amount-item total-amount">
+ <view class="label">鎬昏垂鐢�:</view>
+ <view class="value total">楼{{ totalAmount }}</view>
+ </view>
+ </view>
+
+ <view class="settlement-form">
+ <view class="form-item">
+ <view class="form-label">缁撶畻閲戦</view>
+ <input
+ class="form-input"
+ type="digit"
+ placeholder="璇疯緭鍏ョ粨绠楅噾棰�"
+ v-model="settlementAmount"
+ />
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">鏀粯鏂瑰紡</view>
+ <picker mode="selector" :range="paymentMethods" @change="onPaymentMethodChange">
+ <view class="form-input picker-input">
+ {{ selectedPaymentMethod || '璇烽�夋嫨鏀粯鏂瑰紡' }}
+ <uni-icons type="arrowright" size="16" color="#999"></uni-icons>
+ </view>
+ </picker>
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">澶囨敞</view>
+ <textarea
+ class="form-textarea"
+ placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�"
+ v-model="remark"
+ />
+ </view>
+ </view>
+
+ <!-- 鏀粯浜岀淮鐮佸尯鍩� -->
+ <view v-if="showQRCode" class="qr-code-section">
+ <view class="section-title">璇锋壂鐮佹敮浠�</view>
+ <view class="qr-code-container">
+ <image class="qr-code" :src="qrCodeImage" mode="widthFix"></image>
+ <view class="qr-tip">璇蜂娇鐢▄{ selectedPaymentMethod }}鎵爜鏀粯</view>
+ </view>
+ <view class="payment-status">
+ <view v-if="paymentStatus === 'pending'" class="status-pending">绛夊緟鏀粯...</view>
+ <view v-if="paymentStatus === 'success'" class="status-success">
+ <uni-icons type="checkmarkempty" size="24" color="#4cd964"></uni-icons>
+ 鏀粯鎴愬姛
+ </view>
+ </view>
+ </view>
+ </scroll-view>
+
+ <view class="action-section">
+ <button
+ v-if="!showQRCode || paymentStatus === 'success'"
+ class="submit-btn"
+ @click="saveSettlement"
+ :disabled="!canSave"
+ >
+ 淇濆瓨缁撶畻
+ </button>
+ </view>
+
+ <!-- 闄勫姞璐圭敤寮圭獥 -->
+ <uni-popup ref="additionalFeesPopup" type="bottom">
+ <view class="popup-content">
+ <view class="popup-header">
+ <text class="header-title">闄勫姞璐圭敤</text>
+ <view class="close-btn" @click="closeAdditionalFeesPopup">
+ <uni-icons type="close" size="20" color="#999"></uni-icons>
+ </view>
+ </view>
+
+ <!-- 绠�鍖栫増璐圭敤娣诲姞 -->
+ <view class="simple-fee-section">
+ <view class="form-item">
+ <view class="form-label">璐圭敤绫诲瀷</view>
+ <picker mode="selector" :range="additionalFeeTypeNames" @change="onFeeTypeChange">
+ <view class="form-input picker-input">
+ {{ selectedFeeTypeName || '璇烽�夋嫨璐圭敤绫诲瀷' }}
+ <uni-icons type="arrowright" size="16" color="#999"></uni-icons>
+ </view>
+ </picker>
+ </view>
+
+ <view class="form-item">
+ <view class="form-label">璐圭敤閲戦</view>
+ <input
+ class="form-input"
+ type="digit"
+ placeholder="璇疯緭鍏ヨ垂鐢ㄩ噾棰�"
+ v-model="newFeePrice"
+ />
+ </view>
+
+ <view class="add-fee-btn">
+ <button class="confirm-btn" @click="addCustomFee">娣诲姞璐圭敤</button>
+ </view>
+ </view>
+
+ <!-- 宸叉坊鍔犵殑璐圭敤鍒楄〃 -->
+ <view class="added-fees-list" v-if="selectedAdditionalFees.length > 0">
+ <view class="section-title">宸叉坊鍔犺垂鐢�</view>
+ <view
+ class="fee-item"
+ v-for="(fee, index) in selectedAdditionalFees"
+ :key="index"
+ >
+ <view class="fee-info">
+ <view class="fee-name">{{ fee.name }}</view>
+ <view class="fee-price">楼{{ fee.price }} 脳 {{ fee.quantity }}</view>
+ </view>
+ <view class="fee-total">楼{{ (fee.price * fee.quantity).toFixed(2) }}</view>
+ </view>
+ </view>
+
+ <view class="popup-footer">
+ <button class="confirm-btn" @click="confirmAdditionalFees">纭畾</button>
+ </view>
+ </view>
+ </uni-popup>
+ </view>
+</template>
+
+<script>
+ export default {
+ data() {
+ return {
+ task: {
+ id: 1,
+ taskNo: 'RW20230515001',
+ type: 'emergency',
+ vehicle: '绮12345',
+ startLocation: '骞垮窞甯傚ぉ娌冲尯XX璺�123鍙�',
+ endLocation: '骞垮窞甯傜櫧浜戝尯YY璺�456鍙�'
+ },
+ baseAmount: 1000, // 鍩虹璐圭敤
+ additionalAmount: 0, // 闄勫姞璐圭敤
+ settlementAmount: '', // 缁撶畻閲戦
+ remark: '', // 澶囨敞
+ paymentMethods: ['鐜伴噾', '鏀粯瀹�', '寰俊', '鎸傚笎'],
+ selectedPaymentMethod: '',
+ showQRCode: false,
+ paymentStatus: 'pending', // pending, success
+ qrCodeImage: '/static/images/qrcode.png', // 浜岀淮鐮佸浘鐗囪矾寰�
+ additionalFeeTypes: [
+ { name: '鎷呮灦璐�', price: 200 },
+ { name: '绛夊緟璐�', price: 100 },
+ { name: '鍠勫悗璐�', price: 150 },
+ { name: '澶滈棿鏈嶅姟璐�', price: 300 },
+ { name: '闀块�旇垂', price: 500 }
+ ],
+ selectedAdditionalFees: [], // 宸查�夋嫨鐨勯檮鍔犺垂鐢�
+ selectedFeeTypeName: '', // 閫変腑鐨勮垂鐢ㄧ被鍨嬪悕绉�
+ newFeePrice: '' // 鏂板璐圭敤浠锋牸
+ }
+ },
+ computed: {
+ totalAmount() {
+ return this.baseAmount + this.additionalAmount;
+ },
+ canSave() {
+ // 鐜伴噾鍜屾寕甯愬彲浠ョ洿鎺ヤ繚瀛橈紝鍏朵粬鏀粯鏂瑰紡闇�瑕佹敮浠樻垚鍔熷悗鎵嶈兘淇濆瓨
+ if (!this.settlementAmount || !this.selectedPaymentMethod) {
+ return false;
+ }
+
+ if (this.selectedPaymentMethod === '鐜伴噾' || this.selectedPaymentMethod === '鎸傚笎') {
+ return true;
+ }
+
+ // 鏀粯瀹濄�佸井淇$瓑闇�瑕佹敮浠樻垚鍔�
+ return this.paymentStatus === 'success';
+ },
+ // 鑾峰彇璐圭敤绫诲瀷鍚嶇О鏁扮粍
+ additionalFeeTypeNames() {
+ return this.additionalFeeTypes.map(fee => fee.name);
+ }
+ },
+ onLoad(options) {
+ // 瀹為檯椤圭洰涓繖閲屼細閫氳繃API鑾峰彇浠诲姟璇︽儏
+ // const taskId = options.id;
+ // this.getTaskDetail(taskId);
+ },
+ methods: {
+ getTaskTypeText(type) {
+ const typeMap = {
+ 'maintenance': '缁翠慨淇濆吇',
+ 'refuel': '鍔犳补',
+ 'inspection': '宸℃',
+ 'emergency': '鎬ユ晳杞繍',
+ 'welfare': '绂忕杞�'
+ }
+ return typeMap[type] || '鏈煡绫诲瀷'
+ },
+
+ onPaymentMethodChange(e) {
+ this.selectedPaymentMethod = this.paymentMethods[e.detail.value];
+
+ // 濡傛灉閫夋嫨鏀粯瀹濇垨寰俊锛屾樉绀轰簩缁寸爜
+ if (this.selectedPaymentMethod === '鏀粯瀹�' || this.selectedPaymentMethod === '寰俊') {
+ this.showQRCode = true;
+ this.paymentStatus = 'pending';
+ // 妯℃嫙鏀粯鐘舵�佹鏌�
+ this.checkPaymentStatus();
+ } else {
+ this.showQRCode = false;
+ this.paymentStatus = 'pending';
+ }
+ },
+
+ // 璐圭敤绫诲瀷閫夋嫨
+ onFeeTypeChange(e) {
+ this.selectedFeeTypeName = this.additionalFeeTypeNames[e.detail.value];
+ },
+
+ checkPaymentStatus() {
+ // 妯℃嫙鏀粯鐘舵�佹鏌ワ紝瀹為檯椤圭洰涓簲璇ラ�氳繃API杞妫�鏌ユ敮浠樼姸鎬�
+ setTimeout(() => {
+ // 妯℃嫙鏀粯鎴愬姛
+ this.paymentStatus = 'success';
+ }, 5000);
+ },
+
+ showAdditionalFees() {
+ this.$refs.additionalFeesPopup.open();
+ },
+
+ closeAdditionalFeesPopup() {
+ this.$refs.additionalFeesPopup.close();
+ },
+
+ // 娣诲姞鑷畾涔夎垂鐢�
+ addCustomFee() {
+ if (!this.selectedFeeTypeName) {
+ this.$modal.showToast('璇烽�夋嫨璐圭敤绫诲瀷');
+ return;
+ }
+
+ if (!this.newFeePrice || isNaN(this.newFeePrice) || parseFloat(this.newFeePrice) <= 0) {
+ this.$modal.showToast('璇疯緭鍏ユ湁鏁堢殑璐圭敤閲戦');
+ return;
+ }
+
+ // 鏌ユ壘閫変腑鐨勮垂鐢ㄧ被鍨嬩俊鎭�
+ const selectedFeeType = this.additionalFeeTypes.find(fee => fee.name === this.selectedFeeTypeName);
+
+ // 妫�鏌ユ槸鍚﹀凡瀛樺湪鍚屽悕璐圭敤
+ const existingFee = this.selectedAdditionalFees.find(fee => fee.name === this.selectedFeeTypeName);
+ if (existingFee) {
+ existingFee.quantity += 1;
+ } else {
+ this.selectedAdditionalFees.push({
+ name: this.selectedFeeTypeName,
+ price: parseFloat(this.newFeePrice),
+ quantity: 1
+ });
+ }
+
+ // 娓呯┖杈撳叆妗�
+ this.selectedFeeTypeName = '';
+ this.newFeePrice = '';
+
+ this.calculateAdditionalAmount();
+ this.$modal.showToast('璐圭敤娣诲姞鎴愬姛');
+ },
+
+ calculateAdditionalAmount() {
+ this.additionalAmount = this.selectedAdditionalFees.reduce((total, fee) => {
+ return total + (fee.price * fee.quantity);
+ }, 0);
+ },
+
+ confirmAdditionalFees() {
+ this.calculateAdditionalAmount();
+ this.closeAdditionalFeesPopup();
+ },
+
+ saveSettlement() {
+ if (!this.settlementAmount) {
+ this.$modal.showToast('璇疯緭鍏ョ粨绠楅噾棰�');
+ return;
+ }
+
+ if (!this.selectedPaymentMethod) {
+ this.$modal.showToast('璇烽�夋嫨鏀粯鏂瑰紡');
+ return;
+ }
+
+ // 妫�鏌ョ粨绠楅噾棰濇槸鍚﹀悎鐞�
+ if (parseFloat(this.settlementAmount) > this.totalAmount) {
+ this.$modal.showToast('缁撶畻閲戦涓嶈兘澶т簬鎬昏垂鐢�');
+ return;
+ }
+
+ this.$modal.confirm('纭畾瑕佷繚瀛樼粨绠椾俊鎭悧锛�').then(() => {
+ // 杩欓噷搴旇璋冪敤API淇濆瓨缁撶畻淇℃伅
+ console.log('缁撶畻淇℃伅:', {
+ taskId: this.task.id,
+ baseAmount: this.baseAmount,
+ additionalAmount: this.additionalAmount,
+ totalAmount: this.totalAmount,
+ settlementAmount: this.settlementAmount,
+ paymentMethod: this.selectedPaymentMethod,
+ remark: this.remark,
+ additionalFees: this.selectedAdditionalFees
+ });
+
+ this.$modal.showToast('缁撶畻淇℃伅淇濆瓨鎴愬姛');
+ // 杩斿洖浠诲姟鍒楄〃
+ this.$tab.navigateBack();
+ }).catch(() => {
+ // 鍙栨秷鎿嶄綔
+ });
+ }
+ }
+ }
+</script>
+
+<style lang="scss">
+ .settlement-container {
+ padding: 20rpx;
+ background-color: #f5f5f5;
+ height: 100vh;
+ display: flex;
+ flex-direction: column;
+ // 闅愯棌婊氬姩鏉′絾淇濇寔婊氬姩鍔熻兘
+ ::-webkit-scrollbar {
+ display: none;
+ width: 0 !important;
+ height: 0 !important;
+ background: transparent;
+ }
+
+ // Firefox婊氬姩鏉¢殣钘�
+ * {
+ scrollbar-width: none; /* Firefox */
+ }
+
+ // IE/Edge婊氬姩鏉¢殣钘�
+ * {
+ -ms-overflow-style: none; /* IE 10+ */
+ }
+ }
+
+ .settlement-header {
+ background-color: white;
+ border-radius: 15rpx;
+ padding: 30rpx;
+ margin-bottom: 20rpx;
+ box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+ flex-shrink: 0;
+
+ .header-title {
+ font-size: 36rpx;
+ font-weight: bold;
+ color: #333;
+ text-align: center;
+ }
+ }
+
+ .settlement-content {
+ flex: 1;
+
+ .task-info-section {
+ background-color: white;
+ border-radius: 15rpx;
+ padding: 30rpx;
+ margin-bottom: 20rpx;
+ box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+
+ .info-item {
+ display: flex;
+ margin-bottom: 20rpx;
+ padding-bottom: 20rpx;
+ border-bottom: 1rpx solid #f0f0f0;
+
+ &:last-child {
+ margin-bottom: 0;
+ padding-bottom: 0;
+ border-bottom: none;
+ }
+
+ .label {
+ font-size: 28rpx;
+ color: #666;
+ margin-right: 20rpx;
+ white-space: nowrap;
+ width: 150rpx;
+ }
+
+ .value {
+ font-size: 28rpx;
+ flex: 1;
+ word-break: break-all;
+ }
+ }
+ }
+
+ .amount-section {
+ background-color: white;
+ border-radius: 15rpx;
+ padding: 30rpx;
+ margin-bottom: 20rpx;
+ box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+
+ .section-title {
+ font-size: 32rpx;
+ font-weight: bold;
+ margin-bottom: 30rpx;
+ color: #333;
+ }
+
+ .amount-item {
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: 20rpx;
+ padding-bottom: 20rpx;
+ border-bottom: 1rpx solid #f0f0f0;
+
+ &:last-child {
+ margin-bottom: 0;
+ padding-bottom: 0;
+ border-bottom: none;
+ }
+
+ &.additional-fees {
+ .value {
+ color: #007AFF;
+ }
+ }
+
+ &.total-amount {
+ .label {
+ font-weight: bold;
+ }
+
+ .value.total {
+ font-weight: bold;
+ font-size: 32rpx;
+ color: #e54d42;
+ }
+ }
+
+ .label {
+ font-size: 28rpx;
+ color: #333;
+ }
+
+ .value {
+ font-size: 28rpx;
+ color: #333;
+ }
+ }
+ }
+
+ .settlement-form {
+ background-color: white;
+ border-radius: 15rpx;
+ padding: 30rpx;
+ margin-bottom: 20rpx;
+ box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+
+ .form-item {
+ margin-bottom: 40rpx;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+
+ .form-label {
+ font-size: 28rpx;
+ margin-bottom: 15rpx;
+ color: #333;
+ }
+
+ .form-input {
+ height: 70rpx;
+ padding: 0 20rpx;
+ border: 1rpx solid #eee;
+ border-radius: 10rpx;
+ font-size: 28rpx;
+
+ &.picker-input {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ }
+ }
+
+ .form-textarea {
+ width: 100%;
+ min-height: 150rpx;
+ padding: 20rpx;
+ border: 1rpx solid #eee;
+ border-radius: 10rpx;
+ font-size: 28rpx;
+ resize: none;
+ }
+ }
+ }
+
+ .qr-code-section {
+ background-color: white;
+ border-radius: 15rpx;
+ padding: 30rpx;
+ margin-bottom: 20rpx;
+ box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+ text-align: center;
+
+ .section-title {
+ font-size: 32rpx;
+ font-weight: bold;
+ margin-bottom: 30rpx;
+ color: #333;
+ }
+
+ .qr-code-container {
+ margin-bottom: 30rpx;
+
+ .qr-code {
+ width: 300rpx;
+ height: 300rpx;
+ margin: 0 auto 20rpx;
+ }
+
+ .qr-tip {
+ font-size: 26rpx;
+ color: #666;
+ }
+ }
+
+ .payment-status {
+ .status-pending {
+ font-size: 28rpx;
+ color: #ff9900;
+ }
+
+ .status-success {
+ font-size: 28rpx;
+ color: #4cd964;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+ }
+ }
+ }
+
+ .action-section {
+ padding: 20rpx 0;
+ flex-shrink: 0;
+
+ .submit-btn {
+ width: 80%;
+ height: 80rpx;
+ background-color: #007AFF;
+ color: white;
+ border-radius: 10rpx;
+ font-size: 32rpx;
+ margin: 0 auto;
+ display: block;
+
+ &[disabled] {
+ background-color: #ccc;
+ }
+ }
+ }
+
+ .popup-content {
+ background-color: white;
+ border-top-left-radius: 20rpx;
+ border-top-right-radius: 20rpx;
+ padding: 30rpx;
+ max-height: 80vh;
+
+ .popup-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 30rpx;
+ padding-bottom: 20rpx;
+ border-bottom: 1rpx solid #f0f0f0;
+
+ .header-title {
+ font-size: 36rpx;
+ font-weight: bold;
+ color: #333;
+ }
+
+ .close-btn {
+ padding: 10rpx;
+ }
+ }
+
+ .simple-fee-section {
+ padding: 20rpx 0;
+ border-bottom: 1rpx solid #f0f0f0;
+ margin-bottom: 20rpx;
+
+ .form-item {
+ margin-bottom: 30rpx;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+
+ .form-label {
+ font-size: 28rpx;
+ margin-bottom: 15rpx;
+ color: #333;
+ }
+
+ .form-input {
+ height: 70rpx;
+ padding: 0 20rpx;
+ border: 1rpx solid #eee;
+ border-radius: 10rpx;
+ font-size: 28rpx;
+
+ &.picker-input {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ }
+ }
+ }
+
+ .add-fee-btn {
+ margin-top: 20rpx;
+
+ .confirm-btn {
+ width: 100%;
+ height: 70rpx;
+ background-color: #007AFF;
+ color: white;
+ border-radius: 10rpx;
+ font-size: 28rpx;
+ }
+ }
+ }
+
+ .added-fees-list {
+ margin-bottom: 30rpx;
+
+ .section-title {
+ font-size: 32rpx;
+ font-weight: bold;
+ margin-bottom: 20rpx;
+ color: #333;
+ }
+
+ .fee-item {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 20rpx 0;
+ border-bottom: 1rpx solid #f0f0f0;
+
+ &:last-child {
+ border-bottom: none;
+ }
+
+ .fee-info {
+ .fee-name {
+ font-size: 28rpx;
+ color: #333;
+ margin-bottom: 10rpx;
+ }
+
+ .fee-price {
+ font-size: 26rpx;
+ color: #666;
+ }
+ }
+
+ .fee-total {
+ font-size: 28rpx;
+ font-weight: bold;
+ color: #e54d42;
+ }
+ }
+ }
+
+ .popup-footer {
+ .confirm-btn {
+ width: 100%;
+ height: 80rpx;
+ background-color: #007AFF;
+ color: white;
+ border-radius: 10rpx;
+ font-size: 32rpx;
+ }
+ }
+ }
+</style>
\ No newline at end of file
diff --git a/app/plugins/modal.js b/app/plugins/modal.js
index 99b2215..fa5b4a1 100644
--- a/app/plugins/modal.js
+++ b/app/plugins/modal.js
@@ -48,6 +48,26 @@
})
})
},
+ // 杈撳叆妗�
+ prompt(content, defaultValue) {
+ return new Promise((resolve, reject) => {
+ uni.showModal({
+ title: '绯荤粺鎻愮ず',
+ content: content,
+ editable: true,
+ placeholderText: defaultValue || '',
+ cancelText: '鍙栨秷',
+ confirmText: '纭畾',
+ success: function(res) {
+ if (res.confirm) {
+ resolve(res.content)
+ } else {
+ reject()
+ }
+ }
+ })
+ })
+ },
// 鎻愮ず淇℃伅
showToast(option) {
if (typeof option === "object") {
diff --git a/app/static/icons/README.md b/app/static/icons/README.md
new file mode 100644
index 0000000..17316a0
--- /dev/null
+++ b/app/static/icons/README.md
@@ -0,0 +1,23 @@
+# 鍥炬爣璧勬簮
+
+姝ょ洰褰曠敤浜庡瓨鏀惧簲鐢ㄦ墍闇�鐨勫浘鏍囪祫婧愩��
+
+## 闇�瑕佺殑鍥炬爣
+
+### TabBar 鍥炬爣
+- `home.png` / `home-active.png` - 棣栭〉鍥炬爣
+- `tasks.png` / `tasks-active.png` - 浠诲姟鍥炬爣
+- `create.png` / `create-active.png` - 鍒涘缓鍥炬爣
+- `messages.png` / `messages-active.png` - 娑堟伅鍥炬爣
+- `profile.png` / `profile-active.png` - 涓汉涓績鍥炬爣
+
+## 鍥炬爣瑙勬牸
+
+- 灏哄: 81px * 81px
+- 鏍煎紡: PNG
+- 鑳屾櫙: 閫忔槑
+- 棰滆壊: 鏅�氱姸鎬� #666666锛屾縺娲荤姸鎬� #030213
+
+## 浣跨敤璇存槑
+
+鍥炬爣鏂囦欢闇�瑕佹斁鍦ㄦ鐩綍涓嬶紝骞跺湪 `src/app.config.ts` 涓纭厤缃矾寰勩��
diff --git a/app/static/icons/create-active.png b/app/static/icons/create-active.png
new file mode 100644
index 0000000..32a454d
--- /dev/null
+++ b/app/static/icons/create-active.png
Binary files differ
diff --git a/app/static/icons/create-active.svg b/app/static/icons/create-active.svg
new file mode 100644
index 0000000..4118dcf
--- /dev/null
+++ b/app/static/icons/create-active.svg
@@ -0,0 +1,4 @@
+<svg width="81" height="81" viewBox="0 0 81 81" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <circle cx="40.5" cy="40.5" r="33.75" fill="#030213"/>
+ <path d="M40.5 20.25V60.75M20.25 40.5H60.75" stroke="white" stroke-width="4" stroke-linecap="round"/>
+</svg>
diff --git a/app/static/icons/create.png b/app/static/icons/create.png
new file mode 100644
index 0000000..32a454d
--- /dev/null
+++ b/app/static/icons/create.png
Binary files differ
diff --git a/app/static/icons/create.svg b/app/static/icons/create.svg
new file mode 100644
index 0000000..f719ee7
--- /dev/null
+++ b/app/static/icons/create.svg
@@ -0,0 +1,4 @@
+<svg width="81" height="81" viewBox="0 0 81 81" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <circle cx="40.5" cy="40.5" r="33.75" fill="#666666"/>
+ <path d="M40.5 20.25V60.75M20.25 40.5H60.75" stroke="white" stroke-width="4" stroke-linecap="round"/>
+</svg>
diff --git a/app/static/icons/home-active.png b/app/static/icons/home-active.png
new file mode 100644
index 0000000..e2502d9
--- /dev/null
+++ b/app/static/icons/home-active.png
Binary files differ
diff --git a/app/static/icons/home-active.svg b/app/static/icons/home-active.svg
new file mode 100644
index 0000000..d315bbc
--- /dev/null
+++ b/app/static/icons/home-active.svg
@@ -0,0 +1,3 @@
+<svg width="81" height="81" viewBox="0 0 81 81" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <path d="M40.5 6.75L70.875 27.5625V67.5H54V40.5H27V67.5H10.125V27.5625L40.5 6.75Z" fill="#030213"/>
+</svg>
diff --git a/app/static/icons/home.png b/app/static/icons/home.png
new file mode 100644
index 0000000..a46f990
--- /dev/null
+++ b/app/static/icons/home.png
Binary files differ
diff --git a/app/static/icons/home.svg b/app/static/icons/home.svg
new file mode 100644
index 0000000..0efe59d
--- /dev/null
+++ b/app/static/icons/home.svg
@@ -0,0 +1,3 @@
+<svg width="81" height="81" viewBox="0 0 81 81" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <path d="M40.5 6.75L70.875 27.5625V67.5H54V40.5H27V67.5H10.125V27.5625L40.5 6.75Z" fill="#666666"/>
+</svg>
diff --git a/app/static/icons/messages-active.png b/app/static/icons/messages-active.png
new file mode 100644
index 0000000..17b6932
--- /dev/null
+++ b/app/static/icons/messages-active.png
Binary files differ
diff --git a/app/static/icons/messages-active.svg b/app/static/icons/messages-active.svg
new file mode 100644
index 0000000..91599e9
--- /dev/null
+++ b/app/static/icons/messages-active.svg
@@ -0,0 +1,5 @@
+<svg width="81" height="81" viewBox="0 0 81 81" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <path d="M6.75 20.25H74.25C75.9069 20.25 77.25 21.5931 77.25 23.25V57.75C77.25 59.4069 75.9069 60.75 74.25 60.75H20.25L6.75 74.25V20.25Z" fill="#030213"/>
+ <path d="M20.25 33.75H60.75V40.5H20.25V33.75Z" fill="white"/>
+ <path d="M20.25 47.25H47.25V54H20.25V47.25Z" fill="white"/>
+</svg>
diff --git a/app/static/icons/messages.png b/app/static/icons/messages.png
new file mode 100644
index 0000000..a7f70f6
--- /dev/null
+++ b/app/static/icons/messages.png
Binary files differ
diff --git a/app/static/icons/messages.svg b/app/static/icons/messages.svg
new file mode 100644
index 0000000..a7f081c
--- /dev/null
+++ b/app/static/icons/messages.svg
@@ -0,0 +1,5 @@
+<svg width="81" height="81" viewBox="0 0 81 81" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <path d="M6.75 20.25H74.25C75.9069 20.25 77.25 21.5931 77.25 23.25V57.75C77.25 59.4069 75.9069 60.75 74.25 60.75H20.25L6.75 74.25V20.25Z" fill="#666666"/>
+ <path d="M20.25 33.75H60.75V40.5H20.25V33.75Z" fill="white"/>
+ <path d="M20.25 47.25H47.25V54H20.25V47.25Z" fill="white"/>
+</svg>
diff --git a/app/static/icons/profile-active.png b/app/static/icons/profile-active.png
new file mode 100644
index 0000000..dd2ed3b
--- /dev/null
+++ b/app/static/icons/profile-active.png
Binary files differ
diff --git a/app/static/icons/profile-active.svg b/app/static/icons/profile-active.svg
new file mode 100644
index 0000000..46aab33
--- /dev/null
+++ b/app/static/icons/profile-active.svg
@@ -0,0 +1,4 @@
+<svg width="81" height="81" viewBox="0 0 81 81" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <circle cx="40.5" cy="27" r="13.5" fill="#030213"/>
+ <path d="M13.5 67.5C13.5 54.5 25.5 44.25 40.5 44.25C55.5 44.25 67.5 54.5 67.5 67.5V74.25H13.5V67.5Z" fill="#030213"/>
+</svg>
diff --git a/app/static/icons/profile.png b/app/static/icons/profile.png
new file mode 100644
index 0000000..a88e85a
--- /dev/null
+++ b/app/static/icons/profile.png
Binary files differ
diff --git a/app/static/icons/profile.svg b/app/static/icons/profile.svg
new file mode 100644
index 0000000..8c5cb00
--- /dev/null
+++ b/app/static/icons/profile.svg
@@ -0,0 +1,4 @@
+<svg width="81" height="81" viewBox="0 0 81 81" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <circle cx="40.5" cy="27" r="13.5" fill="#666666"/>
+ <path d="M13.5 67.5C13.5 54.5 25.5 44.25 40.5 44.25C55.5 44.25 67.5 54.5 67.5 67.5V74.25H13.5V67.5Z" fill="#666666"/>
+</svg>
diff --git a/app/static/icons/tasks-active.png b/app/static/icons/tasks-active.png
new file mode 100644
index 0000000..57e4ae6
--- /dev/null
+++ b/app/static/icons/tasks-active.png
Binary files differ
diff --git a/app/static/icons/tasks-active.svg b/app/static/icons/tasks-active.svg
new file mode 100644
index 0000000..bb5b43d
--- /dev/null
+++ b/app/static/icons/tasks-active.svg
@@ -0,0 +1,6 @@
+<svg width="81" height="81" viewBox="0 0 81 81" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <path d="M20.25 6.75H60.75C62.4069 6.75 63.75 8.09315 63.75 9.75V71.25C63.75 72.9069 62.4069 74.25 60.75 74.25H20.25C18.5931 74.25 17.25 72.9069 17.25 71.25V9.75C17.25 8.09315 18.5931 6.75 20.25 6.75Z" fill="#030213"/>
+ <path d="M27 20.25H54V27H27V20.25Z" fill="white"/>
+ <path d="M27 33.75H54V40.5H27V33.75Z" fill="white"/>
+ <path d="M27 47.25H40.5V54H27V47.25Z" fill="white"/>
+</svg>
diff --git a/app/static/icons/tasks.png b/app/static/icons/tasks.png
new file mode 100644
index 0000000..26a3a40
--- /dev/null
+++ b/app/static/icons/tasks.png
Binary files differ
diff --git a/app/static/icons/tasks.svg b/app/static/icons/tasks.svg
new file mode 100644
index 0000000..1bca6b1
--- /dev/null
+++ b/app/static/icons/tasks.svg
@@ -0,0 +1,6 @@
+<svg width="81" height="81" viewBox="0 0 81 81" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <path d="M20.25 6.75H60.75C62.4069 6.75 63.75 8.09315 63.75 9.75V71.25C63.75 72.9069 62.4069 74.25 60.75 74.25H20.25C18.5931 74.25 17.25 72.9069 17.25 71.25V9.75C17.25 8.09315 18.5931 6.75 20.25 6.75Z" fill="#666666"/>
+ <path d="M27 20.25H54V27H27V20.25Z" fill="white"/>
+ <path d="M27 33.75H54V40.5H27V33.75Z" fill="white"/>
+ <path d="M27 47.25H40.5V54H27V47.25Z" fill="white"/>
+</svg>
diff --git a/app/static/images/qrcode.png b/app/static/images/qrcode.png
new file mode 100644
index 0000000..825b074
--- /dev/null
+++ b/app/static/images/qrcode.png
@@ -0,0 +1,222 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" viewBox="0 0 200 200">
+ <rect width="200" height="200" fill="#ffffff"/>
+ <g fill="#000000">
+ <rect x="10" y="10" width="10" height="10"/>
+ <rect x="20" y="10" width="10" height="10"/>
+ <rect x="30" y="10" width="10" height="10"/>
+ <rect x="40" y="10" width="10" height="10"/>
+ <rect x="50" y="10" width="10" height="10"/>
+ <rect x="60" y="10" width="10" height="10"/>
+ <rect x="70" y="10" width="10" height="10"/>
+ <rect x="80" y="10" width="10" height="10"/>
+ <rect x="90" y="10" width="10" height="10"/>
+ <rect x="100" y="10" width="10" height="10"/>
+ <rect x="110" y="10" width="10" height="10"/>
+ <rect x="120" y="10" width="10" height="10"/>
+ <rect x="130" y="10" width="10" height="10"/>
+ <rect x="140" y="10" width="10" height="10"/>
+ <rect x="150" y="10" width="10" height="10"/>
+ <rect x="160" y="10" width="10" height="10"/>
+ <rect x="170" y="10" width="10" height="10"/>
+ <rect x="180" y="10" width="10" height="10"/>
+ <rect x="10" y="20" width="10" height="10"/>
+ <rect x="40" y="20" width="10" height="10"/>
+ <rect x="60" y="20" width="10" height="10"/>
+ <rect x="80" y="20" width="10" height="10"/>
+ <rect x="100" y="20" width="10" height="10"/>
+ <rect x="120" y="20" width="10" height="10"/>
+ <rect x="140" y="20" width="10" height="10"/>
+ <rect x="160" y="20" width="10" height="10"/>
+ <rect x="180" y="20" width="10" height="10"/>
+ <rect x="10" y="30" width="10" height="10"/>
+ <rect x="20" y="30" width="10" height="10"/>
+ <rect x="30" y="30" width="10" height="10"/>
+ <rect x="40" y="30" width="10" height="10"/>
+ <rect x="60" y="30" width="10" height="10"/>
+ <rect x="80" y="30" width="10" height="10"/>
+ <rect x="100" y="30" width="10" height="10"/>
+ <rect x="120" y="30" width="10" height="10"/>
+ <rect x="140" y="30" width="10" height="10"/>
+ <rect x="150" y="30" width="10" height="10"/>
+ <rect x="160" y="30" width="10" height="10"/>
+ <rect x="180" y="30" width="10" height="10"/>
+ <rect x="10" y="40" width="10" height="10"/>
+ <rect x="20" y="40" width="10" height="10"/>
+ <rect x="30" y="40" width="10" height="10"/>
+ <rect x="40" y="40" width="10" height="10"/>
+ <rect x="60" y="40" width="10" height="10"/>
+ <rect x="80" y="40" width="10" height="10"/>
+ <rect x="100" y="40" width="10" height="10"/>
+ <rect x="120" y="40" width="10" height="10"/>
+ <rect x="140" y="40" width="10" height="10"/>
+ <rect x="150" y="40" width="10" height="10"/>
+ <rect x="160" y="40" width="10" height="10"/>
+ <rect x="180" y="40" width="10" height="10"/>
+ <rect x="10" y="50" width="10" height="10"/>
+ <rect x="40" y="50" width="10" height="10"/>
+ <rect x="60" y="50" width="10" height="10"/>
+ <rect x="80" y="50" width="10" height="10"/>
+ <rect x="100" y="50" width="10" height="10"/>
+ <rect x="120" y="50" width="10" height="10"/>
+ <rect x="140" y="50" width="10" height="10"/>
+ <rect x="160" y="50" width="10" height="10"/>
+ <rect x="180" y="50" width="10" height="10"/>
+ <rect x="10" y="60" width="10" height="10"/>
+ <rect x="20" y="60" width="10" height="10"/>
+ <rect x="30" y="60" width="10" height="10"/>
+ <rect x="40" y="60" width="10" height="10"/>
+ <rect x="50" y="60" width="10" height="10"/>
+ <rect x="60" y="60" width="10" height="10"/>
+ <rect x="70" y="60" width="10" height="10"/>
+ <rect x="80" y="60" width="10" height="10"/>
+ <rect x="90" y="60" width="10" height="10"/>
+ <rect x="100" y="60" width="10" height="10"/>
+ <rect x="110" y="60" width="10" height="10"/>
+ <rect x="120" y="60" width="10" height="10"/>
+ <rect x="130" y="60" width="10" height="10"/>
+ <rect x="140" y="60" width="10" height="10"/>
+ <rect x="150" y="60" width="10" height="10"/>
+ <rect x="160" y="60" width="10" height="10"/>
+ <rect x="170" y="60" width="10" height="10"/>
+ <rect x="180" y="60" width="10" height="10"/>
+ <rect x="40" y="70" width="10" height="10"/>
+ <rect x="80" y="70" width="10" height="10"/>
+ <rect x="120" y="70" width="10" height="10"/>
+ <rect x="160" y="70" width="10" height="10"/>
+ <rect x="10" y="80" width="10" height="10"/>
+ <rect x="20" y="80" width="10" height="10"/>
+ <rect x="30" y="80" width="10" height="10"/>
+ <rect x="40" y="80" width="10" height="10"/>
+ <rect x="50" y="80" width="10" height="10"/>
+ <rect x="60" y="80" width="10" height="10"/>
+ <rect x="70" y="80" width="10" height="10"/>
+ <rect x="80" y="80" width="10" height="10"/>
+ <rect x="90" y="80" width="10" height="10"/>
+ <rect x="100" y="80" width="10" height="10"/>
+ <rect x="110" y="80" width="10" height="10"/>
+ <rect x="120" y="80" width="10" height="10"/>
+ <rect x="130" y="80" width="10" height="10"/>
+ <rect x="140" y="80" width="10" height="10"/>
+ <rect x="150" y="80" width="10" height="10"/>
+ <rect x="160" y="80" width="10" height="10"/>
+ <rect x="170" y="80" width="10" height="10"/>
+ <rect x="180" y="80" width="10" height="10"/>
+ <rect x="20" y="90" width="10" height="10"/>
+ <rect x="40" y="90" width="10" height="10"/>
+ <rect x="60" y="90" width="10" height="10"/>
+ <rect x="80" y="90" width="10" height="10"/>
+ <rect x="100" y="90" width="10" height="10"/>
+ <rect x="120" y="90" width="10" height="10"/>
+ <rect x="140" y="90" width="10" height="10"/>
+ <rect x="160" y="90" width="10" height="10"/>
+ <rect x="180" y="90" width="10" height="10"/>
+ <rect x="10" y="100" width="10" height="10"/>
+ <rect x="20" y="100" width="10" height="10"/>
+ <rect x="30" y="100" width="10" height="10"/>
+ <rect x="40" y="100" width="10" height="10"/>
+ <rect x="60" y="100" width="10" height="10"/>
+ <rect x="80" y="100" width="10" height="10"/>
+ <rect x="100" y="100" width="10" height="10"/>
+ <rect x="120" y="100" width="10" height="10"/>
+ <rect x="140" y="100" width="10" height="10"/>
+ <rect x="150" y="100" width="10" height="10"/>
+ <rect x="160" y="100" width="10" height="10"/>
+ <rect x="180" y="100" width="10" height="10"/>
+ <rect x="10" y="110" width="10" height="10"/>
+ <rect x="40" y="110" width="10" height="10"/>
+ <rect x="60" y="110" width="10" height="10"/>
+ <rect x="80" y="110" width="10" height="10"/>
+ <rect x="100" y="110" width="10" height="10"/>
+ <rect x="120" y="110" width="10" height="10"/>
+ <rect x="140" y="110" width="10" height="10"/>
+ <rect x="160" y="110" width="10" height="10"/>
+ <rect x="180" y="110" width="10" height="10"/>
+ <rect x="10" y="120" width="10" height="10"/>
+ <rect x="20" y="120" width="10" height="10"/>
+ <rect x="30" y="120" width="10" height="10"/>
+ <rect x="40" y="120" width="10" height="10"/>
+ <rect x="60" y="120" width="10" height="10"/>
+ <rect x="80" y="120" width="10" height="10"/>
+ <rect x="100" y="120" width="10" height="10"/>
+ <rect x="120" y="120" width="10" height="10"/>
+ <rect x="140" y="120" width="10" height="10"/>
+ <rect x="150" y="120" width="10" height="10"/>
+ <rect x="160" y="120" width="10" height="10"/>
+ <rect x="180" y="120" width="10" height="10"/>
+ <rect x="10" y="130" width="10" height="10"/>
+ <rect x="20" y="130" width="10" height="10"/>
+ <rect x="30" y="130" width="10" height="10"/>
+ <rect x="40" y="130" width="10" height="10"/>
+ <rect x="60" y="130" width="10" height="10"/>
+ <rect x="80" y="130" width="10" height="10"/>
+ <rect x="100" y="130" width="10" height="10"/>
+ <rect x="120" y="130" width="10" height="10"/>
+ <rect x="140" y="130" width="10" height="10"/>
+ <rect x="150" y="130" width="10" height="10"/>
+ <rect x="160" y="130" width="10" height="10"/>
+ <rect x="180" y="130" width="10" height="10"/>
+ <rect x="10" y="140" width="10" height="10"/>
+ <rect x="40" y="140" width="10" height="10"/>
+ <rect x="60" y="140" width="10" height="10"/>
+ <rect x="80" y="140" width="10" height="10"/>
+ <rect x="100" y="140" width="10" height="10"/>
+ <rect x="120" y="140" width="10" height="10"/>
+ <rect x="140" y="140" width="10" height="10"/>
+ <rect x="160" y="140" width="10" height="10"/>
+ <rect x="180" y="140" width="10" height="10"/>
+ <rect x="10" y="150" width="10" height="10"/>
+ <rect x="20" y="150" width="10" height="10"/>
+ <rect x="30" y="150" width="10" height="10"/>
+ <rect x="40" y="150" width="10" height="10"/>
+ <rect x="50" y="150" width="10" height="10"/>
+ <rect x="60" y="150" width="10" height="10"/>
+ <rect x="70" y="150" width="10" height="10"/>
+ <rect x="80" y="150" width="10" height="10"/>
+ <rect x="90" y="150" width="10" height="10"/>
+ <rect x="100" y="150" width="10" height="10"/>
+ <rect x="110" y="150" width="10" height="10"/>
+ <rect x="120" y="150" width="10" height="10"/>
+ <rect x="130" y="150" width="10" height="10"/>
+ <rect x="140" y="150" width="10" height="10"/>
+ <rect x="150" y="150" width="10" height="10"/>
+ <rect x="160" y="150" width="10" height="10"/>
+ <rect x="170" y="150" width="10" height="10"/>
+ <rect x="180" y="150" width="10" height="10"/>
+ <rect x="40" y="160" width="10" height="10"/>
+ <rect x="80" y="160" width="10" height="10"/>
+ <rect x="120" y="160" width="10" height="10"/>
+ <rect x="160" y="160" width="10" height="10"/>
+ <rect x="10" y="170" width="10" height="10"/>
+ <rect x="20" y="170" width="10" height="10"/>
+ <rect x="30" y="170" width="10" height="10"/>
+ <rect x="40" y="170" width="10" height="10"/>
+ <rect x="50" y="170" width="10" height="10"/>
+ <rect x="60" y="170" width="10" height="10"/>
+ <rect x="70" y="170" width="10" height="10"/>
+ <rect x="80" y="170" width="10" height="10"/>
+ <rect x="90" y="170" width="10" height="10"/>
+ <rect x="100" y="170" width="10" height="10"/>
+ <rect x="110" y="170" width="10" height="10"/>
+ <rect x="120" y="170" width="10" height="10"/>
+ <rect x="130" y="170" width="10" height="10"/>
+ <rect x="140" y="170" width="10" height="10"/>
+ <rect x="150" y="170" width="10" height="10"/>
+ <rect x="160" y="170" width="10" height="10"/>
+ <rect x="170" y="170" width="10" height="10"/>
+ <rect x="180" y="170" width="10" height="10"/>
+ <rect x="10" y="180" width="10" height="10"/>
+ <rect x="40" y="180" width="10" height="10"/>
+ <rect x="60" y="180" width="10" height="10"/>
+ <rect x="80" y="180" width="10" height="10"/>
+ <rect x="100" y="180" width="10" height="10"/>
+ <rect x="120" y="180" width="10" height="10"/>
+ <rect x="140" y="180" width="10" height="10"/>
+ <rect x="160" y="180" width="10" height="10"/>
+ <rect x="180" y="180" width="10" height="10"/>
+ <rect x="60" y="190" width="10" height="10"/>
+ <rect x="100" y="190" width="10" height="10"/>
+ <rect x="140" y="190" width="10" height="10"/>
+ </g>
+ <text x="100" y="120" font-family="Arial" font-size="20" text-anchor="middle" fill="#000000">鏀粯浜岀淮鐮�</text>
+</svg>
\ No newline at end of file
diff --git a/app/static/images/tabbar/add.png b/app/static/images/tabbar/add.png
new file mode 100644
index 0000000..32ba169
--- /dev/null
+++ b/app/static/images/tabbar/add.png
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
+ <circle cx="12" cy="12" r="10" fill="#000000"/>
+ <path d="M12,7L12,17M7,12L17,12" stroke="white" stroke-width="2"/>
+</svg>
\ No newline at end of file
diff --git a/app/static/images/tabbar/add_.png b/app/static/images/tabbar/add_.png
new file mode 100644
index 0000000..d365396
--- /dev/null
+++ b/app/static/images/tabbar/add_.png
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
+ <circle cx="12" cy="12" r="10" fill="#007AFF"/>
+ <path d="M12,7L12,17M7,12L17,12" stroke="white" stroke-width="2"/>
+</svg>
\ No newline at end of file
diff --git a/app/static/images/tabbar/message.png b/app/static/images/tabbar/message.png
new file mode 100644
index 0000000..f415695
--- /dev/null
+++ b/app/static/images/tabbar/message.png
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M20,2H4A2,2 0 0,0 2,4V22L6,18H20A2,2 0 0,0 22,16V4A2,2 0 0,0 20,2M6,9H18V11H6M14,14H6V12H14M18,8H6V6H18" fill="#000000"/>
+</svg>
\ No newline at end of file
diff --git a/app/static/images/tabbar/message_.png b/app/static/images/tabbar/message_.png
new file mode 100644
index 0000000..5b214f7
--- /dev/null
+++ b/app/static/images/tabbar/message_.png
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M20,2H4A2,2 0 0,0 2,4V22L6,18H20A2,2 0 0,0 22,16V4A2,2 0 0,0 20,2M6,9H18V11H6M14,14H6V12H14M18,8H6V6H18" fill="#007AFF"/>
+</svg>
\ No newline at end of file
diff --git a/app/static/images/tabbar/task.png b/app/static/images/tabbar/task.png
new file mode 100644
index 0000000..6a07192
--- /dev/null
+++ b/app/static/images/tabbar/task.png
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z" fill="#000000"/>
+</svg>
\ No newline at end of file
diff --git a/app/static/images/tabbar/task_.png b/app/static/images/tabbar/task_.png
new file mode 100644
index 0000000..7b50c5e
--- /dev/null
+++ b/app/static/images/tabbar/task_.png
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z" fill="#007AFF"/>
+</svg>
\ No newline at end of file
diff --git a/app/static/images/wechat.png b/app/static/images/wechat.png
new file mode 100644
index 0000000..c2f9288
--- /dev/null
+++ b/app/static/images/wechat.png
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
+ <rect width="24" height="24" fill="#07c160" rx="4"/>
+ <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm4.5 14.5c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm-9 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm9.5-5.5c-.55 0-1-.45-1-1 0-.55.45-1 1-1s1 .45 1 1-.45 1-1 1zm-10 0c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1z" fill="white"/>
+</svg>
\ No newline at end of file
diff --git a/app/static/scss/global.scss b/app/static/scss/global.scss
index ac636bd..bf4092c 100644
--- a/app/static/scss/global.scss
+++ b/app/static/scss/global.scss
@@ -21,6 +21,37 @@
color: #aaa;
}
+// 闅愯棌婊氬姩鏉′絾淇濇寔婊氬姩鍔熻兘
+::-webkit-scrollbar {
+ display: none;
+ width: 0 !important;
+ height: 0 !important;
+ background: transparent;
+}
+
+// Firefox婊氬姩鏉¢殣钘�
+* {
+ scrollbar-width: none; /* Firefox */
+}
+
+// IE/Edge婊氬姩鏉¢殣钘�
+* {
+ -ms-overflow-style: none; /* IE 10+ */
+}
+
+// 鍏ㄥ眬闅愯棌婊氬姩鏉℃牱寮�
+scroll-view::-webkit-scrollbar {
+ display: none;
+ width: 0 !important;
+ height: 0 !important;
+ background: transparent;
+}
+
+scroll-view {
+ scrollbar-width: none; /* Firefox */
+ -ms-overflow-style: none; /* IE 10+ */
+}
+
.list-cell-arrow::before {
content: ' ';
height: 10px;
@@ -87,4 +118,4 @@
color: #999;
}
}
- }
+ }
\ No newline at end of file
diff --git a/app/store/modules/user.js b/app/store/modules/user.js
index c1ec441..79e8b98 100644
--- a/app/store/modules/user.js
+++ b/app/store/modules/user.js
@@ -2,6 +2,7 @@
import storage from '@/utils/storage'
import constant from '@/utils/constant'
import { login, logout, getInfo } from '@/api/login'
+import { wechatLogin } from '@/api/wechat'
import { getToken, setToken, removeToken } from '@/utils/auth'
const baseUrl = config.baseUrl
@@ -55,6 +56,19 @@
})
},
+ // 寰俊鐧诲綍
+ WechatLogin({ commit }, wechatData) {
+ return new Promise((resolve, reject) => {
+ wechatLogin(wechatData).then(res => {
+ setToken(res.token)
+ commit('SET_TOKEN', res.token)
+ resolve()
+ }).catch(error => {
+ reject(error)
+ })
+ })
+ },
+
// 鑾峰彇鐢ㄦ埛淇℃伅
GetInfo({ commit, state }) {
return new Promise((resolve, reject) => {
@@ -95,4 +109,4 @@
}
}
-export default user
+export default user
\ No newline at end of file
--
Gitblit v1.9.1