|
@@ -1,14 +1,12 @@
|
|
|
<template>
|
|
<template>
|
|
|
<view class="package-detail">
|
|
<view class="package-detail">
|
|
|
- <!-- header -->
|
|
|
|
|
<view class="package-detail__header">
|
|
<view class="package-detail__header">
|
|
|
<view class="package-detail__title">
|
|
<view class="package-detail__title">
|
|
|
{{ packageDetail?.scorePackageName || '积分包详情' }}
|
|
{{ packageDetail?.scorePackageName || '积分包详情' }}
|
|
|
</view>
|
|
</view>
|
|
|
- <view class="package-detail__sub"> 编号:{{ packageDetail?.packageSn || '-' }} </view>
|
|
|
|
|
|
|
+ <view class="package-detail__sub">编号:{{ packageDetail?.packageSn || '-' }}</view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
- <!-- 基础信息 -->
|
|
|
|
|
<view class="detail-card">
|
|
<view class="detail-card">
|
|
|
<view class="detail-card__title">基础信息</view>
|
|
<view class="detail-card__title">基础信息</view>
|
|
|
|
|
|
|
@@ -23,7 +21,6 @@
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
- <!-- 积分规则 -->
|
|
|
|
|
<view v-if="ruleSections.length" class="rule-card">
|
|
<view v-if="ruleSections.length" class="rule-card">
|
|
|
<view class="rule-card__title">积分规则</view>
|
|
<view class="rule-card__title">积分规则</view>
|
|
|
|
|
|
|
@@ -37,40 +34,109 @@
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
- <view v-if="!loading && !packageDetail" class="empty"> 暂无详情数据 </view>
|
|
|
|
|
|
|
+ <view v-if="!loading && !packageDetail" class="empty">暂无详情数据</view>
|
|
|
|
|
+
|
|
|
|
|
+ <view v-if="showExportButton" class="bottom-action">
|
|
|
|
|
+ <wd-button block type="primary" @click="openExportPopup">发送报告</wd-button>
|
|
|
|
|
+ </view>
|
|
|
|
|
+
|
|
|
|
|
+ <wd-popup
|
|
|
|
|
+ v-model="exportPopupVisible"
|
|
|
|
|
+ position="bottom"
|
|
|
|
|
+ custom-style="border-radius: 32rpx 32rpx 0 0;"
|
|
|
|
|
+ @close="resetExportError"
|
|
|
|
|
+ >
|
|
|
|
|
+ <view class="export-popup">
|
|
|
|
|
+ <view class="export-popup__close" @click="exportPopupVisible = false">×</view>
|
|
|
|
|
+
|
|
|
|
|
+ <view class="export-popup__header">
|
|
|
|
|
+ <view class="export-popup__title">报告发送</view>
|
|
|
|
|
+ <view class="export-popup__desc">报告将发送至填写的邮箱,请确认邮箱地址有效。</view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+
|
|
|
|
|
+ <view class="export-popup__body">
|
|
|
|
|
+ <view
|
|
|
|
|
+ class="export-popup__input-wrap"
|
|
|
|
|
+ :class="{ 'export-popup__input-wrap--error': emailError }"
|
|
|
|
|
+ >
|
|
|
|
|
+ <input
|
|
|
|
|
+ v-model="email"
|
|
|
|
|
+ class="export-popup__input"
|
|
|
|
|
+ placeholder="请输入邮箱"
|
|
|
|
|
+ placeholder-class="export-popup__placeholder"
|
|
|
|
|
+ type="text"
|
|
|
|
|
+ confirm-type="send"
|
|
|
|
|
+ cursor-spacing="120"
|
|
|
|
|
+ :focus="emailInputFocus"
|
|
|
|
|
+ :adjust-position="true"
|
|
|
|
|
+ @focus="emailError = ''"
|
|
|
|
|
+ @confirm="submitExportReport"
|
|
|
|
|
+ />
|
|
|
|
|
+ </view>
|
|
|
|
|
+
|
|
|
|
|
+ <view v-if="emailError" class="export-popup__error">
|
|
|
|
|
+ {{ emailError }}
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+
|
|
|
|
|
+ <view class="export-popup__footer">
|
|
|
|
|
+ <wd-button block type="primary" :loading="exportLoading" @click="submitExportReport">
|
|
|
|
|
+ 提交
|
|
|
|
|
+ </wd-button>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </wd-popup>
|
|
|
</view>
|
|
</view>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
|
-import { computed, ref } from 'vue'
|
|
|
|
|
|
|
+import { computed, nextTick, ref } from 'vue'
|
|
|
|
|
|
|
|
import { onLoad } from '@dcloudio/uni-app'
|
|
import { onLoad } from '@dcloudio/uni-app'
|
|
|
|
|
|
|
|
import {
|
|
import {
|
|
|
|
|
+ exportZbInfoFormWeiNewApi,
|
|
|
getPackageCanTaskListApi,
|
|
getPackageCanTaskListApi,
|
|
|
getScorePackagePageByIdApi,
|
|
getScorePackagePageByIdApi,
|
|
|
-} from '@/services/modules/task/package'
|
|
|
|
|
|
|
+} from '@/services/modules/task/package/index'
|
|
|
|
|
+
|
|
|
|
|
+import { useUserStore } from '@/stores/modules/user'
|
|
|
|
|
+
|
|
|
|
|
+const userStore = useUserStore()
|
|
|
|
|
|
|
|
const id = ref('')
|
|
const id = ref('')
|
|
|
const loading = ref(false)
|
|
const loading = ref(false)
|
|
|
|
|
+const exportLoading = ref(false)
|
|
|
|
|
+const exportPopupVisible = ref(false)
|
|
|
|
|
+const emailInputFocus = ref(false)
|
|
|
|
|
+const emailError = ref('')
|
|
|
|
|
+const email = ref('')
|
|
|
const packageDetail = ref(null)
|
|
const packageDetail = ref(null)
|
|
|
const ruleSections = ref([])
|
|
const ruleSections = ref([])
|
|
|
|
|
|
|
|
const EMPTY_TEXT = '无'
|
|
const EMPTY_TEXT = '无'
|
|
|
|
|
|
|
|
|
|
+const roles = computed(() => userStore.currentUserInfo?.roles || [])
|
|
|
|
|
+
|
|
|
|
|
+const showExportButton = computed(() => {
|
|
|
|
|
+ return roles.value.includes(6) && packageDetail.value?.exportFlag === '1'
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
const formatDrugList = (val) => {
|
|
const formatDrugList = (val) => {
|
|
|
if (!val) return EMPTY_TEXT
|
|
if (!val) return EMPTY_TEXT
|
|
|
-
|
|
|
|
|
- // 已经是数组
|
|
|
|
|
- if (Array.isArray(val)) {
|
|
|
|
|
- return val.join('、') || EMPTY_TEXT
|
|
|
|
|
- }
|
|
|
|
|
- return String(val) || EMPTY_TEXT
|
|
|
|
|
|
|
+ if (Array.isArray(val)) return val.join('、') || EMPTY_TEXT
|
|
|
|
|
+ return (
|
|
|
|
|
+ String(val)
|
|
|
|
|
+ .replace(/^\[|\]$/g, '')
|
|
|
|
|
+ .replace(/"/g, '')
|
|
|
|
|
+ .split(',')
|
|
|
|
|
+ .filter(Boolean)
|
|
|
|
|
+ .join('、') || EMPTY_TEXT
|
|
|
|
|
+ )
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const areaName = computed(() => {
|
|
const areaName = computed(() => {
|
|
|
const area = packageDetail.value?.area
|
|
const area = packageDetail.value?.area
|
|
|
-
|
|
|
|
|
if (!Array.isArray(area) || area.length === 0) return EMPTY_TEXT
|
|
if (!Array.isArray(area) || area.length === 0) return EMPTY_TEXT
|
|
|
|
|
|
|
|
return (
|
|
return (
|
|
@@ -83,7 +149,6 @@ const areaName = computed(() => {
|
|
|
|
|
|
|
|
const quizNames = computed(() => {
|
|
const quizNames = computed(() => {
|
|
|
const list = packageDetail.value?.quizRelations
|
|
const list = packageDetail.value?.quizRelations
|
|
|
-
|
|
|
|
|
if (!Array.isArray(list) || list.length === 0) return EMPTY_TEXT
|
|
if (!Array.isArray(list) || list.length === 0) return EMPTY_TEXT
|
|
|
|
|
|
|
|
return (
|
|
return (
|
|
@@ -100,36 +165,28 @@ const detailRows = computed(() => {
|
|
|
return [
|
|
return [
|
|
|
{ label: '截止日期', value: d?.endTimeValue || EMPTY_TEXT },
|
|
{ label: '截止日期', value: d?.endTimeValue || EMPTY_TEXT },
|
|
|
{ label: '接单对象类型', value: d?.typeidName || EMPTY_TEXT },
|
|
{ label: '接单对象类型', value: d?.typeidName || EMPTY_TEXT },
|
|
|
- { label: '接单对象', value: d?.usernameList?.join(',') || EMPTY_TEXT },
|
|
|
|
|
|
|
+ {
|
|
|
|
|
+ label: '接单对象',
|
|
|
|
|
+ value: Array.isArray(d?.usernameList)
|
|
|
|
|
+ ? d.usernameList.join(',')
|
|
|
|
|
+ : d?.usernameList || EMPTY_TEXT,
|
|
|
|
|
+ },
|
|
|
{ label: '结算渠道', value: d?.subjectLocationName || EMPTY_TEXT },
|
|
{ label: '结算渠道', value: d?.subjectLocationName || EMPTY_TEXT },
|
|
|
{ label: '关联服务企业', value: d?.relatedServiceName || EMPTY_TEXT },
|
|
{ label: '关联服务企业', value: d?.relatedServiceName || EMPTY_TEXT },
|
|
|
{ label: '关联任务积分包', value: d?.relationScoreName || EMPTY_TEXT },
|
|
{ label: '关联任务积分包', value: d?.relationScoreName || EMPTY_TEXT },
|
|
|
{ label: '可分配积分值', value: d?.kfpjf || EMPTY_TEXT },
|
|
{ label: '可分配积分值', value: d?.kfpjf || EMPTY_TEXT },
|
|
|
{ label: '积分包值', value: d?.score || EMPTY_TEXT },
|
|
{ label: '积分包值', value: d?.score || EMPTY_TEXT },
|
|
|
- {
|
|
|
|
|
- label: '接单对象范围',
|
|
|
|
|
- value: d?.packageUserScopeName || EMPTY_TEXT,
|
|
|
|
|
- },
|
|
|
|
|
-
|
|
|
|
|
- // ⭐ 重点优化
|
|
|
|
|
- {
|
|
|
|
|
- label: '推广药品',
|
|
|
|
|
- value: formatDrugList(d?.drugtableName),
|
|
|
|
|
- long: true,
|
|
|
|
|
- },
|
|
|
|
|
-
|
|
|
|
|
|
|
+ { label: '接单对象范围', value: d?.packageUserScopeName || EMPTY_TEXT },
|
|
|
|
|
+ { label: '推广药品', value: formatDrugList(d?.drugtableName), long: true },
|
|
|
{ label: '推广区域', value: areaName.value },
|
|
{ label: '推广区域', value: areaName.value },
|
|
|
{
|
|
{
|
|
|
label: '派工范围',
|
|
label: '派工范围',
|
|
|
- value: d?.dispatchUserScopeName?.join(',') || EMPTY_TEXT,
|
|
|
|
|
|
|
+ value: Array.isArray(d?.dispatchUserScopeName)
|
|
|
|
|
+ ? d.dispatchUserScopeName.join(',')
|
|
|
|
|
+ : d?.dispatchUserScopeName || EMPTY_TEXT,
|
|
|
},
|
|
},
|
|
|
{ label: '测试试卷', value: quizNames.value },
|
|
{ label: '测试试卷', value: quizNames.value },
|
|
|
-
|
|
|
|
|
- {
|
|
|
|
|
- label: '描述',
|
|
|
|
|
- value: d?.description || EMPTY_TEXT,
|
|
|
|
|
- long: true,
|
|
|
|
|
- },
|
|
|
|
|
|
|
+ { label: '描述', value: d?.description || EMPTY_TEXT, long: true },
|
|
|
]
|
|
]
|
|
|
})
|
|
})
|
|
|
|
|
|
|
@@ -160,6 +217,7 @@ const initPage = async () => {
|
|
|
const getScorePackagePageById = async () => {
|
|
const getScorePackagePageById = async () => {
|
|
|
const res = await getScorePackagePageByIdApi(id.value)
|
|
const res = await getScorePackagePageByIdApi(id.value)
|
|
|
packageDetail.value = res.data || null
|
|
packageDetail.value = res.data || null
|
|
|
|
|
+ email.value = res.data?.email || ''
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const getPackageCanTaskList = async () => {
|
|
const getPackageCanTaskList = async () => {
|
|
@@ -167,6 +225,54 @@ const getPackageCanTaskList = async () => {
|
|
|
ruleSections.value = normalizeRuleSections(res.data)
|
|
ruleSections.value = normalizeRuleSections(res.data)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+const openExportPopup = async () => {
|
|
|
|
|
+ resetExportError()
|
|
|
|
|
+ exportPopupVisible.value = true
|
|
|
|
|
+
|
|
|
|
|
+ await nextTick()
|
|
|
|
|
+
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ emailInputFocus.value = true
|
|
|
|
|
+ }, 300)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const resetExportError = () => {
|
|
|
|
|
+ emailError.value = ''
|
|
|
|
|
+ emailInputFocus.value = false
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const submitExportReport = async () => {
|
|
|
|
|
+ const value = email.value.trim()
|
|
|
|
|
+
|
|
|
|
|
+ if (!validateEmail(value)) {
|
|
|
|
|
+ emailError.value = '请输入正确的邮箱地址'
|
|
|
|
|
+ emailInputFocus.value = true
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ exportLoading.value = true
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ await exportZbInfoFormWeiNewApi({
|
|
|
|
|
+ id: id.value,
|
|
|
|
|
+ email: value,
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ exportPopupVisible.value = false
|
|
|
|
|
+
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '报告已发送',
|
|
|
|
|
+ icon: 'none',
|
|
|
|
|
+ })
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ exportLoading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const validateEmail = (value) => {
|
|
|
|
|
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
const normalizeRuleSections = (raw) => {
|
|
const normalizeRuleSections = (raw) => {
|
|
|
if (!raw) return []
|
|
if (!raw) return []
|
|
|
|
|
|
|
@@ -187,7 +293,7 @@ const normalizeRuleSections = (raw) => {
|
|
|
<style lang="scss" scoped>
|
|
<style lang="scss" scoped>
|
|
|
.package-detail {
|
|
.package-detail {
|
|
|
min-height: 100vh;
|
|
min-height: 100vh;
|
|
|
- padding: 24rpx;
|
|
|
|
|
|
|
+ padding: 24rpx 24rpx 164rpx;
|
|
|
background: #f5f7fa;
|
|
background: #f5f7fa;
|
|
|
|
|
|
|
|
.package-detail__header {
|
|
.package-detail__header {
|
|
@@ -196,6 +302,7 @@ const normalizeRuleSections = (raw) => {
|
|
|
color: #ffffff;
|
|
color: #ffffff;
|
|
|
background: linear-gradient(135deg, #3fa3f1 0%, #2176e8 100%);
|
|
background: linear-gradient(135deg, #3fa3f1 0%, #2176e8 100%);
|
|
|
border-radius: 24rpx;
|
|
border-radius: 24rpx;
|
|
|
|
|
+ box-shadow: 0 12rpx 28rpx rgba(47, 134, 230, 0.24);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.package-detail__title {
|
|
.package-detail__title {
|
|
@@ -341,6 +448,98 @@ const normalizeRuleSections = (raw) => {
|
|
|
border-radius: 999rpx;
|
|
border-radius: 999rpx;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ .bottom-action {
|
|
|
|
|
+ position: fixed;
|
|
|
|
|
+ right: 0;
|
|
|
|
|
+ bottom: 0;
|
|
|
|
|
+ left: 0;
|
|
|
|
|
+ z-index: 0;
|
|
|
|
|
+ padding: 20rpx 24rpx calc(20rpx + env(safe-area-inset-bottom));
|
|
|
|
|
+ background: #ffffff;
|
|
|
|
|
+ box-shadow: 0 -8rpx 24rpx rgba(15, 23, 42, 0.08);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .export-popup {
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ padding: 40rpx 32rpx 24rpx;
|
|
|
|
|
+ background: #ffffff;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .export-popup__close {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ top: 28rpx;
|
|
|
|
|
+ right: 32rpx;
|
|
|
|
|
+ width: 48rpx;
|
|
|
|
|
+ height: 48rpx;
|
|
|
|
|
+ color: #9ca3af;
|
|
|
|
|
+ font-size: 44rpx;
|
|
|
|
|
+ line-height: 44rpx;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .export-popup__header {
|
|
|
|
|
+ padding-right: 64rpx;
|
|
|
|
|
+ margin-bottom: 34rpx;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .export-popup__title {
|
|
|
|
|
+ color: #111827;
|
|
|
|
|
+ font-size: 38rpx;
|
|
|
|
|
+ font-weight: 700;
|
|
|
|
|
+ line-height: 52rpx;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .export-popup__desc {
|
|
|
|
|
+ margin-top: 10rpx;
|
|
|
|
|
+ color: #6b7280;
|
|
|
|
|
+ font-size: 26rpx;
|
|
|
|
|
+ line-height: 38rpx;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .export-popup__body {
|
|
|
|
|
+ margin-bottom: 40rpx;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .export-popup__input-wrap {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ height: 88rpx;
|
|
|
|
|
+ padding: 0 24rpx;
|
|
|
|
|
+ background: #ffffff;
|
|
|
|
|
+ border: 2rpx solid #e5e7eb;
|
|
|
|
|
+ border-radius: 16rpx;
|
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .export-popup__input-wrap--error {
|
|
|
|
|
+ border-color: #ef4444;
|
|
|
|
|
+ background: #fff7f7;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .export-popup__input {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 88rpx;
|
|
|
|
|
+ color: #111827;
|
|
|
|
|
+ font-size: 30rpx;
|
|
|
|
|
+ line-height: 88rpx;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .export-popup__placeholder {
|
|
|
|
|
+ color: #9ca3af;
|
|
|
|
|
+ font-size: 30rpx;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .export-popup__error {
|
|
|
|
|
+ margin-top: 12rpx;
|
|
|
|
|
+ color: #ef4444;
|
|
|
|
|
+ font-size: 24rpx;
|
|
|
|
|
+ line-height: 34rpx;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .export-popup__footer {
|
|
|
|
|
+ padding-bottom: max(20rpx, env(safe-area-inset-bottom));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
.empty {
|
|
.empty {
|
|
|
padding: 80rpx 24rpx;
|
|
padding: 80rpx 24rpx;
|
|
|
color: #9ca3af;
|
|
color: #9ca3af;
|