codeSet.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. <template>
  2. <el-dialog
  3. title="编号配置"
  4. :visible.sync="dialogVisible"
  5. width="70%"
  6. append-to-body
  7. >
  8. <el-tabs v-model="activeName" type="card" @tab-click="handleClick">
  9. <el-tab-pane v-for="item in activeOptions" :label="item.label" :name="item.value">
  10. <div class="file-rule-container">
  11. <div class="header-box">
  12. <div class="preview-box">
  13. <span>生成预览</span>
  14. <el-input v-model="dataNumber" placeholder="预览编号" style="width: 300px; margin-left: 10px;" disabled size="small"></el-input>
  15. </div>
  16. <div class="header-tools">
  17. <el-button type="text" icon="el-icon-plus" @click="addRow">新增</el-button>
  18. <el-button type="text" icon="el-icon-sort" @click="sortData">排序</el-button>
  19. <el-button type="text" icon="el-icon-delete" @click="delBatchData" style="color: #F56C6C;" :loading="delLoad">删除</el-button>
  20. </div>
  21. </div>
  22. <el-table
  23. :data="tableData"
  24. style="width: 100%"
  25. v-loading="loading"
  26. ref="multipleTable"
  27. @selection-change="handleSelectionChange"
  28. >
  29. <el-table-column label="序号" type="index" width="50"></el-table-column>
  30. <el-table-column
  31. type="selection"
  32. width="55">
  33. </el-table-column>
  34. <el-table-column label="规则">
  35. <template slot-scope="scope">
  36. <el-select
  37. v-if="scope.row.isEdit"
  38. v-model="scope.row.rule"
  39. @change="handleNumberChange($event,scope.row)"
  40. placeholder="请选择"
  41. style="width: 100%"
  42. >
  43. <el-option
  44. v-for="item in numberOptions"
  45. :key="item.dictKey"
  46. :label="item.dictValue"
  47. :value="item.dictKey"
  48. >
  49. </el-option>
  50. </el-select>
  51. <span v-else>{{ getDictValueByRule(scope.row.rule) }}</span>
  52. </template>
  53. </el-table-column>
  54. <el-table-column label="数据填充">
  55. <template slot-scope="scope">
  56. <div v-if="scope.row.isEdit">
  57. <el-input v-model="scope.row.data" placeholder="输入生成编号时包含的固定字符" v-if="scope.row.rule===1"></el-input>
  58. <el-input v-model="scope.row.data" placeholder="*自动获取当前合同段编号" v-if="scope.row.rule===2" disabled></el-input>
  59. <el-input v-model="scope.row.data" placeholder="*自动获取各试验参数掩码" v-if="scope.row.rule===3" disabled></el-input>
  60. <el-input v-model="scope.row.data" placeholder="*自动获取当前年份" v-if="scope.row.rule===4" disabled></el-input>
  61. <el-input v-model="scope.row.data" placeholder="*自动获取当前月份" v-if="scope.row.rule===5" disabled></el-input>
  62. <el-input v-model="scope.row.data" placeholder="输入子增长的起始值和位数" v-if="scope.row.rule===6"></el-input>
  63. </div>
  64. <span v-else>{{ scope.row.data }}</span>
  65. </template>
  66. </el-table-column>
  67. <el-table-column label="是否自增">
  68. <template slot-scope="scope">
  69. <el-checkbox v-model="scope.row.isAutoIncrement" v-if="scope.row.rule==6" :true-label="1" :false-label="0"></el-checkbox>
  70. </template>
  71. </el-table-column>
  72. <el-table-column label="操作" width="150">
  73. <template slot-scope="scope">
  74. <el-button
  75. type="text"
  76. @click="handleEdit(scope.$index, scope.row)"
  77. v-if="!scope.row.isEdit"
  78. >
  79. 编辑
  80. </el-button>
  81. <el-button
  82. type="text"
  83. @click="handleSave(scope.$index, scope.row)"
  84. :loading="scope.row.loading"
  85. v-else
  86. >
  87. 保存
  88. </el-button>
  89. <el-button
  90. type="text"
  91. @click="handleDelete(scope.$index, scope.row)"
  92. >
  93. 删除
  94. </el-button>
  95. </template>
  96. </el-table-column>
  97. </el-table>
  98. </div>
  99. </el-tab-pane>
  100. </el-tabs>
  101. <template>
  102. <!-- 省略其他代码 -->
  103. <el-dialog
  104. title="排序"
  105. :visible.sync="sortDialogVisible"
  106. width="50%"
  107. append-to-body
  108. >
  109. <el-table
  110. :data="sortedTableData"
  111. style="width: 100%"
  112. >
  113. <el-table-column label="序号" type="index" width="50"></el-table-column>
  114. <el-table-column label="规则">
  115. <template slot-scope="scope">
  116. <span >{{ getDictValueByRule(scope.row.rule) }}</span>
  117. </template>
  118. </el-table-column>
  119. <el-table-column label="数据填充">
  120. <template slot-scope="scope">
  121. <span>{{ scope.row.data }}</span>
  122. </template>
  123. </el-table-column>
  124. <el-table-column label="是否自增">
  125. <template slot-scope="scope">
  126. <el-checkbox v-model="scope.row.isAutoIncrement" v-if="scope.row.rule==6" :true-label="1" :false-label="0"></el-checkbox>
  127. </template>
  128. </el-table-column>
  129. <el-table-column label="操作" width="150">
  130. <template slot-scope="scope">
  131. <el-button
  132. type="text"
  133. icon="el-icon-arrow-up"
  134. @click="handleSortUp(scope.$index)"
  135. style="margin-right: 5px;"
  136. ></el-button>
  137. <el-button
  138. type="text"
  139. icon="el-icon-arrow-down"
  140. @click="handleSortDown(scope.$index)"
  141. ></el-button>
  142. </template>
  143. </el-table-column>
  144. </el-table>
  145. <div slot="footer" class="dialog-footer">
  146. <el-button @click="sortDialogVisible = false">取 消</el-button>
  147. <el-button type="primary" @click="sortSave" :loading="sortLoad">确 定</el-button>
  148. </div>
  149. </el-dialog>
  150. </template>
  151. </el-dialog>
  152. </template>
  153. <script>
  154. import {getTrialNumberRule,save,update,remove,sort } from "@/api/ruleManage/codeRule.js";
  155. import { getDictionary } from "@/api/system/dict";
  156. export default {
  157. name: 'FileRuleDialog',
  158. data() {
  159. return {
  160. projectId: '',
  161. dialogVisible: false,
  162. loading: false,
  163. tableData: [],
  164. tableLoading: false,
  165. numberOptions: [
  166. ],
  167. dataNumber: '',
  168. activeName:'1',
  169. activeOptions: [
  170. { label: '试验编号', value: '1' },
  171. { label: '样品编号', value: '2' },
  172. { label: '委托单编号', value: '3' },
  173. { label: '记录表编号', value: '4' },
  174. { label: '报告表编号', value: '5' },
  175. ],
  176. multipleSelection:[],
  177. delLoad: false,
  178. sortDialogVisible: false, // 控制排序弹窗的显示与隐藏
  179. sortedTableData: [], // 排序弹窗的表格数据,为tableData的深拷贝
  180. sortLoad: false, // 排序保存按钮的loading状态
  181. }
  182. },
  183. methods: {
  184. show(pid) {
  185. this.dialogVisible = true
  186. this.projectId = pid
  187. this.getTableData()
  188. this.getNumberOptions()
  189. },
  190. handleClick(tab, event) {
  191. this.dataNumber=''
  192. this.getTableData()
  193. },
  194. addRow() {
  195. this.tableData.push({
  196. isEdit: true,
  197. })
  198. },
  199. sortData() {
  200. this.sortedTableData = JSON.parse(JSON.stringify(this.tableData)); // 深拷贝tableData
  201. this.sortDialogVisible = true; // 显示排序弹窗
  202. },
  203. handleSortUp(index) {
  204. if (index > 0) { // 确保不是第一行
  205. const temp = this.sortedTableData.splice(index, 1)[0]; // 移除当前行
  206. this.sortedTableData.splice(index - 1, 0, temp); // 在上一行插入
  207. } else {
  208. this.$message.warning('已经是第一行,无法上移');
  209. }
  210. },
  211. handleSortDown(index) {
  212. if (index < this.sortedTableData.length - 1) { // 确保不是最后一行
  213. const temp = this.sortedTableData.splice(index, 1)[0]; // 移除当前行
  214. this.sortedTableData.splice(index + 1, 0, temp); // 在下一行插入
  215. } else {
  216. this.$message.warning('已经是最后一行,无法下移');
  217. }
  218. },
  219. sortSave(){
  220. this.sortLoad = true;
  221. let params=this.sortedTableData
  222. sort(params).then((res) => {
  223. if (res.data.code === 200) {
  224. this.dataNumber = res.data.data;
  225. this.$message.success(res.data.msg);
  226. this.getTableData();
  227. } else {
  228. this.dataNumber = '';
  229. this.$message.error(res.data.msg);
  230. this.sortDialogVisible = false; // 关闭排序弹窗
  231. }
  232. }).catch(() => {
  233. this.$message.error('操作失败');
  234. }).finally(() => {
  235. this.sortLoad = false;
  236. });
  237. },
  238. getNumberOptions(){
  239. getDictionary({
  240. code:'trial_number_rule',
  241. }).then((res) => {
  242. this.numberOptions = res.data.data;
  243. this.numberOptions.forEach(item=>{
  244. item.dictKey=Number(item.dictKey)
  245. })
  246. });
  247. },
  248. getTableData()
  249. {
  250. this.tableLoading = true;
  251. getTrialNumberRule({
  252. projectId:this.projectId,
  253. contractId:0,
  254. type:this.activeName,
  255. pageSize:20
  256. }).then(res => {
  257. this.tableLoading = false;
  258. if (res.data.code == 200) {
  259. this.tableData = res.data.data['list'];
  260. this.total = res.data.data['total'];
  261. }else{
  262. this.tableData = [];
  263. }
  264. })
  265. },
  266. refreshData() {
  267. this.loading = true
  268. // TODO: 调用接口刷新数据
  269. setTimeout(() => {
  270. this.loading = false
  271. }, 500)
  272. },
  273. delBatchData(){
  274. if(this.multipleSelection.length===0){
  275. this.$message.warning('请选择要删除的规则!')
  276. return;
  277. }
  278. let ids = this.multipleSelection.map(item => item.id).join(',');
  279. this.$confirm('删除后,数据将无法恢复,是否确认删除?', '提示', {
  280. confirmButtonText: '确定',
  281. cancelButtonText: '取消',
  282. type: 'warning'
  283. }).then(() => {
  284. this.delLoad = true;
  285. return remove({ids: ids});
  286. }).then((res) => {
  287. if (res.data.code === 200) {
  288. this.$message.success(res.data.msg);
  289. this.dataNumber = res.data.data;
  290. this.getTableData();
  291. } else {
  292. this.$message.error(res.data.msg);
  293. }
  294. }).catch(() => {
  295. this.$message.info('已取消删除');
  296. }).finally(() => {
  297. this.delLoad = false;
  298. });
  299. },
  300. handleEdit(index, row) {
  301. this.$set(row, 'isEdit', true)
  302. },
  303. handleSave(index, row) {
  304. if(!row.rule) {
  305. this.$message.warning('请选择规则!')
  306. return;
  307. }
  308. row.loading = true;
  309. const apiMethod = row.id ? update : save;
  310. const params = {
  311. ...row,
  312. type: this.activeName,
  313. projectId: this.projectId,
  314. contractId: 0
  315. };
  316. apiMethod(params).then((res) => {
  317. if (res.data.code === 200) {
  318. this.dataNumber = res.data.data;
  319. this.$message.success(res.data.msg);
  320. this.getTableData();
  321. } else {
  322. this.dataNumber = '';
  323. this.$message.error(res.data.msg);
  324. }
  325. }).catch(() => {
  326. this.$message.error('操作失败');
  327. }).finally(() => {
  328. row.loading = false;
  329. row.isEdit = false;
  330. });
  331. },
  332. handleDelete(index, row) {
  333. if(!row.id) {
  334. this.tableData.splice(index, 1)
  335. return
  336. }
  337. this.$confirm('确认删除该规则?', '提示', {
  338. confirmButtonText: '确定',
  339. cancelButtonText: '取消',
  340. type: 'warning'
  341. }).then(() => {
  342. remove({ ids: row.id }).then((res) => {
  343. if (res.data.code === 200) {
  344. this.dataNumber = res.data.data;
  345. this.$message.success(res.data.msg);
  346. this.getTableData();
  347. } else {
  348. this.$message.error(res.data.msg);
  349. }
  350. })
  351. // this.tableData.splice(index, 1)
  352. })
  353. },
  354. handleNumberChange(data,row) {
  355. this.numberOptions.forEach(item => {
  356. if (item.dictKey === data) {
  357. row.ruleName = item.dictValue
  358. }
  359. })
  360. },
  361. getDictValueByRule(ruleKey) {
  362. const item = this.numberOptions.find(item => item.dictKey == ruleKey);
  363. return item ? item.dictValue : '未知';
  364. },
  365. handleSelectionChange(val) {
  366. this.multipleSelection = val;
  367. },
  368. }
  369. }
  370. </script>
  371. <style lang="scss" scoped>
  372. .file-rule-container {
  373. .header-box{
  374. display: flex;
  375. justify-content: flex-end;
  376. align-items: center;
  377. margin-bottom: 20px;
  378. margin-right: 10px;
  379. }
  380. .header-tools {
  381. // display: flex;
  382. text-align: right;
  383. }
  384. .node-tree {
  385. margin-top: 10px;
  386. max-height: 200px;
  387. overflow-y: auto;
  388. border: 1px solid #EBEEF5;
  389. padding: 10px;
  390. }
  391. }
  392. </style>