master
lzq 2025-12-20 11:49:02 +08:00
parent a9ab89a4fc
commit 2426d96fc5
12 changed files with 343 additions and 133 deletions

View File

@ -1,13 +1,19 @@
import type { Plugin } from 'vite'
import fs from 'fs'
/**
*
* @param options
*/
export function fileWatcher(...options: VitePluginTypes.FileWatcherOptions[]): Plugin {
console.log(`启动文件监听器,处理器数量:${options == null ? 0 : options.length}`)
return {
name: 'file-watcher-plugin',
configureServer(server) {
server.watcher
.on('all', (event, filePath, stats) => {
if (options == null || options.length === 0) return
options.forEach(it => {
const isDir = stats!.isDirectory()
const getContent = () => {

View File

@ -1,44 +1,45 @@
import fs from 'fs'
import path from 'node:path'
interface IconfontJson {
font_family: string;
css_prefix_text: string;
glyphs: {
icon_id: string
font_class: string
unicode: string
name: string
}[];
}
/*
interface IconfontJson {
font_family: string;
css_prefix_text: string;
glyphs: {
icon_id: string
font_class: string
unicode: string
name: string
}[];
}
*/
const targetFile = path.resolve(__dirname, './public/iconfont/ali/iconfont.json')
const targetFile = path.resolve(__dirname, '../src/components/a-icon/iconfont.json')
const outPath = path.resolve(__dirname, './src/components/iconfont')
const outPath = path.resolve(__dirname, '../src/components/a-icon')
/**
*
*/
export default {
process(data: VitePluginTypes.FileWatcherProcessParam) {
const json = JSON.parse(data.getContent()) as IconfontJson
const names = json.glyphs.map(glyph => glyph.font_class)
const dtsFile = outPath + '/iconfont.d.ts'
console.log('正在生成文件:', dtsFile)
const dts = `export {}
declare global {
namespace IconfontTypes {
type name = ${names.map(name => `'${name}'`).join('\n | ')}
}
}
`
fs.writeFileSync(dtsFile, dts, {encoding: 'utf-8'})
const tsFile = outPath + '/icons.ts'
const ts = `export default reactive([${'\n ' + names.map(name => `{name: '${name}'}`).join(',\n ') + '\n'}])`
const text = data.getContent()
const tsFile = path.resolve(outPath, 'iconfont.ts')
console.log('正在生成文件:', tsFile)
fs.writeFileSync(tsFile, ts, {encoding: 'utf-8'})
const tsContent = `export const icons = ${text.trim()} as const
console.log('文件生成完成')
export type IconName = (typeof icons.glyphs)[number]['font_class']
export interface IconGlyphs {
icon_id: string
name: string
font_class: IconName
unicode: string
unicode_decimal: number
}
`
fs.writeFileSync(tsFile, tsContent, {encoding: 'utf-8'})
},
isAccept(data: VitePluginTypes.FileWatcherAcceptParam) {
return data.event === 'change' && !data.isDir && data.filePath === targetFile

32
plugin/types.d.ts vendored
View File

@ -2,23 +2,55 @@ export {}
declare global {
namespace VitePluginTypes {
/**
*
*/
type FileWatcherEvent = 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir'
interface FileWatcherProcessParam {
/**
*
*/
event: FileWatcherEvent
/**
*
*/
filePath: string
/**
*
*/
isDir: boolean
/**
*
*/
getContent: () => string
}
interface FileWatcherAcceptParam {
/**
*
*/
event: FileWatcherEvent
/**
*
*/
filePath: string
/**
*
*/
isDir: boolean
}
interface FileWatcherOptions {
/**
*
* @param data
*/
process: (data: FileWatcherProcessParam) => void
/**
*
* @param data
*/
isAccept: (data: FileWatcherAcceptParam) => boolean
}
}

View File

@ -1,30 +0,0 @@
import '@/components/a-icon/iconfont.css'
import {
type IconName,
icons,
} from '@/components/a-icon/iconfont.ts'
import {
computed,
defineComponent,
} from 'vue'
export default defineComponent(
(props, {attrs}) => {
const prefixText = icons.css_prefix_text
const fontFamily = icons.font_family
const icon = computed(() => {
return props.name == null ? [] : [ fontFamily, prefixText + props.name ]
})
return () => (<><i class={icon.value} {...attrs}></i></>)
},
{
props: {
name: {
type: String as PropType<IconName>,
required: false,
validator: (_: string) => true,
},
},
name: 'AIcon',
})

View File

@ -0,0 +1,25 @@
<script lang="ts" setup>
import {
type IconName,
icons,
} from '@/components/a-icon/iconfont.ts'
import '@/components/a-icon/iconfont.css'
const props = defineProps<{
name?: IconName
}>()
const prefixText = icons.css_prefix_text
const fontFamily = icons.font_family
const icon = computed(() => {
console.log(props.name, 2222)
return props.name == null ? [] : [ fontFamily, prefixText + props.name ]
})
</script>
<template>
<i :class="icon" v-bind="$attrs"/>
</template>
<style lang="stylus" scoped>
</style>

View File

@ -0,0 +1,170 @@
{
"id": "4985351",
"name": "再昇云",
"font_family": "iconfont",
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "8582929",
"name": "编辑/修改",
"font_class": "bianji",
"unicode": "e604",
"unicode_decimal": 58884
},
{
"icon_id": "41408341",
"name": "扣款",
"font_class": "koukuanliebiao",
"unicode": "e63b",
"unicode_decimal": 58939
},
{
"icon_id": "33376724",
"name": "余额充值",
"font_class": "yuechongzhi",
"unicode": "e8f5",
"unicode_decimal": 59637
},
{
"icon_id": "6949389",
"name": "删除订单;报表;清单",
"font_class": "shanchudingdan-mian",
"unicode": "e6d7",
"unicode_decimal": 59095
},
{
"icon_id": "16695459",
"name": "取消订单",
"font_class": "quxiaodingdan",
"unicode": "e64a",
"unicode_decimal": 58954
},
{
"icon_id": "14443392",
"name": "历史轨迹-蓝",
"font_class": "lishiguiji-lan",
"unicode": "e672",
"unicode_decimal": 58994
},
{
"icon_id": "44180887",
"name": "过磅单据",
"font_class": "guobangdanju",
"unicode": "e66c",
"unicode_decimal": 58988
},
{
"icon_id": "26397534",
"name": "电子小票",
"font_class": "dianzixiaopiao",
"unicode": "e64d",
"unicode_decimal": 58957
},
{
"icon_id": "12814001",
"name": "详情",
"font_class": "xiangqing",
"unicode": "e611",
"unicode_decimal": 58897
},
{
"icon_id": "9777840",
"name": "关联单据",
"font_class": "guanliandanju",
"unicode": "e61d",
"unicode_decimal": 58909
},
{
"icon_id": "28095045",
"name": "准运证",
"font_class": "track",
"unicode": "e603",
"unicode_decimal": 58883
},
{
"icon_id": "18446165",
"name": "关联单选",
"font_class": "guanliandanxuan",
"unicode": "e68f",
"unicode_decimal": 59023
},
{
"icon_id": "8725687",
"name": "订单详情",
"font_class": "dingdanxiangqing",
"unicode": "e6bf",
"unicode_decimal": 59071
},
{
"icon_id": "23500943",
"name": "通知",
"font_class": "tongzhi",
"unicode": "e86a",
"unicode_decimal": 59498
},
{
"icon_id": "27250248",
"name": "预警管理",
"font_class": "yujingguanli",
"unicode": "e61b",
"unicode_decimal": 58907
},
{
"icon_id": "25301786",
"name": "字典管理",
"font_class": "shujuguanli",
"unicode": "e70c",
"unicode_decimal": 59148
},
{
"icon_id": "3590945",
"name": "角色管理",
"font_class": "jiaoseguanli",
"unicode": "e62f",
"unicode_decimal": 58927
},
{
"icon_id": "20853364",
"name": "用户管理",
"font_class": "yingyongyonghuguanli",
"unicode": "e6aa",
"unicode_decimal": 59050
},
{
"icon_id": "25007161",
"name": "品类管理",
"font_class": "shangpinguanli",
"unicode": "fcf3",
"unicode_decimal": 64755
},
{
"icon_id": "9206620",
"name": "系统管理",
"font_class": "xitongguanli",
"unicode": "e85c",
"unicode_decimal": 59484
},
{
"icon_id": "20136570",
"name": "菜单管理",
"font_class": "pinleiguanli",
"unicode": "e63d",
"unicode_decimal": 58941
},
{
"icon_id": "15689628",
"name": "公司审核",
"font_class": "qiyezhuce",
"unicode": "e6a1",
"unicode_decimal": 59041
},
{
"icon_id": "5468041",
"name": "审核管理",
"font_class": "shenheguanli",
"unicode": "e639",
"unicode_decimal": 58937
}
]
}

View File

@ -165,8 +165,8 @@ export const icons = {
'font_class': 'shenheguanli',
'unicode': 'e639',
'unicode_decimal': 58937,
},
],
}
]
} as const
export type IconName = (typeof icons.glyphs)[number]['font_class']

View File

@ -8,7 +8,7 @@ import {
type MenuItemRegistered,
} from 'element-plus'
import { elIcons } from '@/common/element/element.ts'
import AIcon from '@/components/a-icon/AIcon.tsx'
import AIcon from '@/components/a-icon/AIcon.vue'
import type { IconName } from '@/components/a-icon/iconfont.ts'
import styles from '@/pages/a-frame/aaside.module.styl'

View File

@ -9,17 +9,16 @@
</ElFormItem> -->
<ElFormItem label="身份类型">
<el-select style="width: 200px" v-model="searchForm.identityCategory" placeholder="身份类型">
<el-option v-for="item in bizList" :key="item.value" :label="item.label" :value="item.value" />
<el-option v-for="item in bizList" :key="item.value" :label="item.label" :value="item.value"/>
</el-select>
</ElFormItem>
<!-- <ElFormItem label="客户姓名">
<ElInput v-model="searchForm.customerName" placeholder="客户姓名" />
</ElFormItem> -->
<ElFormItem label="结算方式">
<el-select v-model="searchForm.settlementWay" placeholder="结算方式" style="width: 200px">
<el-option v-for="item in payList" :key="item.value" :label="item.label" :value="item.value" />
<el-option v-for="item in payList" :key="item.value" :label="item.label" :value="item.value"/>
</el-select>
</ElFormItem>
<!--
@ -49,25 +48,25 @@
<div class="tool-bar">
<!-- <ElButton :icon="elIcons.Plus" type="primary" @click="addHandler"></ElButton> -->
<ElButton :icon="elIcons.Filter" type="default" @click="showSearchForm = !showSearchForm" />
<ElButton :icon="elIcons.Filter" type="default" @click="showSearchForm = !showSearchForm"/>
</div>
<ElTable v-loading="searching" :data="tableData" cell-class-name="table-cell" class="table-list" empty-text="暂无数据" header-row-class-name="table-header" row-key="id">
<!-- <ElTableColumn label="Id" prop="id" /> -->
<ElTableColumn label="账号" prop="username" />
<ElTableColumn label="联系人" prop="nickname" />
<ElTableColumn label="身份类型" prop="identityCategoryTxt" />
<ElTableColumn label="组织信息" prop="orgId" />
<ElTableColumn label="客户姓名" prop="customerName" />
<ElTableColumn label="账号" prop="username"/>
<ElTableColumn label="联系人" prop="nickname"/>
<ElTableColumn label="身份类型" prop="identityCategoryTxt"/>
<ElTableColumn label="组织信息" prop="orgId"/>
<ElTableColumn label="客户姓名" prop="customerName"/>
<!-- <ElTableColumn label="客户联系电话" prop="phone" /> -->
<ElTableColumn label="结算方式" prop="settlementWayTxt" />
<ElTableColumn label="结算方式" prop="settlementWayTxt"/>
<ElTableColumn label="是否管理员">
<template #default="scope">
{{ scope.row.manager ? "是" : "否" }}
{{ scope.row.manager ? '是' : '否' }}
</template>
</ElTableColumn>
<ElTableColumn label="联系电话" prop="phone" />
<ElTableColumn label="创建时间" prop="regdate" />
<ElTableColumn label="联系电话" prop="phone"/>
<ElTableColumn label="创建时间" prop="regdate"/>
<!-- <ElTableColumn label="修改时间" prop="modifyTime" /> -->
<!-- <ElTableColumn label="是否删除" prop="deleted"/> -->
<ElTableColumn label="操作" width="180">
@ -83,8 +82,8 @@
</template>
</ElTableColumn>
</ElTable>
<ElPagination class="pagination" layout="prev, pager, next" :page-size="pagination.size" :total="pagination.total" @change="pageChangeHandler" />
<CustomerForm ref="customerForm" @edit-succ="paging" />
<ElPagination :page-size="pagination.size" :total="pagination.total" class="pagination" layout="prev, pager, next" @change="pageChangeHandler"/>
<CustomerForm ref="customerForm" @edit-succ="paging"/>
</Page>
</template>
@ -94,42 +93,45 @@ import CustomerForm from '@/pages/cst/customer/CustomerForm.vue'
import Page from '@/components/page/Page.vue'
import { elIcons } from '@/common/element/element.ts'
const tableData = ref<CustomerTypes.SearchCustomerResult[]>([]);
const tableData = ref<CustomerTypes.SearchCustomerResult[]>([])
let searchForm = reactive<CustomerTypes.SearchCustomerParam>({
current: 1,
size: 20,
});
const searching = ref(false);
const deling = ref(false);
const showSearchForm = ref(true);
const customerFormIns = useTemplateRef<InstanceType<typeof CustomerForm>>("customerForm");
})
const searching = ref(false)
const deling = ref(false)
const showSearchForm = ref(true)
const customerFormIns = useTemplateRef<InstanceType<typeof CustomerForm>>('customerForm')
const pagination = reactive<G.Pagination>({
total: 0,
current: 1,
size: 1,
});
})
function pageChangeHandler(currentPage: number, pageSize: number) {
searchForm.current = currentPage;
searchForm.size = pageSize;
paging();
}
function showDialog(data?: CustomerTypes.SearchCustomerResult) {
customerFormIns.value?.open(data);
}
function delHandler({ row }: { row: CustomerTypes.SearchCustomerResult }) {
deling.value = true;
CustomerApi.del([row.id!])
.then(() => {
ElMessage.success("删除成功");
paging();
})
.finally(() => {
deling.value = false;
});
searchForm.current = currentPage
searchForm.size = pageSize
paging()
}
function modifyHandler({ row }: { row: CustomerTypes.SearchCustomerResult }) {
showDialog(row);
function showDialog(data?: CustomerTypes.SearchCustomerResult) {
customerFormIns.value?.open(data)
}
function delHandler({row}: { row: CustomerTypes.SearchCustomerResult }) {
deling.value = true
CustomerApi.del([ row.id! ])
.then(() => {
ElMessage.success('删除成功')
paging()
})
.finally(() => {
deling.value = false
})
}
function modifyHandler({row}: { row: CustomerTypes.SearchCustomerResult }) {
showDialog(row)
}
function reset() {
@ -137,62 +139,62 @@ function reset() {
searchForm = reactive<CustomerTypes.SearchCustomerParam>({
current: 1,
size: 20,
});
paging();
})
paging()
}
function paging() {
searching.value = true;
searching.value = true
CustomerApi.paging(searchForm)
.then((res) => {
tableData.value = res.data?.records ?? [];
tableData.value = res.data?.records ?? []
})
.finally(() => {
searching.value = false;
});
searching.value = false
})
}
const payList = [
{
value: "YueJie",
label: "月结",
value: 'YueJie',
label: '月结',
},
{
value: "YuE",
label: "余额",
value: 'YuE',
label: '余额',
},
{
value: "XianFu",
label: "现付",
value: 'XianFu',
label: '现付',
},
];
]
const bizList = [
{
value: "ChanFei",
label: "产废方",
value: 'ChanFei',
label: '产废方',
},
{
value: "YunShu",
label: "运输方",
value: 'YunShu',
label: '运输方',
},
{
value: "XiaoNa",
label: "消纳方",
value: 'XiaoNa',
label: '消纳方',
},
{
value: "CaiGou",
label: "采购方",
value: 'CaiGou',
label: '采购方',
},
{
value: "SiJi",
label: "司机",
value: 'SiJi',
label: '司机',
},
];
]
onMounted(() => {
paging();
});
paging()
})
</script>
<style lang="stylus" scoped>
@ -230,6 +232,7 @@ onMounted(() => {
:deep(.table-cell) {
color #2F3540
}
.action-btn {
width 100%
display flex

View File

@ -90,7 +90,7 @@ import {
type IconGlyphs,
icons,
} from '@/components/a-icon/iconfont.ts'
import AIcon from '@/components/a-icon/AIcon.tsx'
import AIcon from '@/components/a-icon/AIcon.vue'
import ClientUtil from '@/common/utils/client-util.ts'
import Utils from '@/common/utils'

View File

@ -90,7 +90,7 @@ import { onMounted } from 'vue'
import { elIcons } from '@/common/element/element.ts'
import MenuForm from '@/pages/sys/menus/MenuForm.vue'
import Strings from '@/common/utils/strings.ts'
import AIcon from '@/components/a-icon/AIcon.tsx'
import AIcon from '@/components/a-icon/AIcon.vue'
import type { TableInstance } from 'element-plus'
const tableData = ref<MenuTypes.SysMenu[]>([])

View File

@ -13,6 +13,8 @@ import zipDist from './plugin/zip-dist.ts'
import path from 'node:path'
import ElementPlus from 'unplugin-element-plus/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import { fileWatcher } from './plugin/file-watcher.ts'
import IconfontProcess from './plugin/iconfont-process.ts'
// https://vite.dev/config/
export default defineConfig((configEnv) => {
@ -47,6 +49,7 @@ export default defineConfig((configEnv) => {
resolvers: [ ElementPlusResolver() ],
}),
processHtml(env.VITE_APP_NAME),
fileWatcher(IconfontProcess),
zipDist(),
],
resolve: {