Skip to content

Commit a4a376b

Browse files
committed
Merge remote-tracking branch 'yudao-ui-admin-vue3/dev' into dev
# Conflicts: # package.json
2 parents 33b0b5c + 677767f commit a4a376b

32 files changed

+769
-452
lines changed

.image/common/ai-feature.png

20.7 KB
Loading

.image/common/ai-preview.gif

348 KB
Loading

README.md

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -191,26 +191,24 @@ ps:核心功能已经实现,正在对接微信小程序中...
191191

192192
### 商城系统
193193

194+
演示地址:<https://doc.iocoder.cn/mall-preview/>
195+
194196
![功能图](/.image/common/mall-feature.png)
195197

196198
![功能图](/.image/common/mall-preview.png)
197199

198-
_前端基于 crmeb uniapp 经过授权重构,优化代码实现,接入芋道快速开发平台_
199-
200-
演示地址:<https://doc.iocoder.cn/mall-preview/>
201-
202200
### ERP 系统
203201

204-
![功能图](/.image/common/erp-feature.png)
205-
206202
演示地址:<https://doc.iocoder.cn/erp-preview/>
207203

208-
### CRM 系统
204+
![功能图](/.image/common/erp-feature.png)
209205

210-
![功能图](/.image/common/crm-feature.png)
206+
### CRM 系统
211207

212208
演示地址:<https://doc.iocoder.cn/crm-preview/>
213209

210+
![功能图](/.image/common/crm-feature.png)
211+
214212
## 🐷 演示图
215213

216214
### 系统功能

