diff --git a/src/api/api-models.ts b/src/api/api-models.ts
index 93d3f67..e32539e 100644
--- a/src/api/api-models.ts
+++ b/src/api/api-models.ts
@@ -104,8 +104,16 @@ export interface Setting_SendEmail {
recieveQA: boolean
recieveQAReply: boolean
}
+export enum SaftyLevels {
+ Disabled,
+ Low,
+ Medium,
+ High
+}
export interface Setting_QuestionBox {
allowUnregistedUser: boolean
+
+ saftyLevel: SaftyLevels
}
export interface UserSetting {
sendEmail: Setting_SendEmail
@@ -326,6 +334,21 @@ export interface NotifactionInfo {
message: string
type: LevelTypes
}
+//SENSITIVE_TERM, HATE, VIOLENCE, PORNOGRAPHY, POLITICS, ADVERTISING, AGGRESSION
+export enum ViolationTypes {
+ SENSITIVE_TERM,
+ HATE,
+ VIOLENCE,
+ PORNOGRAPHY,
+ POLITICS,
+ ADVERTISING,
+ AGGRESSION,
+}
+export type QAReviewInfo = {
+ isApproved: boolean
+ saftyScore: number
+ violationType: ViolationTypes[]
+}
export interface QAInfo {
id: number
sender: UserBasicInfo
@@ -340,6 +363,7 @@ export interface QAInfo {
isAnonymous: boolean
tag?: string
+ reviewResult?: QAReviewInfo
}
export interface LotteryUserInfo {
name: string
diff --git a/src/components/QuestionItem.vue b/src/components/QuestionItem.vue
index 50ff78c..682f023 100644
--- a/src/components/QuestionItem.vue
+++ b/src/components/QuestionItem.vue
@@ -1,10 +1,16 @@
@@ -15,7 +21,7 @@ const props = defineProps<{
未读
-
+
{{ item.isAnonymous ? '匿名用户' : item.sender?.name }}
@@ -39,6 +45,25 @@ const props = defineProps<{
+
+
+
+
+ {{ useQA.getViolationString(v) }}
+
+
+
+
+
+
+
+
+ 得分: {{ item.reviewResult.saftyScore }}
+
+
+ 审查得分, 满分100, 越低代表消息越8行
+
+
@@ -52,8 +77,13 @@ const props = defineProps<{
-
- {{ item.question?.message }}
+
+
+ {{ item.question?.message }}
+
+
+ {{ item.question?.message }}
+
diff --git a/src/main.ts b/src/main.ts
index f1acf2d..c607e5b 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -10,6 +10,7 @@ import { GetNotifactions } from './data/notifactions'
import router from './router'
import { useAuthStore } from './store/useAuthStore'
import { useVTsuruHub } from './store/useVTsuruHub'
+import { useNotificationStore } from './store/useNotificationStore'
const pinia = createPinia()
@@ -114,6 +115,8 @@ let isHaveNewVersion = false
const { notification } = createDiscreteApi(['notification'])
+useNotificationStore().init()
+
function InitTTS() {
try {
const result = EasySpeech.detect()
diff --git a/src/store/useNotificationStore.ts b/src/store/useNotificationStore.ts
new file mode 100644
index 0000000..c05646b
--- /dev/null
+++ b/src/store/useNotificationStore.ts
@@ -0,0 +1,39 @@
+import { QueryGetAPI } from '@/api/query'
+import { NOTIFACTION_API_URL } from '@/data/constants'
+import { defineStore } from 'pinia'
+import { ref } from 'vue'
+
+export type NotificationData = {
+ title: string
+}
+
+export const useNotificationStore = defineStore('notification', () => {
+ const unread = ref([])
+ const all = ref([])
+
+ const isInited = ref(false)
+
+ async function updateUnread() {
+ try {
+ const result = await QueryGetAPI(
+ NOTIFACTION_API_URL + 'get-unread'
+ )
+ if (result.code == 200) {
+ unread.value = result.data
+ }
+ } catch {}
+ }
+ function init() {
+ if (isInited.value) {
+ return
+ }
+ setInterval(() => {
+ updateUnread()
+ }, 10 * 1000)
+ isInited.value = true
+ }
+ return {
+ init,
+ unread
+ }
+})
diff --git a/src/store/useQuestionBox.ts b/src/store/useQuestionBox.ts
index 89791b5..d92c2d9 100644
--- a/src/store/useQuestionBox.ts
+++ b/src/store/useQuestionBox.ts
@@ -1,5 +1,5 @@
import { useAccount } from '@/api/account'
-import { QAInfo } from '@/api/api-models'
+import { QAInfo, ViolationTypes } from '@/api/api-models'
import { QueryGetAPI, QueryPostAPI } from '@/api/query'
import { ACCOUNT_API_URL, QUESTION_API_URL } from '@/data/constants'
import { List } from 'linqts'
@@ -12,6 +12,8 @@ export type QATagInfo = {
createAt: number
visiable: boolean
}
+//SENSITIVE_TERM, HATE, VIOLENCE, PORNOGRAPHY, POLITICS, ADVERTISING, AGGRESSION, EMOTIONAL
+
export const useQuestionBox = defineStore('QuestionBox', () => {
const isLoading = ref(false)
const isRepling = ref(false)
@@ -21,7 +23,9 @@ export const useQuestionBox = defineStore('QuestionBox', () => {
const recieveQuestions = ref([])
const sendQuestions = ref([])
+ const trashQuestions = ref([])
const tags = ref([])
+ const reviewing = ref(0)
const onlyFavorite = ref(false)
const onlyPublic = ref(false)
@@ -54,18 +58,31 @@ export const useQuestionBox = defineStore('QuestionBox', () => {
async function GetRecieveQAInfo() {
isLoading.value = true
- await QueryGetAPI(QUESTION_API_URL + 'get-recieve')
+ await QueryGetAPI<{ questions: QAInfo[]; reviewCount: number }>(
+ QUESTION_API_URL + 'get-recieve'
+ )
.then((data) => {
if (data.code == 200) {
- if (data.data.length > 0) {
- recieveQuestions.value = new List(data.data)
+ if (data.data.questions.length > 0) {
+ recieveQuestions.value = new List(data.data.questions)
.OrderBy((d) => d.isReaded)
//.ThenByDescending(d => d.isFavorite)
+ .Where(
+ (d) => !d.reviewResult || d.reviewResult.isApproved == true
+ ) //只显示审核通过的
.ThenByDescending((d) => d.sendAt)
.ToArray()
- const displayId = accountInfo.value?.settings.questionDisplay.currentQuestion
+ reviewing.value = data.data.reviewCount
+ trashQuestions.value = data.data.questions.filter(
+ (d) => d.reviewResult && d.reviewResult.isApproved == false
+ )
+
+ const displayId =
+ accountInfo.value?.settings.questionDisplay.currentQuestion
if (displayId && displayQuestion.value?.id != displayId) {
- displayQuestion.value = recieveQuestions.value.find((q) => q.id == displayId)
+ displayQuestion.value = recieveQuestions.value.find(
+ (q) => q.id == displayId
+ )
}
}
//message.success('共收取 ' + data.data.length + ' 条提问')
@@ -101,12 +118,14 @@ export const useQuestionBox = defineStore('QuestionBox', () => {
}
async function DelQA(id: number) {
await QueryGetAPI(QUESTION_API_URL + 'del', {
- id: id,
+ id: id
})
.then((data) => {
if (data.code == 200) {
message.success('删除成功')
- recieveQuestions.value = recieveQuestions.value.filter((q) => q.id != id)
+ recieveQuestions.value = recieveQuestions.value.filter(
+ (q) => q.id != id
+ )
} else {
message.error(data.message)
}
@@ -118,7 +137,7 @@ export const useQuestionBox = defineStore('QuestionBox', () => {
async function GetTags() {
isLoading.value = true
await QueryGetAPI(QUESTION_API_URL + 'get-tags', {
- id: accountInfo.value?.id,
+ id: accountInfo.value?.id
})
.then((data) => {
if (data.code == 200) {
@@ -134,6 +153,25 @@ export const useQuestionBox = defineStore('QuestionBox', () => {
isLoading.value = false
})
}
+ function getViolationString(violation: ViolationTypes) {
+ //SENSITIVE_TERM, HATE, VIOLENCE, PORNOGRAPHY, POLITICS, ADVERTISING, AGGRESSION
+ switch (violation) {
+ case ViolationTypes.SENSITIVE_TERM:
+ return '敏感词'
+ case ViolationTypes.HATE:
+ return '辱骂'
+ case ViolationTypes.VIOLENCE:
+ return '暴力'
+ case ViolationTypes.PORNOGRAPHY:
+ return '色情'
+ case ViolationTypes.POLITICS:
+ return '政治'
+ case ViolationTypes.ADVERTISING:
+ return '广告'
+ case ViolationTypes.AGGRESSION:
+ return '攻击性'
+ }
+ }
async function addTag(tag: string) {
if (!tag) {
message.warning('请输入标签')
@@ -144,7 +182,7 @@ export const useQuestionBox = defineStore('QuestionBox', () => {
return
}
await QueryGetAPI(QUESTION_API_URL + 'add-tag', {
- tag: tag,
+ tag: tag
})
.then((data) => {
if (data.code == 200) {
@@ -168,7 +206,7 @@ export const useQuestionBox = defineStore('QuestionBox', () => {
return
}
await QueryGetAPI(QUESTION_API_URL + 'del-tag', {
- tag: tag,
+ tag: tag
})
.then((data) => {
if (data.code == 200) {
@@ -193,7 +231,7 @@ export const useQuestionBox = defineStore('QuestionBox', () => {
}
await QueryGetAPI(QUESTION_API_URL + 'update-tag-visiable', {
tag: tag,
- visiable: visiable,
+ visiable: visiable
})
.then((data) => {
if (data.code == 200) {
@@ -211,7 +249,7 @@ export const useQuestionBox = defineStore('QuestionBox', () => {
isRepling.value = true
await QueryPostAPI(QUESTION_API_URL + 'reply', {
Id: id,
- Message: msg,
+ Message: msg
})
.then((data) => {
if (data.code == 200) {
@@ -236,7 +274,7 @@ export const useQuestionBox = defineStore('QuestionBox', () => {
async function read(question: QAInfo, read: boolean) {
await QueryGetAPI(QUESTION_API_URL + 'read', {
id: question.id,
- read: read ? 'true' : 'false',
+ read: read ? 'true' : 'false'
})
.then((data) => {
if (data.code == 200) {
@@ -255,7 +293,7 @@ export const useQuestionBox = defineStore('QuestionBox', () => {
async function favorite(question: QAInfo, fav: boolean) {
await QueryGetAPI(QUESTION_API_URL + 'favorite', {
id: question.id,
- favorite: fav,
+ favorite: fav
})
.then((data) => {
if (data.code == 200) {
@@ -272,7 +310,7 @@ export const useQuestionBox = defineStore('QuestionBox', () => {
isChangingPublic.value = true
await QueryGetAPI(QUESTION_API_URL + 'public', {
id: currentQuestion.value?.id,
- public: pub,
+ public: pub
})
.then((data) => {
if (data.code == 200) {
@@ -291,12 +329,12 @@ export const useQuestionBox = defineStore('QuestionBox', () => {
}
async function blacklist(question: QAInfo) {
await QueryGetAPI(ACCOUNT_API_URL + 'black-list/add', {
- id: question.sender.id,
+ id: question.sender.id
})
.then(async (data) => {
if (data.code == 200) {
await QueryGetAPI(QUESTION_API_URL + 'del', {
- id: question.id,
+ id: question.id
}).then((data) => {
if (data.code == 200) {
message.success('已拉黑 ' + question.sender.name)
@@ -325,8 +363,8 @@ export const useQuestionBox = defineStore('QuestionBox', () => {
isCurrent || !item
? null
: {
- id: item.id,
- },
+ id: item.id
+ }
)
if (data.code == 200) {
//message.success('设置成功')
@@ -347,6 +385,8 @@ export const useQuestionBox = defineStore('QuestionBox', () => {
recieveQuestions,
recieveQuestionsFiltered,
sendQuestions,
+ trashQuestions,
+ reviewing,
tags,
onlyFavorite,
onlyPublic,
@@ -366,5 +406,6 @@ export const useQuestionBox = defineStore('QuestionBox', () => {
setPublic,
blacklist,
setCurrentQuestion,
+ getViolationString
}
})
diff --git a/src/views/manage/HistoryView.vue b/src/views/manage/HistoryView.vue
index fd219f4..94116e4 100644
--- a/src/views/manage/HistoryView.vue
+++ b/src/views/manage/HistoryView.vue
@@ -100,7 +100,7 @@ function getOptions() {
// 用于存储粉丝增量数据
const fansIncreacement: { time: Date; count: number }[] = []
// 用于存储完整的时间序列数据,包括时间、粉丝数、是否变化
- const completeTimeSeries: { time: Date; count: number; change: boolean }[] = []
+ const completeTimeSeries: { time: Date; count: number; change: boolean, exist: boolean }[] = []
let startTime = new Date(accountInfo.value?.createAt ?? Date.now())
startTime = startTime < statisticStartDate ? statisticStartDate : startTime // 确保开始时间不早于统计开始时间
@@ -126,6 +126,7 @@ function getOptions() {
time: currentTime,
count: lastDayCount,
change: false,
+ exist: false,
})
break
}
@@ -138,6 +139,7 @@ function getOptions() {
time: currentTime,
count: lastDayCount,
change: changed,
+ exist: true,
})
break
}
@@ -274,7 +276,7 @@ function getOptions() {
let str = ''
for (var i = 0; i < param.length; i++) {
const status =
- param[i].seriesName == '粉丝数' ? (completeTimeSeries[param[i].dataIndex].change ? '' : '(未获取)') : ''
+ param[i].seriesName == '粉丝数' ? (completeTimeSeries[param[i].dataIndex].exist ? '' : '(未获取)') : ''
const statusHtml = status == '' ? '' : ' ' + status + ''
str += param[i].marker + param[i].seriesName + ':' + param[i].data + statusHtml + '
'
}
diff --git a/src/views/manage/QuestionBoxManageView.vue b/src/views/manage/QuestionBoxManageView.vue
index c0d937d..36ccde0 100644
--- a/src/views/manage/QuestionBoxManageView.vue
+++ b/src/views/manage/QuestionBoxManageView.vue
@@ -1,16 +1,19 @@