This commit is contained in:
sdaduanbilei-d1581 2025-12-29 14:59:52 +08:00
parent c198aa6643
commit 8bb2f8e221
11 changed files with 860 additions and 221 deletions

View File

@ -2,19 +2,21 @@ import fetch from '../fetch.js'
export default { export default {
save(params) { save(params) {
return fetch('/claim/add', params,'post','json') return fetch('/claim/add', params, 'post', 'json')
}, },
update(params) { update(params) {
return fetch('/claim/update', params,'post','json') return fetch('/claim/update', params, 'post', 'json')
}, },
list(params) { list(params) {
return fetch('/claim/list', params,'post','json') return fetch('/claim/list', params, 'post', 'json')
}, },
setImg(params) { setImg(params) {
return fetch('/claim/uploadImg',params,'post','json') return fetch('/claim/uploadImg', params, 'post', 'json')
}, },
linkLibrary(parasm) {
return fetch('/claim/unionLibrary', parasm, 'post', 'json')
}
} }

View File

@ -2,56 +2,60 @@ import fetch from '../fetch.js'
export default { export default {
save(params) { save(params) {
return fetch('/library/add', params,'post','json') return fetch('/library/add', params, 'post', 'json')
}, },
update(params) { update(params) {
return fetch('/library/update', params,'post','json') return fetch('/library/update', params, 'post', 'json')
}, },
remove(params) { remove(params) {
return fetch('/library/delete', params,'post','json') return fetch('/library/delete', params, 'post', 'json')
}, },
list(params) { list(params) {
return fetch('/library/list', params,'post','json') return fetch('/library/page', params, 'post', 'json')
}, },
setImg(params) { setImg(params) {
return fetch('/library/uploadImg',params,'post','json') return fetch('/library/uploadImg', params, 'post', 'json')
},
linkClass(params) {
return fetch('/library/relateLibrary', params, 'post', 'json')
}, },
/** /**
* 热门 * 热门
* @param params * @param params
* @returns {Promise | Promise<unknown>} * @returns {Promise | Promise<unknown>}
*/ */
changeHot(params){ changeHot(params) {
return fetch('/library/hot',params,'post','json') return fetch('/library/hot', params, 'post', 'json')
}, },
inviteList(params){ inviteList(params) {
return fetch('/personal/inviteCode/records',params,'post','json') return fetch('/personal/inviteCode/records', params, 'post', 'json')
}, },
wechat(params){ wechat(params) {
return fetch('/config/qrcode/add',params,'post','json') return fetch('/config/qrcode/add', params, 'post', 'json')
}, },
wechatUpdate(params){ wechatUpdate(params) {
return fetch('/config/qrcode/update',params,'post','json') return fetch('/config/qrcode/update', params, 'post', 'json')
}, },
wechatList(params){ wechatList(params) {
return fetch('/config/qrcode/list',params,'post','json') return fetch('/config/qrcode/list', params, 'post', 'json')
}, },
saveCategory(params){ saveCategory(params) {
return fetch('/class/add',params, 'post','json') return fetch('/class/add', params, 'post', 'json')
}, },
updateCategory(params){ updateCategory(params) {
return fetch('/class/update',params, 'post','json') return fetch('/class/update', params, 'post', 'json')
}, },
listCategory(params){ listCategory(params) {
return fetch('/class/list',params, 'post','json') return fetch('/class/list', params, 'post', 'json')
} }
} }

View File

