Browse Source

Merge branch 'wrr' of dd.tall.wiki:wally/TALL-MUI-3 into wrr

tall
wally 4 years ago
parent
commit
e2d9faeb45
  1. 12
      CHANGELOG.md
  2. 4
      src/apis/plugin.js
  3. 25
      src/common/styles/iconfont+.scss
  4. 257
      src/common/styles/iconfont.css
  5. BIN
      src/common/styles/iconfont.ttf
  6. 18
      src/components/Globals/Globals.vue
  7. 54
      src/components/Plugin/Plugin.vue
  8. 4
      src/components/Roles/Roles.vue
  9. 224
      src/components/Roles/component/RoleList.vue
  10. 32
      src/components/TimeLine/TimeLine.vue
  11. 84
      src/components/TimeLine/component/TimeBox.vue
  12. 86
      src/components/TimeLine/component/TimeStatus.vue
  13. 39
      src/components/Title/Title.vue
  14. 1
      src/config/app.js
  15. 17
      src/config/time.js
  16. 4
      src/main.js
  17. 14
      src/mock/mock.js
  18. 7
      src/pages.json
  19. 136
      src/pages/project/project.vue
  20. 35
      src/store/home/mutations.js
  21. 33
      src/store/home/state.js
  22. 3
      src/store/messages/mutations.js
  23. 5
      src/store/user/mutations.js
  24. 1
      src/utils/request.js
  25. 2
      src/utils/tall.js
  26. 17
      src/utils/time.js
  27. 56
      src/utils/ui.js
  28. 2
      vue.config.js

12
CHANGELOG.md

@ -1,20 +1,25 @@
# 0.1.0 (2021-07-22)
# 0.1.0 (2021-07-26)
### 🌟 新功能
范围|描述|commitId
--|--|--
- | 标题栏变化 | [3898cfe](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/3898cfe)
- | 标题栏变化 | [c0fcd9d](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/c0fcd9d)
- | 标题栏角色栏全局任务组件新建 | [0500cb4](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/0500cb4)
- | 插件数据获取 | [5b91bdc](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/5b91bdc)
- | 存token | [b8a178d](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/b8a178d)
- | 定期任务面板骨架屏添加 | [b2698c0](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/b2698c0)
- | 角色栏实现 | [94cd671](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/94cd671)
- | 模拟接口测试 | [69e7931](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/69e7931)
- | 配置默认插件接口 | [f0c177d](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/f0c177d)
- | 全局插件及默认插件位置修改 | [6c80d08](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/6c80d08)
- | 时间基准线,默认插件 | [a33ba1e](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/a33ba1e)
- | 时间轴界面 | [33927e9](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/33927e9)
- | 时间轴修改状态时提示框增加 | [e841392](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/e841392)
- | 提交到本地 | [9cbe411](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/9cbe411)
- | 添加时间轴上下滚动 | [2b81bbc](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/2b81bbc)
- | 引入dayjs | [29b8b93](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/29b8b93)
- | 字体大小更改 | [82cfdd4](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/82cfdd4)
- | db store | [6414c4f](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/6414c4f)
- | indexedDB | [687394e](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/687394e)
- | post 封装 | [da52e94](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/da52e94)
@ -46,11 +51,14 @@
- | 定期任务接口 | [aa4981c](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/aa4981c)
- | 骨架屏替换 | [e9fdd71](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/e9fdd71)
- | 角色栏修改 | [19228d6](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/19228d6)
- | 解决时间轴报错 | [da1eece](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/da1eece)
- | 上下滚动时间轴 | [d533a01](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/d533a01)
- | 上下滑动加载定期任务 | [4090d89](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/4090d89)
- | 时间轴插件 | [225d3cc](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/225d3cc)
- | 时间轴上下滚动数据加载bug修改 | [e82ede4](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/e82ede4)
- | 时间轴上下滑动 | [4d0ae46](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/4d0ae46)
- | 提示信息显示bug及日常任务收缩问题 | [f2f06c5](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/f2f06c5)
- | 下拉加载定期任务传参,时间格式化修改 | [0b95a0e](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/0b95a0e)
- | 修改角色栏组件 | [a54c601](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/a54c601)
- | 修改main | [749ae9a](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/749ae9a)
@ -65,6 +73,7 @@
范围|描述|commitId
--|--|--
- | 下滑时间轴添加备注 | [4fd20e3](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/4fd20e3)
- | project 代码健壮性完善 | [a3202c5](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/a3202c5)
template | eslint prettier sass uview tailwindcss | [9c966a1](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/9c966a1)
@ -72,6 +81,7 @@
范围|描述|commitId
--|--|--
- | 测试接口 | [215e074](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/215e074)
- | 插件查询及展示 | [4dba770](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/4dba770)
- | 角色栏文字颜色修改 | [215c6b3](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/215c6b3)
- | 解决警告 | [c932b09](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/c932b09)
- | 组件文件夹新建 | [22bfe7b](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/22bfe7b)

4
src/apis/plugin.js

@ -1,9 +1,11 @@
const apiUrl = process.env.VUE_APP_API_URL;
const mock = `${apiUrl}/defaultwbs`;
const plugin = `${apiUrl}/pluginshop/plugin`;
const install = (Vue, vm) => {
vm.$u.api = { ...vm.$u.api } || {};
vm.$u.api.getPlugin = param => vm.$u.post(`${mock}/plugin`, { param });
vm.$u.api.getPlugin = param => vm.$u.post(`${mock}/plugin`, param);
vm.$u.api.getOtherPlugin = param => vm.$u.post(`${plugin}/query`, param);
};
export default { install };

25
src/common/styles/iconfont+.scss

