bxlb.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. <script setup lang="ts">
  2. import { ref, getCurrentInstance, reactive } from "vue";
  3. import { useRouter } from "vue-router";
  4. import request, { download } from '~/utils/request';
  5. import { pick } from 'lodash-es';
  6. import { ElMessage } from 'element-plus'
  7. import type { FormInstance, FormRules } from 'element-plus'
  8. import type { AxiosRequestConfig } from 'axios'
  9. // #region (constant)
  10. const TABLE_KEY = 'cs_id'
  11. const URL_CUT = '/common/sjzd'
  12. const URL_CUT_REF = ref(URL_CUT)
  13. const URL_SUBMIT_KEY = URL_CUT.split('/').join('_').slice(1)
  14. const instance = getCurrentInstance()
  15. const router = useRouter()
  16. // #endregion
  17. // #region (variable)
  18. const loading_table = ref(true)
  19. let whichDialogSubmit: 'add' | 'edit'
  20. // #endregion
  21. // #region (type)
  22. type TYPE_TABLE_FIELD = {
  23. [TABLE_KEY]: string;
  24. 'cs_pid': string; // 上级编号
  25. 'cs_name': string; // 字典名称
  26. 'cs_code': string; // 字典编号
  27. 'cs_sort': string; // 排序编号
  28. 'cs_level': string; // 字典层级(备用)
  29. 'cs_path': string; // 字典路径(备用)
  30. 'cs_zdlx': string; // 字典类型
  31. 'cs_sfqy': string; // 是否启用
  32. 'cs_sjlx': string; // 数据类型
  33. 'cs_sjcd': string; // 数据长度
  34. 'cs_bz': string; // 备注
  35. 'cs_pcode': string; // 父级code
  36. }
  37. // #endregion
  38. // #region (props)
  39. // #endregion
  40. // #region (query row)
  41. const queryForm_Data = ref<Partial<TYPE_TABLE_FIELD> & { keyword?: string }>({})
  42. const handleQueryFormBtn_search = () => {
  43. queryApi()
  44. }
  45. const handleQueryFormBtn_clear = () => {
  46. queryForm_Data.value = {}
  47. }
  48. // #endregion
  49. // #region (table selection)
  50. const multipleSelection = ref<TYPE_TABLE_FIELD[]>([])
  51. const handleSelectionChange = (val: TYPE_TABLE_FIELD[]) => {
  52. multipleSelection.value = val
  53. }
  54. // #endregion
  55. // #region (table row)
  56. const handleTableRowBtn_import = async ({ file }: { file: File }) => {
  57. const res = await API_MAP['import']({ file })
  58. if (res.code === '1') {
  59. queryApi()
  60. ElMessage.success(res.msg)
  61. }
  62. }
  63. const handleTableRowBtn_export = () => {
  64. if(multipleSelection.value.length===0) return ElMessage.info('请先勾选导出文件');exportApi({[TABLE_KEY]:multipleSelection.value.map((item: TYPE_TABLE_FIELD)=>item[TABLE_KEY])?.join()})
  65. }
  66. const handleTableRowBtn_add = () => {
  67. whichDialogSubmit = 'add'
  68. dialogForm_Data.value = {}
  69. dialogVisible_addOrEdit.value = true
  70. }
  71. const handleTableRowBtn_delete = async () => {
  72. if(multipleSelection.value.length===0) return ElMessage.info('请先勾选文件');const resp = await deleteApi(multipleSelection.value.map((item: TYPE_TABLE_FIELD) => item[TABLE_KEY]));if(resp.code!=='1')return;ElMessage.success('删除成功');
  73. queryApi()
  74. }
  75. // #endregion
  76. // #region (table body)
  77. const tableData = ref<TYPE_TABLE_FIELD[]>([])
  78. const handleTableColBtn_edit = async (scope: { row: TYPE_TABLE_FIELD }) => {
  79. whichDialogSubmit = 'edit'
  80. const res = await detailApi(scope.row[TABLE_KEY])
  81. dialogForm_Data.value = (res.data?.one_info)
  82. dialogVisible_addOrEdit.value = true
  83. }
  84. const handleTableColBtn_delete = async (scope: { row: TYPE_TABLE_FIELD }) => {
  85. const resp = await deleteApi(scope.row[TABLE_KEY]);if(resp.code!=='1')return;ElMessage.success('删除成功');
  86. queryApi()
  87. }
  88. // #endregion
  89. // #region (pagination)
  90. const total = ref(0)
  91. const limit = ref(10)
  92. const currentPage = ref(1)
  93. function handleCurrentChange() {
  94. queryApi()
  95. }
  96. // #endregion
  97. // #region (dialog base)
  98. const dialogForm_Data = ref<Partial<TYPE_TABLE_FIELD> & { keyword?: string }>({})
  99. const handleDialogFormBtn_submit = async (formRefKey: string, extendData?: Partial<TYPE_TABLE_FIELD>) => {
  100. const isValid = await (instance?.refs[formRefKey] as FormInstance).validate((valid: boolean) => valid)
  101. if (isValid) {
  102. const resp = await API_MAP[whichDialogSubmit](<TYPE_TABLE_FIELD>({ ...dialogForm_Data.value, ...extendData, cs_pid: '837' }))
  103. if(resp.code!=='1')return;ElMessage.success('操作成功');handleDialogFormBtn_cancel()
  104. queryApi()
  105. }
  106. }
  107. const handleDialogFormBtn_cancel = (formRefKey?: string) => {
  108. dialogVisible_addOrEdit.value = false
  109. }
  110. // #endregion
  111. // #region (dialog add/edit)
  112. const dialogVisible_addOrEdit = ref<boolean>(false)
  113. const dialogForm_Ref_addOrEdit = ref<FormInstance>()
  114. const dialogForm_Rules_addOrEdit = reactive({
  115. 'cs_pid': { required: true, message: '上级编号不能为空', trigger: 'submit' },
  116. 'cs_name': { required: true, message: '报修类别名称不能为空', trigger: 'submit' },
  117. 'cs_code': { required: true, message: '字典编号不能为空', trigger: 'submit' },
  118. 'cs_sort': { required: true, message: '排序编号不能为空', trigger: 'submit' },
  119. 'cs_level': { required: true, message: '字典层级(备用)不能为空', trigger: 'submit' },
  120. 'cs_path': { required: true, message: '字典路径(备用)不能为空', trigger: 'submit' },
  121. 'cs_zdlx': { required: true, message: '字典类型不能为空', trigger: 'submit' },
  122. 'cs_sfqy': { required: true, message: '是否启用不能为空', trigger: 'submit' },
  123. 'cs_sjlx': { required: true, message: '数据类型不能为空', trigger: 'submit' },
  124. 'cs_sjcd': { required: true, message: '数据长度不能为空', trigger: 'submit' },
  125. 'cs_bz': { required: true, message: '备注不能为空', trigger: 'submit' },
  126. 'cs_pcode': { required: true, message: '父级code不能为空', trigger: 'submit' },
  127. })
  128. // #endregion
  129. // #region (request api):
  130. function queryApi() {
  131. loading_table.value = true
  132. return request({
  133. url: URL_CUT + '/index',
  134. data: {
  135. ...queryForm_Data.value,
  136. limit: limit.value,
  137. page: currentPage.value,
  138. cs_pid: 837,
  139. }
  140. }).then((response: { data: { total_rows: string, page_data: TYPE_TABLE_FIELD[] } }) => {
  141. const { data } = response
  142. total.value = parseInt(data.total_rows)
  143. tableData.value = data.page_data
  144. return response
  145. }).then(() => {
  146. loading_table.value = false
  147. })
  148. }
  149. function addApi(data: TYPE_TABLE_FIELD) {
  150. return request({
  151. url: URL_CUT + '/add',
  152. data: {
  153. [URL_SUBMIT_KEY]: data,
  154. }
  155. })
  156. }
  157. function editApi(data: Partial<TYPE_TABLE_FIELD>) {
  158. return request({
  159. url: URL_CUT + '/edit',
  160. data: {
  161. [TABLE_KEY]: data[TABLE_KEY],
  162. [URL_SUBMIT_KEY]: pick(data, ['cs_pid', 'cs_name', 'cs_code', 'cs_sort', 'cs_level', 'cs_path', 'cs_zdlx', 'cs_sfqy', 'cs_sjlx', 'cs_sjcd', 'cs_bz', 'cs_pcode',]),
  163. }
  164. })
  165. }
  166. function deleteApi(id: string | string[]) {
  167. return request({
  168. url: URL_CUT + '/delete',
  169. data: {
  170. [TABLE_KEY]: id,
  171. }
  172. })
  173. }
  174. function detailApi(id: string) {
  175. return request({
  176. url: URL_CUT + '/detail',
  177. data: {
  178. [TABLE_KEY]: id,
  179. }
  180. })
  181. }
  182. function importApi(data: { file: File }) {
  183. return request({
  184. $type: 'import',
  185. url: URL_CUT + '/import',
  186. data
  187. } as AxiosRequestConfig)
  188. }
  189. function exportApi(d) {
  190. return download(URL_CUT + '/index', {...queryForm_Data.value,...d,excel_file_name:'报修类别'})
  191. }
  192. const API_MAP = {
  193. query: queryApi,
  194. add: addApi,
  195. edit: editApi,
  196. delete: deleteApi,
  197. detail: detailApi,
  198. import: importApi,
  199. export: exportApi,
  200. }
  201. // #endregion
  202. // #region (page init)
  203. function init() {
  204. queryApi()
  205. }
  206. init()
  207. // #endregion
  208. </script>
  209. <template>
  210. <div class="card flex-grow flex flex-col">
  211. <el-form inline :model="queryForm_Data">
  212. <!-- <el-form-item label="关键字"><el-input v-model="queryForm_Data.keyword" ></el-input></el-form-item> -->
  213. <!-- <el-form-item label="上级编号">
  214. <el-input v-model="queryForm_Data.cs_pid" clearable />
  215. </el-form-item> -->
  216. <el-form-item label="类别名称">
  217. <el-input v-model="queryForm_Data.cs_name" clearable />
  218. </el-form-item>
  219. <!-- <el-form-item label="字典编号">
  220. <el-input v-model="queryForm_Data.cs_code" clearable />
  221. </el-form-item>
  222. <el-form-item label="排序编号">
  223. <el-input v-model="queryForm_Data.cs_sort" clearable />
  224. </el-form-item>
  225. <el-form-item label="字典层级(备用)">
  226. <el-input v-model="queryForm_Data.cs_level" clearable />
  227. </el-form-item>
  228. <el-form-item label="字典路径(备用)">
  229. <el-input v-model="queryForm_Data.cs_path" clearable />
  230. </el-form-item>
  231. <el-form-item label="字典类型">
  232. <el-select v-model="queryForm_Data.cs_zdlx" clearable filterable>
  233. <el-option label="自定义" value="1" />
  234. <el-option label="地方" value="2" />
  235. <el-option label="国标" value="3" />
  236. </el-select>
  237. </el-form-item>
  238. <el-form-item label="是否启用">
  239. <el-select v-model="queryForm_Data.cs_sfqy" clearable filterable>
  240. <el-option label="未启用" value="0" />
  241. <el-option label="已启用" value="1" />
  242. </el-select>
  243. </el-form-item>
  244. <el-form-item label="数据类型">
  245. <el-input v-model="queryForm_Data.cs_sjlx" clearable />
  246. </el-form-item>
  247. <el-form-item label="数据长度">
  248. <el-input v-model="queryForm_Data.cs_sjcd" clearable />
  249. </el-form-item>
  250. <el-form-item label="备注">
  251. <el-input v-model="queryForm_Data.cs_bz" clearable />
  252. </el-form-item>
  253. <el-form-item label="父级code">
  254. <el-input v-model="queryForm_Data.cs_pcode" clearable />
  255. </el-form-item> -->
  256. <el-form-item>
  257. <el-button @click="handleQueryFormBtn_search" type="primary">搜索</el-button>
  258. <el-button @click="handleQueryFormBtn_clear" type="warning">清空</el-button>
  259. </el-form-item>
  260. </el-form>
  261. <div class="divider"></div>
  262. <div>
  263. <import-button @success="queryApi" :url="URL_CUT_REF"></import-button>
  264. <el-button @click="handleTableRowBtn_export" type="success">导出</el-button>
  265. <el-button @click="handleTableRowBtn_add" type="primary">新增</el-button>
  266. <el-button @click="handleTableRowBtn_delete" type="danger">删除</el-button>
  267. </div>
  268. <div class="divider"></div>
  269. <div class="flex-auto">
  270. <el-table :data="tableData" @selection-change="handleSelectionChange" v-loading="loading_table"
  271. element-loading-background="#ffffff70">
  272. <el-table-column type="selection"></el-table-column>
  273. <el-table-column prop="cs_id" label="编号" width="auto" show-overflow-tooltip></el-table-column>
  274. <!-- <el-table-column prop="cs_pid" label="上级编号" width="auto" show-overflow-tooltip></el-table-column> -->
  275. <el-table-column prop="cs_name" label="报修类别名称" width="auto" show-overflow-tooltip></el-table-column>
  276. <!-- <el-table-column prop="cs_code" label="字典编号" width="auto" show-overflow-tooltip></el-table-column>
  277. <el-table-column prop="cs_sort" label="排序编号" width="auto" show-overflow-tooltip></el-table-column>
  278. <el-table-column prop="cs_level" label="字典层级(备用)" width="auto" show-overflow-tooltip></el-table-column>
  279. <el-table-column prop="cs_path" label="字典路径(备用)" width="auto" show-overflow-tooltip></el-table-column>
  280. <el-table-column prop="cs_zdlx" label="字典类型" width="auto" show-overflow-tooltip></el-table-column>
  281. <el-table-column prop="cs_sfqy" label="是否启用" width="auto" show-overflow-tooltip></el-table-column>
  282. <el-table-column prop="cs_sjlx" label="数据类型" width="auto" show-overflow-tooltip></el-table-column>
  283. <el-table-column prop="cs_sjcd" label="数据长度" width="auto" show-overflow-tooltip></el-table-column>
  284. <el-table-column prop="cs_bz" label="备注" width="auto" show-overflow-tooltip></el-table-column>
  285. <el-table-column prop="cs_pcode" label="父级code" width="auto" show-overflow-tooltip></el-table-column> -->
  286. <el-table-column label="操作" fixed="right">
  287. <template #default="scope">
  288. <el-button link :auto-insert-space="false" @click="handleTableColBtn_edit(scope)" type="primary">编辑
  289. </el-button>
  290. <el-button link :auto-insert-space="false" @click="handleTableColBtn_delete(scope)" type="primary">删除
  291. </el-button>
  292. </template>
  293. </el-table-column>
  294. </el-table>
  295. </div>
  296. <div class="flex justify-end mt-10 py-4">
  297. <el-pagination :page-size="limit" v-model:current-page="currentPage" @current-change="handleCurrentChange"
  298. background layout="total, prev, pager, next" :total="total" />
  299. </div>
  300. </div>
  301. <el-dialog v-model="dialogVisible_addOrEdit" append-to-body destroy-on-close>
  302. <el-form :model="dialogForm_Data" ref="dialogForm_Ref_addOrEdit" :rules="dialogForm_Rules_addOrEdit"
  303. label-width="120px">
  304. <!-- <el-form-item label="上级编号" prop="cs_pid">
  305. <el-input v-model="dialogForm_Data.cs_pid" clearable />
  306. </el-form-item> -->
  307. <el-form-item label="报修类别名称" prop="cs_name">
  308. <el-input v-model="dialogForm_Data.cs_name" clearable />
  309. </el-form-item>
  310. <!-- <el-form-item label="字典编号" prop="cs_code">
  311. <el-input v-model="dialogForm_Data.cs_code" clearable />
  312. </el-form-item>
  313. <el-form-item label="排序编号" prop="cs_sort">
  314. <el-input v-model="dialogForm_Data.cs_sort" clearable />
  315. </el-form-item>
  316. <el-form-item label="字典层级(备用)" prop="cs_level">
  317. <el-input v-model="dialogForm_Data.cs_level" clearable />
  318. </el-form-item>
  319. <el-form-item label="字典路径(备用)" prop="cs_path">
  320. <el-input v-model="dialogForm_Data.cs_path" clearable />
  321. </el-form-item>
  322. <el-form-item label="字典类型" prop="cs_zdlx">
  323. <el-radio-group v-model="dialogForm_Data.cs_zdlx">
  324. <el-radio label="1">自定义</el-radio>
  325. <el-radio label="2">地方</el-radio>
  326. <el-radio label="3">国标</el-radio>
  327. </el-radio-group>
  328. </el-form-item>
  329. <el-form-item label="是否启用" prop="cs_sfqy">
  330. <el-radio-group v-model="dialogForm_Data.cs_sfqy">
  331. <el-radio label="0">未启用</el-radio>
  332. <el-radio label="1">已启用</el-radio>
  333. </el-radio-group>
  334. </el-form-item>
  335. <el-form-item label="数据类型" prop="cs_sjlx">
  336. <el-input v-model="dialogForm_Data.cs_sjlx" clearable />
  337. </el-form-item>
  338. <el-form-item label="数据长度" prop="cs_sjcd">
  339. <el-input v-model="dialogForm_Data.cs_sjcd" clearable />
  340. </el-form-item>
  341. <el-form-item label="备注" prop="cs_bz">
  342. <el-input v-model="dialogForm_Data.cs_bz" clearable />
  343. </el-form-item>
  344. <el-form-item label="父级code" prop="cs_pcode">
  345. <el-input v-model="dialogForm_Data.cs_pcode" clearable />
  346. </el-form-item> -->
  347. <div class="flex justify-center">
  348. <el-button @click="handleDialogFormBtn_submit('dialogForm_Ref_addOrEdit')" type="primary">提交</el-button>
  349. <el-button @click="handleDialogFormBtn_cancel('dialogForm_Ref_addOrEdit')" type="default">取消</el-button>
  350. </div>
  351. </el-form>
  352. </el-dialog>
  353. </template>