-
-
-
-
支付
-
- ¥
- 39
-
-
已减¥11
+
+
+ 支付
-
-

请扫码完成支付
-
-
-
- 开通即代表同意
-
-
- 《魔创未来会员协议》
-
+
+ ¥
+ {{ paymentParams.amount }}
+
+
+

请扫码完成支付
+
+
+
+ 开通即代表同意
+
+
+ 《魔创未来会员协议》
+
+
+
+
+
+ 需支付差价,计算规则为:专业版年包价格-剩余未下发基础版年包月数*基础版年包购买价格/12
-
需支付差价,计算规则为:专业版年包价格-剩余未下发基础版年包月数*基础版年包购买价格/12
diff --git a/app/components/PersonalCenterCard.vue b/app/components/PersonalCenterCard.vue
index 385784b..35f026c 100644
--- a/app/components/PersonalCenterCard.vue
+++ b/app/components/PersonalCenterCard.vue
@@ -39,6 +39,22 @@ function toDetails() {
}
}
+// 获取图片详情进行编辑
+const publishPictureData = ref
({})
+async function getPublishPicture() {
+ try {
+ const res = await request.get(`/image/detail?id=${props.item.id}`)
+ if (res.code === 200) {
+ publishPictureData.value = res.data
+ publishPictureData.value.imagePaths = res.data.imagePaths.split(',')
+ // publishPictureData.value.tags = res.data.tags.split(',')
+ }
+ }
+ catch (e) {
+ console.log(e)
+ }
+}
+
// 处理下拉菜单选项 编辑/删除/置顶
function handleSelect(event: Event, key: string) {
event.stopPropagation() // 阻止事件冒泡
@@ -48,6 +64,21 @@ function handleSelect(event: Event, key: string) {
else if (key === 'delete') {
handleDelete()
}
+ else if (key === 'edit') {
+ if (props.currentType === '2') {
+ getPublishPicture()
+ showPublishImg()
+ }
+ else if (props.currentType === '1') {
+ router.push({
+ path: `/publish-workflow`,
+ query: {
+ type: 'edit',
+ id: props.item.id,
+ },
+ })
+ }
+ }
}
// 置顶
@@ -112,6 +143,23 @@ function getFirstImagePath(imagePaths: string): string {
return ''
return imagePaths.split(',')[0] || ''
}
+// 关闭图片
+const isShowPublishPicture = ref(false)
+const PublishPictureRef = ref(null)
+
+function showPublishImg() {
+ isShowPublishPicture.value = true
+ if (PublishPictureRef.value) {
+ PublishPictureRef.value.isVisible = true
+ }
+}
+
+function closePublishImg() {
+ isShowPublishPicture.value = false
+ if (PublishPictureRef.value) {
+ PublishPictureRef.value.isVisible = false
+ }
+}
@@ -155,7 +203,7 @@ function getFirstImagePath(imagePaths: string): string {
>
-
+
- 未通过
+ {{ item.auditStatus === 3 ? '审核中' : '未通过' }}
+
+
+
+
+
diff --git a/app/components/Publish-picture.vue b/app/components/Publish-picture.vue
new file mode 100644
index 0000000..6921eeb
--- /dev/null
+++ b/app/components/Publish-picture.vue
@@ -0,0 +1,183 @@
+
+
+
+
+
+
+
+
+
+
+
+ 上传文件
+
+
+ 点击上传文件
+
+
+
+
+
+
+
![]()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 发布
+
+
+
+
+
+
+
+
diff --git a/app/components/TimeLine.vue b/app/components/TimeLine.vue
new file mode 100644
index 0000000..d02df7b
--- /dev/null
+++ b/app/components/TimeLine.vue
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+ {{ item.index }}
+
+
+ {{ item.name }}
+
+
+
+
+
+
diff --git a/app/components/WangEditor.vue b/app/components/WangEditor.vue
index 3d737cd..a480a53 100644
--- a/app/components/WangEditor.vue
+++ b/app/components/WangEditor.vue
@@ -1,49 +1,117 @@
+
+
diff --git a/app/components/WechatLoginQr.vue b/app/components/WechatLoginQr.vue
index 26d6827..ca19798 100644
--- a/app/components/WechatLoginQr.vue
+++ b/app/components/WechatLoginQr.vue
@@ -56,18 +56,6 @@ async function onGetUUid() {
})
userStore.setUserInfo(res1.user)
window.location.href = '/'
- // const parent = getCurrentInstance().parent
- // parent.exposed.onCloseLogin()
- // store.userInfo = res.data
- // router.push('./home')
-
- // store.dispatch("uuidLogin", res)
- // that.$store.dispatch("uuidLogin", res)
- // setTimeout(() => {
- // that.$router.push({
- // path: that.redirect || "/"
- // }).catch(() => {});
- // }, 1500)
}
}).catch(() => {
clearTimeout(pollingTimer)
diff --git a/app/components/publishModel/EditVersion.vue b/app/components/publishModel/EditVersion.vue
index 6d44460..faf1ffc 100644
--- a/app/components/publishModel/EditVersion.vue
+++ b/app/components/publishModel/EditVersion.vue
@@ -14,24 +14,25 @@ const props = defineProps({
})
const emit = defineEmits(['update:modelValue', 'createModelsNext'])
const acceptTypes = '.safetensors,.ckpt,.pt,.bin,.pth,.zip,.json,.flow,.lightflow,.yaml,.yml,.onnx,.gguf,.sft'
-const isDataReady = ref(false)
const modelVersionItem = {
- versionName: '1.0', // 版本名称
- modelId: 1, // 基础模型
+ versionName: '', // 版本名称
+ modelId: null, // 基础模型
versionDescription: '"
这是一个描述

这是两张图片之间的一些文字说明

"', // 版本描述
- filePath: 'https://ybl2112.oss-cn-beijing.aliyuncs.com/2025/JANUARY/2/19/4/877e449c-3c0d-4630-a304-91ec110499f2.png', // 文件路径
- fileName: 'ddefd反问句说的', // 文档里没有 ,表里没有
+ filePath: '', // 文件路径
+ fileName: '', // 文档里没有 ,表里没有
sampleImagePaths: 'https://ybl2112.oss-cn-beijing.aliyuncs.com/2025/JANUARY/2/19/4/877e449c-3c0d-4630-a304-91ec110499f2.png,https://ybl2112.oss-cn-beijing.aliyuncs.com/2025/JANUARY/2/19/4/877e449c-3c0d-4630-a304-91ec110499f2.png,https://ybl2112.oss-cn-beijing.aliyuncs.com/2025/JANUARY/2/19/4/877e449c-3c0d-4630-a304-91ec110499f2.png', // 第三部的图片路径最多20张,切割
- triggerWords: '触发词', // 触发词
+ triggerWords: '', // 触发词
isPublic: 1, // 权限是否公开权限 1公开 2自见
- allowFusion: 1, // 待确定
- allowDownloadImage: 1, // 允许下载生图
- allowUsage: 1, // 是否允许使用
isFree: 0, // 是否免费 0免费 1会员 ????
+ isOnlineUse: 1, // 是否允许在线使用
+ allowDownloadImage: 1, // 允许下载生图
allowSoftwareUse: 1, // 允许在软件旗下使用
+ allowFusion: 1, // 是否允许融合
allowCommercialUse: 1, // 是否允许商用
+
+ // allowUsage: 1, // 是否允许使用
// 允许模型转售或者融合手出售字段没找到?
- isExclusiveModel: 1, // 是否为独家模型这个字段
+ isExclusiveModel: 0, // 是否为独家模型这个字段
}
const isPublicList = [
{
@@ -46,12 +47,7 @@ const isPublicList = [
defineExpose({
addVersion,
})
-onMounted(() => {
- // 确保数据初始化完成
- nextTick(() => {
- isDataReady.value = true
- })
-})
+
const localForm = computed({
get() {
return props.modelValue
@@ -74,17 +70,22 @@ const formRef = ref
(null)
const rules = {
versionName: {
required: true,
- message: '请输入模型名称',
+ message: '',
trigger: 'blur',
},
modelId: {
+ required: true,
+ message: '',
+ trigger: 'blur',
+ },
+ triggerWords: {
required: true,
message: '请输入模型名称',
trigger: 'blur',
},
}
function addVersion() {
- localForm.value.modelVersionList.push(modelVersionItem)
+ localForm.value.modelVersionList.unshift(modelVersionItem)
}
const originalBtnList = ref([
{
@@ -132,165 +133,198 @@ async function handleFileChange(event: Event) {
-
-
-
-
-
-
-
-
-
-
-
- 100%
+
+
+
+
+
+
+
+
+
+
-
- {{
- item.fileName
- }}
+
+
+ 100%
+
+
+ {{
+ item.fileName
+ }}
+
+
+
+
-
-
-
-
-
-
-
-
- 上传文件
-
-
- 点击上传文件
-
-
- .safetensors/.ckpt/.pt/.bin/.pth/.zip/.json/.flow/.lightflow/.yaml/.yml/.onnx/.gguf/.sft
+
+
+
+
+ 上传文件
+
+
+ 点击上传文件
+
+
+ .safetensors/.ckpt/.pt/.bin/.pth/.zip/.json/.flow/.lightflow/.yaml/.yml/.onnx/.gguf/.sft
+
-
-
-
-
-
-
-
-
-
-
-
-
-
- 触发词
-
-
- 请输入您用来训练的单词
-
-
-
-
-
- 权限设置
-
-
- 可见范围
-
-
-
-
-
- {{ isPublicItem.label }}
-
-
-
-
-
-
-
- 付费设置
-
-
-
- {{ subItem.label }}
+
+
+
+
+
+
+
+
+ 触发词
+
+
+ 请输入您用来训练的单词
+
+
+
+
+
+ 权限设置
+
+
+ 可见范围
+
+
+
+
+
+ {{ isPublicItem.label }}
+
+
+
+
+
+
+
+ 付费设置
+
+
+
+ {{ subItem.label }}
+
+
+
+ 选择会员专属或会员下载视为您已经阅读 《会员模型许可协议》 并同意其中条款
+
+
+
会员下载模型
+
+ 下载模型需购买会员,在线生图对所有人开放,无生图次数限制;会员下载的模型版本生成图片默认可商用。
+
-
- 选择会员专属或会员下载视为您已经阅读
《会员模型许可协议》 并同意其中条款
+
+ 许可范围
-
-
会员下载模型
-
- 下载模型需购买会员,在线生图对所有人开放,无生图次数限制;会员下载的模型版本生成图片默认可商用。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 商用许可范围
+
+
+
+
+
+ 独家设置
+
+
+
+
+ 此版本为魔创未来独家模型 *获取更多流量:独家模型规则
+
-
- 许可范围
-
-
-
+import type { FormInst } from 'naive-ui'
+import { uploadFileBatches } from '@/utils/uploadImg.ts'
+import { Asterisk, Trash } from 'lucide-vue-next'
+import { computed, ref, watch } from 'vue'
+
+// 可接受的文件类型
+const props = defineProps({
+ modelValue: {
+ type: Object,
+ required: true,
+ },
+})
+const emit = defineEmits(['update:modelValue', 'nextStep', 'preStep'])
+
+const localForm = computed({
+ get() {
+ return props.modelValue
+ },
+ set(value) {
+ emit('update:modelValue', value)
+ },
+})
+
+watch(
+ () => localForm.value,
+ (newVal) => {
+ console.log('newVal', newVal)
+ emit('update:modelValue', newVal)
+ },
+ { immediate: true, deep: true },
+)
+const message = useMessage()
+
+const acceptTypes = '.json,.zip'
+
+defineExpose({
+ addVersion,
+})
+
+const modelVersionItem = {
+ versionName: '',
+ versionDescription: '', // 富文本
+ filePath: '', // 文件路径
+ fileName: '', // 文件名
+ delFlag: '0',
+ imagePaths: [],
+}
+const rules = {
+ versionName: {
+ required: true,
+ message: '',
+ trigger: 'blur',
+ },
+}
+function addVersion() {
+ localForm.value.workFlowVersionList.unshift(modelVersionItem)
+}
+
+const formRefs = ref<(FormInst | null)[]>([])
+function setFormRef(el: FormInst | null, index: number) {
+ if (el) {
+ formRefs.value[index] = el
+ }
+}
+async function nextStep() {
+ for (let i = 0; i < localForm.value.workFlowVersionList.length; i++) {
+ if (localForm.value.workFlowVersionList[i].delFlag === '0' && localForm.value.workFlowVersionList[i].fileName === '') {
+ return message.error('请上传文件')
+ }
+ const regex = /[\u4E00-\u9FA5]/ // 匹配汉字的正则表达式
+ if (localForm.value.workFlowVersionList[i].delFlag === '0' && !regex.test(localForm.value.workFlowVersionList[i].versionDescription)) {
+ return message.error('请用中文填写版本介绍')
+ }
+ }
+ try {
+ const promises = formRefs.value
+ .filter((form): form is FormInst => form !== null)
+ .map(form => form.validate())
+
+ await Promise.all(promises)
+ emit('nextStep')
+ }
+ catch (errors) {
+ console.error('部分表单验证失败:', errors)
+ }
+ // formRef.value?.validate((errors) => {
+ // if (!errors) {
+ // emit('nextStep')
+ // }
+ // else {
+ // console.log('error', errors)
+ // }
+ // })
+}
+function preStep() {
+ emit('preStep')
+}
+// 上传文件
+const uploadFileIndex = ref(0)
+const fileInput = ref
(null)
+function triggerFileInput(index: number) {
+ (fileInput.value as HTMLInputElement)?.click()
+ uploadFileIndex.value = index
+}
+async function handleFileChange(event: Event) {
+ const target = event.target as HTMLInputElement
+ const files = target.files
+
+ if (files && files.length > 0) {
+ const res = await uploadFileBatches(files)
+ localForm.value.workFlowVersionList[uploadFileIndex.value].filePath = res[0].url
+ localForm.value.workFlowVersionList[uploadFileIndex.value].fileName = res[0].fileName
+ }
+ target.value = ''
+}
+
+function computedDelFlag() {
+ return localForm.value.workFlowVersionList.filter(item => item.delFlag === '0')
+}
+function onDelete(index: number) {
+ if (computedDelFlag().length === 1)
+ return
+ localForm.value.workFlowVersionList[index].delFlag = '2'
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 填写类别可让模型获得更精准的流量, 平台也有权基于标准修改你的类别标签
+
+
+
+
+
+
+
+
+
+ 100%
+
+
+ {{
+ item.fileName
+ }}
+
+
+
+
+
+
+
+
+
+ 上传文件
+
+
+ 点击上传文件
+
+
+ .json/.zip
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/components/publishWorkFlow/EditWorkFlow.vue b/app/components/publishWorkFlow/EditWorkFlow.vue
new file mode 100644
index 0000000..21274d0
--- /dev/null
+++ b/app/components/publishWorkFlow/EditWorkFlow.vue
@@ -0,0 +1,328 @@
+
+
+
+
+
+
+
+
+
+
+
+ 内容类别
+
+
+ 填写类别可让工作流获得更精准的流量,平台也有权基于标准修改你的类别标签
+
+
+
+
+
+
+ 参与活动
+
+
+ 参与特定活动或比赛,下拉选择
+
+
+
+
+
+
+
+
+
+
+
+
+ 公开状态: 对网站所有人可见
+
+
+ 非公开状态: 仅自己可见,可在“在线生图”自用
+
+
+
+
+
+
+ 发布原创模型拿收益:创作者激励计划
+
+
+
+
+
+
+
+
+
+
+ 用户使用时, 我授予用户以下权限
+
+
+
+
+
+
+ 允许在线使用
+
+
+ 您的工作流为公开状态时,默认同意此条款,他人不能随意转载
+
+
+
+
+
+
+
+ 允许下载工作流
+
+
+ 允许下载后,您的工作流可能会被他人转载,我们无法控制该行为
+
+
+
+
+
+
+ 用户使用时,我授予用户以下商业用途权限:
+
+
+
+
+
+ 下一步
+
+
+
+
+
+
+
diff --git a/app/components/publishWorkFlow/UploadImg.vue b/app/components/publishWorkFlow/UploadImg.vue
new file mode 100644
index 0000000..8f260a0
--- /dev/null
+++ b/app/components/publishWorkFlow/UploadImg.vue
@@ -0,0 +1,198 @@
+
+
+
+
+
+
+
+
+
+ 版本名: {{ item.versionName }}
+
+
+
+ 隐藏图片生成信息
+
+
+
+
+
+ 最多20张图片,图片不超过30M
+
+
+
+
+
+ 上传文件
+
+
+ 点击上传文件
+
+
+ 请勿上传裸露、暴力、血腥或其他包含非法信息图片
+
+
+
+
+
+
![]()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/constants/index.ts b/app/constants/index.ts
index 2da10a4..b7e43b6 100644
--- a/app/constants/index.ts
+++ b/app/constants/index.ts
@@ -1,4 +1,23 @@
+import type { SearchCheckIcon } from 'lucide-vue-next'
+
export const appName = '魔创未来'
export const appDescription = '魔创未来'
export const authRoutes = ['/personal-center', '/publish-model', '/publish-workflow']
-export const verifyBlankRoute = ['/member-center']
+export const verifyBlankRoute = ['/member-center', 'int-detail']
+export const isOriginalList = [{
+ label: '原创',
+ value: 0,
+}, {
+ label: '转载',
+ value: 1,
+}]
+export const isPublicList = [{
+ label: '公开',
+ value: 1,
+}, {
+ label: '自己',
+ value: 2,
+}]
+export const headerRole = { // 包括就隐藏
+ inputSearch: ['/model-square'],
+}
diff --git a/app/layouts/default.vue b/app/layouts/default.vue
index 8a6eac6..4d726d2 100644
--- a/app/layouts/default.vue
+++ b/app/layouts/default.vue
@@ -72,7 +72,7 @@ function handleSide(event: Event, path: string) {
-