This commit is contained in:
18631081161 2026-03-14 17:18:33 +08:00
parent 1bc7e4a098
commit c5d7b5e70a
30 changed files with 455 additions and 176 deletions

View File

@ -35,17 +35,25 @@
<el-dialog v-model="dialogVisible" :title="isEdit ? '编辑 Banner' : '新增 Banner'" width="500px">
<el-form ref="formRef" :model="form" :rules="rules" label-width="90px">
<el-form-item label="图片" prop="imageUrl">
<el-input v-model="form.imageUrl" placeholder="图片地址" />
<el-upload
action="/api/upload/image"
:headers="uploadHeaders"
:show-file-list="false"
:on-success="(res) => form.imageUrl = res.url"
:on-success="onUploadSuccess"
:before-upload="beforeUpload"
accept="image/*"
style="margin-top: 8px;"
>
<el-button size="small">上传图片</el-button>
<el-image
v-if="form.imageUrl"
:src="form.imageUrl"
style="width: 200px; height: 100px; cursor: pointer;"
fit="cover"
/>
<el-button v-else size="small" type="primary">选择图片</el-button>
</el-upload>
<div v-if="form.imageUrl" style="margin-top: 4px;">
<el-button size="small" text type="danger" @click="form.imageUrl = ''">移除图片</el-button>
</div>
</el-form-item>
<el-form-item label="链接类型" prop="linkType">
<el-select v-model="form.linkType" style="width: 100%;">
@ -86,6 +94,27 @@ const formRef = ref(null)
const uploadHeaders = { Authorization: `Bearer ${localStorage.getItem('admin_token')}` }
/** 上传成功回调 */
function onUploadSuccess(res) {
form.imageUrl = res.url
ElMessage.success('图片上传成功')
}
/** 上传前校验 */
function beforeUpload(file) {
const isImage = file.type.startsWith('image/')
const isLt5M = file.size / 1024 / 1024 < 5
if (!isImage) {
ElMessage.error('只能上传图片文件')
return false
}
if (!isLt5M) {
ElMessage.error('图片大小不能超过 5MB')
return false
}
return true
}
const defaultForm = () => ({
imageUrl: '',
linkType: 'External',

View File

@ -1,12 +1,15 @@
<template>
<div>
<h3 style="margin: 0 0 16px;">服务入口管理</h3>
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px;">
<h3 style="margin: 0;">服务入口管理</h3>
<el-button type="primary" @click="openDialog()">新增服务入口</el-button>
</div>
<el-table :data="list" v-loading="loading" border>
<el-table-column prop="name" label="服务名称" width="140" />
<el-table-column label="图标" width="100">
<el-table-column label="背景图" width="160">
<template #default="{ row }">
<el-image :src="row.iconUrl" style="width: 40px; height: 40px;" fit="contain" />
<el-image :src="row.iconUrl" style="width: 120px; height: 40px; border-radius: 4px;" fit="cover" />
</template>
</el-table-column>
<el-table-column prop="pagePath" label="跳转路径" show-overflow-tooltip />
@ -16,31 +19,51 @@
<el-tag :type="row.isEnabled ? 'success' : 'info'">{{ row.isEnabled ? '启用' : '禁用' }}</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="100" fixed="right">
<el-table-column label="操作" width="160" fixed="right">
<template #default="{ row }">
<el-button size="small" @click="openDialog(row)">编辑</el-button>
<el-button size="small" type="danger" @click="handleDelete(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 编辑弹窗 -->
<el-dialog v-model="dialogVisible" title="编辑服务入口" width="500px">
<!-- 新增/编辑弹窗 -->
<el-dialog v-model="dialogVisible" :title="isEdit ? '编辑服务入口' : '新增服务入口'" width="500px">
<el-form ref="formRef" :model="form" :rules="rules" label-width="90px">
<el-form-item label="服务名称">
<el-input :model-value="editName" disabled />
<el-form-item label="服务类型" prop="name">
<el-select v-model="form.name" placeholder="请选择服务类型" :disabled="isEdit" @change="onTypeChange" style="width: 100%;">
<el-option
v-for="item in serviceTypes"
:key="item.name"
:label="item.name"
:value="item.name"
:disabled="existingNames.includes(item.name)"
/>
</el-select>
</el-form-item>
<el-form-item label="图标图片" prop="iconUrl">
<el-input v-model="form.iconUrl" placeholder="图标图片地址" />
<el-form-item label="背景图片" prop="iconUrl">
<el-upload
action="/api/upload/image"
:headers="uploadHeaders"
:show-file-list="false"
:on-success="(res) => form.iconUrl = res.url"
:on-success="onUploadSuccess"
:before-upload="beforeUpload"
accept="image/*"
style="margin-top: 8px;"
>
<el-button size="small">上传图片</el-button>
<el-image
v-if="form.iconUrl"
:src="form.iconUrl"
style="width: 300px; height: 100px; cursor: pointer; border-radius: 8px;"
fit="cover"
/>
<el-button v-else size="small" type="primary">选择图片</el-button>
</el-upload>
<div v-if="form.iconUrl" style="margin-top: 4px;">
<el-button size="small" text type="danger" @click="form.iconUrl = ''">移除图片</el-button>
</div>
</el-form-item>
<el-form-item label="跳转路径">
<el-input v-model="form.pagePath" disabled />
</el-form-item>
<el-form-item label="排序权重">
<el-input-number v-model="form.sortOrder" :min="0" />
@ -59,23 +82,65 @@
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { ElMessage, ElMessageBox } from 'element-plus'
import request from '../utils/request'
const loading = ref(false)
const submitting = ref(false)
const list = ref([])
const dialogVisible = ref(false)
const isEdit = ref(false)
const editId = ref(null)
const editName = ref('')
const formRef = ref(null)
const uploadHeaders = { Authorization: `Bearer ${localStorage.getItem('admin_token')}` }
const form = reactive({ iconUrl: '', sortOrder: 0, isEnabled: true })
/** 服务类型与跳转路径映射 */
const serviceTypes = [
{ name: '代取', path: '/pages/pickup/pickup' },
{ name: '代送', path: '/pages/delivery/delivery' },
{ name: '万能帮', path: '/pages/help/help' },
{ name: '代购', path: '/pages/purchase/purchase' },
{ name: '美食街', path: '/pages/food/food' }
]
/** 已存在的服务名称(新增时禁用已有的选项) */
const existingNames = ref([])
/** 选择服务类型后自动匹配跳转路径 */
function onTypeChange(name) {
const match = serviceTypes.find(t => t.name === name)
if (match) form.pagePath = match.path
}
/** 上传成功回调 */
function onUploadSuccess(res) {
form.iconUrl = res.url
ElMessage.success('图片上传成功')
}
/** 上传前校验 */
function beforeUpload(file) {
const isImage = file.type.startsWith('image/')
const isLt5M = file.size / 1024 / 1024 < 5
if (!isImage) { ElMessage.error('只能上传图片文件'); return false }
if (!isLt5M) { ElMessage.error('图片大小不能超过 5MB'); return false }
return true
}
const defaultForm = () => ({
name: '',
iconUrl: '',
pagePath: '',
sortOrder: 0,
isEnabled: true
})
const form = reactive(defaultForm())
const rules = {
iconUrl: [{ required: true, message: '图标图片地址不能为空', trigger: 'blur' }]
name: [{ required: true, message: '请选择服务类型', trigger: 'change' }],
iconUrl: [{ required: true, message: '请上传背景图片', trigger: 'change' }]
}
/** 获取服务入口列表 */
@ -83,28 +148,40 @@ async function fetchList() {
loading.value = true
try {
list.value = await request.get('/admin/service-entries')
existingNames.value = list.value.map(item => item.name)
} finally {
loading.value = false
}
}
/** 打开编辑弹窗 */
/** 打开新增/编辑弹窗 */
function openDialog(row) {
editId.value = row.id
editName.value = row.name
Object.assign(form, { iconUrl: row.iconUrl, sortOrder: row.sortOrder, isEnabled: row.isEnabled })
isEdit.value = !!row
editId.value = row?.id || null
Object.assign(form, row ? {
name: row.name,
iconUrl: row.iconUrl,
pagePath: row.pagePath,
sortOrder: row.sortOrder,
isEnabled: row.isEnabled
} : defaultForm())
dialogVisible.value = true
}
/** 提交更新 */
/** 提交表单 */
async function handleSubmit() {
const valid = await formRef.value.validate().catch(() => false)
if (!valid) return
submitting.value = true
try {
await request.put(`/admin/service-entries/${editId.value}`, form)
ElMessage.success('更新成功')
if (isEdit.value) {
await request.put(`/admin/service-entries/${editId.value}`, form)
ElMessage.success('更新成功')
} else {
await request.post('/admin/service-entries', form)
ElMessage.success('创建成功')
}
dialogVisible.value = false
fetchList()
} finally {
@ -112,5 +189,13 @@ async function handleSubmit() {
}
}
/** 删除服务入口 */
async function handleDelete(row) {
await ElMessageBox.confirm(`确定删除「${row.name}」?`, '提示', { type: 'warning' })
await request.delete(`/admin/service-entries/${row.id}`)
ElMessage.success('删除成功')
fetchList()
}
onMounted(fetchList)
</script>

View File

@ -3,7 +3,7 @@
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页"
"navigationStyle": "custom"
}
},
{

View File

@ -1,35 +1,28 @@
<template>
<view class="index-page">
<!-- 自定义导航栏 -->
<view class="custom-navbar" :style="{ paddingTop: statusBarHeight + 'px' }">
<view class="navbar-content" :style="{ height: navBarHeight + 'px' }">
<text class="navbar-title">首页</text>
</view>
</view>
<!-- 占位防止内容被导航栏遮挡 -->
<view :style="{ height: (statusBarHeight + navBarHeight) + 'px' }"></view>
<!-- Banner 轮播区域 -->
<swiper
v-if="banners.length > 0"
class="banner-swiper"
indicator-dots
autoplay
circular
indicator-color="rgba(255,255,255,0.5)"
indicator-active-color="#ffffff"
>
<swiper-item
v-for="item in banners"
:key="item.id"
@click="onBannerClick(item)"
>
<swiper v-if="banners.length > 0" class="banner-swiper" indicator-dots autoplay circular
indicator-color="rgba(255,255,255,0.5)" indicator-active-color="#ffffff">
<swiper-item v-for="item in banners" :key="item.id" @click="onBannerClick(item)">
<image class="banner-image" :src="item.imageUrl" mode="aspectFill"></image>
</swiper-item>
</swiper>
<!-- 服务入口区域 -->
<view class="service-section">
<view class="service-title">下订单</view>
<view class="service-grid">
<view
class="service-item"
v-for="entry in serviceEntries"
:key="entry.id"
@click="onServiceClick(entry)"
>
<image class="service-icon" :src="entry.iconUrl" mode="aspectFit"></image>
<!-- 服务入口卡片列表 -->
<view class="service-list">
<view class="service-card" v-for="entry in serviceEntries" :key="entry.id" @click="onServiceClick(entry)">
<image class="service-bg" :src="entry.iconUrl" mode="aspectFit"></image>
<view class="service-overlay">
<text class="service-name">{{ entry.name }}</text>
</view>
</view>
@ -38,114 +31,142 @@
</template>
<script>
import { getBanners, getServiceEntries } from '../../utils/api'
import {
getBanners,
getServiceEntries
} from '../../utils/api'
export default {
data() {
return {
banners: [],
serviceEntries: []
}
},
onShow() {
this.loadData()
},
methods: {
/** 加载 Banner 和服务入口数据 */
async loadData() {
try {
const [bannerRes, entryRes] = await Promise.all([
getBanners(),
getServiceEntries()
])
this.banners = bannerRes || []
this.serviceEntries = entryRes || []
} catch (e) {
//
export default {
data() {
return {
banners: [],
serviceEntries: [],
statusBarHeight: 0,
navBarHeight: 44
}
},
onLoad() {
const sysInfo = uni.getSystemInfoSync()
this.statusBarHeight = sysInfo.statusBarHeight || 0
},
onShow() {
this.loadData()
},
methods: {
/** 加载 Banner 和服务入口数据 */
async loadData() {
try {
const [bannerRes, entryRes] = await Promise.all([
getBanners(),
getServiceEntries()
])
this.banners = bannerRes || []
this.serviceEntries = entryRes || []
} catch (e) {
//
}
},
/**
* Banner 点击处理
* 外部链接通过 web-view 打开
* 内部页面直接跳转
*/
onBannerClick(item) {
if (!item.linkUrl) return
/** Banner 点击处理 */
onBannerClick(item) {
if (!item.linkUrl) return
if (item.linkType === 'External') {
uni.navigateTo({
url: `/pages/webview/webview?url=${encodeURIComponent(item.linkUrl)}`
})
} else {
uni.navigateTo({
url: item.linkUrl
})
}
},
if (item.linkType === 'External') {
// web-view
/** 服务入口点击跳转 */
onServiceClick(entry) {
if (!entry.pagePath) return
uni.navigateTo({
url: `/pages/webview/webview?url=${encodeURIComponent(item.linkUrl)}`
url: entry.pagePath
})
} else {
//
uni.navigateTo({ url: item.linkUrl })
}
},
/**
* 服务入口点击跳转
*/
onServiceClick(entry) {
if (!entry.pagePath) return
uni.navigateTo({ url: entry.pagePath })
}
}
}
</script>
<style scoped>
.index-page {
padding-bottom: 20rpx;
}
.index-page {
padding-bottom: 20rpx;
background-color: #f5f5f5;
}
.banner-swiper {
width: 100%;
height: 320rpx;
}
/* 自定义导航栏 */
.custom-navbar {
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 999;
background: linear-gradient(to right, #FFB700, #FFD59B);
}
.banner-image {
width: 100%;
height: 320rpx;
}
.navbar-content {
display: flex;
align-items: center;
justify-content: center;
}
.service-section {
margin: 30rpx 24rpx 0;
background-color: #ffffff;
border-radius: 16rpx;
padding: 30rpx;
}
.navbar-title {
font-size: 34rpx;
font-weight: bold;
color: #363636;
}
.service-title {
font-size: 32rpx;
font-weight: bold;
color: #333333;
margin-bottom: 30rpx;
}
.banner-swiper {
width: 100%;
height: 400rpx;
}
.service-grid {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.banner-image {
width: 100%;
height: 400rpx;
}
.service-item {
display: flex;
flex-direction: column;
align-items: center;
width: 20%;
margin-bottom: 20rpx;
}
/* 服务入口卡片列表 */
.service-list {
padding: 20rpx 24rpx;
}
.service-icon {
width: 88rpx;
height: 88rpx;
margin-bottom: 12rpx;
}
.service-card {
position: relative;
width: 100%;
height: 180rpx;
overflow: hidden;
margin-bottom: 20rpx;
}
.service-name {
font-size: 24rpx;
color: #666666;
}
</style>
.service-bg {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
.service-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.service-name {
font-size: 48rpx;
font-weight: bold;
color: #363636;
text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.3);
letter-spacing: 8rpx;
}
</style>

View File

@ -15,6 +15,7 @@
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="10.0.3" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="10.0.3" />
<PackageReference Include="Tencent.QCloud.Cos.Sdk" Version="5.4.*" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.1.4" />
</ItemGroup>

View File

@ -2,6 +2,33 @@ using System.ComponentModel.DataAnnotations;
namespace CampusErrand.Models.Dtos;
/// <summary>
/// 服务入口创建请求
/// </summary>
public class ServiceEntryCreateRequest
{
/// <summary>服务名称</summary>
[Required(ErrorMessage = "服务名称不能为空")]
[MaxLength(32)]
public string Name { get; set; } = string.Empty;
/// <summary>背景图片地址</summary>
[Required(ErrorMessage = "背景图片不能为空")]
[MaxLength(512)]
public string IconUrl { get; set; } = string.Empty;
/// <summary>跳转页面路径</summary>
[Required(ErrorMessage = "跳转路径不能为空")]
[MaxLength(256)]
public string PagePath { get; set; } = string.Empty;
/// <summary>排序权重</summary>
public int SortOrder { get; set; }
/// <summary>是否启用</summary>
public bool IsEnabled { get; set; } = true;
}
/// <summary>
/// 服务入口更新请求
/// </summary>

View File

@ -428,6 +428,51 @@ app.MapPut("/api/admin/service-entries/{id}", async (int id, ServiceEntryUpdateR
});
}).RequireAuthorization("AdminOnly");
// 创建服务入口
app.MapPost("/api/admin/service-entries", async (ServiceEntryCreateRequest request, AppDbContext db) =>
{
if (string.IsNullOrWhiteSpace(request.Name))
return Results.BadRequest(new { code = 400, message = "服务名称不能为空" });
if (string.IsNullOrWhiteSpace(request.IconUrl))
return Results.BadRequest(new { code = 400, message = "背景图片不能为空" });
if (string.IsNullOrWhiteSpace(request.PagePath))
return Results.BadRequest(new { code = 400, message = "跳转路径不能为空" });
var entry = new ServiceEntry
{
Name = request.Name,
IconUrl = request.IconUrl,
PagePath = request.PagePath,
SortOrder = request.SortOrder,
IsEnabled = request.IsEnabled
};
db.ServiceEntries.Add(entry);
await db.SaveChangesAsync();
return Results.Created($"/api/admin/service-entries/{entry.Id}", new ServiceEntryResponse
{
Id = entry.Id,
Name = entry.Name,
IconUrl = entry.IconUrl,
PagePath = entry.PagePath,
SortOrder = entry.SortOrder,
IsEnabled = entry.IsEnabled
});
}).RequireAuthorization("AdminOnly");
// 删除服务入口
app.MapDelete("/api/admin/service-entries/{id}", async (int id, AppDbContext db) =>
{
var entry = await db.ServiceEntries.FindAsync(id);
if (entry == null)
return Results.NotFound(new { code = 404, message = "服务入口不存在" });
db.ServiceEntries.Remove(entry);
await db.SaveChangesAsync();
return Results.NoContent();
}).RequireAuthorization("AdminOnly");
// ========== 订单接口 ==========
// 创建订单
@ -2426,33 +2471,43 @@ app.MapPost("/api/upload/image", async (IFormFile file, IConfiguration config) =
if (!allowedExtensions.Contains(ext))
return Results.BadRequest(new { code = 400, message = $"不支持的图片格式,仅支持 {string.Join(", ", allowedExtensions)}" });
// 保存文件
var uploadDir = config.GetValue<string>("Upload:Directory") ?? "uploads";
var fullDir = Path.Combine(Directory.GetCurrentDirectory(), uploadDir);
Directory.CreateDirectory(fullDir);
// 上传到腾讯云 COS
var cosConfig = new COSXML.CosXmlConfig.Builder()
.IsHttps(true)
.SetRegion(config["COS:Region"])
.Build();
var credential = new COSXML.Auth.DefaultQCloudCredentialProvider(
config["COS:SecretId"], config["COS:SecretKey"], 600);
var cosXml = new COSXML.CosXmlServer(cosConfig, credential);
var fileName = $"{Guid.NewGuid()}{ext}";
var filePath = Path.Combine(fullDir, fileName);
var bucket = config["COS:Bucket"]!;
var cosKey = $"uploads/{DateTime.UtcNow:yyyyMMdd}/{Guid.NewGuid()}{ext}";
using (var stream = new FileStream(filePath, FileMode.Create))
// 将上传文件写入临时文件
var tempPath = Path.GetTempFileName();
try
{
await file.CopyToAsync(stream);
}
using (var stream = new FileStream(tempPath, FileMode.Create))
{
await file.CopyToAsync(stream);
}
var url = $"/{uploadDir}/{fileName}";
return Results.Ok(new UploadImageResponse { Url = url });
var putRequest = new COSXML.Model.Object.PutObjectRequest(bucket, cosKey, tempPath);
var putResult = cosXml.PutObject(putRequest);
if (putResult.httpCode != 200)
return Results.BadRequest(new { code = 400, message = "图片上传失败" });
var url = $"{config["COS:BaseUrl"]}/{cosKey}";
return Results.Ok(new UploadImageResponse { Url = url });
}
finally
{
if (File.Exists(tempPath)) File.Delete(tempPath);
}
}).RequireAuthorization()
.DisableAntiforgery();
// 静态文件服务(上传的图片)
var uploadPath = Path.Combine(Directory.GetCurrentDirectory(),
builder.Configuration.GetValue<string>("Upload:Directory") ?? "uploads");
Directory.CreateDirectory(uploadPath);
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new Microsoft.Extensions.FileProviders.PhysicalFileProvider(uploadPath),
RequestPath = "/" + (builder.Configuration.GetValue<string>("Upload:Directory") ?? "uploads")
});
// ========== 系统配置接口 ==========

View File

@ -23,10 +23,16 @@
"AppSecret": "your_wechat_appsecret"
},
"Upload": {
"Directory": "uploads",
"MaxFileSizeBytes": 5242880,
"AllowedExtensions": [ ".jpg", ".jpeg", ".png", ".gif", ".webp" ]
},
"COS": {
"SecretId": "AKIDPioO4YovwtfMrwrYJq8CNN9qT4c0IyQd",
"SecretKey": "1nLfLp44pOxUsKe1AmS8gFoBLH0Vloco",
"Region": "ap-nanjing",
"Bucket": "xypt-1410898760",
"BaseUrl": "https://xypt-1410898760.cos.ap-nanjing.myqcloud.com"
},
"Admin": {
"Username": "admin",
"Password": "admin123"

View File

@ -13,7 +13,8 @@
"Microsoft.EntityFrameworkCore.Design": "10.0.3",
"Microsoft.EntityFrameworkCore.SqlServer": "10.0.3",
"Microsoft.Extensions.Caching.StackExchangeRedis": "10.0.3",
"Swashbuckle.AspNetCore": "10.1.4"
"Swashbuckle.AspNetCore": "10.1.4",
"Tencent.QCloud.Cos.Sdk": "5.4.51"
},
"runtime": {
"CampusErrand.dll": {}
@ -846,6 +847,14 @@
"fileVersion": "9.0.425.16305"
}
}
},
"Tencent.QCloud.Cos.Sdk/5.4.51": {
"runtime": {
"lib/netstandard2.0/COSXML.dll": {
"assemblyVersion": "5.4.51.0",
"fileVersion": "5.4.51.0"
}
}
}
}
},
@ -1225,6 +1234,13 @@
"sha512": "sha512-o94k2RKuAce3GeDMlUvIXlhVa1kWpJw95E6C9LwW0KlG0nj5+SgCiIxJ2Eroqb9sLtG1mEMbFttZIBZ13EJPvQ==",
"path": "system.security.cryptography.protecteddata/9.0.4",
"hashPath": "system.security.cryptography.protecteddata.9.0.4.nupkg.sha512"
},
"Tencent.QCloud.Cos.Sdk/5.4.51": {
"type": "package",
"serviceable": true,
"sha512": "sha512-ZLU6XX7vyLaVFN0i+fcFbiXSN2BENKxlTe7inIRT4JibuzhU9cZxGj+PfSIib46+uJM6HSRJE2ynnGLCMtTt1Q==",
"path": "tencent.qcloud.cos.sdk/5.4.51",
"hashPath": "tencent.qcloud.cos.sdk.5.4.51.nupkg.sha512"
}
}
}