src/api/ai/image/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ export const ImageApi = {
5656
getImagePageMy: async (params: PageParam) => {
5757
return await request.get({ url: `/ai/image/my-page`, params })
5858
},
59+
// 获取公开的绘图记录
60+
getImagePagePublic: async (params) => {
61+
return await request.get({ url: `/ai/image/public-page`, params })
62+
},
5963
// 获取【我的】绘图记录
6064
getImageMy: async (id: number) => {
6165
return await request.get({ url: `/ai/image/get-my?id=${id}` })

src/api/ai/write/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export interface WriteVO {
1717
platform?: string // 平台
1818
model?: string // 模型
1919
generatedContent?: string // 生成的内容
20-
errorMessage: string // 错误信息
20+
errorMessage?: string // 错误信息
2121
createTime?: Date // 创建时间
2222
}
2323

src/api/mall/product/history.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import request from '@/config/axios'
2+
3+
/**
4+
* 获得商品浏览记录分页
5+
*
6+
* @param params 请求参数
7+
*/
8+
export const getBrowseHistoryPage = (params: any) => {
9+
return request.get({ url: '/product/browse-history/page', params })
10+
}

src/assets/audio/response.mp3

1.66 MB
Binary file not shown.

src/components/MarkdownView/index.vue

Lines changed: 16 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
<template>
2-
<div ref="contentRef" class="markdown-view" v-html="contentHtml"></div>
2+
<!-- <div ref="contentRef" class="markdown-view" v-html="contentHtml"></div>-->
3+
<div ref="contentRef" class="markdown-view" v-html="renderedMarkdown"></div>
34
</template>
45

56
<script setup lang="ts">
6-
import { useClipboard } from '@vueuse/core'
7-
import { marked } from 'marked'
7+
import {useClipboard} from '@vueuse/core'
8+
import MarkdownIt from 'markdown-it'
89
import 'highlight.js/styles/vs2015.min.css'
910
import hljs from 'highlight.js'
1011
@@ -19,45 +20,26 @@ const props = defineProps({
1920
const message = useMessage() // 消息弹窗
2021
const { copy } = useClipboard() // 初始化 copy 到粘贴板
2122
const contentRef = ref()
22-
const contentHtml = ref<any>() // 渲染的html内容
2323
const { content } = toRefs(props) // 将 props 变为引用类型
2424
25-
// 代码高亮:https://highlightjs.org/
26-
// 转换 markdown:marked
27-
28-
/** marked 渲染器 */
29-
const renderer = {
30-
code(code, language, c) {
31-
let highlightHtml
32-
try {
33-
highlightHtml = hljs.highlight(code, { language: language, ignoreIllegals: true }).value
34-
} catch (e) {
35-
// skip
25+
const md = new MarkdownIt({
26+
highlight: function (str, lang) {
27+
if (lang && hljs.getLanguage(lang)) {
28+
try {
29+
const copyHtml = `<div id="copy" data-copy='${str}' style="position: absolute; right: 10px; top: 5px; color: #fff;cursor: pointer;">复制</div>`
30+
return `<pre style="position: relative;">${copyHtml}<code class="hljs">${hljs.highlight(lang, str, true).value}</code></pre>`
31+
} catch (__) {}
3632
}
37-
const copyHtml = `<div id="copy" data-copy='${code}' style="position: absolute; right: 10px; top: 5px; color: #fff;cursor: pointer;">复制</div>`
38-
return `<pre style="position: relative;">${copyHtml}<code class="hljs">${highlightHtml}</code></pre>`
33+
return ``
3934
}
40-
}
41-
42-
// 配置 marked
43-
marked.use({
44-
renderer: renderer
45-
})
35+
});
4636
47-
/** 监听 content 变化 */
48-
watch(content, async (newValue, oldValue) => {
49-
await renderMarkdown(newValue)
50-
})
51-
52-
/** 渲染 markdown */
53-
const renderMarkdown = async (content: string) => {
54-
contentHtml.value = await marked(content)
55-
}
37+
const renderedMarkdown = computed(() => {
38+
return md.render(props.content);
39+
});
5640
5741
/** 初始化 **/
5842
onMounted(async () => {
59-
// 解析转换 markdown
60-
await renderMarkdown(props.content as string)
6143
// 添加 copy 监听
6244
contentRef.value.addEventListener('click', (e: any) => {
6345
if (e.target.id === 'copy') {

src/views/ai/image/square/index.vue

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<template>
2+
<div class="square-container">
3+
<el-input
4+
v-model="searchText"
5+
style="width: 100%; margin-bottom: 20px"
6+
size="large"
7+
placeholder="请输入要搜索的内容"
8+
:suffix-icon="Search"
9+
@keyup.enter="handleSearch"
10+
/>
11+
<div class="gallery">
12+
<div v-for="item in publicList" :key="item.id" class="gallery-item">
13+
<img :src="item.picUrl" class="img" />
14+
</div>
15+
</div>
16+
</div>
17+
</template>
18+
<script setup lang="ts">
19+
import { ImageApi, ImageVO } from '@/api/ai/image'
20+
import { Search } from '@element-plus/icons-vue'
21+
22+
/** 属性 */
23+
// TODO @fan:queryParams 里面搞分页哈。
24+
const pageNo = ref<number>(1)
25+
const pageSize = ref<number>(20)
26+
const publicList = ref<ImageVO[]>([])
27+
const searchText = ref<string>('')
28+
29+
/** 获取数据 */
30+
const getListData = async () => {
31+
const res = await ImageApi.getImagePagePublic({
32+
pageNo: pageNo.value,
33+
pageSize: pageSize.value,
34+
prompt: searchText.value
35+
})
36+
publicList.value = res.list as ImageVO[]
37+
}
38+
39+
/** 搜索 */
40+
const handleSearch = async () => {
41+
await getListData()
42+
}
43+
44+
onMounted(async () => {
45+
await getListData()
46+
})
47+
</script>
48+
<style scoped lang="scss">
49+
.square-container {
50+
background-color: #fff;
51+
padding: 20px;
52+
53+
.gallery {
54+
display: grid;
55+
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
56+
gap: 10px;
57+
//max-width: 1000px;
58+
background-color: #fff;
59+
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
60+
}
61+
62+
.gallery-item {
63+
position: relative;
64+
overflow: hidden;
65+
background: #f0f0f0;
66+
cursor: pointer;
67+
transition: transform 0.3s;
68+
}
69+
70+
.gallery-item img {
71+
width: 100%;
72+
height: auto;
73+
display: block;
74+
transition: transform 0.3s;
75+
}
76+
77+
.gallery-item:hover img {
78+
transform: scale(1.1);
79+
}
80+
81+
.gallery-item:hover {
82+
transform: scale(1.05);
83+
}
84+
}
85+
</style>

src/views/ai/music/components/index.vue

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<div class="flex h-1/1">
2+
<div class="flex h-full items-stretch">
33
<!-- 模式 -->
44
<Mode class="flex-none" @generate-music="generateMusic"/>
55
<!-- 音频列表 -->
@@ -13,8 +13,13 @@ import List from './list/index.vue'
1313
1414
defineOptions({ name: 'Index' })
1515
16-
const listRef = ref<{generateMusic: (...args) => void} | null>(null)
16+
const listRef = ref<Nullable<{generateMusic: (...args) => void}>>(null)
1717
18+
/*
19+
*@Description: 拿到左侧配置信息调用右侧音乐生成的方法
20+
*@MethodAuthor: xiaohong
21+
*@Date: 2024-07-19 11:13:38
22+
*/
1823
function generateMusic (args: {formData: Recordable}) {
1924
unref(listRef)?.generateMusic(args.formData)
2025
}
Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,70 @@
11
<template>
2-
<div class="h-72px bg-[var(--el-bg-color-overlay)] b-solid b-1 b-[var(--el-border-color)] b-l-none">播放器</div>
2+
<div class="flex items-center justify-between px-2 h-72px bg-[var(--el-bg-color-overlay)] b-solid b-1 b-[var(--el-border-color)] b-l-none">
3+
<!-- 歌曲信息 -->
4+
<div class="flex gap-[10px]">
5+
<el-image src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png" class="w-[45px]"/>
6+
<div>
7+
<div>{{currentSong.name}}</div>
8+
<div class="text-[12px] text-gray-400">{{currentSong.singer}}</div>
9+
</div>
10+
</div>
11+
12+
<!-- 音频controls -->
13+
<div class="flex gap-[12px] items-center">
14+
<Icon icon="majesticons:back-circle" :size="20" class="text-gray-300 cursor-pointer"/>
15+
<Icon :icon="audioProps.paused ? 'mdi:arrow-right-drop-circle' : 'solar:pause-circle-bold'" :size="30" class=" cursor-pointer" @click="toggleStatus('paused')"/>
16+
<Icon icon="majesticons:next-circle" :size="20" class="text-gray-300 cursor-pointer"/>
17+
<div class="flex gap-[16px] items-center">
18+
<span>{{audioProps.currentTime}}</span>
19+
<el-slider v-model="audioProps.duration" color="#409eff" class="w-[160px!important] "/>
20+
<span>{{ audioProps.duration }}</span>
21+
</div>
22+
<!-- 音频 -->
23+
<audio v-bind="audioProps" ref="audioRef" controls v-show="!audioProps" @timeupdate="audioTimeUpdate">
24+
<source :src="audioUrl"/>
25+
</audio>
26+
</div>
27+
28+
<!-- 音量控制器 -->
29+
<div class="flex gap-[16px] items-center">
30+
<Icon :icon="audioProps.muted ? 'tabler:volume-off' : 'tabler:volume'" :size="20" class="cursor-pointer" @click="toggleStatus('muted')"/>
31+
<el-slider v-model="audioProps.volume" color="#409eff" class="w-[160px!important] "/>
32+
</div>
33+
</div>
334
</template>
435

536
<script lang="ts" setup>
37+
import { formatPast } from '@/utils/formatTime'
38+
import audioUrl from '@/assets/audio/response.mp3'
639
740
defineOptions({ name: 'Index' })
841
42+
const currentSong = inject('currentSong', {})
43+
44+
const audioRef = ref<Nullable<HTMLElement>>(null)
45+
// 音频相关属性https://www.runoob.com/tags/ref-av-dom.html
46+
const audioProps = reactive({
47+
autoplay: true,
48+
paused: false,
49+
currentTime: '00:00',
50+
duration: '00:00',
51+
muted: false,
52+
volume: 50,
53+
})
54+
55+
function toggleStatus (type: string) {
56+
audioProps[type] = !audioProps[type]
57+
if (type === 'paused' && audioRef.value) {
58+
if (audioProps[type]) {
59+
audioRef.value.pause()
60+
} else {
61+
audioRef.value.play()
62+
}
63+
}
64+
}
65+
66+
// 更新播放位置
67+
function audioTimeUpdate (args) {
68+
audioProps.currentTime = formatPast(new Date(args.timeStamp), 'mm:ss')
69+
}
970
</script>

0 commit comments

Comments
 (0)