@ -1,25 +0,0 @@
@font-face {
font-family: 'custom-icon'; /* Project id 2685595 */
src: url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAVsAAsAAAAACgAAAAUfAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHFQGYACDHAqGfIV2ATYCJAMQCwoABCAFhQsHURurCMiuMYUxPrWYbZJ11AENNuDWinu9B3343wTPy36/c+WrJmkq4NUbnswqIdo6oyVCh0pjZM3kN/Sb+9vabmY0s5OZwYtCdsO5QNnpi6ia8CLyL4qgGGt7b54+glfxrBKtmXWGqFaCp0B7SiATEr1ANPXvGzvOkmQsS994MvzlXijX3tRv70+uPsD5P2a6+rgS+DYAiUqMLBrYLNryeeZlUwrdgcsp3zK86iB34z4IiBvJJR7XVDYCxyMKmYEvKb1YEAXLkZ6hgJKT8gqiiArC0K2pSryAEPRW3AB48n5e/iSGEiqUpF9oa4fQglNvlF+/krv/O0w+Mra/NDxdQQgY6M1MLnvV2nOSwNYjES+ySM0BlCVK0Wvbz9vn/6foq+JGjX95YJRAMnRukoAZju0YzSLB8HWdBMXXc/oJcJ3MjoIIpAsgJwhUvkUYmwyUFcbgMUNP8NZs7bxRHjnzp3oxW69OvXx796hdkdpN5y5Ebxkdwyy0i/vNo9wbK1Xk1tF54gvn5PfeNWr37ctTr8YwJ4XR/NAFC9xLZaNP2FbujgGf9ZwyD3DnQc33oheKon7aLHNKrdlOcW+0bV5gW7ibN8+jySFrJfPtigKKzb6vTcXsU1BaIFpe6HwCu/HkmhO2hddjq6Os03jJqjnAq0/wSUKsCLT6KWyVajV+esn9acKTJM832i45UpN9vEPRUT/rJt1Vl7sTtltjd1k1fPmx0O7qFsi9o/lcd+Piclq/x9+580euFfJOCmlCHm/aHdDEN/PVN2zf9aPirdu0KH7P0SfDgoYGPQFri6pmqOdydenxe+I+WE4sH5ScnFTZJ+RLfZZHvhxl+quLBcFV4bqiUqj8l3pCPinq2zdJobhZQax0/jn2f2PJLqEkFUKCDGdd67Hz6D/QX4mH+54XSbEkO1wwcsrateiYAnm2zJj4XzyIP9iZJnPb2yQxR7jJ0iyxJGZOZNQb5edFksqISkmx1C8hrsyzYxI92fKrJEUZRVVE8EfIvDkhSo+Dj/vvmGKPBEm+ISJUYzGXqGI63CfMLYviAmXcHlXBldMNmsSZESsm7p81fsPwjGLxrMnDPa52Cvf9K/u+bBkq9nogPMTf6hWWem4in+r5+O+msp5NnqCxc74uZw8BPnaYGyL7iGpFM6qiCGYIzm4BL6ccX5slzxpOHy1i2UhUcchS+VJUpKlS3BzxfVT8lW8BEVPoJtfHVEeU/vg2X8xlNFB4xED/XyMHq8EtAARbEjtvdvYsqQWCpGk26h+cxt/IEQ39nbL/c1x/46efq5IwYTz+IRqY+sd54MMBnGyKATz1lKgWBcCVmPYRGLYoiBsK+MVckPekD2HhPTpEQiGCKqIGTUId6WCEDIFlZBiswbiuOkpvs4eRkFQeNMzEUJTthyrtDZqy+0gHXxEhbMiQYeAH4w4i4biERkws4iCFoBZrGYzpadasM6MQ3WlBrAnXOtdDptNIcUJ6aG6GnEWPS7EEdXyBswSaIdfdCksXk4iQDtNxrAnT9HsxaDSyWDvHtkEaqVsRas+Mi9MVvYmaZk2gCAeiIJAWpsVgGD0ay0znHEJonSwQlgle8XvqQYxORhSuOo8CSzOI47h6MhhMArV4GLKEa4ZmneEqiy6MRAiig1lcrp0eo5mzGjIaNhamvXhSG4iGqLW2sLTLFEcK6aBc9bh80wWvAeL0m3okIhmpSIuvI0TRrSZoRvYm1gwH06zRuOFr7IrwlkFGnIPazkEAAAA=')
format('woff2');
}
.custom-icon {
font-family: 'custom-icon' !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.custom-icon-attachment:before {
content: '\e7e1';
}
.custom-icon-moneycollect:before {
content: '\e7cd';
}
.custom-icon-C-bxl-redux:before {
content: '\e608';
}

257
src/common/styles/iconfont.css

File diff suppressed because one or more lines are too long

BIN
src/common/styles/iconfont.ttf

Binary file not shown.

18
src/components/Globals/Globals.vue

@ -3,14 +3,14 @@
<u-card :show-foot="false" :show-head="false" :style="{ height: isShrink ? '96rpx' : '300rpx' }" border-radius="25" margin="0">
<view slot="body">
<scroll-view :scrollY="true" :style="{ height: isShrink ? '40rpx' : '240rpx' }">
<skeleton :banner="false" :loading="loading" :row="4" animate class="mt-2 u-line-2 skeleton"></skeleton>
<skeleton :banner="false" :loading="!plugins.length" :row="4" animate class="mt-2 u-line-2 skeleton"></skeleton>
<view class="p-0 u-col-between">
<view class="grid grid-cols-3 gap-2 h-36" v-if="plugins.length">
<view class="grid grid-cols-3 gap-2 h-auto" v-if="plugins.length">
<Plugin
:class="getClass(plugin.col, plugin.row)"
:class="getClass(plugin.colspan, plugin.rowspan)"
:key="pluginIndex"
:pluginId="pluginId"
:styleType="styleType"
:pluginId="plugin.pluginId"
:styleType="plugin.styleType || 0"
v-for="(plugin, pluginIndex) in plugins"
/>
</view>
@ -31,16 +31,16 @@ export default {
props: { plugins: { type: Array, default: () => [] } },
data() {
return {
loading: true,
// loading: true,
pluginId: 0,
styleType: 0,
task: null,
};
},
mounted() {
setTimeout(() => (this.loading = false), 2000);
},
// mounted() {
// setTimeout(() => (this.loading = false), 2000);
// },
computed: mapState('home', ['isShrink']),
methods: {
getClass(col, row) {

54
src/components/Plugin/Plugin.vue

@ -1,28 +1,64 @@
<template>
<view v-if="pluginContent && pluginContent.html" style="height: 100%">
<!-- <view> {{ pluginContent.html }} </view> -->
<view v-html="pluginContent.html" style="height: 100%"> </view>
<!-- <u-parse :html="pluginContent.html" ref="ht-box"></u-parse> -->
<view class="u-font-14">
<view style="height: 100%" v-if="pluginContent">
<view v-if="pluginContent.html">
<view style="height: 100%" v-html="pluginContent.html"></view>
</view>
<view v-else>
<view v-if="item && item.name">
<p-task-title :item="item" v-if="pluginId === '1'" />
<p-task-description :item="item" v-if="pluginId === '2'" />
<p-task-duration-delay :item="item" v-if="pluginId === '3'" />
<p-task-start-time-delay :item="item" v-if="pluginId === '4'" />
<p-deliverable :item="item" v-if="pluginId === '5'" />
<p-subtasks :item="item" v-if="pluginId === '6'" />
<p-subproject :item="item" v-if="pluginId === '7'" />
<p-task-countdown :item="item" v-if="pluginId === '8'" />
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'Plugin',
props: {
item: {
default: () => {},
type: Object,
},
pluginId: {
default: '0',
type: String,
},
styleType: {
default: 0,
type: Number,
},
},
data() {
return { pluginContent: null };
},
async mounted() {
async created() {
await this.getPlugin();
console.log(this.pluginContent.js);
if (this.pluginContent.js) {
var scriptDom = document.createElement('script');
scriptDom.id = `p${this.pluginContent.pluginId}`;
scriptDom.innerHTML = this.pluginContent.js;
document.body.append(scriptDom);
}
},
methods: {
async getPlugin() {
const res = await this.$u.api.getPlugin({
pluginId: 0,
styleType: 0,
const { pluginId, styleType } = this;
const res = await this.$u.api.getOtherPlugin({
pluginId,
styleType,
});
this.$emit('changeLoading', false);
this.pluginContent = res;
console.log(this.pluginContent);
},
},
};

4
src/components/Roles/Roles.vue

@ -4,7 +4,7 @@
<scroll-view :enable-flex="true" :scroll-left="scrollLeft" :throttle="false" scroll-with-animation scroll-x>
<view class="tab-box">
<view :key="index" @click="changeIndex(item.id, index)" class="tab-item" v-for="(item, index) in roles">
<view :class="setColor(item.mine, item.id)" class="tab-children u-skeleton-fillet">{{ item.name }}</view>
<view :class="setColor(item.mine, item.id)" class="tab-children u-skeleton-fillet u-font-14">{{ item.name }}</view>
</view>
</view>
</scroll-view>
@ -93,7 +93,7 @@ export default {
//index
this.setCurrentRole(index);
//
this.setTasks([]);
this.setTasks();
//
await this.$emit('getTasksByRole');
} catch (error) {

224
src/components/Roles/component/RoleList.vue

@ -1,224 +0,0 @@
<template>
<view>
<view class="home-box u-skeleton">
<scroll-view :enable-flex="true" :scroll-left="scrollLeft" :throttle="false" scroll-with-animation scroll-x>
<view class="tab-box">
<view :key="index" @click="changeIndex(item.id, index)" class="tab-item" v-for="(item, index) in roles">
<view :class="setColor(item.mine, item.id)" class="tab-children u-skeleton-fillet">{{ item.name }}</view>
</view>
</view>
</scroll-view>
</view>
<u-skeleton :animation="true" :loading="loading" bg-color="#fff"></u-skeleton>
</view>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex';
export default {
name: 'RoleList',
data() {
return {
tabIndex: 0, //访 index 0
tabList: [], //tab dom
scrollLeft: 0, //scrollview
loading: false, //
roles: [
{
id: 1,
name: '项目经理',
mine: 0,
pm: 1,
sequence: 1,
},
{
id: 2,
name: '运维',
mine: 0,
pm: 0,
sequence: 2,
},
],
};
},
computed: { ...mapState('home', ['visibleRoles', 'roleId', 'tasks']) },
watch: {
visibleRoles(val) {
if (val && val.length) {
this.roles = [...this.visibleRoles];
this.loading = false;
}
},
},
mounted() {
if (!this.visibleRoles || !this.visibleRoles.length) {
this.loading = true;
}
},
methods: {
...mapMutations('home', ['setRoleId']),
...mapActions('home', ['handleRegularTask']),
setCurrentRole(index) {
const data = document.getElementsByClassName('tab-children');
// tabList
data.forEach(item => {
this.tabList.push({
width: item.clientWidth,
left: item.offsetLeft,
});
});
//
let left = 0;
let screenWidth = window.screen.width;
for (let i = 0; i < index; i++) {
left += this.tabList[i].width + this.tabList[i].left * 2;
}
left += this.tabList[index].width;
this.scrollLeft = left - screenWidth / 2;
},
async changeIndex(id, index) {
this.setRoleId(id);
//index
this.setCurrentRole(index);
//
await this.$emit('getTasks', { queryType: 0 });
await this.$emit('getTasks', { queryType: 1 });
console.log('this.tasks && this.tasks.length: ', this.tasks && this.tasks.length);
if (this.tasks && this.tasks.length) {
//
const upQuery = {
timeNode: +this.tasks[0].planStart,
queryType: 0,
queryNum: 6,
};
console.log('upQuery: ', upQuery);
await this.$emit('getTasks', upQuery);
const downQuery = {
timeNode: +this.tasks[this.tasks.length - 1].planStart,
queryType: 0,
queryNum: 6,
};
console.log('downQuery: ', downQuery);
await this.$emit('getTasks', downQuery);
}
},
//
setColor(mine, id) {
const { roleId } = this;
if (mine === '1' && roleId === id) {
return 'default-tab-choice';
}
if (mine === '1' && roleId !== id) {
return 'default-tab-item';
}
if (mine === '0' && roleId === id) {
return 'tab-choice';
}
},
},
};
</script>
<style lang="scss" scoped>
.home-box {
// sticky
position: sticky;
top: 0;
background: #fff; //
/* #ifdef H5 */
// h5 44px
top: 88rpx;
/* #endif */
.tab-box {
position: relative;
white-space: nowrap;
// height: 84rpx;
.tab-item {
// width: 20%;
// height: 84rpx;
padding: 20rpx 24rpx;
position: relative;
display: inline-block;
text-align: center;
font-size: 30rpx;
transition-property: background-color, width;
}
.default-tab-item {
color: $roleChoiceColor;
}
.default-tab-choice {
//
position: relative;
color: $roleChoiceColor;
font-weight: 600;
}
.default-tab-choice:before {
content: '';
position: absolute;
left: 0;
bottom: -20rpx;
width: 100%;
height: 6rpx;
border-radius: 2rpx;
background: $roleChoiceColor;
}
.tab-choice {
//
position: relative;
color: $uni-color-primary;
font-weight: 600;
}
.tab-choice:before {
content: '';
position: absolute;
left: 0;
bottom: -20rpx;
width: 100%;
height: 6rpx;
border-radius: 2rpx;
background: $uni-color-primary;
}
}
}
// //
/* #ifndef APP-NVUE */
::-webkit-scrollbar,
::-webkit-scrollbar,
::-webkit-scrollbar {
display: none;
width: 0 !important;
height: 0 !important;
-webkit-appearance: none;
background: transparent;
}
/* #endif */
/* #ifdef H5 */
// 穿H5scroll-view
scroll-view ::v-deep ::-webkit-scrollbar {
display: none;
}
/* #endif */
.skeleton {
height: 44rpx;
}
</style>

32
src/components/TimeLine/TimeLine.vue

@ -1,10 +1,3 @@
<!--
* @Author: aBin
* @email: binbin0314@126.com
* @Date: 2021-07-19 14:15:35
* @LastEditors: aBin
* @LastEditTime: 2021-07-20 14:22:11
-->
<template>
<!-- 时间间隔栏 -->
<!-- <Barrier /> -->
@ -20,9 +13,9 @@
id="scroll"
>
<!-- 时间轴 -->
<u-divider bg-color="#f3f4f6" v-if="topEnd">到顶啦</u-divider>
<u-divider bg-color="#f3f4f6" class="pt-5" fontSize="14px" v-if="topEnd">到顶啦</u-divider>
<TimeBox />
<u-divider bg-color="#f3f4f6" v-if="bottomEnd">到底啦</u-divider>
<u-divider bg-color="#f3f4f6" class="pb-5" fontSize="14px" v-if="bottomEnd">到底啦</u-divider>
</scroll-view>
</template>
@ -30,6 +23,7 @@
// import Barrier from './component/Barrier.vue';
import { mapState, mapMutations } from 'vuex';
import TimeBox from './component/TimeBox.vue';
export default {
name: 'TimeLine',
components: { TimeBox },
@ -67,13 +61,14 @@ export default {
//
async handleScrollBottom() {
if (this.bottomEnd) return;
// TODO: =+
// =+
const cycle = this.$t.time.computeCycle('天');
const timeNode = this.$t.time.add(+this.tasks[this.tasks.length - 1].planStart, 1, cycle).valueOf();
const downQuery = {
timeNode: +this.tasks[this.tasks.length - 1].planStart,
timeNode,
queryType: 1,
queryNum: 6,
};
console.log('downQuery: ', downQuery);
await this.$emit('getTasks', downQuery);
},
@ -83,11 +78,18 @@ export default {
if (tasks && tasks.length) {
let tasksHeight = 0;
const scrollHeight = document.getElementById('scroll').clientHeight;
let width = document.documentElement.clientWidth;
for (let i = 0; i < 3; i++) {
// TODO:
// if (tasks[i].panel && tasks[i].panel.height) {
// tasksHeight += +tasks[i].panel.height + 42;
// }
if (tasks[i].panel && tasks[i].panel.height) {
// + 42
tasksHeight += +tasks[i].panel.height + 42;
} else {
// rem + 42
// u-card h-16 = 4rem
// += 1rem + 42 = width / 20 + 42
tasksHeight += (width / 20) * 4 + 42;
}
}
this.top = tasksHeight - scrollHeight / 2;
console.log('this.top: ', this.top);

84
src/components/TimeLine/component/TimeBox.vue

@ -1,35 +1,51 @@
<template>
<view class="px-3 pb-10">
<view class="column">
<view :key="index" v-for="(item, index) in tasks">
<view class="flex items-center">
<view class="flex">
<TimeStatus :content="JSON.stringify(item.process)" :status="item.process" />
<view class="flex justify-between flex-1 ml-2">
<view>{{ +item.planStart | date('mm-dd hh:MM') }}</view>
<view class="flex items-center justify-between flex-1 ml-2 task-column">
<view>
<view class="flex justify-between" style="min-width: 180rpx">
<u-icon custom-prefix="custom-icon" name="C-bxl-redux" size="34"></u-icon>
<u-icon custom-prefix="custom-icon" name="attachment" size="42"></u-icon>
<u-icon custom-prefix="custom-icon" name="moneycollect" size="40"></u-icon>
<span>{{ $moment(+item.planStart).format('MM-DD HH:mm') }}</span>
</view>
<view>
<view class="flex justify-between" style="min-width: 90px">
<u-icon custom-prefix="custom-icon" name="C-bxl-redux" size="17px"></u-icon>
<u-icon custom-prefix="custom-icon" name="attachment" size="21px"></u-icon>
<u-icon custom-prefix="custom-icon" name="moneycollect" size="20px"></u-icon>
</view>
</view>
</view>
</view>
<view class="border-l-2 border-gray-300 ml-3.5 my-2">
<view class="plugin border-l-2 border-gray-300 ml-3.5 my-2">
<view class="ml-4 overflow-hidden shadow-lg task-box">
<u-card :show-foot="false" :show-head="false" :style="{ height: setHeight(item.panel) }" class="h-16" margin="0">
<u-card
:show-foot="false"
:show-head="false"
:style="{ height: setHeight(item.panel) }"
@click="changeTimeNode(item.planStart)"
class="h-16"
margin="0"
v-if="item.plugins && item.plugins.length"
>
<!-- 任务面板插件 -->
<view slot="body">
<view :key="pluginIndex" class="p-0 u-col-between u-skeleton" v-for="(plugin, pluginIndex) in item.plugins">
<!-- <view :key="p.pluginId" v-for="p in plugin">
<p-task-title :item="item" v-if="p.pluginId === 1" />
<p-task-description :item="item" v-if="p.pluginId === 2" />
<p-task-duration-delay :item="item" v-if="p.pluginId === 3" />
<p-task-start-time-delay :item="item" v-if="p.pluginId === 4" />
<p-deliverable :item="item" v-if="p.pluginId === 5" />
<p-subtasks :item="item" v-if="p.pluginId === 6" />
<p-subproject :item="item" v-if="p.pluginId === 7" />
<p-task-countdown :item="item" v-if="p.pluginId === 8" />
</view>-->
<view v-if="!item.plugins && !item.plugins.length && taskLoading">
<skeleton :banner="false" :loading="true" :row="4" animate class="mt-2 u-line-2 skeleton"></skeleton>
</view>
<view class="p-0 u-col-between" v-else>
<view :key="pIndex" v-for="(p, pIndex) in item.plugins">
<view class="grid gap-2" v-if="p.length">
<Plugin
:class="getClass(plugin.colspan, plugin.rowspan)"
:item="item"
:key="pluginIndex"
:pluginId="plugin.pluginId"
:styleType="styleType"
@changeLoading="taskLoading = false"
v-for="(plugin, pluginIndex) in p"
/>
</view>
</view>
</view>
</view>
</u-card>
@ -43,12 +59,13 @@
<script>
import { mapState, mapMutations } from 'vuex';
import TimeStatus from './TimeStatus.vue';
import Skeleton from '@/components/Skeleton/Skeleton';
export default {
name: 'TimeBox',
components: { TimeStatus },
components: { TimeStatus, Skeleton },
data() {
return { currentComponent: '' };
return { currentComponent: '', styleType: 0, taskLoading: true };
},
computed: mapState('home', ['roleId', 'timeNode', 'timeUnit', 'tasks']),
@ -56,7 +73,7 @@ export default {
created() {},
methods: {
...mapMutations('home', ['setTipsContent', 'setTipsContent']),
...mapMutations('home', ['setTipsContent', 'setTipsContent', 'setTimeNode']),
//
setHeight(panel) {
@ -66,6 +83,16 @@ export default {
return 'auto';
}
},
// store
changeTimeNode(time) {
this.setTimeNode(time);
},
//
getClass(col, row) {
return [`row-span-${row}`, `col-span-${col}`];
},
},
};
</script>
@ -74,4 +101,13 @@ export default {
.task-box {
border-radius: 24rpx;
}
.column {
padding: 24px 14px;
}
.task-column {
height: 33px;
}
.plugin {
margin: 8px auto;
}
</style>

86
src/components/TimeLine/component/TimeStatus.vue

@ -1,23 +1,16 @@
<!--
* @Author: aBin
* @email: binbin0314@126.com
* @Date: 2021-07-19 15:47:38
* @LastEditors: aBin
* @LastEditTime: 2021-07-19 19:39:36
-->
<template>
<view>
<view class="rounded-full h-7 w-7 flex items-center justify-center text-blue-400" v-if="status === 0" @tap="changeStatus($event, 0)">
<view class="u-font-14">
<view class="iconColumn flex items-center justify-center text-blue-400 rounded-full" v-if="status === 0" @tap="changeStatus($event, 0)">
<u-circle-progress :percent="100" active-color="#2979ff" bgColor="rgba(255,255,255,0)" borderWidth="4" width="66">
<view class="u-progress-content">
<view class="u-progress-dot"></view>
<text class="u-progress-info">
<view class="u-progress-info">
<u-icon name="checkmark" size="30"></u-icon>
</text>
</view>
</view>
</u-circle-progress>
</view>
<view class="rounded-full h-7 w-7 flex items-center justify-center text-black" v-if="status === 1" @tap="changeStatus($event, 1)">
<view class="iconColumn flex items-center justify-center text-black rounded-full" v-if="status === 1" @tap="changeStatus($event, 1)">
<u-circle-progress :percent="80" active-color="#2979ff" bgColor="rgba(255,255,255,0)" borderWidth="6" width="66">
<view class="u-progress-content">
<view class="u-progress-dot"></view>
@ -25,27 +18,27 @@
</view>
</u-circle-progress>
</view>
<view class="rounded-full h-7 w-7 flex items-center justify-center text-gray-400" v-if="status === 2" @tap="changeStatus($event, 2)">
<view class="iconColumn flex items-center justify-center text-gray-400 rounded-full" v-if="status === 2" @tap="changeStatus($event, 2)">
<u-circle-progress :percent="40" active-color="#2979ff" bgColor="rgba(255,255,255,0)" borderWidth="6" width="66">
<view class="u-progress-content">
<view class="u-progress-dot"></view>
<text class="u-progress-info">
<view class="u-progress-info">
<u-icon name="play-right-fill" size="30"></u-icon>
</text>
</view>
</view>
</u-circle-progress>
</view>
<view
class="rounded-full h-7 w-7 flex items-center justify-center text-red-800 font-black"
class="iconColumn flex items-center justify-center font-black text-red-800 rounded-full"
v-if="status === 3"
@tap="changeStatus($event, 3)"
>
<u-circle-progress :percent="80" active-color="#2979ff" bgColor="rgba(255,255,255,0)" borderWidth="6" width="66">
<view class="u-progress-content">
<view class="u-progress-dot"></view>
<text class="u-progress-info">
<view class="u-progress-info">
<u-icon name="pause" size="30"></u-icon>
</text>
</view>
</view>
</u-circle-progress>
</view>
@ -53,56 +46,30 @@
</template>
<script>
import { mapMutations } from 'vuex';
export default {
name: 'TimeStatus',
props: {
status: {
default: 0,
type: Number,
},
content: {
default: '',
type: String,
},
status: { default: 0, type: Number },
content: { default: '', type: String },
},
data() {
return {
time: 20,
start: [
{
text: '确认开始任务',
color: 'blue',
},
],
pause: [
{ text: '继续' },
{
text: '重新开始任务',
color: 'blue',
},
{ text: '结束' },
],
proceed: [
{ text: '暂停' },
{
text: '重新开始任务',
color: 'blue',
},
{ text: '结束' },
],
again: [
{
text: '重新开始任务',
color: 'blue',
},
],
start: [{ text: '确认开始任务', color: 'blue' }],
pause: [{ text: '继续' }, { text: '重新开始任务', color: 'blue' }, { text: '结束' }],
proceed: [{ text: '暂停' }, { text: '重新开始任务', color: 'blue' }, { text: '结束' }],
again: [{ text: '重新开始任务', color: 'blue' }],
};
},
methods: {
...mapMutations('home', ['setClient', 'setTips', 'setStatus', 'setTipsContent']),
chooseList() {
return this.start;
},
changeStatus(e, num) {
this.setStatus(num);
this.setTipsContent(this.chooseTips(num, this.content));
@ -113,6 +80,7 @@ export default {
this.setClient(client);
this.setTips(true);
},
chooseTips(num, content) {
switch (num) {
case 0:
@ -128,3 +96,13 @@ export default {
},
};
</script>
<style scoped lang="scss">
.iconColumn {
height: 33px;
width: 33px;
}
.one {
height: 33px;
width: 33px;
}
</style>

39
src/components/Title/Title.vue

@ -1,14 +1,14 @@
<template>
<view>
<u-navbar back-text="返回">
<u-navbar :is-back="false" back-text="返回">
<view class="flex justify-center flex-1">
<view>{{ project.name }}</view>
<view>我是标题</view>
</view>
<view class="mr-2" slot="right">
<u-icon class="m-1" name="xuanzhong2" custom-prefix="custom-icon" size="38"></u-icon>
<u-icon class="m-1" name="shuaxin1" custom-prefix="custom-icon" size="38"></u-icon>
<u-icon class="m-1" name="home" custom-prefix="custom-icon" size="38"></u-icon>
<u-icon class="m-1" name="xuanxiang" custom-prefix="custom-icon" size="38"></u-icon>
<u-icon class="m-1" name="xuanzhong2" custom-prefix="custom-icon" size="20px" @click="lwbs"></u-icon>
<u-icon class="m-1" name="shuaxin1" custom-prefix="custom-icon" size="20px" @click="projectOverview"></u-icon>
<u-icon class="m-1" name="home" custom-prefix="custom-icon" size="20px" @click="statistics"></u-icon>
<u-icon class="m-1" name="xuanxiang" custom-prefix="custom-icon" size="20px" @click="operation"></u-icon>
</view>
</u-navbar>
</view>
@ -23,14 +23,23 @@ export default {
computed: mapState('home', ['project']),
mounted() {},
methods: {},
methods: {
// LWBS
lwbs() {
this.$t.ui.showToast('LWBS');
},
//
projectOverview() {
this.$t.ui.showToast('项目概览');
},
//
statistics() {
this.$t.ui.showToast('统计');
},
//
operation() {
this.$t.ui.showToast('操作');
},
},
};
</script>
<style scoped lang="scss">
.slot-warp {
display: flex;
justify-content: flex-end;
}
</style>

1
src/config/app.js

@ -4,4 +4,5 @@ export default {
V: version,
version,
theme: [],
tokenKey: 'anyringToken', // storage token key
};

17
src/config/time.js

@ -0,0 +1,17 @@
export default {
timeUnits: [
// 时间颗粒度
{ id: 0, value: '毫秒' },
{ id: 1, value: '秒' },
{ id: 2, value: '分' },
{ id: 3, value: '时' },
{ id: 4, value: '天' },
{ id: 5, value: '周' },
{ id: 6, value: '月' },
{ id: 7, value: '季度' },
{ id: 8, value: '年' },
{ id: 9, value: '年代' },
{ id: 10, value: '世纪' },
{ id: 11, value: '千年' },
],
};

4
src/main.js

@ -17,9 +17,11 @@ Vue.use(indexedDB);
//#endif
Vue.config.productionTip = false;
Vue.prototype.$moment = dayjs;
Vue.use(uView);
Vue.use(Tall);
Vue.use(dayjs);
dayjs.locale('zh-cn');
App.mpType = 'app';

14
src/mock/mock.js

@ -177,11 +177,11 @@ export default [
plugins: [
[
{
col: 123,
col: 1,
colspan: 123,
param: 123,
pluginId: 123456789,
row: 123,
pluginId: 13,
row: 2,
rowspan: 123,
},
],
@ -226,11 +226,11 @@ export default [
plugins: [
[
{
col: 123,
col: 1,
colspan: 123,
param: 123,
pluginId: 123456789,
row: 123,
pluginId: 13,
row: 1,
rowspan: 123,
},
],
@ -387,7 +387,7 @@ export default [
msg: 'ok',
success: true,
data: {
html: 'string',
html: '<div style="background:#0f0;height:100%"></div>',
id: 13,
intro: 'string',
js: 'string',

7
src/pages.json

@ -4,6 +4,7 @@
"path": "pages/project/project",
"style": {
"navigationStyle": "custom" ,
"titleNView": "false",
"navigationBarTextStyle": "white"
}
},
@ -34,10 +35,8 @@
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
"navigationStyle": "custom" ,
"titleNView": "false"
},
"easycom": {
"autoscan": true,

136
src/pages/project/project.vue

@ -1,9 +1,13 @@
<template>
<view :style="{ height: height }" class="flex flex-col overflow-hidden">
<view :style="{ height: height }" class="flex flex-col overflow-hidden u-font-14">
<!-- 标题栏 -->
<Title />
<view class="container flex flex-col flex-1 overflow-hidden bg-gray-100">
<view class="container flex flex-col flex-1 overflow-hidden bg-gray-100" style="margin: auto">
<!-- 角色栏 -->
<Roles @getTasksByRole="getTasksByRole" />
<!-- 日常任务 -->
<Globals :plugins="plugins" />
<!-- 定期任务 -->
<TimeLine @getTasks="getTasks" class="flex-1 overflow-hidden" ref="child" />
</view>
</view>
@ -11,9 +15,10 @@
<script>
import { mapState, mapMutations, mapActions } from 'vuex';
export default {
data() {
return { title: 'Hello', height: '', scrollHeight: null, plugins: [] };
return { height: '', plugins: [] };
},
computed: {
@ -21,32 +26,31 @@ export default {
...mapState('home', ['visibleRoles', 'roleId', 'timeNode', 'timeUnit', 'tasks']),
},
async onLoad(options) {
console.log('options: ', options);
// this.openPage();
const TOKEN = uni.getStorageSync('anyringToken');
if (!TOKEN || !this.token) {
await this.getUserId(options.u);
}
const params = { projectId: options.p };
this.setProjectName(options.pname);
// id
await this.getProjectById(params);
// id
await this.getRoles(params);
this.setInitialRoleId(this.visibleRoles);
//
await this.getTasks({ queryType: 0 });
await this.getTasks({ queryType: 1 });
//
await this.getPermanent();
//
await this.getGlobal();
//
if (this.tasks && this.tasks.length) {
await this.getTasks({ timeNode: +this.tasks[0].planStart, queryType: 0, queryNum: 6 });
await this.getTasks({ timeNode: +this.tasks[this.tasks.length - 1].planStart, queryType: 1, queryNum: 6 });
}
onLoad(options) {
this.init(options);
},
watch: {
/**
* 当时间基准点发生变化时
* 重新根据时间和角色查询普通日常任务
* 永久日常任务不发生改变
*/
async timeNode() {
//
await this.getGlobal();
},
/**
* 当角色发生变化时
* 重新查询永久日常任务和普通日常任务
*/
async roleId() {
this.setTimeNode(new Date().getTime());
//
await this.getPermanent();
//
await this.getGlobal();
},
},
mounted() {
@ -63,13 +67,65 @@ export default {
'setDownTasks',
'setDailyTasks',
'setProjectName',
'setTimeNode',
]),
...mapActions('user', ['getUserId']),
...mapActions('home', ['getProjectById', 'getRoles', 'handleRegularTask']),
...mapMutations('user', ['setToken']),
/**
* 初始化
* @param {object | null} options
*/
async init(options) {
try {
if (!this.token) {
// storetoken
const TOKEN = this.$t.storage.getStorageSync(this.$t.app.tokenKey);
if (TOKEN) {
// token store
this.setToken(TOKEN);
} else {
// token userIdtoken
if (!options || !options.u) {
// u (userId)
this.$t.ui.showToast('缺少用户信息参数');
} else {
await this.getUserId(options.u);
}
}
}
//
options && options.pname && this.setProjectName(options.pname);
if (!options || !options.p) {
// id
this.$t.ui.showToast('缺少项目信息参数');
} else {
// id
await this.getProjectById({ projectId: options.p });
// id
await this.getRoles({ projectId: options.p });
this.setInitialRoleId(this.visibleRoles);
//
await this.getTasks({ queryType: 0 });
await this.getTasks({ queryType: 1 });
openPage() {
console.log('open');
this.$u.route('/pages/pinch/pinch');
//
await this.getPermanent();
//
await this.getGlobal();
//
if (this.tasks && this.tasks.length) {
await this.getTasks({ timeNode: +this.tasks[0].planStart, queryType: 0, queryNum: 6 });
await this.getTasks({ timeNode: +this.tasks[this.tasks.length - 1].planStart, queryType: 1, queryNum: 6 });
}
}
} catch (error) {
console.error('project init function:', error);
}
},
//
@ -109,7 +165,11 @@ export default {
*/
async getPermanent() {
try {
this.allPlugins = [];
const res = await this.$u.api.getPermanent({ roleId: this.roleId });
for (let item of res) {
this.allPlugins = this.allPlugins.concat(item.plugins);
}
console.log('res', res);
} catch (error) {
console.log('error: ', error);
@ -124,12 +184,13 @@ export default {
*/
async getGlobal() {
try {
this.timePlugins = [];
const { roleId, timeNode, timeUnit } = this;
const params = { roleId, timeNode, timeUnit };
const res = await this.$u.api.getGlobal(params);
for (let task of res) {
for (let item of task.plugins) {
this.plugins.push(...item);
this.timePlugins.push(...item);
}
}
this.setDailyTasks(res);
@ -143,15 +204,20 @@ export default {
try {
await this.getTasks({ queryType: 0 });
await this.getTasks({ queryType: 1 });
//
//
const upQuery = {
timeNode: +this.tasks[0].planStart,
queryType: 0,
queryNum: 6,
};
await this.getTasks(upQuery);
//
// =+
const cycle = this.$t.time.computeCycle('天');
const timeNode = this.$t.time.add(+this.tasks[this.tasks.length - 1].planStart, 1, cycle).valueOf();
const downQuery = {
timeNode: +this.tasks[this.tasks.length - 1].planStart,
timeNode,
queryType: 1,
queryNum: 6,
};

35
src/store/home/mutations.js

@ -125,7 +125,12 @@ const mutations = {
if (!data || !data.length) {
state.topEnd = true;
}
state.tasks = [...data.concat(state.tasks)] || [];
console.log('!state.tasks.plugins.length: ', !state.tasks[0].name);
if (!state.tasks[0].name) {
state.tasks = [...data];
} else {
state.tasks = [...data.concat(state.tasks)];
}
},
/**
@ -137,16 +142,36 @@ const mutations = {
if (!data || !data.length) {
state.bottomEnd = true;
}
state.tasks = [...state.tasks.concat(data)] || [];
if (!state.tasks[0].name) {
state.tasks = [...data];
} else {
state.tasks = [...state.tasks.concat(data)];
}
},
/**
* 清空定期任务数据
* @param {Object} state
* @param {Array} data 服务端返回的模板数组
*/
setTasks(state, data) {
state.tasks = data || [];
setTasks(state) {
const data = [
{
panel: {},
plugins: [],
planStart: new Date().getTime(),
},
{
panel: {},
plugins: [],
planStart: new Date().getTime(),
},
{
panel: {},
plugins: [],
planStart: new Date().getTime(),
},
];
state.tasks = data;
},
/**

33
src/store/home/state.js

@ -14,22 +14,23 @@ const state = {
roleId: '', // 当前展示查看的角色id
timeNode: new Date().getTime(), // 时间基准点
timeUnit: 4, // // 时间颗粒度
timeUnits: [
// 时间颗粒度
{ id: 0, value: '毫秒' },
{ id: 1, value: '秒' },
{ id: 2, value: '分' },
{ id: 3, value: '时' },
{ id: 4, value: '天' },
{ id: 5, value: '周' },
{ id: 6, value: '月' },
{ id: 7, value: '季度' },
{ id: 8, value: '年' },
{ id: 9, value: '年代' },
{ id: 10, value: '世纪' },
{ id: 11, value: '千年' },
],
tasks: [], // 定期任务
tasks: [
{
panel: {},
plugins: [],
planStart: new Date().getTime(),
},
{
panel: {},
plugins: [],
planStart: new Date().getTime(),
},
{
panel: {},
plugins: [],
planStart: new Date().getTime(),
},
], // 定期任务
topEnd: false, // 时间轴向上查任务到顶了
bottomEnd: false, // 时间轴向下查任务到底了
dailyTasks: [], // 日常任务

3
src/store/messages/mutations.js

@ -1,4 +1,5 @@
import { setStorageSync, getStorageSync, removeStorageSync } from '@/utils/storage';
import storage from '@/utils/storage';
const { setStorageSync, getStorageSync, removeStorageSync } = storage;
const mutations = {
/**

5
src/store/user/mutations.js

@ -5,9 +5,8 @@ const mutations = {
* @param {string} token
*/
setToken(state, token) {
if (!token) return;
state.token = token;
uni.setStorageSync('anyringToken', token);
state.token = token || '';
uni.$t.storage.setStorageSync(uni.$t.app.tokenKey, token || '');
},
/**

1
src/utils/request.js

@ -11,7 +11,6 @@ const install = (Vue, vm) => {
// 请求拦截部分,如配置,每次请求前都会执行
Vue.prototype.$u.http.interceptor.request = config => {
// TODO: 如果在白名单里 则不需要加token
if (vm.$store.state.user.token) {
config.header.Authorization = `Bearer ${vm.$store.state.user.token}`;
}

2
src/utils/tall.js

@ -3,6 +3,7 @@ import zIndex from '@/config/zIndex.js';
import plugin from '@/config/plugin.js';
import storage from '@/utils/storage.js';
import time from '@/utils/time.js';
import ui from '@/utils/ui.js';
const $t = {
zIndex, // 定位元素层级
@ -10,6 +11,7 @@ const $t = {
plugin, // 插件相关配置信息
storage, // 本地存储storage封装
time, // 时间处理
ui, // ui界面提示相关
};
uni.$t = $t;

17
src/utils/time.js

@ -1,6 +1,7 @@
import dayjs from 'dayjs';
var advancedFormat = require('dayjs/plugin/advancedFormat');
var weekOfYear = require('dayjs/plugin/weekOfYear');
const advancedFormat = require('dayjs/plugin/advancedFormat');
const weekOfYear = require('dayjs/plugin/weekOfYear');
dayjs.extend(advancedFormat);
dayjs.extend(weekOfYear);
@ -29,6 +30,17 @@ const formatTime = beginTime => {
return `${[year, month, day].map(formatNumber).join('/')} ${[hour, minute, second].map(formatNumber).join(':')}`;
};
/**
* 添加一定时间的时长
* @param {number | date} time
* @param {number} num
* @param {string} cycle
*/
const add = (time, num, cycle) => {
const str = dayjs(time).add(num, cycle);
return str;
};
/**
* 时间转换 08:00 转换成8小时0分钟
* @param {string} time
@ -285,6 +297,7 @@ const formatStartTimeToCycleTime = (cycle, time) => {
export default {
formatNumber,
formatTime,
add,
convertTime,
secondToMinute,
setTimestampToStr,

56
src/utils/ui.js

@ -0,0 +1,56 @@
export default {
/**
* 显示toast
* @param {string} title 提示内容
* @param {number} duration 显示时间 默认2000
*/
showToast(title, duration = 2000) {
return uni.showToast({
title,
icon: 'none',
duration,
mask: true,
});
},
// 隐藏toast
hideToast() {
return uni.hideToast();
},
/**
* 显示加载雪花
* @param {string} title
*/
showLoading(title) {
return uni.showLoading({
title,
mask: true,
});
},
// 隐藏loading
hideLoading() {
return uni.hideLoading();
},
/**
* 显示modal弹出框
* @param {string} title 标题
* @param {string} content 内容
* @param {boolean} showCancel 是否显示取消按钮 默认true
*/
showModal(title, content, showCancel = true) {
return new Promise(function (resolve, reject) {
uni.showModal({
title,
content,
showCancel,
success: ({ confirm, cancel }) => {
confirm && resolve();
cancel && reject();
},
});
});
},
};

2
vue.config.js

@ -6,7 +6,7 @@ module.exports = {
productionSourceMap: false,
devServer: {
// open: true,
host: '127.0.0.1',
// host: '127.0.0.1',
overlay: { warnings: false, errors: true },
// proxy: {}
},

Loading…
Cancel
Save