@ -10,13 +10,16 @@
@success="upload" @success="upload"
> >
<template #upload-button> <template #upload-button>
<a-button size="small" type="text"> <a-button size="small" type="text" v-if="type === 'btn'">
<template #icon> <template #icon>
<icon-loading v-if="loading" /> <icon-loading v-if="loading" />
<icon-upload v-else /> <icon-upload v-else />
</template> </template>
<template #default>{{title}}</template> <template #default>{{title}}</template>
</a-button> </a-button>
<div v-else style="width: 60px; height: 60px; border: 1px solid #ccc" class="flex flex-center flex-justify-center" >
<icon-upload />
</div>
</template> </template>
</a-upload> </a-upload>
</div> </div>
@ -33,6 +36,10 @@ export default {
type: String, type: String,
default: '/api/oss/upload' default: '/api/oss/upload'
}, },
type : {
type:String,
default:'btn'
},
headers: { headers: {
type:Object, type:Object,
default(){ default(){

View File

@ -0,0 +1,79 @@
<template>
<div>
<a-button type="text" @click="show = true">百科</a-button>
<a-modal v-model:visible="show" @before-ok="submit">
<div class="flex flex-center flex-justify-start mb-20">
<a-input placeholder="请输入植物名称" v-model="name" @input="search"></a-input>
</div>
<div style="min-height: 400px; overflow-y: auto">
<div v-if="list.length === 0" class="flex flex-center flex-justify-center " style="min-height: 400px;">
<a-empty></a-empty>
</div>
<a-list v-for="item in list" :key="item.id">
<a-list-item>
<div class="flex flex-center flex-justify-between">
<div>{{ item.name }}</div>
<div>
<a-button @click="select(item)" type="text">选择</a-button>
</div>
</div>
</a-list-item>
</a-list>
</div>
</a-modal>
</div>
</template>
<script>
import upload from '@/components/upload/index.vue'
export default {
components: {
upload
},
props: {
id: {
type: String,
default: ''
}
},
data() {
return {
list: [],
show: false,
timer: null,
name: ''
}
},
methods: {
search() {
if (this.timer) clearTimeout(this.timer)
this.timer = setTimeout(() => {
const data = { name: this.name, keyword: this.name, current: 1, pageSize: 999 }
this.$api.flower.list(data).then(res => {
if (res.code === 200) {
this.list = res.data.list
}
})
}, 500)
},
select(item) {
const data = { id: this.id, libraryId: item.id }
this.$api.claim.linkLibrary(data).then(res => {
if (res.code === 200) {
this.$message.success(res.msg)
this.show = false
this.$emit('ok')
}
})
}
}
}
</script>
<style lang="scss" scoped></style>

View File

@ -3,50 +3,39 @@
<navbar title="植物兑换中心" /> <navbar title="植物兑换中心" />
<a-card> <a-card>
<div class="flex flex-center flex-justify-start"> <div class="flex flex-center flex-justify-start">
<edit @ok="fetchList"/> <edit @ok="fetchList" />
</div> </div>
<a-table <a-table class="mt-20" :columns="columns" :data="list" :pagination="page" @pageChange="change">
class="mt-20" <template #name="{ record }">
:columns="columns" <div class="flex flex-center flex-justify-start">
:data="list" <a-image v-if="record.imgList.length > 0" width="60" height="60" :src="record.imgList[0].url"
:pagination="page" :alt="record.id" />
@pageChange="change" <div class="ml-10">{{ record.name }}</div>
> </div>
<template #name="{ record }"> </template>
<div class="flex flex-center flex-justify-start"> <template #menu="{ record }">
<a-image <div class="flex flex-center">
v-if="record.imgList.length > 0" <edit type="edit" :info="record" @ok="fetchList" />
width="60" <baike :id="record.id" @ok="fetchList" />
height="60" </div>
:src="record.imgList[0].url" </template>
:alt="record.id" </a-table>
/> </a-card>
<div class="ml-10">{{ record.name }}</div>
</div>
</template>
<template #menu="{ record }">
<div class="flex flex-center">
<edit type="edit" :info="record" @ok="fetchList" />
<a-button type="text" @click="changeHot(record)">{{
record.isHot === 0 ? '设置热门' : '取消热门'
}}</a-button>
</div>
</template>
</a-table>
</a-card>
</div> </div>
</template> </template>
<script> <script>
import navbar from '@/components/navbar/index.vue' import navbar from '@/components/navbar/index.vue'
import baike from '../claim/components/baike.vue'
import edit from '../claim/components/edit.vue' import edit from '../claim/components/edit.vue'
import upload from '../../../components/upload/index.vue' import upload from '../../../components/upload/index.vue'
export default { export default {
components: { components: {
upload, upload,
edit, edit,
baike,
navbar navbar
}, },
data() { data() {
@ -55,26 +44,26 @@ export default {
current: 0, current: 0,
pageSize: 10 pageSize: 10
}, },
list:[], list: [],
columns :[ columns: [
{ {
title:'名称', title: '名称',
slotName: 'name', slotName: 'name',
}, },
{ {
title:'标签', title: '标签',
dataIndex: 'tag', dataIndex: 'tag',
}, },
{ {
title:'档案', title: '档案',
dataIndex:'content' dataIndex: 'content'
}, },
{ {
title:"操作", title: "操作",
slotName:'menu' slotName: 'menu'
} }
] ]
} }
}, },
mounted() { mounted() {
@ -82,11 +71,11 @@ export default {
}, },
methods: { methods: {
fetchList() { fetchList() {
const data = { keyword: '',name:'', ...this.page } const data = { keyword: '', name: '', ...this.page }
this.$api.claim.list(data).then(res => { this.$api.claim.list(data).then(res => {
if (res.code === 200) { if (res.code === 200) {
console.log(res) console.log(res)
this.list = res.data.list this.list = res.data.list
} }
}) })
} }

View File

@ -1,114 +1,174 @@
<template> <template>
<div> <div>
<a-button type="text" @click="show = true">{{ title }}</a-button> <a-button type="text" @click="show = true">{{ title }}</a-button>
<a-modal v-model:visible="show" @before-ok="submit" @close="reset"> <a-modal v-model:visible="show" @before-ok="submit" @close="reset">
<a-textarea v-model="tmp" :auto-size="{ miniRows: 6 }"></a-textarea> <div class="bold mb-20">请输入花卉信息</div>
</a-modal> <a-textarea v-model="from" :auto-size="{ miniRows: 6 }"></a-textarea>
</div> <div>
<div class="bold mt-20">请选择分类</div>
<div class="mt-20">
<a-tag v-for="item in list" type="primary" class="mr-15" :color="item.checked ? 'green' : ''"
@click="check(item)">
{{ item.tag }}
</a-tag>
</div>
</div>
</a-modal>
</div>
</template> </template>
<script> <script>
export default { export default {
props: { props: {
type: { type: {
type: String, type: String,
default: 'add' default: 'add'
},
info: {
type:Object,
default:null
}
}, },
watch: { info: {
show: { type: Object,
handler(val) { default: null
if (val) { }
this.tmp = JSON.stringify(this.from, null, 4) },
} watch: {
} show: {
}, handler(val) {
type: { if (val) {
handler(val) { if (this.info) {
if (val === 'edit') { this.from = JSON.parse(JSON.stringify(this.info))
console.log(this.info) const keysToRemove = ['careSchedules', 'relatedLibrary', 'classification', 'ralatedLibrary', 'imgList']
this.title = "编辑" Object.keys(this.from).forEach(k => {
this.from.id = this.info.id if (keysToRemove.some(t => t.toLowerCase() === k.toLowerCase())) {
this.from.name = this.info.Name delete this.from[k]
this.from.desc = this.info.Desc }
this.from.remark = this.info.Remark })
this.from.circleDays = this.info.CircleDays }
this.from.isCircle = this.info.isCircle this.from = JSON.stringify(this.from, null, 4)
this.tmp = JSON.stringify(this.from, null, 4) this.fetchList()
}
},
immediate: true
} }
}
}, },
data() { type: {
return { handler(val) {
tmp: null, if (val === 'edit') {
show: false, console.log(this.info)
title: '新增', this.title = "编辑"
from: { this.from.id = this.info.id
"name": "蝴蝶兰", this.from.name = this.info.Name
"latinName": "Phalaenopsis aphrodite Rchb. f.", this.from.desc = this.info.Desc
"aliases": "蝶兰,台湾蝴蝶兰,洋兰皇后", this.from.remark = this.info.Remark
"genus": "蝴蝶兰属", this.from.circleDays = this.info.CircleDays
"ossId": "9bb42e62-9c13-11f0-aa50-ea36f1e40c44", this.from.isCircle = this.info.isCircle
"growthHabit": "喜高温多湿半阴环境,不耐寒,怕干旱和强光,忌积水;附生于树干或岩石,根系暴露于空气中吸收水分", this.from = JSON.stringify(this.from, null, 4)
"pestsDiseases": "叶斑病,灰霉病,褐斑病,介壳虫,煤烟病",
"lifeCycle": "多年生",
"lightIntensity": "中光照",
"lightType": "散射光",
"optimalTempMin": 20,
"optimalTempMax": 28,
"hardyTempMin": 5,
"hardyTempMax": 32,
"foliageType": "稍肉质",
"foliageColor": "正面绿色,背面紫绿色",
"foliageShape": "椭圆形或长圆形,先端锐尖或钝",
"height": 50,
"floweringPeriod": "自然花期4-6月人工栽培可全年开花盛花期12-3月",
"floweringColor": "白、粉、黄、紫红等,常具斑纹或条纹",
"floweringShape": "花姿如蝶唇瓣3裂具卷须",
"flowerDiameter": 90
}
}
},
methods: {
reset(){
this.from = {
name: '请输入名称',
} }
}, },
submit(done) { immediate: true
const data = JSON.parse(this.tmp)
if (this.type === 'add') {
this.$api.flower.save(data).then(res => {
if (res.code === 200) {
this.$message.success(res.msg)
this.$emit('ok')
done()
} else {
this.$message.error(res.msg)
done(false)
}
})
} else {
this.$api.flower.update(data).then(res => {
if (res.code === 200) {
this.$message.success(res.msg)
this.$emit('ok')
done()
} else {
this.$message.error(res.msg)
done(false)
}
})
}
}
} }
},
data() {
return {
tmp: null,
show: false,
title: '新增',
list: [],
from: {
"name": "蝴蝶兰",
"latinName": "Phalaenopsis aphrodite Rchb. f.",
"aliases": "蝶兰,台湾蝴蝶兰,洋兰皇后",
"genus": "蝴蝶兰属",
"ossId": "9bb42e62-9c13-11f0-aa50-ea36f1e40c44",
"growthHabit": "喜高温多湿半阴环境,不耐寒,怕干旱和强光,忌积水;附生于树干或岩石,根系暴露于空气中吸收水分",
"pestsDiseases": "叶斑病,灰霉病,褐斑病,介壳虫,煤烟病",
"lifeCycle": "多年生",
"lightIntensity": "中光照",
"lightType": "散射光",
"optimalTempMin": 20,
"optimalTempMax": 28,
"hardyTempMin": 5,
"hardyTempMax": 32,
"foliageType": "稍肉质",
"foliageColor": "正面绿色,背面紫绿色",
"foliageShape": "椭圆形或长圆形,先端锐尖或钝",
"height": 50,
"floweringPeriod": "自然花期4-6月人工栽培可全年开花盛花期12-3月",
"floweringColor": "白、粉、黄、紫红等,常具斑纹或条纹",
"floweringShape": "花姿如蝶唇瓣3裂具卷须",
"flowerDiameter": 90,
classificationId: ''
}
}
},
methods: {
reset() {
this.from = {
name: '请输入名称',
}
},
fetchList() {
const data = { current: 1, pageSize: 999, }
this.$api.flower.listCategory(data).then((res) => {
if (res.code === 200) {
this.list = res.data.list.map(e => {
e.checked = false
return e
})
}
})
},
check(item) {
this.list.forEach(e => {
e.checked = false
})
item.checked = true
try {
const obj = JSON.parse(this.from)
obj.classificationId = item.id
this.from = JSON.stringify(obj, null, 4)
} catch (e) {
this.$message.error('JSON 格式错误,无法选择分类')
}
},
submit(done) {
let data
try {
data = JSON.parse(this.from)
} catch (e) {
this.$message.error('JSON 格式错误')
done(false)
return
}
if (this.type === 'add') {
// id
if (data.classificationId === '') {
this.$message.error('请设置分类')
done(false)
return
}
this.$api.flower.save(data).then(res => {
if (res.code === 200) {
this.$message.success(res.msg)
this.$emit('ok')
done()
} else {
this.$message.error(res.msg)
done(false)
}
})
} else {
this.$api.flower.update(data).then(res => {
if (res.code === 200) {
this.$message.success(res.msg)
this.$emit('ok')
done()
} else {
this.$message.error(res.msg)
done(false)
}
})
}
}
}
} }
</script> </script>

View File

@ -0,0 +1,78 @@
<template>
<div>
<a-button type="text" @click="show = true">分类</a-button>
<a-modal v-model:visible="show" @before-ok="submit">
<div>
<a-tag v-for="item in list" type="primary" class="mr-15" @click="select(item)">
{{ item.tag }}
</a-tag>
</div>
</a-modal>
</div>
</template>
<script>
export default {
props: {
id: {
type: String,
default: ''
}
},
watch: {
show: {
handler(val) {
if (val) {
this.fetchList()
}
},
immediate: true
}
},
data() {
return {
list: [],
show: false,
timer: null,
name: ''
}
},
methods: {
fetchList() {
const data = { current: 1, pageSize: 999, }
this.$api.flower.listCategory(data).then((res) => {
if (res.code === 200) {
this.list = res.data.list.map(e => {
e.checked = false
return e
})
}
})
},
select(item) {
const data = { id: this.id, ids: [item.id] }
this.$api.flower.linkClass(data).then(res => {
if (res.code === 200) {
this.$message.success(res.msg)
this.show = false
this.$emit('ok')
} else {
this.$message.error(res.msg)
}
})
},
}
}
</script>
<style lang="scss" scoped></style>

View File

@ -1,23 +1,32 @@
<template> <template>
<div> <div>
<navbar title="花卉百科"/> <navbar title="花卉百科" />
<a-card> <a-card>
<div class="flex flex-center flex-justify-start"> <div class="flex flex-center flex-justify-start">
<edit @ok="fetchList"/> <edit @ok="fetchList" />
<category/> <category />
</div> </div>
<a-table class="mt-20" :columns="columns" :data="list" :pagination="page" @pageChange="change"> <a-table class="mt-20" :columns="columns" :data="list" :pagination="page" @pageChange="change">
<template #name="{record}"> <template #name="{ record }">
<div class="flex flex-center flex-justify-start"> <div class="flex flex-center flex-justify-start">
<a-image v-if="record.imgList.length > 0" width="60" height="60" :src="record.imgList[0].url" :alt="record.id"/> <a-image v-if="record.imgList.length > 0" width="60" height="60" :src="record.imgList[0].url" fit="cover"
<div class="ml-10">{{record.name}}</div> :alt="record.id" />
<div v-else>
<upload @ok="upload(record, $event)" type="image" />
</div>
<div class="ml-10">{{ record.name }}</div>
</div> </div>
</template> </template>
<template #menu="{record}"> <template #hot="{ record }">
<div @click="changeHot(record)">
<a-tag color="red" size="small" v-if="record.isHot === 1">热门</a-tag>
<a-tag size="small" v-else>未推荐</a-tag>
</div>
</template>
<template #menu="{ record }">
<div class="flex flex-center"> <div class="flex flex-center">
<edit type="edit" :info="record" @ok="fetchList"/> <edit type="edit" :info="record" @ok="fetchList" />
<a-button type="text" @click="changeHot(record)">{{record.isHot === 0 ?'设置热门':'取消热门'}}</a-button> <linkLibrary :id="record.id" />
<upload @ok="upload(record,$event)"/>
<a-popconfirm content="确认删除该条数据" @ok="remove(record.id)"> <a-popconfirm content="确认删除该条数据" @ok="remove(record.id)">
<a-button type="text">删除</a-button> <a-button type="text">删除</a-button>
</a-popconfirm> </a-popconfirm>
@ -32,58 +41,64 @@
import navbar from '@/components/navbar/index.vue' import navbar from '@/components/navbar/index.vue'
import upload from "../../../components/upload/index.vue"; import upload from "../../../components/upload/index.vue";
import edit from './components/edit.vue' import edit from './components/edit.vue'
import linkLibrary from './components/link.vue'
import category from './components/category.vue' import category from './components/category.vue'
export default { export default {
components: { components: {
navbar, navbar,
edit, edit,
category, category,
upload upload,
linkLibrary
}, },
data() { data() {
return { return {
list: [], list: [],
page:{ page: {
current:1, current: 1,
pageSize:10, pageSize: 10,
total:0 total: 0
}, },
columns :[ columns: [
{ {
title:'名称', title: '名称',
slotName: 'name', slotName: 'name',
}, },
{ {
title:'别名', title: '别名',
dataIndex: 'aliases', dataIndex: 'aliases',
}, },
{ {
title:'latinName', title: 'latinName',
dataIndex:'latinName' dataIndex: 'latinName'
}, },
{ {
title:'科/属', title: '科/属',
dataIndex: 'genus', dataIndex: 'genus',
}, },
{ {
title:"操作", title: '是否推荐',
slotName:'menu' slotName: 'hot',
},
{
title: "操作",
slotName: 'menu'
} }
] ]
} }
}, },
mounted() { mounted() {
this.fetchList() this.fetchList()
}, },
methods: { methods: {
change(page){ change(page) {
this.page.current = page this.page.current = page
this.fetchList() this.fetchList()
}, },
fetchList() { fetchList() {
const data ={...this.page} const data = { ...this.page }
this.$api.flower.list(data).then(res => { this.$api.flower.list(data).then(res => {
if (res.code === 200){ if (res.code === 200) {
this.list = res.data.list this.list = res.data.list
this.page.total = res.data.total this.page.total = res.data.total
} else { } else {
@ -91,30 +106,30 @@ export default {
} }
}) })
}, },
changeHot(item){ changeHot(item) {
const ids = {ids:[item.id],isHot: item.isHot === 0 ? 1 :0} const ids = { ids: [item.id], isHot: item.isHot === 0 ? 1 : 0 }
this.$api.flower.changeHot(ids).then(res => { this.$api.flower.changeHot(ids).then(res => {
if(res.code === 200){ if (res.code === 200) {
this.$message.success(res.msg) this.$message.success(res.msg)
this.fetchList() this.fetchList()
}else { } else {
this.$message.error(res.msg); this.$message.error(res.msg);
} }
}) })
}, },
upload(item,file){ upload(item, file) {
const data = {id:item.id,ossIds:[file.id]} const data = { id: item.id, ossIds: [file.id] }
this.$api.flower.setImg(data).then(res => { this.$api.flower.setImg(data).then(res => {
if(res.code === 200){ if (res.code === 200) {
this.fetchList() this.fetchList()
} else { } else {
this.$message.error(res.msg) this.$message.error(res.msg)
} }
}) })
}, },
remove(id){ remove(id) {
this.$api.flower.remove({ids:[id]}).then(res => { this.$api.flower.remove({ ids: [id] }).then(res => {
if(res.code === 200){ if (res.code === 200) {
this.fetchList() this.fetchList()
} else { } else {
this.$message.error(res.msg) this.$message.error(res.msg)
@ -125,6 +140,4 @@ export default {
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped></style>
</style>

View File

@ -0,0 +1,125 @@
<template>
<div>
<Button type="tertiary" theme="borderless" @click="show = true">{{ type === 'edit'? '编辑' : type === 'addSub' ? '新增子项':'新增'}}</Button>
<Modal
v-model:visible="show"
width="640px"
@ok="handleOk"
:maskClosable="false"
@cancel="handleCancel"
>
<Form
:labelPosition="'top'"
:initValues="form"
:getFormApi="bindFormApi"
ref="formRef"
>
<Form.Input
field="name"
label="名称"
:rules="[{ required: true, message: '请填写名称' }]"
placeholder="请输入名称"
/>
</Form>
</Modal>
</div>
</template>
<script>
import { Modal, Button, Form, Toast, Notification } from '@kousum/semi-ui-vue'
export default {
components: {
Modal,
Button,
Form,
'Form.Input': Form.Input
},
props: {
type: {
type: String,
default: 'new'
},
info:{
type: Object,
default:null
}
},
data() {
return {
show: false,
form: {
id:'',
name: '',
sort: 1,
},
formApi: null
}
},
watch: {
info: {
handler(val) {
if (val) {
this.form = { ...val }
this.$nextTick(() => {
if (this.formApi) {
if (this.type === 'addSub'){
this.formApi.setValues({ parentId: val.id })
} else if (this.type === 'edit'){
this.formApi.setValues(val)
}
}
})
}
},
immediate: true
}
},
methods: {
bindFormApi(api) {
this.formApi = api
},
handleCancel() {
// Optional
},
handleOk() {
return new Promise((resolve, reject) => {
this.formApi.validate().then(values => {
const formData = { ...this.form, ...values }
if (this.form.id !== "" && this.type !== 'new'){
this.$api.sys.clientUpdate(formData).then(res => {
if (res.code === 200) {
Toast.success(res.msg)
this.$emit('ok')
resolve()
} else {
Notification.error({ content: res.msg })
reject()
}
}).catch(() => reject())
} else {
this.$api.sys.clientSave(formData).then(res => {
if (res.code === 200) {
Toast.success(res.msg)
this.$emit('ok')
resolve()
} else {
Notification.error({ content: res.msg })
reject()
}
}).catch(() => reject())
}
}).catch(errors => {
reject()
})
})
},
submit(done) {
// legacy
}
}
}
</script>
<style lang="scss" scoped></style>

View File

@ -0,0 +1,145 @@
<template>
<div>
<Button type="tertiary" theme="borderless" @click="show = true">{{ type === 'edit'? '编辑' : type === 'addSub' ? '新增子菜单':'新增菜单'}}</Button>
<Modal
v-model:visible="show"
width="640px"
@ok="handleOk"
:maskClosable="false"
@cancel="handleCancel"
>
<Form
:labelPosition="'top'"
:initValues="form"
:getFormApi="bindFormApi"
ref="formRef"
>
<Form.Input
field="name"
label="名称"
:rules="[{ required: true, message: '请填写名称' }]"
placeholder="请输入名称"
/>
<Form.Input
field="permission"
label="路径"
:rules="[{ required: true, message: '请输入路径' }]"
placeholder="请输入路径"
/>
<Form.InputNumber
field="sort"
label="排序"
initValue="1"
placeholder="请输入排序"
style="width: 100%"
/>
</Form>
</Modal>
</div>
</template>
<script>
import { Modal, Button, Form, Toast, Notification } from '@kousum/semi-ui-vue'
export default {
components: {
Modal,
Button,
Form,
'Form.Input': Form.Input,
'Form.InputNumber': Form.InputNumber
},
props: {
type: {
type: String,
default: 'new'
},
info:{
type: Object,
default:null
}
},
data() {
return {
show: false,
form: {
id:'',
name: '',
permission: '',
sort: 1,
category: 0,
parentId: '0',
code:''
},
formApi: null
}
},
watch: {
info: {
handler(val) {
if (val) {
this.form = { ...val }
this.$nextTick(() => {
if (this.formApi) {
if (this.type === 'addSub'){
this.formApi.setValues({ parentId: val.id })
} else if (this.type === 'edit'){
this.formApi.setValues(val)
}
}
})
}
},
immediate: true
}
},
methods: {
bindFormApi(api) {
this.formApi = api
},
handleCancel() {
// Optional
},
handleOk() {
return new Promise((resolve, reject) => {
this.formApi.validate().then(values => {
const formData = { ...this.form, ...values }
formData.code = formData.permission
formData.title = formData.name
if (this.form.id !== "" && this.type !== 'new'){
this.$api.sys.menuUpdate(formData).then(res => {
if (res.code === 200) {
Toast.success(res.msg)
this.$emit('ok')
resolve()
} else {
Notification.error({ content: res.msg })
reject()
}
}).catch(() => reject())
} else {
this.$api.sys.menuSave(formData).then(res => {
if (res.code === 200) {
Toast.success(res.msg)
this.$emit('ok')
resolve()
} else {
Notification.error({ content: res.msg })
reject()
}
}).catch(() => reject())
}
}).catch(errors => {
reject()
})
})
},
submit(done) {
// legacy
}
}
}
</script>
<style lang="scss" scoped></style>

View File

@ -0,0 +1,137 @@
<template>
<div>
<Button type="tertiary" theme="borderless" @click="show = true">{{ type === 'edit'? '编辑' : type === 'addSub' ? '新增子项':'新增'}}</Button>
<Modal
v-model:visible="show"
width="640px"
@ok="handleOk"
:maskClosable="false"
@cancel="handleCancel"
>
<Form
:labelPosition="'top'"
:initValues="form"
:getFormApi="bindFormApi"
ref="formRef"
>
<Form.Input
field="account"
label="账户"
:rules="[{ required: true, message: '请填写账户' }]"
placeholder="请输入账户"
/>
<Form.Input
field="phone"
label="电话"
:rules="[{ required: true, message: '请填写电话' }]"
placeholder="请输入电话"
/>
</Form>
</Modal>
</div>
</template>
<script>
import { Modal, Button, Form, Toast, Notification } from '@kousum/semi-ui-vue'
export default {
components: {
Modal,
Button,
Form,
'Form.Input': Form.Input // Use explicit component mapping if needed, or rely on Form.Input in template
},
props: {
type: {
type: String,
default: 'new'
},
info:{
type: Object,
default:null
}
},
data() {
return {
show: false,
form: {
id:'',
name: '',
phone:'',
account: '' // ensure account is in init values
},
formApi: null
}
},
watch: {
info: {
handler(val) {
if (val) {
this.form = { ...val }
// Update formApi if available immediately or next tick
this.$nextTick(() => {
if (this.formApi) {
if (this.type === 'addSub'){
this.formApi.setValues({ parentId: val.id })
} else if (this.type === 'edit'){
this.formApi.setValues(val)
}
}
})
}
},
immediate: true
}
},
methods: {
bindFormApi(api) {
this.formApi = api
},
handleCancel() {
// Reset form on close
// this.formApi.reset() // Optional
},
handleOk() {
// Return promise for Modal loading state
return new Promise((resolve, reject) => {
this.formApi.validate().then(values => {
// values contains the form data
const submitData = { ...this.form, ...values }
if (this.form.id !== "" && this.type !== 'new'){ // Logic check: type edit implies id exists
this.$api.sys.staffUpdate(submitData).then(res => {
if (res.code === 200) {
Toast.success(res.msg)
this.$emit('ok')
resolve()
} else {
Notification.error({ content: res.msg })
reject()
}
}).catch(() => reject())
} else {
this.$api.sys.staffSave(submitData).then(res => {
if (res.code === 200) {
Toast.success(res.msg)
this.$emit('ok')
resolve()
} else {
Toast.error(res.msg)
reject()
}
}).catch(() => reject())
}
}).catch(errors => {
reject()
})
})
},
// Legacy submit adapter if needed, but handleOk replaces it
submit(done) {
// not used with new Modal logic
}
}
}
</script>
<style lang="scss" scoped></style>