View File

@ -23,10 +23,16 @@
"AppSecret": "your_wechat_appsecret"
},
"Upload": {
"Directory": "uploads",
"MaxFileSizeBytes": 5242880,
"AllowedExtensions": [ ".jpg", ".jpeg", ".png", ".gif", ".webp" ]
},
"COS": {
"SecretId": "AKIDPioO4YovwtfMrwrYJq8CNN9qT4c0IyQd",
"SecretKey": "1nLfLp44pOxUsKe1AmS8gFoBLH0Vloco",
"Region": "ap-nanjing",
"Bucket": "xypt-1410898760",
"BaseUrl": "https://xypt-1410898760.cos.ap-nanjing.myqcloud.com"
},
"Admin": {
"Username": "admin",
"Password": "admin123"

View File

@ -73,6 +73,10 @@
"Swashbuckle.AspNetCore": {
"target": "Package",
"version": "[10.1.4, )"
},
"Tencent.QCloud.Cos.Sdk": {
"target": "Package",
"version": "[5.4.*, )"
}
},
"imports": [

View File

@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("CampusErrand")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+8245a67b883c1c90d3366fdad3ae6571b49fb874")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+1bc7e4a09873a38e8ff83966dc378b341abe98ad")]
[assembly: System.Reflection.AssemblyProductAttribute("CampusErrand")]
[assembly: System.Reflection.AssemblyTitleAttribute("CampusErrand")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@ -1 +1 @@
98518d7bd93239cba34464b0a48bacbdc87dd10aa86c7d87d6cac18429a41da5
96b198ea2f78751f1455d36835312860960c974f190b06da8b6cfc34bed4d63b

View File

@ -1 +1 @@
44792c73e656d5f2a97e5c9b6b8ce93c50dcddc8336f696a305446e8c692ccef
78df5ed8d99d8eb59d9966deec229e9c6198cae7cafc5e797e106a95bd2f5937

View File

@ -163,3 +163,4 @@ F:\gitCode\uniapp\campus-errand\server\bin\Debug\net10.0\runtimes\win-x86\native
F:\gitCode\uniapp\campus-errand\server\bin\Debug\net10.0\Microsoft.Extensions.Caching.StackExchangeRedis.dll
F:\gitCode\uniapp\campus-errand\server\bin\Debug\net10.0\Pipelines.Sockets.Unofficial.dll
F:\gitCode\uniapp\campus-errand\server\bin\Debug\net10.0\StackExchange.Redis.dll
F:\gitCode\uniapp\campus-errand\server\bin\Debug\net10.0\COSXML.dll

Binary file not shown.

View File

@ -1 +1 @@
{"GlobalPropertiesHash":"FvzDiEs0EAZdBI8Qwd38I/qGfErxBHzrnzacDdp9C+k=","FingerprintPatternsHash":"gq3WsqcKBUGTSNle7RKKyXRIwh7M8ccEqOqYvIzoM04=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["GK5QIP/XYYWUmh4Y3T9pQ7nr7hLlrhu9WxJOHJg3jys=","z/gGq5d2i3Bdu2Yx2tEtdvNdI2DMCuO1Loennep6rpA=","SoTqP58euSfouOt\u002BChgsmMST1TEMY1s4SX8M5\u002BcSaTw=","2QszdUJOx7XR0BbgOxnwnj2CMLTUOxSCfW9scid9JZc=","Fnoznyra3P\u002BfAr4\u002B9jhnDM6hctHw/2GK9WTw8eHJKVU="],"CachedAssets":{},"CachedCopyCandidates":{}}
{"GlobalPropertiesHash":"FvzDiEs0EAZdBI8Qwd38I/qGfErxBHzrnzacDdp9C+k=","FingerprintPatternsHash":"gq3WsqcKBUGTSNle7RKKyXRIwh7M8ccEqOqYvIzoM04=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["GK5QIP/XYYWUmh4Y3T9pQ7nr7hLlrhu9WxJOHJg3jys=","7O1biPThQ/Mx8/A74Cld5MaMED9jut8kLikNlVczxp0=","SoTqP58euSfouOt\u002BChgsmMST1TEMY1s4SX8M5\u002BcSaTw=","2QszdUJOx7XR0BbgOxnwnj2CMLTUOxSCfW9scid9JZc=","kZStffijBiMuyyJSjpIXxXHAqVzgrSRDWd\u002BAbED3Bw0="],"CachedAssets":{},"CachedCopyCandidates":{}}

View File

@ -1 +1 @@
{"GlobalPropertiesHash":"xZi1R2Spy0ovDkIJOzs1I1YG/hzfBSNqDGLZKXuVfgw=","FingerprintPatternsHash":"gq3WsqcKBUGTSNle7RKKyXRIwh7M8ccEqOqYvIzoM04=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["GK5QIP/XYYWUmh4Y3T9pQ7nr7hLlrhu9WxJOHJg3jys=","z/gGq5d2i3Bdu2Yx2tEtdvNdI2DMCuO1Loennep6rpA=","SoTqP58euSfouOt\u002BChgsmMST1TEMY1s4SX8M5\u002BcSaTw=","2QszdUJOx7XR0BbgOxnwnj2CMLTUOxSCfW9scid9JZc=","Fnoznyra3P\u002BfAr4\u002B9jhnDM6hctHw/2GK9WTw8eHJKVU="],"CachedAssets":{},"CachedCopyCandidates":{}}
{"GlobalPropertiesHash":"xZi1R2Spy0ovDkIJOzs1I1YG/hzfBSNqDGLZKXuVfgw=","FingerprintPatternsHash":"gq3WsqcKBUGTSNle7RKKyXRIwh7M8ccEqOqYvIzoM04=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["GK5QIP/XYYWUmh4Y3T9pQ7nr7hLlrhu9WxJOHJg3jys=","7O1biPThQ/Mx8/A74Cld5MaMED9jut8kLikNlVczxp0=","SoTqP58euSfouOt\u002BChgsmMST1TEMY1s4SX8M5\u002BcSaTw=","2QszdUJOx7XR0BbgOxnwnj2CMLTUOxSCfW9scid9JZc=","kZStffijBiMuyyJSjpIXxXHAqVzgrSRDWd\u002BAbED3Bw0="],"CachedAssets":{},"CachedCopyCandidates":{}}

View File

@ -1 +1 @@
{"GlobalPropertiesHash":"UIXRzOYtQqecH7DZRES/B1ooBYuqqrRO0PLf2qdAYiY=","FingerprintPatternsHash":"gq3WsqcKBUGTSNle7RKKyXRIwh7M8ccEqOqYvIzoM04=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["GK5QIP/XYYWUmh4Y3T9pQ7nr7hLlrhu9WxJOHJg3jys=","z/gGq5d2i3Bdu2Yx2tEtdvNdI2DMCuO1Loennep6rpA="],"CachedAssets":{},"CachedCopyCandidates":{}}
{"GlobalPropertiesHash":"UIXRzOYtQqecH7DZRES/B1ooBYuqqrRO0PLf2qdAYiY=","FingerprintPatternsHash":"gq3WsqcKBUGTSNle7RKKyXRIwh7M8ccEqOqYvIzoM04=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["GK5QIP/XYYWUmh4Y3T9pQ7nr7hLlrhu9WxJOHJg3jys=","7O1biPThQ/Mx8/A74Cld5MaMED9jut8kLikNlVczxp0="],"CachedAssets":{},"CachedCopyCandidates":{}}

View File

@ -1198,6 +1198,15 @@
"build": {
"buildTransitive/net8.0/_._": {}
}
},
"Tencent.QCloud.Cos.Sdk/5.4.51": {
"type": "package",
"compile": {
"lib/netstandard2.0/COSXML.dll": {}
},
"runtime": {
"lib/netstandard2.0/COSXML.dll": {}
}
}
}
},
@ -3669,6 +3678,19 @@
"system.security.cryptography.protecteddata.nuspec",
"useSharedDesignerContext.txt"
]
},
"Tencent.QCloud.Cos.Sdk/5.4.51": {
"sha512": "ZLU6XX7vyLaVFN0i+fcFbiXSN2BENKxlTe7inIRT4JibuzhU9cZxGj+PfSIib46+uJM6HSRJE2ynnGLCMtTt1Q==",
"type": "package",
"path": "tencent.qcloud.cos.sdk/5.4.51",
"files": [
".nupkg.metadata",
".signature.p7s",
"lib/net45/COSXML.dll",
"lib/netstandard2.0/COSXML.dll",
"tencent.qcloud.cos.sdk.5.4.51.nupkg.sha512",
"tencent.qcloud.cos.sdk.nuspec"
]
}
},
"projectFileDependencyGroups": {
@ -3678,7 +3700,8 @@
"Microsoft.EntityFrameworkCore.Design >= 10.0.3",
"Microsoft.EntityFrameworkCore.SqlServer >= 10.0.3",
"Microsoft.Extensions.Caching.StackExchangeRedis >= 10.0.3",
"Swashbuckle.AspNetCore >= 10.1.4"
"Swashbuckle.AspNetCore >= 10.1.4",
"Tencent.QCloud.Cos.Sdk >= 5.4.*"
]
},
"packageFolders": {
@ -3754,6 +3777,10 @@
"Swashbuckle.AspNetCore": {
"target": "Package",
"version": "[10.1.4, )"
},
"Tencent.QCloud.Cos.Sdk": {
"target": "Package",
"version": "[5.4.*, )"
}
},
"imports": [

View File

@ -1,6 +1,6 @@
{
"version": 2,
"dgSpecHash": "bN2gwtm/FeU=",
"dgSpecHash": "1DPzBxf0SFk=",
"success": true,
"projectFilePath": "F:\\gitCode\\uniapp\\campus-errand\\server\\CampusErrand.csproj",
"expectedPackageFiles": [
@ -60,7 +60,8 @@
"C:\\Users\\HJL\\.nuget\\packages\\system.identitymodel.tokens.jwt\\8.0.1\\system.identitymodel.tokens.jwt.8.0.1.nupkg.sha512",
"C:\\Users\\HJL\\.nuget\\packages\\system.memory.data\\8.0.1\\system.memory.data.8.0.1.nupkg.sha512",
"C:\\Users\\HJL\\.nuget\\packages\\system.security.cryptography.pkcs\\9.0.4\\system.security.cryptography.pkcs.9.0.4.nupkg.sha512",
"C:\\Users\\HJL\\.nuget\\packages\\system.security.cryptography.protecteddata\\9.0.4\\system.security.cryptography.protecteddata.9.0.4.nupkg.sha512"
"C:\\Users\\HJL\\.nuget\\packages\\system.security.cryptography.protecteddata\\9.0.4\\system.security.cryptography.protecteddata.9.0.4.nupkg.sha512",
"C:\\Users\\HJL\\.nuget\\packages\\tencent.qcloud.cos.sdk\\5.4.51\\tencent.qcloud.cos.sdk.5.4.51.nupkg.sha512"
],
"logs": []
}