| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372 |
- <template>
- <view class="nav-container">
- <!-- 快捷功能 -->
- <view class="quick-functions-box">
- <view class="qfn-header">
- <text class="qfn-title">常用功能</text>
- <view class="qfn-actions">
- <u-icon name="edit-pen" size="36" color="#999" @click="toggleDelMode" v-if="!isDelMode"></u-icon>
- <text class="qfn-done" @click="toggleDelMode" v-if="isDelMode">完成</text>
- <u-icon name="plus" size="36" color="#999" style="margin-left:16rpx" @click="openAddPopup"></u-icon>
- </view>
- </view>
- <scroll-view scroll-x class="qfn-scroll" v-if="quickFunctions.length">
- <view class="qfn-item" v-for="(it, i) in quickFunctions" :key="it.id || i" @click="handleQuick(it, i)">
- <view class="qfn-icon" :class="isDelMode ? 'qfn-del' : ''">
- <!-- <u-icon :name="it.icon||'grid'" size="44" color="#157A2C"></u-icon> -->
- <span :class="'iconfont ' + it.icon"></span>
- </view>
- <text class="qfn-name">{{ it.name }}</text>
- <u-icon v-if="isDelMode" name="minus-circle-fill" size="32" color="#ff4949"
- class="qfn-badge"></u-icon>
- </view>
- </scroll-view>
- <view class="qfn-empty" v-else @click="openAddPopup">
- <u-icon name="plus-circle" size="40" color="#ccc"></u-icon>
- <text class="qfn-empty-tip">添加常用功能</text>
- </view>
- </view>
- <!-- 原有导航 -->
- <view class="nav">
- <view class="nav-item" v-for="(item, index) in workList" @click="toNav(item.link_url)">
- <span :class="item.class"></span>
- <i class="badge" v-if="item.badge">{{ item.badge }}</i>
- <label>{{ item.title }}</label>
- </view>
- </view>
- <!-- 选择菜单弹窗 -->
- <u-popup :show="showAddPopup" mode="bottom" :round="16" @close="showAddPopup = false" closeable>
- <view class="add-popup">
- <view class="add-popup-head">选择菜单</view>
- <scroll-view scroll-y class="add-popup-body">
- <view class="add-popup-row" v-for="(m, index) in availableMenus" :key="m.id" @click="addQuick(m, index)">
- <view class="add-popup-left">
- <text class="add-popup-name">{{ m.name }}</text>
- </view>
- <u-icon v-if="checkedIds[m.id]" name="checkbox-mark" size="36" color="#157A2C"></u-icon>
- <u-icon v-else name="plus-circle" size="36" color="#ccc"></u-icon>
- </view>
- <view v-if="!availableMenus.length" class="add-popup-none">暂无菜单</view>
- </scroll-view>
- </view>
- </u-popup>
- <u-toast ref="uToast"></u-toast>
- </view>
- </template>
- <script>
- import { todoNuber } from '@/api/myTicket'
- import { userResourceListAPI, userResourceSaveAPI, userResourceDeleteAPI } from '@/api/home'
- export default {
- props: { workOrder: { default: {} } },
- data() {
- return {
- workList: [
- { class: 'iconfont icon-bianji', title: '工单待办', link_url: '/pages/home/myTicket/myTicket?orderType=1', badge: 0 },
- { class: 'iconfont icon-bianji', title: '工单已办', link_url: '/pages/home/myTicket/myTicket?orderType=2', badge: 0 },
- { class: 'iconfont icon-kuneipandian', title: '已发流程', link_url: '/pages/home/wt/send/send', badge: 0 },
- { class: 'iconfont icon-kuneipandian', title: '流程待办', link_url: '/pages/home/wt/todo/todo', badge: 0 },
- { class: 'iconfont icon-kuneipandian', title: '流程已办', link_url: '/pages/home/wt/done/done' }
- ],
- quickFunctions: [],
- isDelMode: false,
- showAddPopup: false,
- availableMenus: [],
- }
- },
- watch: {
- workOrder: { handler(v) { this.workList[0].badge = v.total }, deep: true }
- },
- computed: {
- // 已勾选的菜单 resourceId 映射(resourceId 即菜单 tree 中的 id)
- checkedIds: function() {
- var map = {}
- var qf = this.quickFunctions || []
- for (var i = 0; i < qf.length; i++) {
- map[qf[i].resourceId] = true
- }
- return map
- }
- },
- created() {
- this.gettodoNuber()
- this.loadQuick()
- this.loadMenus()
- },
- methods: {
- toNav(url) { uni.navigateTo({ url }) },
- gettodoNuber() { todoNuber().then(r => { this.workList[3].badge = r.count }) },
- // ===== 快捷功能 =====
- async loadQuick() {
- try { this.quickFunctions = await userResourceListAPI() } catch (e) {}
- },
- loadMenus() {
- try {
- var raw = uni.getStorageSync('treeList')
- if (!raw) { this.availableMenus = []; return }
- var tree = typeof raw === 'string' ? JSON.parse(raw) : raw
- if (Array.isArray(tree) && tree.length === 1 && tree[0].children) {
- tree = tree[0].children
- }
- var arr = []
- var walk = function (list) {
- (list || []).forEach(function (it) {
- if (it.menuType === 2) return
- if (it.path && it.path.indexOf('/pages/') === 0) {
- arr.push({ id: it.id, name: it.name || it.title || '', url: it.path, icon: it.icon || 'grid' })
- }
- if (it.children && it.children.length) { walk(it.children) }
- })
- }
- walk(tree)
- this.availableMenus = arr
- } catch (e) { this.availableMenus = [] }
- },
- toggleDelMode() { this.isDelMode = !this.isDelMode },
- openAddPopup() {
- console.log('availableMenus~~', this.availableMenus)
- if (!this.availableMenus.length) this.loadMenus()
- this.showAddPopup = true
- },
- async addQuick(m, i) {
- // m.id = menu tree ID, quickFunctions[] 中对应 resourceId
- if (this.checkedIds[m.id]) {
- // 找到对应的用户资源记录 ID 来删除
- var found = this.quickFunctions.find(function(it) { return String(it.resourceId) === String(m.id) })
- if (found) {
- await userResourceDeleteAPI([found.id])
- }
- this.quickFunctions = this.quickFunctions.filter(function(it) { return String(it.resourceId) !== String(m.id) })
- } else {
- if (this.quickFunctions.length >= 12) return uni.showToast({ title: '最多12个', icon: 'none' })
- await userResourceSaveAPI({ icon: '', pic: '', resourceId: m.id, sort: i, useScope: 2 })
- // 保存后重新拉取列表,确保拿到服务端返回的 record id
- await this.loadQuick()
- }
- },
- async handleQuick(it, i) {
- if (this.isDelMode) {
- await userResourceDeleteAPI([it.id])
- this.quickFunctions.splice(i, 1)
- return
- }
- if (it.url) { uni.navigateTo({ url: it.url }) }
- },
- }
- }
- </script>
- <style lang="scss" scoped>
- /* 快捷功能 */
- .quick-functions-box {
- background: #fff;
- border-radius: 16rpx;
- margin-bottom: 16rpx;
- padding: 20rpx;
- }
- .qfn-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 16rpx;
- }
- .qfn-title {
- font-size: 28rpx;
- font-weight: bold;
- color: #333;
- }
- .qfn-actions {
- display: flex;
- align-items: center;
- }
- .qfn-done {
- font-size: 26rpx;
- color: #ff4949;
- padding: 4rpx 16rpx;
- }
- .qfn-scroll {
- white-space: nowrap;
- width: 100%;
- }
- .qfn-item {
- display: inline-flex;
- flex-direction: column;
- align-items: center;
- width: 140rpx;
- margin-right: 20rpx;
- position: relative;
- }
- .qfn-item:last-child {
- margin-right: 0;
- }
- .qfn-icon {
- width: 88rpx;
- height: 88rpx;
- border-radius: 50%;
- background: #f5f7fa;
- display: flex;
- align-items: center;
- justify-content: center;
- margin-bottom: 10rpx;
- box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, .06);
- }
- .qfn-icon span {
- font-size: 44rpx;
- color: #157A2C;
- }
- .qfn-del {
- border: 2rpx dashed #ff4949;
- }
- .qfn-name {
- font-size: 26rpx;
- color: #333;
- text-align: center;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- width: 100%;
- }
- .qfn-badge {
- position: absolute;
- top: -4rpx;
- right: -4rpx;
- }
- .qfn-empty {
- display: flex;
- flex-direction: column;
- align-items: center;
- padding: 30rpx 0;
- }
- .qfn-empty-tip {
- font-size: 24rpx;
- color: #ccc;
- margin-top: 10rpx;
- }
- /* 弹窗 */
- .add-popup {
- height: 60vh;
- padding: 30rpx;
- display: flex;
- flex-direction: column;
- }
- .add-popup-head {
- font-size: 30rpx;
- font-weight: bold;
- color: #333;
- text-align: center;
- margin-bottom: 20rpx;
- }
- .add-popup-body {
- flex: 1;
- min-height: 0;
- }
- .add-popup-row {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 24rpx 0;
- border-bottom: 1rpx solid #f0f0f0;
- }
- .add-popup-left {
- display: flex;
- align-items: center;
- flex: 1;
- }
- .add-popup-name {
- font-size: 28rpx;
- color: #333;
- margin-left: 20rpx;
- }
- .add-popup-none {
- text-align: center;
- padding: 60rpx 0;
- color: #999;
- font-size: 28rpx;
- }
- /* 原有导航 */
- .nav {
- display: flex;
- width: 100%;
- padding: 32rpx 0;
- margin-bottom: 24rpx;
- align-items: center;
- justify-content: space-around;
- background-color: #fff;
- font-size: $uni-font-size-sm;
- color: $uni-text-color;
- border-radius: 16rpx;
- }
- .nav-item {
- position: relative;
- display: flex;
- flex-direction: column;
- align-items: center;
- margin-top: 5rpx;
- flex: 1;
- }
- .nav-item span {
- padding: 18rpx;
- color: #fff;
- margin-bottom: 14rpx;
- border-radius: 50%;
- }
- .badge {
- position: absolute;
- top: -8rpx;
- left: 100rpx;
- font-size: 24rpx;
- padding: 0 10rpx;
- border-radius: 38rpx;
- background: #ff4949;
- color: #fff;
- font-style: normal;
- }
- .nav-item:nth-child(1) span {
- background-color: $uni-color-success;
- }
- .nav-item:nth-child(2) span {
- background-color: $uni-color-warning;
- }
- .nav-item:nth-child(3) span {
- background-color: $uni-color-primary;
- }
- .nav-item:nth-child(4) span {
- background-color: $uni-color-error;
- }
- .nav-item:nth-child(5) span {
- background-color: $uni-color-success;
- }
- </style>
|