Compare commits
No commits in common. "main" and "dev-hjf" have entirely different histories.
14
App.vue
14
App.vue
@ -40,7 +40,7 @@ export default {
|
|||||||
if (success) {
|
if (success) {
|
||||||
console.log("IM 初始化成功");
|
console.log("IM 初始化成功");
|
||||||
// IM 初始化成功后,设置全局未读消息监听
|
// IM 初始化成功后,设置全局未读消息监听
|
||||||
// globalUnreadListenerManager.setup();
|
globalUnreadListenerManager.setup();
|
||||||
} else {
|
} else {
|
||||||
console.warn("IM 初始化失败");
|
console.warn("IM 初始化失败");
|
||||||
}
|
}
|
||||||
@ -76,17 +76,6 @@ page {
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.absolute {
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inset-0 {
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inline-block {
|
.inline-block {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
@ -191,7 +180,6 @@ page {
|
|||||||
.pt-5 {
|
.pt-5 {
|
||||||
padding-top: 10rpx;
|
padding-top: 10rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pt-15 {
|
.pt-15 {
|
||||||
padding-top: 30rpx;
|
padding-top: 30rpx;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,33 +0,0 @@
|
|||||||
import { computed, ref, watch } from "vue";
|
|
||||||
import useDebounce from '@/utils/useDebounce'
|
|
||||||
|
|
||||||
export default function usePageList(callback, options = {}) {
|
|
||||||
const keyword = ref('')
|
|
||||||
const list = ref([])
|
|
||||||
const page = ref(1)
|
|
||||||
const pageSize = ref(options.pageSize || 20)
|
|
||||||
const pages = ref(0);
|
|
||||||
const loading = ref(false)
|
|
||||||
const total = ref(0)
|
|
||||||
|
|
||||||
const hasMore = computed(() => page.value < pages.value)
|
|
||||||
|
|
||||||
const handleKeywordChange = useDebounce(() => {
|
|
||||||
getList()
|
|
||||||
}, options.debounce || 1000)
|
|
||||||
|
|
||||||
function changePage(p) {
|
|
||||||
if (loading.value) return
|
|
||||||
page.value = p
|
|
||||||
getList()
|
|
||||||
}
|
|
||||||
|
|
||||||
function getList() {
|
|
||||||
typeof callback === 'function' && callback()
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(keyword, handleKeywordChange);
|
|
||||||
|
|
||||||
return { total, page, pageSize, keyword, list, pages, changePage, loading, hasMore }
|
|
||||||
|
|
||||||
}
|
|
||||||
21
pages.json
21
pages.json
@ -29,27 +29,6 @@
|
|||||||
"disableScroll": true
|
"disableScroll": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"path": "pages/survey/fill",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "问卷",
|
|
||||||
"disableScroll": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/rate/rate-list",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "服务评价",
|
|
||||||
"disableScroll": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/rate/rate-detail",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "服务评价",
|
|
||||||
"disableScroll": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"path": "pages/message/message",
|
"path": "pages/message/message",
|
||||||
"style": {
|
"style": {
|
||||||
|
|||||||
@ -58,13 +58,12 @@ const { useLoad, useShow } = useGuard();
|
|||||||
const { account } = storeToRefs(useAccount());
|
const { account } = storeToRefs(useAccount());
|
||||||
const corpId = ref('');
|
const corpId = ref('');
|
||||||
const teamId = ref('');
|
const teamId = ref('');
|
||||||
const corpUserId = ref('')
|
|
||||||
const enableHis = ref(false);
|
const enableHis = ref(false);
|
||||||
const customers = ref([]);
|
const customers = ref([]);
|
||||||
|
|
||||||
function addArchive() {
|
function addArchive() {
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: `/pages/archive/edit-archive?corpUserId=${corpUserId.value}&teamId=${teamId.value}&corpId=${corpId.value}`
|
url: `/pages/archive/edit-archive?teamId=${teamId.value}&corpId=${corpId.value}`
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +96,6 @@ async function unBindArchive(customer) {
|
|||||||
useLoad(options => {
|
useLoad(options => {
|
||||||
teamId.value = options.teamId;
|
teamId.value = options.teamId;
|
||||||
corpId.value = options.corpId;
|
corpId.value = options.corpId;
|
||||||
corpUserId.value = options.corpUserId;
|
|
||||||
})
|
})
|
||||||
|
|
||||||
useShow(() => {
|
useShow(() => {
|
||||||
|
|||||||
@ -43,7 +43,6 @@ const { account, externalUserId } = storeToRefs(useAccount());
|
|||||||
const { getExternalUserId } = useAccount()
|
const { getExternalUserId } = useAccount()
|
||||||
const corpId = ref('');
|
const corpId = ref('');
|
||||||
const corpName = ref('');
|
const corpName = ref('');
|
||||||
const corpUserId = ref('');
|
|
||||||
const customer = ref({});
|
const customer = ref({});
|
||||||
const customerId = ref('');
|
const customerId = ref('');
|
||||||
const customers = ref([]);
|
const customers = ref([]);
|
||||||
@ -53,6 +52,7 @@ const formItems = ref([]);
|
|||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const teamId = ref('');
|
const teamId = ref('');
|
||||||
const tempRef = ref(null);
|
const tempRef = ref(null);
|
||||||
|
const customerArchive = ref(null);
|
||||||
const verifyVisible = ref(false);
|
const verifyVisible = ref(false);
|
||||||
const visible = ref(false);
|
const visible = ref(false);
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ function change({ title, value }) {
|
|||||||
if (title) {
|
if (title) {
|
||||||
form.value[title] = value;
|
form.value[title] = value;
|
||||||
}
|
}
|
||||||
if (title == 'idCard') {
|
if (title !== 'idCard') return;
|
||||||
const [isIdCard, birthday, gender] = validate.isChinaId(value);
|
const [isIdCard, birthday, gender] = validate.isChinaId(value);
|
||||||
if (isIdCard) {
|
if (isIdCard) {
|
||||||
form.value.birthday = birthday;
|
form.value.birthday = birthday;
|
||||||
@ -72,11 +72,6 @@ function change({ title, value }) {
|
|||||||
const age = dayjs().diff(birthday, 'year');
|
const age = dayjs().diff(birthday, 'year');
|
||||||
form.value.age = Math.max(1, age);
|
form.value.age = Math.max(1, age);
|
||||||
}
|
}
|
||||||
} else if (title === 'birthday' && formItems.value.some(i => i.title === 'age') && value && dayjs(value).valueOf()) {
|
|
||||||
const age = dayjs().diff(value, 'year');
|
|
||||||
form.value.age = Math.max(1, age);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function confirm() {
|
function confirm() {
|
||||||
@ -141,15 +136,10 @@ async function addArchive() {
|
|||||||
externalUserId: externalUserId.value,
|
externalUserId: externalUserId.value,
|
||||||
realUnionid: account.value.unionid || '',
|
realUnionid: account.value.unionid || '',
|
||||||
}
|
}
|
||||||
if (externalUserId.value) {
|
|
||||||
const corpUserId = await getResponsiblePerson();
|
|
||||||
if (corpUserId) {
|
|
||||||
params.personResponsibles = [{ corpUserId, teamId: teamId.value }]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
const res = await api('addCustomer', { params });
|
const res = await api('addCustomer', { params });
|
||||||
if (res && res.success) {
|
if (res && res.success) {
|
||||||
|
set('home-invite-teamId', teamId.value);
|
||||||
uni.$emit('reloadTeamCustomers')
|
uni.$emit('reloadTeamCustomers')
|
||||||
uni.redirectTo({
|
uni.redirectTo({
|
||||||
url: `/pages/archive/archive-result?corpId=${corpId.value}&teamId=${teamId.value}`
|
url: `/pages/archive/archive-result?corpId=${corpId.value}&teamId=${teamId.value}`
|
||||||
@ -159,21 +149,11 @@ async function addArchive() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getResponsiblePerson() {
|
|
||||||
const res = await api('getResponsiblePerson', { corpId: corpId.value, teamId: teamId.value, externalUserId: externalUserId.value, corpUserId: corpUserId.value });
|
|
||||||
return res && res.data ? res.data : ''
|
|
||||||
}
|
|
||||||
|
|
||||||
async function bindArchive(customerId) {
|
async function bindArchive(customerId) {
|
||||||
let responsiblePerson = '';
|
const res = await api('bindMiniAppArchive', { id: customerId, corpId: corpId.value, teamId: teamId.value, miniAppId: account.value.openid });
|
||||||
if (externalUserId.value) {
|
|
||||||
const corpUserId = await getResponsiblePerson();
|
|
||||||
responsiblePerson = corpUserId || '';
|
|
||||||
}
|
|
||||||
const res = await api('bindMiniAppArchive', { id: customerId, corpId: corpId.value, teamId: teamId.value, miniAppId: account.value.openid, externalUserId: externalUserId.value, responsiblePerson });
|
|
||||||
if (res && res.success) {
|
if (res && res.success) {
|
||||||
await toast('绑定成功');
|
await toast('绑定成功');
|
||||||
uni.$emit('reloadTeamCustomers')
|
set('home-invite-teamId', teamId.value);
|
||||||
uni.switchTab({
|
uni.switchTab({
|
||||||
url: '/pages/home/home'
|
url: '/pages/home/home'
|
||||||
})
|
})
|
||||||
@ -282,7 +262,6 @@ async function unBindArchive() {
|
|||||||
|
|
||||||
onLoad(options => {
|
onLoad(options => {
|
||||||
customerId.value = options.id || '';
|
customerId.value = options.id || '';
|
||||||
corpUserId.value = options.corpUserId || '';
|
|
||||||
uni.setNavigationBarTitle({ title: customerId.value ? '编辑档案' : '新增档案' })
|
uni.setNavigationBarTitle({ title: customerId.value ? '编辑档案' : '新增档案' })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
<template>
|
<template>
|
||||||
<full-page mainClass="bg-white">
|
|
||||||
<view class="article-detail-page">
|
<view class="article-detail-page">
|
||||||
<view v-if="loading" class="loading-container">
|
<view v-if="loading" class="loading-container">
|
||||||
<uni-icons type="spinner-cycle" size="40" color="#999" />
|
<uni-icons type="spinner-cycle" size="40" color="#999" />
|
||||||
@ -23,12 +22,10 @@
|
|||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
</full-page>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onLoad } from "@dcloudio/uni-app";
|
import { onLoad } from "@dcloudio/uni-app";
|
||||||
import FullPage from "@/components/full-page.vue";
|
|
||||||
import api from "@/utils/api.js";
|
import api from "@/utils/api.js";
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import { storeToRefs } from "pinia";
|
import { storeToRefs } from "pinia";
|
||||||
@ -43,15 +40,15 @@ const articleData = ref({
|
|||||||
});
|
});
|
||||||
|
|
||||||
let articleId = "";
|
let articleId = "";
|
||||||
const corpId = ref("");
|
const corpId = ref('')
|
||||||
|
|
||||||
const markArticleRead = async (sendId) => {
|
const markArticleRead = async () => {
|
||||||
const unionid = account.value?.unionid;
|
const unionid = account.value?.unionid;
|
||||||
if (!unionid || !articleId) return;
|
if (!unionid || !articleId) return;
|
||||||
try {
|
try {
|
||||||
await api(
|
await api(
|
||||||
"addArticleReadRecord",
|
"addArticleReadRecord",
|
||||||
{ corpId: corpId.value, articleId, unionid, sendId },
|
{ corpId: corpId.value, articleId, unionid },
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -94,10 +91,7 @@ const loadArticle = async () => {
|
|||||||
loading.value = true;
|
loading.value = true;
|
||||||
error.value = "";
|
error.value = "";
|
||||||
try {
|
try {
|
||||||
const res = await api("getArticle", {
|
const res = await api("getArticle", { id: articleId, corpId: corpId.value });
|
||||||
id: articleId,
|
|
||||||
corpId: corpId.value,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (res.success && res.data) {
|
if (res.success && res.data) {
|
||||||
// 格式化日期
|
// 格式化日期
|
||||||
@ -130,7 +124,7 @@ onLoad((options) => {
|
|||||||
corpId.value = options.corpId;
|
corpId.value = options.corpId;
|
||||||
if (options.id) {
|
if (options.id) {
|
||||||
articleId = options.id;
|
articleId = options.id;
|
||||||
markArticleRead(options.sendId || '');
|
markArticleRead();
|
||||||
loadArticle();
|
loadArticle();
|
||||||
} else {
|
} else {
|
||||||
error.value = "文章信息不完整";
|
error.value = "文章信息不完整";
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<full-page pageClass="bg-gray-100">
|
<view class="bg-gray-100 min-h-screen">
|
||||||
<template #header>
|
<!-- Filter Tabs -->
|
||||||
<scroll-view scroll-x class="bg-white whitespace-nowrap px-15 py-10 sticky top-0 z-10 w-full"
|
<scroll-view scroll-x class="bg-white whitespace-nowrap px-15 py-10 sticky top-0 z-10 w-full"
|
||||||
:show-scrollbar="false">
|
:show-scrollbar="false">
|
||||||
<view v-for="(tab, index) in tabs" :key="index"
|
<view v-for="(tab, index) in tabs" :key="index"
|
||||||
@ -12,7 +12,7 @@
|
|||||||
{{ tab.name }}
|
{{ tab.name }}
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</template>
|
|
||||||
<!-- Article List -->
|
<!-- Article List -->
|
||||||
<view v-if="loading && articles.length === 0" class="loading-container">
|
<view v-if="loading && articles.length === 0" class="loading-container">
|
||||||
<uni-icons type="spinner-cycle" size="30" color="#999" />
|
<uni-icons type="spinner-cycle" size="30" color="#999" />
|
||||||
@ -74,7 +74,7 @@
|
|||||||
没有更多了
|
没有更多了
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</full-page>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@ -84,8 +84,6 @@ import { storeToRefs } from "pinia";
|
|||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import api from "@/utils/api.js";
|
import api from "@/utils/api.js";
|
||||||
import useAccountStore from "@/store/account.js";
|
import useAccountStore from "@/store/account.js";
|
||||||
|
|
||||||
import fullPage from "@/components/full-page.vue";
|
|
||||||
import EmptyData from "@/components/empty-data.vue";
|
import EmptyData from "@/components/empty-data.vue";
|
||||||
|
|
||||||
const { account, openid } = storeToRefs(useAccountStore());
|
const { account, openid } = storeToRefs(useAccountStore());
|
||||||
@ -100,7 +98,6 @@ const pageSize = 20;
|
|||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const inited = ref(false);
|
const inited = ref(false);
|
||||||
const corpId = ref('');
|
const corpId = ref('');
|
||||||
const teamId = ref('');
|
|
||||||
|
|
||||||
const selectTab = async (customerId) => {
|
const selectTab = async (customerId) => {
|
||||||
if (activeTab.value === customerId) return;
|
if (activeTab.value === customerId) return;
|
||||||
@ -142,7 +139,6 @@ const mapRowToView = (row) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const loadArticleList = async (reset = false) => {
|
const loadArticleList = async (reset = false) => {
|
||||||
const customerIds = tabs.value.map(i => i.value).filter(Boolean);
|
|
||||||
if (loading.value) return;
|
if (loading.value) return;
|
||||||
const unionid = account.value?.unionid;
|
const unionid = account.value?.unionid;
|
||||||
const miniAppId = openid.value || uni.getStorageSync("openid");
|
const miniAppId = openid.value || uni.getStorageSync("openid");
|
||||||
@ -156,12 +152,6 @@ const loadArticleList = async (reset = false) => {
|
|||||||
articles.value = [];
|
articles.value = [];
|
||||||
total.value = 0;
|
total.value = 0;
|
||||||
}
|
}
|
||||||
if (customerIds.length === 0) {
|
|
||||||
page.value = 1;
|
|
||||||
articles.value = [];
|
|
||||||
total.value = 0;
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
try {
|
try {
|
||||||
@ -171,10 +161,8 @@ const loadArticleList = async (reset = false) => {
|
|||||||
miniAppId,
|
miniAppId,
|
||||||
page: page.value,
|
page: page.value,
|
||||||
pageSize,
|
pageSize,
|
||||||
customerIds,
|
|
||||||
teamId: teamId.value
|
|
||||||
};
|
};
|
||||||
if (activeTab.value) params.customerIds = [activeTab.value];
|
if (activeTab.value) params.customerId = activeTab.value;
|
||||||
|
|
||||||
const res = await api("getMiniAppReceivedArticleList", params);
|
const res = await api("getMiniAppReceivedArticleList", params);
|
||||||
if (res && res.success) {
|
if (res && res.success) {
|
||||||
@ -196,11 +184,10 @@ const loadArticleList = async (reset = false) => {
|
|||||||
|
|
||||||
function goToDetail(item) {
|
function goToDetail(item) {
|
||||||
if (!item?.articleId) return;
|
if (!item?.articleId) return;
|
||||||
uni.navigateTo({ url: `/pages/article/article-detail?sendId=${item._id}&id=${item.articleId}&corpId=${corpId.value}` });
|
uni.navigateTo({ url: `/pages/article/article-detail?id=${item.articleId}&corpId=${corpId.value}` });
|
||||||
}
|
}
|
||||||
onLoad(opts => {
|
onLoad(opts => {
|
||||||
corpId.value = opts.corpId;
|
corpId.value = opts.corpId;
|
||||||
teamId.value = opts.teamId;
|
|
||||||
})
|
})
|
||||||
|
|
||||||
onShow(async () => {
|
onShow(async () => {
|
||||||
|
|||||||
@ -4,9 +4,8 @@
|
|||||||
|
|
||||||
<view class="consult-grid">
|
<view class="consult-grid">
|
||||||
<view class="consult-item" v-for="item in consultItems" :key="item.id" @click="handleItemClick(item)">
|
<view class="consult-item" v-for="item in consultItems" :key="item.id" @click="handleItemClick(item)">
|
||||||
<view class="relative item-icon">
|
<view class="item-icon">
|
||||||
<image :src="item.icon" class="icon-img" mode="aspectFill" />
|
<image :src="item.icon" class="icon-img" mode="aspectFill" />
|
||||||
<view v-if="badgeMap[item.badge]" class="item-dot"></view>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="item-label">{{ item.label }}</view>
|
<view class="item-label">{{ item.label }}</view>
|
||||||
</view>
|
</view>
|
||||||
@ -19,7 +18,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, watch } from "vue";
|
import { ref, computed } from "vue";
|
||||||
import { storeToRefs } from "pinia";
|
import { storeToRefs } from "pinia";
|
||||||
import useAccount from "@/store/account";
|
import useAccount from "@/store/account";
|
||||||
import api from "@/utils/api";
|
import api from "@/utils/api";
|
||||||
@ -47,8 +46,6 @@ const props = defineProps({
|
|||||||
|
|
||||||
const { account } = storeToRefs(useAccount());
|
const { account } = storeToRefs(useAccount());
|
||||||
const consultantPopup = ref(null);
|
const consultantPopup = ref(null);
|
||||||
const badgeMap = ref({});
|
|
||||||
let loading = false;
|
|
||||||
|
|
||||||
const consultItems = ref([
|
const consultItems = ref([
|
||||||
{
|
{
|
||||||
@ -56,28 +53,24 @@ const consultItems = ref([
|
|||||||
label: "聊天咨询",
|
label: "聊天咨询",
|
||||||
icon: "/static/home/chat-consult.png",
|
icon: "/static/home/chat-consult.png",
|
||||||
needSelectConsultant: true,
|
needSelectConsultant: true,
|
||||||
badge: 'chat'
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "education",
|
id: "education",
|
||||||
label: "我的宣教",
|
label: "我的宣教",
|
||||||
icon: "/static/home/my-education.png",
|
icon: "/static/home/my-education.png",
|
||||||
path: "/pages/article/article-list",
|
path: "/pages/article/article-list",
|
||||||
badge: 'article'
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "survey",
|
id: "survey",
|
||||||
label: "我的问卷",
|
label: "我的问卷",
|
||||||
icon: "/static/home/my-questionnaire.png",
|
icon: "/static/home/my-questionnaire.png",
|
||||||
path: "/pages/survey/survey-list",
|
path: "/pages/survey/survey-list",
|
||||||
badge: 'survey'
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "rating",
|
id: "rating",
|
||||||
label: "服务评价",
|
label: "服务评价",
|
||||||
icon: "/static/home/service-rating.png",
|
icon: "/static/home/service-rating.png",
|
||||||
path: "/pages/rate/rate-list",
|
path: "",
|
||||||
badge: 'rate'
|
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -163,32 +156,6 @@ function handleAddNewArchive() {
|
|||||||
url: `/pages/archive/edit-archive?corpId=${props.corpId}&teamId=${props.teamId}`,
|
url: `/pages/archive/edit-archive?corpId=${props.corpId}&teamId=${props.teamId}`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getBadgeCount() {
|
|
||||||
if (loading) return;
|
|
||||||
loading = true;
|
|
||||||
const customerIds = props.customers.map((item) => item._id);
|
|
||||||
if (customerIds.length === 0) {
|
|
||||||
badgeMap.value = {};
|
|
||||||
loading = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const res = await api('getMiniAppHomeStats', { corpId: props.corpId, teamId: props.teamId, customerIds }, false)
|
|
||||||
const data = res?.data || {};
|
|
||||||
const article = typeof data.article === 'number' ? data.article : 0;
|
|
||||||
const survey = typeof data.survey === 'number' ? data.survey : 0;
|
|
||||||
const rate = typeof data.rate === 'number' ? data.rate : 0;
|
|
||||||
badgeMap.value = { article, survey, rate };
|
|
||||||
loading = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(() => [props.customers, props.teamId, props.corpId], n => {
|
|
||||||
getBadgeCount()
|
|
||||||
}, { immediate: true })
|
|
||||||
|
|
||||||
defineExpose({
|
|
||||||
getBadgeCount,
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@ -237,16 +204,6 @@ defineExpose({
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.item-dot {
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
top: 0;
|
|
||||||
width: 20rpx;
|
|
||||||
height: 20rpx;
|
|
||||||
background: red;
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.consult-item:active .item-icon {
|
.consult-item:active .item-icon {
|
||||||
transform: scale(0.95);
|
transform: scale(0.95);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -82,10 +82,6 @@ const props = defineProps({
|
|||||||
type: String,
|
type: String,
|
||||||
default: "",
|
default: "",
|
||||||
},
|
},
|
||||||
corpUserIds: {
|
|
||||||
type: Object,
|
|
||||||
default: () => ({}),
|
|
||||||
},
|
|
||||||
customers: {
|
customers: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
@ -97,10 +93,8 @@ const props = defineProps({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(["update:customers"]);
|
const emit = defineEmits(["update:customers"]);
|
||||||
let loading = false;
|
|
||||||
|
|
||||||
const { account, externalUserId } = storeToRefs(useAccount());
|
const { account } = storeToRefs(useAccount());
|
||||||
const { getExternalUserId } = useAccount()
|
|
||||||
const current = ref(null);
|
const current = ref(null);
|
||||||
const customers = ref([]);
|
const customers = ref([]);
|
||||||
|
|
||||||
@ -148,7 +142,8 @@ function toHealthList() {
|
|||||||
if (canAuth.value) {
|
if (canAuth.value) {
|
||||||
toast("请先授权本服务团队");
|
toast("请先授权本服务团队");
|
||||||
} else {
|
} else {
|
||||||
const name = `${current.value.name} ${current.value.relationship || ""}`;
|
const name = `${current.value.name} ${current.value.relationship ? `(${current.value.relationship})` : ""
|
||||||
|
}`;
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: `/pages/health/list?teamId=${props.team.teamId}&corpId=${props.corpId
|
url: `/pages/health/list?teamId=${props.team.teamId}&corpId=${props.corpId
|
||||||
}&id=${current.value._id}&name=${encodeURIComponent(name)}`,
|
}&id=${current.value._id}&name=${encodeURIComponent(name)}`,
|
||||||
@ -161,20 +156,17 @@ function toggle(i) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function toManagePage() {
|
function toManagePage() {
|
||||||
const corpUserId = props.corpUserIds && props.corpUserIds[props.team.teamId] ? props.corpUserIds[props.team.teamId] : "";
|
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: `/pages/archive/archive-manage?corpUserId=${corpUserId}&corpId=${props.corpId}&teamId=${props.team.teamId}`,
|
url: `/pages/archive/archive-manage?corpId=${props.corpId}&teamId=${props.team.teamId}`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function auth() {
|
async function auth() {
|
||||||
await confirm(`是否授权${props.team.name}提供服务`);
|
await confirm(`是否授权${props.team.name}提供服务`);
|
||||||
const corpUserId = await getResponsiblePerson();
|
|
||||||
const res = await api("authCustomerToTeam", {
|
const res = await api("authCustomerToTeam", {
|
||||||
corpId: props.corpId,
|
corpId: props.corpId,
|
||||||
teamId: props.team.teamId,
|
teamId: props.team.teamId,
|
||||||
id: current.value._id,
|
id: current.value._id,
|
||||||
corpUserId
|
|
||||||
});
|
});
|
||||||
if (res && res.success) {
|
if (res && res.success) {
|
||||||
await toast("授权成功");
|
await toast("授权成功");
|
||||||
@ -185,12 +177,10 @@ async function auth() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function getCustomers() {
|
async function getCustomers() {
|
||||||
if (loading) return;
|
|
||||||
loading = true
|
|
||||||
const res = await api("getMiniAppCustomers", {
|
const res = await api("getMiniAppCustomers", {
|
||||||
miniAppId: account.value.openid,
|
miniAppId: account.value.openid,
|
||||||
corpId: props.corpId,
|
corpId: props.corpId,
|
||||||
}, false);
|
});
|
||||||
if (res && res.success) {
|
if (res && res.success) {
|
||||||
customers.value = res && Array.isArray(res.data) ? res.data : [];
|
customers.value = res && Array.isArray(res.data) ? res.data : [];
|
||||||
const customer = customers.value.find(
|
const customer = customers.value.find(
|
||||||
@ -202,16 +192,6 @@ async function getCustomers() {
|
|||||||
} else {
|
} else {
|
||||||
toast(res.message || "获取档案失败");
|
toast(res.message || "获取档案失败");
|
||||||
}
|
}
|
||||||
loading = false
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getResponsiblePerson() {
|
|
||||||
if (!externalUserId.value) {
|
|
||||||
await getExternalUserId(props.corpId)
|
|
||||||
}
|
|
||||||
const corpUserId = props.corpUserIds && props.corpUserIds[props.team.teamId] ? props.corpUserIds[props.team.teamId] : "";
|
|
||||||
const res = await api('getResponsiblePerson', { corpId: props.corpId, teamId: props.team.teamId, corpUserId, externalUserId: externalUserId.value });
|
|
||||||
return res && res.data ? res.data : ''
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@ -229,10 +209,6 @@ watch(
|
|||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
defineExpose({
|
|
||||||
getCustomers,
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.archive-container {
|
.archive-container {
|
||||||
|
|||||||
@ -5,11 +5,10 @@
|
|||||||
<team-head :team="team" :teams="teams" @changeTeam="changeTeam" />
|
<team-head :team="team" :teams="teams" @changeTeam="changeTeam" />
|
||||||
</template>
|
</template>
|
||||||
<view class="home-section home-section--first">
|
<view class="home-section home-section--first">
|
||||||
<customer-archive ref="archiveRef" :corpId="corpId" :corpUserIds="corpUserIds" :team="team"
|
<customer-archive :corpId="corpId" :team="team" @update:customers="handleCustomersUpdate" />
|
||||||
@update:customers="handleCustomersUpdate" />
|
|
||||||
</view>
|
</view>
|
||||||
<view class="home-section">
|
<view class="home-section">
|
||||||
<consult ref="consultRef" :corpId="corpId" :teamId="team.teamId" :team="team" :customers="customers" />
|
<consult :corpId="corpId" :teamId="team.teamId" :team="team" :customers="customers" />
|
||||||
</view>
|
</view>
|
||||||
<!-- <view class="home-section">
|
<!-- <view class="home-section">
|
||||||
<team-mate :team="team" />
|
<team-mate :team="team" />
|
||||||
@ -47,9 +46,6 @@ const team = ref(null);
|
|||||||
const teams = ref([]);
|
const teams = ref([]);
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const customers = ref([]);
|
const customers = ref([]);
|
||||||
const consultRef = ref(null);
|
|
||||||
const archiveRef = ref(null);
|
|
||||||
const corpUserIds = ref({});
|
|
||||||
|
|
||||||
const corpId = computed(() => team.value?.corpId);
|
const corpId = computed(() => team.value?.corpId);
|
||||||
|
|
||||||
@ -73,14 +69,15 @@ async function changeTeam({ teamId, corpId, corpName }) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getTeams(inviteTeamId = '') {
|
async function getTeams() {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
const res = await api('getWxappRelateTeams', { openid: account.value.openid });
|
const res = await api('getWxappRelateTeams', { openid: account.value.openid });
|
||||||
teams.value = res && Array.isArray(res.data) ? res.data : [];
|
teams.value = res && Array.isArray(res.data) ? res.data : [];
|
||||||
const matchTeamId = inviteTeamId || (team.value ? team.value.teamId : '');
|
const matchTeamId = get('home-invite-teamId') || (team.value ? team.value.teamId : '');
|
||||||
const validTeam = teams.value.find(i => i.teamId && i.teamId === matchTeamId);
|
const validTeam = teams.value.find(i => i.teamId && i.teamId === matchTeamId);
|
||||||
const firstTeam = teams.value[0]
|
const firstTeam = teams.value[0]
|
||||||
if (validTeam || firstTeam) {
|
if (validTeam || firstTeam) {
|
||||||
|
remove('home-invite-teamId');
|
||||||
changeTeam(validTeam || firstTeam);
|
changeTeam(validTeam || firstTeam);
|
||||||
} else {
|
} else {
|
||||||
team.value = null;
|
team.value = null;
|
||||||
@ -100,24 +97,12 @@ onLoad(() => {
|
|||||||
|
|
||||||
onShow(async () => {
|
onShow(async () => {
|
||||||
if (!account.value) await login();
|
if (!account.value) await login();
|
||||||
const inviteTeam = get('home-invite-team-info');
|
|
||||||
remove('home-invite-team-info');
|
|
||||||
if (inviteTeam && inviteTeam.teamId && inviteTeam.corpUserId) {
|
|
||||||
corpUserIds.value[inviteTeam.teamId] = inviteTeam.corpUserId;
|
|
||||||
}
|
|
||||||
if (account.value && account.value.openid) {
|
if (account.value && account.value.openid) {
|
||||||
getTeams(inviteTeam && inviteTeam.teamId ? inviteTeam.teamId : '');
|
getTeams();
|
||||||
} else {
|
} else {
|
||||||
teams.value = [];
|
teams.value = [];
|
||||||
}
|
}
|
||||||
if (consultRef.value && typeof consultRef.value.getBadgeCount === 'function') {
|
|
||||||
consultRef.value.getBadgeCount()
|
|
||||||
}
|
|
||||||
if (archiveRef.value && typeof archiveRef.value.getCustomers === 'function') {
|
|
||||||
archiveRef.value.getCustomers()
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(account, (n, o) => {
|
watch(account, (n, o) => {
|
||||||
if (n && !o) {
|
if (n && !o) {
|
||||||
getTeams();
|
getTeams();
|
||||||
|
|||||||
@ -110,6 +110,7 @@ async function bindTeam() {
|
|||||||
}
|
}
|
||||||
const res1 = await api('getWxAppCustomerCount', { miniAppId: account.value.openid, corpId: team.value.corpId, teamId: team.value.teamId });
|
const res1 = await api('getWxAppCustomerCount', { miniAppId: account.value.openid, corpId: team.value.corpId, teamId: team.value.teamId });
|
||||||
if (res1 && res1.data > 0) {
|
if (res1 && res1.data > 0) {
|
||||||
|
set('home-invite-teamId', team.value.teamId);
|
||||||
toHome();
|
toHome();
|
||||||
} else {
|
} else {
|
||||||
attempToPage(redirectUrl.value)
|
attempToPage(redirectUrl.value)
|
||||||
@ -142,7 +143,7 @@ async function attempToPage(url) {
|
|||||||
onLoad((opts) => {
|
onLoad((opts) => {
|
||||||
if (opts.source === "teamInvite") {
|
if (opts.source === "teamInvite") {
|
||||||
team.value = get("invite-team-info");
|
team.value = get("invite-team-info");
|
||||||
redirectUrl.value = `/pages/archive/edit-archive?corpUserId=${team.value.corpUserId || ''}&teamId=${team.value.teamId}&corpId=${team.value.corpId}`;
|
redirectUrl.value = `/pages/archive/edit-archive?teamId=${team.value.teamId}&corpId=${team.value.corpId}`;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
redirectUrl.value = opts.redirectUrl || "";
|
redirectUrl.value = opts.redirectUrl || "";
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="flex flex-col justify-center items-center h-full" @click="copy()">
|
<view class="flex flex-col justify-center items-center h-full">
|
||||||
<image class="flash-logo" src="/static/logo-plain.png" />
|
<image class="flash-logo" src="/static/logo-plain.png" />
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
@ -19,30 +19,18 @@ const { account } = storeToRefs(useAccountStore());
|
|||||||
|
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const team = ref(null);
|
const team = ref(null);
|
||||||
const opts = ref('');
|
|
||||||
|
|
||||||
function copy() {
|
async function changeTeam({ teamId, corpId }) {
|
||||||
uni.setClipboardData({
|
|
||||||
data: opts.value || '暂无内容'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async function changeTeam({ teamId, corpId, corpUserId }) {
|
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
const res = await api("getTeamData", { teamId, corpId, withCorpName: true });
|
const res = await api("getTeamData", { teamId, corpId, withCorpName: true });
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
if (res && res.data) {
|
if (res && res.data) {
|
||||||
team.value = res.data;
|
team.value = res.data;
|
||||||
team.value.corpName = res.data.corpName;
|
team.value.corpName = res.data.corpName;
|
||||||
set('home-invite-team-info', {
|
|
||||||
teamId: team.value.teamId,
|
|
||||||
corpUserId: corpUserId || ''
|
|
||||||
});
|
|
||||||
if (account.value) {
|
if (account.value) {
|
||||||
bindTeam(corpUserId)
|
bindTeam()
|
||||||
} else {
|
} else {
|
||||||
set("invite-team-info", {
|
set("invite-team-info", {
|
||||||
corpUserId,
|
|
||||||
corpId: team.value.corpId,
|
corpId: team.value.corpId,
|
||||||
teamId: team.value.teamId,
|
teamId: team.value.teamId,
|
||||||
corpName: team.value.corpName,
|
corpName: team.value.corpName,
|
||||||
@ -61,25 +49,25 @@ async function changeTeam({ teamId, corpId, corpUserId }) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function bindTeam(corpUserId) {
|
async function bindTeam() {
|
||||||
const res = await api('bindWxappWithTeam', { appid, corpId: team.value.corpId, teamId: team.value.teamId, openid: account.value.openid });
|
const res = await api('bindWxappWithTeam', { appid, corpId: team.value.corpId, teamId: team.value.teamId, openid: account.value.openid });
|
||||||
if (!res || !res.success) {
|
if (!res || !res.success) {
|
||||||
return toast("关联团队失败");
|
return toast("关联团队失败");
|
||||||
}
|
}
|
||||||
const res1 = await api('getWxAppCustomerCount', { miniAppId: account.value.openid, corpId: team.value.corpId, teamId: team.value.teamId });
|
const res1 = await api('getWxAppCustomerCount', { miniAppId: account.value.openid, corpId: team.value.corpId, teamId: team.value.teamId });
|
||||||
if (res1 && res1.data > 0) {
|
if (res1 && res1.data > 0) {
|
||||||
|
set('home-invite-teamId', team.value.teamId);
|
||||||
uni.switchTab({
|
uni.switchTab({
|
||||||
url: "/pages/home/home",
|
url: "/pages/home/home",
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
uni.redirectTo({
|
uni.redirectTo({
|
||||||
url: `/pages/archive/edit-archive?corpUserId=${corpUserId || ''}&teamId=${team.value.teamId}&corpId=${team.value.corpId}`
|
url: `/pages/archive/edit-archive?teamId=${team.value.teamId}&corpId=${team.value.corpId}`
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onLoad((options) => {
|
onLoad((options) => {
|
||||||
opts.value = JSON.stringify(options)
|
|
||||||
const href =
|
const href =
|
||||||
typeof options.q === "string" ? decodeURIComponent(options.q) : "";
|
typeof options.q === "string" ? decodeURIComponent(options.q) : "";
|
||||||
const [, url = ""] = href.split("?");
|
const [, url = ""] = href.split("?");
|
||||||
|
|||||||
@ -407,7 +407,7 @@ $primary-color: #0877F1;
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 12rpx 20rpx;
|
padding: 12rpx 20rpx;
|
||||||
padding-bottom: 40rpx;
|
padding-bottom: env(safe-area-inset-bottom);
|
||||||
gap: 12rpx;
|
gap: 12rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -514,7 +514,7 @@ $primary-color: #0877F1;
|
|||||||
background: #fff;
|
background: #fff;
|
||||||
border-top: 1rpx solid #eee;
|
border-top: 1rpx solid #eee;
|
||||||
padding: 20rpx 0 20rpx 60rpx;
|
padding: 20rpx 0 20rpx 60rpx;
|
||||||
padding-bottom: 40rpx;
|
padding-bottom: env(safe-area-inset-bottom);
|
||||||
gap: 40rpx 50rpx;
|
gap: 40rpx 50rpx;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
@ -544,7 +544,7 @@ $primary-color: #0877F1;
|
|||||||
background-color: white;
|
background-color: white;
|
||||||
border-top: 1rpx solid #e0e0e0;
|
border-top: 1rpx solid #e0e0e0;
|
||||||
padding: 16rpx;
|
padding: 16rpx;
|
||||||
margin-bottom: 40rpx;
|
margin-bottom: env(safe-area-inset-bottom);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@ -689,7 +689,7 @@ $primary-color: #0877F1;
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
max-height: 80vh;
|
max-height: 80vh;
|
||||||
padding: 20rpx;
|
padding: 20rpx;
|
||||||
padding-bottom: calc(20rpx + 40rpx);
|
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
|
||||||
position: relative;
|
position: relative;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@ -821,7 +821,7 @@ $primary-color: #0877F1;
|
|||||||
background-color: white;
|
background-color: white;
|
||||||
width: auto;
|
width: auto;
|
||||||
padding: 32rpx 20rpx 48rpx 20rpx;
|
padding: 32rpx 20rpx 48rpx 20rpx;
|
||||||
padding-bottom: calc(48rpx + 40rpx);
|
padding-bottom: calc(48rpx + env(safe-area-inset-bottom));
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
@ -36,8 +36,6 @@ const handleApply = () => {
|
|||||||
padding: 20rpx 32rpx;
|
padding: 20rpx 32rpx;
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
position:absolute;
|
|
||||||
bottom: 40rpx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.apply-card {
|
.apply-card {
|
||||||
|
|||||||
@ -12,10 +12,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
const emit = defineEmits(["cancel"]);
|
|
||||||
|
const emit = defineEmits(['cancel']);
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
emit("cancel");
|
emit('cancel');
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -25,8 +26,6 @@ const handleCancel = () => {
|
|||||||
padding: 20rpx 32rpx;
|
padding: 20rpx 32rpx;
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
position: absolute;
|
|
||||||
bottom: 40rpx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.cancel-card {
|
.cancel-card {
|
||||||
|
|||||||
@ -195,9 +195,9 @@ const getArticleData = (message) => {
|
|||||||
|
|
||||||
// 处理文章点击
|
// 处理文章点击
|
||||||
const handleArticleClick = (message) => {
|
const handleArticleClick = (message) => {
|
||||||
const { articleId, sendId } = getArticleData(message);
|
const { articleId } = getArticleData(message);
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: `/pages/article/article-detail?id=${articleId}&sendId=${sendId || ''}&corpId=${props.corpId}`,
|
url: `/pages/article/article-detail?id=${articleId}&corpId=${props.corpId}`,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -207,7 +207,6 @@ const getSurveyData = (message) => {
|
|||||||
if (message.payload && message.payload.data) {
|
if (message.payload && message.payload.data) {
|
||||||
const data = JSON.parse(message.payload.data);
|
const data = JSON.parse(message.payload.data);
|
||||||
return {
|
return {
|
||||||
...data,
|
|
||||||
title: data.title || "填写问卷",
|
title: data.title || "填写问卷",
|
||||||
desc: data.desc || "请填写问卷",
|
desc: data.desc || "请填写问卷",
|
||||||
url: data.url || "",
|
url: data.url || "",
|
||||||
@ -222,26 +221,18 @@ const getSurveyData = (message) => {
|
|||||||
desc: "请填写问卷",
|
desc: "请填写问卷",
|
||||||
url: "",
|
url: "",
|
||||||
imgUrl: "",
|
imgUrl: "",
|
||||||
err: true
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// 处理问卷点击
|
// 处理问卷点击
|
||||||
const handleSurveyClick = (message) => {
|
const handleSurveyClick = (message) => {
|
||||||
const surveyData = getSurveyData(message);
|
const surveyData = getSurveyData(message);
|
||||||
if (surveyData.err) {
|
if (surveyData.url) {
|
||||||
return
|
// 跳转到问卷填写页面或打开外部链接
|
||||||
}
|
console.log("打开问卷:", surveyData.url);
|
||||||
if (surveyData.isSystem) {
|
// uni.navigateTo({
|
||||||
uni.navigateTo({
|
// url: `/pages/survey/fill?url=${encodeURIComponent(surveyData.url)}`
|
||||||
url: `/pages/web-view/web-view?src=${encodeURIComponent(surveyData.url)}`
|
// });
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (surveyData.answerId) {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: `/pages/survey/fill?name=${surveyData.name}&memberId=${surveyData.memberId}&surveryId=${surveyData.surveryId}&corpId=${surveyData.corpId}&answerId=${surveyData.answerId}`
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -58,8 +58,8 @@ export default function useGroupChat(groupID) {
|
|||||||
return member.isTeamMember ? '/static/default-avatar.png' : '/static/default-patient-avatar.png'
|
return member.isTeamMember ? '/static/default-avatar.png' : '/static/default-patient-avatar.png'
|
||||||
}
|
}
|
||||||
// 获取群聊信息和成员头像
|
// 获取群聊信息和成员头像
|
||||||
async function getGroupInfo(id) {
|
async function getGroupInfo() {
|
||||||
const gid = id || groupID;
|
const gid = typeof groupID === 'string' ? groupID : groupID.value
|
||||||
if (!gid) return
|
if (!gid) return
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -73,8 +73,10 @@ export default function useGroupChat(groupID) {
|
|||||||
status: groupResult.data.orderStatus || 'active',
|
status: groupResult.data.orderStatus || 'active',
|
||||||
teamId: groupResult.data.teamId
|
teamId: groupResult.data.teamId
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 如果有teamId,获取团队成员头像和名称
|
// 2. 如果有teamId,获取团队成员头像和名称
|
||||||
if (groupResult.data.teamId) {
|
if (groupResult.data.teamId) {
|
||||||
|
|
||||||
const memberMap = await teamStore.getTeamMemberAvatarsAndName(groupResult.data.teamId)
|
const memberMap = await teamStore.getTeamMemberAvatarsAndName(groupResult.data.teamId)
|
||||||
|
|
||||||
// 3. 存储团队成员ID列表
|
// 3. 存储团队成员ID列表
|
||||||
@ -110,14 +112,13 @@ export default function useGroupChat(groupID) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// onShow(() => {
|
onShow(() => {
|
||||||
|
getGroupInfo()
|
||||||
|
})
|
||||||
|
|
||||||
// getGroupInfo()
|
onUnload(() => {
|
||||||
// })
|
// 清理资源
|
||||||
|
})
|
||||||
// onUnload(() => {
|
|
||||||
// // 清理资源
|
|
||||||
// })
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
groupInfo,
|
groupInfo,
|
||||||
|
|||||||
@ -444,7 +444,7 @@ function getBubbleClass(message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 页面加载
|
// 页面加载
|
||||||
onLoad(async (options) => {
|
onLoad((options) => {
|
||||||
groupId.value = options.groupID || "";
|
groupId.value = options.groupID || "";
|
||||||
messageList.value = [];
|
messageList.value = [];
|
||||||
isLoading.value = false;
|
isLoading.value = false;
|
||||||
@ -456,7 +456,7 @@ onLoad(async (options) => {
|
|||||||
if (options.userID) {
|
if (options.userID) {
|
||||||
chatInfo.value.userID = options.userID;
|
chatInfo.value.userID = options.userID;
|
||||||
}
|
}
|
||||||
await getGroupInfo(groupId.value);
|
|
||||||
// 监听键盘高度变化
|
// 监听键盘高度变化
|
||||||
uni.onKeyboardHeightChange((res) => {
|
uni.onKeyboardHeightChange((res) => {
|
||||||
console.log("键盘高度变化:", res.height);
|
console.log("键盘高度变化:", res.height);
|
||||||
@ -473,8 +473,6 @@ onLoad(async (options) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 先获取群组信息和成员信息,确保 chatMember 已初始化
|
|
||||||
|
|
||||||
checkLoginAndInitTIM();
|
checkLoginAndInitTIM();
|
||||||
updateNavigationTitle();
|
updateNavigationTitle();
|
||||||
});
|
});
|
||||||
@ -565,7 +563,7 @@ const initTIMCallbacks = async () => {
|
|||||||
.then(async () => {
|
.then(async () => {
|
||||||
console.log("✓ 收到新消息后已标记为已读");
|
console.log("✓ 收到新消息后已标记为已读");
|
||||||
// 标记为已读后,立即刷新 tabBar 徽章
|
// 标记为已读后,立即刷新 tabBar 徽章
|
||||||
// await globalUnreadListenerManager.refreshBadge();
|
await globalUnreadListenerManager.refreshBadge();
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error("✗ 标记已读失败:", error);
|
console.error("✗ 标记已读失败:", error);
|
||||||
@ -719,7 +717,7 @@ const loadMessageList = async () => {
|
|||||||
.then(async () => {
|
.then(async () => {
|
||||||
console.log("✓ 会话已标记为已读:", chatInfo.value.conversationID);
|
console.log("✓ 会话已标记为已读:", chatInfo.value.conversationID);
|
||||||
// 标记为已读后,立即刷新 tabBar 徽章
|
// 标记为已读后,立即刷新 tabBar 徽章
|
||||||
// await globalUnreadListenerManager.refreshBadge();
|
await globalUnreadListenerManager.refreshBadge();
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error("✗ 标记会话已读失败:", error);
|
console.error("✗ 标记会话已读失败:", error);
|
||||||
@ -915,10 +913,10 @@ onHide(() => {
|
|||||||
timChatManager.currentConversationID = null;
|
timChatManager.currentConversationID = null;
|
||||||
console.log("✓ 页面隐藏,已清空当前会话ID");
|
console.log("✓ 页面隐藏,已清空当前会话ID");
|
||||||
|
|
||||||
// // 页面隐藏时刷新 tabBar 徽章,确保显示正确的未读数
|
// 页面隐藏时刷新 tabBar 徽章,确保显示正确的未读数
|
||||||
// if (globalUnreadListenerManager.isInitialized) {
|
if (globalUnreadListenerManager.isInitialized) {
|
||||||
// globalUnreadListenerManager.refreshBadge();
|
globalUnreadListenerManager.refreshBadge();
|
||||||
// }
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 处理取消申请
|
// 处理取消申请
|
||||||
|
|||||||
@ -380,8 +380,8 @@ const setupConversationListener = () => {
|
|||||||
// 将回调添加到全局未读监听器的回调链中
|
// 将回调添加到全局未读监听器的回调链中
|
||||||
// 这样不会覆盖全局未读监听器,而是与之共存
|
// 这样不会覆盖全局未读监听器,而是与之共存
|
||||||
if (globalUnreadListenerManager.isInitialized) {
|
if (globalUnreadListenerManager.isInitialized) {
|
||||||
// globalUnreadListenerManager.addCallback("onConversationListUpdated", handleConversationListUpdate);
|
globalUnreadListenerManager.addCallback("onConversationListUpdated", handleConversationListUpdate);
|
||||||
// globalUnreadListenerManager.addCallback("onMessageReceived", handleMessageReceived);
|
globalUnreadListenerManager.addCallback("onMessageReceived", handleMessageReceived);
|
||||||
console.log("【消息列表页】已添加回调到全局监听器回调链");
|
console.log("【消息列表页】已添加回调到全局监听器回调链");
|
||||||
} else {
|
} else {
|
||||||
console.warn("【消息列表页】全局未读监听器未初始化,使用直接回调方式");
|
console.warn("【消息列表页】全局未读监听器未初始化,使用直接回调方式");
|
||||||
@ -454,7 +454,7 @@ const handleClickConversation = async (conversation) => {
|
|||||||
console.log("✓ 已标记会话为已读:", conversation.conversationID);
|
console.log("✓ 已标记会话为已读:", conversation.conversationID);
|
||||||
|
|
||||||
// 立即刷新 tabBar 徽章
|
// 立即刷新 tabBar 徽章
|
||||||
// await globalUnreadListenerManager.refreshBadge();
|
await globalUnreadListenerManager.refreshBadge();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("✗ 标记会话已读失败:", error);
|
console.error("✗ 标记会话已读失败:", error);
|
||||||
}
|
}
|
||||||
@ -514,9 +514,9 @@ const cleanMessageText = (text) => {
|
|||||||
// 页面显示
|
// 页面显示
|
||||||
onShow(async () => {
|
onShow(async () => {
|
||||||
// 页面显示时刷新 tabBar 徽章
|
// 页面显示时刷新 tabBar 徽章
|
||||||
// if (globalUnreadListenerManager.isInitialized) {
|
if (globalUnreadListenerManager.isInitialized) {
|
||||||
// await globalUnreadListenerManager.refreshBadge();
|
await globalUnreadListenerManager.refreshBadge();
|
||||||
// }
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 页面隐藏
|
// 页面隐藏
|
||||||
@ -544,12 +544,12 @@ onUnmounted(() => {
|
|||||||
updateTimer = null;
|
updateTimer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// // 从全局未读监听器的回调链中移除本页面的回调
|
// 从全局未读监听器的回调链中移除本页面的回调
|
||||||
// if (globalUnreadListenerManager.isInitialized) {
|
if (globalUnreadListenerManager.isInitialized) {
|
||||||
// globalUnreadListenerManager.removeCallback("onConversationListUpdated", handleConversationListUpdate);
|
globalUnreadListenerManager.removeCallback("onConversationListUpdated", handleConversationListUpdate);
|
||||||
// globalUnreadListenerManager.removeCallback("onMessageReceived", handleMessageReceived);
|
globalUnreadListenerManager.removeCallback("onMessageReceived", handleMessageReceived);
|
||||||
// console.log("【消息列表页】已从回调链移除回调");
|
console.log("【消息列表页】已从回调链移除回调");
|
||||||
// }
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -1,251 +0,0 @@
|
|||||||
<template>
|
|
||||||
<full-page v-if="record">
|
|
||||||
<view class="flex items-center px-15 py-10 border-b">
|
|
||||||
<view>
|
|
||||||
<image class="box-50" :src="record.avatar"></image>
|
|
||||||
</view>
|
|
||||||
<view class="ml-10">
|
|
||||||
<view class="text-base font-semibold leading-normal">
|
|
||||||
{{ record.userName || "" }}
|
|
||||||
</view>
|
|
||||||
<view class="text-sm text-gray">{{ record.job }}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="px-15 py-10">
|
|
||||||
<view class="text-base mb-10">请您对我的本次服务进行评价</view>
|
|
||||||
<view class="flex items-center px-10 py-5 mb-10 border rounded">
|
|
||||||
<view v-for="i in 5" :key="i" class="mr-5 w-star" @click="changeRate(i)">
|
|
||||||
<uni-icons v-if="i <= starCount" type="star-filled" :size="30" color="#FF9900"></uni-icons>
|
|
||||||
<uni-icons v-else type="star" :size="30" color="#FF9900"></uni-icons>
|
|
||||||
</view>
|
|
||||||
<view class="flex-shrink-0 w-star text-sm text-primary whitespace-nowrap">
|
|
||||||
{{ rateText }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<template v-if="enable">
|
|
||||||
<view class="flex flex-wrap text-sm">
|
|
||||||
<view v-for="tag in tags" :key="tag._id"
|
|
||||||
class="py-5 px-10 mr-10 mb-10 max-w-full break-all rounded-full bg-gray border" :class="selectedTag[tag._id]
|
|
||||||
? 'text-white bg-primary border-primary'
|
|
||||||
: ''
|
|
||||||
" @click="toggle(tag)">
|
|
||||||
{{ tag.text }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="px-10 py-5 border rounded">
|
|
||||||
<textarea v-model="words" :auto-height="true" class="text-base block w-full min-h-100"
|
|
||||||
placeholder="展开说说您对我本次服务的想法吧……" placeholder-class="text-gray text-base" :maxlength="1000" />
|
|
||||||
<view class="text-gray text-right">
|
|
||||||
{{ words.length }} / {{ 1000 }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
<template v-else>
|
|
||||||
<view v-if="record.tags && record.tags.length" class="flex flex-wrap text-sm">
|
|
||||||
<view v-for="(tag, i) in record.tags" :key="i"
|
|
||||||
class="py-5 px-10 mr-10 mb-10 max-w-full break-all rounded-full text-white bg-primary border-primary border-[1px] border-solid">
|
|
||||||
{{ tag }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view v-if="record.words && record.words.length"
|
|
||||||
class="px-10 py-5 border border-solid border-gray-100 rounded pointer-events-none">
|
|
||||||
<textarea :value="record.words" :disabled="true" class="text-sm block w-full min-h-[100px]"
|
|
||||||
placeholder-class="text-gray text-sm" :maxlength="1000" />
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
<view class="h-20"></view>
|
|
||||||
</view>
|
|
||||||
<template #footer>
|
|
||||||
<view v-if="enable" class="flex-shrink-0 px-15 py-10 text-center bg-white">
|
|
||||||
<view class="pb-10 text-sm">
|
|
||||||
{{ record.userName ? `您正在对 ${record.userName} 进行匿名评价` : "您正在进行匿名评价" }}
|
|
||||||
</view>
|
|
||||||
<view class="py-10 text-base text-white rounded bg-primary" @click="confirm()">
|
|
||||||
提交
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
</full-page>
|
|
||||||
<view v-else class="h-screen relative">
|
|
||||||
<view v-if="isError" class="empty">
|
|
||||||
<image class="empty__icon" src="/static/empty.svg"></image>
|
|
||||||
<text class="empty__txt">{{ emptyTxt }} {{ record }}</text>
|
|
||||||
</view>
|
|
||||||
<view v-else-if="rated" class="empty text-green-500">
|
|
||||||
<uni-icons type="checkbox-filled" color=" " size="60"></uni-icons>
|
|
||||||
<text class="text-gray text-base block mt-4">评价已完成</text>
|
|
||||||
</view>
|
|
||||||
<view v-else class="empty text-gray">
|
|
||||||
<!-- <view class="animate-spin ease-linear duration-[2500]">
|
|
||||||
<uni-icons type="spinner-cycle animate-spin" color=" " size="50"></uni-icons>
|
|
||||||
</view> -->
|
|
||||||
<text class="text-base block mt-4">评价尚未完成</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { computed, ref } from 'vue';
|
|
||||||
import { onLoad } from "@dcloudio/uni-app";
|
|
||||||
import api from "@/utils/api.js";
|
|
||||||
import { toast } from "@/utils/widget";
|
|
||||||
|
|
||||||
import FullPage from '@/components/full-page.vue';
|
|
||||||
|
|
||||||
|
|
||||||
// import { submitRateRecord, getRateRecord } from "@/api/knowledgeBase.js";
|
|
||||||
|
|
||||||
const RateText = {
|
|
||||||
1: "很不满意",
|
|
||||||
2: "不满意",
|
|
||||||
3: "一般",
|
|
||||||
4: "满意",
|
|
||||||
5: "很满意",
|
|
||||||
};
|
|
||||||
const RateStar = {
|
|
||||||
1: "oneStar",
|
|
||||||
2: "twoStar",
|
|
||||||
3: "threeStar",
|
|
||||||
4: "fourStar",
|
|
||||||
5: "fiveStar",
|
|
||||||
};
|
|
||||||
|
|
||||||
const id = ref("");
|
|
||||||
const corpId = ref("");
|
|
||||||
const isError = ref(true);
|
|
||||||
const record = ref(null);
|
|
||||||
const enable = ref(false);
|
|
||||||
const rateTags = ref([]);
|
|
||||||
const rated = ref(false);
|
|
||||||
const emptyTxt = ref("正在获取评价信息...");
|
|
||||||
const rate = ref(0);
|
|
||||||
const words = ref("");
|
|
||||||
const selectedTag = ref({});
|
|
||||||
const loading = ref(false);
|
|
||||||
|
|
||||||
const tags = computed(() => {
|
|
||||||
if (enable.value) {
|
|
||||||
const key = RateStar[rate.value];
|
|
||||||
const group = rateTags.value.find((i) => i.rateStar === key);
|
|
||||||
return group && Array.isArray(group.rateTags) ? group.rateTags : [];
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
});
|
|
||||||
|
|
||||||
const starCount = computed(() => {
|
|
||||||
return rate.value % 1 === 0 && rate.value >= 0 && rate.value <= 5
|
|
||||||
? rate.value
|
|
||||||
: 0;
|
|
||||||
})
|
|
||||||
|
|
||||||
const emptyStarCount = computed(() => {
|
|
||||||
return 5 - starCount.value;
|
|
||||||
});
|
|
||||||
|
|
||||||
const rateText = computed(() => {
|
|
||||||
return RateText[starCount.value] || "";
|
|
||||||
});
|
|
||||||
|
|
||||||
async function confirm() {
|
|
||||||
if (!enable.value) return;
|
|
||||||
if (![1, 2, 3, 4, 5].includes(rate.value)) {
|
|
||||||
toast("请选择评分");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const tagsText = tags.value
|
|
||||||
.filter((i) => selectedTag.value[i._id])
|
|
||||||
.map((i) => i.text);
|
|
||||||
loading.value = true;
|
|
||||||
const { message, success } = await api('submitRateRecord', {
|
|
||||||
id: id.value,
|
|
||||||
corpId: corpId.value,
|
|
||||||
rate: rate.value,
|
|
||||||
tags: tagsText,
|
|
||||||
words: words.value,
|
|
||||||
});
|
|
||||||
if (success) {
|
|
||||||
await toast("评价成功");
|
|
||||||
uni.navigateBack();
|
|
||||||
} else {
|
|
||||||
toast(message);
|
|
||||||
loading.value = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function init() {
|
|
||||||
const res = await api('getRateRecord', {
|
|
||||||
id: id.value,
|
|
||||||
corpId: corpId.value,
|
|
||||||
});
|
|
||||||
if (res && res.success) {
|
|
||||||
enable.value = typeof res.enable == 'boolean' ? res.enable : false;
|
|
||||||
rated.value = typeof res.rated == 'boolean' ? res.rated : false;
|
|
||||||
record.value = res.record;
|
|
||||||
rate.value = res.record && res.record.rate ? res.record.rate : 0;
|
|
||||||
rateTags.value = Array.isArray(res.rateTags) ? res.rateTags : [];
|
|
||||||
if (record.value && record.value.updateTime) {
|
|
||||||
words.value = typeof record.value.words == 'string' ? record.value.words : '';
|
|
||||||
} else if (record.value && Date.now() > record.value.expireTime) {
|
|
||||||
rate.value = 5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function changeRate(i) {
|
|
||||||
if (!enable.value) return;
|
|
||||||
rate.value = i;
|
|
||||||
selectedTag.value = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggle(i) {
|
|
||||||
if (!enable.value) return;
|
|
||||||
selectedTag.value[i._id] = !selectedTag.value[i._id];
|
|
||||||
}
|
|
||||||
|
|
||||||
onLoad(opts => {
|
|
||||||
corpId.value = opts.corpId;
|
|
||||||
id.value = opts.id;
|
|
||||||
if (id.value && corpId.value) {
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.h-screen {
|
|
||||||
height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.min-h-100 {
|
|
||||||
min-height: 200rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.box-50 {
|
|
||||||
width: 100rpx;
|
|
||||||
height: 100rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.w-star {
|
|
||||||
width: 16%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.empty {
|
|
||||||
position: absolute;
|
|
||||||
left: 50%;
|
|
||||||
top: 40%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
@at-root &__icon {
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 16rpx;
|
|
||||||
width: 240rpx;
|
|
||||||
height: 240rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
@at-root &__txt {
|
|
||||||
font-size: 32rpx;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -1,441 +0,0 @@
|
|||||||
<template>
|
|
||||||
<full-page @reachBottom="getMore">
|
|
||||||
<template #header>
|
|
||||||
<scroll-view scroll-x class="bg-white whitespace-nowrap px-15 py-10 sticky top-0 z-10 w-full"
|
|
||||||
:show-scrollbar="false">
|
|
||||||
<view v-for="(tab, index) in tabs" :key="index"
|
|
||||||
class="inline-block px-15 py-5 mr-10 text-sm rounded-full border transition-colors" :class="[
|
|
||||||
activeTab === tab.value
|
|
||||||
? 'bg-orange-100 text-orange-500 border-orange-500'
|
|
||||||
: 'bg-white text-gray-600 border-gray-200'
|
|
||||||
]" @click="selectTab(tab.value)">
|
|
||||||
{{ tab.name }}
|
|
||||||
</view>
|
|
||||||
</scroll-view>
|
|
||||||
</template>
|
|
||||||
<view class="bg-gray-100 min-h-screen">
|
|
||||||
<!-- Survey List -->
|
|
||||||
<view v-if="loading && list.length === 0" class="loading-container">
|
|
||||||
<uni-icons type="spinner-cycle" size="30" color="#999" />
|
|
||||||
<text class="loading-text">加载中...</text>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view v-else-if="!loading && list.length === 0" class="empty-container">
|
|
||||||
<empty-data text="暂无评价" />
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view v-else class="p-15">
|
|
||||||
<view v-for="item in list" :key="item._id" class="bg-white rounded-lg p-15 mb-15 shadow-sm"
|
|
||||||
@click="goToDetail(item)">
|
|
||||||
<!-- Header -->
|
|
||||||
<view class="flex items-start justify-between mb-10">
|
|
||||||
<view class="flex items-start flex-1 mr-10 relative">
|
|
||||||
<view class="text-xs text-green-600 border border-green-600 px-5 rounded mr-5 flex-shrink-0 mt-1 tag-box">
|
|
||||||
服务评价
|
|
||||||
</view>
|
|
||||||
<view class="text-base font-bold text-gray-800 leading-normal line-clamp-2">
|
|
||||||
请您对我的今日服务做出评价
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="flex items-center flex-shrink-0 ml-2">
|
|
||||||
<text v-if="item.rate" class="text-sm mr-2 text-gray-400">查看</text>
|
|
||||||
<text v-else class="text-sm mr-2 text-danger">未评价</text>
|
|
||||||
<uni-icons type="right" size="14" color="#9ca3af"></uni-icons>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="text-sm text-gray-600 mb-5 flex items-start">
|
|
||||||
<text class="text-gray-400 mr-2 field-label">服务人员:</text>
|
|
||||||
<text>{{ item.userName || '-' }}</text>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="text-sm text-gray-600 mb-10 pb-10 border-b border-gray-100 flex items-start">
|
|
||||||
<text class="text-gray-400 mr-2 field-label">团队:</text>
|
|
||||||
<text>{{ item.teamName || '-' }}</text>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="flex items-center justify-between">
|
|
||||||
<view class="text-sm text-gray-400">
|
|
||||||
服务时间: {{ item.time || '-' }}
|
|
||||||
</view>
|
|
||||||
<view class="text-sm text-gray-400">
|
|
||||||
人员: {{ item.customerName || '-' }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view v-if="loading && list.length > 0" class="loading-more">
|
|
||||||
<uni-icons type="spinner-cycle" size="20" color="#999" />
|
|
||||||
<text>加载中...</text>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view v-if="!hasMore" class="no-more">
|
|
||||||
没有更多了
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</full-page>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref } from "vue";
|
|
||||||
import { onLoad, onShow } from "@dcloudio/uni-app";
|
|
||||||
import { storeToRefs } from "pinia";
|
|
||||||
import dayjs from "dayjs";
|
|
||||||
import api from "@/utils/api.js";
|
|
||||||
import usePageList from '@/hooks/usePageList';
|
|
||||||
|
|
||||||
import useAccountStore from "@/store/account.js";
|
|
||||||
import EmptyData from "@/components/empty-data.vue";
|
|
||||||
import FullPage from '@/components/full-page.vue';
|
|
||||||
|
|
||||||
const { openid } = storeToRefs(useAccountStore());
|
|
||||||
|
|
||||||
const tabs = ref([{ name: "全部", value: "" }]);
|
|
||||||
const activeTab = ref("");
|
|
||||||
const corpId = ref('')
|
|
||||||
const teamId = ref('')
|
|
||||||
|
|
||||||
|
|
||||||
const inited = ref(false);
|
|
||||||
const { list, page, pages, pageSize, total, loading, hasMore, changePage } = usePageList(getList)
|
|
||||||
|
|
||||||
const selectTab = async (memberId) => {
|
|
||||||
if (activeTab.value === memberId) return;
|
|
||||||
activeTab.value = memberId;
|
|
||||||
changePage(1)
|
|
||||||
};
|
|
||||||
|
|
||||||
const loadCustomers = async () => {
|
|
||||||
const miniAppId = openid.value || uni.getStorageSync("openid");
|
|
||||||
if (!miniAppId) return;
|
|
||||||
try {
|
|
||||||
const res = await api("getMiniAppCustomers", { miniAppId, corpId: corpId.value });
|
|
||||||
if (res && res.success) {
|
|
||||||
const list = Array.isArray(res.data) ? res.data : [];
|
|
||||||
tabs.value = [
|
|
||||||
{ name: "全部", value: "" },
|
|
||||||
...list.map((c) => ({ name: c.name || "未命名", value: c._id })),
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
uni.showToast({ title: res?.message || "获取档案失败", icon: "none" });
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.error("loadCustomers failed:", err);
|
|
||||||
uni.showToast({ title: "获取档案失败", icon: "none" });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
async function getList() {
|
|
||||||
if (loading.value) return;
|
|
||||||
const customerIds = activeTab.value ? [activeTab.value] : tabs.value.map(i => i.value);
|
|
||||||
const res = await api('searchRateList', {
|
|
||||||
corpId: corpId.value,
|
|
||||||
page: page.value,
|
|
||||||
pageSize: pageSize.value,
|
|
||||||
customerIds,
|
|
||||||
teamId: teamId.value
|
|
||||||
})
|
|
||||||
const arr = res && Array.isArray(res.list) ? res.list.map(i => ({
|
|
||||||
...i,
|
|
||||||
time: i.createTime ? dayjs(i.createTime).format('YYYY-MM-DD HH:mm') : '-',
|
|
||||||
})) : [];
|
|
||||||
list.value = page.value === 1 ? arr : [...list.value, ...arr];
|
|
||||||
total.value = res && typeof res.total === 'number' ? res.total : 0;
|
|
||||||
pages.value = res && typeof res.pages === 'number' ? res.pages : 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
function goToDetail(item) {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: `/pages/rate/rate-detail?id=${item._id}&corpId=${item.corpId}`
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function getMore() {
|
|
||||||
if (hasMore.value && !loading.value) {
|
|
||||||
changePage(page.value + 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onLoad(opts => {
|
|
||||||
corpId.value = opts.corpId
|
|
||||||
teamId.value = opts.teamId
|
|
||||||
})
|
|
||||||
|
|
||||||
onShow(async () => {
|
|
||||||
if (!inited.value) {
|
|
||||||
await loadCustomers();
|
|
||||||
inited.value = true
|
|
||||||
}
|
|
||||||
await changePage(1)
|
|
||||||
});
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.min-h-screen {
|
|
||||||
min-height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg-gray-100 {
|
|
||||||
background-color: #f7f8fa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg-white {
|
|
||||||
background-color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-15 {
|
|
||||||
padding: 30rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.px-15 {
|
|
||||||
padding-left: 30rpx;
|
|
||||||
padding-right: 30rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.py-10 {
|
|
||||||
padding-top: 20rpx;
|
|
||||||
padding-bottom: 20rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.py-5 {
|
|
||||||
padding-top: 10rpx;
|
|
||||||
padding-bottom: 10rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.px-5 {
|
|
||||||
padding-left: 10rpx;
|
|
||||||
padding-right: 10rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mr-10 {
|
|
||||||
margin-right: 20rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mr-5 {
|
|
||||||
margin-right: 10rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ml-2 {
|
|
||||||
margin-left: 10rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mr-2 {
|
|
||||||
margin-right: 10rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mb-15 {
|
|
||||||
margin-bottom: 30rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mb-10 {
|
|
||||||
margin-bottom: 20rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mb-5 {
|
|
||||||
margin-bottom: 10rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mt-1 {
|
|
||||||
margin-top: 6rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pb-10 {
|
|
||||||
padding-bottom: 20rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flex {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.items-start {
|
|
||||||
align-items: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.items-center {
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.justify-between {
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flex-1 {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flex-shrink-0 {
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.relative {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border {
|
|
||||||
border-width: 1px;
|
|
||||||
border-style: solid;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-b {
|
|
||||||
border-bottom-width: 1px;
|
|
||||||
border-bottom-style: solid;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rounded-full {
|
|
||||||
border-radius: 9999px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rounded {
|
|
||||||
border-radius: 8rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rounded-lg {
|
|
||||||
border-radius: 12rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shadow-sm {
|
|
||||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-xs {
|
|
||||||
font-size: 22rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-sm {
|
|
||||||
font-size: 28rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-base {
|
|
||||||
font-size: 32rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.font-bold {
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leading-normal {
|
|
||||||
line-height: 1.4;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Colors - Adjusting to match image roughly */
|
|
||||||
.text-orange-500 {
|
|
||||||
color: #f29e38;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg-orange-100 {
|
|
||||||
background-color: #fff8eb;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-orange-500 {
|
|
||||||
border-color: #f29e38;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-gray-600 {
|
|
||||||
color: #333333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-gray-500 {
|
|
||||||
color: #999999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-gray-400 {
|
|
||||||
color: #999999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-gray-800 {
|
|
||||||
color: #1a1a1a;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-gray-200 {
|
|
||||||
border-color: #e5e5e5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-gray-100 {
|
|
||||||
border-color: #f5f5f5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-green-600 {
|
|
||||||
color: #4b8d5f;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-green-600 {
|
|
||||||
border-color: #4b8d5f;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-red-500 {
|
|
||||||
color: #e04a4a;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sticky {
|
|
||||||
position: sticky;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-0 {
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.z-10 {
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
.w-full {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.whitespace-nowrap {
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inline-block {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag-box {
|
|
||||||
border-radius: 4rpx;
|
|
||||||
line-height: 1.2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.line-clamp-2 {
|
|
||||||
overflow: hidden;
|
|
||||||
display: -webkit-box;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
-webkit-line-clamp: 2;
|
|
||||||
line-clamp: 2;
|
|
||||||
word-break: break-all;
|
|
||||||
}
|
|
||||||
|
|
||||||
.field-label {
|
|
||||||
flex-shrink: 0;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loading-container,
|
|
||||||
.empty-container {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
padding: 100rpx 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loading-text {
|
|
||||||
margin-top: 20rpx;
|
|
||||||
font-size: 28rpx;
|
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loading-more,
|
|
||||||
.no-more {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
padding: 30rpx 0;
|
|
||||||
font-size: 24rpx;
|
|
||||||
color: #999;
|
|
||||||
gap: 10rpx;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -1,53 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="h-full py-20vh">
|
|
||||||
<view class="mb-10 px-15 text-lg font-semibold text-center">{{ survey.name }}</view>
|
|
||||||
<scroll-view :scroll-y="true" class="h-40vh">
|
|
||||||
<view class="text-sm text-gray px-15 text-center leading-normal">
|
|
||||||
{{ survey.description || '' }}
|
|
||||||
</view>
|
|
||||||
</scroll-view>
|
|
||||||
<view v-if="customerName" class="my-4 text-center text-base">
|
|
||||||
<text class="text-gray">客户:</text>
|
|
||||||
<text class="font-semibold">{{ customerName }}</text>
|
|
||||||
</view>
|
|
||||||
<view
|
|
||||||
class="mx-auto answer-btn h-12 text-base flex items-center justify-center text-white text-center rounded-full bg-primary"
|
|
||||||
@click="answer()">
|
|
||||||
开始答题
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
<script setup>
|
|
||||||
defineProps({
|
|
||||||
customerName: { type: String, default: '' },
|
|
||||||
survey: { type: Object, default: () => ({}) }
|
|
||||||
})
|
|
||||||
const emits = defineEmits(['answer'])
|
|
||||||
|
|
||||||
function answer() {
|
|
||||||
emits('answer')
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
<style>
|
|
||||||
.h-40vh {
|
|
||||||
height: 40vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.py-20vh {
|
|
||||||
padding: 20vh 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.my-4 {
|
|
||||||
margin-top: 30rpx;
|
|
||||||
margin-bottom: 30rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.answer-btn {
|
|
||||||
width: 80%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h-12 {
|
|
||||||
height: 96rpx;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -1,196 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="h-full flex flex-col">
|
|
||||||
<view class="flex-shrink-0 px-10 pt-5 text-lg text-primary font-semibold text-center truncate">{{ survey.name }}
|
|
||||||
</view>
|
|
||||||
<view v-if="survey.description"
|
|
||||||
class="flex-shrink-0 px-10 mt-10 text-sm leading-normal text-gray line-clamp-2 text-center">
|
|
||||||
{{ survey.description }}
|
|
||||||
</view>
|
|
||||||
<view v-if="survey.enableScore" class="text-right mt-10 px-10 text-sm">
|
|
||||||
当前得分:<span class="text-primary text-base font-semibold min-w-5 inline-block">{{ allScore }} </span>
|
|
||||||
</view>
|
|
||||||
<view v-if="quesiton" class="my-3 text-base font-semibold px-10 leading-normal ">
|
|
||||||
<span v-if="quesiton.require" class="text-xs text-danger">*</span> {{ index + 1 }}、{{ quesiton.title }}
|
|
||||||
</view>
|
|
||||||
<view v-if="quesiton" class="flex-grow relative">
|
|
||||||
<scroll-view :scroll-y="true" class="absolute inset-0">
|
|
||||||
<view class="px-10">
|
|
||||||
<template v-if="quesiton.type === 'radio'">
|
|
||||||
<view v-for="(opt, idx) in quesiton.options" :key="opt.value" class="flex py-4 border-b "
|
|
||||||
:class="idx === 0 ? 'border-t' : ''" @click="changeRadio(opt.value)">
|
|
||||||
<uni-icons v-if="answer[quesiton.id] === opt.value" class="mr-2 text-primary flex-shrink-0" color=" "
|
|
||||||
type="checkbox-filled" size="24"></uni-icons>
|
|
||||||
<uni-icons v-else class="mr-2 text-gray flex-shrink-0" color=" " type="circle" size="24"></uni-icons>
|
|
||||||
<view class="flex-grow text-base leading-normal">
|
|
||||||
{{ opt.label }}
|
|
||||||
<span v-if="survey.enableScore && opt.score >= 0">
|
|
||||||
( {{ opt.score }}分)
|
|
||||||
</span>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
<textarea v-else-if="quesiton.type === 'input'" :value="answer[quesiton.id]" placeholder="请输入..."
|
|
||||||
placeholder-class="text-gray text-sm"
|
|
||||||
class="p-10 text-sm w-full box-border rounded border min-h-30 border-gray-200" @input="change($event)" />
|
|
||||||
</view>
|
|
||||||
</scroll-view>
|
|
||||||
</view>
|
|
||||||
<view v-if="list.length > 1" class="flex-shrink-0 py-3">
|
|
||||||
<view class="mx-3 bg-gray-100 h-3 rounded-lg overflow-hidden">
|
|
||||||
<view class="h-3 rounded-lg bg-primary" :style="{ width: `${progress}%` }"></view>
|
|
||||||
</view>
|
|
||||||
<view class="flex items-center justify-between px-10 py-15">
|
|
||||||
<view class="flex items-center text-primary" :class="index > 0 ? '' : 'opacity-0'" @click="prev()">
|
|
||||||
<uni-icons class="inline-block mr-10rpx" color=" " type="arrowleft"></uni-icons>
|
|
||||||
<span class="text-base font-semibold">上一题</span>
|
|
||||||
</view>
|
|
||||||
<!-- 当前得分:40 -->
|
|
||||||
<view class="text-sm">{{ index + 1 }} / {{ list.length }}</view>
|
|
||||||
<view v-if="index < list.length - 1" class="flex items-center text-primary"
|
|
||||||
:class="index < list.length - 1 ? '' : 'opacity-0'" @click="next()">
|
|
||||||
<span class="text-base font-semibold">下一题</span>
|
|
||||||
<uni-icons class="inline-block ml-10rpx" color=" " type="arrowright"></uni-icons>
|
|
||||||
</view>
|
|
||||||
<view v-if="index === list.length - 1" class="flex items-center text-primary" @click="submit()">
|
|
||||||
<span class="text-base font-semibold">提交</span>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view v-if="list.length === 1"
|
|
||||||
class="flex-shrink-0 mx-10 py-12 leading-normal text-white text-center rounded bg-primary" @click="submit()">
|
|
||||||
提交
|
|
||||||
</view>
|
|
||||||
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
<script>
|
|
||||||
import { toast } from '@/utils/widget'
|
|
||||||
export default {
|
|
||||||
name: 'Question',
|
|
||||||
props: {
|
|
||||||
list: { type: Array, default: () => ([]) },
|
|
||||||
survey: { type: Object, default: () => ({}) }
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
index: 0,
|
|
||||||
answer: {},
|
|
||||||
waiting: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
quesiton() {
|
|
||||||
return this.list[this.index]
|
|
||||||
},
|
|
||||||
progress() {
|
|
||||||
return (this.index + 1) / (this.list.length || 1) * 100
|
|
||||||
},
|
|
||||||
allScore() {
|
|
||||||
return this.list.reduce((score, item) => {
|
|
||||||
if (item.type === 'radio') {
|
|
||||||
const opt = item.options.find(i => i.value && i.value === this.answer[item.id])
|
|
||||||
if (opt && opt.score >= 0) {
|
|
||||||
score = Math.floor(score * 100 + opt.score * 100) / 100
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return score
|
|
||||||
}, 0)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
|
|
||||||
change(e) {
|
|
||||||
this.$set(this.answer, this.quesiton.id, e.detail.value)
|
|
||||||
},
|
|
||||||
changeIndex(num) {
|
|
||||||
if (this.waiting) return;
|
|
||||||
this.waiting = true;
|
|
||||||
setTimeout(() => this.waiting = false, 1000);
|
|
||||||
const target = num + this.index;
|
|
||||||
this.index = target >= 0 && target < this.list.length ? target : this.index
|
|
||||||
},
|
|
||||||
changeRadio(value) {
|
|
||||||
this.$set(this.answer, this.quesiton.id, value)
|
|
||||||
},
|
|
||||||
prev() {
|
|
||||||
this.changeIndex(-1)
|
|
||||||
},
|
|
||||||
next() {
|
|
||||||
if (this.quesiton.require && this.quesiton.type === 'radio' && !this.quesiton.options.some(i => i.value && i.value === this.answer[this.quesiton.id])) {
|
|
||||||
toast('请完成当前题目')
|
|
||||||
} else if (this.quesiton.require && this.quesiton.type === 'input' && (typeof this.answer[this.quesiton.id] !== 'string' || this.answer[this.quesiton.id].trim() === '')) {
|
|
||||||
toast('请完成当前题目')
|
|
||||||
} else {
|
|
||||||
this.changeIndex(1)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
verify() {
|
|
||||||
const index = this.list.findIndex(i => {
|
|
||||||
if (i.require && i.type === 'radio' && !i.options.some(j => j.value && j.value === this.answer[i.id])) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if (i.require && i.type === 'input' && (typeof this.answer[i.id] !== 'string' || this.answer[i.id].trim() === '')) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
if (index >= 0) {
|
|
||||||
toast('请完成第' + (index + 1) + '题')
|
|
||||||
this.index = index
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
submit() {
|
|
||||||
if (this.verify()) {
|
|
||||||
const list = this.list.map(i => {
|
|
||||||
const item = {
|
|
||||||
id: i.id,
|
|
||||||
value: this.answer[i.id] || '',
|
|
||||||
title: i.title,
|
|
||||||
type: i.type,
|
|
||||||
require: i.require,
|
|
||||||
}
|
|
||||||
if (Array.isArray(i.options)) {
|
|
||||||
item.options = i.options.map(opt => ({ ...opt }))
|
|
||||||
}
|
|
||||||
return item
|
|
||||||
})
|
|
||||||
this.$emit('submit', { list, score: this.allScore })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.pt-5 {
|
|
||||||
padding-top: 40rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.min-w-5 {
|
|
||||||
min-width: 40rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inline-block {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.my-3 {
|
|
||||||
margin-top: 24rpx;
|
|
||||||
margin-bottom: 24rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.py-4 {
|
|
||||||
padding-top: 30rpx;
|
|
||||||
padding-bottom: 30rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-t {
|
|
||||||
border-top: 1px solid #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
.min-h-30 {
|
|
||||||
min-height: 200rpx;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -1,93 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="h-full flex flex-col">
|
|
||||||
<view class="flex-shrink-0 px-10 pt-5 text-base font-semibold text-center truncate">{{ surery.name }}</view>
|
|
||||||
<view v-if="surery.description"
|
|
||||||
class="flex-shrink-0 px-10 mt-10 text-sm leading-normal text-gray line-clamp-2 text-center">
|
|
||||||
{{ surery.description }}
|
|
||||||
</view>
|
|
||||||
<view class="flex items-center text-gray text-sm px-10 mt-10">
|
|
||||||
<view v-if="surery.enableScore">
|
|
||||||
当前得分:<text class="text-primary text-base font-semibold min-w-5 inline-block">{{ allScore }}
|
|
||||||
</text>
|
|
||||||
</view>
|
|
||||||
<view class="ml-auto">
|
|
||||||
客户:<text class="text-black text-base font-semibold min-w-5 inline-block">{{ customerName }} </text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="flex-grow relative">
|
|
||||||
<scroll-view :scroll-y="true" class="absolute inset-0">
|
|
||||||
<view v-for="(quesiton, index) in list" :key="quesiton.id">
|
|
||||||
<view v-if="quesiton" class="my-4 text-base px-10 leading-normal">
|
|
||||||
<text v-if="quesiton.require" class="text-base text-red-500">*</text> {{ index + 1 }}、{{ quesiton.title }}
|
|
||||||
</view>
|
|
||||||
<view class="px-10">
|
|
||||||
<template v-if="quesiton.type === 'radio'">
|
|
||||||
<view v-for="(opt, idx) in quesiton.options" :key="opt.value" class="flex py-15 border-b"
|
|
||||||
:class="idx === 0 ? 'border-t' : ''">
|
|
||||||
<view class="flex-grow pl-4 text-gray leading-normal"
|
|
||||||
:class="quesiton.value && quesiton.value === opt.value ? 'text-primary' : ''">
|
|
||||||
{{ opt.label }}
|
|
||||||
<text v-if="surery.enableScore && opt.score >= 0">
|
|
||||||
( {{ opt.score }}分)
|
|
||||||
</text>
|
|
||||||
</view>
|
|
||||||
<uni-icons v-if="quesiton.value && quesiton.value === opt.value" class="ml-1 text-primary flex-shrink-0"
|
|
||||||
color=" " type="checkbox-filled" size="24"></uni-icons>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
<view v-else-if="quesiton.type === 'input'"
|
|
||||||
class="my-4 p-10 text-base leading-normal border rounded">
|
|
||||||
{{ quesiton.value || '' }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</scroll-view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'Question',
|
|
||||||
props: {
|
|
||||||
customerName: { type: String, default: '' },
|
|
||||||
list: { type: Array, default: () => ([]) },
|
|
||||||
surery: { type: Object, default: () => ({}) }
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
allScore() {
|
|
||||||
return this.list.reduce((score, item) => {
|
|
||||||
if (item.type === 'radio') {
|
|
||||||
const opt = item.options.find(i => i.value && i.value === item.value && item.value)
|
|
||||||
if (opt && opt.score >= 0) {
|
|
||||||
score = Math.floor(score * 100 + opt.score * 100) / 100
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return score
|
|
||||||
}, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.min-w-5 {
|
|
||||||
min-width: 40rpx
|
|
||||||
}
|
|
||||||
|
|
||||||
.pt-5 {
|
|
||||||
padding-top: 40rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.my-4 {
|
|
||||||
margin-top: 32rpx;
|
|
||||||
margin-bottom: 32rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-t {
|
|
||||||
border-top: 1px solid #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pl-4 {
|
|
||||||
padding-left: 30rpx;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -1,243 +0,0 @@
|
|||||||
<template>
|
|
||||||
<full-page :customScroll="true">
|
|
||||||
<template v-if="survey && survey.status === 'enable' && !readonly">
|
|
||||||
<survey-cover v-if="step === 'cover'" :customerName="customerName" :survey="survey" @answer="step = 'question'" />
|
|
||||||
<survey-question v-else-if="step === 'question'" :survey="survey" :list="showList" @submit="submit" />
|
|
||||||
</template>
|
|
||||||
<survey-record v-else-if="survey && survey.status === 'enable' && readonly" :customerName="customerName"
|
|
||||||
:survey="survey" :list="showList" />
|
|
||||||
<view v-else class="empty">
|
|
||||||
<image class="empty__icon" src="/static/empty.svg"></image>
|
|
||||||
<text class="empty__txt">{{ emptyTxt }}</text>
|
|
||||||
</view>
|
|
||||||
</full-page>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { computed, ref } from "vue";
|
|
||||||
import { onLoad } from "@dcloudio/uni-app";
|
|
||||||
import api from "@/utils/api.js";
|
|
||||||
import { loading, toast, hideLoading } from "@/utils/widget";
|
|
||||||
|
|
||||||
import FullPage from '@/components/full-page.vue';
|
|
||||||
import surveyCover from "./components/survey-cover.vue";
|
|
||||||
import surveyQuestion from "./components/survey-question.vue";
|
|
||||||
import surveyRecord from "./components/survey-record.vue";
|
|
||||||
|
|
||||||
const corpId = ref('');
|
|
||||||
const surveryId = ref('');
|
|
||||||
const answerId = ref('');
|
|
||||||
const memberId = ref('');
|
|
||||||
const survey = ref(null);
|
|
||||||
const emptyTxt = ref('')
|
|
||||||
const customerName = ref('');
|
|
||||||
const step = ref('cover');
|
|
||||||
|
|
||||||
const readonly = computed(() => survey.value && survey.value.submitTime);
|
|
||||||
const list = computed(() => survey.value && Array.isArray(survey.value.list) ? survey.value.list : []);
|
|
||||||
const showList = computed(() => {
|
|
||||||
return list.value.filter(item => {
|
|
||||||
const showCase = Array.isArray(item.showCase) ? item.showCase : [];
|
|
||||||
if (showCase.length) {
|
|
||||||
const res = showCase.every(({
|
|
||||||
type,
|
|
||||||
id,
|
|
||||||
value
|
|
||||||
}) => {
|
|
||||||
const question = this.list.find(i => i.id === id);
|
|
||||||
const val = question ? question.value : '';
|
|
||||||
return type === 'in' ? value.includes(val) : val === value.join()
|
|
||||||
})
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
async function init() {
|
|
||||||
loading('加载中...');
|
|
||||||
try {
|
|
||||||
const record = await getAnswerRecord();
|
|
||||||
if (record && record.submitTime) {
|
|
||||||
record.status = 'enable';
|
|
||||||
survey.value = record;
|
|
||||||
hideLoading()
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
survey.value = await getSurvey();
|
|
||||||
if (survey.value.status == 'stop') {
|
|
||||||
emptyTxt.value = '问卷已经停用'
|
|
||||||
} else if (survey.value.status == 'init') {
|
|
||||||
emptyTxt.value = '问卷暂未启用'
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
hideLoading();
|
|
||||||
toast('获取问卷失败');
|
|
||||||
uni.navigateBack();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getAnswerRecord() {
|
|
||||||
const res = await api('getAnswer', { corpId: corpId.value, surveryId: surveryId.value, answerId: answerId.value, memberId: memberId.value });
|
|
||||||
if (res && res.success) {
|
|
||||||
return res.record
|
|
||||||
}
|
|
||||||
return Promise.reject();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getSurvey() {
|
|
||||||
const res = await api('getSurveryDetail', { corpId: corpId.value, id: surveryId.value })
|
|
||||||
if (res && res.success && res.data) {
|
|
||||||
return res.data
|
|
||||||
}
|
|
||||||
return Promise.reject();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function submit({ list, score }) {
|
|
||||||
const res = await api('answerSurvery', {
|
|
||||||
corpId: corpId.value,
|
|
||||||
name: survey.value.name,
|
|
||||||
memberId: memberId.value,
|
|
||||||
list: list,
|
|
||||||
score: score,
|
|
||||||
answerId: answerId.value,
|
|
||||||
})
|
|
||||||
if (res && res.success) {
|
|
||||||
await toast('提交成功');
|
|
||||||
uni.navigateBack();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onLoad(opts => {
|
|
||||||
corpId.value = opts.corpId;
|
|
||||||
surveryId.value = opts.surveryId;
|
|
||||||
answerId.value = opts.answerId;
|
|
||||||
memberId.value = opts.memberId;
|
|
||||||
customerName.value = opts.name;
|
|
||||||
init();
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.survey {
|
|
||||||
position: relative;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
height: 100vh;
|
|
||||||
width: 100vw;
|
|
||||||
color: ragb(0, 0, 0, .9);
|
|
||||||
background: #fff;
|
|
||||||
|
|
||||||
@at-root &__wrapper {
|
|
||||||
padding: 30rpx 40rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
@at-root &__scroll {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
@at-root &__customer {
|
|
||||||
text-align: right;
|
|
||||||
font-size: 28rpx;
|
|
||||||
padding-bottom: 16rpx;
|
|
||||||
margin-bottom: 24rpx;
|
|
||||||
color: #333;
|
|
||||||
border-bottom: 1px solid #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
@at-root &__title {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 32rpx;
|
|
||||||
font-weight: 600;
|
|
||||||
margin-bottom: 24rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
@at-root &__desc {
|
|
||||||
text-align: left;
|
|
||||||
color: #666;
|
|
||||||
font-size: 28rpx;
|
|
||||||
margin-bottom: 24rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
@at-root &__item {
|
|
||||||
padding: 0 10rpx;
|
|
||||||
margin-bottom: 24rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
@at-root &__question {
|
|
||||||
position: relative;
|
|
||||||
font-size: 32rpx;
|
|
||||||
margin-bottom: 24rpx;
|
|
||||||
|
|
||||||
@at-root &--require::before {
|
|
||||||
position: absolute;
|
|
||||||
left: -20rpx;
|
|
||||||
top: 0;
|
|
||||||
content: '*';
|
|
||||||
color: #f56c6c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@at-root &__input {
|
|
||||||
padding: 10rpx 24rpx;
|
|
||||||
font-size: 28rpx;
|
|
||||||
border: 1px solid #eee;
|
|
||||||
border-radius: 8rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
@at-root &__radio {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding-bottom: 24rpx;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@at-root &__btn {
|
|
||||||
margin-top: 30rpx;
|
|
||||||
padding: 24rpx 30rpx;
|
|
||||||
border-radius: 8rpx;
|
|
||||||
font-size: 28rpx;
|
|
||||||
color: #fff;
|
|
||||||
background: #006eff;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.radio {
|
|
||||||
@at-root &__icon {
|
|
||||||
flex-shrink: 0;
|
|
||||||
margin-top: 4rpx;
|
|
||||||
margin-right: 10rpx;
|
|
||||||
width: 40rpx;
|
|
||||||
height: 40rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
@at-root &__label {
|
|
||||||
flex-grow: 1;
|
|
||||||
font-size: 32rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.empty {
|
|
||||||
position: absolute;
|
|
||||||
left: 50%;
|
|
||||||
top: 40%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
@at-root &__icon {
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 16rpx;
|
|
||||||
width: 240rpx;
|
|
||||||
height: 240rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
@at-root &__txt {
|
|
||||||
font-size: 32rpx;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<full-page pageClass="bg-gray-100">
|
<view class="bg-gray-100 min-h-screen">
|
||||||
<template #header>
|
<!-- Filter Tabs -->
|
||||||
<scroll-view scroll-x class="bg-white whitespace-nowrap px-15 py-10 sticky top-0 z-10 w-full"
|
<scroll-view scroll-x class="bg-white whitespace-nowrap px-15 py-10 sticky top-0 z-10 w-full"
|
||||||
:show-scrollbar="false">
|
:show-scrollbar="false">
|
||||||
<view v-for="(tab, index) in tabs" :key="index"
|
<view v-for="(tab, index) in tabs" :key="index"
|
||||||
@ -12,7 +12,6 @@
|
|||||||
{{ tab.name }}
|
{{ tab.name }}
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</template>
|
|
||||||
|
|
||||||
<!-- Survey List -->
|
<!-- Survey List -->
|
||||||
<view v-if="loading && surveys.length === 0" class="loading-container">
|
<view v-if="loading && surveys.length === 0" class="loading-container">
|
||||||
@ -42,8 +41,7 @@
|
|||||||
|
|
||||||
<!-- Status (暂不展示未填写/已填写) -->
|
<!-- Status (暂不展示未填写/已填写) -->
|
||||||
<view class="flex items-center flex-shrink-0 ml-2">
|
<view class="flex items-center flex-shrink-0 ml-2">
|
||||||
<text v-if="item.status === 'FILLED'" class="text-sm mr-2 text-gray-400">查看</text>
|
<text class="text-sm mr-2 text-gray-400">查看</text>
|
||||||
<text v-else class="text-sm mr-2 text-danger">未填写</text>
|
|
||||||
<uni-icons type="right" size="14" color="#9ca3af"></uni-icons>
|
<uni-icons type="right" size="14" color="#9ca3af"></uni-icons>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@ -74,7 +72,7 @@
|
|||||||
没有更多了
|
没有更多了
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</full-page>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@ -84,8 +82,6 @@ import { storeToRefs } from "pinia";
|
|||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import api from "@/utils/api.js";
|
import api from "@/utils/api.js";
|
||||||
import useAccountStore from "@/store/account.js";
|
import useAccountStore from "@/store/account.js";
|
||||||
|
|
||||||
import fullPage from "@/components/full-page.vue";
|
|
||||||
import EmptyData from "@/components/empty-data.vue";
|
import EmptyData from "@/components/empty-data.vue";
|
||||||
|
|
||||||
|
|
||||||
@ -93,8 +89,7 @@ const { openid } = storeToRefs(useAccountStore());
|
|||||||
|
|
||||||
const tabs = ref([{ name: "全部", value: "" }]);
|
const tabs = ref([{ name: "全部", value: "" }]);
|
||||||
const activeTab = ref("");
|
const activeTab = ref("");
|
||||||
const corpId = ref('');
|
const corpId = ref('')
|
||||||
const teamId = ref('');
|
|
||||||
|
|
||||||
const surveys = ref([]);
|
const surveys = ref([]);
|
||||||
const total = ref(0);
|
const total = ref(0);
|
||||||
@ -139,8 +134,6 @@ const mapRowToView = (row) => {
|
|||||||
team: row?.team?.name || "-",
|
team: row?.team?.name || "-",
|
||||||
time: sendTime,
|
time: sendTime,
|
||||||
status: row?.status || "",
|
status: row?.status || "",
|
||||||
memberId: row?.memberId || "",
|
|
||||||
corpId: row?.corpId || "",
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -163,7 +156,6 @@ const loadSurveyList = async (reset = false) => {
|
|||||||
const params = {
|
const params = {
|
||||||
corpId: corpId.value,
|
corpId: corpId.value,
|
||||||
miniAppId,
|
miniAppId,
|
||||||
teamId: teamId.value,
|
|
||||||
page: page.value,
|
page: page.value,
|
||||||
pageSize,
|
pageSize,
|
||||||
};
|
};
|
||||||
@ -187,17 +179,13 @@ const loadSurveyList = async (reset = false) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function goToDetail(item) {
|
function goToDetail() {
|
||||||
console.log(item)
|
uni.showToast({ title: "详情暂未接入", icon: "none" });
|
||||||
uni.navigateTo({
|
|
||||||
url: `/pages/survey/fill?name=${item.person}&memberId=${item.memberId}&surveryId=${item.surveryId}&corpId=${item.corpId}&answerId=${item._id}`
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
onLoad(opts => {
|
onLoad(opts => {
|
||||||
corpId.value = opts.corpId;
|
corpId.value = opts.corpId
|
||||||
teamId.value = opts.teamId;
|
|
||||||
})
|
})
|
||||||
|
|
||||||
onShow(async () => {
|
onShow(async () => {
|
||||||
|
|||||||
@ -11,9 +11,7 @@
|
|||||||
</view> -->
|
</view> -->
|
||||||
<view class="flex">
|
<view class="flex">
|
||||||
<view class="flex-shrink-0 text-base text-gray">执业机构:</view>
|
<view class="flex-shrink-0 text-base text-gray">执业机构:</view>
|
||||||
<view v-if="member.source === 'wxapp'" class="flex-shrink-0 text-base text-dark">
|
<view v-if="member.hospitalName" class="flex-shrink-0 text-base text-dark">{{ member.hospitalName }}</view>
|
||||||
{{ member.hospitalName || '' }}
|
|
||||||
</view>
|
|
||||||
<view v-else class="flex-shrink-0 text-base text-dark">{{ corpNames }}</view>
|
<view v-else class="flex-shrink-0 text-base text-dark">{{ corpNames }}</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@ -79,7 +79,7 @@ export default defineStore("accountStore", () => {
|
|||||||
console.log('IM 初始化成功');
|
console.log('IM 初始化成功');
|
||||||
|
|
||||||
// IM 初始化成功后,设置全局未读消息监听
|
// IM 初始化成功后,设置全局未读消息监听
|
||||||
// globalUnreadListenerManager.setup();
|
globalUnreadListenerManager.setup();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -99,7 +99,7 @@ export default defineStore("accountStore", () => {
|
|||||||
|
|
||||||
// 清除全局未读监听
|
// 清除全局未读监听
|
||||||
if (globalUnreadListenerManager.isInitialized) {
|
if (globalUnreadListenerManager.isInitialized) {
|
||||||
// globalUnreadListenerManager.destroy();
|
globalUnreadListenerManager.destroy();
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('退出腾讯IM失败:', error);
|
console.error('退出腾讯IM失败:', error);
|
||||||
|
|||||||
@ -40,10 +40,10 @@ export default defineStore("teamStore", () => {
|
|||||||
|
|
||||||
// 获取团队成员头像和名称映射
|
// 获取团队成员头像和名称映射
|
||||||
async function getTeamMemberAvatarsAndName(teamId) {
|
async function getTeamMemberAvatarsAndName(teamId) {
|
||||||
|
if (!teamId || !account.value?.corpId) return {};
|
||||||
if (!teamId) return {};
|
|
||||||
const res = await api('getTeamMemberAvatarsAndName', {
|
const res = await api('getTeamMemberAvatarsAndName', {
|
||||||
teamId
|
teamId,
|
||||||
|
corpId: account.value.corpId
|
||||||
}, false);
|
}, false);
|
||||||
if (res && res.success && res.data) {
|
if (res && res.success && res.data) {
|
||||||
return res.data;
|
return res.data;
|
||||||
|
|||||||
17
utils/api.js
17
utils/api.js
@ -12,9 +12,7 @@ const urlsConfig = {
|
|||||||
getCorpMemberJob: "getCorpMemberJob",
|
getCorpMemberJob: "getCorpMemberJob",
|
||||||
bindWxappWithTeam: 'bindWxappWithTeam',
|
bindWxappWithTeam: 'bindWxappWithTeam',
|
||||||
getWxappRelateTeams: 'getWxappRelateTeams',
|
getWxappRelateTeams: 'getWxappRelateTeams',
|
||||||
getTeamMemberAvatarsAndName: "getTeamMemberAvatarsAndName",
|
getTeamMemberAvatarsAndName: "getTeamMemberAvatarsAndName"
|
||||||
getMiniAppHomeStats: "getMiniAppHomeStats",
|
|
||||||
getResponsiblePerson: 'getTeamResponsiblePerson'
|
|
||||||
},
|
},
|
||||||
|
|
||||||
knowledgeBase: {
|
knowledgeBase: {
|
||||||
@ -38,10 +36,7 @@ const urlsConfig = {
|
|||||||
addArticleSendRecord: 'addArticleSendRecord',
|
addArticleSendRecord: 'addArticleSendRecord',
|
||||||
addArticleReadRecord: 'addArticleReadRecord',
|
addArticleReadRecord: 'addArticleReadRecord',
|
||||||
getMiniAppReceivedArticleList: 'getMiniAppReceivedArticleList',
|
getMiniAppReceivedArticleList: 'getMiniAppReceivedArticleList',
|
||||||
getPageDisease: 'getPageDisease',
|
getPageDisease:'getPageDisease'
|
||||||
searchRateList: 'searchRateList',
|
|
||||||
submitRateRecord: 'submitRateRecord',
|
|
||||||
getRateRecord: 'getRateRecord',
|
|
||||||
},
|
},
|
||||||
member: {
|
member: {
|
||||||
addCustomer: 'add',
|
addCustomer: 'add',
|
||||||
@ -61,7 +56,7 @@ const urlsConfig = {
|
|||||||
updateCustomer: 'update'
|
updateCustomer: 'update'
|
||||||
},
|
},
|
||||||
wecom: {
|
wecom: {
|
||||||
addContactWay: 'getCorpFriendQrcode'
|
addContactWay: 'addContactWay'
|
||||||
},
|
},
|
||||||
im: {
|
im: {
|
||||||
getUserSig: 'getUserSig',
|
getUserSig: 'getUserSig',
|
||||||
@ -75,11 +70,7 @@ const urlsConfig = {
|
|||||||
getGroupList: "getGroupList"
|
getGroupList: "getGroupList"
|
||||||
},
|
},
|
||||||
survery: {
|
survery: {
|
||||||
getMiniAppReceivedSurveryList: 'getMiniAppReceivedSurveryList',
|
getMiniAppReceivedSurveryList: 'getMiniAppReceivedSurveryList'
|
||||||
getSurveryDetail: 'getDetail',
|
|
||||||
answerSurvery: 'answerSurvery',
|
|
||||||
getAnswerRecord: 'getAnswerRecord',
|
|
||||||
getAnswer: 'getAnswer'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const urls = Object.keys(urlsConfig).reduce((acc, path) => {
|
const urls = Object.keys(urlsConfig).reduce((acc, path) => {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user