code.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. <template>
  2. <hc-body split>
  3. <template #left>
  4. <div class="hc-menu-contents-box">
  5. <el-scrollbar>
  6. <HcMenuSimple
  7. :datas="menuOptions"
  8. :keys="menuKey"
  9. :props="menuProps"
  10. @change="handleMenuValue"
  11. />
  12. </el-scrollbar>
  13. </div>
  14. </template>
  15. <hc-card>
  16. <template #header>
  17. <span class="text-orange">*编号更改后,所有已生成的资料删除编号内容,保存后重新自动生成。</span>
  18. </template>
  19. <template #extra>
  20. <span class="mr-1">生成预览</span>
  21. <el-input v-model="inputNum" style="width: 300px;" class="mr-1" />
  22. <HcTooltip keys="tentative-basic-code-add">
  23. <el-button
  24. hc-btn
  25. type="primary"
  26. @click="handleAdd()"
  27. >
  28. <HcIcon name="add-circle" />
  29. <span>新增</span>
  30. </el-button>
  31. </HcTooltip>
  32. <HcTooltip keys="tentative-basic-code-sort">
  33. <el-button hc-btn type="primary" color="#12C060" style="color: white;" @click="sortFormClick">
  34. <HcIcon name="arrow-up-down" />
  35. <span>排序</span>
  36. </el-button>
  37. </HcTooltip>
  38. <HcTooltip keys="tentative-basic-code-resign">
  39. <el-button
  40. hc-btn
  41. color="#e03997" style="color: white;"
  42. :loading="resetLoad"
  43. @click="resetModalClick"
  44. >
  45. <HcIcon name="restart" />
  46. <span>重置编号</span>
  47. </el-button>
  48. </HcTooltip>
  49. <HcTooltip keys="tentative-basic-code-delete">
  50. <el-button hc-btn color="red" :loading="delModalLoad" @click="delModalClick">
  51. <HcIcon name="delete-bin-2" />
  52. <span>删除</span>
  53. </el-button>
  54. </HcTooltip>
  55. </template>
  56. <HcTable
  57. ref="tableRef" :column="tableColumn" :datas="tableData" :loading="tableLoad"
  58. is-new :index-style="{ width: 60 }" is-check :check-style="{ width: 29 }"
  59. @selection-change="tableSelection"
  60. >
  61. <template #type="{ row }">
  62. <el-select v-if="row.isEdit" v-model="row.rule" placeholder="请选择">
  63. <el-option
  64. v-for="item in typeOptions"
  65. :key="item.key"
  66. :label="item.label"
  67. :value="item.key"
  68. />
  69. </el-select>
  70. <span v-else>{{ getTypeLabel(row.rule) }}</span>
  71. </template>
  72. <template #data="{ row }">
  73. <el-input v-if="row.isEdit" v-model="row.data" placeholder="请输入数据" />
  74. <span v-else>{{ row.data }}</span>
  75. </template>
  76. <template #isAutoIncrement="{ row }">
  77. <el-checkbox v-if="row?.rule === 6" v-model="row.isAutoIncrement" :disabled="!row.isEdit" :true-value="1" :false-value="0" />
  78. </template>
  79. <template #action="{ row }">
  80. <el-button
  81. v-if="!row.isEdit"
  82. type="primary"
  83. link
  84. @click="handleEdit(row)"
  85. >
  86. <HcIcon name="edit-2" />
  87. 编辑
  88. </el-button>
  89. <el-button
  90. v-if="row.isEdit"
  91. type="success"
  92. link
  93. :loading="row.saveLoading"
  94. @click="handleSave(row)"
  95. >
  96. <HcIcon name="save-3" />
  97. 保存
  98. </el-button>
  99. <el-button
  100. v-del-com:[handleDelete]="row"
  101. type="danger"
  102. link
  103. >
  104. <HcIcon name="delete-bin-2" />
  105. 删除
  106. </el-button>
  107. </template>
  108. </HcTable>
  109. </hc-card>
  110. <!-- 表单排序 -->
  111. <hc-new-dialog
  112. v-model="sortFormShow"
  113. is-table
  114. title="排序"
  115. widths="800px"
  116. is-footer-center
  117. @close="sortFormClose"
  118. >
  119. <hc-table
  120. ref="tableSortFormRef"
  121. :column="tableSortFormColumn"
  122. :datas="tableSortFormData"
  123. is-row-drop
  124. is-sort
  125. quick-sort
  126. @row-drop="sortFormDropTap"
  127. @row-sort="rowSortFormTap"
  128. />
  129. <template #footer>
  130. <el-button hc-btn @click="sortFormClose">取消</el-button>
  131. <el-button
  132. hc-btn
  133. type="primary"
  134. :loading="sortFormLoading"
  135. @click="sortFormSubmit"
  136. >
  137. 提交
  138. </el-button>
  139. </template>
  140. </hc-new-dialog>
  141. </hc-body>
  142. </template>
  143. <script setup>
  144. import { nextTick, onMounted, ref } from 'vue'
  145. import { getDictionary } from '~api/other'
  146. import { arrToId, getArrValue } from 'js-fast-way'
  147. import dataApi from '~api/basic/code'
  148. import { useAppStore } from '~src/store'
  149. import { HcDelMsg } from 'hc-vue3-ui'
  150. import { deepClone } from 'js-fast-way'
  151. const store = useAppStore()
  152. const projectId = ref(store.getProjectId)
  153. const contractId = ref(store.getContractId)
  154. onMounted(()=>{
  155. getTypeOptions()
  156. getTableData()
  157. })
  158. //左侧菜单
  159. const menuKey = ref('1')
  160. const menuOptions = ref([
  161. { key: '1', label: '材料编号' },
  162. { key: '2', label: '样品编号' },
  163. { key: '3', label: '委托单编号' },
  164. { key: '4', label: '记录表编号' },
  165. { key: '5', label: '报告表编号' },
  166. ])
  167. const inputNum = ref('')
  168. //左侧菜单
  169. const menuProps = {
  170. key: 'key',
  171. label: 'label',
  172. }
  173. const typeOptions = ref([])
  174. const getTypeOptions = async ()=>{
  175. const { data } = await getDictionary({
  176. code: 'trial_number_rule',
  177. })
  178. //处理数据
  179. let newArr = []
  180. const newData = getArrValue(data)
  181. for (let i = 0; i < newData.length; i++) {
  182. newArr.push({
  183. label: newData[i]['dictValue'],
  184. key: Number(newData[i]['dictKey']),
  185. })
  186. }
  187. typeOptions.value = newArr
  188. }
  189. // 查找typeOptions中对应的label
  190. const getTypeLabel = (typeKey) => {
  191. return typeOptions.value.find(item => item.key === typeKey)?.label || '未知类型'
  192. }
  193. const handleMenuValue = (item) => {
  194. menuKey.value = item.key
  195. getTableData()
  196. }
  197. //获取数据
  198. const tableLoad = ref(true)
  199. const tableData = ref([])
  200. const tableRef = ref(null)
  201. const tableColumn = ref([
  202. { key: 'type', name: '规则' },
  203. { key: 'data', name: '数据填充' },
  204. { key: 'isAutoIncrement', name: '是否自增' },
  205. { key: 'action', name: '操作' },
  206. ])
  207. const getTableData = async () => {
  208. tableLoad.value = true
  209. const { error, code, data } = await dataApi.getTrialNumberRule({
  210. projectId: projectId.value,
  211. contractId: contractId.value,
  212. type: menuKey.value,
  213. })
  214. //处理数据
  215. tableLoad.value = false
  216. if (!error && code === 200) {
  217. tableData.value = getArrValue(data['list'])
  218. inputNum.value = data['trialNumber']
  219. } else {
  220. tableData.value = []
  221. inputNum.value = ''
  222. }
  223. }
  224. //多选
  225. const tableCheckedKeys = ref([])
  226. const tableSelection = (rows) => {
  227. tableCheckedKeys.value = rows
  228. }
  229. // 编辑行
  230. const handleEdit = (row) => {
  231. row.isEdit = true
  232. }
  233. const saveLoading = ref(false)
  234. // 保存行
  235. const handleSave = async (row) => {
  236. saveLoading.value = true
  237. if (!row.id) {
  238. const { error, code, msg, data } = await dataApi.save({
  239. ...row,
  240. projectId: projectId.value,
  241. contractId: contractId.value,
  242. type: menuKey.value,
  243. })
  244. //处理数据
  245. saveLoading.value = false
  246. if (!error && code === 200) {
  247. window?.$message?.success(msg)
  248. row.isEdit = false
  249. inputNum.value = data
  250. getTableData()
  251. }
  252. } else {
  253. const { error, code, msg, data } = await dataApi.update({
  254. ...row,
  255. projectId: projectId.value,
  256. contractId: contractId.value,
  257. type: menuKey.value,
  258. })
  259. //处理数据
  260. saveLoading.value = false
  261. if (!error && code === 200) {
  262. window?.$message?.success(msg)
  263. row.isEdit = false
  264. inputNum.value = data
  265. getTableData()
  266. }
  267. }
  268. }
  269. const handleDelete = async ({ item }, resolve) => {
  270. if (!item.id) {
  271. tableData.value = tableData.value.filter(ele => ele !== item)
  272. } else {
  273. await delData(item.id)
  274. }
  275. resolve()
  276. }
  277. //删除请求
  278. const delData = async (id) => {
  279. const { error, code, msg, data } = await dataApi.remove({
  280. ids:id,
  281. }, false)
  282. //判断状态
  283. if (!error && code === 200) {
  284. window?.$message?.success(msg)
  285. inputNum.value = data
  286. getTableData()
  287. } else {
  288. window?.$message?.error(msg)
  289. }
  290. }
  291. //删除节点
  292. const delModalLoad = ref(false)
  293. const delModalClick = () => {
  294. delModalLoad.value = true
  295. const rows = tableCheckedKeys.value
  296. const ids = rows.filter(row => row.id).map(row => row.id).join(',')
  297. HcDelMsg(async (resolve) => {
  298. await delData(ids)
  299. delModalLoad.value = false
  300. resolve() // 关闭弹窗的回调
  301. })
  302. }
  303. const handleAdd = () => {
  304. tableData.value.push({
  305. isEdit: true,
  306. })
  307. }
  308. const resetLoad = ref(false)
  309. const resetModalClick = async () => {
  310. // getTableData()
  311. resetLoad.value = true
  312. const { error, code, data, msg } = await dataApi.reTrialNumberRule({
  313. projectId: projectId.value,
  314. contractId: contractId.value,
  315. type: menuKey.value,
  316. })
  317. //处理数据
  318. resetLoad.value = false
  319. if (!error && code === 200) {
  320. window?.$message?.success(msg)
  321. getTableData()
  322. inputNum.value = data
  323. }
  324. }
  325. //排序
  326. const sortFormShow = ref(false)
  327. const tableSortFormRef = ref(null)
  328. const tableSortFormData = ref([])
  329. const sortFormLoading = ref(false)
  330. const tableSortFormColumn = ref([
  331. { key: 'type', name: '规则' },
  332. { key: 'data', name: '数据填充' },
  333. { key: 'isAutoIncrement', name: '是否自增' },
  334. { key: 'action', name: '操作' },
  335. ])
  336. const sortFormClick = () => {
  337. sortFormShow.value = true
  338. tableSortFormData.value = deepClone(tableData.value)
  339. }
  340. // 行拖拽
  341. const sortFormDropTap = (rows) => {
  342. tableSortFormData.value = [] // 先清空,否则排序会异常
  343. nextTick(() => {
  344. tableSortFormRef.value?.setData(rows)
  345. })
  346. }
  347. // 点击排序
  348. const rowSortFormTap = (rows) => {
  349. tableSortFormData.value = [] // 先清空,否则排序会异常
  350. nextTick(() => {
  351. tableSortFormData.value = rows
  352. })
  353. }
  354. //关闭排序
  355. const sortFormClose = () => {
  356. sortFormShow.value = false
  357. sortFormLoading.value = false
  358. tableSortFormData.value = []
  359. }
  360. const sortFormSubmit = async () => {
  361. //发起请求
  362. sortFormLoading.value = true
  363. const { error, code, msg, data } = await dataApi.sort(
  364. tableSortFormData.value,
  365. )
  366. sortFormLoading.value = false
  367. if (!error && code === 200) {
  368. window?.$message?.success(msg)
  369. inputNum.value = data
  370. getTableData()
  371. sortFormClose()
  372. }
  373. }
  374. </script>
  375. <style scoped>
  376. .wrap-text {
  377. white-space: normal; /* 或者使用 pre-wrap */
  378. word-wrap: break-word; /* 防止长单词不换行 */
  379. }
  380. </style>