222
This commit is contained in:
parent
35866b1387
commit
87c7fffd3e
|
|
@ -0,0 +1,178 @@
|
||||||
|
# 新建项目系列选择功能实现
|
||||||
|
|
||||||
|
## 需求分析
|
||||||
|
- 当用户点击"新建项目"卡片时,需要弹出系列选择弹窗
|
||||||
|
- 系列弹窗包含两个选项:Done 和 Oone,对应图片在 src/assets/xh 文件夹中
|
||||||
|
- 选中后将系列名称作为 type 参数传递给 createNewProject 函数
|
||||||
|
|
||||||
|
## 实现计划
|
||||||
|
|
||||||
|
### 1. 创建 SeriesSelector 组件
|
||||||
|
- **文件路径**:`src/views/components/SeriesSelector.vue`
|
||||||
|
- **功能**:
|
||||||
|
- 显示两个系列选项(Done 和 Oone)
|
||||||
|
- 每个选项显示对应的图片
|
||||||
|
- 支持选中状态切换
|
||||||
|
- 提供确认和取消按钮
|
||||||
|
- 通过 emit 事件返回选中的系列名称
|
||||||
|
|
||||||
|
### 2. 修改 CreationWorkspace.vue
|
||||||
|
- **引入组件**:在 CreationWorkspace.vue 中引入 SeriesSelector 组件
|
||||||
|
- **添加状态管理**:
|
||||||
|
- `showSeriesSelector`:控制系列选择弹窗的显示/隐藏
|
||||||
|
- **修改新建项目逻辑**:
|
||||||
|
- 点击"新建项目"卡片时,显示系列选择弹窗
|
||||||
|
- 监听 SeriesSelector 的确认事件,获取选中的系列名称
|
||||||
|
- 将系列名称作为 type 参数调用 createNewProject 函数
|
||||||
|
|
||||||
|
### 3. 样式设计
|
||||||
|
- 系列选择弹窗采用与现有删除确认弹窗一致的设计风格
|
||||||
|
- 系列选项卡片包含图片和名称,支持悬停和选中效果
|
||||||
|
- 确认和取消按钮使用现有按钮样式
|
||||||
|
|
||||||
|
## 代码结构
|
||||||
|
|
||||||
|
### SeriesSelector.vue
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<!-- 系列选择弹窗 -->
|
||||||
|
<div v-if="show" class="modal-overlay" @click="onCancel">
|
||||||
|
<div class="modal-content" @click.stop>
|
||||||
|
<!-- 模态头部 -->
|
||||||
|
<div class="modal-header">
|
||||||
|
<h2 class="modal-title">{{ t('creationWorkspace.selectSeries') }}</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 模态内容 -->
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="series-selector-content">
|
||||||
|
<!-- 系列选项列表 -->
|
||||||
|
<div class="series-list">
|
||||||
|
<!-- Done 系列 -->
|
||||||
|
<div
|
||||||
|
class="series-item"
|
||||||
|
:class="{ active: selectedSeries === 'Done' }"
|
||||||
|
@click="selectedSeries = 'Done'"
|
||||||
|
>
|
||||||
|
<div class="series-image">
|
||||||
|
<img src="@/assets/xh/Done.webp" alt="Done" />
|
||||||
|
</div>
|
||||||
|
<div class="series-name">Done</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Oone 系列 -->
|
||||||
|
<div
|
||||||
|
class="series-item"
|
||||||
|
:class="{ active: selectedSeries === 'Oone' }"
|
||||||
|
@click="selectedSeries = 'Oone'"
|
||||||
|
>
|
||||||
|
<div class="series-image">
|
||||||
|
<img src="@/assets/xh/Oone.webp" alt="Oone" />
|
||||||
|
</div>
|
||||||
|
<div class="series-name">Oone</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 操作按钮 -->
|
||||||
|
<div class="series-actions">
|
||||||
|
<button class="modal-action-btn cancel" @click="onCancel">
|
||||||
|
{{ t('creationWorkspace.cancel') }}
|
||||||
|
</button>
|
||||||
|
<button class="modal-action-btn primary" @click="onConfirm">
|
||||||
|
{{ t('creationWorkspace.confirm') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, defineProps, defineEmits } from 'vue'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
show: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['confirm', 'cancel'])
|
||||||
|
|
||||||
|
const selectedSeries = ref('')
|
||||||
|
|
||||||
|
const onConfirm = () => {
|
||||||
|
if (selectedSeries.value) {
|
||||||
|
emit('confirm', selectedSeries.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const onCancel = () => {
|
||||||
|
emit('cancel')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* 系列选择弹窗样式 */
|
||||||
|
.series-selector-content {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.series-list {
|
||||||
|
display: flex;
|
||||||
|
gap: 24px;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.series-item {
|
||||||
|
background: #f8fafc;
|
||||||
|
border: 2px solid #e2e8f0;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.series-item:hover {
|
||||||
|
transform: translateY(-4px);
|
||||||
|
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.series-item.active {
|
||||||
|
border-color: #6B46C1;
|
||||||
|
background: rgba(107, 70, 193, 0.05);
|
||||||
|
box-shadow: 0 4px 16px rgba(107, 70, 193, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.series-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 120px;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.series-image img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.series-name {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #1f2937;
|
||||||
|
}
|
||||||
|
|
||||||
|
.series-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 16px;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -175,7 +175,8 @@ export default {
|
||||||
shenhe: 'Under Review',
|
shenhe: 'Under Review',
|
||||||
unsuccess: 'Rejected',
|
unsuccess: 'Rejected',
|
||||||
clz: 'Processing',
|
clz: 'Processing',
|
||||||
dfh: 'Pending Shipment'
|
dfh: 'Pending Shipment',
|
||||||
|
success:'Completed'
|
||||||
},
|
},
|
||||||
sort: {
|
sort: {
|
||||||
created_at: 'Created Time',
|
created_at: 'Created Time',
|
||||||
|
|
@ -741,7 +742,26 @@ export default {
|
||||||
},
|
},
|
||||||
commissionManagement: {
|
commissionManagement: {
|
||||||
title: 'Commission Management',
|
title: 'Commission Management',
|
||||||
|
configTitle: 'Commission Configuration',
|
||||||
commissionRate: 'Commission Rate',
|
commissionRate: 'Commission Rate',
|
||||||
|
minWithdrawAmount: 'Minimum Withdraw Amount',
|
||||||
|
withdrawFeeRate: 'Withdraw Fee Rate',
|
||||||
|
settlementCycle: 'Settlement Cycle',
|
||||||
|
status: 'Status',
|
||||||
|
remark: 'Remark',
|
||||||
|
saveConfig: 'Save Configuration',
|
||||||
|
selectSettlementCycle: 'Please select settlement cycle',
|
||||||
|
enterRemark: 'Please enter remark',
|
||||||
|
daily: 'Daily',
|
||||||
|
weekly: 'Weekly',
|
||||||
|
monthly: 'Monthly',
|
||||||
|
requiredCommissionRate: 'Please enter commission rate',
|
||||||
|
invalidCommissionRate: 'Commission rate should be between 1-100',
|
||||||
|
requiredMinWithdrawAmount: 'Please enter minimum withdraw amount',
|
||||||
|
invalidMinWithdrawAmount: 'Minimum withdraw amount cannot be less than 0',
|
||||||
|
getConfigFailed: 'Failed to get commission configuration',
|
||||||
|
saveConfigSuccess: 'Configuration saved successfully',
|
||||||
|
saveConfigFailed: 'Failed to save configuration',
|
||||||
saveRate: 'Save',
|
saveRate: 'Save',
|
||||||
defaultRate: '15%',
|
defaultRate: '15%',
|
||||||
rateSaved: 'Commission rate saved successfully',
|
rateSaved: 'Commission rate saved successfully',
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,8 @@ orderManagement: {
|
||||||
shenhe:'待审核',
|
shenhe:'待审核',
|
||||||
unsuccess:'已拒绝',
|
unsuccess:'已拒绝',
|
||||||
clz:'处理中',
|
clz:'处理中',
|
||||||
dfh:'待发货'
|
dfh:'待发货',
|
||||||
|
success:'已完成'
|
||||||
},
|
},
|
||||||
sort: {
|
sort: {
|
||||||
created_at: '创建时间',
|
created_at: '创建时间',
|
||||||
|
|
@ -738,7 +739,26 @@ orderManagement: {
|
||||||
},
|
},
|
||||||
commissionManagement: {
|
commissionManagement: {
|
||||||
title: '佣金管理',
|
title: '佣金管理',
|
||||||
|
configTitle: '佣金配置',
|
||||||
commissionRate: '佣金比例',
|
commissionRate: '佣金比例',
|
||||||
|
minWithdrawAmount: '最低提现金额',
|
||||||
|
withdrawFeeRate: '提现费率',
|
||||||
|
settlementCycle: '结算周期',
|
||||||
|
status: '状态',
|
||||||
|
remark: '备注',
|
||||||
|
saveConfig: '保存配置',
|
||||||
|
selectSettlementCycle: '请选择结算周期',
|
||||||
|
enterRemark: '请输入备注',
|
||||||
|
daily: '每日',
|
||||||
|
weekly: '每周',
|
||||||
|
monthly: '每月',
|
||||||
|
requiredCommissionRate: '请输入佣金比例',
|
||||||
|
invalidCommissionRate: '佣金比例应在1-100之间',
|
||||||
|
requiredMinWithdrawAmount: '请输入最低提现金额',
|
||||||
|
invalidMinWithdrawAmount: '最低提现金额不能小于0',
|
||||||
|
getConfigFailed: '获取佣金配置失败',
|
||||||
|
saveConfigSuccess: '保存配置成功',
|
||||||
|
saveConfigFailed: '保存配置失败',
|
||||||
saveRate: '保存',
|
saveRate: '保存',
|
||||||
defaultRate: '15%',
|
defaultRate: '15%',
|
||||||
rateSaved: '佣金比例保存成功',
|
rateSaved: '佣金比例保存成功',
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ const initRoutes = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// initRoutes()
|
initRoutes()
|
||||||
// 配置路由
|
// 配置路由
|
||||||
app.use(router)
|
app.use(router)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -196,6 +196,43 @@ export const permissionRoutes = [
|
||||||
requiresAuth: true
|
requiresAuth: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
]
|
||||||
|
const routes = [
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
name: 'Home',
|
||||||
|
meta: {
|
||||||
|
title: '首页重定向'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/about',
|
||||||
|
name: 'About',
|
||||||
|
component: About,
|
||||||
|
meta: {
|
||||||
|
title: '关于页面'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/login',
|
||||||
|
name: 'Login',
|
||||||
|
component: AdminLogin,
|
||||||
|
meta: {
|
||||||
|
title: '登录',
|
||||||
|
requiresAuth: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/admin',
|
||||||
|
name: 'Admin',
|
||||||
|
component: AdminLayout,
|
||||||
|
meta: {
|
||||||
|
requiresAuth: true
|
||||||
|
},
|
||||||
|
children: [
|
||||||
{
|
{
|
||||||
path: 'disassembly-orders/:id',
|
path: 'disassembly-orders/:id',
|
||||||
name: 'AdminDisassemblyDetail',
|
name: 'AdminDisassemblyDetail',
|
||||||
|
|
@ -232,40 +269,7 @@ export const permissionRoutes = [
|
||||||
requiresAuth: true
|
requiresAuth: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]//[]//
|
||||||
const routes = [
|
|
||||||
{
|
|
||||||
path: '/',
|
|
||||||
name: 'Home',
|
|
||||||
meta: {
|
|
||||||
title: '首页重定向'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/about',
|
|
||||||
name: 'About',
|
|
||||||
component: About,
|
|
||||||
meta: {
|
|
||||||
title: '关于页面'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/login',
|
|
||||||
name: 'Login',
|
|
||||||
component: AdminLogin,
|
|
||||||
meta: {
|
|
||||||
title: '登录',
|
|
||||||
requiresAuth: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/admin',
|
|
||||||
name: 'Admin',
|
|
||||||
component: AdminLayout,
|
|
||||||
meta: {
|
|
||||||
requiresAuth: true
|
|
||||||
},
|
|
||||||
children: permissionRoutes//[]//
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/:pathMatch(.*)*',
|
path: '/:pathMatch(.*)*',
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ export const useAuthStore = defineStore('auth', {
|
||||||
permissionButton: JSON.parse(localStorage.getItem('permissionButton') || '[]'),
|
permissionButton: JSON.parse(localStorage.getItem('permissionButton') || '[]'),
|
||||||
router: null,
|
router: null,
|
||||||
routesUpdated: 0,//路由更新次数
|
routesUpdated: 0,//路由更新次数
|
||||||
routerList: permissionRoutes//侧边栏路由
|
routerList: []//侧边栏路由
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getters: {
|
getters: {
|
||||||
|
|
@ -161,8 +161,6 @@ export const useAuthStore = defineStore('auth', {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.routerList = [];
|
this.routerList = [];
|
||||||
console.log(accessibleRoutes,'accessibleRoutes');
|
|
||||||
|
|
||||||
accessibleRoutes.forEach(route => {
|
accessibleRoutes.forEach(route => {
|
||||||
this.router.addRoute('Admin', route);
|
this.router.addRoute('Admin', route);
|
||||||
this.routerList.push(route);
|
this.routerList.push(route);
|
||||||
|
|
|
||||||
|
|
@ -310,10 +310,6 @@ const rejectRules = {
|
||||||
|
|
||||||
// 选中行数据
|
// 选中行数据
|
||||||
const selectedReview = ref(null)
|
const selectedReview = ref(null)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 计算属性
|
// 计算属性
|
||||||
const filteredReviewList = computed(() => {
|
const filteredReviewList = computed(() => {
|
||||||
let list = ordersList.value.map((item) =>{
|
let list = ordersList.value.map((item) =>{
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,7 @@
|
||||||
>
|
>
|
||||||
<div class="timeline-content">
|
<div class="timeline-content">
|
||||||
<h3>{{ $t('admin.disassemblyOrders.detail.step3') }}</h3>
|
<h3>{{ $t('admin.disassemblyOrders.detail.step3') }}</h3>
|
||||||
<div class="step-content" v-if="false">
|
<div class="step-content" >
|
||||||
<div class="model-upload-section">
|
<div class="model-upload-section">
|
||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
|
|
@ -414,9 +414,10 @@ const handlePartialEdit = (imageUrl, index) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleCanvasSave = (editedImageUrl,editContent) => {
|
const handleCanvasSave = (editedImageUrl,editContent) => {
|
||||||
|
fileServer.uploadFile(editedImageUrl).then((url) => {
|
||||||
const newItem = {
|
const newItem = {
|
||||||
id: new Date().getTime(),
|
id: new Date().getTime(),
|
||||||
thumbnailUrl: editedImageUrl,
|
thumbnailUrl: url,
|
||||||
taskID: '',
|
taskID: '',
|
||||||
taskQueue: '',
|
taskQueue: '',
|
||||||
prompt: editContent,
|
prompt: editContent,
|
||||||
|
|
@ -424,6 +425,7 @@ const handleCanvasSave = (editedImageUrl,editContent) => {
|
||||||
project_id: orderDetail.value.projectId,
|
project_id: orderDetail.value.projectId,
|
||||||
};
|
};
|
||||||
disassembledImages.value.push(newItem);
|
disassembledImages.value.push(newItem);
|
||||||
|
})
|
||||||
}
|
}
|
||||||
canvasEditorVisible.value = false;
|
canvasEditorVisible.value = false;
|
||||||
// 当前步骤
|
// 当前步骤
|
||||||
|
|
@ -708,11 +710,13 @@ const generateModelFromImage = async (image) => {
|
||||||
// console.log('generateModelFromImage',image);
|
// console.log('generateModelFromImage',image);
|
||||||
const newModel = {
|
const newModel = {
|
||||||
id: new Date().getTime(),
|
id: new Date().getTime(),
|
||||||
imgUrl: image,
|
image: image,
|
||||||
taskId: ''
|
taskId: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
// 使用展开运算符创建新数组以确保响应式更新
|
// 使用展开运算符创建新数组以确保响应式更新
|
||||||
generatedModels.value = [...generatedModels.value, newModel];
|
generatedModels.value = [...generatedModels.value, newModel];
|
||||||
|
console.log('generatedModels.value',generatedModels.value);
|
||||||
// 如果是第一次生成模型,进入第三步
|
// 如果是第一次生成模型,进入第三步
|
||||||
// if (currentStep.value < 3) {
|
// if (currentStep.value < 3) {
|
||||||
// currentStep.value = 3
|
// currentStep.value = 3
|
||||||
|
|
|
||||||
|
|
@ -827,13 +827,14 @@ const executeAction = (action) => {
|
||||||
// 处理更新支付状态
|
// 处理更新支付状态
|
||||||
const handleUpdatePayStatus = (row) => {
|
const handleUpdatePayStatus = (row) => {
|
||||||
adminOrders.updatePayStatus(row,1).then(res=>{
|
adminOrders.updatePayStatus(row,1).then(res=>{
|
||||||
|
selectedOrderForAction.value = false
|
||||||
|
actionDialogVisible.value = false
|
||||||
if(res.code === 0){
|
if(res.code === 0){
|
||||||
ElMessage.success('更新支付状态成功');
|
ElMessage.success('更新支付状态成功');
|
||||||
init();
|
init();
|
||||||
}else{
|
}else{
|
||||||
ElMessage.error(res.msg || '更新支付状态失败');
|
ElMessage.error(res.msg || '更新支付状态失败');
|
||||||
}
|
}
|
||||||
selectedOrderForAction.value = false;
|
|
||||||
})
|
})
|
||||||
// selectedOrderForStatus.value = row
|
// selectedOrderForStatus.value = row
|
||||||
// statusForm.status = 'paid' // 默认设置为已支付
|
// statusForm.status = 'paid' // 默认设置为已支付
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ export class AdminPointsManagement {
|
||||||
status:data.status
|
status:data.status
|
||||||
}
|
}
|
||||||
let requestURL = {
|
let requestURL = {
|
||||||
url:(adminApi.default.updateRechargePackageStatus.url.replace('{id}', data.id)).replace('status',data.status),
|
url:(adminApi.default.updateRechargePackageStatus.url.replace('{id}', data.id)).replace('status',`status?status=${data.status}`),
|
||||||
method:adminApi.default.updateRechargePackageStatus.method,
|
method:adminApi.default.updateRechargePackageStatus.method,
|
||||||
isLoading:adminApi.default.updateRechargePackageStatus.isLoading
|
isLoading:adminApi.default.updateRechargePackageStatus.isLoading
|
||||||
}
|
}
|
||||||
|
|
@ -31,7 +31,7 @@ export class AdminPointsManagement {
|
||||||
isRecommended:data.isRecommended
|
isRecommended:data.isRecommended
|
||||||
}
|
}
|
||||||
let requestURL = {
|
let requestURL = {
|
||||||
url:(adminApi.default.updateRecommendedStatus.url.replace('{id}', data.id)).replace('isRecommended',data.isRecommended),
|
url:(adminApi.default.updateRecommendedStatus.url.replace('{id}', data.id)).replace('recommended',`recommended?isRecommended=${data.isRecommended}`),
|
||||||
method:adminApi.default.updateRecommendedStatus.method,
|
method:adminApi.default.updateRecommendedStatus.method,
|
||||||
isLoading:adminApi.default.updateRecommendedStatus.isLoading
|
isLoading:adminApi.default.updateRecommendedStatus.isLoading
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@
|
||||||
<li>订单确认:在下单后的1个工作日内,我们会确认信息后开始处理。</li>
|
<li>订单确认:在下单后的1个工作日内,我们会确认信息后开始处理。</li>
|
||||||
<li>生产时间:生产周期为 5–15 个工作日,节假日可能顺延。</li>
|
<li>生产时间:生产周期为 5–15 个工作日,节假日可能顺延。</li>
|
||||||
<li>物流:发货后将提供订单与跟踪编号,物流信息会发送到您的邮箱。</li>
|
<li>物流:发货后将提供订单与跟踪编号,物流信息会发送到您的邮箱。</li>
|
||||||
<li>售后与退款:请参考退款政策;如有问题,请联系13121765685</li>
|
<li>售后与退款:请参考退款政策;如有问题,请联系 </li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -36,18 +36,12 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="header-right-section">
|
<div class="header-right-section">
|
||||||
<div class="free-counts-display" v-if="false">
|
<div class="free-counts-display" >
|
||||||
<div class="image-count">
|
|
||||||
<el-icon class="count-icon">
|
|
||||||
<Picture />
|
|
||||||
</el-icon>
|
|
||||||
<span class="count-text">{{ t('header.imageFreeCount') }}: {{ freeImageCount }}{{ t('header.times') }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="model-count">
|
<div class="model-count">
|
||||||
<el-icon class="count-icon">
|
<el-icon class="count-icon">
|
||||||
<MagicStick />
|
<MagicStick />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
<span class="count-text">{{ t('header.modelFreeCount') }}: {{ freeModelCount }}{{ t('header.times') }}</span>
|
<span class="count-text">{{ t('header.remainingCredits') }}: {{ total_score }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<LanguageToggle
|
<LanguageToggle
|
||||||
|
|
@ -77,11 +71,7 @@ import LanguageToggle from '../ui/LanguageToggle.vue'
|
||||||
|
|
||||||
const emit = defineEmits(['openGuideModal'])
|
const emit = defineEmits(['openGuideModal'])
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
freeImageCount: {
|
total_score: {
|
||||||
type: Number,
|
|
||||||
default: 0
|
|
||||||
},
|
|
||||||
freeModelCount: {
|
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
<!-- 缩略图显示 -->
|
<!-- 缩略图显示 -->
|
||||||
<div v-if="step.hasThumbnail" class="step-thumbnail">
|
<div v-if="step.hasThumbnail" class="step-thumbnail">
|
||||||
<img
|
<img
|
||||||
src="https://picsum.photos/seed/product-parts/300/200.jpg"
|
src="https://draft-user.s3.us-east-2.amazonaws.com/images/4abf3da6-6abe-4604-adb9-554cf49d9743.webp"
|
||||||
alt="产品零件示例图"
|
alt="产品零件示例图"
|
||||||
class="thumbnail-image"
|
class="thumbnail-image"
|
||||||
/>
|
/>
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="process-note">
|
<div class="process-note">
|
||||||
<el-icon class="note-icon"><InfoFilled /></el-icon>
|
<el-icon class="note-icon"><InfoFilled /></el-icon>
|
||||||
<p>{{ $t('orderProcess.note') || '注意:以上时间为工作日计算,节假日可能会顺延。如有问题,请联系客服:13121765685' }}</p>
|
<p>{{ $t('orderProcess.note') || '注意:以上时间为工作日计算,节假日可能会顺延。如有问题,请联系客服' }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button class="acknowledge-btn" @click="handleAcknowledge">
|
<button class="acknowledge-btn" @click="handleAcknowledge">
|
||||||
|
|
@ -52,6 +52,12 @@ import { ElIcon } from 'element-plus'
|
||||||
import {
|
import {
|
||||||
CloseBold,
|
CloseBold,
|
||||||
InfoFilled,
|
InfoFilled,
|
||||||
|
CreditCard,
|
||||||
|
Document,
|
||||||
|
Calendar,
|
||||||
|
Setting,
|
||||||
|
Picture,
|
||||||
|
Van
|
||||||
} from '@element-plus/icons-vue'
|
} from '@element-plus/icons-vue'
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
|
@ -68,38 +74,38 @@ const handleAcknowledge = () => {
|
||||||
// 订单流程步骤
|
// 订单流程步骤
|
||||||
const processSteps = computed(() => [
|
const processSteps = computed(() => [
|
||||||
{
|
{
|
||||||
icon: 'CreditCard',
|
icon: CreditCard,
|
||||||
title: t('orderProcess.steps.payment.title'),
|
title: t('orderProcess.steps.payment.title'),
|
||||||
description: t('orderProcess.steps.payment.description'),
|
description: t('orderProcess.steps.payment.description'),
|
||||||
time: t('orderProcess.steps.payment.time')
|
time: t('orderProcess.steps.payment.time')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: 'Document',
|
icon: Document,
|
||||||
title: t('orderProcess.steps.review.title'),
|
title: t('orderProcess.steps.review.title'),
|
||||||
description: t('orderProcess.steps.review.description'),
|
description: t('orderProcess.steps.review.description'),
|
||||||
time: t('orderProcess.steps.review.time')
|
time: t('orderProcess.steps.review.time')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: 'Calendar',
|
icon: Calendar,
|
||||||
title: t('orderProcess.steps.scheduling.title'),
|
title: t('orderProcess.steps.scheduling.title'),
|
||||||
description: t('orderProcess.steps.scheduling.description'),
|
description: t('orderProcess.steps.scheduling.description'),
|
||||||
time: t('orderProcess.steps.scheduling.time')
|
time: t('orderProcess.steps.scheduling.time')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: 'Setting',
|
icon: Setting,
|
||||||
title: t('orderProcess.steps.production.title'),
|
title: t('orderProcess.steps.production.title'),
|
||||||
description: t('orderProcess.steps.production.description'),
|
description: t('orderProcess.steps.production.description'),
|
||||||
time: t('orderProcess.steps.production.time')
|
time: t('orderProcess.steps.production.time')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: 'Picture',
|
icon: Picture,
|
||||||
title: t('orderProcess.steps.inspection.title'),
|
title: t('orderProcess.steps.inspection.title'),
|
||||||
description: t('orderProcess.steps.inspection.description'),
|
description: t('orderProcess.steps.inspection.description'),
|
||||||
time: t('orderProcess.steps.inspection.time'),
|
time: t('orderProcess.steps.inspection.time'),
|
||||||
hasThumbnail: true
|
hasThumbnail: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: 'Van',
|
icon: Van,
|
||||||
title: t('orderProcess.steps.shipping.title'),
|
title: t('orderProcess.steps.shipping.title'),
|
||||||
description: t('orderProcess.steps.shipping.description'),
|
description: t('orderProcess.steps.shipping.description'),
|
||||||
time: t('orderProcess.steps.shipping.time')
|
time: t('orderProcess.steps.shipping.time')
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,351 @@
|
||||||
|
<template>
|
||||||
|
<!-- 系列选择弹窗 -->
|
||||||
|
<div v-if="show" class="modal-overlay" @click="onCancel">
|
||||||
|
<div class="modal-content" @click.stop>
|
||||||
|
<!-- 模态头部 -->
|
||||||
|
<div class="modal-header">
|
||||||
|
<h2 class="modal-title">{{ t('creationWorkspace.selectSeries') }}</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 模态内容 -->
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="series-selector-content">
|
||||||
|
<!-- 系列选项列表 -->
|
||||||
|
<div class="series-list">
|
||||||
|
<!-- Done 系列 -->
|
||||||
|
<div
|
||||||
|
class="series-item"
|
||||||
|
@click="selectSeries('Done')"
|
||||||
|
>
|
||||||
|
<div class="series-image">
|
||||||
|
<img src="@/assets/xh/Done.webp" alt="Done" />
|
||||||
|
</div>
|
||||||
|
<div class="series-name">Done</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Oone 系列 -->
|
||||||
|
<div
|
||||||
|
class="series-item"
|
||||||
|
@click="selectSeries('Oone')"
|
||||||
|
>
|
||||||
|
<div class="series-image">
|
||||||
|
<img src="@/assets/xh/Oone.webp" alt="Oone" />
|
||||||
|
</div>
|
||||||
|
<div class="series-name">Oone</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { defineProps, defineEmits } from 'vue'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
show: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['confirm', 'cancel'])
|
||||||
|
|
||||||
|
const selectSeries = (series) => {
|
||||||
|
emit('confirm', series)
|
||||||
|
}
|
||||||
|
|
||||||
|
const onCancel = () => {
|
||||||
|
emit('cancel')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* 弹窗遮罩层 */
|
||||||
|
.modal-overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.6);
|
||||||
|
backdrop-filter: blur(8px);
|
||||||
|
z-index: 9999;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 20px;
|
||||||
|
animation: modalFadeIn 0.3s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes modalFadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 弹窗内容 */
|
||||||
|
.modal-content {
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 20px;
|
||||||
|
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
|
||||||
|
max-width: 600px;
|
||||||
|
width: 100%;
|
||||||
|
max-height: 90vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
position: relative;
|
||||||
|
animation: modalSlideIn 0.3s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes modalSlideIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(20px) scale(0.95);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0) scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 弹窗头部 */
|
||||||
|
.modal-header {
|
||||||
|
padding: 32px 32px 24px;
|
||||||
|
text-align: center;
|
||||||
|
border-bottom: 1px solid #e5e7eb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-title {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #1F2937;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 弹窗主体 */
|
||||||
|
.modal-body {
|
||||||
|
padding: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 系列选择弹窗样式 */
|
||||||
|
.series-selector-content {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.series-list {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||||
|
gap: 20px;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
max-width: 500px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.series-item {
|
||||||
|
background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
|
||||||
|
border: 2px solid #e2e8f0;
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease-out;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.series-item::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: linear-gradient(135deg, rgba(107, 70, 193, 0.05) 0%, rgba(167, 139, 250, 0.05) 100%);
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.2s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.series-item:hover {
|
||||||
|
transform: translateY(-6px);
|
||||||
|
box-shadow: 0 12px 32px rgba(107, 70, 193, 0.15);
|
||||||
|
border-color: #A78BFA;
|
||||||
|
}
|
||||||
|
|
||||||
|
.series-item:hover::before {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.series-item.active {
|
||||||
|
border-color: #6B46C1;
|
||||||
|
background: linear-gradient(135deg, rgba(107, 70, 193, 0.08) 0%, rgba(167, 139, 250, 0.08) 100%);
|
||||||
|
box-shadow: 0 8px 24px rgba(107, 70, 193, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.series-item.active::before {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.series-item.active::after {
|
||||||
|
content: '✓';
|
||||||
|
position: absolute;
|
||||||
|
top: 12px;
|
||||||
|
right: 12px;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
background: linear-gradient(135deg, #6B46C1 0%, #8B5CF6 100%);
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: white;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
z-index: 1;
|
||||||
|
animation: checkmarkPop 0.3s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes checkmarkPop {
|
||||||
|
0% {
|
||||||
|
transform: scale(0);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: scale(1.2);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.series-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 140px;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 12px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
position: relative;
|
||||||
|
background: linear-gradient(135deg, #f1f5f9 0%, #e2e8f0 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.series-image img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
transition: transform 0.3s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.series-item:hover .series-image img {
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.series-name {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #1F2937;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
transition: color 0.2s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.series-item:hover .series-name {
|
||||||
|
color: #6B46C1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.series-item.active .series-name {
|
||||||
|
color: #6B46C1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.series-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 16px;
|
||||||
|
justify-content: center;
|
||||||
|
padding-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-action-btn {
|
||||||
|
padding: 12px 32px;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease-out;
|
||||||
|
border: none;
|
||||||
|
min-width: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-action-btn.cancel {
|
||||||
|
background: #f3f4f6;
|
||||||
|
color: #4b5563;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-action-btn.cancel:hover {
|
||||||
|
background: #e5e7eb;
|
||||||
|
color: #1f2937;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-action-btn.primary {
|
||||||
|
background: linear-gradient(135deg, #6B46C1 0%, #8B5CF6 100%);
|
||||||
|
color: white;
|
||||||
|
box-shadow: 0 4px 12px rgba(107, 70, 193, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-action-btn.primary:hover {
|
||||||
|
background: linear-gradient(135deg, #5b3a9e 0%, #7c4ed6 100%);
|
||||||
|
box-shadow: 0 6px 16px rgba(107, 70, 193, 0.4);
|
||||||
|
transform: translateY(-2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-action-btn.primary:active {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 响应式设计 */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.series-list {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.series-item {
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.series-image {
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.series-name {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.series-actions {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-action-btn {
|
||||||
|
width: 100%;
|
||||||
|
padding: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.series-list {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
max-width: 280px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.series-image {
|
||||||
|
height: 120px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -40,10 +40,10 @@
|
||||||
<div class="role-badge" :class="userRole">{{ getRoleDisplayName(currentUser.userRole) }}</div>
|
<div class="role-badge" :class="userRole">{{ getRoleDisplayName(currentUser.userRole) }}</div>
|
||||||
<!-- <div class="role-badge" :class="userRole">{{ currentUser.nickname }}</div> -->
|
<!-- <div class="role-badge" :class="userRole">{{ currentUser.nickname }}</div> -->
|
||||||
</div>
|
</div>
|
||||||
<div class="user-points">
|
<!-- <div class="user-points">
|
||||||
<span class="points-icon">🪄</span>
|
<span class="points-icon">🪄</span>
|
||||||
<span class="points-text">{{ remainingPoints }}</span>
|
<span class="points-text">{{ remainingPoints }}</span>
|
||||||
</div>
|
</div> -->
|
||||||
<!-- 用户信息模块已取消 -->
|
<!-- 用户信息模块已取消 -->
|
||||||
</div>
|
</div>
|
||||||
<!-- 折叠状态下的用户头像 -->
|
<!-- 折叠状态下的用户头像 -->
|
||||||
|
|
@ -148,13 +148,13 @@ const coreMenuItems = computed(() => [
|
||||||
icon: 'OrdersIcon',
|
icon: 'OrdersIcon',
|
||||||
badge: null
|
badge: null
|
||||||
},
|
},
|
||||||
// {
|
{
|
||||||
// id: 'user-center',
|
id: 'user-center',
|
||||||
// path: '/user-center',
|
path: '/user-center',
|
||||||
// label: t('sidebar.userCenter'),
|
label: t('sidebar.userCenter'),
|
||||||
// icon: 'UserIcon',
|
icon: 'UserIcon',
|
||||||
// badge: null
|
badge: null
|
||||||
// },
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
// 判断当前路由是否激活
|
// 判断当前路由是否激活
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ export default {
|
||||||
orderProcess: {
|
orderProcess: {
|
||||||
title: '定制到家流程',
|
title: '定制到家流程',
|
||||||
subtitle: '了解您的订单从支付到发货的全过程',
|
subtitle: '了解您的订单从支付到发货的全过程',
|
||||||
note: '注意:以上时间为工作日计算,节假日可能会顺延。如有问题,请联系客服:13121765685',
|
note: '注意:以上时间为工作日计算,节假日可能会顺延。如有问题,请联系客服: ',
|
||||||
acknowledge: '我已知晓',
|
acknowledge: '我已知晓',
|
||||||
steps: {
|
steps: {
|
||||||
payment: {
|
payment: {
|
||||||
|
|
@ -617,7 +617,7 @@ export default {
|
||||||
orderConfirmation: '订单确认:在下单后的1个工作日内,我们会确认信息后开始处理。',
|
orderConfirmation: '订单确认:在下单后的1个工作日内,我们会确认信息后开始处理。',
|
||||||
productionTime: '生产时间:生产周期为 5–15 个工作日,节假日可能顺延。',
|
productionTime: '生产时间:生产周期为 5–15 个工作日,节假日可能顺延。',
|
||||||
logistics: '物流:发货后将提供订单与跟踪编号,物流信息会发送到您的邮箱。',
|
logistics: '物流:发货后将提供订单与跟踪编号,物流信息会发送到您的邮箱。',
|
||||||
afterSales: '售后与退款:请参考退款政策;如有问题,请联系13121765685',
|
afterSales: '售后与退款:请参考退款政策;如有问题,请联系 ',
|
||||||
error: {
|
error: {
|
||||||
firstNameRequired: '名不能为空',
|
firstNameRequired: '名不能为空',
|
||||||
lastNameRequired: '姓不能为空',
|
lastNameRequired: '姓不能为空',
|
||||||
|
|
@ -1404,7 +1404,7 @@ export default {
|
||||||
orderProcess: {
|
orderProcess: {
|
||||||
title: 'Customize to Home Process',
|
title: 'Customize to Home Process',
|
||||||
subtitle: 'Understand the complete process from payment to delivery',
|
subtitle: 'Understand the complete process from payment to delivery',
|
||||||
note: 'Note: The above times are calculated in working days. Holidays may cause delays. If you have any questions, please contact customer service: 13121765685',
|
note: 'Note: The above times are calculated in working days. Holidays may cause delays. If you have any questions, please contact customer service: ',
|
||||||
acknowledge: 'I Acknowledge',
|
acknowledge: 'I Acknowledge',
|
||||||
steps: {
|
steps: {
|
||||||
payment: {
|
payment: {
|
||||||
|
|
@ -1844,7 +1844,7 @@ export default {
|
||||||
orderConfirmation: 'Order Confirmation: We will confirm the information within 1 business day after placing the order and begin processing.',
|
orderConfirmation: 'Order Confirmation: We will confirm the information within 1 business day after placing the order and begin processing.',
|
||||||
productionTime: 'Production Time: The production cycle is 5-15 business days, which may be extended during holidays.',
|
productionTime: 'Production Time: The production cycle is 5-15 business days, which may be extended during holidays.',
|
||||||
logistics: 'Logistics: After shipping, we will provide order and tracking numbers, and logistics information will be sent to your email.',
|
logistics: 'Logistics: After shipping, we will provide order and tracking numbers, and logistics information will be sent to your email.',
|
||||||
afterSales: 'After-sales & Refund: Please refer to the refund policy; if you have any questions, please contact 13121765685'
|
afterSales: 'After-sales & Refund: Please refer to the refund policy; if you have any questions, please contact '
|
||||||
},
|
},
|
||||||
// 中国省份中文映射
|
// 中国省份中文映射
|
||||||
cnProvinces: {
|
cnProvinces: {
|
||||||
|
|
|
||||||
|
|
@ -156,7 +156,7 @@ export default {
|
||||||
orderProcess: {
|
orderProcess: {
|
||||||
title: '定制到家流程',
|
title: '定制到家流程',
|
||||||
subtitle: '了解您的订单从支付到发货的全过程',
|
subtitle: '了解您的订单从支付到发货的全过程',
|
||||||
note: '注意:以上时间为工作日计算,节假日可能会顺延。如有问题,请联系客服:13121765685',
|
note: '注意:以上时间为工作日计算,节假日可能会顺延。如有问题,请联系客服: ',
|
||||||
acknowledge: '我已知晓',
|
acknowledge: '我已知晓',
|
||||||
steps: {
|
steps: {
|
||||||
payment: {
|
payment: {
|
||||||
|
|
@ -210,6 +210,7 @@ export default {
|
||||||
imageFreeCount: '生图免费',
|
imageFreeCount: '生图免费',
|
||||||
modelFreeCount: '模型免费',
|
modelFreeCount: '模型免费',
|
||||||
times: '次',
|
times: '次',
|
||||||
|
remainingCredits: '剩余积分',
|
||||||
guide: '使用指南',
|
guide: '使用指南',
|
||||||
back: '返回',
|
back: '返回',
|
||||||
skip: '跳过',
|
skip: '跳过',
|
||||||
|
|
@ -505,7 +506,8 @@ export default {
|
||||||
shenhe:'待审核',
|
shenhe:'待审核',
|
||||||
unsuccess:'已拒绝',
|
unsuccess:'已拒绝',
|
||||||
clz:'处理中',
|
clz:'处理中',
|
||||||
dfh:'待发货'
|
dfh:'待发货',
|
||||||
|
success:'已完成'
|
||||||
},
|
},
|
||||||
sort: {
|
sort: {
|
||||||
created_at: '创建时间',
|
created_at: '创建时间',
|
||||||
|
|
@ -678,7 +680,7 @@ export default {
|
||||||
orderConfirmation: '订单确认:在下单后的1个工作日内,我们会确认信息后开始处理。',
|
orderConfirmation: '订单确认:在下单后的1个工作日内,我们会确认信息后开始处理。',
|
||||||
productionTime: '生产时间:生产周期为 5–15 个工作日,节假日可能顺延。',
|
productionTime: '生产时间:生产周期为 5–15 个工作日,节假日可能顺延。',
|
||||||
logistics: '物流:发货后将提供订单与跟踪编号,物流信息会发送到您的邮箱。',
|
logistics: '物流:发货后将提供订单与跟踪编号,物流信息会发送到您的邮箱。',
|
||||||
afterSales: '售后与退款:请参考退款政策;如有问题,请联系13121765685',
|
afterSales: '售后与退款:请参考退款政策;如有问题,请联系 ',
|
||||||
error: {
|
error: {
|
||||||
firstNameRequired: '名不能为空',
|
firstNameRequired: '名不能为空',
|
||||||
lastNameRequired: '姓不能为空',
|
lastNameRequired: '姓不能为空',
|
||||||
|
|
@ -1270,7 +1272,9 @@ export default {
|
||||||
dropToDeleteHint: '释放鼠标即可删除项目',
|
dropToDeleteHint: '释放鼠标即可删除项目',
|
||||||
confirmDelete: '确认删除',
|
confirmDelete: '确认删除',
|
||||||
deleteProject: '删除项目',
|
deleteProject: '删除项目',
|
||||||
cancel: '取消'
|
cancel: '取消',
|
||||||
|
selectSeries: '选择系列',
|
||||||
|
confirm: '确认'
|
||||||
},
|
},
|
||||||
loading: '加载中...',
|
loading: '加载中...',
|
||||||
allLoaded: '已加载全部数据',
|
allLoaded: '已加载全部数据',
|
||||||
|
|
@ -1474,7 +1478,7 @@ export default {
|
||||||
orderProcess: {
|
orderProcess: {
|
||||||
title: 'Customize to Home Process',
|
title: 'Customize to Home Process',
|
||||||
subtitle: 'Understand the complete process of your order from payment to delivery',
|
subtitle: 'Understand the complete process of your order from payment to delivery',
|
||||||
note: 'Note: The above times are calculated on working days, holidays may be delayed. If you have any questions, please contact customer service: 13121765685',
|
note: 'Note: The above times are calculated on working days, holidays may be delayed. If you have any questions, please contact customer service: ',
|
||||||
acknowledge: 'I Acknowledge',
|
acknowledge: 'I Acknowledge',
|
||||||
steps: {
|
steps: {
|
||||||
payment: {
|
payment: {
|
||||||
|
|
@ -1528,6 +1532,7 @@ export default {
|
||||||
imageFreeCount: 'Free Image Generation',
|
imageFreeCount: 'Free Image Generation',
|
||||||
modelFreeCount: 'Free Model',
|
modelFreeCount: 'Free Model',
|
||||||
times: 'times',
|
times: 'times',
|
||||||
|
remainingCredits: 'Remaining Credits',
|
||||||
guide: 'User Guide',
|
guide: 'User Guide',
|
||||||
back: 'Back',
|
back: 'Back',
|
||||||
skip: 'Skip',
|
skip: 'Skip',
|
||||||
|
|
@ -1899,7 +1904,8 @@ export default {
|
||||||
shenhe:'Pending Review',
|
shenhe:'Pending Review',
|
||||||
unsuccess:'Rejected',
|
unsuccess:'Rejected',
|
||||||
clz:'Processing',
|
clz:'Processing',
|
||||||
dfh:'To Be Shipped'
|
dfh:'To Be Shipped',
|
||||||
|
success:'Completed'
|
||||||
},
|
},
|
||||||
sort: {
|
sort: {
|
||||||
created_at: 'Created Time',
|
created_at: 'Created Time',
|
||||||
|
|
@ -2069,7 +2075,7 @@ export default {
|
||||||
orderConfirmation: 'Order Confirmation: Within 1 business day after placing the order, we will confirm the information and start processing.',
|
orderConfirmation: 'Order Confirmation: Within 1 business day after placing the order, we will confirm the information and start processing.',
|
||||||
productionTime: 'Production Time: The production cycle is 5–15 business days, which may be extended during holidays.',
|
productionTime: 'Production Time: The production cycle is 5–15 business days, which may be extended during holidays.',
|
||||||
logistics: 'Logistics: After shipment, we will provide the order and tracking number, and logistics information will be sent to your email.',
|
logistics: 'Logistics: After shipment, we will provide the order and tracking number, and logistics information will be sent to your email.',
|
||||||
afterSales: 'After-sales & Refund: Please refer to the refund policy; if you have any questions, please contact 13121765685',
|
afterSales: 'After-sales & Refund: Please refer to the refund policy; if you have any questions, please contact ',
|
||||||
error: {
|
error: {
|
||||||
firstNameRequired: 'First name cannot be empty',
|
firstNameRequired: 'First name cannot be empty',
|
||||||
lastNameRequired: 'Last name cannot be empty',
|
lastNameRequired: 'Last name cannot be empty',
|
||||||
|
|
@ -2554,7 +2560,9 @@ export default {
|
||||||
dropToDeleteHint: 'Release mouse to delete project',
|
dropToDeleteHint: 'Release mouse to delete project',
|
||||||
confirmDelete: 'Confirm Delete',
|
confirmDelete: 'Confirm Delete',
|
||||||
deleteProject: 'Delete Project',
|
deleteProject: 'Delete Project',
|
||||||
cancel: 'Cancel'
|
cancel: 'Cancel',
|
||||||
|
selectSeries: 'Select Series',
|
||||||
|
confirm: 'Confirm'
|
||||||
},
|
},
|
||||||
loading: 'Loading...',
|
loading: 'Loading...',
|
||||||
allLoaded: 'All data loaded',
|
allLoaded: 'All data loaded',
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ export const freeRoutes = [
|
||||||
meta: { requiresAuth: true, keepAlive: false }
|
meta: { requiresAuth: true, keepAlive: false }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/project/:id',
|
path: '/project/:id/:series',
|
||||||
name: 'project',
|
name: 'project',
|
||||||
component: () => import('../views/Project/CreateProject.vue'),
|
component: () => import('../views/Project/CreateProject.vue'),
|
||||||
meta: { requiresAuth: true, fullScreen: true }
|
meta: { requiresAuth: true, fullScreen: true }
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@
|
||||||
<!-- 新建项目卡片 -->
|
<!-- 新建项目卡片 -->
|
||||||
<div
|
<div
|
||||||
class="new-project-card"
|
class="new-project-card"
|
||||||
@click="createNewProject"
|
@click="showSeriesSelector = true"
|
||||||
>
|
>
|
||||||
<div class="new-project-icon">
|
<div class="new-project-icon">
|
||||||
<PlusIcon />
|
<PlusIcon />
|
||||||
|
|
@ -129,107 +129,85 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 系列选择弹窗 -->
|
||||||
|
<SeriesSelector
|
||||||
|
:show="showSeriesSelector"
|
||||||
|
@confirm="handleSeriesConfirm"
|
||||||
|
@cancel="handleSeriesCancel"
|
||||||
|
/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script setup>
|
||||||
import { ref, computed, onMounted } from 'vue'
|
import { ref, onMounted } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { Plus as PlusIcon, Folder, Edit, View, Close, Upload, Delete } from '@element-plus/icons-vue'
|
import { Plus as PlusIcon, Folder as FolderIcon, Edit as EditIcon, View as ViewIcon, Close as CloseIcon, Upload as UploadIcon, Delete as DeleteIcon } from '@element-plus/icons-vue'
|
||||||
|
import SeriesSelector from '../components/SeriesSelector.vue'
|
||||||
import {Project} from './Project/index'
|
import {Project} from './Project/index'
|
||||||
import { dateUtils } from '@deotaland/utils'
|
import { dateUtils } from '@deotaland/utils'
|
||||||
const { formatDate } = dateUtils;
|
|
||||||
const PluginProject = new Project();
|
const { formatDate } = dateUtils
|
||||||
export default {
|
const PluginProject = new Project()
|
||||||
name: 'CreationWorkspace',
|
|
||||||
components: {
|
|
||||||
PlusIcon,
|
|
||||||
FolderIcon: Folder,
|
|
||||||
EditIcon: Edit,
|
|
||||||
ViewIcon: View,
|
|
||||||
CloseIcon: Close,
|
|
||||||
UploadIcon: Upload,
|
|
||||||
DeleteIcon: Delete
|
|
||||||
},
|
|
||||||
setup() {
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
// 模态状态
|
|
||||||
const showModal = ref(false)
|
const showModal = ref(false)
|
||||||
const modalType = ref('') // 'view' or 'edit'
|
const modalType = ref('')
|
||||||
const modalTitle = ref('')
|
const modalTitle = ref('')
|
||||||
const modalSubtitle = ref('')
|
const modalSubtitle = ref('')
|
||||||
const currentProject = ref(null)
|
const currentProject = ref(null)
|
||||||
const fileInput = ref(null)
|
const fileInput = ref(null)
|
||||||
|
|
||||||
// 真实项目数据
|
const projects = ref([])
|
||||||
const projects = ref([]);
|
const page = ref(1)
|
||||||
const page = ref(1);
|
const pageSize = ref(15)
|
||||||
const pageSize = ref(15);
|
const total = ref(0)
|
||||||
const total = ref(0);
|
const loading = ref(false)
|
||||||
const loading = ref(false);
|
const finished = ref(false)
|
||||||
const finished = ref(false);
|
|
||||||
|
|
||||||
// 拖拽相关状态
|
const draggedProject = ref(null)
|
||||||
const draggedProject = ref(null);
|
const showTrash = ref(false)
|
||||||
const showTrash = ref(false);
|
const draggedOverCard = ref(null)
|
||||||
const draggedOverCard = ref(null);
|
|
||||||
|
const showDeleteConfirm = ref(false)
|
||||||
|
const projectToDelete = ref(null)
|
||||||
|
|
||||||
|
// 系列选择弹窗状态
|
||||||
|
const showSeriesSelector = ref(false)
|
||||||
|
|
||||||
// 二次确认相关状态
|
|
||||||
const showDeleteConfirm = ref(false);
|
|
||||||
const projectToDelete = ref(null);
|
|
||||||
const loadMore = () => {
|
const loadMore = () => {
|
||||||
getProjectList();
|
getProjectList()
|
||||||
}
|
}
|
||||||
// 获取项目列表
|
|
||||||
const getProjectList = async () => {
|
|
||||||
if (loading.value || finished.value) return;
|
|
||||||
|
|
||||||
loading.value = true;
|
const getProjectList = async () => {
|
||||||
|
if (loading.value || finished.value) return
|
||||||
|
|
||||||
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
const params = {
|
const params = {
|
||||||
"page": page.value,//页码
|
"page": page.value,
|
||||||
"page_size": pageSize.value,//每页数量
|
"page_size": pageSize.value,
|
||||||
}
|
}
|
||||||
const data = await PluginProject.getProjectList(params)
|
const data = await PluginProject.getProjectList(params)
|
||||||
|
|
||||||
if (page.value === 1) {
|
if (page.value === 1) {
|
||||||
projects.value = data.items;
|
projects.value = data.items
|
||||||
} else {
|
} else {
|
||||||
projects.value = [...projects.value, ...data.items];
|
projects.value = [...projects.value, ...data.items]
|
||||||
}
|
}
|
||||||
|
|
||||||
total.value = data.total;
|
total.value = data.total
|
||||||
finished.value = projects.value.length >= total.value;
|
finished.value = projects.value.length >= total.value
|
||||||
page.value++;
|
page.value++
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取项目列表异常:', error)
|
console.error('获取项目列表异常:', error)
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 更改项目缩略图
|
|
||||||
const changeProjectThumbnail = (project) => {
|
|
||||||
currentProject.value = project
|
|
||||||
triggerFileSelect()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 模态控制方法
|
|
||||||
const openProjectModal = (project, type) => {
|
|
||||||
currentProject.value = project
|
|
||||||
modalType.value = type
|
|
||||||
|
|
||||||
if (type === 'view') {
|
|
||||||
modalTitle.value = '查看项目'
|
|
||||||
modalSubtitle.value = '项目详细信息'
|
|
||||||
} else if (type === 'edit') {
|
|
||||||
modalTitle.value = '更换缩略图'
|
|
||||||
modalSubtitle.value = '为项目选择新的缩略图'
|
|
||||||
}
|
|
||||||
|
|
||||||
showModal.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
const closeModal = () => {
|
const closeModal = () => {
|
||||||
showModal.value = false
|
showModal.value = false
|
||||||
|
|
@ -239,220 +217,154 @@ export default {
|
||||||
currentProject.value = null
|
currentProject.value = null
|
||||||
}
|
}
|
||||||
|
|
||||||
// 文件选择相关方法
|
|
||||||
const triggerFileSelect = () => {
|
|
||||||
fileInput.value?.click()
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleFileSelect = (event) => {
|
const handleFileSelect = (event) => {
|
||||||
const file = event.target.files[0]
|
const file = event.target.files[0]
|
||||||
if (!file) return
|
if (!file) return
|
||||||
|
|
||||||
// 检查文件类型
|
|
||||||
if (!file.type.startsWith('image/')) {
|
if (!file.type.startsWith('image/')) {
|
||||||
console.error('请选择图片文件')
|
console.error('请选择图片文件')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查文件大小 (2MB限制)
|
|
||||||
if (file.size > 2 * 1024 * 1024) {
|
if (file.size > 2 * 1024 * 1024) {
|
||||||
console.error('图片文件大小不能超过2MB')
|
console.error('图片文件大小不能超过2MB')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// TODO: 实现文件上传逻辑
|
|
||||||
console.log('选择的文件:', file)
|
console.log('选择的文件:', file)
|
||||||
|
|
||||||
// 模拟上传
|
|
||||||
console.log('缩略图更新成功')
|
console.log('缩略图更新成功')
|
||||||
closeModal()
|
closeModal()
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('上传失败:', error)
|
console.error('上传失败:', error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清空文件输入
|
|
||||||
event.target.value = ''
|
event.target.value = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
// 打开项目
|
|
||||||
const openProject = (project) => {
|
const openProject = (project) => {
|
||||||
console.log('打开项目:', project.title)
|
console.log('打开项目:', project.title)
|
||||||
// 跳转到具体项目页面
|
router.push(`/project/${project.id}/${project.tags[0]}`)
|
||||||
router.push(`/project/${project.id}`)
|
|
||||||
|
|
||||||
// TODO: 跳转到具体项目页面
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建新项目 - 跳转到全屏创建页面
|
const createNewProject = (type) => {
|
||||||
const createNewProject = () => {
|
router.push(`/project/new/${type}`)
|
||||||
router.push('/project/new')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理系列选择确认
|
||||||
|
const handleSeriesConfirm = (series) => {
|
||||||
|
showSeriesSelector.value = false
|
||||||
|
createNewProject(series)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理系列选择取消
|
||||||
|
const handleSeriesCancel = () => {
|
||||||
|
showSeriesSelector.value = false
|
||||||
|
}
|
||||||
|
|
||||||
// 辅助函数:找到最近的父级卡片元素
|
|
||||||
const findParentCard = (element) => {
|
const findParentCard = (element) => {
|
||||||
while (element && !element.classList.contains('project-card')) {
|
while (element && !element.classList.contains('project-card')) {
|
||||||
element = element.parentElement;
|
element = element.parentElement
|
||||||
|
}
|
||||||
|
return element
|
||||||
}
|
}
|
||||||
return element;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 拖拽相关事件处理函数
|
|
||||||
const onDragStart = (event, project) => {
|
const onDragStart = (event, project) => {
|
||||||
draggedProject.value = project;
|
draggedProject.value = project
|
||||||
showTrash.value = true;
|
showTrash.value = true
|
||||||
// 添加拖拽样式
|
event.target.classList.add('dragging')
|
||||||
event.target.classList.add('dragging');
|
event.dataTransfer.effectAllowed = 'move'
|
||||||
// 设置拖拽数据
|
event.dataTransfer.setData('text/plain', project.id)
|
||||||
event.dataTransfer.effectAllowed = 'move';
|
event.dataTransfer.setDragImage(new Image(), 0, 0)
|
||||||
event.dataTransfer.setData('text/plain', project.id);
|
}
|
||||||
// 取消默认的拖拽图像
|
|
||||||
event.dataTransfer.setDragImage(new Image(), 0, 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onDragEnd = (event) => {
|
const onDragEnd = (event) => {
|
||||||
showTrash.value = false;
|
showTrash.value = false
|
||||||
draggedOverCard.value = null;
|
draggedOverCard.value = null
|
||||||
// 移除拖拽样式
|
event.target.classList.remove('dragging')
|
||||||
event.target.classList.remove('dragging');
|
|
||||||
// 移除所有卡片的拖拽高亮样式
|
|
||||||
document.querySelectorAll('.project-card').forEach(card => {
|
document.querySelectorAll('.project-card').forEach(card => {
|
||||||
card.classList.remove('drag-over');
|
card.classList.remove('drag-over')
|
||||||
});
|
})
|
||||||
};
|
}
|
||||||
|
|
||||||
const onDragOver = (event) => {
|
const onDragOver = (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault()
|
||||||
event.dataTransfer.dropEffect = 'move';
|
event.dataTransfer.dropEffect = 'move'
|
||||||
};
|
}
|
||||||
|
|
||||||
const onDragEnter = (event, targetProject) => {
|
const onDragEnter = (event, targetProject) => {
|
||||||
// 找到最近的父级卡片元素
|
const cardElement = findParentCard(event.target)
|
||||||
const cardElement = findParentCard(event.target);
|
|
||||||
if (!cardElement) {
|
if (!cardElement) {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加拖拽高亮样式
|
cardElement.classList.add('drag-over')
|
||||||
cardElement.classList.add('drag-over');
|
draggedOverCard.value = cardElement
|
||||||
draggedOverCard.value = cardElement;
|
|
||||||
|
|
||||||
// 实现实时排序
|
|
||||||
if (draggedProject.value && targetProject && draggedProject.value.id !== targetProject.id) {
|
if (draggedProject.value && targetProject && draggedProject.value.id !== targetProject.id) {
|
||||||
const draggedIndex = projects.value.findIndex(p => p.id === draggedProject.value.id);
|
const draggedIndex = projects.value.findIndex(p => p.id === draggedProject.value.id)
|
||||||
const targetIndex = projects.value.findIndex(p => p.id === targetProject.id);
|
const targetIndex = projects.value.findIndex(p => p.id === targetProject.id)
|
||||||
|
|
||||||
if (draggedIndex !== -1 && targetIndex !== -1) {
|
if (draggedIndex !== -1 && targetIndex !== -1) {
|
||||||
// 从原位置移除
|
const [draggedItem] = projects.value.splice(draggedIndex, 1)
|
||||||
const [draggedItem] = projects.value.splice(draggedIndex, 1);
|
projects.value.splice(targetIndex, 0, draggedItem)
|
||||||
// 插入到新位置
|
}
|
||||||
projects.value.splice(targetIndex, 0, draggedItem);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
const onDragLeave = (event) => {
|
const onDragLeave = (event) => {
|
||||||
// 找到最近的父级卡片元素
|
const cardElement = findParentCard(event.target)
|
||||||
const cardElement = findParentCard(event.target);
|
|
||||||
if (cardElement) {
|
if (cardElement) {
|
||||||
cardElement.classList.remove('drag-over');
|
cardElement.classList.remove('drag-over')
|
||||||
if (cardElement === draggedOverCard.value) {
|
if (cardElement === draggedOverCard.value) {
|
||||||
draggedOverCard.value = null;
|
draggedOverCard.value = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
const onDrop = (event, targetProject) => {
|
const onDrop = (event, targetProject) => {
|
||||||
event.preventDefault();
|
event.preventDefault()
|
||||||
// 找到最近的父级卡片元素
|
const cardElement = findParentCard(event.target)
|
||||||
const cardElement = findParentCard(event.target);
|
|
||||||
if (cardElement) {
|
if (cardElement) {
|
||||||
cardElement.classList.remove('drag-over');
|
cardElement.classList.remove('drag-over')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 最终排序已经在dragEnter中完成,这里只需要清理
|
draggedProject.value = null
|
||||||
draggedProject.value = null;
|
}
|
||||||
};
|
|
||||||
|
|
||||||
// 删除项目
|
|
||||||
const deleteProject = async (project) => {
|
const deleteProject = async (project) => {
|
||||||
const index = projects.value.findIndex(p => p.id === project.id);
|
const index = projects.value.findIndex(p => p.id === project.id)
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
projects.value.splice(index, 1);
|
projects.value.splice(index, 1)
|
||||||
await PluginProject.deleteProject(project.id)
|
await PluginProject.deleteProject(project.id)
|
||||||
}
|
}
|
||||||
// getProjectList();
|
}
|
||||||
};
|
|
||||||
|
|
||||||
// 拖拽到垃圾箱删除
|
|
||||||
const onDropToTrash = () => {
|
const onDropToTrash = () => {
|
||||||
if (draggedProject.value) {
|
if (draggedProject.value) {
|
||||||
projectToDelete.value = draggedProject.value;
|
projectToDelete.value = draggedProject.value
|
||||||
showDeleteConfirm.value = true;
|
showDeleteConfirm.value = true
|
||||||
|
}
|
||||||
|
showTrash.value = false
|
||||||
}
|
}
|
||||||
showTrash.value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 确认删除项目
|
|
||||||
const confirmDeleteProject = () => {
|
const confirmDeleteProject = () => {
|
||||||
if (projectToDelete.value) {
|
if (projectToDelete.value) {
|
||||||
deleteProject(projectToDelete.value);
|
deleteProject(projectToDelete.value)
|
||||||
projectToDelete.value = null;
|
projectToDelete.value = null
|
||||||
showDeleteConfirm.value = false;
|
showDeleteConfirm.value = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
// 取消删除项目
|
|
||||||
const cancelDeleteProject = () => {
|
const cancelDeleteProject = () => {
|
||||||
projectToDelete.value = null;
|
projectToDelete.value = null
|
||||||
showDeleteConfirm.value = false;
|
showDeleteConfirm.value = false
|
||||||
};
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getProjectList();
|
getProjectList()
|
||||||
})
|
})
|
||||||
return {
|
|
||||||
projects,
|
|
||||||
showModal,
|
|
||||||
modalType,
|
|
||||||
modalTitle,
|
|
||||||
modalSubtitle,
|
|
||||||
currentProject,
|
|
||||||
fileInput,
|
|
||||||
openProject,
|
|
||||||
createNewProject,
|
|
||||||
changeProjectThumbnail,
|
|
||||||
openProjectModal,
|
|
||||||
closeModal,
|
|
||||||
triggerFileSelect,
|
|
||||||
handleFileSelect,
|
|
||||||
formatDate,
|
|
||||||
t,
|
|
||||||
loading, // 导出加载状态
|
|
||||||
finished, // 导出加载完成状态
|
|
||||||
page, // 导出当前页码
|
|
||||||
|
|
||||||
// 拖拽相关导出
|
|
||||||
draggedProject,
|
|
||||||
showTrash,
|
|
||||||
onDragStart,
|
|
||||||
onDragEnd,
|
|
||||||
loadMore,
|
|
||||||
onDragOver,
|
|
||||||
onDragEnter,
|
|
||||||
onDragLeave,
|
|
||||||
onDrop,
|
|
||||||
onDropToTrash,
|
|
||||||
|
|
||||||
// 二次确认相关导出
|
|
||||||
showDeleteConfirm,
|
|
||||||
projectToDelete,
|
|
||||||
confirmDeleteProject,
|
|
||||||
cancelDeleteProject
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.creation-workspace {
|
.creation-workspace {
|
||||||
|
|
|
||||||
|
|
@ -221,7 +221,7 @@ onMounted(() => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.order-detail { padding: 24px; height: 100vh; display: flex; flex-direction: column; }
|
.order-detail { padding: 24px; height: 100%; display: flex; flex-direction: column; }
|
||||||
.detail-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; }
|
.detail-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; }
|
||||||
.header-left { display: flex; align-items: center; gap: 8px; }
|
.header-left { display: flex; align-items: center; gap: 8px; }
|
||||||
.back-btn { padding: 0 8px; }
|
.back-btn { padding: 0 8px; }
|
||||||
|
|
@ -347,7 +347,7 @@ onMounted(() => {
|
||||||
/* 右侧:物流时间线样式 */
|
/* 右侧:物流时间线样式 */
|
||||||
.logistics-timeline-container {
|
.logistics-timeline-container {
|
||||||
max-height: none;
|
max-height: none;
|
||||||
height: 38%;
|
height: 100%;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
padding-right: 8px;
|
padding-right: 8px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
<div class="creative-zone" @contextmenu.prevent>
|
<div class="creative-zone" @contextmenu.prevent>
|
||||||
<!-- 顶部固定头部组件 -->
|
<!-- 顶部固定头部组件 -->
|
||||||
<div class="header-wrapper">
|
<div class="header-wrapper">
|
||||||
<HeaderComponent :freeImageCount="Limits.generateCount" :freeModelCount="Limits.modelCount" :projectName="projectInfo.title" @updateProjectInfo="projectInfo = {...projectInfo, ...$event}" @openGuideModal="showGuideModal = true" />
|
<HeaderComponent :total_score="total_score" :projectName="projectInfo.title" @updateProjectInfo="projectInfo = {...projectInfo, ...$event}" @openGuideModal="showGuideModal = true" />
|
||||||
</div>
|
</div>
|
||||||
<!-- 导入的侧边栏组件 -->
|
<!-- 导入的侧边栏组件 -->
|
||||||
<div class="sidebar-container">
|
<div class="sidebar-container">
|
||||||
|
|
@ -180,11 +180,14 @@ const currentImageIndex = ref(0);
|
||||||
// 事件监听器清理函数存储
|
// 事件监听器清理函数存储
|
||||||
const cleanupFunctions = ref({});
|
const cleanupFunctions = ref({});
|
||||||
const projectId = ref(null);
|
const projectId = ref(null);
|
||||||
|
const series = ref(null);//项目系列
|
||||||
//项目数据
|
//项目数据
|
||||||
const projectInfo = ref({});
|
const projectInfo = ref({});
|
||||||
|
const total_score = ref(0);
|
||||||
//获取生图次数和模型次数
|
//获取生图次数和模型次数
|
||||||
const getGenerateCount = async ()=>{
|
const getGenerateCount = async ()=>{
|
||||||
const {data} = await modernHome.getModelLimits();
|
const {data} = await modernHome.getModelLimits();
|
||||||
|
total_score.value = data.total_score
|
||||||
// Limits.value.generateCount = data[0].model_count;
|
// Limits.value.generateCount = data[0].model_count;
|
||||||
// Limits.value.modelCount = data[1].model_count;
|
// Limits.value.modelCount = data[1].model_count;
|
||||||
}
|
}
|
||||||
|
|
@ -207,10 +210,11 @@ const getMaxZIndex = (type)=>{
|
||||||
}
|
}
|
||||||
const combinedPromptJson = ref({});
|
const combinedPromptJson = ref({});
|
||||||
//获取动态提示词
|
//获取动态提示词
|
||||||
const getCombinedPrompt = async (type=1)=>{
|
const getCombinedPrompt = async ()=>{
|
||||||
try {
|
try {
|
||||||
const data = await PluginProject.getCombinedPrompt(type);
|
const data = await PluginProject.getCombinedPrompt(series.value);
|
||||||
combinedPromptJson.value = data;
|
combinedPromptJson.value = data;
|
||||||
|
console.log(combinedPromptJson.value);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
|
|
@ -255,8 +259,8 @@ const handleSaveProject = (index,item,type='image')=>{
|
||||||
}
|
}
|
||||||
const createProject = async ()=>{
|
const createProject = async ()=>{
|
||||||
const {id} = await PluginProject.createProject();
|
const {id} = await PluginProject.createProject();
|
||||||
// 创建新项目后,将当前路由跳转到 project/项目id
|
// 创建新项目后,将当前路由跳转到 project/项目id/系列
|
||||||
await router.replace(`/project/${id}`);
|
await router.replace(`/project/${id}/${series.value}`);
|
||||||
projectId.value = id;
|
projectId.value = id;
|
||||||
getProjectInfo(id);
|
getProjectInfo(id);
|
||||||
// projectId.value = 8;
|
// projectId.value = 8;
|
||||||
|
|
@ -273,6 +277,7 @@ const getProjectInfo = async (id)=>{
|
||||||
...card,
|
...card,
|
||||||
id: card.id || Date.now() + Math.random().toString(36).substr(2, 9)
|
id: card.id || Date.now() + Math.random().toString(36).substr(2, 9)
|
||||||
}));
|
}));
|
||||||
|
projectInfo.value.tags = [series.value];
|
||||||
}
|
}
|
||||||
//更新项目信息
|
//更新项目信息
|
||||||
const updateProjectInfo = async (newProjectInfo)=>{
|
const updateProjectInfo = async (newProjectInfo)=>{
|
||||||
|
|
@ -1000,6 +1005,7 @@ import { addPassiveEventListener } from '@/utils/passiveEventListeners'
|
||||||
const init = ()=>{
|
const init = ()=>{
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
projectId.value = route.params.id;
|
projectId.value = route.params.id;
|
||||||
|
series.value = route.params.series;
|
||||||
if(projectId.value === 'new'){
|
if(projectId.value === 'new'){
|
||||||
createProject();
|
createProject();
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -729,13 +729,19 @@ export class Project{
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
//获取动态提示词
|
//获取动态提示词
|
||||||
async getCombinedPrompt(){//type:1人物类型2动物类型
|
async getCombinedPrompt(series){//series:项目系列Done Oone
|
||||||
try {
|
try {
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
const res = await requestUtils.common(clientApi.default.combined)
|
const res = await requestUtils.common(clientApi.default.combined)
|
||||||
if(res.code === 0){
|
if(res.code === 0){
|
||||||
let data = res.data;
|
let data = res.data;
|
||||||
|
// 如果是Oone系列,过滤掉title中包含"动物坐姿"或"人物姿势"的提示词
|
||||||
|
if (series === 'Oone') {
|
||||||
|
data = data.filter(item => {
|
||||||
|
if (!item.title) return true;
|
||||||
|
return !item.title.includes('动物坐姿') && !item.title.includes('人物姿势');
|
||||||
|
});
|
||||||
|
}
|
||||||
// 初始化返回数据结构
|
// 初始化返回数据结构
|
||||||
const result = {
|
const result = {
|
||||||
person: {
|
person: {
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -12,30 +12,30 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 隐藏的文件上传输入 -->
|
<!-- 隐藏的文件上传输入 -->
|
||||||
<input
|
<!-- <input
|
||||||
ref="avatarInput"
|
ref="avatarInput"
|
||||||
type="file"
|
type="file"
|
||||||
accept="image/*"
|
accept="image/*"
|
||||||
class="avatar-input"
|
class="avatar-input"
|
||||||
@change="handleAvatarUpload"
|
@change="handleAvatarUpload"
|
||||||
hidden
|
hidden
|
||||||
/>
|
/> -->
|
||||||
</div>
|
</div>
|
||||||
|
<!-- @click="toggleEditName" -->
|
||||||
<div class="user-details-section">
|
<div class="user-details-section">
|
||||||
<div class="user-name-row">
|
<div class="user-name-row">
|
||||||
<div class="editable-name-container">
|
<div class="editable-name-container">
|
||||||
<h1
|
<h1
|
||||||
class="user-name"
|
class="user-name"
|
||||||
@click="toggleEditName"
|
|
||||||
:class="{ 'editable': true }"
|
:class="{ 'editable': true }"
|
||||||
>{{ userData.nickname }}</h1>
|
>{{ userData.nickname }}</h1>
|
||||||
<div v-if="isEditingName" class="name-edit-form">
|
<div v-if="isEditingName" class="name-edit-form">
|
||||||
|
<!-- @blur="saveNickname"
|
||||||
|
@keyup.enter="saveNickname" -->
|
||||||
<el-input
|
<el-input
|
||||||
v-model="editNameValue"
|
v-model="editNameValue"
|
||||||
size="large"
|
size="large"
|
||||||
@blur="saveNickname"
|
|
||||||
@keyup.enter="saveNickname"
|
|
||||||
ref="nameInput"
|
ref="nameInput"
|
||||||
placeholder="Please enter a nickname"
|
placeholder="Please enter a nickname"
|
||||||
/>
|
/>
|
||||||
|
|
@ -48,7 +48,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 积分信息区域 - 免费会员可见 -->
|
<!-- 积分信息区域 - 免费会员可见 -->
|
||||||
<div class="points-section">
|
<div class="points-section" v-if="false">
|
||||||
<h2>{{ $t('userCenter.points.title') }}</h2>
|
<h2>{{ $t('userCenter.points.title') }}</h2>
|
||||||
<!-- 积分明细和规则并排容器 -->
|
<!-- 积分明细和规则并排容器 -->
|
||||||
|
|
||||||
|
|
@ -115,8 +115,8 @@
|
||||||
</div>
|
</div>
|
||||||
<!-- 邀请信息区域 - 免费会员可见 -->
|
<!-- 邀请信息区域 - 免费会员可见 -->
|
||||||
<div class="invitation-section">
|
<div class="invitation-section">
|
||||||
<h2>{{ $t('userCenter.invitation.title') }}</h2>
|
<h2 v-if="false">{{ $t('userCenter.invitation.title') }}</h2>
|
||||||
<div class="invitation-info">
|
<div v-if="false" class="invitation-info">
|
||||||
<div class="info-item">
|
<div class="info-item">
|
||||||
<label>{{ $t('userCenter.invitation.inviteCount') }}</label>
|
<label>{{ $t('userCenter.invitation.inviteCount') }}</label>
|
||||||
<span>{{ userData.inviteCount }}</span>
|
<span>{{ userData.inviteCount }}</span>
|
||||||
|
|
@ -128,7 +128,7 @@
|
||||||
<h3>{{ $t('userCenter.invitation.inviteCodes') }}</h3>
|
<h3>{{ $t('userCenter.invitation.inviteCodes') }}</h3>
|
||||||
<div class="invite-cards-container">
|
<div class="invite-cards-container">
|
||||||
<div
|
<div
|
||||||
v-for="(inviteCode, index) in userData.inviteCodes"
|
v-for="(inviteCode, index) in (userData.inviteCodes.filter(item => item.codeType!='permanent'))"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="invite-card"
|
class="invite-card"
|
||||||
:class="{ 'used': inviteCode.used }"
|
:class="{ 'used': inviteCode.used }"
|
||||||
|
|
@ -154,7 +154,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 合并后的邀请相关列表 -->
|
<!-- 合并后的邀请相关列表 -->
|
||||||
<div class="invite-related-section">
|
<div v-if="false" class="invite-related-section">
|
||||||
<h3>{{ userData.role === 'creator' ? $t('userCenter.creator.invitedUsersList') : $t('userCenter.invitation.invitePointsDetails') }}</h3>
|
<h3>{{ userData.role === 'creator' ? $t('userCenter.creator.invitedUsersList') : $t('userCenter.invitation.invitePointsDetails') }}</h3>
|
||||||
<div class="table-container">
|
<div class="table-container">
|
||||||
<table class="details-table">
|
<table class="details-table">
|
||||||
|
|
@ -227,20 +227,20 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 成为达人会员模块 - 仅免费会员可见,放在达人会员规则右侧 -->
|
<!-- 成为达人会员模块 - 仅免费会员可见,放在达人会员规则右侧 -->
|
||||||
<div v-if="userData.role === 'free'" class="upgrade-creator-section">
|
<!-- <div v-if="userData.role === 'free'" class="upgrade-creator-section">
|
||||||
<h4>{{ $t('userCenter.invitation.rules.becomeCreator.title') }}</h4>
|
<h4>{{ $t('userCenter.invitation.rules.becomeCreator.title') }}</h4>
|
||||||
<div class="qr-code-container">
|
<div class="qr-code-container">
|
||||||
<!-- QR码占位 -->
|
|
||||||
<div class="qr-placeholder">{{ $t('userCenter.invitation.rules.becomeCreator.qrCode') }}</div>
|
<div class="qr-placeholder">{{ $t('userCenter.invitation.rules.becomeCreator.qrCode') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 佣金统计(独立模块) -->
|
<!-- 佣金统计(独立模块) -->
|
||||||
<div v-if="userData.role === 'creator'" class="commission-section">
|
<!-- v-if="userData.role === 'creator'" -->
|
||||||
|
<div v-if="false" class="commission-section">
|
||||||
<h2>{{ $t('userCenter.creator.commissionTitle') }}</h2>
|
<h2>{{ $t('userCenter.creator.commissionTitle') }}</h2>
|
||||||
<div class="commission-info">
|
<div class="commission-info">
|
||||||
<div class="info-item">
|
<div class="info-item">
|
||||||
|
|
@ -313,7 +313,8 @@ const fetchInviteCodes = async () => {
|
||||||
const inviteCodes = response.data.map(item => ({
|
const inviteCodes = response.data.map(item => ({
|
||||||
code: item.inviteCode,
|
code: item.inviteCode,
|
||||||
used: item.isUsed === 1, // isUsed为1表示已使用
|
used: item.isUsed === 1, // isUsed为1表示已使用
|
||||||
createdAt: item.createdAt
|
createdAt: item.createdAt,
|
||||||
|
codeType: item.codeType
|
||||||
}))
|
}))
|
||||||
userData.value.inviteCodes = inviteCodes
|
userData.value.inviteCodes = inviteCodes
|
||||||
userData.value.inviteCount = inviteCodes.length
|
userData.value.inviteCount = inviteCodes.length
|
||||||
|
|
@ -403,7 +404,8 @@ const saveNickname = () => {
|
||||||
|
|
||||||
// 复制邀请码
|
// 复制邀请码
|
||||||
const copyInviteCode = (code) => {
|
const copyInviteCode = (code) => {
|
||||||
navigator.clipboard.writeText(code)
|
const InviteLink = `🎉 限时福利!送你专属邀请码:${code},注册立得积分+解锁高级功能,快来一起体验吧!${window.location.origin}/#/login?inviteCode=${code}`
|
||||||
|
navigator.clipboard.writeText(InviteLink)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
ElMessage.success(t('userCenter.invitation.copySuccess'))
|
ElMessage.success(t('userCenter.invitation.copySuccess'))
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -574,5 +574,5 @@ export interface ModalProps {
|
||||||
|
|
||||||
**设计版本**: 1.0
|
**设计版本**: 1.0
|
||||||
**创建时间**: 2025-11-18
|
**创建时间**: 2025-11-18
|
||||||
**技术负责人**: 13121765685
|
**技术负责人**:
|
||||||
**审核状态**: 待审核
|
**审核状态**: 待审核
|
||||||
|
|
@ -224,5 +224,5 @@ Monorepo架构将为DeotalandAi项目带来显著的开发效率提升和维护
|
||||||
---
|
---
|
||||||
**变更ID**: monorepo-architecture-design
|
**变更ID**: monorepo-architecture-design
|
||||||
**创建时间**: 2025-11-18
|
**创建时间**: 2025-11-18
|
||||||
**作者**: 13121765685
|
**作者**:
|
||||||
**状态**: 待确认
|
**状态**: 待确认
|
||||||
|
|
@ -78,4 +78,4 @@ DeotalandAi 是一个 AI 驱动的前端项目,采用现代化的 Vue3 技术
|
||||||
- **CDN 资源**: 图标库和字体文件 (fallback 到本地)
|
- **CDN 资源**: 图标库和字体文件 (fallback 到本地)
|
||||||
|
|
||||||
## Archived Changes
|
## Archived Changes
|
||||||
- 2025-11-12-13121765685-add-frontend-vue3-elementplus-i18n-template: 前端 Vue3 模板框架(Element Plus + I18n)- 已完成,包含完整的Vue3项目初始化、Element Plus集成、国际化支持、响应式设计和性能优化
|
- 2025-11-12- -add-frontend-vue3-elementplus-i18n-template: 前端 Vue3 模板框架(Element Plus + I18n)- 已完成,包含完整的Vue3项目初始化、Element Plus集成、国际化支持、响应式设计和性能优化
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
const order = {
|
const order = {
|
||||||
getOrderDetailt:{url:'/api-core/admin/order/get',method:'GET'},//获取订单详情
|
getOrderDetailt:{url:'/api-core/admin/order/get',method:'GET',isLoading:true},//获取订单详情
|
||||||
getOrderList:{url:'/api-core/admin/order/list',method:'POST'},//获取订单列表
|
getOrderList:{url:'/api-core/admin/order/list',method:'POST',isLoading:true},//获取订单列表
|
||||||
refundApprove:{url:'/api-core/admin/order/refund/approve',method:'GET'},//同意退款
|
refundApprove:{url:'/api-core/admin/order/refund/approve',method:'GET',isLoading:true},//同意退款
|
||||||
refundReject:{url:'/api-core/admin/order/refund/reject',method:'GET'},//拒绝退款
|
refundReject:{url:'/api-core/admin/order/refund/reject',method:'GET',isLoading:true},//拒绝退款
|
||||||
updateOrderStatus:{url:'/api-core/admin/order/update',method:'POST'},//修改订单状态
|
updateOrderStatus:{url:'/api-core/admin/order/update',method:'POST',isLoading:true},//修改订单状态
|
||||||
getOrderStatistics:{url:'/api-core/admin/order/statistics',method:'GET'},//订单状态统计
|
getOrderStatistics:{url:'/api-core/admin/order/statistics',method:'GET',isLoading:true},//订单状态统计
|
||||||
}
|
}
|
||||||
export default order;
|
export default order;
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
const login = {
|
const login = {
|
||||||
MODEL_LIMITS:{url:'/api-core/front/user/model-limits',method:'GET'},// 模型限制
|
MODEL_LIMITS:{url:'/api-core/front/user/model-limits',method:'GET'},// 模型限制
|
||||||
USER_STATISTICS:{url:'/api-core/front/user/statistics',method:'GET'},// 用户统计
|
USER_STATISTICS:{url:'/api-core/front/user/statistics',method:'GET',isLoading:true},// 用户统计
|
||||||
INVITE_CODES:{url:'/api-base/user/invite/codes',method:'GET'},// 返回当前用户的邀请码列表及使用状态
|
INVITE_CODES:{url:'/api-base/user/invite/codes',method:'GET',isLoading:true},// 返回当前用户的邀请码列表及使用状态
|
||||||
INVITE_RECORDS:{url:'/api-base/user/invite/records',method:'GET'},// 返回邀请的用户列表,包含奖励明细
|
INVITE_RECORDS:{url:'/api-base/user/invite/records',method:'GET',isLoading:true},// 返回邀请的用户列表,包含奖励明细
|
||||||
combined:{url:'/api-base/prompt/active',method:'GET'},// 返回动态提示词
|
combined:{url:'/api-base/prompt/active',method:'GET',isLoading:true},// 返回动态提示词
|
||||||
UPGRADE:{url:'/api-base/user/upgrade',method:'POST'},// 候补会员使用邀请码升级为正式会员
|
UPGRADE:{url:'/api-base/user/upgrade',method:'POST',isLoading:true},// 候补会员使用邀请码升级为正式会员
|
||||||
USER_INFO:{url:'/api-base/user/info',method:'GET',isLoading:true},// 返回用户信息
|
USER_INFO:{url:'/api-base/user/info',method:'GET',isLoading:true},// 返回用户信息
|
||||||
}
|
}
|
||||||
export default login;
|
export default login;
|
||||||
|
|
|
||||||
|
|
@ -351,8 +351,8 @@ export class FileServer {
|
||||||
prefix:isModelFile ? 'uploads' : 'images',
|
prefix:isModelFile ? 'uploads' : 'images',
|
||||||
...config
|
...config
|
||||||
}
|
}
|
||||||
// const requestUrl = this.RULE=='admin'?adminApi.default.adminUPLOADS3:clientApi.default.UPLOADS3;
|
const requestUrl = this.RULE=='admin'?adminApi.default.adminUPLOADS3:clientApi.default.UPLOADS3;
|
||||||
const requestUrl = clientApi.default.UPLOADS3;
|
// const requestUrl = clientApi.default.UPLOADS3;
|
||||||
const response = await requestUtils.common(requestUrl, params);
|
const response = await requestUtils.common(requestUrl, params);
|
||||||
if(response.code==0){
|
if(response.code==0){
|
||||||
let data = response.data;
|
let data = response.data;
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ export class MeshyServer extends FileServer {
|
||||||
"payload": {
|
"payload": {
|
||||||
image_url:'',
|
image_url:'',
|
||||||
ai_model: 'latest',
|
ai_model: 'latest',
|
||||||
enable_pbr: true,
|
enable_pbr: false,
|
||||||
should_remesh: false,
|
should_remesh: false,
|
||||||
should_texture: false,
|
should_texture: false,
|
||||||
save_pre_remeshed_model: true,
|
save_pre_remeshed_model: true,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue