Browse Source

fix(交付物): 修复检查人选择组件之间相互影响的bug

deliver
wally 4 years ago
parent
commit
435c0bd814
  1. 149
      .drone.yml
  2. 1
      CHANGELOG.md
  3. 38
      components/Reviewer/Reviewer.vue
  4. 2
      config/deliver.js
  5. 16
      config/index.js
  6. 51
      pages/index/index.vue
  7. 88
      plugins/p-deliver/p-deliver.vue

149
.drone.yml

@ -1,149 +0,0 @@
---
kind: pipeline
type: docker
name: dev
# 挂载的主机卷,可以映射到docker容器中
volumes:
# maven构建缓存(宿主机目录)
- name: ssh_key
host:
path: /root/.ssh/
- name: cache
host:
path: /var/lib/cache
- name: data
host:
path: /var/lib/data
steps:
# - name: restore-cache
# image: drillster/drone-volume-cache
# volumes:
# - name: cache
# path: /cache
# settings:
# restore: true
# mount:
# - ./node_modules
- name: build
image: node:latest
pull: if-not-exists # default always
# volumes:
# - name: cache
# path: /root/.m2
commands:
- npm config set registry http://registry.npm.taobao.org
- npm i
- npm run test
# - name: rebuild-cache
# image: drillster/drone-volume-cache
# volumes:
# - name: cache
# path: /cache
# settings:
# rebuild: true
# mount:
# - ./node_modules
- name: deploy-scp
image: appleboy/drone-scp
pull: if-not-exists
volumes:
- name: ssh_key
path: /root/.ssh/
settings:
host: test.tall.wiki
port: 22
username: root
key_path: /root/.ssh/id_rsa
rm: true # true则会删除目标目录重建
target: /home/tall/v4.0.0
source: dist/*
strip_components: 1 # 去除的目录层数,如果没有该选项,则拷贝过去是 target/xxx.jar,1代表去除target
# - name: run-ssh
# image: appleboy/drone-ssh
# pull: if-not-exists
# volumes:
# - name: ssh_key
# path: /root/.ssh/
# settings:
# settings:
# host: test.tall.wiki
# port: 22
# username: root
# key_path: /root/.ssh/id_rsa
# script_stop: true # stop script after first failure
# #command_timeout: 30s # 30seconds, the maximum amount of time for the execute commands, default is 10 minutes.
# script:
# - cd /home/iacd-platform-drone
# - ./re.sh > /dev/null 2> /dev/null &
- name: notify-email
image: drillster/drone-email
pull: if-not-exists
settings:
host: smtp.qiye.aliyun.com #例如 smtp.qq.com
port: 465 #例如QQ邮箱端口465
username: devops@ccsens.com #邮箱用户名
password: #邮箱密码
from_secret: orgsecret_password_mail_devops
from: devops@ccsens.com
recipients: weizezhao@ccsens.com #收件人,多个用,隔开
when: #执行条件
status:
- success
- changed
- failure
- name: notify-wechatwork
image: fifsky/drone-wechat-work
pull: if-not-exists
settings:
url: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=b2b93e9a-128b-41d4-8dce-12004e3f48b9
msgtype: markdown
content: |
{{if eq .Status "success" }}
#### 🎉 ${DRONE_REPO} 构建成功
> Commit: [${DRONE_COMMIT_MESSAGE}](${DRONE_COMMIT_LINK})
> Author: ${DRONE_COMMIT_AUTHOR}
> [点击查看](${DRONE_BUILD_LINK})
{{else}}
#### ❌ ${DRONE_REPO} 构建失败
> Commit: [${DRONE_COMMIT_MESSAGE}](${DRONE_COMMIT_LINK})
> Author: ${DRONE_COMMIT_AUTHOR}
> 请立即修复!!!
> [点击查看](${DRONE_BUILD_LINK})
{{end}}
when:
status:
- failure
- success
trigger:
branch: feat
# - name: notify-dingtalk
# image: lddsb/drone-dingtalk-message
# environment:
# PASSWORD:
# from_secret: password_mail_devops
# settings:
# token: your-dingtalk-robot-access-token
# type: markdown
# message_color: true
# message_pic: true
# sha_link: true
# -name: notify-slack
# image: plugins/slack
# webhook: https://hooks.slack.com/ www.dijiuyy.com services/xxx/xxx/xxx
# channel: dev
# template: >
# {{#success build.status}}
# build {{build.number}} succeeded. Good job.
# {{else}}
# build {{build.number}} failed. Fix me please.
# {{/success}}

1
CHANGELOG.md

@ -90,6 +90,7 @@
- | 提交交付物,查看提交记录,修改交付物标题的接口核对完成 | [7c08530](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/7c08530)
- | 提取deliver store;细节调整 | [4d901ac](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/4d901ac)
- | 查看提交历史记录页面数据同步更新 | [749cb10](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/749cb10)
- | 细节调整 | [7f9cf1f](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/7f9cf1f)
- | 细节调整 | [3d1c463](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/3d1c463)
- | 重构project init 部分 | [c7bf2df](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/c7bf2df)
- | 项目列表 | [0486e98](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/0486e98)

38
components/Reviewer/Reviewer.vue

@ -2,9 +2,8 @@
<view class="border border-solid border-gray-300 rounded-md mt-3 p-2" @click="collapsed = !collapsed">
<view class="top flex justify-between">
<view class="mr-3 text-sm">审核人</view>
<!-- 展示选择的审核人 -->
<view class="flex item-center truncate justify-end flex-1 text-sm">
<view class="flex item-center justify-end flex-1 text-sm">
<view v-for="item in showCheckers" class="mx-1">
<!-- <u-badge :is-dot="true" is-center></u-badge> -->
{{ item.name }}
@ -20,17 +19,19 @@
<view v-show="!collapsed" class="foot mt-2 flex flex-wrap">
<u-button
v-for="item in checkers"
:type="item.checked ? 'primary' : 'default'"
:type="checkedCheckers.find(checker => checker.memberId === item.memberId) ? 'primary' : 'default'"
size="mini"
class="my-1 mx-2"
@click="item.checked = !item.checked"
>{{ item.name }}</u-button>
@click="handleSelectChecker(item)"
>
{{ item.name }}
</u-button>
</view>
</view>
</template>
<script setup>
import { ref, computed } from 'vue';
import { ref, computed, defineExpose } from 'vue';
import { useStore } from 'vuex';
const store = useStore();
@ -42,15 +43,24 @@ const collapsed = ref(true);
const checkers = computed(() => store.state.role.members);
//
const checkedCheckers = computed(() => checkers.value.filter(item => item.checked) || []);
const checkedCheckers = ref([]);
//
//
const showCheckers = computed(() => {
if (checkedCheckers.value.length === 0) {
//
return [checkers.value[0]];
const showCheckers = computed(() => (checkedCheckers.value.length > 3 ? checkedCheckers.value.slice(0, 3) : checkedCheckers.value));
defineExpose({ checkedCheckers, collapsed });
/**
* 点击成员 切换检查人的选中状态
* @param {object} member 成员对象
*/
function handleSelectChecker(member) {
const target = checkedCheckers.value.find(item => item.memberId === member.memberId);
if (target) {
//
checkedCheckers.value = checkedCheckers.value.filter(item => item.memberId !== member.memberId);
} else {
checkedCheckers.value.push(member);
}
return checkedCheckers.value.length > 3 ? checkedCheckers.value.slice(0, 3) : checkedCheckers.value;
});
}
</script>

