Parcourir la source

fix: preserve team background state

Developer il y a 3 jours
Parent
commit
8d62dac541

+ 1 - 3
components/CusTeamBackgroundFiles/index.vue

@@ -336,16 +336,14 @@ export default {
 			if (!teamId || !this.editable || !this.sameTeamId(teamId, this.activeTeamId())) return []
 			const generation = this.contextGeneration
 			const requestId = ++this.refreshRequestId
-			this.files = []
-			this.count = 0
 			this.filesReady = false
-			this.$emit('countChange', 0)
 			let files
 			try {
 				files = await listTeamBackgroundFiles(teamId)
 			} catch (error) {
 				if (!this.isCurrentContext(teamId, generation)
 					|| requestId !== this.refreshRequestId) return this.files
+				this.filesReady = this.hasLoadedFiles
 				throw error
 			}
 			if (!this.isCurrentContext(teamId, generation)

+ 1 - 1
components/CusTeamInfoFill/index.vue

@@ -16,7 +16,7 @@
 			<view class="form-item adfacjb">
 				<view class="form-item-title red">企业官网</view>
 				<view class="form-item-inp">
-					<u-input v-model="teamInfo.enterpriseWebsite" placeholder="无官网请填写“无”" placeholder-style="color:#B3BFC8;" border="none" inputAlign="right" fontSize="30rpx" color="#667E90" />
+					<u-input v-model="teamInfo.enterpriseWebsite" maxlength="500" placeholder="无官网请填写“无”" placeholder-style="color:#B3BFC8;" border="none" inputAlign="right" fontSize="30rpx" color="#667E90" />
 				</view>
 			</view>
 			<view class="form-item adfacjb">

+ 45 - 0
tests/teamBackgroundFile.test.js

@@ -8,6 +8,10 @@ const rules = require('../utils/teamBackgroundFile')
 assert.equal(rules.validateEnterpriseWebsite(' 无 '), '')
 assert.equal(rules.validateEnterpriseWebsite('https://example.com'), '')
 assert.match(rules.validateEnterpriseWebsite('ftp://example.com'), /http/)
+const websiteWithLength = length => `https://example.com/${'a'.repeat(length - 20)}`
+assert.equal(rules.validateEnterpriseWebsite(websiteWithLength(499)), '')
+assert.equal(rules.validateEnterpriseWebsite(websiteWithLength(500)), '')
+assert.match(rules.validateEnterpriseWebsite(websiteWithLength(501)), /500/)
 assert.equal(rules.validateBackgroundFile({ name: 'brief.PDF', size: 1 }), '')
 assert.match(rules.validateBackgroundFile({ name: 'brief.zip', size: 1 }), /类型/)
 assert.match(rules.validateBackgroundFile({ name: 'brief.pdf', size: 50 * 1024 * 1024 + 1 }), /50MB/)
@@ -1029,6 +1033,45 @@ async function testFileActionsWaitForCurrentListAndDocumentContext() {
 	assert.ok(toasts.some(message => String(message).includes('open failed')))
 }
 
+async function testSameTeamRefreshFailurePreservesExistingFilesAndCount() {
+	const listRequest = createDeferred()
+	const emittedCounts = []
+	const component = await loadVueComponent(backgroundComponentPath, {
+		http: { listTeamBackgroundFiles: () => listRequest.promise }
+	})
+	const instance = instantiateComponent(component, {
+		teamId: '', editable: true, $showToast() {},
+		$emit(name, value) { if (name === 'countChange') emittedCounts.push(value) }
+	})
+	instance.resetTeamContext(30)
+	const existingFiles = [{ id: 301, fileName: 'existing.pdf' }]
+	instance.files = existingFiles
+	instance.count = 1
+	instance.filesReady = true
+	instance.hasLoadedFiles = true
+	emittedCounts.length = 0
+
+	const refresh = instance.refreshFiles(30)
+	assert.equal(instance.files, existingFiles, 'same-team refresh must retain the visible list while loading')
+	assert.equal(instance.count, 1)
+	assert.deepEqual(emittedCounts, [], 'same-team refresh must not transiently emit zero')
+	listRequest.reject(new Error('refresh failed'))
+	await assert.rejects(refresh, /refresh failed/)
+	assert.equal(instance.files, existingFiles)
+	assert.equal(instance.count, 1)
+	assert.deepEqual(emittedCounts, [])
+
+	instance.resetTeamContext(31)
+	assert.equal(instance.files.length, 0)
+	assert.equal(instance.count, 0)
+	assert.deepEqual(emittedCounts, [0], 'switching teams must still clear the old count immediately')
+}
+
+async function testTeamWebsiteInputExposesTheAuthoritativeLengthLimit() {
+	const source = fs.readFileSync(teamFillComponentPath, 'utf8')
+	assert.match(source, /v-model="teamInfo\.enterpriseWebsite"[^>]*maxlength="500"/)
+}
+
 async function testTeamFillFlushesBeforeEmitAndLocks() {
 	const component = await loadVueComponent(teamFillComponentPath)
 	const flushDeferred = createDeferred()
@@ -1447,6 +1490,8 @@ async function main() {
 	await testDeferredPcWaiterSingleFlightFinishesAllCallers()
 	await testTeamContextResetAndUploadIsolation()
 	await testFileActionsWaitForCurrentListAndDocumentContext()
+	await testSameTeamRefreshFailurePreservesExistingFilesAndCount()
+	await testTeamWebsiteInputExposesTheAuthoritativeLengthLimit()
 	await testTeamFillFlushesBeforeEmitAndLocks()
 	await testCreatedTeamResumeAndSubmitLock()
 	await testCreatedTeamNavigationIsAwaitableAndResumable()

+ 1 - 0
utils/teamBackgroundFile.js

@@ -6,6 +6,7 @@ const SESSION_EXPIRES_AT_PATTERN = /^(\d{4})-(\d{2})-(\d{2})([ T])(\d{2}):(\d{2}
 function validateEnterpriseWebsite(value) {
 	const normalized = String(value || '').trim()
 	if (!normalized) return '请输入企业官网,无官网请填写“无”'
+	if (normalized.length > 500) return '企业官网不能超过500个字符'
 	if (normalized === '无') return ''
 	if (!/^https?:\/\/[^/\s?#]+(?:[/?#][^\s]*)?$/i.test(normalized)) return '请输入以http://或https://开头的企业官网'
 	return ''