2
config/deliver.js

@ -0,0 +1,2 @@
// 上传文件的扩展名
export const UPLOAD_EXTENSION = ['.xls', '.xlsx', '.zip', '.exe', '.pdf', '.doc', '.docx', '.ppt', '.pptx'];

16
config/index.js

@ -0,0 +1,16 @@
// 环境 (development|production)
export const SCENE = 'development';
// 一些特殊的API区分生产测试环境
export const api = {
baseUrl: {
development: 'https://test.tall.wiki',
production: 'https://www.tall.wiki',
},
upload: {
development: 'https://test.tall.wiki/filedeal/file/upload/multiple',
production: 'http://101.201.226.21/filedeal/file/upload/multiple',
},
};
export const UPLOAD_URL = api.upload[SCENE]; // 多文件上传路径

51
pages/index/index.vue

@ -1,19 +1,19 @@
<template>
<!-- <view class="flex flex-col h-full bg-gray-50" @click="openAuth"> -->
<view class="flex flex-col h-full bg-gray-50">
<view class="relative" @touchmove="onMove">
<!-- 日历 -->
<Calendar @selected-change="onDateChange" :show-back="true" ref="calendar" @handleFindPoint="handleFindPoint" />
<!-- 上传 导入wbs -->
<Upload @success="onUploadSuccess" @error="onUploadError" />
</view>
<u-button @click="toLogin">登录</u-button>
<!-- 项目列表 -->
<Projects @getProjects="getProjects" class="flex-1 overflow-y-auto" />
<!-- 全局提示框 -->
<u-top-tips ref="uTips"></u-top-tips>
</view>
<!-- <view class="flex flex-col h-full bg-gray-50" @click="openAuth"> -->
<view class="flex flex-col h-full bg-gray-50">
<view class="relative" @touchmove="onMove">
<!-- 日历 -->
<Calendar @selected-change="onDateChange" :show-back="true" ref="calendar" @handleFindPoint="handleFindPoint" />
<!-- 上传 导入wbs -->
<Upload @success="onUploadSuccess" @error="onUploadError" />
</view>
<u-button @click="toLogin">登录</u-button>
<!-- 项目列表 -->
<Projects @getProjects="getProjects" class="flex-1 overflow-y-auto" />
<!-- 全局提示框 -->
<u-top-tips ref="uTips"></u-top-tips>
</view>
</template>
<script setup>
@ -40,7 +40,14 @@ watchEffect(() => {
});
//
function getProjects(start = dayjs().startOf('day').valueOf(), end = dayjs().endOf('day').valueOf()) {
function getProjects(
start = dayjs()
.startOf('day')
.valueOf(),
end = dayjs()
.endOf('day')
.valueOf(),
) {
// const data = await this.$u.api.getProjects(start, end);
uni.$catchReq.getProjects(start, end, (err, data) => {
if (err) {
@ -56,8 +63,14 @@ function getProjects(start = dayjs().startOf('day').valueOf(), end = dayjs().end
async function handleFindPoint(start, end) {
try {
const startTime = start || dayjs().startOf('month').valueOf();
const endTime = end || dayjs().endOf('month').valueOf();
const startTime = start
|| dayjs()
.startOf('month')
.valueOf();
const endTime = end
|| dayjs()
.endOf('month')
.valueOf();
const res = await uni.$u.api.findRedPoint(startTime, endTime);
store.commit('project/setDotList', res);
} catch (error) {
@ -108,7 +121,7 @@ function onMove(event) {
}
function toLogin() {
uni.navigateTo({ url: '/pages/user/accountLogin' })
uni.navigateTo({ url: '/pages/user/accountLogin' });
}
</script>

88
plugins/p-deliver/p-deliver.vue

@ -1,15 +1,11 @@
<template>
<!-- <view class="deliver-container">p-deliver</view> -->
<!-- TODO if 是测试用的 -->
<view class="my-2 bg-white p-2 rounded-md relative" @longpress.prevent="showMask = true" v-if="deliverRef">
<!-- 是自己的任务 且该任务有交付物 才显示提交组件 -->
<view class="my-2 bg-white p-2 rounded-md relative" @longpress.prevent="showMask = true" v-if="isMine && deliver">
<!-- 插件名称输入和提交 -->
<view class="flex item-center justify-between py-3 pl-2">
<!-- <u-input v-model="iptValue" type="text" :border="false" placeholder="请编辑交付物名称" /> -->
<!-- TODO: 可能会有多个交付物 需要遍历 或者展示第一个 -->
<!-- TODO: 应该是交付物的名称 -->
<view class="flex-1">
<span class="relative px-1" v-if="deliver && deliver.deliverName">
<u-badge :is-dot="true" is-center v-if="uBadgeShow"></u-badge>
<!-- <u-badge :is-dot="true" is-center v-show="showBadge"></u-badge> -->
{{ deliver.deliverName }}
</span>
</view>
@ -23,9 +19,9 @@
:disabled="submitState"
:ripple="true"
:loading="submitBtnLoading"
v-show="!uBadgeShow"
>提交</u-button
>
提交
</u-button>
<!-- 查看提交历史的按钮 -->
<u-icon name="arrow-right" class="ml-3" @click="openDeliverHistory"></u-icon>
@ -45,9 +41,9 @@
<!-- 编辑和删除的遮罩层 -->
<view class="mask flex items-center justify-center bg-grey" v-show="showMask" @click="showMask = false">
<view class="bg-yellow-500 text-white w-12 h-12 text-center leading-12 rounded-w-12 mx-8" @click.stop="showEditModal = true"
>修改</view
>
<view class="bg-yellow-500 text-white w-12 h-12 text-center leading-12 rounded-w-12 mx-8" @click.stop="showEditModal = true">
修改
</view>
<view class="bg-red-500 text-white w-12 h-12 text-center leading-12 rounded-w-12 mx-8" @click.stop="deleteDeliver">删除</view>
<!-- 删除的二次提示modal -->
<u-modal v-model="showDeleteModal" :content="content" :show-cancel-button="true" @confirm="confirmDelete"></u-modal>
@ -61,7 +57,6 @@
<view class>
<u-input :border="true" class="m-5" placeholder="请输入交付物名称" v-model="newInputRef"></u-input>
</view>
<!-- TODO: 边框 -->
<view class="flex justify-around h-12 mt-7 justify-self-stretch box-modal-border">
<view class="leading-12 flex-1 text-center delete-modal-border" @click="showEditModal = false">取消</view>
<view class="text-blue-700 leading-12 flex-1 text-center" @click="confirmEditDeliverName">确定</view>
@ -71,36 +66,34 @@
</u-mask>
<!-- 插件审核人员选择 -->
<Reviewer />
<Reviewer ref="reviewerRef" />
</view>
</template>
<script setup>
import { ref, computed } from 'vue';
import { useStore } from 'vuex';
import { UPLOAD_URL } from '@/config/index';
import { UPLOAD_EXTENSION } from '@/config/deliver';
const props = defineProps({ task: { type: Object, default: () => {} } });
const store = useStore();
const submitBtnLoading = ref(false);
//
const deliverRef = ref(true); //
const reviewerRef = ref(null);
const submitBtnLoading = ref(false);
const linkValue = ref(''); //
const showMask = ref(false); //
const showEditModal = ref(false); // modal
const newInputRef = ref(''); //
const showDeleteModal = ref(false); // modal
const content = '是否确定删除';
const uBadgeShow = ref(false); // u-badge
const deliver = ref();
const showBadge = ref(false); // u-badge
const deliver = ref(null); //
//
const submitState = computed(() => !linkValue.value);
const projectId = computed(() => store.getters['project/projectId']);
//
const checkers = computed(() => store.state.role.members);
const checkedCheckers = computed(() => checkers.value.filter(item => item.checked));
const isMine = computed(() => store.getters['role/isMine']); //
// id
(async function getDeliverData() {
@ -110,14 +103,13 @@ const checkedCheckers = computed(() => checkers.value.filter(item => item.checke
const param = { taskId: props.task.id };
const data = await uni.$u.api.getDeliverByTaskId(param);
deliver.value = data;
store.commit('deliver/setDeliverRecordId', deliver.value.deliverRecordId);
} catch (error) {
console.log('error: ', error);
}
})();
//
function validateDeliverForm() {
function validateDeliverForm(checkedCheckers) {
const reg = /^http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- ./?%&=]*)?$/;
if (!reg.test(linkValue.value)) {
// toast
@ -125,7 +117,7 @@ function validateDeliverForm() {
return false;
}
//
if (!checkedCheckers.value || !checkedCheckers.value.length) {
if (!checkedCheckers || !checkedCheckers.length) {
uni.$ui.showToast('请选择检查人');
return false;
}
@ -133,14 +125,16 @@ function validateDeliverForm() {
}
//
function submit() {
async function submit() {
const checkedCheckers = reviewerRef.value.checkedCheckers; //
//
if (!validateDeliverForm()) return;
if (!validateDeliverForm(checkedCheckers)) return;
submitBtnLoading.value = true; // loading
//
try {
const checkerList = [];
checkedCheckers.value.forEach(item => {
checkedCheckers.forEach(item => {
checkerList.push(item.memberId);
});
const param = {
@ -149,10 +143,9 @@ function submit() {
fileList: [linkValue.value],
checkerList,
};
uni.$u.api.submitDeliverInfo(param);
submitBtnLoading.value = false; // loading
uBadgeShow.value = true;
await uni.$u.api.submitDeliverInfo(param);
uni.$ui.showToast('提交交付物信息成功');
resetControlState(); //
} catch (error) {
console.log('error: ', error);
uni.$ui.showToast('提交交付物信息失败');
@ -160,11 +153,18 @@ function submit() {
}
}
//
function resetControlState() {
submitBtnLoading.value = false; // loading
linkValue.value = ''; //
reviewerRef.value.collapsed = true; //
}
//
function openDeliverHistory() {
const deliverIds = deliver.value.deliverId;
const deliverId = deliver.value.deliverId;
// console.log(deliverId)
uni.navigateTo({ url: `/pages/submitList/submitList?deliverId=${deliverIds}` });
uni.navigateTo({ url: `/pages/submitList/submitList?deliverId=${deliverId}` });
}
//
@ -179,12 +179,7 @@ function paste() {
//
async function uploadFile() {
try {
const data = await uni.$upload.chooseAndUpload(
'https://test.tall.wiki/filedeal/file/upload/multiple',
{},
['.xls', '.xlsx', '.zip', '.exe', '.pdf', '.doc', '.docx', '.ppt', '.pptx'],
'files',
);
const data = await uni.$upload.chooseAndUpload(UPLOAD_URL, {}, UPLOAD_EXTENSION, 'files');
// console.log(data[0]);
linkValue.value = data[0].visitUrl;
} catch (error) {
@ -192,15 +187,10 @@ async function uploadFile() {
}
}
//
// TODO:
async function uploadPhoto() {
try {
const data = await uni.$upload.chooseAndUpload(
'https://test.tall.wiki/filedeal/file/upload/multiple',
{},
['.xls', '.xlsx', '.zip', '.exe', '.pdf', '.doc', '.docx', '.ppt', '.pptx'],
'files',
);
const data = await uni.$upload.chooseAndUpload(UPLOAD_URL, {}, UPLOAD_EXTENSION, 'files');
// console.log(data[0])
linkValue.value = data[0].visitUrl;
} catch (error) {
@ -226,7 +216,7 @@ async function confirmEditDeliverName() {
//
showEditModal.value = false;
showMask.value = false;
uBadgeShow.value = false;
showBadge.value = false;
newInputRef.value = '';
} catch (error) {
console.error('error: ', error);
@ -253,5 +243,3 @@ async function confirmDelete() {
}
}
</script>
<style scoped lang="scss"></style>

Loading…
Cancel
Save